changeset 162:2476790223b8

First drag and drop support: can drag from AStringContentWidget to any content editable. No visual feedback while dragging.
author Diggory Hardy <diggory.hardy@gmail.com>
date Fri, 22 May 2009 19:59:22 +0200
parents e3fe6acc16fb
children 24d77c52243f
files codeDoc/jobs.txt mde/content/AStringContent.d mde/content/Content.d mde/content/IContent.d mde/gui/WidgetManager.d mde/gui/widget/AChildWidget.d mde/gui/widget/Ifaces.d mde/gui/widget/ParentContent.d mde/gui/widget/TextWidget.d mde/gui/widget/layout.d mde/gui/widget/miscContent.d
diffstat 11 files changed, 132 insertions(+), 15 deletions(-) [+]
line wrap: on
line diff
--- a/codeDoc/jobs.txt	Thu May 21 22:15:40 2009 +0200
+++ b/codeDoc/jobs.txt	Fri May 22 19:59:22 2009 +0200
@@ -8,10 +8,12 @@
 
 To do (importance 0-5: 0 pointless, 1 no obvious impact now, 2 todo sometime, 3 useful, 4 important, 5 urgent):
 Also search for FIXME/NOTE/BUG/WARNING comment marks.
+3   Enable dragging from more widgets: bool content, enum
+3   Content: setContent specialisations, opAssign should reject more values (particularly for BoolContent).
 3   GUI: up-clicks get passed as events and activate objects
-3   Too many redraws: mouse-over causes them
 3   Widget saving: how to deal with modifier functions, esp. when they discard parameters? Remove feature except for dimdata and handle gui editing separately?
 3   Windows compatibility - no registry support (useful to find path).
+2   Visual feedback for dragging
 2   First glyph drawn incorrectly in release mode - ??
 2   glBindTexture not working with non-0 index - perhaps use a higher level graphics library at some point.
 2   Popup help boxes on hover/right click to display content description.
--- a/mde/content/AStringContent.d	Thu May 21 22:15:40 2009 +0200
+++ b/mde/content/AStringContent.d	Fri May 22 19:59:22 2009 +0200
@@ -51,6 +51,21 @@
              : null;
     }
     
+    /** Set the content via conversion to/from string. */
+    override bool setContent (IContent c) {
+	AStringContent asc = cast (AStringContent) c;
+	if (asc !is null) {
+	    try {
+		sv = asc.toString (0);
+		endEdit;
+	    } catch (Exception) {	// invalid conversion; just reject c
+		return false;
+	    }
+	    return true;
+	}
+	return false;
+    }
+    
     /** Acts on a keystroke and returns the new value.
      *
      * Supports one-line editing: left/right, home/end, backspace/delete. */
@@ -223,6 +238,17 @@
 	super (symbol);
     }
     
+    // NOTE: the only point of this method is to avoid int->string->int conversions,
+    // and perhaps specialise (double->int rounding?)
+    override bool setContent (IContent c) {
+	IntContent ic = cast (IntContent) c;
+	if (ic !is null) {
+	    this = ic();
+	    return true;
+	}
+	return super.setContent (c);
+    }
+    
     void assignNoCng (int val) {
 	v = val;
 	sv = Int.toString (v);
--- a/mde/content/Content.d	Thu May 21 22:15:40 2009 +0200
+++ b/mde/content/Content.d	Fri May 22 19:59:22 2009 +0200
@@ -116,13 +116,6 @@
 	return this;
     }
     
-    override char[] toString (uint i) {
-	return i == 0 ? "No value"
-	: i == 1 ? name_
-	: i == 2 ? desc_
-	: null;
-    }
-    
     /** End of an event, e.g. a button release or end of an edit (calls callbacks).
      *
      * Content holding a value should override this, setting its new value in
@@ -136,6 +129,19 @@
 	    dg (this);
     }
     
+    override char[] toString (uint i) {
+	return i == 0 ? "No value"
+	: i == 1 ? name_
+	: i == 2 ? desc_
+	: null;
+    }
+    
+    /** A naive implementation which assumes the passed content is
+     * incompatible. */
+    override bool setContent (IContent) {
+	return false;
+    }
+    
 protected:
     char[] symbol;
     char[] name_, desc_;	// translated name and description
@@ -184,6 +190,15 @@
         list_ ~= x;
     }
     
+    override bool setContent (IContent c) {
+	IContentList cl = cast (IContentList) c;
+	if (cl !is null) {
+	    list_ = cl.list();
+	    return true;
+	}
+	return false;
+    }
+    
 protected:
     final Content[] list_;
 }
--- a/mde/content/IContent.d	Thu May 21 22:15:40 2009 +0200
+++ b/mde/content/IContent.d	Fri May 22 19:59:22 2009 +0200
@@ -40,5 +40,12 @@
     *  $(TR $(TD other) $(TD null))
     *  ) */
     char[] toString (uint i);
+    
+    /** Generic way to set content value.
+     *
+     * If cont's type is compatible, the method should set its instance's
+     * value to that of cont and return true, otherwise it should return false.
+     */
+    bool setContent (IContent);
 }
 
--- a/mde/gui/WidgetManager.d	Thu May 21 22:15:40 2009 +0200
+++ b/mde/gui/WidgetManager.d	Fri May 22 19:59:22 2009 +0200
@@ -104,6 +104,10 @@
         child.setPosition (0,0);
         requestRedraw;
     }
+    
+    override bool dropContent (IContent content) {
+	return false;
+    }
     //END IParentWidget methods
     
     //BEGIN IPopupParentWidget methods
--- a/mde/gui/widget/AChildWidget.d	Thu May 21 22:15:40 2009 +0200
+++ b/mde/gui/widget/AChildWidget.d	Fri May 22 19:59:22 2009 +0200
@@ -144,6 +144,10 @@
     // Called when mouse moves over or off this
     override void underMouse (bool state) {}
     
+    override bool dropContent (IContent content) {
+	return parent.dropContent (content);
+    }
+    
     // Only useful to widgets creating popups.
     override void popupClose () {}
     override bool popupParentClick () {
--- a/mde/gui/widget/Ifaces.d	Thu May 21 22:15:40 2009 +0200
+++ b/mde/gui/widget/Ifaces.d	Fri May 22 19:59:22 2009 +0200
@@ -35,6 +35,33 @@
 
 
 /******************************************************************************
+ * The root widget interface, for methods required by both IParentWidget and
+ * IChildWidget.
+ *****************************************************************************/
+interface IWidget
+{
+    
+    /** Called on a widget when something is dragged onto it.
+     *
+     * Generally, content editing widgets should implement this as:
+     * ---
+    override bool dropContent (IContent content) {
+	if (content_.setContent (content))
+	    return true;
+	return parent.dropContent (content);
+    }
+     * ---
+     * And other widgets should just:
+     * ---
+     * return parent.dropContent (content);
+     * ---
+     *
+     * Returns: true if the content was received (false if it reaches the
+     *	WidgetManager and is still not used). */
+    bool dropContent (IContent content);
+}
+
+/******************************************************************************
  * Interface for parent widgets, including IWidgetManager.
  *
  * All widgets implement this via AWidget to make things simpler (code sharing).
@@ -44,7 +71,7 @@
  *  Layout widget: a widget containing multiple sub-widges (which hence
  *   controls how they are laid out).
  *****************************************************************************/
-interface IParentWidget
+interface IParentWidget : IWidget
 {
     /** Checks for recursion of unsafe widgets to prevent infinite recursion. */
     void recursionCheck (widgetID, IContent);
@@ -273,7 +300,7 @@
  * during their creation.
  *****************************************************************************/
 //NOTE: add another this() without the data for default initialization, for the GUI editor?
-interface IChildWidget
+interface IChildWidget : IWidget
 {
 //BEGIN Load and save
     /** 2nd stage of initialization for widgets; also called on some changes.
--- a/mde/gui/widget/ParentContent.d	Thu May 21 22:15:40 2009 +0200
+++ b/mde/gui/widget/ParentContent.d	Fri May 22 19:59:22 2009 +0200
@@ -78,6 +78,12 @@
         return content_;
     }
     
+    override bool dropContent (IContent content) {
+	if (content_.setContent (content))
+	    return true;
+	return parent.dropContent (content);
+    }
+    
     override void recursionCheck (widgetID wID, IContent c) {
         if (wID is id && c is content_)
             throw new WidgetRecursionException (wID);
--- a/mde/gui/widget/TextWidget.d	Thu May 21 22:15:40 2009 +0200
+++ b/mde/gui/widget/TextWidget.d	Fri May 22 19:59:22 2009 +0200
@@ -149,11 +149,19 @@
     }
     
     /** On click, request keyboard input. */
-    override int clickEvent (wdabs cx, wdabs, ubyte, bool) {
-	//adapter.index = content_.editIndex;
-        content_.editIndex = adapter.setIndex (cx - x);
-	mgr.requestRedraw;
-	return 1;	// get keyboard input via keyEvent
+    override int clickEvent (wdabs cx, wdabs, ubyte, bool state) {
+	if (state) {
+	    //adapter.index = content_.editIndex;
+	    content_.editIndex = adapter.setIndex (cx - x);
+	    mgr.requestRedraw;
+	    return 3;	// get keyboard input via keyEvent
+	}
+    }
+    
+    override bool dragRelease (wdabs, wdabs, IChildWidget widg) {
+	if (widg !is this)	// don't copy content to self
+	    widg.dropContent (content_);
+	return true;
     }
     
     override void keyEvent (ushort s, char[] i) {
@@ -173,6 +181,12 @@
 	mgr.requestRedraw;
     }
     
+    override bool dropContent (IContent content) {
+	if (content_.setContent (content))
+	    return true;
+	return parent.dropContent (content);
+    }
+    
 protected:
     void update (Content) {	// callback
         adapter.text = content_.toString(0);
--- a/mde/gui/widget/layout.d	Thu May 21 22:15:40 2009 +0200
+++ b/mde/gui/widget/layout.d	Fri May 22 19:59:22 2009 +0200
@@ -120,6 +120,12 @@
         return cList;
     }
     
+    override bool dropContent (IContent content) {
+	if (cList.setContent (content))
+	    return true;
+	return parent.dropContent (content);
+    }
+    
     override void recursionCheck (widgetID wID, IContent c) {
         if (wID is id && c is cList)
             throw new WidgetRecursionException (wID);
--- a/mde/gui/widget/miscContent.d	Thu May 21 22:15:40 2009 +0200
+++ b/mde/gui/widget/miscContent.d	Fri May 22 19:59:22 2009 +0200
@@ -50,6 +50,12 @@
         return content_;
     }
     
+    override bool dropContent (IContent content) {
+	if (content_.setContent (content))
+	    return true;
+	return parent.dropContent (content);
+    }
+    
     override void draw () {
         mgr.renderer.drawToggle (x,y, content_(), pushed);
     }