Murga-Projects Forums

Full Version: Using callbacks to move objects on the screen
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
I am brand new to lua and new to fltk/fluid, so expect dumb questions from me. I find this stuff highly interesting and full of promises ;-). So, I decided to try and learn it to see what is possible. I would be interested in using murgaLua mostly to write mini educational games.

I can draw an interface, play it, modify and get some basic stuff done. However, I can't find the way to move an object on the screen dynamically, from within the lua script.

That's the onscreen object I want to move:

moving_point = fltk:Fl_Button(135, 35, 15, 15);

That's the dial I use to try and manipulate the x position of the object:

point_dial_x = fltk:Fl_Dial(26, 30, 25, 25);
point_dial_x:range(40, 200)

    -- fltk.fl_message(point_dial_x:x())  --> works, gives me the x value
    -- fltk.fl_message(point_dial_x:value()) --> works, gives me the value on the dial
    moving_point:set_x(point_dial_x:value());  --> causes a crash.

I tried: moving_point:x(int), moving_point:set_x(int), moving_point:move_x(int), none works. I can find mention of a o->position(x,y) construct on the fltk pages but don't know how to transfer this to murgaLua.

Reading tobi's post that mentions a change from "->" to ":" that isn't applied, I gave a try to


Works... except that I know have multiple versions of the object on screen. Okay, changing

moving_point:redraw()  -- old
window:redraw(); -- new

does the trick nicely.

Is it possible to have a drag and drop functionality? I can see an example at fltk cheat sheets - Draggable boxes

How to detect and react to these events from within murgaLua?

case FL_PUSH:
    offset[0] = x() - Fl::event_x();    // save where user clicked for dragging
    offset[1] = y() - Fl::event_y();
case FL_DRAG:
    position(offset[0]+Fl::event_x(), offset[1]+Fl::event_y());     // handle dragging

I'll look into this tonight ...
OK, I'll have to think about how to implement the "handle" functionality.

Not as easy as I hoped ... I'll keep you posted.

We discovered mikshaws "positionerTest.lua" in the murgaLua examples folder.
In just a few minutes Marielle modified it into this great drag and drop example.

Here's a movie preview
File maintained at the Widged murgaLua Gallery
Thanks Bill, that's spiffy stuff! Bill provided me with the code (from mikshaw, I assume), I only had to modify a few lines.

It can be useful to know that thing = the crosshair widget.

To see it, change 50 to another color in thing:selection_color(50).

It's a hacked drag and drop, so it doesn't really work like a standard drag and drop. What you need to do is first click on the object you want to drag. Then you have to click again on the object to move it around (to the user, it looks like they drag the object when what they do, in reality, is drag the center of the crosshair, with a callback that resets the position of the square).

Note that the maths are slightly inexact and don't take into account the left and right margins (causing the square to appear slightly offset when on the extreme left or right sides of the screen).

Feel free to suggest ways to improve the code. In particular, there shouldn't be the need for two square_cb functions... I don't have time to do better today.

widged Wrote:
There shouldn't be the need for two square_cb functions...

Learning the basics of Lua.


is in fact equivalent to

square2.callback(square2, square2_cb)

which means that no more than one square_cb function is needed:

function square_cb(self)
  square = self



which allows to rewrite the code to be more generic:

ww=350 --window (width and height)
fw = ww-20 -- frame
fh = ww-20
dw = fw-10 -- drag and drop area
dh = fw-10
sw = 10 -- square width
square = {}
square_selected = {}

-- :Square object
-- Constucts a little square on the screen that can be drag and dropped within a given display area.
-- @param x the x position of the square
-- @param y the y position of the square
-- @param c the color of the square
function square_create(x,y,c)
  sq = fltk:Fl_Button(x,y,sw,sw);
  return sq

-- Callbacks
function crosshair_cb()
  x = crosshair:xvalue()
  y = crosshair:yvalue()
  -- The crosshair area needs to be larger than the drag area, otherwise, a box that is on the far
  -- right or far bottom of the screen cannot be moved anymore.
  out:value("X: ".. xpos .."  Y: ".. ypos)
  out2:value("X: ".. string.format("%.2f",x) .."  Y: ".. string.format("%.2f",y))
  -- out:value("X: "..crosshair:xvalue() * ww .."  Y: "..crosshair:yvalue() * wh)

function square_cb(self)
  square_selected = self

-- GUI / Interface

w=fltk:Fl_Window(ww,wh,"murgaLua Drag and Drop Demo")


display = fltk:Fl_Group(10,10,fw,fh)

  square[1] = square_create(15,15,80)
  square[2] = square_create(200,200,60)

  crosshair:selection_color(36) -- same color as frame background
  -- crosshair:selection_color(72)

-- outputs, display the x and y values during drag and drop

-- required as button 1 is active by default and clicking anywhere on the screen
-- other than one of the two buttons crashes the app.
square_selected = square[1]


JohnMurga Wrote:
OK, I'll have to think about how to implement the "handle" functionality.

A quick hack, this will react to the button being pressed down as well as up. These fltk constants don't seem to be understood by murgalua, so the number between brackets need to be used.

but = fltk:Fl_Button(10,wh-30,80,22,"a button");
    FL_WHEN_NEVER             {0;}
    FL_WHEN_CHANGED           {1;}
    FL_WHEN_RELEASE           {4;}
    FL_WHEN_ENTER_KEY         {8;}
    FL_WHEN_NOT_CHANGED       {2;}

Pages: 1 2
Reference URL's