MODULE: DragDrop 1.1.0: helps to drag things around your AGS game!

Started by Crimson Wizard, Mon 14/03/2016 00:09:54

Previous topic - Next topic

Crimson Wizard

Full rewritten documentation for this module is now available here:
https://github.com/ivan-mogilko/ags-script-modules/wiki/Drag-&-Drop-module

I tried to explain things in more simple words where possible, and give more practical script examples to illustrate the concepts.
Still might add more real use examples later.

vga256

Hi CW. This module has become one of the most important modules I'm using for an art project that has a fake macintosh-style OS.

I'm running 1.1.0 and I'm wondering if the limitation "eDDCmnMoveGhostGUI - drags supplied custom GUI with object's image on it (currently does not work for GUI and Controls, but this is ONLY way to make inventory items drag & drop)" can be overcome?

I've got a situation where I want to simulate dragging a GUIControl from one GUI to another. The GUIcontrol does not have to actually move from one GUI to another, I just need it to *appear* that way (e.g. show a graphic that follows the mouse cursor to its drop point). The usage scenario is dragging an icon from Window A (a remote FTP, gFTP) to Window B (a local hard drive, gHardDrive).

Currently, the DragDropCommon module allows me to drag a GUIControl, but the control is only moved within its parent GUI... it cannot move beyond the boundaries of the parent GUI. After spending a few hours reading through the DDC module, it appears that the eDDCmnMoveGhostGUI setting is ignored for GUIs and GUIControls.

And yet, according to the documentation, "GhostGUI" mode works with everything, and is the only way to drag Inventory Items. You must provide a GUI though, by setting DragDropCommon.GhostGUI. GhostGUI also uses GhostTransparency property.

Is this just an inconsistency between the documentation and the module code? Is there a conceptual workaround that would allow me to simulate dragging and dropping (via a GhostGUI) a GUIControl from one GUI to another?

Thanks for your help and the great module!

Crimson Wizard

@vga256,

The documentation appears to be wrong where it sais that "Ghost GUI" works with everything.

The reason why "Ghost GUI" does not work for GUI & controls is quite simple. With "Ghost" GUI/Overlay the module must draw the dragged object on that GUI/Overlay. With characters and objects this is straightforward: you draw their current sprite (or animation frame). But with GUI it's not easy: there's no way to ask AGS to draw a GUI or control on a drawing surface or a dynamic sprite, so I would have to reimplement virtually whole GUI drawing in script! Naturally, I decided to not do that.

One may speculate that this could be worked around using a screenshot feature, but this approach will be additionally complicated by other screen elements which would have to be hidden (and that's not reliably possible to script in the module, I think).

Another workaround would be to only support controls which are drawn using sprites:
* Empty GUIs with background image and nothing else;
* Buttons which have a graphic assigned to them.

With the current module though, you would have to resort to scripting a custom drag-drop mode. The easiest method may be to replicate "Ghost GUI" or "Ghost Overlay", but let it set any image instead of knowing what AGS object you're dragging. You may follow examples in documentation, or use either demo game or DragDropCommon module as an example.

vga256

Quote from: Crimson Wizard on Fri 23/12/2022 23:00:05@vga256,
Another workaround would be to only support controls which are drawn using sprites:
* Empty GUIs with background image and nothing else;
* Buttons which have a graphic assigned to them.

With the current module though, you would have to resort to scripting a custom drag-drop mode. The easiest method may be to replicate "Ghost GUI" or "Ghost Overlay", but let it set any image instead of knowing what AGS object you're dragging. You may follow examples in documentation, or use either demo game or DragDropCommon module as an example.

Thanks for the explanation - that all makes sense. Since I am specifically only trying to drag and drop buttons (with assigned graphics), I will go that route and try to come up with custom drag mode based on GhostGUI.

I'll provide an update here when I come up with something workable.

vga256

Update: I added a few lines that allow for a Button to be draggable using the GhostGUI/Overlay:

Code: ags
//===========================================================================
//
// DragDropCommon::TryHookGUIControl()
//
//===========================================================================
static bool DragDropCommon::TryHookGUIControl()
{
  if (!DragDrop.EvtWantObject)
    return false;
  GUIControl *gc;
  // TODO: pixel perfect detection
  gc = GUIControl.GetAtScreenXY(DragDrop.DragStartX, DragDrop.DragStartY);
  if (gc == null)
    return false;
  if (DDSet.TestClickable && !gc.Clickable)
    return false;
  DDState._GUIControl = gc;
  DragDrop.HookObject(eDragDropGUIControl, gc.X, gc.Y);
  // Allow for GhostGUI/GhostOverlay when dealing with GUIControls that 
  // are buttons
  if (DDSet.Move != eDDCmnMoveSelf)
  {
    if (gc.AsButton != null)
    {
      int sprite = gc.AsButton.Graphic;
      DDState.CreateRepresentation(DDSet.Move, gc.X, gc.Y, gc.OwningGUI.X, gc.OwningGUI.Y, sprite,
                                   DDSet.GhostTransparency, DDSet.GhostAlpha);                                   
    }

  }
  return true;
}

For anyone interested in using this code to make buttons draggable via ghostguis/overlays: of note are the offsets "gc.OwningGUI.X" and "gc.OwningGUI.Y" - control positions are always relative to their parent GUI. So I've used the parent GUI's current position as the offset, to ensure that the overlay is created at the right spot.

SMF spam blocked by CleanTalk