cleaned all trailing white space from source files.
[sdk] / ecere / src / gui / controls / DataBox.ec
1 namespace gui::controls;
2
3 import "Window"
4
5 default:
6 extern int __ecereVMethodID_class_OnGetString;
7 extern int __ecereVMethodID_class_OnGetDataFromString;
8 extern int __ecereVMethodID_class_OnCompare;
9 extern int __ecereVMethodID_class_OnSerialize;
10 extern int __ecereVMethodID_class_OnUnserialize;
11 extern int __ecereVMethodID_class_OnFree;
12 extern int __ecereVMethodID_class_OnEdit;
13 extern int __ecereVMethodID_class_OnCopy;
14 extern int __ecereVMethodID_class_OnDisplay;
15 extern int __ecereVMethodID_class_OnSaveEdit;
16 private:
17
18 public class DataBox : CommonControl
19 {
20 public:
21    Class type;
22    void * data;
23    void * fieldData;
24    Window editor;
25    bool readOnly;
26    bool keepEditor;
27    bool autoSize;
28    bool needUpdate;
29    String stringValue;
30    needUpdate = true;
31
32    ~DataBox()
33    {
34       delete stringValue;
35    }
36
37    virtual void SetData(any_object newData, bool closingDropDown)
38    {
39       //((void (*)(void *, void *, void *))(void *)type._vTbl[__ecereVMethodID_class_OnCopy])(type, data, newData);
40       needUpdate = true;
41       if(type)
42       {
43          if(type.type == normalClass || type.type == noHeadClass)
44          {
45             if(((void **)data)[0])
46                ((void (*)(void *, void *))(void *)type._vTbl[__ecereVMethodID_class_OnFree])(type, ((void **)data)[0]);
47             ((void **)data)[0] = newData;
48          }
49          else
50          {
51             // Free old data first
52             ((void (*)(void *, void *))(void *)type._vTbl[__ecereVMethodID_class_OnFree])(type, data);
53             ((void (*)(void *, void *, void *))(void *)type._vTbl[__ecereVMethodID_class_OnCopy])(type, data, newData);
54          }
55       }
56       if(created)
57          NotifyChanged(master, closingDropDown);
58       //editor.Activate();
59    }
60
61    bool SaveData()      // TODO: Clear this up, along with Saving DataBox
62    {
63       if(editor && ((bool (*)(void *, void *, Window, void *))(void *)type._vTbl[__ecereVMethodID_class_OnSaveEdit])(type, data, editor, null))
64       {
65          Refresh();
66          NotifyChanged(master, false);
67          // Refresh();
68          return true;
69       }
70       return false;
71    }
72
73    void Modified()
74    {
75       NotifyModified(master);
76    }
77
78    void Refresh()
79    {
80       needUpdate = true;
81       if(created)
82       {
83          if(!keepEditor)
84          {
85             editor.Destroy(0);
86             editor = null;
87          }
88          OnPostCreate();
89       }
90    }
91
92    virtual bool Window::NotifyModified();
93    virtual bool Window::NotifyChanged(bool closingDropDown);
94    virtual void OnConfigure(Window editor);
95
96 private:
97    bool inAutoSize;
98
99    bool OnPostCreate()
100    {
101       // Right now for read-only DataBoxes the only reason we'd want to create an editor is for autoSize purposes, when using the default EditBox editor that supports it.
102       // ( A tweak for enum classes is in typeEdit.ec, as the base class editor invokes it )
103       if(type && (!readOnly || (autoSize && type._vTbl[__ecereVMethodID_class_OnEdit] == class(Instance)._vTbl[__ecereVMethodID_class_OnEdit])) &&
104          (type.type == normalClass || type.type == noHeadClass || data))
105       {
106          // IMPORTANT FIX: If keepEditor is true, we were passing editor rather than the editor's current master
107          editor = ((Window (*)(void *, void *, DataBox, void *, int, int, int, int, void*))(void *)type._vTbl[__ecereVMethodID_class_OnEdit])(type,
108             (type.type == normalClass || type.type == noHeadClass) ? (data ? (*(void **)data) : null) : data,
109             this, (keepEditor && editor) ? editor.master : this, 0, 0, clientSize.w, clientSize.h, fieldData);// null);
110          if(editor)
111          {
112             // editor.anchor = { 0, 0, 0, 0 };
113             editor.background = background;
114             editor.foreground = foreground;
115             editor.opacity = opacity;
116 /*#if _DEBUG
117             if(autoSize)
118                PrintLn("DataBox::OnPostCreate -- autoSize == true");
119 #endif*/
120             if(eClass_IsDerived(editor._class, class(EditBox)))
121             {
122                ((EditBox)editor).readOnly = readOnly;
123                ((EditBox)editor).autoSize = autoSize;
124                ((EditBox)editor).clickThrough = true;
125             }
126          }
127          else
128          {
129             // TODO: Should returning 0 from OnPostCreate cancel creation?
130             Destroy(0);
131             return false;
132          }
133       }
134       return true;
135    }
136
137    void OnRedraw(Surface surface)
138    {
139       if(type && (!editor || !editor.created || editor.anchor.left)) // ColorDropBox lets part of the DataBox show
140       {
141          char tempString[1024];
142          if(type._vTbl[__ecereVMethodID_class_OnDisplay] == class(Instance)._vTbl[__ecereVMethodID_class_OnDisplay])
143          {
144             if(needUpdate)
145             {
146                String s;
147                if(type.type == noHeadClass || type.type == normalClass)
148                   s = ((char *(*)(void *, void *, char *, void *, bool *))(void *)type._vTbl[__ecereVMethodID_class_OnGetString])(type, *(void **)this.data, tempString, fieldData, null);
149                else
150                   s = ((char *(*)(void *, void *, char *, void *, bool *))(void *)type._vTbl[__ecereVMethodID_class_OnGetString])(type, this.data, tempString, fieldData, null);
151                delete stringValue;
152                stringValue = CopyString(s);
153                needUpdate = false;
154             }
155             ((void (*)(void *, void *, void *, int, int, int, void *, uint, uint))(void *)class(String)._vTbl[__ecereVMethodID_class_OnDisplay])(class(String), stringValue, surface, 3, 1, clientSize.w, fieldData, type.defaultAlignment, 0);
156          }
157          else
158          {
159             if(type.type == noHeadClass || type.type == normalClass)
160                ((void (*)(void *, void *, void *, int, int, int, void *, uint, uint))(void *)type._vTbl[__ecereVMethodID_class_OnDisplay])(type, *(void **)this.data, surface, 3, 1, clientSize.w, fieldData, type.defaultAlignment, 0);
161             else
162                ((void (*)(void *, void *, void *, int, int, int, void *, uint, uint))(void *)type._vTbl[__ecereVMethodID_class_OnDisplay])(type, this.data, surface, 3, 1, clientSize.w, fieldData, type.defaultAlignment, 0);
163          }
164       }
165    }
166
167    void OnDestroy()
168    {
169       editor = null;
170       CommonControl::OnDestroy();
171    }
172
173    void OnPosition(int x, int y, int width, int height)
174    {
175       if(editor)
176          editor.OnPosition(editor.position.x, editor.position.y, editor.size.w, editor.size.h);
177    }
178
179    bool OnKeyHit(Key key, unichar ch)
180    {
181       return editor ? editor.OnKeyHit(key, ch) : true;
182    }
183
184    bool OnKeyDown(Key key, unichar ch)
185    {
186       if((SmartKey)key == enter)
187       {
188          SaveData();
189          return false;
190       }
191       else if((SmartKey)key == escape)
192       {
193          Refresh();
194          return true;
195       }
196       return editor ? editor.OnKeyDown(key, ch) : true;
197    }
198
199    void OnChildResized(Window child, int x, int y, int w, int h)
200    {
201       if(!inAutoSize && autoSize == true)
202       {
203          inAutoSize = true;
204          clientSize = { w, h };
205          inAutoSize = false;
206       }
207    }
208 };
209
210 public class SavingDataBox : DataBox
211 {
212    class_property(icon) = "<:ecere>controls/dataBox.png";
213    borderStyle = deep;
214    bool OnActivate(bool active, Window previous, bool * goOnWithActivation, bool direct)
215    {
216       if(!active && editor && !editor.modalSlave)
217       {
218          if(!SaveData())
219             Refresh();
220       }
221       return true;
222    }
223
224    bool OnKeyDown(Key key, unichar ch)
225    {
226       if((SmartKey)key == enter)
227       {
228          if(!SaveData())
229             // Force Refresh on Enter if SaveData didn't do it
230             Refresh();
231          return true;
232       }
233       return DataBox::OnKeyDown(key, ch);
234    }
235
236    bool OnResizing(int * w, int * h)
237    {
238       if(!*w || !*h)
239       {
240          int spaceH;
241          display.FontExtent(fontObject, " ", 1, null, &spaceH);
242          if(!*h)
243             *h = spaceH + 2;
244          if(!*w)
245             *w = spaceH * 80 / 14;
246       }
247       return true;
248    }
249 }