Dunno how to drag a GUI with mouse

Started by gatewayer, Fri 07/05/2010 17:01:12

Previous topic - Next topic

gatewayer

Hello everyone, this is my first post, and i wanna say first that AGS is
the best tool for adventure games i've ever seen. Thanks very much
for this Chris!

I want to make an inventory window that doesn't pause the game
when it is visible, but i want also to make it draggable with the mouse,
like all windows in windows xp for example.

I've tried it with a button that seems like the title bar, and made an OnClick
event were i've simply put:

function btnMainInvTitle_Click(...)
{
   gMainInventory.X = mouse.x; gMainInventory.Y = mouse.y;
}

The result is very bad. The Gui jumps to the new pos, instead of moving smoothly.
I also tried mouse.IsButtonDown(...), inside the button event function, but it also doesn't work.

I've searched in the forums for the problem but i came with a similar
solution for objects that doesn't help me.
Sorry if there was one post about guis i missed.

Bye!

Calin Leafshade

#1
the trick is to use an offset.. i.e the distance between the mouse on click and the gui position.. like so:

The whole thing with 'clicked' is to stop the gui from catching the mouse if you hold down the button whilst not over the guicontrol.

Also you'll have to fiddle with the gui/control names to make the code work for your particular project.

Code: ags

bool clicked, Dragging;
int DragX, DragY;

function repeatedly_execute(){


if (mouse.IsButtonDown(eMouseLeft)){
    if (!clicked){
      if (GUIControl.GetAtScreenXY(mouse.x, mouse.y) == CtlEmailBar){
        Dragging = true;
        DragX = mouse.x - gEmail.X;
        DragY = mouse.y - gEmail.Y;
        
      }
    
      clicked = true;
    }
  }
  else {
    clicked = false;
    Dragging = false;
  }
  
  if (Dragging){
    gEmail.X = mouse.x - DragX;
    gEmail.Y = mouse.y - DragY;
    gEmail.Transparency = 80;
  }
  else gEmail.Transparency = 10;
  
}
  



EDIT: Note that there are many ways to optimise this code.. specifically the whole 'if(Dragging)' part.. but i never bothered.

Ryan Timothy B

#2
When you click the GUI, assuming it's the top 28 pixels of the GUI like here, it should run this:
Code: ags

function gTheGUI_OnClick(GUI *theGui, MouseButton button)
{
  if (mouse.y<gTheGUI.Y+28) dragGUI(gTheGUI);
}



Then the function it calls is this, which works for all GUI's:
Code: ags

function noloopcheck dragGUI(GUI*g)
{
  int gX, gY;
  int xa = mouse.x - g.X;
  int ya = mouse.y - g.Y;
  while(mouse.IsButtonDown(eMouseLeft)){
    gX = mouse.x - xa;
    gY = mouse.y - ya;
    if (gX<0) gX=0;
      else
      if (gX>System.ViewportWidth-g.Width) gX=System.ViewportWidth-g.Width;
    if (gY<0) gY=0;
      else
      if (gY>System.ViewportHeight-g.Height) gY=System.ViewportHeight-g.Height;
    g.X=gX;
    g.Y=gY;
    Wait(1);
  }
}


It also stops when the edges of the GUI touch the edges of the screen.  You can always change this.

Edit: Sorry, forgot to mention that while you're holding the GUI and moving it around, it pauses the game.

Calin Leafshade

Ryans code is quite alot tidier than mine so I'd probably go with his.. although either is likely to produce similar results.

Ryan Timothy B

Of course, it was originally from Khris in this post.  I had used this a while ago and had tweaked it to work for a GUI instead and also prevented it from leaving the edge of the screen.

Khris

#5
Heh, I didn't remember posting that at all and had written completely new code (edit: weeks ago) to do that:

Code: ags
bool gui_is_dragged;
GUI*dragged_gui;
int xa, ya;

void on_event (EventType event, int data) {
  if (event == eEventGUIMouseDown && mouse.IsButtonDown(eMouseLeft)) {
    GUIControl*gc = GUIControl.GetAtScreenXY(mouse.x, mouse.y);
    GUI*g;
    if (gc != null && gc.ID == 0) {
      dragged_gui = gc.OwningGUI;
      xa = mouse.x - dragged_gui.X;
      ya = mouse.y - dragged_gui.Y;
      gui_is_dragged = true;
      // dragged_gui.ZOrder = gui[1-dragged_gui.ID].ZOrder + 1;
    }
  }
}

void repeatedly_execute() {
  if (gui_is_dragged) {
    if (!mouse.IsButtonDown(eMouseLeft)) gui_is_dragged = false;
    else {
      dragged_gui.X = mouse.x - xa;
      dragged_gui.Y = mouse.y - ya;
    }
  }
}


This makes any GUI draggable by clicking on the GUI Control with index 0, so one can disable it for a GUI or make it draggable just by the title bar, etc.
It's probably best to put this code in a new script, for tidiness.

gatewayer

Thank you very much, i've tested some of the solutions
and i got all fine now.

I appreciate very much so much help one gets in this forum.
Thanks Calin, Ryan and Khris.

See ya!

SMF spam blocked by CleanTalk