|
@@ -94,12 +94,7 @@ void sprite_cell_from_index(out int r, out int c, int num_cols, int index)
|
|
|
|
|
|
|
|
public class SpriteImportDialog : Gtk.Dialog
|
|
public class SpriteImportDialog : Gtk.Dialog
|
|
|
{
|
|
{
|
|
|
- public Cairo.Surface _checker;
|
|
|
|
|
public Gdk.Pixbuf _pixbuf;
|
|
public Gdk.Pixbuf _pixbuf;
|
|
|
- public Cairo.Pattern _pixbuf_pattern;
|
|
|
|
|
- public Gtk.DrawingArea _slices;
|
|
|
|
|
- public Gtk.ScrolledWindow _scrolled_window;
|
|
|
|
|
- public Gtk.DrawingArea _preview;
|
|
|
|
|
|
|
|
|
|
public EntryResourceBasename _unit_name;
|
|
public EntryResourceBasename _unit_name;
|
|
|
public Gtk.Label resolution;
|
|
public Gtk.Label resolution;
|
|
@@ -130,19 +125,16 @@ public class SpriteImportDialog : Gtk.Dialog
|
|
|
public EntryDouble mass;
|
|
public EntryDouble mass;
|
|
|
public Gtk.CheckButton lock_rotation_y;
|
|
public Gtk.CheckButton lock_rotation_y;
|
|
|
|
|
|
|
|
- public Gtk.Notebook _notebook;
|
|
|
|
|
-
|
|
|
|
|
public Gtk.Button _previous_frame;
|
|
public Gtk.Button _previous_frame;
|
|
|
public Gtk.Button _next_frame;
|
|
public Gtk.Button _next_frame;
|
|
|
public EntryDouble _current_frame;
|
|
public EntryDouble _current_frame;
|
|
|
public Gtk.Box _frame_selector_box;
|
|
public Gtk.Box _frame_selector_box;
|
|
|
public Gtk.Overlay _preview_overlay;
|
|
public Gtk.Overlay _preview_overlay;
|
|
|
- public Gtk.EventControllerScroll _preview_controller_scroll;
|
|
|
|
|
- public Gtk.EventControllerScroll _slices_controller_scroll;
|
|
|
|
|
|
|
+ public PixbufView _slices;
|
|
|
|
|
+ public PixbufView _preview;
|
|
|
|
|
+ public Gtk.ScrolledWindow _scrolled_window;
|
|
|
|
|
|
|
|
- public double _preview_zoom;
|
|
|
|
|
- public double _slices_zoom;
|
|
|
|
|
- public double _zoom_speed;
|
|
|
|
|
|
|
+ public Gtk.Notebook _notebook;
|
|
|
|
|
|
|
|
// Widgets
|
|
// Widgets
|
|
|
public SpriteImportDialog(string image_path, string unit_name)
|
|
public SpriteImportDialog(string image_path, string unit_name)
|
|
@@ -157,190 +149,6 @@ public class SpriteImportDialog : Gtk.Dialog
|
|
|
loge(e.message);
|
|
loge(e.message);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- _pixbuf_pattern = new Cairo.Pattern.for_surface(Gdk.cairo_surface_create_from_pixbuf(_pixbuf, 1, null));
|
|
|
|
|
- _pixbuf_pattern.set_filter(Cairo.Filter.NEAREST);
|
|
|
|
|
-
|
|
|
|
|
- // Create checkered pattern
|
|
|
|
|
- {
|
|
|
|
|
- int width = 16;
|
|
|
|
|
- int height = 16;
|
|
|
|
|
- _checker = new Cairo.ImageSurface(Cairo.Format.RGB24, width, height);
|
|
|
|
|
-
|
|
|
|
|
- Cairo.Context cr = new Cairo.Context(_checker);
|
|
|
|
|
- cr.set_source_rgb(0.9, 0.9, 0.9);
|
|
|
|
|
- cr.paint();
|
|
|
|
|
- cr.set_source_rgb(0.7, 0.7, 0.7);
|
|
|
|
|
- cr.rectangle(width / 2, 0, width / 2, height / 2);
|
|
|
|
|
- cr.rectangle(0, height / 2, width / 2, height / 2);
|
|
|
|
|
- cr.fill();
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- _slices = new Gtk.DrawingArea();
|
|
|
|
|
- _slices.set_size_request(_pixbuf.width, _pixbuf.height);
|
|
|
|
|
-
|
|
|
|
|
- _slices.draw.connect((cr) => {
|
|
|
|
|
- int allocated_width = _preview.get_allocated_width();
|
|
|
|
|
- int allocated_height = _preview.get_allocated_height();
|
|
|
|
|
- double original_line_width = cr.get_line_width();
|
|
|
|
|
-
|
|
|
|
|
- cr.set_source_rgb(0.1, 0.1, 0.1);
|
|
|
|
|
- cr.paint();
|
|
|
|
|
-
|
|
|
|
|
- cr.translate(allocated_width * 0.5, allocated_height * 0.5);
|
|
|
|
|
- cr.scale(_slices_zoom, _slices_zoom);
|
|
|
|
|
- cr.set_line_width(original_line_width / _slices_zoom);
|
|
|
|
|
- cr.translate(-_pixbuf.width * 0.5, -_pixbuf.height * 0.5);
|
|
|
|
|
-
|
|
|
|
|
- cr.save();
|
|
|
|
|
- cr.set_source_surface(_checker, 0, 0);
|
|
|
|
|
- Cairo.Pattern pattern = cr.get_source();
|
|
|
|
|
- pattern.set_filter(Cairo.Filter.NEAREST);
|
|
|
|
|
- pattern.set_extend(Cairo.Extend.REPEAT);
|
|
|
|
|
- cr.rectangle(0, 0, _pixbuf.width, _pixbuf.height);
|
|
|
|
|
- cr.clip();
|
|
|
|
|
- cr.paint();
|
|
|
|
|
- cr.restore();
|
|
|
|
|
-
|
|
|
|
|
- cr.set_source(_pixbuf_pattern);
|
|
|
|
|
- cr.paint();
|
|
|
|
|
-
|
|
|
|
|
- int num_v = (int)cells.value.y;
|
|
|
|
|
- int num_h = (int)cells.value.x;
|
|
|
|
|
-
|
|
|
|
|
- for (int h = 0; h < num_v; ++h) {
|
|
|
|
|
- for (int w = 0; w < num_h; ++w) {
|
|
|
|
|
- Vector2 sc = sprite_cell_xy(h
|
|
|
|
|
- , w
|
|
|
|
|
- , (int)offset.value.x
|
|
|
|
|
- , (int)offset.value.y
|
|
|
|
|
- , (int)cell.value.x
|
|
|
|
|
- , (int)cell.value.y
|
|
|
|
|
- , (int)spacing.value.x
|
|
|
|
|
- , (int)spacing.value.y
|
|
|
|
|
- );
|
|
|
|
|
-
|
|
|
|
|
- int x0 = (int)sc.x;
|
|
|
|
|
- int y0 = (int)sc.y;
|
|
|
|
|
- int x1 = x0 + (int)cell.value.x;
|
|
|
|
|
- int y1 = y0;
|
|
|
|
|
- int x2 = x1;
|
|
|
|
|
- int y2 = y0 + (int)cell.value.y;
|
|
|
|
|
- int x3 = x0;
|
|
|
|
|
- int y3 = y2;
|
|
|
|
|
- // https://www.cairographics.org/FAQ/#sharp_lines
|
|
|
|
|
- cr.move_to((double)x0, (double)y0 + 0.5);
|
|
|
|
|
- cr.line_to((double)x1, (double)y1 + 0.5);
|
|
|
|
|
- cr.move_to((double)x1 + 0.5, (double)y1);
|
|
|
|
|
- cr.line_to((double)x2 + 0.5, (double)y2);
|
|
|
|
|
- cr.move_to((double)x2, (double)y2 + 0.5);
|
|
|
|
|
- cr.line_to((double)x3, (double)y3 + 0.5);
|
|
|
|
|
- cr.move_to((double)x3 + 0.5, (double)y3);
|
|
|
|
|
- cr.line_to((double)x0 + 0.5, (double)y0);
|
|
|
|
|
-
|
|
|
|
|
- cr.set_source_rgba(0.9, 0.1, 0.1, 0.9);
|
|
|
|
|
- cr.stroke();
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- return Gdk.EVENT_STOP;
|
|
|
|
|
- });
|
|
|
|
|
-
|
|
|
|
|
- _scrolled_window = new Gtk.ScrolledWindow(null, null);
|
|
|
|
|
- _scrolled_window.min_content_width = 640;
|
|
|
|
|
- _scrolled_window.min_content_height = 640;
|
|
|
|
|
- _scrolled_window.add(_slices);
|
|
|
|
|
-
|
|
|
|
|
- _preview = new Gtk.DrawingArea();
|
|
|
|
|
- _preview.set_size_request(128, 128);
|
|
|
|
|
-
|
|
|
|
|
- _preview.draw.connect((cr) => {
|
|
|
|
|
- int allocated_width = _preview.get_allocated_width();
|
|
|
|
|
- int allocated_height = _preview.get_allocated_height();
|
|
|
|
|
- double original_line_width = cr.get_line_width();
|
|
|
|
|
-
|
|
|
|
|
- cr.set_source_rgb(0.1, 0.1, 0.1);
|
|
|
|
|
- cr.paint();
|
|
|
|
|
-
|
|
|
|
|
- int r, c;
|
|
|
|
|
- sprite_cell_from_index(out r, out c, (int)cells.value.x, (int)_current_frame.value);
|
|
|
|
|
-
|
|
|
|
|
- Vector2 sc = sprite_cell_xy(r
|
|
|
|
|
- , c
|
|
|
|
|
- , (int)offset.value.x
|
|
|
|
|
- , (int)offset.value.y
|
|
|
|
|
- , (int)cell.value.x
|
|
|
|
|
- , (int)cell.value.y
|
|
|
|
|
- , (int)spacing.value.x
|
|
|
|
|
- , (int)spacing.value.y
|
|
|
|
|
- );
|
|
|
|
|
-
|
|
|
|
|
- int x0 = (int)sc.x;
|
|
|
|
|
- int y0 = (int)sc.y;
|
|
|
|
|
-
|
|
|
|
|
- cr.translate(allocated_width * 0.5, allocated_height * 0.5);
|
|
|
|
|
- cr.scale(_preview_zoom, _preview_zoom);
|
|
|
|
|
- cr.set_line_width(original_line_width / _preview_zoom);
|
|
|
|
|
- cr.translate(-cell.value.x * 0.5, -cell.value.y * 0.5);
|
|
|
|
|
-
|
|
|
|
|
- // Draw checkered background.
|
|
|
|
|
- cr.save();
|
|
|
|
|
- cr.set_source_surface(_checker, 0, 0);
|
|
|
|
|
- Cairo.Pattern pattern = cr.get_source();
|
|
|
|
|
- pattern.set_filter(Cairo.Filter.NEAREST);
|
|
|
|
|
- pattern.set_extend(Cairo.Extend.REPEAT);
|
|
|
|
|
- cr.rectangle(0, 0, (int)cell.value.x, (int)cell.value.y);
|
|
|
|
|
- cr.clip();
|
|
|
|
|
- cr.new_path(); // path not consumed by clip()
|
|
|
|
|
- cr.paint();
|
|
|
|
|
- cr.restore();
|
|
|
|
|
-
|
|
|
|
|
- // Draw sprite frame.
|
|
|
|
|
- Gdk.Pixbuf frame_pixbuf = new Gdk.Pixbuf.subpixbuf(_pixbuf, x0, y0, (int)cell.value.x, (int)cell.value.y);
|
|
|
|
|
- Cairo.Surface frame_surface = Gdk.cairo_surface_create_from_pixbuf(frame_pixbuf, 1, null);
|
|
|
|
|
- Cairo.Pattern frame_pattern = new Cairo.Pattern.for_surface(frame_surface);
|
|
|
|
|
- frame_pattern.set_filter(Cairo.Filter.NEAREST);
|
|
|
|
|
- cr.save();
|
|
|
|
|
- cr.set_source(frame_pattern);
|
|
|
|
|
- cr.paint();
|
|
|
|
|
- cr.clip();
|
|
|
|
|
- cr.new_path(); // path not consumed by clip()
|
|
|
|
|
- cr.paint();
|
|
|
|
|
- cr.restore();
|
|
|
|
|
-
|
|
|
|
|
- // Draw collider.
|
|
|
|
|
- if (shape.visible_child_name == "square_collider") {
|
|
|
|
|
- cr.rectangle(collision_xy.value.x, collision_xy.value.y, collision_wh.value.x, collision_wh.value.y);
|
|
|
|
|
- cr.set_source_rgba(collider_color.red, collider_color.green, collider_color.blue, collider_color.alpha);
|
|
|
|
|
- cr.stroke();
|
|
|
|
|
- } else if (shape.visible_child_name == "circle_collider") {
|
|
|
|
|
- cr.arc(circle_collision_center.value.x, circle_collision_center.value.y, circle_collision_radius.value, 0, 2*Math.PI);
|
|
|
|
|
- cr.set_source_rgba(collider_color.red, collider_color.green, collider_color.blue, collider_color.alpha);
|
|
|
|
|
- cr.stroke();
|
|
|
|
|
- } else if (shape.visible_child_name == "capsule_collider") {
|
|
|
|
|
- double x = capsule_collision_center.value.x;
|
|
|
|
|
- double y = capsule_collision_center.value.y;
|
|
|
|
|
- double radius = capsule_collision_radius.value;
|
|
|
|
|
- double height = capsule_collision_height.value - 2*radius;
|
|
|
|
|
- cr.arc(x - height/2, y, radius, Math.PI/2, 3*Math.PI/2);
|
|
|
|
|
- cr.rectangle(x - height/2, y - radius, height, 2*radius);
|
|
|
|
|
- cr.arc(x + height/2, y, radius, 3*Math.PI/2, Math.PI/2);
|
|
|
|
|
- cr.set_source_rgba(collider_color.red, collider_color.green, collider_color.blue, collider_color.alpha);
|
|
|
|
|
- cr.stroke();
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- // Draw pivot.
|
|
|
|
|
- // Pivot is relative to the top-left corner of the cell.
|
|
|
|
|
- Vector2 pivot = sprite_cell_pivot_xy((int)cell.value.x
|
|
|
|
|
- , (int)cell.value.y
|
|
|
|
|
- , (int)pivot.active
|
|
|
|
|
- );
|
|
|
|
|
- cr.arc(pivot.x, pivot.y, 5.0, 0, 2*Math.PI);
|
|
|
|
|
- cr.set_source_rgba(0.1, 0.1, 0.9, 0.6);
|
|
|
|
|
- cr.fill();
|
|
|
|
|
-
|
|
|
|
|
- return Gdk.EVENT_STOP;
|
|
|
|
|
- });
|
|
|
|
|
-
|
|
|
|
|
_unit_name = new EntryResourceBasename(unit_name);
|
|
_unit_name = new EntryResourceBasename(unit_name);
|
|
|
|
|
|
|
|
resolution = new Gtk.Label(_pixbuf.width.to_string() + " × " + _pixbuf.height.to_string());
|
|
resolution = new Gtk.Label(_pixbuf.width.to_string() + " × " + _pixbuf.height.to_string());
|
|
@@ -382,6 +190,7 @@ public class SpriteImportDialog : Gtk.Dialog
|
|
|
_current_frame.set_max(cells.value.x * cells.value.y - 1);
|
|
_current_frame.set_max(cells.value.x * cells.value.y - 1);
|
|
|
|
|
|
|
|
_slices.queue_draw();
|
|
_slices.queue_draw();
|
|
|
|
|
+ set_preview_frame();
|
|
|
_preview.queue_draw();
|
|
_preview.queue_draw();
|
|
|
});
|
|
});
|
|
|
|
|
|
|
@@ -396,16 +205,19 @@ public class SpriteImportDialog : Gtk.Dialog
|
|
|
circle_collision_center.value = Vector2(cell.value.x/2.0, cell.value.y/2.0);
|
|
circle_collision_center.value = Vector2(cell.value.x/2.0, cell.value.y/2.0);
|
|
|
capsule_collision_center.value = Vector2(cell.value.x/2.0, cell.value.y/2.0);
|
|
capsule_collision_center.value = Vector2(cell.value.x/2.0, cell.value.y/2.0);
|
|
|
_slices.queue_draw();
|
|
_slices.queue_draw();
|
|
|
|
|
+ set_preview_frame();
|
|
|
_preview.queue_draw();
|
|
_preview.queue_draw();
|
|
|
});
|
|
});
|
|
|
|
|
|
|
|
offset.value_changed.connect(() => {
|
|
offset.value_changed.connect(() => {
|
|
|
_slices.queue_draw();
|
|
_slices.queue_draw();
|
|
|
|
|
+ set_preview_frame();
|
|
|
_preview.queue_draw();
|
|
_preview.queue_draw();
|
|
|
});
|
|
});
|
|
|
|
|
|
|
|
spacing.value_changed.connect(() => {
|
|
spacing.value_changed.connect(() => {
|
|
|
_slices.queue_draw();
|
|
_slices.queue_draw();
|
|
|
|
|
+ set_preview_frame();
|
|
|
_preview.queue_draw();
|
|
_preview.queue_draw();
|
|
|
});
|
|
});
|
|
|
|
|
|
|
@@ -532,13 +344,18 @@ public class SpriteImportDialog : Gtk.Dialog
|
|
|
_previous_frame = new Gtk.Button.from_icon_name("go-previous-symbolic", Gtk.IconSize.LARGE_TOOLBAR);
|
|
_previous_frame = new Gtk.Button.from_icon_name("go-previous-symbolic", Gtk.IconSize.LARGE_TOOLBAR);
|
|
|
_previous_frame.clicked.connect(() => {
|
|
_previous_frame.clicked.connect(() => {
|
|
|
_current_frame.value -= 1;
|
|
_current_frame.value -= 1;
|
|
|
|
|
+ set_preview_frame();
|
|
|
|
|
+ _preview.queue_draw();
|
|
|
});
|
|
});
|
|
|
_next_frame = new Gtk.Button.from_icon_name("go-next-symbolic", Gtk.IconSize.LARGE_TOOLBAR);
|
|
_next_frame = new Gtk.Button.from_icon_name("go-next-symbolic", Gtk.IconSize.LARGE_TOOLBAR);
|
|
|
_next_frame.clicked.connect(() => {
|
|
_next_frame.clicked.connect(() => {
|
|
|
_current_frame.value += 1;
|
|
_current_frame.value += 1;
|
|
|
|
|
+ set_preview_frame();
|
|
|
|
|
+ _preview.queue_draw();
|
|
|
});
|
|
});
|
|
|
_current_frame = new EntryDouble(0.0, 0.0, cells.value.x * cells.value.y - 1);
|
|
_current_frame = new EntryDouble(0.0, 0.0, cells.value.x * cells.value.y - 1);
|
|
|
_current_frame.value_changed.connect(() => {
|
|
_current_frame.value_changed.connect(() => {
|
|
|
|
|
+ set_preview_frame();
|
|
|
_preview.queue_draw();
|
|
_preview.queue_draw();
|
|
|
});
|
|
});
|
|
|
_frame_selector_box = new Gtk.Box(Gtk.Orientation.HORIZONTAL, 0);
|
|
_frame_selector_box = new Gtk.Box(Gtk.Orientation.HORIZONTAL, 0);
|
|
@@ -549,30 +366,124 @@ public class SpriteImportDialog : Gtk.Dialog
|
|
|
_frame_selector_box.pack_start(_previous_frame);
|
|
_frame_selector_box.pack_start(_previous_frame);
|
|
|
_frame_selector_box.pack_start(_current_frame);
|
|
_frame_selector_box.pack_start(_current_frame);
|
|
|
_frame_selector_box.pack_end(_next_frame);
|
|
_frame_selector_box.pack_end(_next_frame);
|
|
|
|
|
+
|
|
|
|
|
+ _slices = new PixbufView();
|
|
|
|
|
+ _slices.set_size_request(_pixbuf.width, _pixbuf.height);
|
|
|
|
|
+ _slices.set_pixbuf(_pixbuf);
|
|
|
|
|
+
|
|
|
|
|
+ _slices.draw.connect((cr) => {
|
|
|
|
|
+ int allocated_width = _preview.get_allocated_width();
|
|
|
|
|
+ int allocated_height = _preview.get_allocated_height();
|
|
|
|
|
+ double original_line_width = cr.get_line_width();
|
|
|
|
|
+
|
|
|
|
|
+ cr.translate(allocated_width * 0.5, allocated_height * 0.5);
|
|
|
|
|
+ cr.scale(_slices._zoom, _slices._zoom);
|
|
|
|
|
+ cr.set_line_width(original_line_width / _slices._zoom);
|
|
|
|
|
+ cr.translate(-_pixbuf.width * 0.5, -_pixbuf.height * 0.5);
|
|
|
|
|
+
|
|
|
|
|
+ int num_v = (int)cells.value.y;
|
|
|
|
|
+ int num_h = (int)cells.value.x;
|
|
|
|
|
+
|
|
|
|
|
+ for (int h = 0; h < num_v; ++h) {
|
|
|
|
|
+ for (int w = 0; w < num_h; ++w) {
|
|
|
|
|
+ Vector2 sc = sprite_cell_xy(h
|
|
|
|
|
+ , w
|
|
|
|
|
+ , (int)offset.value.x
|
|
|
|
|
+ , (int)offset.value.y
|
|
|
|
|
+ , (int)cell.value.x
|
|
|
|
|
+ , (int)cell.value.y
|
|
|
|
|
+ , (int)spacing.value.x
|
|
|
|
|
+ , (int)spacing.value.y
|
|
|
|
|
+ );
|
|
|
|
|
+
|
|
|
|
|
+ int x0 = (int)sc.x;
|
|
|
|
|
+ int y0 = (int)sc.y;
|
|
|
|
|
+ int x1 = x0 + (int)cell.value.x;
|
|
|
|
|
+ int y1 = y0;
|
|
|
|
|
+ int x2 = x1;
|
|
|
|
|
+ int y2 = y0 + (int)cell.value.y;
|
|
|
|
|
+ int x3 = x0;
|
|
|
|
|
+ int y3 = y2;
|
|
|
|
|
+ // https://www.cairographics.org/FAQ/#sharp_lines
|
|
|
|
|
+ cr.move_to((double)x0, (double)y0 + 0.5);
|
|
|
|
|
+ cr.line_to((double)x1, (double)y1 + 0.5);
|
|
|
|
|
+ cr.move_to((double)x1 + 0.5, (double)y1);
|
|
|
|
|
+ cr.line_to((double)x2 + 0.5, (double)y2);
|
|
|
|
|
+ cr.move_to((double)x2, (double)y2 + 0.5);
|
|
|
|
|
+ cr.line_to((double)x3, (double)y3 + 0.5);
|
|
|
|
|
+ cr.move_to((double)x3 + 0.5, (double)y3);
|
|
|
|
|
+ cr.line_to((double)x0 + 0.5, (double)y0);
|
|
|
|
|
+
|
|
|
|
|
+ cr.set_source_rgba(0.9, 0.1, 0.1, 0.9);
|
|
|
|
|
+ cr.stroke();
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return Gdk.EVENT_STOP;
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
|
|
+ _preview = new PixbufView();
|
|
|
|
|
+ _preview._zoom = 4.0;
|
|
|
|
|
+ _preview.set_size_request(128, 128);
|
|
|
|
|
+ set_preview_frame();
|
|
|
|
|
+
|
|
|
|
|
+ _preview.draw.connect((cr) => {
|
|
|
|
|
+ int allocated_width = _preview.get_allocated_width();
|
|
|
|
|
+ int allocated_height = _preview.get_allocated_height();
|
|
|
|
|
+ double original_line_width = cr.get_line_width();
|
|
|
|
|
+
|
|
|
|
|
+ cr.translate(allocated_width * 0.5, allocated_height * 0.5);
|
|
|
|
|
+ cr.scale(_preview._zoom, _preview._zoom);
|
|
|
|
|
+ cr.set_line_width(original_line_width / _preview._zoom);
|
|
|
|
|
+ cr.translate(-cell.value.x * 0.5, -cell.value.y * 0.5);
|
|
|
|
|
+
|
|
|
|
|
+ // Draw collider.
|
|
|
|
|
+ if (shape.visible_child_name == "square_collider") {
|
|
|
|
|
+ cr.rectangle(collision_xy.value.x, collision_xy.value.y, collision_wh.value.x, collision_wh.value.y);
|
|
|
|
|
+ cr.set_source_rgba(collider_color.red, collider_color.green, collider_color.blue, collider_color.alpha);
|
|
|
|
|
+ cr.stroke();
|
|
|
|
|
+ } else if (shape.visible_child_name == "circle_collider") {
|
|
|
|
|
+ cr.arc(circle_collision_center.value.x, circle_collision_center.value.y, circle_collision_radius.value, 0, 2*Math.PI);
|
|
|
|
|
+ cr.set_source_rgba(collider_color.red, collider_color.green, collider_color.blue, collider_color.alpha);
|
|
|
|
|
+ cr.stroke();
|
|
|
|
|
+ } else if (shape.visible_child_name == "capsule_collider") {
|
|
|
|
|
+ double x = capsule_collision_center.value.x;
|
|
|
|
|
+ double y = capsule_collision_center.value.y;
|
|
|
|
|
+ double radius = capsule_collision_radius.value;
|
|
|
|
|
+ double height = capsule_collision_height.value - 2*radius;
|
|
|
|
|
+ cr.arc(x - height/2, y, radius, Math.PI/2, 3*Math.PI/2);
|
|
|
|
|
+ cr.rectangle(x - height/2, y - radius, height, 2*radius);
|
|
|
|
|
+ cr.arc(x + height/2, y, radius, 3*Math.PI/2, Math.PI/2);
|
|
|
|
|
+ cr.set_source_rgba(collider_color.red, collider_color.green, collider_color.blue, collider_color.alpha);
|
|
|
|
|
+ cr.stroke();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // Draw pivot.
|
|
|
|
|
+ // Pivot is relative to the top-left corner of the cell.
|
|
|
|
|
+ Vector2 pivot = sprite_cell_pivot_xy((int)cell.value.x
|
|
|
|
|
+ , (int)cell.value.y
|
|
|
|
|
+ , (int)pivot.active
|
|
|
|
|
+ );
|
|
|
|
|
+ cr.arc(pivot.x, pivot.y, 5.0, 0, 2*Math.PI);
|
|
|
|
|
+ cr.set_source_rgba(0.1, 0.1, 0.9, 0.6);
|
|
|
|
|
+ cr.fill();
|
|
|
|
|
+
|
|
|
|
|
+ return Gdk.EVENT_STOP;
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
_preview_overlay = new Gtk.Overlay();
|
|
_preview_overlay = new Gtk.Overlay();
|
|
|
_preview_overlay.add(_preview);
|
|
_preview_overlay.add(_preview);
|
|
|
_preview_overlay.add_overlay(_frame_selector_box);
|
|
_preview_overlay.add_overlay(_frame_selector_box);
|
|
|
|
|
|
|
|
|
|
+ _scrolled_window = new Gtk.ScrolledWindow(null, null);
|
|
|
|
|
+ _scrolled_window.min_content_width = 640;
|
|
|
|
|
+ _scrolled_window.min_content_height = 640;
|
|
|
|
|
+ _scrolled_window.add(_slices);
|
|
|
|
|
+
|
|
|
_notebook = new Gtk.Notebook();
|
|
_notebook = new Gtk.Notebook();
|
|
|
_notebook.append_page(_preview_overlay, new Gtk.Label("Preview"));
|
|
_notebook.append_page(_preview_overlay, new Gtk.Label("Preview"));
|
|
|
_notebook.append_page(_scrolled_window, new Gtk.Label("Slices"));
|
|
_notebook.append_page(_scrolled_window, new Gtk.Label("Slices"));
|
|
|
|
|
|
|
|
- _preview_controller_scroll = new Gtk.EventControllerScroll(_preview, Gtk.EventControllerScrollFlags.VERTICAL);
|
|
|
|
|
- _preview_controller_scroll.scroll.connect((dx, dy) => {
|
|
|
|
|
- _preview_zoom = double.min(10.0, double.max(0.25, _preview_zoom - dy * _zoom_speed));
|
|
|
|
|
- _preview.queue_draw();
|
|
|
|
|
- });
|
|
|
|
|
-
|
|
|
|
|
- _slices_controller_scroll = new Gtk.EventControllerScroll(_slices, Gtk.EventControllerScrollFlags.VERTICAL);
|
|
|
|
|
- _slices_controller_scroll.scroll.connect((dx, dy) => {
|
|
|
|
|
- _slices_zoom = double.min(10.0, double.max(0.25, _slices_zoom - dy * _zoom_speed));
|
|
|
|
|
- _slices.queue_draw();
|
|
|
|
|
- });
|
|
|
|
|
-
|
|
|
|
|
- _preview_zoom = 4.0;
|
|
|
|
|
- _slices_zoom = 1.0;
|
|
|
|
|
- _zoom_speed = 0.2;
|
|
|
|
|
-
|
|
|
|
|
Gtk.Paned pane;
|
|
Gtk.Paned pane;
|
|
|
pane = new Gtk.Paned(Gtk.Orientation.HORIZONTAL);
|
|
pane = new Gtk.Paned(Gtk.Orientation.HORIZONTAL);
|
|
|
pane.pack1(_notebook, false, false);
|
|
pane.pack1(_notebook, false, false);
|
|
@@ -603,6 +514,37 @@ public class SpriteImportDialog : Gtk.Dialog
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ public void set_preview_frame()
|
|
|
|
|
+ {
|
|
|
|
|
+ assert(cells != null);
|
|
|
|
|
+ assert(_current_frame != null);
|
|
|
|
|
+ assert(offset != null);
|
|
|
|
|
+ assert(cell != null);
|
|
|
|
|
+ assert(spacing != null);
|
|
|
|
|
+
|
|
|
|
|
+ int r, c;
|
|
|
|
|
+ sprite_cell_from_index(out r, out c, (int)cells.value.x, (int)_current_frame.value);
|
|
|
|
|
+
|
|
|
|
|
+ Vector2 sc = sprite_cell_xy(r
|
|
|
|
|
+ , c
|
|
|
|
|
+ , (int)offset.value.x
|
|
|
|
|
+ , (int)offset.value.y
|
|
|
|
|
+ , (int)cell.value.x
|
|
|
|
|
+ , (int)cell.value.y
|
|
|
|
|
+ , (int)spacing.value.x
|
|
|
|
|
+ , (int)spacing.value.y
|
|
|
|
|
+ );
|
|
|
|
|
+
|
|
|
|
|
+ Gdk.Pixbuf frame_pixbuf = new Gdk.Pixbuf.subpixbuf(_pixbuf
|
|
|
|
|
+ , (int)sc.x
|
|
|
|
|
+ , (int)sc.y
|
|
|
|
|
+ , (int)cell.value.x
|
|
|
|
|
+ , (int)cell.value.y
|
|
|
|
|
+ );
|
|
|
|
|
+
|
|
|
|
|
+ _preview.set_pixbuf(frame_pixbuf);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
public void load(Hashtable importer_settings)
|
|
public void load(Hashtable importer_settings)
|
|
|
{
|
|
{
|
|
|
// Load settings
|
|
// Load settings
|