Add new `CanvasItem` snapping option
This commit is contained in:
parent
bf53956289
commit
a6ea944631
|
@ -604,6 +604,9 @@
|
||||||
<member name="show_behind_parent" type="bool" setter="set_draw_behind_parent" getter="is_draw_behind_parent_enabled" default="false">
|
<member name="show_behind_parent" type="bool" setter="set_draw_behind_parent" getter="is_draw_behind_parent_enabled" default="false">
|
||||||
If [code]true[/code], the object draws behind its parent.
|
If [code]true[/code], the object draws behind its parent.
|
||||||
</member>
|
</member>
|
||||||
|
<member name="snap_to_pixel" type="int" setter="set_snap_to_pixel" getter="get_snap_to_pixel" enum="CanvasItem.SnapToPixel" default="0">
|
||||||
|
The snapping to pixel mode to use on this [CanvasItem].
|
||||||
|
</member>
|
||||||
<member name="texture_filter" type="int" setter="set_texture_filter" getter="get_texture_filter" enum="CanvasItem.TextureFilter" default="0">
|
<member name="texture_filter" type="int" setter="set_texture_filter" getter="get_texture_filter" enum="CanvasItem.TextureFilter" default="0">
|
||||||
The texture filtering mode to use on this [CanvasItem].
|
The texture filtering mode to use on this [CanvasItem].
|
||||||
</member>
|
</member>
|
||||||
|
@ -736,5 +739,17 @@
|
||||||
<constant name="CLIP_CHILDREN_MAX" value="3" enum="ClipChildrenMode">
|
<constant name="CLIP_CHILDREN_MAX" value="3" enum="ClipChildrenMode">
|
||||||
Represents the size of the [enum ClipChildrenMode] enum.
|
Represents the size of the [enum ClipChildrenMode] enum.
|
||||||
</constant>
|
</constant>
|
||||||
|
<constant name="SNAP_TO_PIXEL_PARENT_NODE" value="0" enum="SnapToPixel">
|
||||||
|
The [CanvasItem] will inherit the snapping mode from its parent.
|
||||||
|
</constant>
|
||||||
|
<constant name="SNAP_TO_PIXEL_DISABLED" value="1" enum="SnapToPixel">
|
||||||
|
The [CanvasItem] will not snap.
|
||||||
|
</constant>
|
||||||
|
<constant name="SNAP_TO_PIXEL_ENABLED" value="2" enum="SnapToPixel">
|
||||||
|
The [CanvasItem] will snap.
|
||||||
|
</constant>
|
||||||
|
<constant name="SNAP_TO_PIXEL_MAX" value="3" enum="SnapToPixel">
|
||||||
|
Represents the size of the [enum SnapToPixel] enum.
|
||||||
|
</constant>
|
||||||
</constants>
|
</constants>
|
||||||
</class>
|
</class>
|
||||||
|
|
|
@ -328,6 +328,7 @@ void CanvasItem::_notification(int p_what) {
|
||||||
|
|
||||||
_update_texture_filter_changed(false);
|
_update_texture_filter_changed(false);
|
||||||
_update_texture_repeat_changed(false);
|
_update_texture_repeat_changed(false);
|
||||||
|
_update_snap_to_pixel_changed(false);
|
||||||
|
|
||||||
if (!block_transform_notify && !xform_change.in_list()) {
|
if (!block_transform_notify && !xform_change.in_list()) {
|
||||||
get_tree()->xform_change_list.add(&xform_change);
|
get_tree()->xform_change_list.add(&xform_change);
|
||||||
|
@ -1270,6 +1271,9 @@ void CanvasItem::_bind_methods() {
|
||||||
ClassDB::bind_method(D_METHOD("set_clip_children_mode", "mode"), &CanvasItem::set_clip_children_mode);
|
ClassDB::bind_method(D_METHOD("set_clip_children_mode", "mode"), &CanvasItem::set_clip_children_mode);
|
||||||
ClassDB::bind_method(D_METHOD("get_clip_children_mode"), &CanvasItem::get_clip_children_mode);
|
ClassDB::bind_method(D_METHOD("get_clip_children_mode"), &CanvasItem::get_clip_children_mode);
|
||||||
|
|
||||||
|
ClassDB::bind_method(D_METHOD("set_snap_to_pixel", "snap"), &CanvasItem::set_snap_to_pixel);
|
||||||
|
ClassDB::bind_method(D_METHOD("get_snap_to_pixel"), &CanvasItem::get_snap_to_pixel);
|
||||||
|
|
||||||
GDVIRTUAL_BIND(_draw);
|
GDVIRTUAL_BIND(_draw);
|
||||||
|
|
||||||
ADD_GROUP("Visibility", "");
|
ADD_GROUP("Visibility", "");
|
||||||
|
@ -1294,6 +1298,10 @@ void CanvasItem::_bind_methods() {
|
||||||
ADD_GROUP("Material", "");
|
ADD_GROUP("Material", "");
|
||||||
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "material", PROPERTY_HINT_RESOURCE_TYPE, "CanvasItemMaterial,ShaderMaterial"), "set_material", "get_material");
|
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "material", PROPERTY_HINT_RESOURCE_TYPE, "CanvasItemMaterial,ShaderMaterial"), "set_material", "get_material");
|
||||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "use_parent_material"), "set_use_parent_material", "get_use_parent_material");
|
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "use_parent_material"), "set_use_parent_material", "get_use_parent_material");
|
||||||
|
|
||||||
|
ADD_GROUP("Snap", "");
|
||||||
|
ADD_PROPERTY(PropertyInfo(Variant::INT, "snap_to_pixel", PROPERTY_HINT_ENUM, "Inherit,Disabled,Enabled"), "set_snap_to_pixel", "get_snap_to_pixel");
|
||||||
|
|
||||||
// ADD_PROPERTY(PropertyInfo(Variant::BOOL,"transform/notify"),"set_transform_notify","is_transform_notify_enabled");
|
// ADD_PROPERTY(PropertyInfo(Variant::BOOL,"transform/notify"),"set_transform_notify","is_transform_notify_enabled");
|
||||||
|
|
||||||
ADD_SIGNAL(MethodInfo("draw"));
|
ADD_SIGNAL(MethodInfo("draw"));
|
||||||
|
@ -1328,6 +1336,11 @@ void CanvasItem::_bind_methods() {
|
||||||
BIND_ENUM_CONSTANT(CLIP_CHILDREN_ONLY);
|
BIND_ENUM_CONSTANT(CLIP_CHILDREN_ONLY);
|
||||||
BIND_ENUM_CONSTANT(CLIP_CHILDREN_AND_DRAW);
|
BIND_ENUM_CONSTANT(CLIP_CHILDREN_AND_DRAW);
|
||||||
BIND_ENUM_CONSTANT(CLIP_CHILDREN_MAX);
|
BIND_ENUM_CONSTANT(CLIP_CHILDREN_MAX);
|
||||||
|
|
||||||
|
BIND_ENUM_CONSTANT(SNAP_TO_PIXEL_PARENT_NODE);
|
||||||
|
BIND_ENUM_CONSTANT(SNAP_TO_PIXEL_DISABLED);
|
||||||
|
BIND_ENUM_CONSTANT(SNAP_TO_PIXEL_ENABLED);
|
||||||
|
BIND_ENUM_CONSTANT(SNAP_TO_PIXEL_MAX);
|
||||||
}
|
}
|
||||||
|
|
||||||
Transform2D CanvasItem::get_canvas_transform() const {
|
Transform2D CanvasItem::get_canvas_transform() const {
|
||||||
|
@ -1565,6 +1578,62 @@ CanvasItem::TextureRepeat CanvasItem::get_texture_repeat_in_tree() const {
|
||||||
return (TextureRepeat)texture_repeat_cache;
|
return (TextureRepeat)texture_repeat_cache;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CanvasItem::_refresh_snap_to_pixel_cache() const {
|
||||||
|
if (!is_inside_tree()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (snap_to_pixel == SNAP_TO_PIXEL_PARENT_NODE) {
|
||||||
|
CanvasItem *parent_item = get_parent_item();
|
||||||
|
if (parent_item) {
|
||||||
|
snap_to_pixel_cache = parent_item->snap_to_pixel_cache;
|
||||||
|
} else {
|
||||||
|
snap_to_pixel_cache = RS::CANVAS_ITEM_SNAP_TO_PIXEL_DEFAULT;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
snap_to_pixel_cache = RS::CanvasItemSnapToPixel(snap_to_pixel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CanvasItem::_update_self_snap_to_pixel(RS::CanvasItemSnapToPixel p_snap) {
|
||||||
|
RS::get_singleton()->canvas_item_set_snap_to_pixel(get_canvas_item(), p_snap);
|
||||||
|
queue_redraw();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CanvasItem::_update_snap_to_pixel_changed(bool p_propagate) {
|
||||||
|
if (!is_inside_tree()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
_refresh_snap_to_pixel_cache();
|
||||||
|
_update_self_snap_to_pixel(snap_to_pixel_cache);
|
||||||
|
|
||||||
|
if (p_propagate) {
|
||||||
|
for (CanvasItem *E : children_items) {
|
||||||
|
if (!E->top_level && E->snap_to_pixel == SNAP_TO_PIXEL_PARENT_NODE) {
|
||||||
|
E->_update_snap_to_pixel_changed(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CanvasItem::set_snap_to_pixel(SnapToPixel p_snap_to_pixel) {
|
||||||
|
ERR_THREAD_GUARD;
|
||||||
|
ERR_FAIL_COND(p_snap_to_pixel >= SNAP_TO_PIXEL_MAX);
|
||||||
|
|
||||||
|
if (snap_to_pixel == p_snap_to_pixel) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
snap_to_pixel = p_snap_to_pixel;
|
||||||
|
_update_snap_to_pixel_changed(true);
|
||||||
|
notify_property_list_changed();
|
||||||
|
}
|
||||||
|
|
||||||
|
CanvasItem::SnapToPixel CanvasItem::get_snap_to_pixel() const {
|
||||||
|
ERR_READ_THREAD_GUARD_V(SNAP_TO_PIXEL_DISABLED);
|
||||||
|
return snap_to_pixel;
|
||||||
|
}
|
||||||
|
|
||||||
CanvasItem::CanvasItem() :
|
CanvasItem::CanvasItem() :
|
||||||
xform_change(this) {
|
xform_change(this) {
|
||||||
canvas_item = RenderingServer::get_singleton()->canvas_item_create();
|
canvas_item = RenderingServer::get_singleton()->canvas_item_create();
|
||||||
|
|
|
@ -73,6 +73,13 @@ public:
|
||||||
CLIP_CHILDREN_MAX,
|
CLIP_CHILDREN_MAX,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum SnapToPixel {
|
||||||
|
SNAP_TO_PIXEL_PARENT_NODE,
|
||||||
|
SNAP_TO_PIXEL_DISABLED,
|
||||||
|
SNAP_TO_PIXEL_ENABLED,
|
||||||
|
SNAP_TO_PIXEL_MAX,
|
||||||
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
mutable SelfList<Node>
|
mutable SelfList<Node>
|
||||||
xform_change;
|
xform_change;
|
||||||
|
@ -112,8 +119,10 @@ private:
|
||||||
|
|
||||||
mutable RS::CanvasItemTextureFilter texture_filter_cache = RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR;
|
mutable RS::CanvasItemTextureFilter texture_filter_cache = RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR;
|
||||||
mutable RS::CanvasItemTextureRepeat texture_repeat_cache = RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED;
|
mutable RS::CanvasItemTextureRepeat texture_repeat_cache = RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED;
|
||||||
|
mutable RS::CanvasItemSnapToPixel snap_to_pixel_cache = RS::CANVAS_ITEM_SNAP_TO_PIXEL_DISABLED;
|
||||||
TextureFilter texture_filter = TEXTURE_FILTER_PARENT_NODE;
|
TextureFilter texture_filter = TEXTURE_FILTER_PARENT_NODE;
|
||||||
TextureRepeat texture_repeat = TEXTURE_REPEAT_PARENT_NODE;
|
TextureRepeat texture_repeat = TEXTURE_REPEAT_PARENT_NODE;
|
||||||
|
SnapToPixel snap_to_pixel = SNAP_TO_PIXEL_PARENT_NODE;
|
||||||
|
|
||||||
Ref<Material> material;
|
Ref<Material> material;
|
||||||
|
|
||||||
|
@ -148,12 +157,15 @@ private:
|
||||||
void _update_texture_repeat_changed(bool p_propagate);
|
void _update_texture_repeat_changed(bool p_propagate);
|
||||||
void _refresh_texture_filter_cache() const;
|
void _refresh_texture_filter_cache() const;
|
||||||
void _update_texture_filter_changed(bool p_propagate);
|
void _update_texture_filter_changed(bool p_propagate);
|
||||||
|
void _refresh_snap_to_pixel_cache() const;
|
||||||
|
void _update_snap_to_pixel_changed(bool p_propagate);
|
||||||
|
|
||||||
void _notify_transform_deferred();
|
void _notify_transform_deferred();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void _update_self_texture_repeat(RS::CanvasItemTextureRepeat p_texture_repeat);
|
virtual void _update_self_texture_repeat(RS::CanvasItemTextureRepeat p_texture_repeat);
|
||||||
virtual void _update_self_texture_filter(RS::CanvasItemTextureFilter p_texture_filter);
|
virtual void _update_self_texture_filter(RS::CanvasItemTextureFilter p_texture_filter);
|
||||||
|
virtual void _update_self_snap_to_pixel(RS::CanvasItemSnapToPixel p_snap);
|
||||||
|
|
||||||
_FORCE_INLINE_ void _notify_transform() {
|
_FORCE_INLINE_ void _notify_transform() {
|
||||||
_notify_transform(this);
|
_notify_transform(this);
|
||||||
|
@ -380,6 +392,9 @@ public:
|
||||||
int get_canvas_layer() const;
|
int get_canvas_layer() const;
|
||||||
CanvasLayer *get_canvas_layer_node() const;
|
CanvasLayer *get_canvas_layer_node() const;
|
||||||
|
|
||||||
|
virtual void set_snap_to_pixel(SnapToPixel p_snap_to_pixel);
|
||||||
|
SnapToPixel get_snap_to_pixel() const;
|
||||||
|
|
||||||
CanvasItem();
|
CanvasItem();
|
||||||
~CanvasItem();
|
~CanvasItem();
|
||||||
};
|
};
|
||||||
|
@ -387,6 +402,7 @@ public:
|
||||||
VARIANT_ENUM_CAST(CanvasItem::TextureFilter)
|
VARIANT_ENUM_CAST(CanvasItem::TextureFilter)
|
||||||
VARIANT_ENUM_CAST(CanvasItem::TextureRepeat)
|
VARIANT_ENUM_CAST(CanvasItem::TextureRepeat)
|
||||||
VARIANT_ENUM_CAST(CanvasItem::ClipChildrenMode)
|
VARIANT_ENUM_CAST(CanvasItem::ClipChildrenMode)
|
||||||
|
VARIANT_ENUM_CAST(CanvasItem::SnapToPixel)
|
||||||
|
|
||||||
class CanvasTexture : public Texture2D {
|
class CanvasTexture : public Texture2D {
|
||||||
GDCLASS(CanvasTexture, Texture2D);
|
GDCLASS(CanvasTexture, Texture2D);
|
||||||
|
|
|
@ -285,7 +285,7 @@ void RendererCanvasCull::_cull_canvas_item(Item *p_canvas_item, const Transform2
|
||||||
rect.position -= repeat_size / scale * (repeat_times / 2);
|
rect.position -= repeat_size / scale * (repeat_times / 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (snapping_2d_transforms_to_pixel) {
|
if ((p_canvas_item->snap_to_pixel == RS::CANVAS_ITEM_SNAP_TO_PIXEL_DEFAULT && snapping_2d_transforms_to_pixel) || (p_canvas_item->snap_to_pixel == RS::CANVAS_ITEM_SNAP_TO_PIXEL_ENABLED)) {
|
||||||
Size2 scale = final_xform.get_scale().snappedf(0.0001);
|
Size2 scale = final_xform.get_scale().snappedf(0.0001);
|
||||||
Point2 abs_scaled_position = (rect.position * scale).abs();
|
Point2 abs_scaled_position = (rect.position * scale).abs();
|
||||||
Point2 odd_sized_correction = Point2(
|
Point2 odd_sized_correction = Point2(
|
||||||
|
@ -2327,6 +2327,12 @@ void RendererCanvasCull::canvas_item_set_default_texture_repeat(RID p_item, RS::
|
||||||
ci->texture_repeat = p_repeat;
|
ci->texture_repeat = p_repeat;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RendererCanvasCull::canvas_item_set_snap_to_pixel(RID p_item, RS::CanvasItemSnapToPixel p_snap) {
|
||||||
|
Item *ci = canvas_item_owner.get_or_null(p_item);
|
||||||
|
ERR_FAIL_NULL(ci);
|
||||||
|
ci->snap_to_pixel = p_snap;
|
||||||
|
}
|
||||||
|
|
||||||
void RendererCanvasCull::update_visibility_notifiers() {
|
void RendererCanvasCull::update_visibility_notifiers() {
|
||||||
SelfList<Item::VisibilityNotifierData> *E = visibility_notifier_list.first();
|
SelfList<Item::VisibilityNotifierData> *E = visibility_notifier_list.first();
|
||||||
while (E) {
|
while (E) {
|
||||||
|
|
|
@ -339,6 +339,7 @@ public:
|
||||||
|
|
||||||
void canvas_item_set_default_texture_filter(RID p_item, RS::CanvasItemTextureFilter p_filter);
|
void canvas_item_set_default_texture_filter(RID p_item, RS::CanvasItemTextureFilter p_filter);
|
||||||
void canvas_item_set_default_texture_repeat(RID p_item, RS::CanvasItemTextureRepeat p_repeat);
|
void canvas_item_set_default_texture_repeat(RID p_item, RS::CanvasItemTextureRepeat p_repeat);
|
||||||
|
void canvas_item_set_snap_to_pixel(RID p_item, RS::CanvasItemSnapToPixel p_snap);
|
||||||
|
|
||||||
void update_visibility_notifiers();
|
void update_visibility_notifiers();
|
||||||
|
|
||||||
|
|
|
@ -458,6 +458,7 @@ public:
|
||||||
|
|
||||||
RS::CanvasItemTextureFilter texture_filter;
|
RS::CanvasItemTextureFilter texture_filter;
|
||||||
RS::CanvasItemTextureRepeat texture_repeat;
|
RS::CanvasItemTextureRepeat texture_repeat;
|
||||||
|
RS::CanvasItemSnapToPixel snap_to_pixel;
|
||||||
|
|
||||||
Item() {
|
Item() {
|
||||||
commands = nullptr;
|
commands = nullptr;
|
||||||
|
|
|
@ -883,6 +883,8 @@ public:
|
||||||
|
|
||||||
FUNC2(canvas_item_set_draw_behind_parent, RID, bool)
|
FUNC2(canvas_item_set_draw_behind_parent, RID, bool)
|
||||||
|
|
||||||
|
FUNC2(canvas_item_set_snap_to_pixel, RID, CanvasItemSnapToPixel)
|
||||||
|
|
||||||
FUNC6(canvas_item_add_line, RID, const Point2 &, const Point2 &, const Color &, float, bool)
|
FUNC6(canvas_item_add_line, RID, const Point2 &, const Point2 &, const Color &, float, bool)
|
||||||
FUNC5(canvas_item_add_polyline, RID, const Vector<Point2> &, const Vector<Color> &, float, bool)
|
FUNC5(canvas_item_add_polyline, RID, const Vector<Point2> &, const Vector<Color> &, float, bool)
|
||||||
FUNC5(canvas_item_add_multiline, RID, const Vector<Point2> &, const Vector<Color> &, float, bool)
|
FUNC5(canvas_item_add_multiline, RID, const Vector<Point2> &, const Vector<Color> &, float, bool)
|
||||||
|
|
|
@ -860,6 +860,13 @@ public:
|
||||||
CANVAS_ITEM_TEXTURE_REPEAT_MAX,
|
CANVAS_ITEM_TEXTURE_REPEAT_MAX,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum CanvasItemSnapToPixel {
|
||||||
|
CANVAS_ITEM_SNAP_TO_PIXEL_DEFAULT,
|
||||||
|
CANVAS_ITEM_SNAP_TO_PIXEL_DISABLED,
|
||||||
|
CANVAS_ITEM_SNAP_TO_PIXEL_ENABLED,
|
||||||
|
CANVAS_ITEM_SNAP_TO_PIXEL_MAX,
|
||||||
|
};
|
||||||
|
|
||||||
virtual RID viewport_create() = 0;
|
virtual RID viewport_create() = 0;
|
||||||
|
|
||||||
enum ViewportScaling3DMode {
|
enum ViewportScaling3DMode {
|
||||||
|
@ -1451,6 +1458,8 @@ public:
|
||||||
|
|
||||||
virtual void canvas_item_set_draw_behind_parent(RID p_item, bool p_enable) = 0;
|
virtual void canvas_item_set_draw_behind_parent(RID p_item, bool p_enable) = 0;
|
||||||
|
|
||||||
|
virtual void canvas_item_set_snap_to_pixel(RID p_item, CanvasItemSnapToPixel p_snap) = 0;
|
||||||
|
|
||||||
enum NinePatchAxisMode {
|
enum NinePatchAxisMode {
|
||||||
NINE_PATCH_STRETCH,
|
NINE_PATCH_STRETCH,
|
||||||
NINE_PATCH_TILE,
|
NINE_PATCH_TILE,
|
||||||
|
|
Loading…
Reference in New Issue