bindings: Picture, Anchor
authorJerome St-Louis <jerome@ecere.com>
Wed, 22 Jun 2016 08:33:33 +0000 (04:33 -0400)
committerJerome St-Louis <jerome@ecere.com>
Mon, 21 Nov 2016 14:18:59 +0000 (09:18 -0500)
- Also fixed crashes on clicking button then closing second window

bindings/c/ecere.c
bindings/c/ecere.h
bindings/python/cffi-ecere.h
bindings/python/pyEcere.py
bindings/python/samples/sample.py

index 439edea..6aaaa2b 100644 (file)
@@ -6,6 +6,13 @@ Method * method_Surface_writeTextf;
 
 void (* Surface_writeTextf)(Surface s, int x, int y, const char * format, ...);
 
+Class * class_BitmapResource;
+
+Property * property_BitmapResource_fileName;
+
+void (* BitmapResource_set_fileName)(BitmapResource f, constString v);
+constString (* BitmapResource_get_fileName)(BitmapResource f);
+
 Class * class_FontResource;
 
 Property * property_FontResource_faceName;
@@ -49,6 +56,7 @@ Property * property_Window_background;
 Property * property_Window_foreground;
 Property * property_Window_parent;
 Property * property_Window_position;
+Property * property_Window_anchor;
 Property * property_Window_font;
 Property * property_Window_displayDriver;
 
@@ -88,6 +96,9 @@ Color (* Window_get_foreground)(Window w);
 void (* Window_set_position)(Window w, const Point * v);
 void (* Window_get_position)(Window w, Point * v);
 
+void (* Window_set_anchor)(Window w, const Anchor * v);
+void (* Window_get_anchor)(Window w, Anchor * v);
+
 void (* Window_set_font)(Window w, Instance v);
 FontResource (* Window_get_font)(Window w);
 
@@ -111,6 +122,13 @@ Class * class_ToolButton;
 
 Class * class_Label;
 
+Class * class_Picture;
+
+Property * property_Picture_image;
+
+void (* Picture_set_image)(Picture p, BitmapResource v);
+constString (* Picture_get_image)(Picture p);
+
 Class * class_GuiApplication;
 
 Class * class_MessageBox;
@@ -180,6 +198,17 @@ Module ecere_init(Module fromModule)
          }
       }
 
+      class_BitmapResource = eC_findClass(module, "BitmapResource");
+      if(class_BitmapResource)
+      {
+         property_BitmapResource_fileName = Class_findProperty(class_BitmapResource, "fileName", module);
+         if(property_BitmapResource_fileName)
+         {
+            BitmapResource_set_fileName = (void *)property_BitmapResource_fileName->Set;
+            BitmapResource_get_fileName = (void *)property_BitmapResource_fileName->Get;
+         }
+      }
+
       class_Window = eC_findClass(module, "Window");
       if(class_Window)
       {
@@ -282,6 +311,13 @@ Module ecere_init(Module fromModule)
             Window_get_position = (void *)property_Window_position->Get;
          }
 
+         property_Window_anchor = Class_findProperty(class_Window, "anchor", module);
+         if(property_Window_anchor)
+         {
+            Window_set_anchor = (void *)property_Window_anchor->Set;
+            Window_get_anchor = (void *)property_Window_anchor->Get;
+         }
+
          property_Window_font = Class_findProperty(class_Window, "font", module);
          if(property_Window_font)
          {
@@ -300,6 +336,17 @@ Module ecere_init(Module fromModule)
             Button_notifyClicked_vTblID = method_Button_notifyClicked->vid;
       }
 
+      class_Picture = eC_findClass(module, "Picture");
+      if(class_Picture)
+      {
+         property_Picture_image = Class_findProperty(class_Picture, "image", module);
+         if(property_Picture_image)
+         {
+            Picture_set_image = (void *)property_Picture_image->Set;
+            Picture_get_image = (void *)property_Picture_image->Get;
+         }
+      }
+
       class_MessageBox = eC_findClass(module, "MessageBox");
       if(class_MessageBox)
       {
index 92a493b..ac9136a 100644 (file)
@@ -35,10 +35,12 @@ extern "C"
 
 #define Surface         eC_Surface
 #define FontResource    eC_FontResource
+#define BitmapResource  eC_BitmapResource
 
 #define Window          eC_Window
 #define DataBox         eC_DataBox
 #define Button          eC_Button
+#define Picture         eC_Picture
 #define Label           eC_Label
 #define MessageBox      eC_MessageBox
 #define GuiApplication  eC_GuiApplication
@@ -161,6 +163,17 @@ extern bool (* FontResource_get_bold)(FontResource f);
 extern void (* FontResource_set_italic)(FontResource f, bool v);
 extern bool (* FontResource_get_italic)(FontResource f);
 
+///////////// BitmapResource Class /////////////////////////////////////////////////
+extern Class * class_BitmapResource;
+
+typedef Instance BitmapResource;
+
+// Properties
+extern Property * property_BitmapResource_fileName;
+
+extern void (* BitmapResource_set_fileName)(BitmapResource f, constString v);
+extern constString (* BitmapResource_get_fileName)(BitmapResource f);
+
 /****************************************************************************
    ecere::gui Namespace
 ****************************************************************************/
@@ -213,6 +226,44 @@ enum enum_BorderStyle
    deepContour  = deep|contour
 };
 
+#if !defined(__cplusplus)
+typedef enum AnchorValueType AnchorValueType;
+#endif
+
+enum AnchorValueType { /*none, */offset = 1, relative, middleRelative, cascade, vTiled, hTiled };
+
+typedef struct AnchorValue AnchorValue;
+struct AnchorValue
+{
+   AnchorValueType type;
+
+   union
+   {
+      int distance;
+      float percent;
+   };
+};
+
+typedef struct MiddleAnchorValue MiddleAnchorValue;
+struct MiddleAnchorValue
+{
+   AnchorValueType type;
+
+   union
+   {
+      int distance;
+      float percent;
+   };
+};
+
+typedef struct Anchor Anchor;
+struct Anchor
+{
+   union { AnchorValue left; MiddleAnchorValue horz; };
+   union { AnchorValue top; MiddleAnchorValue vert; };
+   AnchorValue right, bottom;
+};
+
 ///////////// Window Class /////////////////////////////////////////////////
 typedef Instance Window;
 
@@ -262,6 +313,9 @@ extern Color (* Window_get_foreground)(Window w);
 extern void (* Window_set_position)(Window w, const Point * v);
 extern void (* Window_get_position)(Window w, Point * v);
 
+extern void (* Window_set_anchor)(Window w, const Anchor * v);
+extern void (* Window_get_anchor)(Window w, Anchor * v);
+
 extern void (* Window_set_font)(Window w, FontResource v);
 extern FontResource (* Window_get_font)(Window w);
 
@@ -312,6 +366,16 @@ extern int Button_notifyClicked_vTblID;
 
 extern Class * class_ToolButton;
 
+///////////// Picture Class /////////////////////////////////////////////////
+typedef Window Picture;
+
+extern Class * class_Picture;
+
+extern Property * property_Picture_image;
+
+extern void (* Picture_set_image)(Picture p, BitmapResource v);
+extern constString (* Picture_get_image)(Picture p);
+
 ///////////// DataBox Class /////////////////////////////////////////////////
 typedef Window DataBox;
 
@@ -328,9 +392,11 @@ Module ecere_init(Module fromModule);
    #undef Label
    #undef Window
    #undef DataBox
+   #undef Picture
    #undef GuiApplication
 
    #undef FontResource
+   #undef BitmapResource
    #undef Surface
 
    #undef Module
index b99fe6a..a40abd7 100644 (file)
@@ -149,6 +149,13 @@ extern Class * class_GuiApplication;
 
 extern Class * class_FontResource;
 
+extern Class * class_BitmapResource;
+
+typedef Instance BitmapResource;
+
+extern void (* BitmapResource_set_fileName)(BitmapResource f, constString v);
+extern constString (* BitmapResource_get_fileName)(BitmapResource f);
+
 #define false 0
 #define true 1
 
@@ -188,6 +195,42 @@ typedef Window MessageBox;
 typedef int64_t DialogResult;
 typedef uint32 Modifiers;
 
+enum AnchorValueType { /*none, */offset = 1, relative, middleRelative, cascade, vTiled, hTiled };
+typedef enum AnchorValueType AnchorValueType;
+
+typedef struct AnchorValue AnchorValue;
+struct AnchorValue
+{
+   AnchorValueType type;
+
+   union
+   {
+      int distance;
+      float percent;
+   };
+};
+
+typedef struct MiddleAnchorValue MiddleAnchorValue;
+struct MiddleAnchorValue
+{
+   AnchorValueType type;
+
+   union
+   {
+      int distance;
+      float percent;
+   };
+};
+
+typedef struct Anchor Anchor;
+struct Anchor
+{
+   union { AnchorValue left; MiddleAnchorValue horz; };
+   union { AnchorValue top; MiddleAnchorValue vert; };
+   AnchorValue right, bottom;
+};
+
+
 extern DialogResult (* Window_modal)(Window);
 extern bool (* Window_create)(Window);
 
@@ -206,6 +249,9 @@ extern FontResource (* Window_get_font)(Window w);
 extern void (* Window_set_position)(Window w, const Point * v);
 extern void (* Window_get_position)(Window w, Point * v);
 
+extern void (* Window_set_anchor)(Window w, const Anchor * v);
+extern void (* Window_get_anchor)(Window w, Anchor * v);
+
 extern void (* Window_set_hasClose)(Window w, bool hasClose);
 extern bool (* Window_get_hasClose)(Window w);
 
@@ -230,6 +276,13 @@ extern Color (* Window_get_foreground)(Window w);
 extern void (* MessageBox_set_contents)(MessageBox m, constString contents);
 extern constString (* MessageBox_get_contents)(MessageBox m);
 
+typedef Window Picture;
+
+extern Class * class_Picture;
+
+extern void (* Picture_set_image)(Picture p, BitmapResource v);
+extern constString (* Picture_get_image)(Picture p);
+
 #define COLOR_r_MASK       0x00FF0000
 #define COLOR_r_SHIFT      16
 #define COLOR_g_MASK       0x0000FF00
index 08895c0..99c103c 100644 (file)
@@ -97,6 +97,16 @@ class Color:
    @b.setter
    def b(self, value): self.value = ((self.value) & ~(lib.COLOR_b_MASK)) | (((value)) << lib.COLOR_b_SHIFT)
 
+class BitmapResource:
+   def __init__(self, fileName = None):
+      self.this = lib.Instance_new(lib.class_BitmapResource)
+      if fileName is not None:      self.fileName = fileName
+
+   @property
+   def fileName(self): return ffi.string(lib.FontResource_get_fileName(self.this)).decode('utf8')
+   @fileName.setter
+   def fileName(self, value): lib.BitmapResource_set_fileName(self.this, value.encode('utf8'))
+
 class FontResource:
    def __init__(self, faceName = None, size = None, outlineSize = None, outlineFade = None):
       self.this = lib.Instance_new(lib.class_FontResource)
@@ -146,8 +156,9 @@ class Instance:
    def __init__(self): self.this = ffi.NULL
 
 @ffi.callback("void(Instance)")
-def cb_Instance_destructor(w):
+def cb_Window_destructor(w):
    instance = ffi.from_handle(ffi.cast("void **", ffi.cast("char *", w) + w._class.offset)[0])
+   Window.instances.remove(instance)
    #print("Instance destroyed now!")
    instance.handle = 0
 
@@ -163,9 +174,10 @@ class Application(Instance):
    def __init__(self):
       self.this = lib.eC_init(True, True, len(sys.argv), [ffi.new("char[]", i.encode('utf8')) for i in sys.argv])
       lib.ecere_init(self.this)
-      Window.pyClass_Window         = lib.eC_registerClass(lib.normalClass, "PyWindow"    .encode('utf8'), "Window"     .encode('utf8'), 8, 0, ffi.NULL, ffi.cast("void(*)(void *)", cb_Instance_destructor), self.this, lib.publicAccess, lib.publicAccess);
-      Button.pyClass_Button         = lib.eC_registerClass(lib.normalClass, "PyButton"    .encode('utf8'), "Button"     .encode('utf8'), 8, 0, ffi.NULL, ffi.cast("void(*)(void *)", cb_Instance_destructor), self.this, lib.publicAccess, lib.publicAccess);
-      MessageBox.pyClass_MessageBox = lib.eC_registerClass(lib.normalClass, "PyMessageBox".encode('utf8'), "MessageBox" .encode('utf8'), 8, 0, ffi.NULL, ffi.cast("void(*)(void *)", cb_Instance_destructor), self.this, lib.publicAccess, lib.publicAccess);
+      Window.pyClass_Window         = lib.eC_registerClass(lib.normalClass, "PyWindow"    .encode('utf8'), "Window"     .encode('utf8'), 8, 0, ffi.NULL, ffi.cast("void(*)(void *)", cb_Window_destructor), self.this, lib.publicAccess, lib.publicAccess);
+      Button.pyClass_Button         = lib.eC_registerClass(lib.normalClass, "PyButton"    .encode('utf8'), "Button"     .encode('utf8'), 8, 0, ffi.NULL, ffi.cast("void(*)(void *)", cb_Window_destructor), self.this, lib.publicAccess, lib.publicAccess);
+      Picture.pyClass_Picture       = lib.eC_registerClass(lib.normalClass, "PyPicture"   .encode('utf8'), "Picture"    .encode('utf8'), 8, 0, ffi.NULL, ffi.cast("void(*)(void *)", cb_Window_destructor), self.this, lib.publicAccess, lib.publicAccess);
+      MessageBox.pyClass_MessageBox = lib.eC_registerClass(lib.normalClass, "PyMessageBox".encode('utf8'), "MessageBox" .encode('utf8'), 8, 0, ffi.NULL, ffi.cast("void(*)(void *)", cb_Window_destructor), self.this, lib.publicAccess, lib.publicAccess);
 
    def main(self):
       lib.Application_main(self.this)
@@ -175,19 +187,74 @@ class GuiApplication(Application):
       Application.__init__(self)
       rApp = ffi.new("Instance *", self.this); lib.Instance_evolve(rApp, lib.class_GuiApplication); self.this = rApp[0]
 
+class Anchor:
+   def __init__(self, left = None, right = None, top = None, bottom = None, horz = None, vert = None):
+      self.this = ffi.new("Anchor *")
+      # Would generate conversion properties here instead?
+      if left is not None:
+         if type(left) == int:
+            self.this.left.type = lib.offset
+            self.this.left.distance = left
+         elif type(left) == float:
+            self.this.left.type = lib.relative
+            self.this.left.distance = left
+      if right is not None:
+         if type(right) == int:
+            self.this.right.type = lib.offset
+            self.this.right.distance = right
+         elif type(right) == float:
+            self.this.right.type = lib.relative
+            self.this.right.distance = right
+      if top is not None:
+         if type(top) == int:
+            self.this.top.type = lib.offset
+            self.this.top.distance = top
+         elif type(top) == float:
+            self.this.top.type = lib.relative
+            self.this.top.distance = top
+      if bottom is not None:
+         if type(bottom) == int:
+            self.this.bottom.type = lib.offset
+            self.this.bottom.distance = bottom
+         elif type(bottom) == float:
+            self.this.bottom.type = lib.relative
+            self.this.bottom.distance = bottom
+      if horz is not None:
+         if type(horz) == int:
+            self.this.horz.type = lib.offset
+            self.this.horz.distance = horz
+         elif type(horz) == float:
+            self.this.horz.type = lib.relative
+            self.this.horz.distance = horz
+      if vert is not None:
+         if type(vert) == int:
+            self.this.vert.type = lib.offset
+            self.this.vert.distance = vert
+         elif type(vert) == float:
+            self.this.vert.type = lib.relative
+            self.this.vert.distance = vert
+
 @ffi.callback("void(Window, Surface)")
 def cb_Window_onRedraw(w, s):
    window = ffi.from_handle(ffi.cast("void **", ffi.cast("char *", w) + w._class.offset)[0])
    surface = Surface(this = s)
    window.fn_onRedraw(window, surface)
 
+@ffi.callback("void(Window, Surface)")
+def cb_Window_onDrawOverChildren(w, s):
+   window = ffi.from_handle(ffi.cast("void **", ffi.cast("char *", w) + w._class.offset)[0])
+   surface = Surface(this = s)
+   window.fn_onDrawOverChildren(window, surface)
+
 class Window(Instance):
+   instances = []
+
    def __init__(self,
       parent = None, caption = None, displayDriver = None,
       hasClose = None, hasMinimize = None, hasMaximize = None,
       borderStyle = None, clientSize = None, font = None, background = None, foreground = None, position = None):
-
       self.this = lib.Instance_new(Window.pyClass_Window)
+      Window.instances.append(self)
       self.handle = ffi.new_handle(self)
       ffi.cast("void **", ffi.cast("char *", self.this) + self.this._class.offset)[0] = self.handle
 
@@ -221,6 +288,11 @@ class Window(Instance):
    def position(self, value): lib.Window_set_position(self.this, value.this)
 
    @property
+   def anchor(self): value = Anchor(); lib.Window_get_anchor(self.this, value.this); return value
+   @anchor.setter
+   def anchor(self, value): lib.Window_set_anchor(self.this, value.this)
+
+   @property
    def clientSize(self): value = Size(); lib.Window_get_size(self.this, value.this); return value
    @clientSize.setter
    def clientSize(self, value): lib.Window_set_size(self.this, value.this)
@@ -277,6 +349,13 @@ class Window(Instance):
       self.fn_onRedraw = value
       lib.Instance_setMethod(self.this, "OnRedraw".encode('utf8'), cb_Window_onRedraw);
 
+   @property
+   def onDrawOverChildren(self): return self.fn_onDrawOverChildren
+   @onDrawOverChildren.setter
+   def onDrawOverChildren(self, value):
+      self.fn_onDrawOverChildren = value
+      lib.Instance_setMethod(self.this, "OnDrawOverChildren".encode('utf8'), cb_Window_onDrawOverChildren);
+
 @ffi.callback("bool(Window, Button, int, int, Modifiers)")
 def cb_Button_notifyClicked(m, b, x, y, mods):
    button = ffi.from_handle(ffi.cast("void **", ffi.cast("char *", b) + b._class.offset)[0])
@@ -287,6 +366,7 @@ def cb_Button_notifyClicked(m, b, x, y, mods):
 class Button(Window):
    def __init__(self, parent = None, caption = None, position = None, font = None, notifyClicked = None):
       self.this = lib.Instance_new(Button.pyClass_Button)
+      Window.instances.append(self)
       self.handle = ffi.new_handle(self)
       ffi.cast("void **", ffi.cast("char *", self.this) + self.this._class.offset)[0] = self.handle
 
@@ -303,9 +383,28 @@ class Button(Window):
       self.fn_notifyClicked = value
       lib.Instance_setMethod(self.this, "NotifyClicked".encode('utf8'), cb_Button_notifyClicked);
 
+class Picture(Window):
+   def __init__(self, parent = None, caption = None, image = None, position = None, anchor = None):
+      self.this = lib.Instance_new(Picture.pyClass_Picture)
+      Window.instances.append(self)
+      self.handle = ffi.new_handle(self)
+      ffi.cast("void **", ffi.cast("char *", self.this) + self.this._class.offset)[0] = self.handle
+
+      if parent is not None:       self.parent = parent
+      if caption is not None:      self.caption = caption
+      if image is not None:        self.image = image
+      if position is not None:     self.position = position
+      if anchor is not None:       self.anchor = anchor
+
+   @property
+   def image(self): value = lib.Picture_get_image(self.this); return BitmapResource(this = value)
+   @image.setter
+   def image(self, value): lib.Picture_set_image(self.this, value.this)
+
 class MessageBox(Window):
    def __init__(self, parent = None, caption = None, contents = None, position = None):
       self.this = lib.Instance_new(MessageBox.pyClass_MessageBox)
+      Window.instances.append(self)
       self.handle = ffi.new_handle(self)
       ffi.cast("void **", ffi.cast("char *", self.this) + self.this._class.offset)[0] = self.handle
 
index a9bba60..28a4430 100644 (file)
@@ -20,7 +20,7 @@ class MyForm(Window):
 
       def myOnRedraw(self, surface):
          surface.writeTextf(20, 20, I18N("Writing Stuff on the wall!!"))
-      self.onRedraw = myOnRedraw
+      self.onDrawOverChildren = myOnRedraw
 
       def button1Clicked(self, button, x, y, mods):
          printLn("I got pushed! (master is ", self.caption, ")")
@@ -28,12 +28,14 @@ class MyForm(Window):
          MessageBox(caption = I18N("Hello, Python!"), contents = I18N("Python is pretty nifty.")).modal()
          return True
 
+      self.picture1 = Picture(parent = self, anchor = Anchor(0,0,0,0), image = BitmapResource("C:/Users/Jerome/Desktop/khaleesi.png"))
+
       self.button1 = Button(
-            parent = self,
-            caption = "Push It!",
-            position = Point(80,80),
-            font = FontResource("Merriweather", 30),
-            notifyClicked = button1Clicked )
+          parent = self,
+          caption = "Push It!",
+          position = Point(80,80),
+          font = FontResource("Merriweather", 30),
+          notifyClicked = button1Clicked )
 
 MyForm()