# HG changeset patch # User Diggory Hardy # Date 1243015162 -7200 # Node ID 2476790223b82998a9e053b9d2db4c7404df7f97 # Parent e3fe6acc16fb50ca614ed2733862f64eef1a1721 First drag and drop support: can drag from AStringContentWidget to any content editable. No visual feedback while dragging. diff -r e3fe6acc16fb -r 2476790223b8 codeDoc/jobs.txt --- 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. diff -r e3fe6acc16fb -r 2476790223b8 mde/content/AStringContent.d --- 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); diff -r e3fe6acc16fb -r 2476790223b8 mde/content/Content.d --- 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_; } diff -r e3fe6acc16fb -r 2476790223b8 mde/content/IContent.d --- 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); } diff -r e3fe6acc16fb -r 2476790223b8 mde/gui/WidgetManager.d --- 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 diff -r e3fe6acc16fb -r 2476790223b8 mde/gui/widget/AChildWidget.d --- 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 () { diff -r e3fe6acc16fb -r 2476790223b8 mde/gui/widget/Ifaces.d --- 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. diff -r e3fe6acc16fb -r 2476790223b8 mde/gui/widget/ParentContent.d --- 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); diff -r e3fe6acc16fb -r 2476790223b8 mde/gui/widget/TextWidget.d --- 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); diff -r e3fe6acc16fb -r 2476790223b8 mde/gui/widget/layout.d --- 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); diff -r e3fe6acc16fb -r 2476790223b8 mde/gui/widget/miscContent.d --- 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); }