Changeset 174:3d58adc17d20
- Timestamp:
- 08/31/09 07:54:23
(3 years ago)
- Author:
- Diggory Hardy <diggory.hardy@gmail.com>
- branch:
- default
- Message:
Temporary commit to allow backup
-
Files:
-
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
| r173 |
r174 |
|
| 69 | 69 | +> combined rendering (to texture?) of each "layer" to enable nice transparancy |
|---|
| 70 | 70 | > lower performance? |
|---|
| | 71 | > Data: |
|---|
| | 72 | > remove "designs" concept from WidgetLoader: |
|---|
| | 73 | > have one design per file |
|---|
| | 74 | > to load multiple designs, have multiple WidgetLoaders in memory (so each just stores one set of data) |
|---|
| | 75 | > pass a reference to a WidgetLoader or whatever it's called to the WidgetManager |
|---|
| | 76 | > instead of class extension |
|---|
| | 77 | > allows easily swapping data sets |
|---|
| 71 | 78 | |
|---|
| 72 | 79 | |
|---|
| 73 | 80 | Content: |
|---|
| 74 | 81 | -> Per-content undo support? |
|---|
| 75 | | > Services: |
|---|
| | 82 | > Possible extra services: |
|---|
| 76 | 83 | > All content: |
|---|
| 77 | | +> Clipboard |
|---|
| 78 | 84 | > Some content: |
|---|
| 79 | 85 | +> Spellchecking |
|---|
| 80 | 86 | +> Calculator |
|---|
| 81 | | -2> Fixed list of services working on IContent/Content: |
|---|
| 82 | | > Clipboard - can't store Content (callbacks) |
|---|
| 83 | | -> needs to check content type |
|---|
| 84 | | > unless stored as char[] which all content can take |
|---|
| 85 | | -> extra conversions (minor) |
|---|
| 86 | | -> Need to check type of content for specific services |
|---|
| 87 | | +1> List for each type of content: |
|---|
| 88 | | +> can use a static list widget for each type |
|---|
| 89 | | -> clipboard is type specific; need to decide when to convert, etc. |
|---|
| 90 | | ?> enables better copying; e.g. from double 3.5e9 to int 4Ã10â¹ |
|---|
| 91 | | > Use a list of content as the service menu |
|---|
| 92 | | > each item is a BoolContent and has value true if it can interact with the current content type |
|---|
| 93 | | > wrapped in a CollapsibleWidget, displaying based on own value |
|---|
| 94 | 87 | > Context menus: |
|---|
| 95 | 88 | > Context menu serves (editable?) content most directly under mouse cursor |
|---|
| r173 |
r174 |
|
| 25 | 25 | |
|---|
| 26 | 26 | Implement a RootWidget moving functionality out of AWidgetManager, etc., now, or later? |
|---|
| | 27 | RequestRedraw becomes a function of the renderer. |
|---|
| | 28 | |
|---|
| | 29 | Undefined reference problem: (see ~/d/small/tests/compilerErrors/packageFunc.d) |
|---|
| | 30 | Solution: access via a class base instead of an interface base. |
|---|
| | 31 | Two ways to implement: |
|---|
| | 32 | Leave IChildWidget an interface, but change stored refs to AChildWidget and cast references passed in functions before calling member functions. |
|---|
| | 33 | Use AChildWidget directly or an abstract base class instead of IChildWidget, so that interfaced functions can pass the same type stored. |
|---|
| | 34 | Making IChildWidget an abstact class seems to have partially solved it. But IPopupParentWidget (needs to be an interface), etc., still need some help. |
|---|
| | 35 | Presumably setWidth is getting called from IChildWidget instead of AChildWidget now. ?? |
|---|
| | 36 | More link errors with ldc. |
|---|
| 27 | 37 | |
|---|
| 28 | 38 | |
|---|
| … | … | |
| 31 | 41 | 4 Move createWidget code out of WidgetManager. |
|---|
| 32 | 42 | 4 GUI: up-clicks get passed as events and activate objects |
|---|
| | 43 | 3 May be useful to make all widgets override draw() to ensure the invariant runs locally. |
|---|
| 33 | 44 | 3 Closing menus when release-click is not on menu or parent (ordinary & context). |
|---|
| 34 | 45 | 3 Dragging and dropping of editable data: should content immediately appear as being dragged? |
|---|
| r163 |
r174 |
|
| 37 | 37 | 4 Initialisation / cleanup |
|---|
| 38 | 38 | |
|---|
| 39 | | 5 Testing |
|---|
| | 39 | 5 Callbacks |
|---|
| 40 | 40 | |
|---|
| 41 | | 6 Logging |
|---|
| | 41 | 6 Testing |
|---|
| 42 | 42 | |
|---|
| 43 | | 7 Exceptions |
|---|
| | 43 | 7 Logging |
|---|
| 44 | 44 | |
|---|
| 45 | | 8 Translating strings |
|---|
| | 45 | 8 Exceptions |
|---|
| 46 | 46 | |
|---|
| 47 | | 9 Floating point types |
|---|
| | 47 | 9 Translating strings |
|---|
| | 48 | |
|---|
| | 49 | 10 Floating point types |
|---|
| 48 | 50 | |
|---|
| 49 | 51 | |
|---|
| … | … | |
| 102 | 104 | |
|---|
| 103 | 105 | |
|---|
| | 106 | --- Callbacks --- |
|---|
| | 107 | I suggest making callbacks called by external objects public, so that invariants are called. |
|---|
| | 108 | |
|---|
| | 109 | |
|---|
| | 110 | |
|---|
| 104 | 111 | --- Testing --- |
|---|
| 105 | 112 | Testing should, as far as reasonably possible, be done by unittests, defined either in the appropriate module or another module. Any modules containing unittests must be imported by test.mdeTest. |
|---|
| … | … | |
| 139 | 146 | Exceptions should only be used for errors (see comment on log levels above). Thus when an exception is caught, by definition an error occured. |
|---|
| 140 | 147 | |
|---|
| 141 | | Thrown exceptions should, where documented, be documented via the logger. |
|---|
| | 148 | Caught exceptions should be documented via the logger. TODO: work out the best way of incorporating a stack trace. Then lots of specific exception types and messages aren't necessary. |
|---|
| 142 | 149 | |
|---|
| 143 | 150 | Thrown exceptions should use an exception class specific to at least the package involved to enable specific catching of errors. Exception classes should be defined within a module exception.d in the package directory. Exception classes should generally follow the conventions within mde/exception.d to aid in providing reasonable error messages. |
|---|
| r171 |
r174 |
|
| 1 | 1 | {MT01} |
|---|
| 2 | 2 | <char[]|Renderer="Simple"> |
|---|
| 3 | | <char[]|Design="Working"> |
|---|
| | 3 | <char[]|Design="Basic"> |
|---|
| 4 | 4 | {Working} |
|---|
| 5 | 5 | <WidgetData|root={0:[0x4100,0,2,1],1:["bar","float"]}> |
|---|
| … | … | |
| 54 | 54 | {Basic} |
|---|
| 55 | 55 | <WidgetData|root={0:[0x21,0x90D970],1:["A string!"]}> |
|---|
| | 56 | <WidgetData|context={0:[0x4040]}> |
|---|
| r173 |
r174 |
|
| 29 | 29 | import tango.time.Clock; // Clock.now() |
|---|
| 30 | 30 | import tango.util.log.Log : Log, Logger; |
|---|
| 31 | | import tango.core.stacktrace.TraceExceptions; |
|---|
| | 31 | //import tango.core.stacktrace.TraceExceptions; |
|---|
| 32 | 32 | |
|---|
| 33 | 33 | int main(char[][] args) |
|---|
| r173 |
r174 |
|
| 22 | 22 | module mde.gui.WMScreen; |
|---|
| 23 | 23 | |
|---|
| 24 | | import mde.gui.WidgetManager; |
|---|
| | 24 | import mde.gui.widget.WidgetManager; |
|---|
| 25 | 25 | import mde.gui.WidgetLoader; |
|---|
| 26 | 26 | import mde.gui.widget.Ifaces; |
|---|
| … | … | |
| 75 | 75 | |
|---|
| 76 | 76 | /** Draw the gui. */ |
|---|
| 77 | | void draw() { |
|---|
| | 77 | override void draw() { |
|---|
| 78 | 78 | synchronized(mutex) { |
|---|
| 79 | 79 | debug (mdeDrawEvents) |
|---|
| 80 | 80 | logger.trace ("drawing"); |
|---|
| 81 | | wmDrawWidgets(); |
|---|
| | 81 | super.draw; |
|---|
| 82 | 82 | } |
|---|
| 83 | 83 | } |
|---|
| … | … | |
| 110 | 110 | * Should be called before createWidgets to prevent widgets being squashed |
|---|
| 111 | 111 | * to min-dims on loading (losing saved dimensions of columns, etc). */ |
|---|
| 112 | | void sizeEvent (int nw, int nh) { // IDrawable function |
|---|
| 113 | | mutex.lock; |
|---|
| 114 | | scope(exit) mutex.unlock; |
|---|
| 115 | | |
|---|
| 116 | | w = cast(wdim) nw; |
|---|
| 117 | | h = cast(wdim) nh; |
|---|
| 118 | | matchMinimalSize; |
|---|
| 119 | | |
|---|
| 120 | | if (!childRoot) return; // if not created yet. |
|---|
| 121 | | childRoot.setWidth (w, -1); |
|---|
| 122 | | childRoot.setHeight (h, -1); |
|---|
| 123 | | childRoot.setPosition (0,0); |
|---|
| | 112 | override void sizeEvent (int nw, int nh) { // IDrawable function |
|---|
| | 113 | synchronized (mutex) { |
|---|
| | 114 | wmSizeEvent (nw, nh); |
|---|
| | 115 | } |
|---|
| 124 | 116 | } |
|---|
| 125 | 117 | |
|---|
| r171 |
r174 |
|
| 21 | 21 | module mde.gui.WidgetLoader; |
|---|
| 22 | 22 | |
|---|
| 23 | | import mde.gui.WidgetManager; |
|---|
| | 23 | import mde.gui.widget.WidgetManager; |
|---|
| 24 | 24 | import mde.gui.WidgetDataSet; |
|---|
| 25 | 25 | import mde.gui.exception; |
|---|
| r172 |
r174 |
|
| 40 | 40 | * classes provides useful basic implementations for widgets. |
|---|
| 41 | 41 | *****************************************************************************/ |
|---|
| 42 | | abstract class AChildWidget : IChildWidget |
|---|
| | 42 | abstract class AChildWidget : IChildWidget, IWidget |
|---|
| 43 | 43 | { |
|---|
| 44 | 44 | //BEGIN Load and save |
|---|
| … | … | |
| 56 | 56 | |
|---|
| 57 | 57 | // Don't save any data: fine for many widgets. |
|---|
| 58 | | override bool saveChanges () { |
|---|
| | 58 | public override bool saveChanges () { |
|---|
| 59 | 59 | return false; |
|---|
| 60 | 60 | } |
|---|
| … | … | |
| 134 | 134 | |
|---|
| 135 | 135 | /* Dummy functions; many widgets don't need to respond to dragging. */ |
|---|
| 136 | | void dragMotion (wdabs cx, wdabs cy, IChildWidget) {} |
|---|
| 137 | | bool dragRelease (wdabs cx, wdabs cy, IChildWidget) { |
|---|
| | 136 | override void dragMotion (wdabs cx, wdabs cy, IChildWidget) {} |
|---|
| | 137 | override bool dragRelease (wdabs cx, wdabs cy, IChildWidget) { |
|---|
| 138 | 138 | return false; // any widgets not handling events should let them be passed as normal to clickEvent |
|---|
| 139 | 139 | } |
|---|
| 140 | 140 | |
|---|
| 141 | 141 | /* Dummy functions: suitable for widgets with no text input. */ |
|---|
| 142 | | override void keyEvent (ushort, char[]) {} |
|---|
| 143 | | override void keyFocusLost () {} |
|---|
| | 142 | public override void keyEvent (ushort, char[]) {} |
|---|
| | 143 | public override void keyFocusLost () {} |
|---|
| 144 | 144 | |
|---|
| 145 | 145 | // Called when mouse moves over or off this |
|---|
| 146 | 146 | override void underMouse (bool state) {} |
|---|
| 147 | 147 | |
|---|
| 148 | | override bool dropContent (IContent content) { |
|---|
| | 148 | public override bool dropContent (IContent content) { |
|---|
| 149 | 149 | return parent.dropContent (content); |
|---|
| 150 | 150 | } |
|---|
| 151 | 151 | |
|---|
| 152 | 152 | // Only useful to widgets creating popups. |
|---|
| 153 | | override void popupClose () {} |
|---|
| 154 | | override bool popupParentClick () { |
|---|
| | 153 | protected override void popupClose () {} |
|---|
| | 154 | protected override bool popupParentClick () { |
|---|
| 155 | 155 | return true; |
|---|
| 156 | 156 | } |
|---|
| … | … | |
| 158 | 158 | |
|---|
| 159 | 159 | /* Basic draw method: draw the background (all widgets should do this). */ |
|---|
| 160 | | override void draw () { |
|---|
| | 160 | public override void draw () { |
|---|
| | 161 | //TODO: possibly enforce all widgets to implement this so their invariant runs: |
|---|
| | 162 | //assert (false, "all widgets should override draw"); |
|---|
| 161 | 163 | mgr.renderer.drawWidgetBack (x,y, w,h); |
|---|
| 162 | 164 | } |
|---|
| 163 | 165 | |
|---|
| 164 | 166 | // Debug function to print size info. Intended to be correct not optimal. |
|---|
| 165 | | debug override void logWidgetSize () { |
|---|
| | 167 | debug public override void logWidgetSize () { |
|---|
| 166 | 168 | logger.trace ("size: {,4},{,4}; minimal: {,4},{,4}; sizable: {},{} - {,-50} {}", this.width, this.height, this.minWidth, this.minHeight, cast(int)this.isWSizable, cast(int)this.isHSizable, this, id); |
|---|
| 167 | 169 | } |
|---|
| … | … | |
| 212 | 214 | } |
|---|
| 213 | 215 | |
|---|
| | 216 | invariant { |
|---|
| | 217 | assert (w >= mw); |
|---|
| | 218 | assert (h >= mh); |
|---|
| | 219 | } |
|---|
| | 220 | |
|---|
| 214 | 221 | IWidgetManager mgr; // the enclosing window |
|---|
| 215 | 222 | IParentWidget parent; // the parent widget |
|---|
| … | … | |
| 310 | 317 | |
|---|
| 311 | 318 | /// The action triggered when the button is clicked... |
|---|
| 312 | | void activated (); |
|---|
| | 319 | abstract void activated (); |
|---|
| 313 | 320 | |
|---|
| 314 | 321 | protected: |
|---|
| r173 |
r174 |
|
| 59 | 59 | } |
|---|
| 60 | 60 | |
|---|
| 61 | | override bool saveChanges () { |
|---|
| | 61 | public override bool saveChanges () { |
|---|
| 62 | 62 | bool c = false; |
|---|
| 63 | 63 | foreach (w; subWidgets) |
|---|
| … | … | |
| 75 | 75 | |
|---|
| 76 | 76 | // Parents taking a content should override, only throwing if both the |
|---|
| 77 | | // widget id and the content are the same (as its it and content). |
|---|
| 78 | | override void recursionCheck (widgetID wID, IContent c) { |
|---|
| | 77 | // widget id and the content are the same (as its id and content). |
|---|
| | 78 | public override void recursionCheck (widgetID wID, IContent c) { |
|---|
| 79 | 79 | debug assert (id !is null && parent !is null, "recursionCheck called before parent and id set"); |
|---|
| 80 | | if (wID == id) |
|---|
| | 80 | if (wID is id) |
|---|
| 81 | 81 | throw new WidgetRecursionException (wID); |
|---|
| 82 | 82 | parent.recursionCheck (wID, c); |
|---|
| 83 | 83 | } |
|---|
| 84 | 84 | |
|---|
| 85 | | IPopupParentWidget getParentIPPW () { |
|---|
| | 85 | public override IPopupParentWidget getParentIPPW () { |
|---|
| 86 | 86 | return parent.getParentIPPW; |
|---|
| 87 | 87 | } |
|---|
| … | … | |
| 89 | 89 | // Most parent widgets need to implement these, although not all |
|---|
| 90 | 90 | // They must at a minimum make sure widget's size is at least nmw by nmh. |
|---|
| 91 | | override void minWChange (IChildWidget widget, wdim nmw) { |
|---|
| | 91 | public override void minWChange (IChildWidget widget, wdim nmw) { |
|---|
| 92 | 92 | if (widget.width < nmw) |
|---|
| 93 | 93 | widget.setWidth (nmw, -1); |
|---|
| 94 | 94 | } |
|---|
| 95 | | override void minHChange (IChildWidget widget, wdim nmh) { |
|---|
| | 95 | public override void minHChange (IChildWidget widget, wdim nmh) { |
|---|
| 96 | 96 | if (widget.height < nmh) |
|---|
| 97 | 97 | widget.setHeight (nmh, -1); |
|---|
| 98 | 98 | } |
|---|
| 99 | 99 | |
|---|
| 100 | | debug override void logWidgetSize () { |
|---|
| | 100 | debug public override void logWidgetSize () { |
|---|
| 101 | 101 | super.logWidgetSize; |
|---|
| 102 | 102 | foreach (widg; subWidgets) |
|---|
| … | … | |
| 192 | 192 | } |
|---|
| 193 | 193 | |
|---|
| 194 | | debug invariant () { |
|---|
| | 194 | debug invariant { |
|---|
| 195 | 195 | // True as long as removedIPPW gets called: |
|---|
| 196 | | if (!parentIPPW.isChild (this)) { |
|---|
| | 196 | /+TODO: |
|---|
| | 197 | if (!parentIPPW.isChild (this)) { |
|---|
| 197 | 198 | assert (childIPPW is null, "APPW: childIPPW"); |
|---|
| 198 | 199 | assert (mAIPPW is false, "APPW: mAIPPW"); |
|---|
| 199 | | } |
|---|
| | 200 | }+/ |
|---|
| | 201 | } |
|---|
| | 202 | |
|---|
| | 203 | debug override bool isChild (IPopupParentWidget ippw) { |
|---|
| | 204 | return ippw is childIPPW; |
|---|
| 200 | 205 | } |
|---|
| 201 | 206 | |
|---|
| … | … | |
| 207 | 212 | mgr.positionPopup (this, popup); |
|---|
| 208 | 213 | }+/ |
|---|
| 209 | | |
|---|
| 210 | | debug override bool isChild (IPopupParentWidget ippw) { |
|---|
| 211 | | return ippw is childIPPW; |
|---|
| 212 | | } |
|---|
| 213 | 214 | |
|---|
| 214 | 215 | IPopupParentWidget parentIPPW; |
|---|
| r173 |
r174 |
|
| 227 | 227 | return 0; |
|---|
| 228 | 228 | } |
|---|
| 229 | | void dragMotion (wdabs cx, wdabs cy, IChildWidget) { |
|---|
| | 229 | override void dragMotion (wdabs cx, wdabs cy, IChildWidget) { |
|---|
| 230 | 230 | if (resizeType == RESIZE.NONE) { |
|---|
| 231 | 231 | with (sWData[active]) { |
|---|
| … | … | |
| 289 | 289 | } |
|---|
| 290 | 290 | } |
|---|
| 291 | | bool dragRelease (wdabs, wdabs, IChildWidget) { |
|---|
| | 291 | override bool dragRelease (wdabs, wdabs, IChildWidget) { |
|---|
| 292 | 292 | return true; // we've handled the up-click |
|---|
| 293 | 293 | } |
|---|
| r172 |
r174 |
|
| 27 | 27 | * It's recommended that widgets inherit one of the A*Widget classes rather |
|---|
| 28 | 28 | * than impement I*Widget directly. |
|---|
| | 29 | * |
|---|
| | 30 | * Protection: please keep it as tight as possible. List it explicitly for |
|---|
| | 31 | * every function in this module; then the compiler checks overridden functions |
|---|
| | 32 | * have the correct protection attribute. |
|---|
| | 33 | * BUG: currently it's a bit of a mess, because of a compiler bug. |
|---|
| 29 | 34 | *****************************************************************************/ |
|---|
| 30 | 35 | module mde.gui.widget.Ifaces; |
|---|
| … | … | |
| 50 | 55 | * Actually the return value is ignored; I think widgets still return it |
|---|
| 51 | 56 | * correctly though. */ |
|---|
| 52 | | bool saveChanges (); |
|---|
| | 57 | public bool saveChanges (); |
|---|
| | 58 | |
|---|
| | 59 | /** Draw, using the stored values of x and y. |
|---|
| | 60 | * |
|---|
| | 61 | * Maybe later enforce clipping of all sub-widget drawing, particularly for cases where only |
|---|
| | 62 | * part of the widget is visible: scroll bars or a hidden window. */ |
|---|
| | 63 | public void draw (); |
|---|
| 53 | 64 | |
|---|
| 54 | 65 | /** Called on a widget when something is dragged onto it. |
|---|
| … | … | |
| 56 | 67 | * Generally, content editing widgets should implement this as: |
|---|
| 57 | 68 | * --- |
|---|
| 58 | | override bool dropContent (IContent content) { |
|---|
| | 69 | public override bool dropContent (IContent content) { |
|---|
| 59 | 70 | if (content_.setContent (content)) |
|---|
| 60 | 71 | return true; |
|---|
| … | … | |
| 69 | 80 | * Returns: true if the content was received (false if it reaches the |
|---|
| 70 | 81 | * WidgetManager and is still not used). */ |
|---|
| 71 | | bool dropContent (IContent content); |
|---|
| | 82 | public bool dropContent (IContent content); |
|---|
| 72 | 83 | } |
|---|
| 73 | 84 | |
|---|
| … | … | |
| 84 | 95 | interface IParentWidget : IWidget |
|---|
| 85 | 96 | { |
|---|
| 86 | | /** Checks for recursion of unsafe widgets to prevent infinite recursion. */ |
|---|
| | 97 | /** Checks for recursion of unsafe widgets to prevent infinite recursion. |
|---|
| | 98 | * |
|---|
| | 99 | * Only called by makeWidget() when creating child widgets and recursively |
|---|
| | 100 | * from the same method in a child widget. */ |
|---|
| 87 | 101 | void recursionCheck (widgetID, IContent); |
|---|
| 88 | 102 | |
|---|
| … | … | |
| 94 | 108 | * |
|---|
| 95 | 109 | * Parents $(I must) increase their child's size if the child is too small. |
|---|
| 96 | | * Parents $(I must not) decrease their own size, even if they are not |
|---|
| 97 | | * sizable; they may only decrease their childrens' sizes if it does not |
|---|
| 98 | | * affect their own (i.e. WidgetManager and FloatingAreaWidget). |
|---|
| | 110 | * Parents $(I must not) change their own size, even if they are not |
|---|
| | 111 | * sizable; they may only change their childrens' sizes if it does not |
|---|
| | 112 | * affect their own (i.e. WidgetManager and floating / popup widgets). |
|---|
| | 113 | * |
|---|
| | 114 | * (Hence most parents need to call this function on their parents to change |
|---|
| | 115 | * size. In this case they also must propegate setWidth/setHeight calls on |
|---|
| | 116 | * the child originally calling min[WH]Change.) |
|---|
| 99 | 117 | * |
|---|
| 100 | 118 | * Child widgets may depend on setPosition being called afterwards. |
|---|
| … | … | |
| 115 | 133 | * Note: ANY_SUBWIDGETS can cause problems like enlarging a menu bar containing a resizable |
|---|
| 116 | 134 | * blank instead of the main part of a window. */ |
|---|
| 117 | | enum SIZABILITY_ENUM { |
|---|
| | 135 | protected enum SIZABILITY_ENUM { |
|---|
| 118 | 136 | NEVER = 0, /// Parents are never resizable |
|---|
| 119 | 137 | ALL_SUBWIDGETS = 3, /// Parents are only resizable if all sub-widgets are |
|---|
| … | … | |
| 123 | 141 | SUBWIDGETS = 2, /// Flag set by ALL_SUBWIDGETS and ANY_SUBWIDGETS |
|---|
| 124 | 142 | } |
|---|
| 125 | | static const SIZABILITY = SIZABILITY_ENUM.ANY_SUBWIDGETS; /// ditto |
|---|
| | 143 | protected static const SIZABILITY = SIZABILITY_ENUM.ANY_SUBWIDGETS; /// ditto |
|---|
| 126 | 144 | } |
|---|
| 127 | 145 | |
|---|
| … | … | |
| 333 | 351 | *****************************************************************************/ |
|---|
| 334 | 352 | //NOTE: add another this() without the data for default initialization, for the GUI editor? |
|---|
| 335 | | interface IChildWidget : IWidget |
|---|
| | 353 | abstract class IChildWidget : IWidget |
|---|
| 336 | 354 | { |
|---|
| 337 | 355 | //BEGIN Load and save |
|---|
| … | … | |
| 352 | 370 | * The method must return true on initial setup and if its dimensions |
|---|
| 353 | 371 | * (may) have changed. */ |
|---|
| 354 | | bool setup (uint n, uint flags); |
|---|
| | 372 | bool setup (uint n, uint flags) {return 0;} |
|---|
| 355 | 373 | |
|---|
| 356 | 374 | /+ Use when widget editing is available? Requires widgets to know their parents. |
|---|
| … | … | |
| 370 | 388 | * Parents normally take their resizability from sub-widgets; see SIZABILITY for how they do |
|---|
| 371 | 389 | * this. */ |
|---|
| 372 | | bool isWSizable (); |
|---|
| 373 | | bool isHSizable (); /// ditto |
|---|
| | 390 | bool isWSizable () {return 0;} |
|---|
| | 391 | bool isHSizable () {return 0;} /// ditto |
|---|
| 374 | 392 | |
|---|
| 375 | 393 | /** The minimal size the widget could be shrunk to (or its fixed size). |
|---|
| 376 | 394 | * |
|---|
| 377 | 395 | * Takes into account child-widgets and any other contents. */ |
|---|
| 378 | | wdim minWidth (); |
|---|
| 379 | | wdim minHeight (); /// ditto |
|---|
| | 396 | wdim minWidth () {return 0;} |
|---|
| | 397 | wdim minHeight() {return 0;} /// ditto |
|---|
| 380 | 398 | |
|---|
| 381 | 399 | /** Get the current size of the widget. */ |
|---|
| 382 | | wdim width (); |
|---|
| 383 | | wdim height(); /// ditto |
|---|
| | 400 | wdim width () {return 0;} |
|---|
| | 401 | wdim height() {return 0;} /// ditto |
|---|
| 384 | 402 | |
|---|
| 385 | 403 | /** (Smallest) coordinates of widget. */ |
|---|
| 386 | | wdabs xPos (); |
|---|
| 387 | | wdabs yPos (); /// ditto |
|---|
| | 404 | wdabs xPos () {return 0;} |
|---|
| | 405 | wdabs yPos () {return 0;} /// ditto |
|---|
| 388 | 406 | |
|---|
| 389 | 407 | /** Used to adjust the size. |
|---|
| … | … | |
| 401 | 419 | * |
|---|
| 402 | 420 | * setPosition must be called after calling either setWidth or setHeight. */ |
|---|
| 403 | | void setWidth (wdim nw, int dir); |
|---|
| 404 | | void setHeight (wdim nh, int dir); /// ditto |
|---|
| | 421 | void setWidth (wdim nw, int dir) {} |
|---|
| | 422 | void setHeight (wdim nh, int dir) {} /// ditto |
|---|
| 405 | 423 | |
|---|
| 406 | 424 | /** Set the current position (called after setup and to move widget). */ |
|---|
| 407 | | void setPosition (wdim x, wdim y); |
|---|
| | 425 | void setPosition (wdim x, wdim y) {} |
|---|
| 408 | 426 | //END Size and position |
|---|
| 409 | 427 | |
|---|
| 410 | 428 | //BEGIN Content |
|---|
| 411 | 429 | /** Return the widget's content, or null. */ |
|---|
| 412 | | IContent content (); |
|---|
| | 430 | IContent content () {return null;} |
|---|
| 413 | 431 | |
|---|
| 414 | 432 | /** Set the widget's content, if the widget takes content and changing it |
|---|
| 415 | 433 | * at this stage is feasible. (Also pass to sub-widgets, where the |
|---|
| 416 | 434 | * constructor normally does so.) */ |
|---|
| 417 | | void setContent (IContent); |
|---|
| | 435 | void setContent (IContent) {} |
|---|
| 418 | 436 | //END Content |
|---|
| 419 | 437 | |
|---|
| … | … | |
| 428 | 446 | * |
|---|
| 429 | 447 | * Note: use global coordinates (cx,cy) not coordinates relative to the widget. */ |
|---|
| 430 | | IChildWidget getWidget (wdabs cx, wdabs cy); |
|---|
| | 448 | IChildWidget getWidget (wdabs cx, wdabs cy) {return null;} |
|---|
| 431 | 449 | |
|---|
| 432 | 450 | /** Return true if (cx,cy) is on self's box (doesn't matter if actually on a subwidget). */ |
|---|
| 433 | | bool onSelf (wdabs cx, wdabs cy); |
|---|
| | 451 | bool onSelf (wdabs cx, wdabs cy) {return 0;} |
|---|
| 434 | 452 | |
|---|
| 435 | 453 | /** Receive a mouse click event at cx,cy from button b (1-5 correspond to L,M,B, wheel up,down) |
|---|
| … | … | |
| 444 | 462 | * $(TR $(TD 4) $(TD Display the widget's content while dragging (requires 2))) |
|---|
| 445 | 463 | * ) */ |
|---|
| 446 | | int clickEvent (wdabs cx, wdabs cy, ubyte b, bool state); |
|---|
| | 464 | int clickEvent (wdabs cx, wdabs cy, ubyte b, bool state) {return 0;} |
|---|
| 447 | 465 | |
|---|
| 448 | 466 | /** Called when dragging motion occurs, originating from this widget. |
|---|
| … | … | |
| 451 | 469 | * |
|---|
| 452 | 470 | * Only called if requested by clickEvent. */ |
|---|
| 453 | | void dragMotion (wdabs cx, wdabs cy, IChildWidget target); |
|---|
| | 471 | void dragMotion (wdabs cx, wdabs cy, IChildWidget target) {} |
|---|
| 454 | 472 | |
|---|
| 455 | 473 | /** Called at the end of a drag which originated from this widget. |
|---|
| … | … | |
| 461 | 479 | * |
|---|
| 462 | 480 | * Only called if requested by clickEvent. */ |
|---|
| 463 | | bool dragRelease (wdabs cx, wdabs cy, IChildWidget target); |
|---|
| | 481 | bool dragRelease (wdabs cx, wdabs cy, IChildWidget target) {return 0;} |
|---|
| 464 | 482 | |
|---|
| 465 | 483 | /** Receives keyboard events when requested. |
|---|
| … | … | |
| 468 | 486 | * sym SDLKey key sym, useful for keys with no character code such as arrow keys |
|---|
| 469 | 487 | * letter The character input, in UTF-8 */ |
|---|
| 470 | | void keyEvent (ushort sym, char[] letter); |
|---|
| | 488 | public void keyEvent (ushort sym, char[] letter); |
|---|
| 471 | 489 | |
|---|
| 472 | 490 | /** Called when keyboard input focus is lost. */ |
|---|
| 473 | | void keyFocusLost (); |
|---|
| | 491 | public void keyFocusLost (); |
|---|
| 474 | 492 | |
|---|
| 475 | 493 | /** Called on all widgets when the mouse moves over it (state == true) and |
|---|
| 476 | 494 | * when it leaves (state == false). */ |
|---|
| 477 | | void underMouse (bool state); |
|---|
| | 495 | void underMouse (bool state) {} |
|---|
| 478 | 496 | |
|---|
| 479 | 497 | /** When a pop-up is closed the manager calls requestRedraw and this function on its parent. */ |
|---|
| 480 | | void popupClose (); |
|---|
| | 498 | protected void popupClose (); |
|---|
| 481 | 499 | /** When a click is on the parent of a popup, this function is called instead of the usual |
|---|
| 482 | 500 | * clickEvent. |
|---|
| … | … | |
| 486 | 504 | * |
|---|
| 487 | 505 | * Note: this means the parent can't receive text input without code changes. */ |
|---|
| 488 | | bool popupParentClick (); |
|---|
| | 506 | protected bool popupParentClick (); |
|---|
| 489 | 507 | |
|---|
| 490 | 508 | //END Events |
|---|
| 491 | 509 | |
|---|
| 492 | | /** Draw, using the stored values of x and y. |
|---|
| 493 | | * |
|---|
| 494 | | * Maybe later enforce clipping of all sub-widget drawing, particularly for cases where only |
|---|
| 495 | | * part of the widget is visible: scroll bars or a hidden window. */ |
|---|
| 496 | | void draw (); |
|---|
| 497 | | |
|---|
| 498 | 510 | /// Logs the current and minimal size of every widget. |
|---|
| 499 | | debug void logWidgetSize (); |
|---|
| | 511 | debug public void logWidgetSize (); |
|---|
| 500 | 512 | } |
|---|
| r173 |
r174 |
|
| 469 | 469 | protected: |
|---|
| 470 | 470 | invariant { |
|---|
| 471 | | // this() calls makeWidget() which calls recursionCheck(); invariant is called at this point before this() finishes |
|---|
| 472 | | if (subWidgets.length) { |
|---|
| 473 | | assert (subWidgets.length == 1); |
|---|
| 474 | | assert (mw == subWidgets[0].minWidth + border.x1 + border.x2); |
|---|
| 475 | | assert (mh == subWidgets[0].minHeight + border.y1 + border.y2); |
|---|
| 476 | | } |
|---|
| | 471 | /+TODO |
|---|
| | 472 | assert (subWidgets.length == 1); |
|---|
| | 473 | assert (mw == subWidgets[0].minWidth + border.x1 + border.x2); |
|---|
| | 474 | assert (mh == subWidgets[0].minHeight + border.y1 + border.y2); |
|---|
| | 475 | +/ |
|---|
| 477 | 476 | } |
|---|
| 478 | 477 | |
|---|
| r172 |
r174 |
|
| 71 | 71 | * |
|---|
| 72 | 72 | * Widget uses the initialisation data: |
|---|
| 73 | | * [widgetID, contentID, colour] |
|---|
| | 73 | * ints: [widgetID, colour] |
|---|
| | 74 | * strings: [text] |
|---|
| 74 | 75 | * where contentID is an ID for the string ID of the contained content |
|---|
| 75 | 76 | * and colour is an 8-bit-per-channel RGB colour of the form 0xRRGGBB. */ |
|---|
| … | … | |
| 187 | 188 | } |
|---|
| 188 | 189 | |
|---|
| 189 | | override void keyEvent (ushort s, char[] i) { |
|---|
| | 190 | public override void keyEvent (ushort s, char[] i) { |
|---|
| 190 | 191 | adapter.text = content_.keyStroke (s, i); |
|---|
| 191 | 192 | adapter.index = content_.editIndex; |
|---|
| … | … | |
| 198 | 199 | mgr.requestRedraw; |
|---|
| 199 | 200 | } |
|---|
| 200 | | override void keyFocusLost () { |
|---|
| | 201 | public override void keyFocusLost () { |
|---|
| 201 | 202 | content_.endEdit; |
|---|
| 202 | 203 | adapter.text = content_.toString (0); |
|---|
| r170 |
r174 |
|
| 28 | 28 | import mde.content.AStringContent; |
|---|
| 29 | 29 | import mde.content.miscContent; |
|---|
| | 30 | |
|---|
| 30 | 31 | |
|---|
| 31 | 32 | /****************************************************************************** |
|---|
| r172 |
r174 |
|
| 130 | 130 | } |
|---|
| 131 | 131 | |
|---|
| 132 | | override bool dropContent (IContent content) { |
|---|
| | 132 | public override bool dropContent (IContent content) { |
|---|
| 133 | 133 | if (cList.set (content)) |
|---|
| 134 | 134 | return true; |
|---|
| … | … | |
| 364 | 364 | } |
|---|
| 365 | 365 | |
|---|
| 366 | | package: |
|---|
| | 366 | private: |
|---|
| 367 | 367 | /* Calculations which need to be run whenever a new sub-widget structure is set |
|---|
| 368 | 368 | * or other changes affecting widget sizes. Most of these need to happen regardless of whether |
|---|
| … | … | |
| 440 | 440 | } |
|---|
| 441 | 441 | |
|---|
| 442 | | private: |
|---|
| 443 | 442 | override void setColWidth (size_t i, wdim w, int dir) { |
|---|
| 444 | 443 | for (size_t j = 0; j < rows; ++j) { |
|---|
| … | … | |
| 910 | 909 | alias IParentWidget.SIZABILITY_ENUM SIZABILITY_ENUM; |
|---|
| 911 | 910 | |
|---|
| 912 | | debug invariant() |
|---|
| | 911 | invariant |
|---|
| 913 | 912 | { |
|---|
| 914 | 913 | if (setupWidths) { |
|---|