Drag & Drop (swap) 3 texture buttons in a Margin Container->VBox - godot

Following along a great tutorial, code is replicated yet does not function as shown. No new texture appears to be created when I try to drag the texture button. Only difference is the tutorial uses a TextureRect, while I'm using a TextureButton.
extends TextureButton
func get_drag_data(position: Vector2):
var vControl = Control.new()
var vData = {}
var vTexture = TextureRect.new()
vTexture.expand = true
vTexture.texture = texture_disabled
vTexture.rect_size = Vector2(320, 400)
vControl.add_child(vTexture)
vTexture.rect_position = -0.5 * vTexture.rect_size
set_drag_preview(vTexture)
return vData
Code above is attached to Party_1. texture_disabled does have a texture set.

It would work if you had the code in get_drag_data looking like this:
func get_drag_data(_position: Vector2):
var vTexture = TextureRect.new()
vTexture.expand = true
vTexture.texture = texture_disabled
vTexture.rect_size = Vector2(320, 400)
set_drag_preview(vTexture)
return {}
However, that would place the TextureRect top-left corner at the cursor position.
You want to offset the position of the TextureRect so it is centered at the cursor position. To do that, you create another Control, add the TextureRect as a child to it… And pass the TextureRect anyway? No, that does not work, you need to pass the new Control:
func get_drag_data(_position: Vector2):
var vTexture = TextureRect.new()
vTexture.expand = true
vTexture.texture = texture_disabled
vTexture.rect_size = Vector2(320, 400)
var vControl = Control.new()
vControl.add_child(vTexture)
vTexture.rect_position = -0.5 * vTexture.rect_size
set_drag_preview(vControl)
return {}
Please notice I'm giving vControl to set_drag_preview, not vTexture.
You cannot give to set_drag_preview a Control that has a parent. In fact, if you tried you would get an error in the Output console saying:
_gui_set_drag_preview: Condition "p_control->get_parent() != nullptr" is true.
Or
_gui_set_drag_preview: Condition "p_control->is_inside_tree()" is true.

Related

How to rotate using canvas_item_set_transform?

I'm trying to copy a Sprite node and display it on screen through a VisualServer and so far this has been my progress based on this example
ci_rid = VisualServer.canvas_item_create()
VisualServer.canvas_item_set_parent(ci_rid, get_canvas_item())
self.remove_child(sprite_node);
sprite_node.queue_free();
var texture = load(sprite_node.texture.resource_path);
var pos_and_size=Rect2(Vector2(0,0), sprite_node.region_rect.size);
if(sprite_node.region_enabled==true):
VisualServer.canvas_item_add_texture_rect_region(ci_rid,pos_and_size, texture,sprite_node.region_rect);
var transform_matrix=Transform2D.IDENTITY;
VisualServer.canvas_item_set_transform(ci_rid,transform_matrix.translated(sprite_node.position-sprite_node.region_rect.size / 2))
but when I try to replicate the rotation on it's own axis like this:
VisualServer.canvas_item_set_transform(ci_rid,
transform_matrix.rotated(deg2rad(sprite_node.rotation_degrees)).translated(sprite_node.position-sprite_node.region_rect.size / 2)
)
it doesn't give the desired result and moves the entire image to another position
Original Sprite node:
VisualServer copy:
You can take the global_transform before you remove it:
var sprite_transform := sprite_node.global_transform
Or you can reconstruct it after you removed it:
var sprite_transform = global_transform * Transform2D(sprite_node.rotation, sprite_node.position).scaled(sprite_node.scale)
I'm using global_transform here because the node used to be a child of where the code is running. So its transform is relative to it.
I really don't know how you are not getting errors with your texture. This is the way I ended up going about it:
var image:Image = sprite_node.texture.get_data()
var texture_rid := VisualServer.texture_create_from_image(image)
Then the region and size are handled like this:
var texture_size:Vector2 = image.get_size()
var region:Rect2 = sprite_node.region_rect if sprite_node.region_enabled else Rect2(Vector2.ZERO, texture_size)
var pos_and_size := Rect2(region.size * -0.5 if sprite_node.centered else Vector2.ZERO, region.size)
And these are my VisualServer calls:
var ci_rid := VisualServer.canvas_item_create()
VisualServer.canvas_item_set_parent(ci_rid, get_canvas_item())
VisualServer.canvas_item_add_texture_rect_region(ci_rid, pos_and_size, texture_rid, region);
VisualServer.canvas_item_set_transform(ci_rid, sprite_transform)

Switching between two colors on a awesome wm container widget

I create a wibox.container.background with something like:
local w = wibox.widget({
{
id = "texte",
text = "mon texte",
widget = wibox.widget.textbox
},
bg = beautiful.bg_normal,
widget = wibox.container.background
})
Now I want to switch between two background colors with:
w.bg = w.bg == beautiful.bg_normal and beautiful.bg_focus or beautiful.bg_normal
But that doesn't work. It seems w.bg refers to a solid pattern and not to a simple hexa color string.
Am I pointing to the correct bg variable?
I would recommend that you keep your own variable local is_focus = true and use that to update the background.
What happens is that the background "string" that you specify goes through gears.color and is transformed into a cairo pattern. That is what is then actually used for drawing. You could also pass in a cairo pattern directly and avoid the "loop" through gears.color.
Example for my proposed solution:
local w = wibox.widget({
{
id = "texte",
text = "mon texte",
widget = wibox.widget.textbox
},
bg = beautiful.bg_normal,
widget = wibox.container.background
})
local is_focused = false
local function switch_background()
is_focused = not is_focused
w.bg = is_focused and beautiful.bg_focus or beautiful.bg_normal
end

Why _integrate_forces doesn't work get RigidBody2D has Gravity Scale set to 0?

I am trying to drag and drop a RigidBody2D, however I have noticed that my code doesn't work at all if I set the Gravity Scale = 0 and if I set the Gravity Scale to 0.5 it works however if I drag it and stop moving the mouse for a second, it gets stuck in its place as if I did set the Gravity Scale to 0.
extends RigidBody2D
var is_held = false
func _ready():
set_process_input(true)
func _integrate_forces(state):
i = i + 1
var lv = state.get_linear_velocity()
if is_held:
lv = (get_viewport().get_mouse_pos() - get_pos()) * 16
state.set_linear_velocity(lv)
func _input(event):
if event.type == InputEvent.MOUSE_BUTTON and not event.pressed and event.button_index == BUTTON_LEFT:
is_held = false
func _on_food_input_event( viewport, event, shape_idx ):
if event.type == InputEvent.MOUSE_BUTTON and event.pressed and event.button_index == BUTTON_LEFT:
is_held = true
In the end what I am trying is to be able to drag and drop the rigid body either vertically or horizontally and not both nor diagonal.
You must go in your visual editor under properties of the RigidBody2D and set the first property to "Mode:Character".
You function "_integrate_forces" is not called all the time in "Mode:Rigid". When it stops the engine stops to call it. But it is called all the time in "Mode:Character". That will solve your problem.

Dragging a circle

I am beginning to use snap.svg, and stuck in a probably simple question. I draw a circle, and want to let the user drag it around, and when the user stops dragging, I want to know the alert the final position of the circle.
I started with this:
var s = Snap("#svg");
var d = s.circle(20,20,5);
Then I created the following functions as drag event-handlers; I only need the drag-end event so I made the two other event-handlers null:
var endFnc = function(e) {
alert("end: "+e.layerX+","+e.layerY);
}
var startFnc = null;
var moveFnc = null;
Then I installed the drag event handlers:
d.drag(moveFnc,startFnc,endFnc);
Whenever I tried to drag a circle, the end event fired, but, the circle did not move.
So I figured maybe I have to also create the drag move event (although I don't need it):
var moveFnc = function(dx, dy, x, y) {
this.transform('t' + x + ',' + y);
}
Now the circle did move, but, not exactly at the mouse, but approximately 20 pixels at its bottom right.
I read the documentation here: http://snapsvg.io/docs and there seems to be no explanation about how to create working drag events.
How does anyone get this knowledge?!
After struggling for some hours to do this with snap.js, I finally discovered svg.js and its draggable plugin, with which it is so much easier:
var draw = SVG('svg');
var circle = draw.circle(10).attr({cx:30,cy:30,fill:'#f06'});
circle.dragend = function(delta, event) {
alert(this.attr('cx'))
}
circle.draggable();
So, I switched to svg.js ...

iOS 7 view controller layout issue with transparent/blurred nav bar

I am having trouble with my view controllers in iOS 7. I'm trying to figure out the best way to adjust my view's layout under the nav bar and status bar while maintaining the transparency/blur of the nav bar. So for example, if I have a view controller with:
def viewDidLoad
#scroll = UIScrollView.alloc.initWithFrame(new_frame)
#scroll.bounces = true
#scroll.delegate = self
#scroll.alwaysBounceVertical = true
#scroll.scrollsToTop = true
#scroll.contentSize = CGSizeMake(UIScreen.mainScreen.bounds.size.width, scroll_frame.size.height)
self.view.addSubview(#scroll)
end
My content appears under the nav bar, which I get given the iOS 7 transition guide. To correct that, if I add the following inside of viewDidLoad:
self.edgesForExtendedLayout = UIRectEdgeNone
The layout is adjusted but the navbar no longer has transparency or blur because the view doesn't extend behind it.
If I don't adjust scrollView insets instead of setting edges for layout:
self.automaticallyAdjustsScrollViewInsets = false
Then change my scroll frame to:
def viewDidLoad
nav_bar_height = self.navigationController.navigationBar.frame.size.height
status_height = UIApplication.sharedApplication.statusBarFrame.size.height
height = nav_bar_height + status_height
scroll_frame = self.view.bounds
new_frame = CGRect.new([0, height], [scroll_frame.size.width, scroll_frame.size.height])
#scroll = UIScrollView.alloc.initWithFrame(new_frame)
#scroll.bounces = true
#scroll.delegate = self
#scroll.alwaysBounceVertical = true
#scroll.scrollsToTop = true
#scroll.contentSize = CGSizeMake(UIScreen.mainScreen.bounds.size.width, scroll_frame.size.height)
self.view.addSubview(#scroll)
end
I no longer get the transparent/blur of the nav bar. Only when I adjust the scroll's frame - at the x origin - with a new height does this seem to happen. So I'm wondering why that is and how I can best adjust my scroll without losing the blur/transparency.
Maybe you can try with inset
[scroll setContentInset:UIEdgeInsetsMake(nav_bar_height + status_height, 0.0, 0.0, 0.0)];
[scroll setScrollIndicatorInsets:UIEdgeInsetsMake(nav_bar_height + status_height,0.0,0.0,0.0)];
Hope that help

Resources