From b41da278f588de6cb86d3a0e55b919d7349152d7 Mon Sep 17 00:00:00 2001 From: beriff Date: Fri, 6 Mar 2026 21:21:56 +0700 Subject: [PATCH] feat: revealer-based tool menu --- .../actions/vektor-circle-symbolic.svg | 1 + .../scalable/actions/vektor-circle.svg | 1 + .../scalable/actions/vektor-line-symbolic.svg | 1 + .../scalable/actions/vektor-rect-symbolic.svg | 1 + .../scalable/actions/vektor-tool-symbolic.svg | 1 + src/application/applicationstate.c | 20 +++++ src/ui/uicontroller.c | 20 +++++ src/ui/uicontroller.h | 5 ++ ui/main.css | 2 +- ui/main.ui | 86 ++++++++++++++++--- 10 files changed, 127 insertions(+), 11 deletions(-) create mode 100644 icons/hicolor/scalable/actions/vektor-circle-symbolic.svg create mode 100644 icons/hicolor/scalable/actions/vektor-circle.svg create mode 100644 icons/hicolor/scalable/actions/vektor-line-symbolic.svg create mode 100644 icons/hicolor/scalable/actions/vektor-rect-symbolic.svg create mode 100644 icons/hicolor/scalable/actions/vektor-tool-symbolic.svg diff --git a/icons/hicolor/scalable/actions/vektor-circle-symbolic.svg b/icons/hicolor/scalable/actions/vektor-circle-symbolic.svg new file mode 100644 index 0000000..13b3824 --- /dev/null +++ b/icons/hicolor/scalable/actions/vektor-circle-symbolic.svg @@ -0,0 +1 @@ + diff --git a/icons/hicolor/scalable/actions/vektor-circle.svg b/icons/hicolor/scalable/actions/vektor-circle.svg new file mode 100644 index 0000000..13b3824 --- /dev/null +++ b/icons/hicolor/scalable/actions/vektor-circle.svg @@ -0,0 +1 @@ + diff --git a/icons/hicolor/scalable/actions/vektor-line-symbolic.svg b/icons/hicolor/scalable/actions/vektor-line-symbolic.svg new file mode 100644 index 0000000..66a97ac --- /dev/null +++ b/icons/hicolor/scalable/actions/vektor-line-symbolic.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/hicolor/scalable/actions/vektor-rect-symbolic.svg b/icons/hicolor/scalable/actions/vektor-rect-symbolic.svg new file mode 100644 index 0000000..3ab8869 --- /dev/null +++ b/icons/hicolor/scalable/actions/vektor-rect-symbolic.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/hicolor/scalable/actions/vektor-tool-symbolic.svg b/icons/hicolor/scalable/actions/vektor-tool-symbolic.svg new file mode 100644 index 0000000..ec94c87 --- /dev/null +++ b/icons/hicolor/scalable/actions/vektor-tool-symbolic.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/application/applicationstate.c b/src/application/applicationstate.c index fdd4ab5..2cb8fd1 100644 --- a/src/application/applicationstate.c +++ b/src/application/applicationstate.c @@ -1,10 +1,12 @@ #include "./applicationstate.h" #include "glib.h" +#include "gtk/gtkrevealer.h" #include "src/core/primitives.h" #include "src/core/raster.h" #include "src/ui/vektorcanvas.h" typedef struct button_tool_set_data { + GtkRevealer* revealer; VektorAppState* state; VektorAppTool tool; } button_tool_set_data; @@ -13,10 +15,19 @@ static void appstate_set_tool(GtkButton* button, gpointer user_data) { button_tool_set_data* data = (button_tool_set_data*)user_data; data->state->selectedTool = data->tool; + // setting tool makes the sub-tools menu to close + gtk_revealer_set_reveal_child(data->revealer, FALSE); + // setting tool also resets selected primitive data->state->selectedPrimitive = NULL; } +static void appstate_reveal_subtools(GtkButton* button, gpointer user_data) { + GtkRevealer* revealer = (GtkRevealer*)user_data; + gboolean visible = gtk_revealer_get_reveal_child(revealer); + gtk_revealer_set_reveal_child(revealer, !visible); +} + static void canvas_onclick(GtkGestureClick* gesture, int n_press, double x, double y, gpointer user_data) { @@ -76,6 +87,7 @@ void vektor_appstate_new(VektorWidgetState* wstate, VektorAppState* stateOut) { button_tool_set_data* data_linetool = malloc(sizeof(button_tool_set_data)); data_linetool->state = stateOut; data_linetool->tool = VektorLineTool; + data_linetool->revealer = wstate->workspaceRevealerShapes; // populate appstate stateOut->primitiveBuffer = malloc(sizeof(VektorPrimitiveBuffer)); @@ -88,6 +100,14 @@ void vektor_appstate_new(VektorWidgetState* wstate, VektorAppState* stateOut) { // link all the buttons g_signal_connect(G_OBJECT(wstate->workspaceButtonLinetool), "clicked", G_CALLBACK(appstate_set_tool), data_linetool); + g_signal_connect(G_OBJECT(wstate->workspaceButtonRecttool), "clicked", + G_CALLBACK(appstate_set_tool), data_linetool); + g_signal_connect(G_OBJECT(wstate->workspaceButtonCircletool), "clicked", + G_CALLBACK(appstate_set_tool), data_linetool); + + // hook subtool revealers to their master buttons + g_signal_connect(G_OBJECT(wstate->workspaceButtonMasterShapes), "clicked", + G_CALLBACK(appstate_reveal_subtools), wstate->workspaceRevealerShapes); // Add click gesture to canvas GtkGesture* canvasClickGesture = gtk_gesture_click_new(); diff --git a/src/ui/uicontroller.c b/src/ui/uicontroller.c index 84da301..9e26388 100644 --- a/src/ui/uicontroller.c +++ b/src/ui/uicontroller.c @@ -3,6 +3,7 @@ #include "glib-object.h" #include "gtk/gtk.h" #include "gtk/gtkcssprovider.h" +#include "gtk/gtkrevealer.h" void vektor_uictrl_init(GtkApplication* app, VektorWidgetState* stateOut) { GtkBuilder* builder = gtk_builder_new(); @@ -20,6 +21,13 @@ void vektor_uictrl_init(GtkApplication* app, VektorWidgetState* stateOut) { gdk_display_get_default(), GTK_STYLE_PROVIDER(provider), GTK_STYLE_PROVIDER_PRIORITY_APPLICATION); + // Load theme + gtk_icon_theme_add_search_path( + gtk_icon_theme_get_for_display( + gdk_display_get_default() + ), "icons" + ); + // populate state stateOut->window = GTK_WINDOW(gtk_builder_get_object(builder, "main_window")); @@ -27,8 +35,18 @@ void vektor_uictrl_init(GtkApplication* app, VektorWidgetState* stateOut) { GTK_PANED(gtk_builder_get_object(builder, "workspace_paned")); stateOut->workspaceCanvas = GTK_GL_AREA(gtk_builder_get_object(builder, "workspace")); + + stateOut->workspaceButtonMasterShapes = + GTK_BUTTON(gtk_builder_get_object(builder, "button_shapetools")); + stateOut->workspaceRevealerShapes = + GTK_REVEALER(gtk_builder_get_object(builder, "shape_revealer")); stateOut->workspaceButtonLinetool = GTK_BUTTON(gtk_builder_get_object(builder, "button_linetool")); + stateOut->workspaceButtonRecttool = + GTK_BUTTON(gtk_builder_get_object(builder, "button_rectangletool")); + stateOut->workspaceButtonCircletool = + GTK_BUTTON(gtk_builder_get_object(builder, "button_circletool")); + // Set window properties gtk_window_set_application(stateOut->window, app); @@ -44,4 +62,6 @@ void vektor_uictrl_map(VektorWidgetState* state) { int window_width = gtk_widget_get_width(GTK_WIDGET(state->window)); g_print("%i", window_width); gtk_paned_set_position(state->workspacePaned, 800 * .7); + + } diff --git a/src/ui/uicontroller.h b/src/ui/uicontroller.h index 723274e..5ebd16d 100644 --- a/src/ui/uicontroller.h +++ b/src/ui/uicontroller.h @@ -2,6 +2,7 @@ #define VKTR_UICTRL_H #include "gtk/gtk.h" +#include "gtk/gtkrevealer.h" /* Global application widget state, holding references to @@ -12,7 +13,11 @@ typedef struct VektorWidgetState { GtkPaned* workspacePaned; GtkGLArea* workspaceCanvas; + GtkButton* workspaceButtonMasterShapes; + GtkRevealer* workspaceRevealerShapes; GtkButton* workspaceButtonLinetool; + GtkButton* workspaceButtonRecttool; + GtkButton* workspaceButtonCircletool; // GtkWidget* Workspace } VektorWidgetState; diff --git a/ui/main.css b/ui/main.css index 35b16f7..57b909d 100755 --- a/ui/main.css +++ b/ui/main.css @@ -5,5 +5,5 @@ } button { - background: none; + /*background: none;*/ } \ No newline at end of file diff --git a/ui/main.ui b/ui/main.ui index 718ee6c..fe103ea 100644 --- a/ui/main.ui +++ b/ui/main.ui @@ -45,13 +45,6 @@ - - true true @@ -71,15 +64,64 @@ 12 + + - - insert-object-symbolic + + horizontal + + + + + vektor-tool-symbolic + + + + + + + slide-right + + + + + horizontal + + + + + vektor-line-symbolic + + + + + + + vektor-rect-symbolic + + + + + + + vektor-circle-symbolic + + + + + + + + + + - + edit-copy-symbolic + start @@ -99,8 +141,32 @@ + + + + + + horizontal + 6 + 6 + 3 + 3 + + + + + 0 MiB + 0 + + + + + + + + \ No newline at end of file