From e84900047543f69ff1721ba103f4288cfd020a57 Mon Sep 17 00:00:00 2001 From: Olaf Wintermann Date: Sun, 12 Jan 2025 20:36:05 +0100 Subject: [PATCH] add basic frame for custom files view widget (GTK4) --- mizunara/Makefile | 1 + mizunara/application.h | 15 ++++++++++ mizunara/filebrowser.c | 5 ++++ mizunara/gtk-filesview.c | 61 ++++++++++++++++++++++++++++++++++++++++ mizunara/gtk-filesview.h | 56 ++++++++++++++++++++++++++++++++++++ mizunara/window.c | 35 ++++++++++++++++++++++- mizunara/window.h | 2 ++ ui/gtk/container.c | 11 ++++++++ ui/ui/container.h | 18 ++++++++++++ 9 files changed, 203 insertions(+), 1 deletion(-) create mode 100644 mizunara/gtk-filesview.c create mode 100644 mizunara/gtk-filesview.h diff --git a/mizunara/Makefile b/mizunara/Makefile index 2f8d5e3..8fa6d75 100644 --- a/mizunara/Makefile +++ b/mizunara/Makefile @@ -36,6 +36,7 @@ SRC += application.c SRC += menu.c SRC += window.c SRC += filebrowser.c +SRC += gtk-filesview.c SRC += $(MZUI) diff --git a/mizunara/application.h b/mizunara/application.h index 25e00d2..9b10531 100644 --- a/mizunara/application.h +++ b/mizunara/application.h @@ -56,6 +56,21 @@ typedef struct MainWindow { */ typedef struct FileBrowser { UiContext *ctx; + + /* + * view tabview (icon-grid, list) + */ + UiInteger *view; + + /* + * gridview file list + */ + UiList *grid_files; + + /* + * file listview list + */ + UiList *list_files; } FileBrowser; diff --git a/mizunara/filebrowser.c b/mizunara/filebrowser.c index 4059ccd..1a7b216 100644 --- a/mizunara/filebrowser.c +++ b/mizunara/filebrowser.c @@ -34,5 +34,10 @@ FileBrowser* filebrowser_new(const char *url) { UiContext *ctx = ui_document_context(browser); browser->ctx = ctx; + browser->view = ui_int_new(ctx, "view"); + + browser->grid_files = ui_list_new(ctx, "grid_files"); + browser->list_files = ui_list_new(ctx, "list_files"); + return browser; } diff --git a/mizunara/gtk-filesview.c b/mizunara/gtk-filesview.c new file mode 100644 index 0000000..0ce526c --- /dev/null +++ b/mizunara/gtk-filesview.c @@ -0,0 +1,61 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2024 Olaf Wintermann. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include "gtk-filesview.h" + + + + +G_DEFINE_TYPE(MzFilesView, mz_files_view, GTK_TYPE_WIDGET) + +static void mz_files_view_class_init(MzFilesViewClass *klass) { + printf("mz_files_view_class_init\n"); + klass->parent_class.snapshot = mz_files_view_snapshot; +} + +static void mz_files_view_init(MzFilesView *self) { + self->data = NULL; +} + +MzFilesView* mz_files_view_new(void) { + MzFilesView *obj = g_object_new(mz_files_view_get_type(), NULL); + obj->data = NULL; + return obj; +} + +void mz_files_view_snapshot(GtkWidget *widget, GtkSnapshot *snapshot) { + printf("mz_files_view_snapshot\n"); + + GdkRGBA red; + gdk_rgba_parse (&red, "red"); + + int w = gtk_widget_get_width(widget); + int h = gtk_widget_get_height(widget); + + gtk_snapshot_append_color(snapshot, &red, &GRAPHENE_RECT_INIT(0, 0, w, h)); +} diff --git a/mizunara/gtk-filesview.h b/mizunara/gtk-filesview.h new file mode 100644 index 0000000..cb51006 --- /dev/null +++ b/mizunara/gtk-filesview.h @@ -0,0 +1,56 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2024 Olaf Wintermann. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef MZ_GTK_FILEVIEW_H +#define MZ_GTK_FILEVIEW_H + +#include "application.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct MzFilesView { + GtkWidget widget; + void *data; +} MzFilesView; + +typedef struct MzFilesViewClass { + GtkWidgetClass parent_class; +} MzFilesViewClass; + +MzFilesView* mz_files_view_new(void); + +void mz_files_view_snapshot(GtkWidget *widget, GtkSnapshot *snapshot); + +#ifdef __cplusplus +} +#endif + +#endif /* MZ_GTK_FILEVIEW_H */ + diff --git a/mizunara/window.c b/mizunara/window.c index a03e13c..e115c46 100644 --- a/mizunara/window.c +++ b/mizunara/window.c @@ -30,6 +30,10 @@ #include "filebrowser.h" +#ifdef GTK_MAJOR_VERSION +#include "gtk-filesview.h" +#endif + UiObject* window_create(const char *url) { // toplevel window object UiObject *obj = ui_sidebar_window("Mizunara", NULL); @@ -46,7 +50,7 @@ UiObject* window_create(const char *url) { ui_attach_document(obj->ctx, browser); // add UI - ui_sidebar0(obj) { + ui_sidebar0(obj) { UiSubList sublists[] = { { .value = wdata->default_dirs, .userdata = window_sidebar_default_dirs_item }, { .value = wdata->user_dirs, .userdata = window_sidebar_user_dirs_item, .separator = TRUE } @@ -54,10 +58,39 @@ UiObject* window_create(const char *url) { ui_sourcelist(obj, .sublists = sublists, .numsublists = 2, .getvalue = window_sidebar_getvalue); } + ui_hbox(obj, .spacing = 4, .fill = UI_OFF) { + ui_button(obj, .style_class = "flat", .icon = UI_ICON_GO_BACK); + ui_button(obj, .style_class = "flat", .icon = UI_ICON_GO_FORWARD); + ui_path_textfield(obj, .varname = "path", .fill = UI_ON); + } + + window_create_browser_view(obj, wdata); + ui_set(browser->view, 0); // select default view + + return obj; } +#ifdef GTK_MAJOR_VERSION +static UIWIDGET create_filesview(UiObject *obj, UiWidgetArgs args, void *userdata) { + MzFilesView *view = mz_files_view_new(); + return GTK_WIDGET(view); +} +#endif + +void window_create_browser_view(UiObject *obj, MainWindow *win) { + ui_tabview(obj, .tabview = UI_TABVIEW_INVISIBLE, .varname = "view") { + ui_tab(obj, "iconview") { + ui_customwidget(obj, create_filesview, NULL, .fill = UI_ON); + } + + ui_tab(obj, "listview") { + + } + } +} + void windowdata_init(UiContext *ctx, MainWindow *win) { win->default_dirs = ui_list_new(ctx, NULL); diff --git a/mizunara/window.h b/mizunara/window.h index a5b46bf..d3dd96a 100644 --- a/mizunara/window.h +++ b/mizunara/window.h @@ -37,6 +37,8 @@ extern "C" { UiObject* window_create(const char *url); +void window_create_browser_view(UiObject *obj, MainWindow *win); + void windowdata_init(UiContext *ctx, MainWindow *win); void window_sidebar_getvalue(void *sublist_userdata, void *rowdata, int index, UiSubListItem *item); diff --git a/ui/gtk/container.c b/ui/gtk/container.c index 863f4a7..9a24822 100644 --- a/ui/gtk/container.c +++ b/ui/gtk/container.c @@ -52,6 +52,17 @@ int ui_container_finish(UiObject *obj) { return 1; } +UIEXPORT UIWIDGET ui_customwidget_create(UiObject *obj, ui_createwidget_func create_widget, void *userdata, UiWidgetArgs args) { + UiObject* current = uic_current_obj(obj); + + UIWIDGET widget = create_widget(obj, args, userdata); + + UI_APPLY_LAYOUT1(current, args); + current->container->add(current->container, widget, FALSE); + + return widget; +} + GtkWidget* ui_gtk_vbox_new(int spacing) { #if GTK_MAJOR_VERSION >= 3 return gtk_box_new(GTK_ORIENTATION_VERTICAL, spacing); diff --git a/ui/ui/container.h b/ui/ui/container.h index e08553f..3d194bb 100644 --- a/ui/ui/container.h +++ b/ui/ui/container.h @@ -57,6 +57,18 @@ typedef enum UiHeaderbarAlternative { UI_HEADERBAR_ALTERNATIVE_BOX } UiHeaderbarAlternative; +typedef struct UiWidgetArgs { + UiTri fill; + UiBool hexpand; + UiBool vexpand; + UiBool hfill; + UiBool vfill; + int colspan; + int rowspan; + const char *name; + const char *style_class; +} UiWidgetArgs; + typedef struct UiContainerArgs { UiTri fill; UiBool hexpand; @@ -277,6 +289,12 @@ UIEXPORT UiTabbedPane* ui_tabbed_document_view(UiObject *obj); UIEXPORT UiObject* ui_document_tab(UiTabbedPane *view); +typedef UIWIDGET (*ui_createwidget_func)(UiObject *obj, UiWidgetArgs args, void *userdata); +UIEXPORT UIWIDGET ui_customwidget_create(UiObject *obj, ui_createwidget_func create_widget, void *userdata, UiWidgetArgs args); + +#define ui_customwidget(obj, create_widget, userdata, ...) ui_customwidget_create(obj, create_widget, userdata, (UiWidgetArgs) { __VA_ARGS__ }) + + /* used for macro */ UIEXPORT void ui_container_begin_close(UiObject *obj); UIEXPORT int ui_container_finish(UiObject *obj); -- 2.43.5