Add new `CanvasItem` snapping option
This commit is contained in:
parent
8e36f98ea5
commit
2b9942a044
|
@ -604,6 +604,9 @@
|
|||
<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.
|
||||
</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">
|
||||
The texture filtering mode to use on this [CanvasItem].
|
||||
</member>
|
||||
|
@ -736,5 +739,17 @@
|
|||
<constant name="CLIP_CHILDREN_MAX" value="3" enum="ClipChildrenMode">
|
||||
Represents the size of the [enum ClipChildrenMode] enum.
|
||||
</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>
|
||||
</class>
|
||||
|
|
|
@ -328,6 +328,7 @@ void CanvasItem::_notification(int p_what) {
|
|||
|
||||
_update_texture_filter_changed(false);
|
||||
_update_texture_repeat_changed(false);
|
||||
_update_snap_to_pixel_changed(false);
|
||||
|
||||
if (!block_transform_notify && !xform_change.in_list()) {
|
||||
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("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);
|
||||
|
||||
ADD_GROUP("Visibility", "");
|
||||
|
@ -1294,6 +1298,10 @@ void CanvasItem::_bind_methods() {
|
|||
ADD_GROUP("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_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_SIGNAL(MethodInfo("draw"));
|
||||
|
@ -1328,6 +1336,11 @@ void CanvasItem::_bind_methods() {
|
|||
BIND_ENUM_CONSTANT(CLIP_CHILDREN_ONLY);
|
||||
BIND_ENUM_CONSTANT(CLIP_CHILDREN_AND_DRAW);
|
||||
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 {
|
||||
|
@ -1565,6 +1578,62 @@ CanvasItem::TextureRepeat CanvasItem::get_texture_repeat_in_tree() const {
|
|||
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() :
|
||||
xform_change(this) {
|
||||
canvas_item = RenderingServer::get_singleton()->canvas_item_create();
|
||||
|
|
|
@ -73,6 +73,13 @@ public:
|
|||
CLIP_CHILDREN_MAX,
|
||||
};
|
||||
|
||||
enum SnapToPixel {
|
||||
SNAP_TO_PIXEL_PARENT_NODE,
|
||||
SNAP_TO_PIXEL_DISABLED,
|
||||
SNAP_TO_PIXEL_ENABLED,
|
||||
SNAP_TO_PIXEL_MAX,
|
||||
};
|
||||
|
||||
private:
|
||||
mutable SelfList<Node>
|
||||
xform_change;
|
||||
|
@ -112,8 +119,10 @@ private:
|
|||
|
||||
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::CanvasItemSnapToPixel snap_to_pixel_cache = RS::CANVAS_ITEM_SNAP_TO_PIXEL_DISABLED;
|
||||
TextureFilter texture_filter = TEXTURE_FILTER_PARENT_NODE;
|
||||
TextureRepeat texture_repeat = TEXTURE_REPEAT_PARENT_NODE;
|
||||
SnapToPixel snap_to_pixel = SNAP_TO_PIXEL_PARENT_NODE;
|
||||
|
||||
Ref<Material> material;
|
||||
|
||||
|
@ -148,12 +157,15 @@ private:
|
|||
void _update_texture_repeat_changed(bool p_propagate);
|
||||
void _refresh_texture_filter_cache() const;
|
||||
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();
|
||||
|
||||
protected:
|
||||
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_snap_to_pixel(RS::CanvasItemSnapToPixel p_snap);
|
||||
|
||||
_FORCE_INLINE_ void _notify_transform() {
|
||||
_notify_transform(this);
|
||||
|
@ -380,6 +392,9 @@ public:
|
|||
int get_canvas_layer() 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();
|
||||
};
|
||||
|
@ -387,6 +402,7 @@ public:
|
|||
VARIANT_ENUM_CAST(CanvasItem::TextureFilter)
|
||||
VARIANT_ENUM_CAST(CanvasItem::TextureRepeat)
|
||||
VARIANT_ENUM_CAST(CanvasItem::ClipChildrenMode)
|
||||
VARIANT_ENUM_CAST(CanvasItem::SnapToPixel)
|
||||
|
||||
class CanvasTexture : public Texture2D {
|
||||
GDCLASS(CanvasTexture, Texture2D);
|
||||
|
|
|
@ -283,7 +283,7 @@ void RendererCanvasCull::_cull_canvas_item(Item *p_canvas_item, const Transform2
|
|||
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)) {
|
||||
final_xform.columns[2] = (final_xform.columns[2] + Point2(0.5, 0.5)).floor();
|
||||
parent_xform.columns[2] = (parent_xform.columns[2] + Point2(0.5, 0.5)).floor();
|
||||
}
|
||||
|
@ -2311,6 +2311,12 @@ void RendererCanvasCull::canvas_item_set_default_texture_repeat(RID p_item, RS::
|
|||
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() {
|
||||
SelfList<Item::VisibilityNotifierData> *E = visibility_notifier_list.first();
|
||||
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_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();
|
||||
|
||||
|
|
|
@ -458,6 +458,7 @@ public:
|
|||
|
||||
RS::CanvasItemTextureFilter texture_filter;
|
||||
RS::CanvasItemTextureRepeat texture_repeat;
|
||||
RS::CanvasItemSnapToPixel snap_to_pixel;
|
||||
|
||||
Item() {
|
||||
commands = nullptr;
|
||||
|
|
|
@ -883,6 +883,8 @@ public:
|
|||
|
||||
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)
|
||||
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)
|
||||
|
|
|
@ -860,6 +860,13 @@ public:
|
|||
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;
|
||||
|
||||
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_snap_to_pixel(RID p_item, CanvasItemSnapToPixel p_snap) = 0;
|
||||
|
||||
enum NinePatchAxisMode {
|
||||
NINE_PATCH_STRETCH,
|
||||
NINE_PATCH_TILE,
|
||||
|
|
Loading…
Reference in New Issue