compiler/libec; ecere; ide: Safer default virtual method calls
[sdk] / ecere / src / gui / controls / DataBox.ec
index 72c6837..7d3932f 100644 (file)
@@ -36,34 +36,35 @@ public:
 
    virtual void SetData(any_object newData, bool closingDropDown)
    {
-      //type._vTbl[__ecereVMethodID_class_OnCopy](type, data, newData);
+      //((void (*)(void *, void *, void *))(void *)type._vTbl[__ecereVMethodID_class_OnCopy])(type, data, newData);
       needUpdate = true;
       if(type)
       {
          if(type.type == normalClass || type.type == noHeadClass)
          {
             if(((void **)data)[0])
-               type._vTbl[__ecereVMethodID_class_OnFree](type, ((void **)data)[0]);
+               ((void (*)(void *, void *))(void *)type._vTbl[__ecereVMethodID_class_OnFree])(type, ((void **)data)[0]);
             ((void **)data)[0] = newData;
          }
          else
          {
             // Free old data first
-            type._vTbl[__ecereVMethodID_class_OnFree](type, data);
-            type._vTbl[__ecereVMethodID_class_OnCopy](type, data, newData);
+            ((void (*)(void *, void *))(void *)type._vTbl[__ecereVMethodID_class_OnFree])(type, data);
+            ((void (*)(void *, void *, void *))(void *)type._vTbl[__ecereVMethodID_class_OnCopy])(type, data, newData);
          }
       }
       if(created)
-         NotifyChanged(master, closingDropDown);
+         NotifyChanged(master, this, closingDropDown);
       //editor.Activate();
    }
 
    bool SaveData()      // TODO: Clear this up, along with Saving DataBox
    {
-      if(editor && type._vTbl[__ecereVMethodID_class_OnSaveEdit](type, data, editor, null))
+      bool (* onSaveEdit)(void *, void *, Window, void *) = (void *)type._vTbl[__ecereVMethodID_class_OnSaveEdit];
+      if(editor && (!onSaveEdit || onSaveEdit(type, data, editor, null)))
       {
          Refresh();
-         NotifyChanged(master, false);
+         NotifyChanged(master, this, false);
          // Refresh();
          return true;
       }
@@ -90,39 +91,51 @@ public:
    }
 
    virtual bool Window::NotifyModified();
-   virtual bool Window::NotifyChanged(bool closingDropDown);
+   virtual bool Window::NotifyChanged(DataBox dataBox, bool closingDropDown);
    virtual void OnConfigure(Window editor);
 
 private:
    bool inAutoSize;
 
+   watch(background)     { if(editor) editor.background = background; };
+   watch(foreground)     { if(editor) editor.foreground = foreground; };
+   //watch(selectionColor) { if(editor) editor.selectionColor = selectionColor; };
+   //watch(selectionText)  { if(editor) editor.selectionText = selectionText; };
+   watch(opacity)        { if(editor) editor.opacity = opacity; };
+
    bool OnPostCreate()
    {
       // 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.
       // ( A tweak for enum classes is in typeEdit.ec, as the base class editor invokes it )
-      if(type && (!readOnly || (autoSize && type._vTbl[__ecereVMethodID_class_OnEdit] == class(Instance)._vTbl[__ecereVMethodID_class_OnEdit])) &&
+      if(type/* && (!readOnly || (autoSize && type._vTbl[__ecereVMethodID_class_OnEdit] == class(Instance)._vTbl[__ecereVMethodID_class_OnEdit]))*/ &&
          (type.type == normalClass || type.type == noHeadClass || data))
       {
          // IMPORTANT FIX: If keepEditor is true, we were passing editor rather than the editor's current master
-         editor = (Window)type._vTbl[__ecereVMethodID_class_OnEdit](type, 
-            (type.type == normalClass || type.type == noHeadClass) ? (data ? (*(void **)data) : null) : data, 
+         editor = ((Window (*)(void *, void *, DataBox, void *, int, int, int, int, void*))(void *)type._vTbl[__ecereVMethodID_class_OnEdit])(type,
+            (type.type == normalClass || type.type == noHeadClass) ? (data ? (*(void **)data) : null) : data,
             this, (keepEditor && editor) ? editor.master : this, 0, 0, clientSize.w, clientSize.h, fieldData);// null);
+         if(editor && readOnly && !eClass_IsDerived(editor._class, class(EditBox)) &&
+               !(autoSize && type._vTbl[__ecereVMethodID_class_OnEdit] == class(Instance)._vTbl[__ecereVMethodID_class_OnEdit]))
+         {
+            editor.Destroy(0);
+            editor = null;
+            return true;
+         }
          if(editor)
          {
             // editor.anchor = { 0, 0, 0, 0 };
             editor.background = background;
             editor.foreground = foreground;
             editor.opacity = opacity;
-/*#if _DEBUG
-            if(autoSize)
-               PrintLn("DataBox::OnPostCreate -- autoSize == true");
-#endif*/
             if(eClass_IsDerived(editor._class, class(EditBox)))
             {
                ((EditBox)editor).readOnly = readOnly;
-               ((EditBox)editor).autoSize = autoSize;
+               if(autoSize)
+                  ((EditBox)editor).autoSize = autoSize;
                ((EditBox)editor).clickThrough = true;
             }
+            else if(eClass_IsDerived(editor._class, class(Button)) && autoSize)
+               size = editor.size;
          }
          else
          {
@@ -136,30 +149,30 @@ private:
 
    void OnRedraw(Surface surface)
    {
-      if(type && (!editor || !editor.created))
+      if(type && data && (!editor || !editor.created || editor.anchor.left)) // ColorDropBox lets part of the DataBox show
       {
          char tempString[1024];
          if(type._vTbl[__ecereVMethodID_class_OnDisplay] == class(Instance)._vTbl[__ecereVMethodID_class_OnDisplay])
          {
             if(needUpdate)
             {
-               String s;
+               const String s;
                if(type.type == noHeadClass || type.type == normalClass)
-                  s = (String)type._vTbl[__ecereVMethodID_class_OnGetString](type, *(void **)this.data, tempString, fieldData, null);
+                  s = ((const char *(*)(void *, void *, char *, void *, bool *))(void *)type._vTbl[__ecereVMethodID_class_OnGetString])(type, *(void **)this.data, tempString, fieldData, null);
                else
-                  s = (String)type._vTbl[__ecereVMethodID_class_OnGetString](type, this.data, tempString, fieldData, null);
+                  s = ((const char *(*)(void *, void *, char *, void *, bool *))(void *)type._vTbl[__ecereVMethodID_class_OnGetString])(type, this.data, tempString, fieldData, null);
                delete stringValue;
                stringValue = CopyString(s);
                needUpdate = false;
             }
-            class(String)._vTbl[__ecereVMethodID_class_OnDisplay](class(String), stringValue, surface, 3, 1, clientSize.w, fieldData, type.defaultAlignment, 0);
+            ((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);
          }
          else
          {
             if(type.type == noHeadClass || type.type == normalClass)
-               type._vTbl[__ecereVMethodID_class_OnDisplay](type, *(void **)this.data, surface, 3, 1, clientSize.w, fieldData, type.defaultAlignment, 0);
+               ((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);
             else
-               type._vTbl[__ecereVMethodID_class_OnDisplay](type, this.data, surface, 3, 1, clientSize.w, fieldData, type.defaultAlignment, 0);
+               ((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);
          }
       }
    }
@@ -232,4 +245,18 @@ public class SavingDataBox : DataBox
       }
       return DataBox::OnKeyDown(key, ch);
    }
+
+   bool OnResizing(int * w, int * h)
+   {
+      if(!*w || !*h)
+      {
+         int spaceH;
+         display.FontExtent(fontObject, " ", 1, null, &spaceH);
+         if(!*h)
+            *h = spaceH + 2;
+         if(!*w)
+            *w = spaceH * 80 / 14;
+      }
+      return true;
+   }
 }