Я пишу простое приложение Gtk в Vala, которое «бросает кости» и отображает результат в виде изображения. Когда я сделал это в Python, используя Tkinter, я обнаружил, что могу загружать gif кадр за кадром и помещать каждый из них в массив, как в spritesheet.
Я пытаюсь сделать что-то подобное в Gtk путем создания итератора Gdk PixbufAnimation для получения каждого кадра. Так как это работает на основе временных интервалов, я получаю время и использую его для заполнения итератора, затем использую get_delay_time
, чтобы вычислить, насколько я должен увеличивать начальное число при каждом вызове advance
. Затем я вызываю заранее столько раз, сколько нужно, чтобы получить каждую сторону, сохраняя каждую в массиве Pixbufs, используя get_pixbuf
. Когда пришло время отображать заданную сторону, я просто индексирую этот массив и использую изображение, хранящееся там, для виджета Gtk Image.
Приведенный ниже код должен содержать достаточно информации для решения проблемы. Прошу прощения за несомненные многочисленные плохие практики.
public class DiceBox : Gtk.Box {
public DiceBox (Gtk.Orientation orientation, int spacing, Gtk.Application application) {
// set properties
this.orientation = orientation;
this.spacing = spacing;
// prepare variables
Gdk.PixbufAnimationIter imagepb = null;
TimeVal time = TimeVal ();
// attempt to get an image iterator; on failure, show a message
try {
imagepb = new Gdk.PixbufAnimation.from_file ("../img/d20.gif").get_iter (time);
} catch (Error e) {
stderr.printf ("PixbufAnimation creation error: %s\n", e.message);
var error_button = new Gtk.Button.with_label (@"Error: $(e.message)\nClick to exit");
error_button.clicked.connect(application.quit);
this.pack_start (error_button);
}
if (imagepb != null) {
// create pixbuf array
Gdk.Pixbuf[] d20buf = new Gdk.Pixbuf[20];
var frame_time = imagepb.get_delay_time () * 1000;
for (int i = 0; i < 20; i++) {
d20buf[i] = imagepb.get_pixbuf ();
time.add (frame_time);
if (!imagepb.advance (time)) {
stdout.printf("Frame skipped\n");
};
}
var frame = 0;
var image = new Gtk.Image.from_pixbuf (d20buf[frame]);
// for (int frame = 0; frame < 20; frame++) {
// this.pack_start (new Gtk.Image.from_pixbuf (d20buf[frame]));
// }
var button = new Gtk.Button.with_label ("Click to roll");
button.clicked.connect(() => {
frame++;
image.set_from_pixbuf (d20buf[frame]);
});
this.pack_start (image);
this.pack_end (button);
}
this.show_all ();
}
}
Я открыт для всех путей достижения своей цели, даже если это означает отказ от этого пути. Я просто не хочу иметь изображение с каждой стороны, если смогу помочь.