From 6f5318f35078e408b2f4da3f360d91e1c15b3daf Mon Sep 17 00:00:00 2001
From: Ivica Ico Bukvic <ico@vt.edu>
Date: Thu, 17 Sep 2020 22:12:18 -0400
Subject: [PATCH] Improvements to iemgui numbox (drawstyle, font sizing and
 dialog)

* drawstyle ported from 1.x (formerly known as hide_frame option

* font sizing applies only to the label, not the number value

* number value is automatically sized based on the numbox height

* improved dialog to accommodate the new option
---
 pd/nw/dialog_iemgui.html          | 25 ++++++++++++-
 pd/nw/locales/en/translation.json |  4 ++-
 pd/nw/pdgui.js                    | 30 ++++++++++++----
 pd/src/g_all_guis.c               |  2 +-
 pd/src/g_all_guis.h               |  4 ++-
 pd/src/g_numbox.c                 | 60 ++++++++++++++++++-------------
 6 files changed, 89 insertions(+), 36 deletions(-)

diff --git a/pd/nw/dialog_iemgui.html b/pd/nw/dialog_iemgui.html
index d40dbfa8f..4a8e2861f 100644
--- a/pd/nw/dialog_iemgui.html
+++ b/pd/nw/dialog_iemgui.html
@@ -291,6 +291,27 @@
       <fieldset> 
       <legend data-i18n="iem.prop.heading.colors"></legend> 
 
+      <table class="draw_style prop hidden" style="margin-bottom: 7px;">
+        <tr>
+          <td>
+            <label data-i18n="[title]iem.prop.drawstyle_tt">
+              <span data-i18n="iem.prop.drawstyle"
+                style="margin-right: 6px;"></span>
+            </label>
+          </td>
+          <td data-i18n="[title]iem.prop.drawstyle_tt">
+            <select name="draw_style"
+                   onchange="update_attr(this, true);"
+                   style="width: 14em;">
+              <option value="0">draw everything (default)</option>
+              <option value="1">draw frame only</option>
+              <option value="2">draw triangle only</option>
+              <option value="3">draw number only</option> 
+            </select>
+          </td>
+          <td>
+      </table>
+
       <div class="background_color prop hidden">
         <label data-i18n="[title]iem.prop.bgcolor_tt">
           <input type="color" name="background_color"
@@ -512,6 +533,8 @@ function send_params(attrs, create_undo_point) {
 
     var slot18 = attrs.steady_on_click ? +attrs.steady_on_click : 0;
 
+    var draw_style = attrs.draw_style ? +attrs.draw_style : 0;
+
     pdgui.pdsend(pd_object_callback, "dialog",
         width, height,
         slot3, // bng: flash_interrupt
@@ -532,7 +555,7 @@ function send_params(attrs, create_undo_point) {
         background_color, foreground_color,
         label_color,
         slot18, // steady on click
-        0, // not sure what this is doing here
+        draw_style, // numbox draw style
         create_undo_point ? 1 : 0 // whether we set an undo point
     );
 }
diff --git a/pd/nw/locales/en/translation.json b/pd/nw/locales/en/translation.json
index b54d90c99..9883efa2a 100644
--- a/pd/nw/locales/en/translation.json
+++ b/pd/nw/locales/en/translation.json
@@ -5,7 +5,7 @@
           "size":    "size and behavior",
           "messages": "messaging",
           "label":   "label",
-          "colors":  "colors"
+          "colors":  "appearance"
       },
       "size_tt": "size of the iemgui",
       "size": "size",
@@ -41,6 +41,8 @@
       "log_height_tt":   "the framus intersects with the ramistan approximately at the podernoster",
       "steady":       "steady on click",
       "steady_tt":    "don't move the slider when clicked. Only move it when dragging the mouse",
+      "drawstyle":    "frame style",
+      "drawstyle_tt":    "adjust number frame style by toggling its elements",
       "send":         "send symbol",
       "send_tt":      "symbol to send wireless messages to other iemguis or objects",
       "receive":      "receive symbol",
diff --git a/pd/nw/pdgui.js b/pd/nw/pdgui.js
index 7e90a2594..4fcacc3d9 100644
--- a/pd/nw/pdgui.js
+++ b/pd/nw/pdgui.js
@@ -3272,13 +3272,18 @@ function gui_toggle_update(cid, tag, state, color) {
     })
 }
 
-function numbox_data_string(w, h) {
+function numbox_data_string_frame(w, h) {
     return ["M", 0, 0,
             "L", w - 4, 0,
                  w, 4,
                  w, h,
                  0, h,
-            "z",
+            "z"]
+    .join(" ");
+}
+
+function numbox_data_string_triangle(w, h) {
+    return ["M", 0, 0,
             "L", 0, 0,
                  (h / 2)|0, (h / 2)|0, // |0 to force int
                  0, h]
@@ -3286,27 +3291,38 @@ function numbox_data_string(w, h) {
 }
 
 // Todo: send fewer parameters from c
-function gui_numbox_new(cid, tag, color, x, y, w, h, is_toplevel) {
+function gui_numbox_new(cid, tag, color, x, y, w, h, drawstyle, is_toplevel) {
     // numbox doesn't have a standard iemgui border,
     // so we must create its gobj manually
     gui(cid).get_elem("patchsvg", function() {
         var g = gui_gobj_new(cid, tag, "iemgui", x, y, is_toplevel);
-        var data = numbox_data_string(w, h);
         var border = create_item(cid, "path", {
-            d: data,
+            d: numbox_data_string_frame(w, h),
             fill: color,
             stroke: "black",
-            "stroke-width": 1,
+            "stroke-width": (drawstyle < 2 ? 1 : 0),
             id: (tag + "border"),
             "class": "border"
         });
         g.appendChild(border);
+        var triangle = create_item(cid, "path", {
+            d: numbox_data_string_triangle(w, h),
+            fill: color,
+            stroke: "black",
+            "stroke-width": (drawstyle == 0 || drawstyle ==  2 ? 1 : 0),
+            id: (tag + "triangle"),
+            "class": "border"
+        });
+        g.appendChild(triangle);
     });
 }
 
 function gui_numbox_coords(cid, tag, w, h) {
     gui(cid).get_elem(tag + "border", {
-        d: numbox_data_string(w, h)
+        d: numbox_data_string_frame(w, h)
+    });
+    gui(cid).get_elem(tag + "triangle", {
+        d: numbox_data_string_triangle(w, h)
     });
 }
 
diff --git a/pd/src/g_all_guis.c b/pd/src/g_all_guis.c
index 1af9841ae..7b65fe13e 100644
--- a/pd/src/g_all_guis.c
+++ b/pd/src/g_all_guis.c
@@ -1268,7 +1268,7 @@ void iemgui_draw_io(t_iemgui *x, int old_sr_flags)
     t_canvas *canvas=glist_getcanvas(x->x_glist);
     if (x->x_glist != canvas) return; // is gop
     t_class *c = pd_class((t_pd *)x);
-    if (c == my_numbox_class && ((t_my_numbox *)x)->x_hide_frame > 1)
+    if (c == my_numbox_class && ((t_my_numbox *)x)->x_drawstyle > 1)
         return; //sigh
     if (!(old_sr_flags&4) && !glist_isvisible(canvas))
     {
diff --git a/pd/src/g_all_guis.h b/pd/src/g_all_guis.h
index d7dec8359..b40ac12fe 100644
--- a/pd/src/g_all_guis.h
+++ b/pd/src/g_all_guis.h
@@ -191,8 +191,10 @@ typedef struct _my_numbox
     int      x_scalewidth;  /* temporary value for scalehandle */
     int      x_scaleheight; /* temporary value for scalehandle */
     int      x_tmpfontsize; /* temporary value for scalehandle */
+    int      x_num_fontsize; /* font size for the number only that should
+                                automatically adjust to the box size */
     int      x_log_height;
-    int      x_hide_frame;  /* 0 default, 1 just arrow, 2, just frame, 3 both */
+    int      x_drawstyle;  /* 0 default, 1 just frame, 2, just arrow, 3 number only */
 } t_my_numbox;
 
 extern int sys_noloadbang;
diff --git a/pd/src/g_numbox.c b/pd/src/g_numbox.c
index b72c46bc9..e668be5d2 100644
--- a/pd/src/g_numbox.c
+++ b/pd/src/g_numbox.c
@@ -74,15 +74,17 @@ void my_numbox_clip(t_my_numbox *x)
 int my_numbox_calc_fontwidth2(t_my_numbox *x, int w, int h, int fontsize)
 {
     int f=31;
-    if     (x->x_gui.x_font_style == 1) f = 27;
-    else if(x->x_gui.x_font_style == 2) f = 25;
+    // ico@vt.edu 20200917: below options are disabled for the value
+    // inside the numbox since we ignore those in 2.x
+    //if     (x->x_gui.x_font_style == 1) f = 27;
+    //else if(x->x_gui.x_font_style == 2) f = 25;
     return (fontsize * f * w) / 36 + (h / 2) + 4;
 }
 
 int my_numbox_calc_fontwidth(t_my_numbox *x)
 {
     return my_numbox_calc_fontwidth2(x,x->x_gui.x_w,x->x_gui.x_h,
-        x->x_gui.x_fontsize);
+        x->x_num_fontsize);
 }
 
 void my_numbox_ftoa(t_my_numbox *x)
@@ -198,7 +200,7 @@ static void my_numbox_draw_new(t_my_numbox *x, t_glist *glist)
     int x1=text_xpix(&x->x_gui.x_obj, glist), x2=x1+x->x_numwidth;
     int y1=text_ypix(&x->x_gui.x_obj, glist), y2=y1+x->x_gui.x_h;
 
-    gui_vmess("gui_numbox_new", "xxsiiiii",
+    gui_vmess("gui_numbox_new", "xxsiiiiii",
         canvas,
         x,
         cbuf,
@@ -206,10 +208,11 @@ static void my_numbox_draw_new(t_my_numbox *x, t_glist *glist)
         y1,
         x2 - x1,
         y2 - y1,
+        x->x_drawstyle,
         glist_istoplevel(glist));
     /* Not sure when it is necessary to hide the frame... perhaps for
        k12? */
-    if (!x->x_hide_frame || x->x_hide_frame == 2)
+    if (!x->x_drawstyle || x->x_drawstyle == 2)
     {
         //sys_vgui(".x%zx.c create polyline %d %d %d %d %d %d -stroke #%6.6x "
         //    "-tags {%zxBASE2 x%zx text iemgui}\n",
@@ -222,7 +225,7 @@ static void my_numbox_draw_new(t_my_numbox *x, t_glist *glist)
         canvas,
         x,
         x->x_buf,
-        x->x_gui.x_fontsize,
+        x->x_num_fontsize,
         cbuf,
         x1+half+2, y1+half+d, x1, y1);
 }
@@ -238,9 +241,9 @@ static void my_numbox_draw_move(t_my_numbox *x, t_glist *glist)
 
     iemgui_base_draw_move(&x->x_gui);
 
-    if (x->x_hide_frame <= 1)
+    if (x->x_drawstyle <= 1)
         iemgui_io_draw_move(&x->x_gui);
-    if (!x->x_hide_frame || x->x_hide_frame == 2)
+    if (!x->x_drawstyle || x->x_drawstyle == 2)
     {
         //sys_vgui(".x%zx.c coords %zxBASE2 %d %d %d %d %d %d\n",
         //    canvas, x, x1, y1, x1 + half, y1 + half, x1, y2);
@@ -271,7 +274,7 @@ static void my_numbox_draw_config(t_my_numbox* x,t_glist* glist)
         fg,
         bg,
         iemgui_typeface((t_iemgui *)x),
-        x->x_gui.x_fontsize,
+        x->x_num_fontsize,
         sys_fontweight);
 }
 
@@ -329,12 +332,14 @@ static void my_numbox__motionhook(t_scalehandle *sh,
             dy, x->x_gui.x_obj.te_ypix + SCALE_NUM_MINHEIGHT);
 
         /* then readjust fontsize */
-        x->x_tmpfontsize = maxi((newy - x->x_gui.x_obj.te_ypix) * 0.8,
+        x->x_tmpfontsize = maxi((newy - x->x_gui.x_obj.te_ypix) * 0.9,
             IEM_FONT_MINSIZE);
 
         int f = 31;
-        if     (x->x_gui.x_font_style == 1) f = 27;
-        else if(x->x_gui.x_font_style == 2) f = 25;
+        // ico@vt.edu 20200917: below options are disabled for the value
+        // inside the numbox since we ignore those in 2.x
+        //if     (x->x_gui.x_font_style == 1) f = 27;
+        //else if(x->x_gui.x_font_style == 2) f = 25;
         int char_w = (x->x_tmpfontsize * f) / 36;
 
         /* get the new total width */
@@ -359,7 +364,7 @@ static void my_numbox__motionhook(t_scalehandle *sh,
         //    dx,dy,x->x_scalewidth,x->x_scaleheight,numwidth,sh->h_dragx);
         scalehandle_drag_scale(sh);
 
-        x->x_gui.x_fontsize = x->x_tmpfontsize;
+        x->x_num_fontsize = x->x_tmpfontsize;
         x->x_gui.x_w = new_char_len;
         x->x_gui.x_h = x->x_scaleheight;
         x->x_numwidth = my_numbox_calc_fontwidth(x);
@@ -434,7 +439,7 @@ static void my_numbox_save(t_gobj *z, t_binbuf *b)
         srl[0], srl[1], srl[2], x->x_gui.x_ldx, x->x_gui.x_ldy,
         iem_fstyletoint(&x->x_gui), x->x_gui.x_fontsize,
         bflcol[0], bflcol[1], bflcol[2],
-        x->x_val, x->x_log_height, x->x_hide_frame);
+        x->x_val, x->x_log_height, x->x_drawstyle);
 }
 
 int my_numbox_check_minmax(t_my_numbox *x, double min, double max)
@@ -495,7 +500,7 @@ static void my_numbox_properties(t_gobj *z, t_glist *owner)
         -----------output-range:----------- %g min: %g max: %d \
         %d lin log %d %d log-height: %d {%s} {%s} {%s} %d %d %d %d %d %d %d\n",
         x->x_gui.x_w, 1, x->x_gui.x_h, 8, x->x_min, x->x_max,
-        x->x_hide_frame, /*EXCEPTION: x_hide_frame instead of schedule*/
+        x->x_drawstyle, /*EXCEPTION: x_drawstyle instead of schedule*/
         x->x_lin0_log1, x->x_gui.x_loadinit, -1,
         x->x_log_height, /*no multi, but iem-characteristic*/
         srl[0]->s_name, srl[1]->s_name, srl[2]->s_name,
@@ -526,7 +531,7 @@ static void my_numbox_properties(t_gobj *z, t_glist *owner)
     gui_s("background_color"); gui_i(0xffffff & x->x_gui.x_bcol);
     gui_s("foreground_color"); gui_i(0xffffff & x->x_gui.x_fcol);
     gui_s("label_color");      gui_i(0xffffff & x->x_gui.x_lcol);
-    gui_s("hide_frame");       gui_i(x->x_hide_frame);
+    gui_s("draw_style");       gui_i(x->x_drawstyle);
     gui_end_array();
     gui_end_vmess();
 }
@@ -547,14 +552,15 @@ static void my_numbox_dialog(t_my_numbox *x, t_symbol *s, int argc,
     double max = atom_getfloatarg(3, argc, argv);
     x->x_lin0_log1 = !!atom_getintarg(4, argc, argv);
     x->x_log_height = maxi(atom_getintarg(6, argc, argv),10);
-    if (argc > 17)
-        x->x_hide_frame = (int)atom_getintarg(18, argc, argv);
+    x->x_drawstyle = (int)atom_getintarg(18, argc, argv);
     iemgui_dialog(&x->x_gui, argc, argv);
     x->x_numwidth = my_numbox_calc_fontwidth(x);
 
     my_numbox_check_minmax(x, min, max);
+    // automatically adjust the number font size
+    x->x_num_fontsize = maxi(x->x_gui.x_h * 0.9, IEM_FONT_MINSIZE);
     // normally, you'd do move+config, but here you have to do erase+new
-    // because iemgui_draw_io does not support changes to x_hide_frame.
+    // because iemgui_draw_io does not support changes to x_drawstyle.
     iemgui_draw_erase(&x->x_gui);
     iemgui_draw_new(&x->x_gui);
     //iemgui_draw_move(&x->x_gui);
@@ -655,13 +661,13 @@ static void my_numbox_log_height(t_my_numbox *x, t_floatarg lh)
         x->x_k = 1.0;
 }
 
-static void my_numbox_hide_frame(t_my_numbox *x, t_floatarg lh)
+static void my_numbox_drawstyle(t_my_numbox *x, t_floatarg lh)
 {
     if(lh < 0.0)
         lh = 0.0;
     if (lh > 3.0)
         lh = 3.0;
-    x->x_hide_frame = (int)lh;
+    x->x_drawstyle = (int)lh;
     my_numbox_draw(x, x->x_gui.x_glist, 4);
     my_numbox_draw(x, x->x_gui.x_glist, 2);  
 }
@@ -897,9 +903,9 @@ static void *my_numbox_new(t_symbol *s, int argc, t_atom *argv)
     else iemgui_new_getnames(&x->x_gui, 6, 0);
     if((argc == 18)&&IS_A_FLOAT(argv,17))
         log_height = maxi(atom_getintarg(17, argc, argv),10);
-    x->x_hide_frame = 0; // default behavior
+    x->x_drawstyle = 0; // default behavior
     if((argc == 19)&&IS_A_FLOAT(argv,18))
-        x->x_hide_frame = (int)atom_getintarg(18, argc, argv);
+        x->x_drawstyle = (int)atom_getintarg(18, argc, argv);
     x->x_gui.x_draw = (t_iemfunptr)my_numbox_draw;
     x->x_gui.x_glist = (t_glist *)canvas_getcurrent();
     x->x_val = x->x_gui.x_loadinit ? v : 0.0;
@@ -914,6 +920,9 @@ static void *my_numbox_new(t_symbol *s, int argc, t_atom *argv)
     x->x_gui.x_w = w;
     x->x_gui.x_h = h;
     x->x_buf[0] = 0;
+    // default font size that will then automatically adjust
+    // based on width and height
+    x->x_num_fontsize = maxi(x->x_gui.x_h * 0.9, IEM_FONT_MINSIZE);
     x->x_numwidth = my_numbox_calc_fontwidth(x);
     my_numbox_check_minmax(x, min, max);
     iemgui_verify_snd_ne_rcv(&x->x_gui);
@@ -927,6 +936,7 @@ static void *my_numbox_new(t_symbol *s, int argc, t_atom *argv)
     x->x_scalewidth = 0;
     x->x_scaleheight = 0;
     x->x_tmpfontsize = 0;
+
     x->x_gui.x_obj.te_iemgui = 1;
     x->x_gui.x_changed = 0;
 
@@ -981,8 +991,8 @@ void g_numbox_setup(void)
         gensym("init"), A_FLOAT, 0);
     class_addmethod(my_numbox_class, (t_method)my_numbox_log_height,
         gensym("log_height"), A_FLOAT, 0);
-    class_addmethod(my_numbox_class, (t_method)my_numbox_hide_frame,
-        gensym("hide_frame"), A_FLOAT, 0);
+    class_addmethod(my_numbox_class, (t_method)my_numbox_drawstyle,
+        gensym("drawstyle"), A_FLOAT, 0);
 
     numbox_keyname_sym_a = gensym("#keyname_a");
 
-- 
GitLab