274912b15398a8b829d3c1b26ab74e2eb6ec3e2d
[sdk] / ecere / src / gui / controls / DropBox.ec
1 namespace gui::controls;
2
3 import "Window"
4
5 #include <stdarg.h>
6
7 //#define BTN_WIDTH       20
8 #define BTN_WIDTH       16
9 #define ROW_HEIGHT      listBox.rowHeight /*16*/
10
11 default:
12 extern int __ecereVMethodID_class_OnDisplay;
13 extern int __ecereVMethodID_class_OnGetString;
14
15 private:
16
17 class DropBoxBits { bool noHighlight:1, noStipple:1, editText:1, activeColor:1, showNone:1, changeContents:1; };
18
19 public class DropBox : CommonControl
20 {
21    tabCycle = true;
22    borderStyle = deep;
23    style.activeColor = true;
24
25    class_property(icon) = "<:ecere>controls/dropBox.png";
26
27    watch(foreground)
28    {
29       listBox.foreground = foreground;
30    };
31    watch(background)
32    {
33       listBox.background = background;
34    };
35
36 public:
37    property bool activeStipple
38    {
39       property_category "Appearance" 
40       set
41       {
42          style.noStipple = !value;
43          Update(null);
44       }
45       get { return !style.noStipple; }
46    };
47    property bool showButton
48    {
49       property_category "Appearance" 
50       set
51       {
52          button.visible = value;
53          listBox.borderStyle = value ? contour : none;
54       }
55       get { return button.visible; }
56    };
57    property Alignment alignment
58    {
59       property_category "Appearance" 
60       set
61       {
62          alignment = value;
63          if(field)
64             field.alignment = value;
65       }
66       get { return alignment; }
67    };
68    property bool noHighlight
69    {
70       property_category "Appearance" 
71       set
72       {
73          if(this)
74          {
75             style.noHighlight = value;
76             listBox.fullRowSelect = !value;
77             Update(null);
78          }
79       }
80       get { return style.noHighlight; }
81    };
82    property bool activeColor
83    {
84       property_category "Appearance" 
85       set
86       {
87          if(this)
88          {
89             style.activeColor = value;
90             Update(null);
91          }
92       }
93       get { return style.activeColor; }
94    };
95    property DataRow currentRow
96    {
97       property_category "Private" 
98       set
99       {
100          if(this)
101          {
102             currentRow = value;
103             listBox.currentRow = value ? value : (style.showNone ? noneRow : null);
104             if(style.editText && style.changeContents)
105             {
106                char tempString[4096];
107                if(currentRow)
108                   editBox.contents = (char *)dataType._vTbl[__ecereVMethodID_class_OnGetString](dataType, currentRow.GetData(null), tempString, null, null);
109                else
110                   editBox.contents = "";
111             }                  
112             Update(null);
113             if(style.editText)
114             {
115                if(editBox.modifiedDocument)
116                {
117                   NotifyTextEntry(master, this, editBox.contents, false);
118                   editBox.modifiedDocument = false;
119                }
120                // editBox.Deactivate();
121             }
122          }
123       }
124       get { return currentRow; }
125    };
126    property DataRow firstRow { get { return this ? listBox.firstRow : null; } };
127    property char * contents { property_category "Data" set { if(editBox) editBox.contents = value; } get { return editBox ? editBox.contents : null; } };
128    property bool editText
129    {
130       property_category "Behavior" 
131       set
132       {
133          if(this)
134          {
135             if(value)
136             {
137                if(!editBox)
138                {
139                   editBox = EditBox
140                   {
141                      this, textHorzScroll = true, borderStyle = 0;
142                      anchor = Anchor { left = 0, top = 0, right = BTN_WIDTH, bottom = 0 };
143                      // visible = false, modifyVirtualArea = false;
144                   };
145                   incref editBox;
146                   editBox.Create();
147                   button.inactive = false;
148                }      
149                style.editText = true;
150                tabCycle = false;
151             }
152             else
153             {
154                if(editBox)
155                {
156                   editBox.Destroy(0);
157                   delete editBox;
158                   button.inactive = true;
159                }
160                style.editText = false;
161             }
162          }
163       }
164       get { return style.editText; }
165    };
166    property EditBox editBox { get { return editBox; } }
167    property Seconds typingTimeout { property_category "Behavior" set { listBox.typingTimeout = value; } get { return listBox.typingTimeout; } };
168    property int rowHeight { property_category "Appearance" set { listBox.rowHeight = value; } get { return listBox.rowHeight; } };
169    property int maxShown
170    {
171       property_category "Behavior" 
172       set
173       {
174          listBoxMaxShown = value;
175          OnPosition(position.x, position.y, clientSize.w, clientSize.h);
176       }
177       get { return listBoxMaxShown; }
178    };
179    property Window pullDown
180    {
181       get { return pulledWindow; }
182    }
183    property bool showNone
184    {
185       set
186       {
187          if(value != style.showNone)
188          {
189             if(style.showNone)
190             {
191                listBox.DeleteRow(noneRow);
192                noneRow = null;
193             }
194             style.showNone = value;
195             if(value)
196             {
197                noneRow = listBox.AddRowNone();
198             }
199          }
200       }
201       get { return style.showNone; }
202    }
203    property Color selectionColor { set { selectionColor = value; } get { return selectionColor; } isset { return selectionColor ? true : false; } };
204    property bool changeContents
205    {
206       set { style.changeContents = value; }
207       get { return style.changeContents; }
208    }
209
210    property ListBox listBox { get { return listBox; } }
211
212    // Notifications
213    virtual bool Window::NotifySelect(DropBox dropBox, DataRow row, Modifiers mods);
214    virtual bool Window::NotifyClose(DropBox dropBox);
215    virtual bool Window::NotifyHighlight(DropBox dropBox, DataRow row, Modifiers mods);
216    virtual bool Window::NotifyTextEntry(DropBox dropBox, char * string, bool confirmed);
217
218    virtual Window OnDropDown()
219    {
220       // NASTY BUG ON WINDOWS IN PROPERTIES SHEET IF WE DON'T RECREATE THE LISTBOX HERE
221       // To reproduce, comment out, select borderStyle property, alt-tab to another program, come back, drop down
222       // The listBox goes annoyingly to 0, 0
223       listBox.Destroy(0);
224       listBox.Create();
225
226       ResizeListbox();
227       // listBox.visible = true;
228       return listBox;   
229    }
230
231    virtual void OnCloseDropDown(Window pullDown)
232    {
233       listBox.visible = false;
234       if(style.editText)
235       {
236          editBox.ActivateEx(true, false, false, false, null, null);
237          editBox.SelectAll();
238       }
239    }
240
241    // Methods
242    DataRow AddStringf(char * format, ...)
243    {
244       if(this)
245       {
246          DataRow row;
247
248          char string[MAX_F_STRING];
249          va_list args;
250
251          va_start(args, format);
252          vsprintf(string, format, args);
253          va_end(args);
254
255          row = AddRow();
256          row.SetData(null, string);
257          return row;
258       }
259       return null;
260    }
261
262    DataRow AddString(char * string)
263    {
264       if(this)
265       {
266          DataRow row;
267          row = AddRow();
268          row.SetData(null, string);
269          return row;
270       }
271       return null;
272    }
273
274    void DeleteRow(DataRow row)
275    {
276       if(!row) row = currentRow;
277       listBox.DeleteRow(row);
278       /*
279       if(row == currentRow)
280          currentRow = null;*/
281       Update(null);
282    }
283
284    // Convenience function using current rows
285    int GetTag()
286    {
287       return currentRow.tag;
288    }
289
290    void * SetData(DataField field, any_object data)
291    {
292       if(this)
293       {
294          if(currentRow)
295             return currentRow.SetData(field, data);
296       }
297       return null;
298    }
299
300    any_object GetData(DataField field)
301    {
302       if(this)
303       {
304          // TODO: Fix this shouldn't be required (memguard?)
305          return (void *)currentRow.GetData(field);
306       }
307       return null;
308    }
309
310    void Sort(DataField field, int order)
311    {
312       listBox.Sort(field, order);
313    }
314
315    void AddField(DataField field)
316    {
317       if(this)
318       {
319          if(!field)
320             field = DataField { alignment = alignment };
321          
322          listBox.AddField(field);
323          this.field = listBox.firstField;
324          dataType = this.field.dataType;
325       }
326    }
327
328    DataRow AddRow()
329    {
330       DataRow row = null;
331       if(this)
332       {
333          row = listBox.AddRow();
334          OnPosition(position.x, position.y, clientSize.w, clientSize.h);
335       }
336       return row;
337    }
338
339    DataRow AddRowAfter(DataRow after)
340    {
341       DataRow row = null;
342       if(this)
343       {
344          row = listBox.AddRowAfter(after);
345          OnPosition(position.x, position.y, clientSize.w, clientSize.h);
346       }
347       return row;
348    }
349
350    int GetRowCount()
351    {
352       return listBox.rowCount;
353    }
354
355    void Clear()
356    {
357       if(this)
358       {
359          Window master = this.master;
360          listBox.Clear();
361
362          if(currentRow && master)
363          {
364             currentRow = null;
365             NotifySelect(master, this, null, 0);
366          }
367          currentRow = null;
368          if(style.editText && style.changeContents)
369             editBox.contents = "";
370          Update(null);
371          if(style.showNone)
372             noneRow = listBox.AddRowNone();
373       }
374    }
375
376    DataRow FindRow(int tag)
377    {
378       if(this)
379       {
380          return listBox.FindRow(tag);
381       }
382       return null;
383    }
384
385    DataRow FindSubRow(int tag)
386    {
387       if(this)
388       {
389          return listBox.FindSubRow(tag);
390       }
391       return null;
392    }
393
394    // Drop Box Specific
395    void SelectRow(DataRow row)
396    {
397       if(this)
398       {
399          currentRow = row;
400          if(style.editText && style.changeContents)
401          {
402             char tempString[4096];
403             if(currentRow)
404                editBox.contents = (char *)dataType._vTbl[__ecereVMethodID_class_OnGetString](dataType, currentRow.GetData(null), tempString, null, null);
405             else
406                editBox.contents = "";
407          }                  
408          listBox.SelectRow(currentRow ? currentRow : (style.showNone ? noneRow : null));
409
410          Update(null);
411       }
412    }
413
414    bool Save()
415    {
416       if(editBox && editBox.modifiedDocument)
417       {
418          NotifyTextEntry(master, this, editBox.contents, true);
419          if(editBox)
420             editBox.modifiedDocument = false;
421          return true;
422       }
423       return false;
424    }
425
426 private:
427    DropBox()
428    {
429       listBoxMaxShown = 1000;
430       field = listBox.firstField;
431       dataType = field.dataType;
432       style.changeContents = true;
433       return true;
434    }
435
436    ~DropBox()
437    {
438       delete editBox;
439    }
440
441    void ResizeListbox()
442    {
443       int rowCount = Min(listBox.rowCount, listBoxMaxShown);
444       int height = rowCount * ROW_HEIGHT;
445       listBox.clientSize = { clientSize.w, height };
446    }
447
448    void OnPosition(int x, int y, int width, int height)
449    {
450       if(pulledWindow)
451       {
452          int lx = absPosition.x - guiApp.desktop.absPosition.x;
453          int ly = absPosition.y - guiApp.desktop.absPosition.y;
454          int availHeight = pulledWindow.parent.clientSize.h;
455          int height = pulledWindow.clientSize.h;
456
457          // If it won't fit below but fits above, place it above...
458          if(ly + size.h + height > availHeight && height < ly)
459             ly -= height;
460          else
461          {
462             ly += size.h;
463             if(ly + height > availHeight)
464                height = ((availHeight - ly) / ROW_HEIGHT) * ROW_HEIGHT;
465          }
466             
467          if(!pulledWindow.initSize.w)
468             pulledWindow.size.w = size.w;
469          else
470             // Align it to the right (pull down button)
471             lx -= pulledWindow.size.w - size.w;
472          pulledWindow.position = { lx, ly };
473          pulledWindow.clientSize = { pulledWindow.clientSize.w, height };
474       }
475    }
476
477    bool OnKeyDown(Key key, unichar ch)
478    {
479       switch(key)
480       {
481          case hotKey:
482          case space:
483          case right:
484          case escape:
485             // ADDED THIS CHECK HERE TO NAVIGATE THROUGH GRID LISTBOX
486             if(key == right)
487             {
488                if(eClass_IsDerived(master._class, class(DataBox)))
489                {
490                   if(eClass_IsDerived(master.master._class, class(ListBox)))
491                      return true;
492                }
493                else if(eClass_IsDerived(master._class, class(ListBox)))
494                   return true;
495             }
496             if(key == escape && !pulledWindow)
497             {
498                //if(editBox) button.Deactivate();
499                //if(editBox) button.Activate();
500                if(style.editText)
501                {
502                   if(editBox.modifiedDocument)
503                   {
504                      NotifyTextEntry(master, this, editBox.contents, false);
505                      editBox.modifiedDocument = false;
506                   }
507                   //editBox.Deactivate();
508                }
509                break;
510             }
511             if(style.editText && (key == space || key == right))
512                break;
513
514             if(pulledWindow)
515             {
516                OnCloseDropDown(pulledWindow);
517                pulledWindow = null;
518                button.checked = false;
519                NotifyClose(master, this);
520
521                if(style.editText)
522                {
523                   if(editBox.modifiedDocument)
524                   {
525                      NotifyTextEntry(master, this, editBox.contents, false);
526                      editBox.modifiedDocument = false;
527                   }
528                   editBox.Activate();
529                }
530             }
531             else
532             {
533                listBox.currentRow = currentRow ? currentRow : (style.showNone ? noneRow : null);
534                pulledWindow = OnDropDown();
535                OnPosition(position.x, position.y, clientSize.w, clientSize.h);
536                if(pulledWindow) pulledWindow.visible = true;
537                button.checked = true;
538             }         
539             Update(null);         
540             return false;
541          case enter:
542          case keyPadEnter:
543             if(!pulledWindow)
544             {
545                if(style.editText)
546                {
547                   if(editBox.modifiedDocument)
548                   {
549                      NotifyTextEntry(master, this, editBox.contents, true);
550                      editBox.modifiedDocument = false;
551                      //editBox.Deactivate();
552                   }
553
554                   // Add code to look through listbox and set current row if listbox is used
555                }
556                break;
557             }
558             else
559             {
560                incref this;
561
562                OnCloseDropDown(pulledWindow);
563                pulledWindow = null;
564                button.checked = false;
565                Update(null);
566                
567                if(!NotifyClose(master, this))
568                {
569                   delete this;
570                   return false;
571                }
572
573                // Moved this from below NotifySelect
574                currentRow = listBox.currentRow;
575                if(currentRow && currentRow.noneRow) currentRow = null;
576                if(style.editText && style.changeContents)
577                {
578                   char tempString[4096];
579                   if(currentRow)
580                      editBox.contents = (char *)dataType._vTbl[__ecereVMethodID_class_OnGetString](dataType, currentRow.GetData(null), tempString, null, null);
581                   else
582                      editBox.contents = "";
583                }                  
584
585                NotifySelect(master, this, currentRow, key.modifiers | { closingDropDown = true });
586                
587                delete this;               
588                return false;
589             }
590             return false;
591          //default:
592          //   return listBox.OnKeyDown(key, ch);
593       }
594       return true;
595    }
596
597    void OnApplyGraphics()
598    {
599       button.anchor = { right = 0, top = 0, bottom = 0 };
600       button.size = { guiApp.textMode ? 8 : BTN_WIDTH, 0 };
601    }
602    
603    /*Timer timer
604    {
605       window = this, delay = 0.01;
606
607       bool DelayExpired()
608       {
609          background = active ? red : lime;
610          parent.parent.background = parent.parent.active ? red : lime;
611          guiApp.desktop.Update(null);
612          return true;
613       }
614    };*/
615
616    void OnRedraw(Surface surface)
617    {
618       //timer.started = true;
619       if(!style.editText)
620       {
621          if(active && !pulledWindow/*listBox.visible*/)
622          {
623             if(style.activeColor)
624             {
625                surface.SetBackground(selectionColor ? selectionColor : SELECTION_COLOR);
626                if(!style.noHighlight || !currentRow)
627                {
628                   surface.Area(0,0, clientSize.w-1,clientSize.h-1);
629                }
630             }
631          }
632          if(!isEnabled)
633             surface.SetForeground(Color { 85,85,85 } );
634          else
635             surface.SetForeground((active && style.activeColor && !pulledWindow /*listBox.visible*/) ? SELECTION_TEXT : foreground);
636          surface.TextOpacity(true);
637
638          if(currentRow)
639          {
640             DataDisplayFlags displayFlags { active = active, current = true, dropBox = true, selected = true, fullRow = true };
641             dataType._vTbl[__ecereVMethodID_class_OnDisplay](dataType, currentRow.GetData(null), surface, 3, 
642                1+(clientSize.h - listBox.rowHeight) / 2, clientSize.w - (button.visible ? button.size.w : 0) - 3, 
643                field.userData, alignment, displayFlags);
644          }
645          else
646             surface.WriteText(2,2, "(none)", 6);
647
648          if(!style.noStipple && (!style.noHighlight || !currentRow))
649          {
650             surface.SetForeground(0xFFFFFF80);
651             if(active && !pulledWindow /*listBox.visible*/)
652             {
653                surface.Rectangle(0,0,clientSize.w-1-BTN_WIDTH,clientSize.h-1);
654                surface.SetForeground(black);
655                surface.LineStipple(0xAAAA);
656                surface.Rectangle(0,0,clientSize.w-1-BTN_WIDTH,clientSize.h-1);
657                surface.LineStipple(0);
658             }
659          }
660       }
661    }
662
663    bool OnResizing(int *width, int *height)
664    {
665       int rowHeight = 0;
666
667       display.FontExtent(fontObject, "W", 1, null, &rowHeight); 
668       rowHeight = Max(rowHeight, 16);
669
670       if(!*width) *width = Max(*width, rowHeight * 100 / 16);
671
672       //if(!*width) *width = Max(*width, 100);
673       //if(!*height) *height = Max(*height, 20);
674       if(!*height) *height = Max(*height, rowHeight * 20 / 16);
675
676       return true;
677    }
678
679    /*
680    watch(font)
681    {
682       SetInitSize(initSize);
683    };
684    */
685
686    bool OnLeftButtonDown(int x, int y, Modifiers mods)
687    {
688       Update(null);
689       if(pulledWindow)
690       {
691          OnCloseDropDown(pulledWindow);
692          button.checked = false;
693          pulledWindow = null;
694       
695          if(!NotifyClose(master, this))
696             return false;
697       }
698       else
699       {
700          listBox.currentRow = currentRow ? currentRow : (style.showNone ? noneRow : null);
701          pulledWindow = OnDropDown();
702          OnPosition(position.x, position.y, clientSize.w, clientSize.h);
703          if(pulledWindow) pulledWindow.visible = true;
704          if(listBox.freeSelect)
705             pulledWindow.OnLeftButtonDown(-2,-2, 0);
706          button.checked = true;
707       }
708       return true;
709    }
710
711    bool OnKeyHit(Key key, unichar ch)
712    {
713       DataRow currentRow = this.currentRow;
714       
715       if(!pulledWindow /*listBox.visible*/)
716       {
717          int c;
718          if(style.showNone && !currentRow) currentRow = noneRow;
719
720          switch(key)
721          {
722             case wheelDown:
723             case down: currentRow = currentRow ? currentRow.next : null; break;
724             case wheelUp:
725             case up:   currentRow = currentRow ? currentRow.prev : null; break;
726             case pageDown:
727                for(c = 0; c<listBoxMaxShown && currentRow && currentRow.next; c++, currentRow = currentRow.next);
728                break;
729             case pageUp:
730                for(c = 0; c<listBoxMaxShown && currentRow && currentRow.prev; c++, currentRow = currentRow.prev);
731                break;
732             case end:
733                for(; currentRow && currentRow.next; currentRow = currentRow.next);
734                break;
735             case home:
736                for(; currentRow && currentRow.prev; currentRow = currentRow.prev);
737                break;
738             default:
739                if(!editBox || button.active || !editBox.active || editBox.OnKeyHit(key, ch))
740                {
741                   return listBox.OnKeyHit(key, ch);
742                }
743                else
744                   return false;
745          }
746          if(currentRow)
747          {
748             if(currentRow.noneRow) currentRow = null;
749             property::currentRow = currentRow;
750             //return
751                NotifySelect(master, this, currentRow, key.modifiers);
752             //return false;
753          }
754          return false;
755       }
756       else
757       {
758          if(listBox.vertScroll)
759          {
760             if(key == wheelUp)
761                listBox.vertScroll.Action(up, 0, key);
762             else if(key == wheelDown)
763                listBox.vertScroll.Action(down, 0, key);
764          }
765          return listBox.OnKeyHit(key, ch);
766       }
767       return true;
768    }
769
770    bool OnActivate(bool active, Window swap, bool * goOnWithActivation, bool direct)
771    {
772       // WAS !active JUST MISSING HERE ?
773       if(!active && style.editText)
774       {
775          if(editBox.modifiedDocument)
776          {
777             if(editBox) editBox.modifiedDocument = false;
778             NotifyTextEntry(master, this, editBox.contents, true); //false);
779             // MOVED THIS ABOVE TO AVOID INFINITE RECURSION
780             // if(editBox) editBox.modifiedDocument = false;
781          }
782          //editBox.Deactivate();
783       }
784       Update(null);
785       return true;
786    }
787
788    public Button button
789    {
790       this, toggle = true, bevel = true, inactive = true,
791       anchor = Anchor { right = 0, top = 0, bottom = 0 },
792       size = Size { BTN_WIDTH, 0 },
793       symbol = 25;
794       bitmap = { "<:ecere>elements/arrowDown.png" };
795
796       bool NotifyPushed(Button control, int x, int y, Modifiers mods)
797       {
798          if(pulledWindow)
799          {
800             OnCloseDropDown(pulledWindow);
801             pulledWindow = null;
802             button.checked = false;
803             NotifyClose(master, this);
804          }
805          else
806          {
807             incref this;
808             if(editBox && editBox.modifiedDocument)
809             {
810                NotifyTextEntry(master, this, editBox.contents, true);
811                editBox.modifiedDocument = false;
812             }
813             pulledWindow = OnDropDown();
814             if(pulledWindow)
815             {
816                OnPosition(position.x, position.y, clientSize.w, clientSize.h);
817                if(listBox.freeSelect)
818                   pulledWindow.OnLeftButtonDown(-2,-2, 0);
819                button.checked = true;
820                pulledWindow.visible = true;
821             }
822             delete this;
823          }
824          Update(null);
825          return true;
826       }
827    };
828
829    ListBox listBox
830    {
831       master = this, fullRowSelect = true, freeSelect = true, /* noHighlight = style.noHighlight , */
832       interim = true, hasVertScroll = true, borderStyle = contour, position = { absPosition.x, absPosition.y + size.h },
833       size.w = size.w, visible = false;
834
835       bool NotifyActivate(Window control, bool active, Window swap)
836       {
837          if(!active)
838          {
839             Update(null);
840             if(swap != button && swap != this)
841             {
842                if(editBox && editBox.modifiedDocument)
843                {
844                   NotifyTextEntry(master, this, editBox.contents, true);
845                   editBox.modifiedDocument = false;
846                }
847
848                OnCloseDropDown(pulledWindow);
849                pulledWindow = null;
850                button.checked = false;
851                NotifyClose(master, this);
852             }
853          }
854          return true;
855       }
856
857       bool NotifySelect(ListBox listBox, DataRow row, Modifiers mods)
858       {
859          Update(null);
860
861          // Add code to set text to list box contents if it has an editbox
862
863          if(pulledWindow)
864          {
865             OnCloseDropDown(pulledWindow);
866             pulledWindow = null;
867             button.checked = false;
868             mods.closingDropDown = true;
869             if(!NotifyClose(master, this))
870                return false;
871          }
872          currentRow = (row && !row.noneRow) ? row : null;
873          if(style.editText && style.changeContents)
874          {
875             char tempString[4096];
876             if(currentRow)
877                editBox.contents = (char *)dataType._vTbl[__ecereVMethodID_class_OnGetString](dataType, currentRow.GetData(null), tempString, null, null);
878             else
879                editBox.contents = "";
880             if(active)
881                editBox.SelectAll();
882          }                  
883          button.Deactivate();
884          return NotifySelect(master, this, currentRow, mods);
885       }
886
887       bool NotifyHighlight(ListBox control, DataRow row, Modifiers mods)
888       {
889          return NotifyHighlight(master, this, row, mods);
890       }
891
892       bool NotifyKeyDown(ListBox listBox, DataRow selection, Key key, unichar ch)
893       {
894          return OnKeyDown(key, ch);
895          //return true;
896       }
897    };
898
899    bool OnPostCreate()
900    {
901       if(font)
902          listBox.font = { font.faceName, font.size };
903       return true;
904    }
905
906    DropBoxBits style;
907    Window pulledWindow;
908    DataRow currentRow;
909    int listBoxMaxShown;
910    Class dataType;
911    DataField field;
912    EditBox editBox;
913    Alignment alignment;
914    DataRow noneRow;
915    Color selectionColor;
916 };