# HG changeset patch # User Diggory Hardy # Date 1246096646 -7200 # Node ID 620d4ea30228d2ef59957efae65b331fe4f0cc85 # Parent 55667d048c31554e804adb4c3e282234e5d6fa70 Context menus: added a clipboard (functions accessible from main menu rather than context menu). diff -r 55667d048c31 -r 620d4ea30228 codeDoc/ideas.txt --- 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? diff -r 55667d048c31 -r 620d4ea30228 data/L10n/en-GB.mtt --- 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 @@ + + + {Font} diff -r 55667d048c31 -r 620d4ea30228 mde/content/AStringContent.d --- 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; } diff -r 55667d048c31 -r 620d4ea30228 mde/content/Content.d --- 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; diff -r 55667d048c31 -r 620d4ea30228 mde/content/IContent.d --- 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 { +} diff -r 55667d048c31 -r 620d4ea30228 mde/content/miscContent.d --- 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); } diff -r 55667d048c31 -r 620d4ea30228 mde/gui/WidgetManager.d --- 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 diff -r 55667d048c31 -r 620d4ea30228 mde/gui/widget/contentFunctions.d --- 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); }