starting the material window
authorJohn Tsiombikas <nuclear@member.fsf.org>
Mon, 3 Jul 2023 21:03:57 +0000 (00:03 +0300)
committerJohn Tsiombikas <nuclear@member.fsf.org>
Mon, 3 Jul 2023 21:03:57 +0000 (00:03 +0300)
Makefile
src/modui.c [new file with mode: 0644]
src/modui.h [new file with mode: 0644]
src/rtk.c
src/rtk.h
src/rtk_impl.h
src/scr_mod.c

index 634f40a..35c61a6 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -4,8 +4,8 @@ dosobj = src/dos/main.obj src/dos/keyb.obj src/dos/mouse.obj src/dos/timer.obj &
        src/dos/drv_s3.obj
 appobj = src/app.obj src/cmesh.obj src/darray.obj src/font.obj src/logger.obj &
        src/meshgen.obj src/meshload.obj src/options.obj src/rbtree.obj src/geom.obj &
-       src/rend.obj src/rtk.obj src/scene.obj src/scr_mod.obj src/scr_rend.obj &
-       src/texture.obj src/material.obj &
+       src/rend.obj src/rtk.obj src/scene.obj src/scr_mod.obj src/modui.obj &
+       src/scr_rend.obj src/texture.obj src/material.obj &
        src/util.obj src/util_s.obj src/cpuid.obj src/cpuid_s.obj
 gawobj = src/gaw/gaw_sw.obj src/gaw/gawswtnl.obj src/gaw/polyclip.obj src/gaw/polyfill.obj
 
@@ -17,8 +17,8 @@ dosobj = src\dos\main.obj src\dos\keyb.obj src\dos\mouse.obj src\dos\timer.obj &
        src\dos\drv_s3.obj
 appobj = src\app.obj src\cmesh.obj src\darray.obj src\font.obj src\logger.obj &
        src\meshgen.obj src\meshload.obj src\options.obj src\rbtree.obj src\geom.obj &
-       src\rend.obj src\rtk.obj src\scene.obj src\scr_mod.obj src\scr_rend.obj &
-       src\texture.obj src\material.obj &
+       src\rend.obj src\rtk.obj src\scene.obj src\scr_mod.obj src\modui.obj &
+       src\scr_rend.obj src\texture.obj src\material.obj &
        src\util.obj src\util_s.obj src\cpuid.obj src\cpuid_s.obj
 gawobj = src\gaw\gaw_sw.obj src\gaw\gawswtnl.obj src\gaw\polyclip.obj src\gaw\polyfill.obj
 
diff --git a/src/modui.c b/src/modui.c
new file mode 100644 (file)
index 0000000..4ff94a4
--- /dev/null
@@ -0,0 +1,128 @@
+/*
+RetroRay - integrated standalone vintage modeller/renderer
+Copyright (C) 2023  John Tsiombikas <nuclear@mutantstargoat.com>
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program.  If not, see <https://www.gnu.org/licenses/>.
+*/
+#include <assert.h>
+#include "modui.h"
+#include "app.h"
+#include "rtk.h"
+
+static const char *tbn_icon_name[] = {
+       "new", "open", "save", 0,
+       "sel", "move", "rot", "scale", 0,
+       "add", "remove", 0,
+       "union", "isect", "diff", 0,
+       "mtl", "rend", "rend-area", "viewrend", 0, "cfg"
+};
+static int tbn_icon_pos[][2] = {
+       {0,0}, {16,0}, {32,0}, {-1,-1},
+       {48,0}, {64,0}, {80,0}, {96,0}, {-1,-1},
+       {112,0}, {112,16}, {-1,-1},
+       {0,16}, {16,16}, {32,16}, {-1,-1},
+       {48,16}, {64,16}, {64, 32}, {80,16}, {-1,-1}, {96,16}
+};
+static int tbn_istool[] = {
+       0, 0, 0, 0,
+       1, 1, 1, 1, 0,
+       0, 0, 0,
+       1, 1, 1, 0,
+       0, 0, 1, 0, 0, 0
+};
+static rtk_icon *tbn_icons[NUM_TOOL_BUTTONS];
+static rtk_widget *tbn_buttons[NUM_TOOL_BUTTONS];
+static rtk_iconsheet *icons;
+
+rtk_widget *toolbar, *mtlwin;
+rtk_widget *tools[NUM_TOOLS];
+
+static int create_toolbar(void);
+static int create_mtlwin(void);
+
+int modui_init(void)
+{
+       if(!(icons = rtk_load_iconsheet("data/icons.png"))) {
+               errormsg("failed to load iconsheet\n");
+               return -1;
+       }
+
+       if(create_toolbar() == -1) {
+               return -1;
+       }
+       if(create_mtlwin() == -1) {
+               return -1;
+       }
+       return 0;
+}
+
+static int create_toolbar(void)
+{
+       int i, toolidx;
+       rtk_widget *w;
+
+       for(i=0; i<NUM_TOOL_BUTTONS; i++) {
+               if(tbn_icon_name[i]) {
+                       tbn_icons[i] = rtk_define_icon(icons, tbn_icon_name[i],
+                                       tbn_icon_pos[i][0], tbn_icon_pos[i][1], 16, 16);
+               } else {
+                       tbn_icons[i] = 0;
+               }
+       }
+
+       if(!(toolbar = rtk_create_window(0, "toolbar", 0, 0, win_width, TOOLBAR_HEIGHT, 0))) {
+               return -1;
+       }
+       rtk_win_layout(toolbar, RTK_HBOX);
+
+       toolidx = 0;
+       for(i=0; i<NUM_TOOL_BUTTONS; i++) {
+               if(!tbn_icons[i]) {
+                       rtk_create_separator(toolbar);
+               } else {
+                       if(!(w = rtk_create_iconbutton(toolbar, tbn_icons[i], 0))) {
+                               return -1;
+                       }
+                       tbn_buttons[i] = w;
+                       rtk_set_callback(w, tbn_callback, (void*)(intptr_t)i);
+                       if(tbn_istool[i]) {
+                               rtk_bn_mode(w, RTK_TOGGLEBN);
+                               tools[toolidx++] = w;
+                       }
+                       if(i == TBN_SEL) {
+                               rtk_set_value(w, 1);
+                       }
+               }
+       }
+       assert(toolidx == NUM_TOOLS);
+
+       return 0;
+}
+
+static int create_mtlwin(void)
+{
+       if(!(mtlwin = rtk_create_window(0, "Materials", win_width / 2, 64, 256, 380,
+                                       RTK_WIN_FRAME | RTK_WIN_MOVABLE | RTK_WIN_RESIZABLE))) {
+               return -1;
+       }
+
+       return 0;
+}
+
+void modui_cleanup(void)
+{
+       rtk_free_widget(toolbar);
+       rtk_free_widget(mtlwin);
+       rtk_free_iconsheet(icons);
+}
diff --git a/src/modui.h b/src/modui.h
new file mode 100644 (file)
index 0000000..fafbb3d
--- /dev/null
@@ -0,0 +1,35 @@
+#ifndef MODUI_H_
+#define MODUI_H_
+
+#include "rtk.h"
+
+#define TOOLBAR_HEIGHT 26
+
+/* tools */
+enum {
+       TOOL_SEL, TOOL_MOVE, TOOL_ROT, TOOL_SCALE,
+       TOOL_UNION, TOOL_ISECT, TOOL_DIFF, TOOL_REND_AREA,
+       NUM_TOOLS
+};
+
+/* toolbar buttons */
+enum {
+       TBN_NEW, TBN_OPEN, TBN_SAVE, TBN_SEP1,
+       TBN_SEL, TBN_MOVE, TBN_ROT, TBN_SCALE, TBN_SEP2,
+       TBN_ADD, TBN_RM, TBN_SEP3,
+       TBN_UNION, TBN_ISECT, TBN_DIFF, TBN_SEP4,
+       TBN_MTL, TBN_REND, TBN_REND_AREA, TBN_VIEWREND, TBN_SEP5, TBN_CFG,
+
+       NUM_TOOL_BUTTONS
+};
+
+
+extern rtk_widget *toolbar, *mtlwin;
+extern rtk_widget *tools[NUM_TOOLS];
+
+int modui_init(void);
+void modui_cleanup(void);
+
+void tbn_callback(rtk_widget *w, void *cls);
+
+#endif /* MODUI_H_ */
index 95ad604..4049f88 100644 (file)
--- a/src/rtk.c
+++ b/src/rtk.c
@@ -126,6 +126,23 @@ void rtk_set_callback(rtk_widget *w, rtk_callback cbfunc, void *cls)
        w->any.cbcls = cls;
 }
 
+void rtk_show(rtk_widget *w)
+{
+       w->any.flags |= VISIBLE;
+       rtk_invalidate(w);
+}
+
+void rtk_hide(rtk_widget *w)
+{
+       w->any.flags &= ~VISIBLE;
+       invalfb(w);
+}
+
+int rtk_visible(const rtk_widget *w)
+{
+       return w->any.flags & VISIBLE;
+}
+
 void rtk_invalidate(rtk_widget *w)
 {
        w->any.flags |= DIRTY;
@@ -247,7 +264,8 @@ rtk_icon *rtk_bn_get_icon(rtk_widget *w)
 
 /* --- constructors --- */
 
-rtk_widget *rtk_create_window(rtk_widget *par, const char *title, int x, int y, int width, int height)
+rtk_widget *rtk_create_window(rtk_widget *par, const char *title, int x, int y,
+               int width, int height, unsigned int flags)
 {
        rtk_widget *w;
 
@@ -259,6 +277,8 @@ rtk_widget *rtk_create_window(rtk_widget *par, const char *title, int x, int y,
        rtk_set_text(w, title);
        rtk_move(w, x, y);
        rtk_resize(w, width, height);
+
+       w->any.flags |= flags << 16;
        return w;
 }
 
@@ -496,6 +516,10 @@ void rtk_draw_widget(rtk_widget *w)
 {
        int dirty;
 
+       if(!(w->any.flags & VISIBLE)) {
+               return;
+       }
+
        if(need_relayout(w)) {
                calc_layout(w);
        }
@@ -562,6 +586,9 @@ static void abs_pos(rtk_widget *w, int *xpos, int *ypos)
 #define COL_LBEV       0xffaaaaaa
 #define COL_SBEV       0xff222222
 #define COL_TEXT       0xff000000
+#define COL_WINFRM     0xff2244aa
+#define COL_WINFRM_LIT 0xff4466ff
+#define COL_WINFRM_SHAD        0xff051166
 
 static void hline(int x, int y, int sz, uint32_t col)
 {
@@ -585,6 +612,16 @@ static void vline(int x, int y, int sz, uint32_t col)
 
 enum {FRM_SOLID, FRM_OUTSET, FRM_INSET};
 
+enum {UICOL_BG, UICOL_LBEV, UICOL_SBEV};
+static uint32_t uicol[3];
+
+static void uicolor(uint32_t col, uint32_t lcol, uint32_t scol)
+{
+       uicol[UICOL_BG] = col;
+       uicol[UICOL_LBEV] = lcol;
+       uicol[UICOL_SBEV] = scol;
+}
+
 static void draw_frame(rtk_rect *rect, int type)
 {
        int tlcol, brcol;
@@ -594,12 +631,12 @@ static void draw_frame(rtk_rect *rect, int type)
                tlcol = brcol = 0xff000000;
                break;
        case FRM_OUTSET:
-               tlcol = COL_LBEV;
-               brcol = COL_SBEV;
+               tlcol = uicol[UICOL_LBEV];
+               brcol = uicol[UICOL_SBEV];
                break;
        case FRM_INSET:
-               tlcol = COL_SBEV;
-               brcol = COL_LBEV;
+               tlcol = uicol[UICOL_SBEV];
+               brcol = uicol[UICOL_LBEV];
                break;
        default:
                break;
@@ -611,14 +648,47 @@ static void draw_frame(rtk_rect *rect, int type)
        vline(rect->x + rect->width - 1, rect->y + 1, rect->height - 2, brcol);
 }
 
+#define WINFRM_SZ      2
+#define WINFRM_TBAR    16
+
 static void draw_window(rtk_widget *w)
 {
-       rtk_rect rect;
+       rtk_rect rect, frmrect, tbrect;
        rtk_widget *c;
        int win_dirty = w->any.flags & DIRTY;
 
        if(win_dirty) {
                widget_rect(w, &rect);
+
+               if(w->any.flags & FRAME) {
+                       uicolor(COL_WINFRM, COL_WINFRM_LIT, COL_WINFRM_SHAD);
+
+                       frmrect = rect;
+                       frmrect.width += WINFRM_SZ * 2;
+                       frmrect.height += WINFRM_SZ * 2 + WINFRM_TBAR;
+                       frmrect.x -= WINFRM_SZ;
+                       frmrect.y -= WINFRM_SZ + WINFRM_TBAR;
+
+                       tbrect.x = rect.x;
+                       tbrect.y = rect.y - WINFRM_TBAR;
+                       tbrect.width = rect.width;
+                       tbrect.height = WINFRM_TBAR;
+
+                       draw_frame(&frmrect, FRM_OUTSET);
+                       frmrect.x++;
+                       frmrect.y++;
+                       frmrect.width -= 2;
+                       frmrect.height -= 2;
+                       draw_frame(&frmrect, FRM_INSET);
+
+                       draw_frame(&tbrect, FRM_OUTSET);
+                       tbrect.x++;
+                       tbrect.y++;
+                       tbrect.width -= 2;
+                       tbrect.height -= 2;
+                       gfx.fill(&tbrect, COL_WINFRM);
+               }
+
                gfx.fill(&rect, COL_BG);
        }
 
@@ -646,6 +716,8 @@ static void draw_button(rtk_widget *w)
                pressed = w->any.flags & PRESS;
        }
 
+       uicolor(COL_BG, COL_LBEV, COL_SBEV);
+
        if(rect.width > 2 && rect.height > 2) {
                draw_frame(&rect, pressed ? FRM_INSET : FRM_OUTSET);
 
@@ -675,6 +747,8 @@ static void draw_separator(rtk_widget *w)
 
        if(!win) return;
 
+       uicolor(COL_BG, COL_LBEV, COL_SBEV);
+
        widget_rect(w, &rect);
        abs_pos(w, &rect.x, &rect.y);
 
index 2ebdef2..a2a54ef 100644 (file)
--- a/src/rtk.h
+++ b/src/rtk.h
@@ -1,6 +1,8 @@
 #ifndef RTK_H_
 #define RTK_H_
 
+#include "sizeint.h"
+
 /* widget type */
 enum {
        RTK_ANY,
@@ -13,6 +15,12 @@ enum {
 };
 /* window layout */
 enum { RTK_NONE, RTK_VBOX, RTK_HBOX };
+/* window flags */
+enum {
+       RTK_WIN_FRAME           = 1,
+       RTK_WIN_MOVABLE         = 2,
+       RTK_WIN_RESIZABLE       = 4
+};
 /* button mode */
 enum { RTK_PUSHBN, RTK_TOGGLEBN };
 
@@ -67,6 +75,10 @@ int rtk_get_value(rtk_widget *w);
 
 void rtk_set_callback(rtk_widget *w, rtk_callback cbfunc, void *cls);
 
+void rtk_show(rtk_widget *w);
+void rtk_hide(rtk_widget *w);
+int rtk_visible(const rtk_widget *w);
+
 void rtk_invalidate(rtk_widget *w);
 void rtk_validate(rtk_widget *w);
 
@@ -82,7 +94,8 @@ void rtk_bn_mode(rtk_widget *w, int mode);
 void rtk_bn_set_icon(rtk_widget *w, rtk_icon *icon);
 rtk_icon *rtk_bn_get_icon(rtk_widget *w);
 
-rtk_widget *rtk_create_window(rtk_widget *par, const char *title, int x, int y, int w, int h);
+rtk_widget *rtk_create_window(rtk_widget *par, const char *title, int x, int y,
+               int width, int height, unsigned int flags);
 rtk_widget *rtk_create_button(rtk_widget *par, const char *str, rtk_callback cbfunc);
 rtk_widget *rtk_create_iconbutton(rtk_widget *par, rtk_icon *icon, rtk_callback cbfunc);
 rtk_widget *rtk_create_label(rtk_widget *par, const char *text);
index 34afd0f..566e254 100644 (file)
@@ -11,7 +11,12 @@ enum {
        HOVER           = 0x010,
        PRESS           = 0x020,
        GEOMCHG         = 0x100,
-       DIRTY           = 0x200
+       DIRTY           = 0x200,
+
+       /* window flags */
+       FRAME           = RTK_WIN_FRAME << 16,
+       MOVABLE         = RTK_WIN_MOVABLE << 16,
+       RESIZABLE       = RTK_WIN_RESIZABLE << 16
 };
 
 typedef struct rtk_any {
index 834c1c0..48e51a0 100644 (file)
@@ -15,7 +15,6 @@ GNU General Public License for more details.
 You should have received a copy of the GNU General Public License
 along with this program.  If not, see <https://www.gnu.org/licenses/>.
 */
-#include <assert.h>
 #include "gaw/gaw.h"
 #include "app.h"
 #include "rtk.h"
@@ -25,48 +24,7 @@ along with this program.  If not, see <https://www.gnu.org/licenses/>.
 #include "meshgen.h"
 #include "font.h"
 #include "rend.h"
-
-enum {
-       TBN_NEW, TBN_OPEN, TBN_SAVE, TBN_SEP1,
-       TBN_SEL, TBN_MOVE, TBN_ROT, TBN_SCALE, TBN_SEP2,
-       TBN_ADD, TBN_RM, TBN_SEP3,
-       TBN_UNION, TBN_ISECT, TBN_DIFF, TBN_SEP4,
-       TBN_MTL, TBN_REND, TBN_REND_AREA, TBN_VIEWREND, TBN_SEP5, TBN_CFG,
-
-       NUM_TOOL_BUTTONS
-};
-static const char *tbn_icon_name[] = {
-       "new", "open", "save", 0,
-       "sel", "move", "rot", "scale", 0,
-       "add", "remove", 0,
-       "union", "isect", "diff", 0,
-       "mtl", "rend", "rend-area", "viewrend", 0, "cfg"
-};
-static int tbn_icon_pos[][2] = {
-       {0,0}, {16,0}, {32,0}, {-1,-1},
-       {48,0}, {64,0}, {80,0}, {96,0}, {-1,-1},
-       {112,0}, {112,16}, {-1,-1},
-       {0,16}, {16,16}, {32,16}, {-1,-1},
-       {48,16}, {64,16}, {64, 32}, {80,16}, {-1,-1}, {96,16}
-};
-static int tbn_istool[] = {
-       0, 0, 0, 0,
-       1, 1, 1, 1, 0,
-       0, 0, 0,
-       1, 1, 1, 0,
-       0, 0, 1, 0, 0, 0
-};
-static rtk_icon *tbn_icons[NUM_TOOL_BUTTONS];
-static rtk_widget *tbn_buttons[NUM_TOOL_BUTTONS];
-
-#define TOOLBAR_HEIGHT 26
-
-enum {
-       TOOL_SEL, TOOL_MOVE, TOOL_ROT, TOOL_SCALE,
-       TOOL_UNION, TOOL_ISECT, TOOL_DIFF, TOOL_REND_AREA,
-       NUM_TOOLS
-};
-static rtk_widget *tools[NUM_TOOLS];
+#include "modui.h"
 
 static int vpdirty;
 static rtk_rect totalrend;
@@ -85,7 +43,6 @@ static void mdl_motion(int x, int y);
 static void draw_object(struct object *obj);
 static void setup_material(struct material *mtl);
 static void draw_grid(void);
-static void tbn_callback(rtk_widget *w, void *cls);
 
 static void act_settool(int tidx);
 static void act_addobj(void);
@@ -104,8 +61,6 @@ struct app_screen scr_model = {
        mdl_keyb, mdl_mouse, mdl_motion
 };
 
-static rtk_widget *toolbar;
-static rtk_iconsheet *icons;
 
 static struct cmesh *mesh_sph;
 
@@ -127,47 +82,10 @@ static rtk_rect rendrect;
 
 static int mdl_init(void)
 {
-       int i, toolidx;
-       rtk_widget *w;
-
-       if(!(icons = rtk_load_iconsheet("data/icons.png"))) {
-               errormsg("failed to load iconsheet\n");
+       if(modui_init() == -1) {
+               errormsg("failed to initialize modeller UI\n");
                return -1;
        }
-       for(i=0; i<NUM_TOOL_BUTTONS; i++) {
-               if(tbn_icon_name[i]) {
-                       tbn_icons[i] = rtk_define_icon(icons, tbn_icon_name[i],
-                                       tbn_icon_pos[i][0], tbn_icon_pos[i][1], 16, 16);
-               } else {
-                       tbn_icons[i] = 0;
-               }
-       }
-
-       if(!(toolbar = rtk_create_window(0, "toolbar", 0, 0, win_width, TOOLBAR_HEIGHT))) {
-               return -1;
-       }
-       rtk_win_layout(toolbar, RTK_HBOX);
-
-       toolidx = 0;
-       for(i=0; i<NUM_TOOL_BUTTONS; i++) {
-               if(!tbn_icons[i]) {
-                       rtk_create_separator(toolbar);
-               } else {
-                       if(!(w = rtk_create_iconbutton(toolbar, tbn_icons[i], 0))) {
-                               return -1;
-                       }
-                       tbn_buttons[i] = w;
-                       rtk_set_callback(w, tbn_callback, (void*)(intptr_t)i);
-                       if(tbn_istool[i]) {
-                               rtk_bn_mode(w, RTK_TOGGLEBN);
-                               tools[toolidx++] = w;
-                       }
-                       if(i == TBN_SEL) {
-                               rtk_set_value(w, 1);
-                       }
-               }
-       }
-       assert(toolidx == NUM_TOOLS);
 
        if(!(mesh_sph = cmesh_alloc())) {
                errormsg("failed to allocate sphere vis mesh\n");
@@ -182,7 +100,7 @@ static int mdl_init(void)
 static void mdl_destroy(void)
 {
        cmesh_free(mesh_sph);
-       rtk_free_iconsheet(icons);
+       modui_cleanup();
 }
 
 static int mdl_start(void)
@@ -246,6 +164,7 @@ static void mdl_display(void)
 
                /* dirty all GUI windows */
                rtk_invalidate(toolbar);
+               rtk_invalidate(mtlwin);
        }
 
        /* render layer */
@@ -258,6 +177,7 @@ static void mdl_display(void)
 
        /* GUI */
        rtk_draw_widget(toolbar);
+       rtk_draw_widget(mtlwin);
 }
 
 static void draw_object(struct object *obj)
@@ -488,7 +408,7 @@ static void add_sphere(void)
        scn_add_object(scn, obj);
 }
 
-static void tbn_callback(rtk_widget *w, void *cls)
+void tbn_callback(rtk_widget *w, void *cls)
 {
        int id = (intptr_t)cls;
 
@@ -509,6 +429,16 @@ static void tbn_callback(rtk_widget *w, void *cls)
        case TBN_DIFF:
                act_settool(id - TBN_UNION + TOOL_UNION);
                break;
+
+       case TBN_MTL:
+               if(rtk_visible(mtlwin)) {
+                       rtk_hide(mtlwin);
+                       inval_vport();
+               } else {
+                       rtk_show(mtlwin);
+               }
+               break;
+
        case TBN_REND_AREA:
                act_settool(TOOL_REND_AREA);
                break;