Browse Source

Libjay: Free and list widget functions (#807)

* New Border structure


Signed-off-by: fuchicar <rafita.fernandez@gmail.com>

* free and list widget functions


Signed-off-by: fuchicar <rafita.fernandez@gmail.com>
Rafa 6 years ago
parent
commit
29435b61c1

+ 14 - 3
sys/include/jay.h

@@ -4,6 +4,7 @@ typedef struct Widget Widget;
 typedef struct WListElement WListElement;
 typedef struct Panel Panel;
 typedef struct Label Label;
+typedef struct Border Border;
 typedef enum wtype wtype;
 
 enum wtype{
@@ -55,7 +56,12 @@ struct Widget {
 
   //Methods
   int (*addWidget)(Widget *me, Widget *new, Point pos);
+  Widget *(*getWidget)(Widget *me, char *id);
+  Widget *(*extractWidget)(Widget *me, char *id);
+  int  (*listWidgets)(Widget *me, char ***list);
+  void (*deleteWidget)(Widget *me, char *id);
   void (*setVisible)(Widget *w, int visible);
+  void (*freeWidget)(Widget *w);
 
   //User Events:
   void (*hover)(Widget *w);
@@ -101,6 +107,12 @@ struct WListElement {
   Widget *w;
 };
 
+struct Border{
+  int size;
+  int _3d; // True if border is 3D
+  int up; // Up or Down 3D effect
+};
+
 struct Panel {
   Widget *w;
   uint32_t backColor;
@@ -112,9 +124,7 @@ struct Label {
   char *t;
   Font *f;
 
-  int border;
-  int d3; // 3D Border true/false
-  int up; // If d3=true then up defines the efect
+  Border border;
   uint32_t backColor;
   uint32_t textColor;
 
@@ -125,5 +135,6 @@ struct Label {
 Widget *initjayapp(char *name);
 void startjayapp(Widget * w);
 void initdefaultconfig();
+Border createBorder(int size, int _3D, int up);
 Widget *createPanel(char *id, int height, int width, Point p);
 Widget *createLabel(char *id, int height, int width);

+ 6 - 0
sys/src/libjay/fns.h

@@ -6,5 +6,11 @@ Widget *createPanel1(char *id, Rectangle r, Point p);
 WListElement *createWListElement(Widget *w);
 WListElement *getWListElementByID(WListElement *list, char *id);
 int addWListElement(WListElement *list, Widget *w);
+void destroyWList(WListElement *list);
+void freeWListElement(WListElement *e);
+Widget *extractWidgetByPos(WListElement *list, int pos);
+Widget *extractWidgetByID(WListElement *list, char *id);
+int countWListElements(WListElement *list);
+void freeWidget(Widget *w);
 
 void _simpleResize(Widget *w, Point d);

+ 25 - 12
sys/src/libjay/label.c

@@ -18,6 +18,7 @@ void _dclickLabel(Widget *w, Mouse *m);
 void _mPressDownLabel(Widget *w, Mouse *m);
 void _mPressUpLabel(Widget *w, Mouse *m);
 void _changeLabel(Widget *w);
+void _freeLabel(Widget *w);
 
 Widget *
 createLabel(char *id, int height, int width){
@@ -36,9 +37,7 @@ createLabel(char *id, int height, int width){
   laux->t = nil;
   laux->backColor = jayconfig->mainBackColor;
   laux->textColor = jayconfig->mainTextColor;
-  laux->border = 0;
-  laux->d3 = 0;
-  laux->up = 0;
+  laux->border = createBorder(0, 0, 0);
   laux->w = w;
   laux->gettext=_getTextLabel;
   laux->setText=_setTextLabel;
@@ -52,6 +51,7 @@ createLabel(char *id, int height, int width){
   w->_mpressdown=_mPressDownLabel;
   w->_mpressup=_mPressUpLabel;
   w->_change=_changeLabel;
+  w->freeWidget=_freeLabel;
   return w;
 }
 
@@ -113,24 +113,24 @@ _drawLabel(Widget *w, Image *dst){
 
   if(l->t != nil){
     Image *i = allocimage(display, Rect(0,0,1,1), RGB24, 1, l->textColor);
-    Rectangle r = insetrect(w->r, l->border);
+    Rectangle r = insetrect(w->r, l->border.size);
     Point s = stringsize(l->f, l->t);
     Point p = Pt(r.min.x, r.min.y + ((Dy(r)/2) - (s.y/2) + 1) );
     string(w->i, p, i, p, l->f, l->t);
     freeimage(i);
   }
 
-  if (l->border > 0){
-    if (l->d3){
+  if (l->border.size > 0){
+    if (l->border._3d){
       Image *i=allocimage(display, Rect(0,0,1,1), RGB24, 1, 0xCCCCCCFF);
-      if(l->up){
-        border3d(w->i, w->r, l->border, i, display->black, ZP);
+      if(l->border.up){
+        border3d(w->i, w->r, l->border.size, i, display->black, ZP);
       } else {
-        border3d(w->i, w->r, l->border, display->black, i, ZP);
+        border3d(w->i, w->r, l->border.size, display->black, i, ZP);
       }
       freeimage(i);
     } else {
-      border(w->i, w->r, l->border, display->black, ZP);
+      border(w->i, w->r, l->border.size, display->black, ZP);
     }
   }
   draw(dst, w->r, w->i, nil, w->p);
@@ -194,10 +194,10 @@ autosizeLabel(Widget *w){
   } else {
     Point p = stringsize(l->f, l->t);
     if (fh<0){
-      fh = p.y + (2*l->border); //2*border because is a box, we have 2 sides in this axis.
+      fh = p.y + (2*l->border.size); //2*border because is a box, we have 2 sides in this axis.
     }
     if(fw<0){
-      fw = p.x + (2*l->border); //2*border because is a box, we have 2 sides in this axis.
+      fw = p.x + (2*l->border.size); //2*border because is a box, we have 2 sides in this axis.
     }
   }
   return Rect(w->p.x, w->p.y, w->p.x + fw, w->p.y + fh);
@@ -260,3 +260,16 @@ _changeLabel(Widget *w){
     w->change(w);
   }
 }
+
+void
+_freeLabel(Widget *w){
+  if (!checkLabel(w)){
+    return;
+  }
+  Label *l = w->w;
+  free(l->t);
+  freefont(l->f);
+  free(l);
+  w->w=nil;
+  freeWidget(w);
+}

+ 70 - 0
sys/src/libjay/panel.c

@@ -16,6 +16,11 @@ void _clickPanel(Widget *w, Mouse *m);
 void _dclickPanel(Widget *w, Mouse *m);
 void _mPressDownPanel(Widget *w, Mouse *m);
 void _mPressUpPanel(Widget *w, Mouse *m);
+void _freePanel(Widget *w);
+void _deleteWidgetPanel(Widget *me, char *id);
+int _listWidgetsPanel(Widget *me, char ***list);
+Widget * _extractWidgetPanel(Widget *me, char *id);
+Widget * _getWidgetPanel(Widget *me, char *id);
 
 static void
 genPanel(Widget *w, Panel *paux, Point p){
@@ -32,6 +37,11 @@ genPanel(Widget *w, Panel *paux, Point p){
   w->_dclick=_dclickPanel;
   w->_mpressdown=_mPressDownPanel;
   w->_mpressup=_mPressUpPanel;
+  w->freeWidget=_freePanel;
+  w->deleteWidget=_deleteWidgetPanel;
+  w->listWidgets=_listWidgetsPanel;
+  w->extractWidget=_extractWidgetPanel;
+  w->getWidget=_getWidgetPanel;
   w->p=p;
 }
 
@@ -276,3 +286,63 @@ _mPressUpPanel(Widget *w, Mouse *m){
     w->lh->_mpressup(w->lh, m);
   }
 }
+
+void
+_freePanel(Widget *w){
+  if(!checkPanel(w)){
+    return;
+  }
+  Panel *p = w->w;
+  destroyWList(p->l);
+  free(p);
+  freeWidget(w);
+}
+
+Widget *
+_getWidgetPanel(Widget *me, char *id){
+  if(!checkPanel(me)){
+    return nil;
+  }
+  Panel *p = me->w;
+  WListElement *e = getWListElementByID(p->l, id);
+  if (e == nil){
+    return nil;
+  }
+  return e->w;
+}
+
+Widget *
+_extractWidgetPanel(Widget *me, char *id){
+  if(!checkPanel(me)){
+    return nil;
+  }
+  Panel *p = me->w;
+  return extractWidgetByID(p->l, id);
+}
+
+int
+_listWidgetsPanel(Widget *me, char ***list){
+  if(!checkPanel(me)){
+    return 0;
+  }
+  Panel *p = me->w;
+  int n = countWListElements(p->l);
+  *list = malloc(n);
+  int i=0;
+  for(WListElement *e = p->l; e != nil ; e=e->next ){
+    *((*list)+i) = strdup(e->w->id);
+    i++;
+  }
+  return n;
+}
+
+void
+_deleteWidgetPanel(Widget *me, char *id){
+  if(!checkPanel(me)){
+    return;
+  }
+  Panel *p = me->w;
+  Widget *w = extractWidgetByID(p->l, id);
+  w->freeWidget(w);
+  me->_redraw(me);
+}

+ 5 - 0
sys/src/libjay/utils.c

@@ -15,3 +15,8 @@ void _simpleResize(Widget *w, Point d){
     w->resize(w);
   }
 }
+
+Border createBorder(int size, int _3D, int up){
+  Border b = {size, _3D, up};
+  return b;
+}

+ 11 - 0
sys/src/libjay/widget.c

@@ -43,6 +43,11 @@ genWidget(char *id, wtype t, void *w){
   wr->change=nil;
   wr->_change=nil;
   wr->setVisible=setVisible;
+  wr->freeWidget=nil;
+  wr->deleteWidget=nil;
+  wr->getWidget=nil;
+  wr->extractWidget=nil;
+  wr->listWidgets=nil;
   return wr;
 }
 
@@ -76,6 +81,12 @@ createWidget1(char *id, Rectangle r, wtype t, void *w){
   return wr;
 }
 
+void
+freeWidget(Widget *w){
+  freeimage(w->i);
+  free(w->id);
+}
+
 static int
 checkWidget(Widget *w){
   if (w == nil || w->w == nil || w->father == nil){

+ 69 - 0
sys/src/libjay/wlist.c

@@ -28,6 +28,18 @@ getWListElementByID(WListElement *list, char *id){
   return nil;
 }
 
+WListElement *
+getWListElementByPos(WListElement *list, int pos){
+  int i=0;
+  for(WListElement *e = list; e != nil ; e=e->next ){
+    if(pos == i){
+      return e;
+    }
+    i++;
+  }
+  return nil;
+}
+
 int
 addWListElement(WListElement *list, Widget *w){
   if(list == nil){
@@ -49,3 +61,60 @@ addWListElement(WListElement *list, Widget *w){
   }
   return 0;
 }
+
+Widget *
+extractWidgetByID(WListElement *list, char *id){
+  WListElement *e = getWListElementByID(list, id);
+  if (e == nil){
+    return nil;
+  }
+  if(e->prev == nil){
+    list = e->next;
+  } else {
+    e->prev->next = e->next;
+  }
+  if(e->next != nil){
+    e->next->prev = e->prev;
+  }
+  Widget *w = e->w;
+  free(e);
+  return w;
+}
+
+Widget *
+extractWidgetByPos(WListElement *list, int pos){
+  WListElement *e = getWListElementByPos(list, pos);
+  if (e == nil){
+    return nil;
+  }
+  return extractWidgetByID(list, e->w->id);
+}
+
+void
+freeWListElement(WListElement *e){
+  if(e->w != nil){
+    e->w->freeWidget(e->w);
+    e->w=nil;
+  }
+  free(e);
+}
+
+void
+destroyWList(WListElement *list){
+  WListElement *e;
+  for(e = list; e != nil ; e=e->next ){
+    if(e->prev!=nil){
+      freeWListElement(e->prev);
+    }
+  }
+  freeWListElement(e);
+}
+
+int
+countWListElements(WListElement *list){
+  int i=0;
+  for(WListElement *e = list; e != nil ; e=e->next ){
+    i++;
+  }
+  return i;
+}

+ 38 - 11
sys/src/test/labels.c

@@ -21,8 +21,9 @@ void onClick_L3(Widget *w, Mouse *m);
 void onClick_L4(Widget *w, Mouse *m);
 void onChange_L4(Widget *w);
 
-void onPress(Widget *w, Mouse *m);
-void onRelease(Widget *w, Mouse *m);
+void onClick_L5(Widget *w, Mouse *m);
+
+void onClick_L6(Widget *w, Mouse *m);
 
 void
 threadmain(int argc, char *argv[]) {
@@ -35,10 +36,12 @@ threadmain(int argc, char *argv[]) {
   Widget *l2 = createLabel("label2", 20, 120);
   Widget *l3 = createLabel("label3", 20, 200);
   Widget *l4 = createLabel("label4", 20, 270);
+  Widget *l5 = createLabel("label5", 20, 200);
+  Widget *l6 = createLabel("label6", -1, -1);
 
   Label *aux = l->w;
   aux->setText(aux, "This is a label with autosize");
-  aux->border=1;
+  aux->border=createBorder(1, 0, 0);
   l->hover=onHover_L1;
   l->unhover=onHover_L1;
   l->click=onClick_L1;
@@ -46,8 +49,7 @@ threadmain(int argc, char *argv[]) {
 
   aux = l2->w;
   aux->setText(aux, "Click me");
-  aux->border=1;
-  aux->d3=1;
+  aux->border=createBorder(1, 1, 0);
   l2->click=onClick_L2;
   l2->dclick=onDClick_L2;
   l2->hover = onHover_L2;
@@ -65,6 +67,16 @@ threadmain(int argc, char *argv[]) {
   l4->click=onClick_L4;
   w->addWidget(w, l4, Pt(30, 120));
 
+  aux = l5->w;
+  aux->setText(aux, "Delete Label");
+  l5->click=onClick_L5;
+  w->addWidget(w, l5, Pt(30, 150));
+
+  aux = l6->w;
+  aux->setText(aux, "List widgets");
+  l6->click=onClick_L6;
+  w->addWidget(w, l6, Pt(30, 180));
+
   startjayapp(w);
   threadexits(nil);
 }
@@ -73,18 +85,18 @@ threadmain(int argc, char *argv[]) {
 void onHover_L1(Widget *w){
   Label *l = w->w;
   if(w->hovered){
-    l->border=3;
+    l->border.size=3;
   } else {
-    l->border=1;
+    l->border.size=1;
   }
 }
 
 void onHover_L2(Widget *w){
   Label *l = w->w;
   if(w->hovered){
-    l->up=1;
+    l->border.up=1;
   } else {
-    l->up=0;
+    l->border.up=0;
   }
 }
 
@@ -147,10 +159,25 @@ void onDClick_L2(Widget *w, Mouse *m){
 
 void onPress(Widget *w, Mouse *m){
   Label *l = w->w;
-  l->border=0;
+  l->border.size=0;
 }
 
 void onRelease(Widget *w, Mouse *m){
   Label *l = w->w;
-  l->border=1;
+  l->border.size=1;
+}
+
+void onClick_L5(Widget *w, Mouse *m){
+  w->father->deleteWidget(w->father, w->id);
+}
+
+void onClick_L6(Widget *w, Mouse *m){
+  char buf[512]="";
+  char **l=nil;
+  int n = w->father->listWidgets(w->father, &l);
+  for (int i = 0; i<n; i++){
+    sprint(buf, "%s%s ",buf, *(l+i));
+  }
+  Label *lbl = w->w;
+  lbl->setText(lbl, buf);
 }