changeset 167:620d4ea30228

Context menus: added a clipboard (functions accessible from main menu rather than context menu).
author Diggory Hardy <diggory.hardy@gmail.com>
date Sat, 27 Jun 2009 11:57:26 +0200
parents 55667d048c31
children da8d3091fdaf
files codeDoc/ideas.txt data/L10n/en-GB.mtt mde/content/AStringContent.d mde/content/Content.d mde/content/IContent.d mde/content/miscContent.d mde/gui/WidgetManager.d mde/gui/widget/contentFunctions.d
diffstat 8 files changed, 41 insertions(+), 7 deletions(-) [+]
line wrap: on
line diff
--- a/codeDoc/ideas.txt	Sun Jun 21 12:19:18 2009 +0200
+++ b/codeDoc/ideas.txt	Sat Jun 27 11:57:26 2009 +0200
@@ -75,7 +75,10 @@
     +1> List for each type of content:
     	+>  can use a static list widget for each type
     	->  clipboard is type specific; need to decide when to convert, etc.
-            +>  enables better copying; e.g. from double 3.5e9 to int 4×10⁹
+            ?>  enables better copying; e.g. from double 3.5e9 to int 4×10⁹
+	>   Use a list of content as the service menu
+	    >	each item is a BoolContent and has value true if it can interact with the current content type
+	    >	wrapped in a CollapsibleWidget, displaying based on own value
   > Context menus:
     > Context menu serves (editable?) content most directly under mouse cursor
     > plus content higher up widget tree?
--- a/data/L10n/en-GB.mtt	Sun Jun 21 12:19:18 2009 +0200
+++ b/data/L10n/en-GB.mtt	Sat Jun 27 11:57:26 2009 +0200
@@ -7,6 +7,9 @@
 <entry|debug.guiDemo={0:"GUI Demo"}>
 <entry|help={0:"Help"}>
 <entry|help.about={0:"About",1:"Show author and copyright information"}>
+<entry|services={0:"Services"}>
+<entry|services.copy={0:"Copy",1:"Copy selected content to clipboard"}>
+<entry|services.paste={0:"Paste",1:"Paste clipboard contents into selected content object"}>
 {Font}
 <entry|lcdFilter={0:"LCD filtering",1:"Filtering used with LCD rendering."}>
 <entry|lcdFilter.none={0:"None",1:"Leaves big colour fringes."}>
--- a/mde/content/AStringContent.d	Sun Jun 21 12:19:18 2009 +0200
+++ b/mde/content/AStringContent.d	Sat Jun 27 11:57:26 2009 +0200
@@ -83,6 +83,12 @@
 	return false;
     }
     
+    /** Set value directly from a string. */
+    override void opAssign (char[] str) {
+	sv = str.dup;
+	return endEdit;
+    }
+    
     /** Acts on a keystroke to edit the value as a string.
      *
      * After this has been used to edit the string, endEdit should be called
@@ -181,6 +187,7 @@
     bool endEdit ();
     
 protected:
+    //TODO: copy-on-assign, copy-on-edit, or what?
     /* String version of value (for toString(0) and editing).
      * WARNING: This must point to mutable memory (for endEdit), and
      * when keyStroke can be called we must have svBuf[0..sv.length] == sv. */
@@ -256,7 +263,7 @@
     }
     
     void assignNoCng (char[] val) {
-	v = val;
+	v = val.dup;
 	if (pos > sv.length) pos = sv.length;
         endEvent;
     }
--- a/mde/content/Content.d	Sun Jun 21 12:19:18 2009 +0200
+++ b/mde/content/Content.d	Sat Jun 27 11:57:26 2009 +0200
@@ -97,6 +97,7 @@
             	parent = new ContentList (parentSym);
         }
         parent.append (this);
+	//logger.trace ("Created: {}\t{}", symbol, this);
     }
     
     void name (Translation.Entry e) {
@@ -141,6 +142,8 @@
     override bool set (IContent) {
 	return false;
     }
+    /// ditto
+    override void opAssign (char[]) {}
     
 protected:
     char[] symbol;
--- a/mde/content/IContent.d	Sun Jun 21 12:19:18 2009 +0200
+++ b/mde/content/IContent.d	Sat Jun 27 11:57:26 2009 +0200
@@ -47,5 +47,15 @@
      * value to that of cont and return true, otherwise it should return false.
      */
     bool set (IContent);
+    
+    /** Similarly, try to set the value directly from a string.
+     * Doesn't do anything for content not storing a value. */
+    void opAssign (char[]);
 }
 
+/** Interface for content which should be interacted with as a button.
+ *
+ * Actually not used to provide extra methods, but to tell widget-choosing
+ * functions a button is desired. */
+interface IEventContent : IContent {
+}
--- a/mde/content/miscContent.d	Sun Jun 21 12:19:18 2009 +0200
+++ b/mde/content/miscContent.d	Sat Jun 27 11:57:26 2009 +0200
@@ -31,7 +31,7 @@
 /** A Content with no value but able to pass on an event.
 *
 * The point being that a button can be tied to one of these. */
-class EventContent : Content {
+class EventContent : Content, IEventContent {
     this (char[] symbol) {
         super (symbol);
     }
--- a/mde/gui/WidgetManager.d	Sun Jun 21 12:19:18 2009 +0200
+++ b/mde/gui/WidgetManager.d	Sat Jun 27 11:57:26 2009 +0200
@@ -29,6 +29,7 @@
 
 import imde = mde.imde;
 import mde.content.Content;
+import mde.content.ServiceContent;
 debug import mde.content.miscContent;	// Debug menu
 
 // Widgets to create:
@@ -72,6 +73,11 @@
         auto p = "MiscOptions.l10n" in Content.allContent;
         assert (p, "MiscOptions.l10n not created!");
         p.addCallback (&reloadStrings);
+	
+	serviceContent = cast (IServiceContent) Content.get ("menus.services");
+	assert (Content.get ("menus.services"));
+	assert (serviceContent !is null, "Content service menu doesn't exist or has wrong type");
+	
         debug {	// add a debug-mode menu
             auto lWS = new EventContent ("menus.debug."~name~".logWidgetSize");
             lWS.addCallback (&logWidgetSize);
@@ -321,9 +327,10 @@
 	
 	// Finally, post the actual event:
 	if (b == 3 && !state) {	// right click - open context menu
-	    IContent contextContent = underMouse.content;
+	    Content contextContent = cast(Content)underMouse.content;
 	    if (contextContent is null) return;
 	    // NOTE: Creates new widgets every time; not optimal
+	    serviceContent.setContent (contextContent);
 	    popupContext = makeWidget (this, "context", contextContent);
 	    popupContext.setup (0, 3);
 	    positionPopup (underMouse, popupContext);
@@ -524,6 +531,7 @@
     
     // Popup(s) handled directly by AWidgetManager:
     IChildWidget popupContext;		// context menu (active if not null)
+    IServiceContent serviceContent;	// context menu content tree
     IChildWidget dragContentDisplay;	// displays dragged content; no interaction
     
     IChildWidget dragStart;		// if non-null, this widget should receive motion and click-release events
--- a/mde/gui/widget/contentFunctions.d	Sun Jun 21 12:19:18 2009 +0200
+++ b/mde/gui/widget/contentFunctions.d	Sat Jun 27 11:57:26 2009 +0200
@@ -48,6 +48,9 @@
 IChildWidget editContent (IWidgetManager mgr, IParentWidget parent, widgetID id, WidgetData data, IContent c) {
     // Note: SAFE_RECURSION enabled
     if (c is null) throw new ContentException;
+    // Normally only EventContents are used for buttons, but any Content can be:
+    if (cast(IEventContent) c)
+	return new ButtonContentWidget(mgr,parent,id,data,c);
     if (cast(AStringContent) c) {
         if (cast(EnumContent) c)	// can be PopupMenuWidget or ContentListWidget
             return new PopupMenuWidget(mgr,parent,id,data,c);
@@ -57,9 +60,6 @@
     }
     if (cast(IContentList) c)
         return new ContentListWidget(mgr,parent,id,data,c);
-    // Normally only EventContents are used for buttons, but any Content can be:
-    if (cast(EventContent) c)
-        return new ButtonContentWidget(mgr,parent,id,data,c);
     // generic uneditable option
     return new DisplayContentWidget(mgr,parent,id,data,c);
 }