From f722acdd208f5f9a0244a7042e768161aaa29f8a Mon Sep 17 00:00:00 2001 From: DanyLE Date: Wed, 5 Mar 2025 14:29:54 +0100 Subject: [PATCH] Use gt4-layer-shell 1.1.0 that supports session lock --- meson.build | 7 +- src/launcher.c | 18 +- src/main.c | 18 + src/session.c | 479 +++------------------- src/session.h | 6 +- src/shell.c | 78 +++- src/shell.h | 3 - src/wayland.c | 2 + src/widgets/cairo-box.c | 299 -------------- src/widgets/cairo-box.h | 14 - src/widgets/cairo-image.c | 263 ------------ src/widgets/cairo-image.h | 9 - src/widgets/cairo-text.c | 367 ----------------- src/widgets/cairo-text.h | 31 -- src/widgets/cairo-widget.c | 804 ------------------------------------- src/widgets/cairo-widget.h | 138 ------- src/widgets/cairo-window.c | 139 ------- src/widgets/cairo-window.h | 14 - 18 files changed, 151 insertions(+), 2538 deletions(-) delete mode 100644 src/widgets/cairo-box.c delete mode 100644 src/widgets/cairo-box.h delete mode 100644 src/widgets/cairo-image.c delete mode 100644 src/widgets/cairo-image.h delete mode 100644 src/widgets/cairo-text.c delete mode 100644 src/widgets/cairo-text.h delete mode 100644 src/widgets/cairo-widget.c delete mode 100644 src/widgets/cairo-widget.h delete mode 100644 src/widgets/cairo-window.c delete mode 100644 src/widgets/cairo-window.h diff --git a/meson.build b/meson.build index da1472b..082480f 100644 --- a/meson.build +++ b/meson.build @@ -30,7 +30,7 @@ wl_protocol_dir = wayland_protocols.get_variable('pkgdatadir') # pkg_config = import('pkgconfig') # gnome = import('gnome') -gtk_layer_shell = dependency('gtk4-layer-shell-0', version: '>=1.0.2') +gtk_layer_shell = dependency('gtk4-layer-shell-0', version: '>=1.1.0') wayland_targets=[] wl_protocols = [ @@ -56,11 +56,6 @@ src = [ 'src/shell.c', 'src/foreign.c', 'src/session.c', - 'src/widgets/cairo-widget.c', - 'src/widgets/cairo-box.c', - 'src/widgets/cairo-window.c', - 'src/widgets/cairo-image.c', - 'src/widgets/cairo-text.c', 'src/main.c', wayland_targets] diff --git a/src/launcher.c b/src/launcher.c index 8c604a7..525730c 100644 --- a/src/launcher.c +++ b/src/launcher.c @@ -12,27 +12,29 @@ static void on_launcher_destroy(GtkWindow *window, GApplication *_data) //g_application_quit (G_APPLICATION (gtk_window_get_application (window))); } -static void on_foreign_window_change(GtkApplication* app, DiyaForeignWindow * win, gpointer data) +static void on_foreign_window_change(DiyaShell* shell, DiyaForeignWindow * win, gpointer data) { - (void) app; (void) data; assert(win); - g_warning("WINDOW CHANGEEEEEEEEE %s", diya_object_to_string(DIYA_OBJECT(win))); + assert(shell); + g_warning("on_foreign_window_change: WINDOW CHANGE %s, shell %s", diya_object_to_string(DIYA_OBJECT(win)), diya_object_to_string(DIYA_OBJECT(shell))); } -static void on_foreign_window_removed(GtkApplication* app, DiyaForeignWindow * win, gpointer data) +static void on_foreign_window_removed(DiyaShell* shell, DiyaForeignWindow * win, gpointer data) { - (void) app; (void) data; assert(win); - g_warning("WINDOW removed %s", diya_object_to_string(DIYA_OBJECT(win))); + assert(shell); + g_warning("on_foreign_window_removed: WINDOW REMOVED %s, shell %s", diya_object_to_string(DIYA_OBJECT(win)), diya_object_to_string(DIYA_OBJECT(shell))); } static void session_lock(GtkWidget *widget,gpointer data) { + (void) widget; g_warning("Enter session lock"); diya_shell_lock(data); } + void diya_shell_launcher_init(DiyaShell * shell) { assert(shell); @@ -84,10 +86,10 @@ void diya_shell_launcher_init(DiyaShell * shell) { gpointer element_data = l->data; - /*g_warning("%s", g_app_info_get_display_name(element_data)); + g_warning("%s", g_app_info_get_display_name(element_data)); g_warning("%s", g_app_info_get_id(element_data)); g_warning("%s", g_app_info_get_name(element_data)); - //g_warning("%s", g_app_info_get_icon(element_data));*/ + //g_warning("%s", g_app_info_get_icon(element_data)); } g_list_free_full(apps, g_object_unref); } \ No newline at end of file diff --git a/src/main.c b/src/main.c index ceef9fb..f2f58e3 100644 --- a/src/main.c +++ b/src/main.c @@ -1,9 +1,11 @@ #include +#include #include "shell.h" #include "background.h" #include "launcher.h" #include "wayland.h" #include "foreign.h" +#include "session.h" static gchar **g_shell_argv; @@ -55,6 +57,20 @@ static void startup(GtkApplication *app, void *data) g_unix_signal_add(SIGINT,(GSourceFunc)g_application_quit,(void*)app); } +static void session_locked(DiyaShell* shell, void* data) +{ + (void)data; + assert(shell); + g_warning("session_locked callback triggered"); +} + +static void session_unlocked(DiyaShell* shell, void* data) +{ + (void)data; + assert(shell); + g_warning("session_unlocked callback triggered"); +} + int main(int argc, char *argv[]) { g_shell_argv = g_malloc0(sizeof(gchar *) * (argc + 1)); @@ -66,6 +82,8 @@ int main(int argc, char *argv[]) DiyaShell *shell = diya_shell_new(app); g_signal_connect(app, "startup", G_CALLBACK(startup), (void *)shell); g_signal_connect(app, "activate", G_CALLBACK(activate), (void *)shell); + g_signal_connect(shell, "session-locked", G_CALLBACK(session_locked), NULL); + g_signal_connect(shell, "session-unlocked", G_CALLBACK(session_unlocked), NULL); // g_signal_connect(app, "shutdown", G_CALLBACK(shutdown), (void*)shell); int status = g_application_run(G_APPLICATION(app), argc, argv); g_warning("Exiting SHELL"); diff --git a/src/session.c b/src/session.c index 75ef0ae..b9e710f 100644 --- a/src/session.c +++ b/src/session.c @@ -1,434 +1,71 @@ #include -// #include -// #include -#include -#include -#include -#include -#include -#include -#include +#include +#include #include "session.h" -#include "wayland.h" -#include "widgets/cairo-window.h" -#include "widgets/cairo-box.h" -#include "widgets/cairo-image.h" -#include "widgets/cairo-text.h" -#define DEF_SURF_W 600 -#define DEF_SURF_H 400 - -#define LOREM "Lorem ipsum dolor sit amet, consectetur adipiscing elit,\n" \ -"sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.\n" \ -"Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris \n" \ -"nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in \n" \ -"reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.\n" \ -"Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia \n" \ -"deserunt mollit anim id est laborum." - -struct _DiyaLockSession +static void unlock_session(GtkButton *button, DiyaShell *shell) { - DiyaObject parent; - - struct ext_session_lock_v1 *session_lock; - struct ext_session_lock_v1_listener session_listener; - - struct ext_session_lock_surface_v1_listener surface_listener; - struct wl_callback_listener frame_listener; - struct wl_surface *wl_surface; - - struct wl_buffer *wl_buffer; - void * raw_shared_buffer; - guint32 raw_shared_buffer_size; - cairo_surface_t *cairo_surface; - - DiyaCairoWindow * window; - - guint surface_width; - guint surface_height; - - guint32 last_frame_time; - - guint hold; -}; - -G_DEFINE_FINAL_TYPE(DiyaLockSession, diya_lock_session, DIYA_TYPE_SHELL_OBJECT) -static struct ext_session_lock_manager_v1 *g_session_lock_manager; -static const cairo_user_data_key_t shm_surface_data_key; - -static void diya_lock_session_dispose(GObject *object) -{ - DiyaLockSession *self = DIYA_LOCK_SESSION(object); - g_debug("diya_lock_session_dispose: %s", diya_object_to_string(self)); - if (self->session_lock && !self->hold) - { - ext_session_lock_v1_unlock_and_destroy(self->session_lock); - } - else - { - g_warning("diya_lock_session_dispose: the lock session is disposed but the lock has not been released"); - } - if (self->cairo_surface) - { - cairo_surface_destroy(self->cairo_surface); - self->cairo_surface = NULL; - } - if(self->window) - { - g_object_unref(self->window); - self->window = NULL; - } - G_OBJECT_CLASS(diya_lock_session_parent_class)->dispose(object); + (void)button; + assert(shell); + diya_shell_unlock(shell); } -static void handle_session_locked(void *data, struct ext_session_lock_v1 *lock) -{ - (void) lock; - DiyaShell *shell; - GtkApplication *app; - DiyaWayland *wayland; - DiyaLockSession *self = data; - g_object_get(self, "shell", &shell, NULL); +void diya_shell_lock(DiyaShell* shell) +{ assert(shell); - g_object_get(shell, "application", &app, "wayland", &wayland, NULL); + GtkSessionLockInstance * lock; + g_object_get(shell, "session-lock", &lock, NULL); + assert(lock); + if(gtk_session_lock_instance_is_locked(lock)) + { + g_warning("Shell session is already locked, doing nothing"); + return; + } + if(!gtk_session_lock_instance_lock(lock)) + { + g_error("gtk_session_lock_instance_lock:Unable to lock the current session"); + return; + } + GtkApplication * app; + g_object_get(shell, "application", &app, NULL); assert(app); - assert(DIYA_IS_WAYLAND(wayland)); - g_debug("Session locked on shell: %s", diya_object_to_string(shell)); - struct wl_surface *surface = diya_wayland_create_surface(wayland); - struct wl_output *output = diya_wayland_get_output(wayland, 0); - assert(output); - self->wl_surface = surface; - struct ext_session_lock_surface_v1 *lock_surface = ext_session_lock_v1_get_lock_surface(self->session_lock, surface, output); - ext_session_lock_surface_v1_add_listener(lock_surface, &self->surface_listener, data); - struct wl_callback *cb = wl_surface_frame(self->wl_surface); - wl_callback_add_listener(cb, &self->frame_listener, data); + GdkDisplay *display = gdk_display_get_default(); + GListModel *monitors = gdk_display_get_monitors(display); + guint n_monitors = g_list_model_get_n_items(monitors); + + for (guint i = 0; i < n_monitors; ++i) + { + GdkMonitor *monitor = g_list_model_get_item(monitors, i); + + GtkWindow *gtk_window = GTK_WINDOW(gtk_application_window_new(app)); + gtk_session_lock_instance_assign_window_to_monitor(lock, gtk_window, monitor); + + GtkWidget *box = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0); + gtk_widget_set_halign(box, GTK_ALIGN_CENTER); + gtk_widget_set_valign(box, GTK_ALIGN_CENTER); + gtk_box_set_spacing(GTK_BOX (box), 10); + + GtkWidget *label = gtk_label_new("GTK Session Lock example"); + gtk_box_append(GTK_BOX(box), label); + + GtkWidget *button = gtk_button_new_with_label("Unlock"); + g_signal_connect(button, "clicked", G_CALLBACK(unlock_session), shell); + gtk_box_append(GTK_BOX(box), button); + + // Not displayed, but allows testing that creating popups doesn't crash GTK + gtk_widget_set_tooltip_text(button, "Foo Bar Baz"); + + gtk_window_set_child(GTK_WINDOW(gtk_window), box); + gtk_window_present(gtk_window); + } } -static void handle_session_lock_finished(void *data, struct ext_session_lock_v1 *lock) +void diya_shell_unlock(DiyaShell* shell) { - DiyaShell *shell; - g_object_get(data, "shell", &shell, NULL); assert(shell); - ext_session_lock_v1_destroy(lock); - g_warning("Session locked finished on shell %s", diya_object_to_string(shell)); -} -static void randname(char *buf) -{ - long r = g_get_real_time() / 1000000; - for (int i = 0; i < 6; ++i) - { - buf[i] = 'A' + (r & 15) + (r & 16) * 2; - r >>= 5; - } -} -static int create_shm_file(void) -{ - int retries = 100; - do - { - char name[] = "/diya_shell_wl_shm-XXXXXX"; - randname(name + sizeof(name) - 7); - --retries; - int fd = shm_open(name, O_RDWR | O_CREAT | O_EXCL, 0600); - if (fd >= 0) - { - shm_unlink(name); - return fd; - } - } while (retries > 0 && errno == EEXIST); - return -1; -} - -static int allocate_shm_file(guint size) -{ - int fd = create_shm_file(); - if (fd < 0) - { - g_error("allocate_shm_file: unable to create_shm_file: %s", strerror(errno)); - return -1; - } - int ret; - do - { - ret = ftruncate(fd, size); - } while (ret < 0 && errno == EINTR); - if (ret < 0) - { - g_error("allocate_shm_file: unable to ftruncate: %s", strerror(errno)); - close(fd); - return -1; - } - return fd; -} - -static void session_lock_free_surface(void *data) -{ - DiyaLockSession * self = data; - assert(DIYA_IS_LOCK_SESSION(self)); - if (self->wl_buffer) - { - g_debug("Destroy share buffer wl_buffer"); - wl_buffer_destroy(self->wl_buffer); - self->wl_buffer = NULL; - } - if(self->raw_shared_buffer) - { - g_debug("unmapped shared buffer of %d bytes", self->raw_shared_buffer_size); - munmap(self->raw_shared_buffer, self->raw_shared_buffer_size); - self->raw_shared_buffer = NULL; - self->raw_shared_buffer_size = 0; - } -} - -static void session_lock_realloc_surface(DiyaLockSession *self) -{ - DiyaShell *shell; - g_object_get(self, "shell", &shell, NULL); - assert(DIYA_IS_SHELL(shell)); - DiyaWayland *wayland = diya_shell_get_wayland(shell); - assert(DIYA_IS_WAYLAND(wayland)); - if (self->cairo_surface) - { - cairo_surface_destroy(self->cairo_surface); - self->cairo_surface = NULL; - } - int stride = cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, self->surface_width); - guint size = stride * self->surface_height; - - int fd = allocate_shm_file(size); - if (fd == -1) - { - g_error("session_lock_realloc_surface: unable to allocate_shm_file"); - return; - } - void *data = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); - if (data == MAP_FAILED) - { - g_error("session_lock_realloc_surface: unable to mmap: %s", strerror(errno)); - close(fd); - return; - } - self->cairo_surface = cairo_image_surface_create_for_data(data, - CAIRO_FORMAT_ARGB32, - self->surface_width, - self->surface_height, - stride); - cairo_surface_set_user_data(self->cairo_surface, &shm_surface_data_key, self, session_lock_free_surface); - - struct wl_shm_pool *pool = diya_wayland_create_shm_pool(wayland, fd, size); - self->wl_buffer = wl_shm_pool_create_buffer(pool, 0, - self->surface_width, self->surface_height, stride, WL_SHM_FORMAT_XRGB8888); - wl_shm_pool_destroy(pool); - close(fd); - - self->raw_shared_buffer = data; - self->raw_shared_buffer_size = size; -} - -static void lock_session_draw_frame(DiyaLockSession *self) -{ - if(!self->cairo_surface) - { - return; - } - diya_cairo_window_render(self->window, self->cairo_surface); - - wl_surface_attach(self->wl_surface, self->wl_buffer, 0, 0); - wl_surface_damage_buffer(self->wl_surface, 0, 0, self->surface_width, self->surface_height); - wl_surface_commit(self->wl_surface); -} - -static void lock_surface_configure(void *data, - struct ext_session_lock_surface_v1 *lock_surface, - uint32_t serial, uint32_t width, uint32_t height) -{ - DiyaLockSession *self = data; - assert(DIYA_IS_LOCK_SESSION(self)); - if (!self->wl_buffer || self->surface_width != width || self->surface_height != height) - { - self->surface_width = width; - self->surface_height = height; - session_lock_realloc_surface(self); - diya_cairo_widget_set_size(self->window, width, height); - g_warning("update and damaged window"); - diya_cairo_window_update(self->window); - } - ext_session_lock_surface_v1_ack_configure(lock_surface, serial); - - lock_session_draw_frame(self); -} - - -static void lock_surface_frame_done(void *data, struct wl_callback *cb, uint32_t time) -{ - /* Destroy this callback */ - wl_callback_destroy(cb); - DiyaLockSession *lock = data; - assert(DIYA_IS_LOCK_SESSION(lock)); - cb = wl_surface_frame(lock->wl_surface); - wl_callback_add_listener(cb, &lock->frame_listener, data); - - if (!lock->cairo_surface || !lock->wl_buffer || lock->window) - { - return; - } - lock->last_frame_time = time; - lock_session_draw_frame(lock); -} - -static void diya_lock_session_ui(DiyaCairoWindow * window) -{ - diya_stroke_t stroke = { - 2.0, - { 1.0, 0.0, 1.0, 1.0 } - }; - - diya_stroke_t stroke1 = { - 2.0, - { 0.0, 0.0, 1.0, 1.0 } - }; - - diya_offset_t margin = {10,20,10,20}; - diya_offset_t padding = {20, 10, 20, 10}; - - g_object_set(window, "margin", &margin, "padding", &padding, NULL); - - DiyaCairoBox * root = g_object_new( - DIYA_TYPE_CAIRO_BOX, - "mode", DIYA_CAIRO_BOX_HORIZONTAL, - "stroke", &stroke, - NULL); - - diya_cairo_window_set_background_image(window, "/etc/xdg/labwc/wpp.jpg", TRUE); - diya_cairo_window_set_root(window, root); - - DiyaCairoBox * box = g_object_new(DIYA_TYPE_CAIRO_BOX, - "mode", DIYA_CAIRO_BOX_HORIZONTAL, - "stroke", &stroke1, - NULL); - diya_cairo_container_add(root, box); - - box = g_object_new(DIYA_TYPE_CAIRO_BOX, - "mode", DIYA_CAIRO_BOX_VERTICAL, - "vspace", DIYA_CAIRO_WIDGET_FILL_CONTENT, - "hspace", DIYA_CAIRO_WIDGET_FILL_CONTENT, - "stroke", &stroke, - NULL); - diya_cairo_container_add(root, box); - - - DiyaCairoBox* hbox = g_object_new(DIYA_TYPE_CAIRO_BOX, - "mode", DIYA_CAIRO_BOX_HORIZONTAL, - "stroke", &stroke1, - NULL); - diya_cairo_container_add(box, hbox); - - hbox = g_object_new(DIYA_TYPE_CAIRO_BOX, - "mode", DIYA_CAIRO_BOX_HORIZONTAL, - "vspace", DIYA_CAIRO_WIDGET_FILL_CONTENT, - "hspace", DIYA_CAIRO_WIDGET_FILL_CONTENT, - "stroke", &stroke, - "padding", &padding, - "corner-radius", 10.0, - NULL); - diya_cairo_container_add(box, hbox); - - diya_stroke_t stroke_img = { - 2.0, - { 0.0, 0.0, 1.0, 1.0 } - }; - diya_color_t fill = { 1.0,1.0,1.0,1.0 }; - diya_color_t color = { 0.0,0.0,0.0,1.0 }; - - DiyaCairoText *text = g_object_new(DIYA_TYPE_CAIRO_TEXT, - "vspace", DIYA_CAIRO_WIDGET_FILL_NONE, - "hspace", DIYA_CAIRO_WIDGET_FILL_NONE, - "stroke", &stroke, - "padding", &padding, - "corner-radius", 5.0, - "fill", &fill, - "color", &color, - "font-size", 11, - "font-family", "Monospace", - "halign", DIYA_CAIRO_WIDGET_ALIGN_START, - "valign", DIYA_CAIRO_WIDGET_ALIGN_START, - NULL); - diya_cairo_text_set_text(text, LOREM); - diya_cairo_widget_set_size(text, 600, 400); - diya_cairo_container_add(hbox, text); - /*DiyaCairoImage * image = g_object_new(DIYA_TYPE_CAIRO_IMAGE, - "file", - "/home/diya/test.jpg", - "stroke", - &stroke_img, - "vspace", DIYA_CAIRO_WIDGET_FILL_NONE, - "hspace", DIYA_CAIRO_WIDGET_FILL_NONE, - NULL); - diya_cairo_container_add(hbox, image);*/ - - hbox = g_object_new(DIYA_TYPE_CAIRO_BOX, - "mode", DIYA_CAIRO_BOX_HORIZONTAL, - "stroke", &stroke1, - NULL); - diya_cairo_container_add(box, hbox); - - box = g_object_new(DIYA_TYPE_CAIRO_BOX, - "mode", DIYA_CAIRO_BOX_HORIZONTAL, - "stroke", &stroke1, - NULL); - diya_cairo_container_add(root, box); -} - -static void diya_lock_session_init(DiyaLockSession *self) -{ - self->session_lock = ext_session_lock_manager_v1_lock(g_session_lock_manager); - self->session_listener.locked = handle_session_locked; - self->session_listener.finished = handle_session_lock_finished; - - self->surface_listener.configure = lock_surface_configure; - ext_session_lock_v1_add_listener(self->session_lock, &self->session_listener, self); - - self->frame_listener.done = lock_surface_frame_done; - - self->surface_width = DEF_SURF_W; - self->surface_height = DEF_SURF_H; - self->hold = true; - self->last_frame_time = 0; - - self->wl_surface = NULL; - self->wl_buffer = NULL; - - self->window = g_object_new(DIYA_TYPE_CAIRO_WINDOW,NULL); - - diya_lock_session_ui(self->window); - - self->cairo_surface = NULL; - self->raw_shared_buffer = NULL; - self->raw_shared_buffer_size = 0; -} -static const gchar *diya_lock_session_to_string(DiyaObject *object) -{ - (void)object; - // DiyaLockSession* self = DIYA_LOCK_SESSION(object); - return "DIYA SHELL LOCK SESSION"; -} - -static void diya_lock_session_class_init(DiyaLockSessionClass *class) -{ - GObjectClass *gobject_class = G_OBJECT_CLASS(class); - DiyaObjectClass *base_class = DIYA_OBJECT_CLASS(class); - - gobject_class->dispose = diya_lock_session_dispose; - - base_class->to_string = diya_lock_session_to_string; -} - -void diya_shell_session_lock_register(struct wl_registry *registry, uint32_t name) -{ - g_session_lock_manager = wl_registry_bind(registry, name, &ext_session_lock_manager_v1_interface, 1); -} - -void diya_shell_session_lock_release(DiyaLockSession *self) -{ - self->hold = false; + GtkSessionLockInstance * lock; + g_object_get(shell, "session-lock", &lock, NULL); + assert(lock); + gtk_session_lock_instance_unlock(lock); + g_debug("gtk_session_lock_instance_unlock: Shell unlocked"); } \ No newline at end of file diff --git a/src/session.h b/src/session.h index dd5719b..4b47500 100644 --- a/src/session.h +++ b/src/session.h @@ -1,9 +1,9 @@ #ifndef DIYA_SESSION_H #define DIYA_SESSION_H -#include "ext-session-lock-v1.h" #include "shell.h" -void diya_shell_session_lock_register(struct wl_registry *registry, uint32_t name); -void diya_shell_session_lock_release(DiyaLockSession * self); +void diya_shell_lock(DiyaShell* shell); +void diya_shell_unlock(DiyaShell* shell); + #endif \ No newline at end of file diff --git a/src/shell.c b/src/shell.c index 3598a82..31f8ada 100644 --- a/src/shell.c +++ b/src/shell.c @@ -1,7 +1,6 @@ #include - -#include "foreign.h" -#include "session.h" +#include +#include "shell.h" #define SHELL_DESCRIPTION "Diya GTK shell for wayland (diyac)" @@ -11,6 +10,7 @@ enum SHELL_APP, SHELL_BACKGROUND_WIDGET, SHELL_LAUNCHPAD_WIDGET, + SHELL_LOCK_SESSION, SHELL_WINDOWS, SHELL_WAYLAND, N_PROPERTIES @@ -25,7 +25,7 @@ struct _DiyaShell GtkWindow* background; GtkWindow* launcher; GHashTable* windows; - DiyaLockSession* lock; + GtkSessionLockInstance* lock; DiyaWayland * wayland; }; G_DEFINE_FINAL_TYPE(DiyaShell, diya_shell, DIYA_TYPE_OBJECT) @@ -88,6 +88,10 @@ static void diya_shell_get_property(GObject *object, guint property_id, GValue * assert(self->launcher); g_value_set_pointer(value, self->launcher); break; + case SHELL_LOCK_SESSION: + assert(self->lock); + g_value_set_pointer(value, self->lock); + break; case SHELL_WAYLAND: g_value_set_pointer(value, self->wayland); break; @@ -119,6 +123,7 @@ static void diya_shell_class_init(DiyaShellClass *class) shell_properties[SHELL_APP] = g_param_spec_pointer("application", NULL, "Shell application", G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY); shell_properties[SHELL_BACKGROUND_WIDGET] = g_param_spec_pointer("background", NULL, "Shell background widget", G_PARAM_READWRITE ); shell_properties[SHELL_LAUNCHPAD_WIDGET] = g_param_spec_pointer("launchpad", NULL, "Shell launchpad", G_PARAM_READWRITE ); + shell_properties[SHELL_LOCK_SESSION] = g_param_spec_pointer("session-lock", NULL, "Shell lock session", G_PARAM_READABLE ); shell_properties[SHELL_WINDOWS] = g_param_spec_pointer("windows", NULL, "Shell foreign windows", G_PARAM_READABLE); shell_properties[SHELL_WAYLAND] = g_param_spec_pointer("wayland", NULL, "Shell wayland", G_PARAM_READWRITE ); @@ -148,6 +153,52 @@ static void diya_shell_class_init(DiyaShellClass *class) G_TYPE_NONE, 1, G_TYPE_POINTER); + g_signal_new("session-locked", + DIYA_TYPE_SHELL, + G_SIGNAL_DETAILED | + G_SIGNAL_ACTION | + G_SIGNAL_RUN_FIRST, + 0, + NULL, + NULL, + NULL, + G_TYPE_NONE, + 0); + g_signal_new("session-unlocked", + DIYA_TYPE_SHELL, + G_SIGNAL_DETAILED | + G_SIGNAL_ACTION | + G_SIGNAL_RUN_FIRST, + 0, + NULL, + NULL, + NULL, + G_TYPE_NONE, + 0); +} + +static void on_session_locked(GtkSessionLockInstance *lock, DiyaShell *shell) { + (void)lock; + assert(shell); + g_message("Session locked successfully"); + g_signal_emit_by_name(shell, "session-locked"); +} + +/* +static void failed(GtkSessionLockInstance *lock, void *data) { + (void)lock; + (void)data; + + g_critical("The session could not be locked"); + g_application_quit(G_APPLICATION(app)); +} +*/ + +static void on_session_unlocked(GtkSessionLockInstance *lock, DiyaShell *shell) { + (void)lock; + assert(shell); + g_message("Session unlocked"); + g_signal_emit_by_name(shell, "session-unlocked"); } static void diya_shell_init(DiyaShell *self) @@ -156,6 +207,10 @@ static void diya_shell_init(DiyaShell *self) self->background = NULL; self->launcher = NULL; self->wayland = NULL; + self->lock = gtk_session_lock_instance_new(); + g_signal_connect(self->lock, "locked", G_CALLBACK(on_session_locked), self); + // g_signal_connect(lock, "failed", G_CALLBACK(failed), NULL); + g_signal_connect(self->lock, "unlocked", G_CALLBACK(on_session_unlocked), self); self->windows = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, g_object_unref); } @@ -190,21 +245,6 @@ DiyaShell * diya_shell_new(GtkApplication * app) return DIYA_SHELL(g_object_new(DIYA_TYPE_SHELL,"application",app, NULL)); } -void diya_shell_lock(DiyaShell* shell) -{ - if(shell->lock) - { - g_warning("Shell session is already locked, doing nothing"); - return; - } - shell->lock = g_object_new(DIYA_TYPE_LOCK_SESSION, "shell", shell, NULL); -} -void diya_shell_unlock(DiyaShell* shell) -{ - diya_shell_session_lock_release(shell->lock); - g_object_unref(shell->lock); - shell->lock = NULL; -} DiyaWayland * diya_shell_get_wayland(DiyaShell* shell) { DiyaWayland * wayland; diff --git a/src/shell.h b/src/shell.h index 9570a0b..59f1717 100644 --- a/src/shell.h +++ b/src/shell.h @@ -30,9 +30,6 @@ gboolean diya_shell_add_window(DiyaShell * shell, DiyaForeignWindow * win); gboolean diya_shell_remove_window(DiyaShell * shell, DiyaForeignWindow * win); void diya_shell_remove_all_windows(DiyaShell * shell); -void diya_shell_lock(DiyaShell* shell); -void diya_shell_unlock(DiyaShell* shell); - DiyaShell * diya_shell_new(GtkApplication * app); DiyaWayland * diya_shell_get_wayland(DiyaShell* shell); #endif \ No newline at end of file diff --git a/src/wayland.c b/src/wayland.c index e9054ad..50a7893 100644 --- a/src/wayland.c +++ b/src/wayland.c @@ -61,10 +61,12 @@ static void handle_global(void *data, struct wl_registry *registry, uint32_t nam { diya_shell_foreign_toplevel_register(registry, name, data); } + /* else if(!g_strcmp0(interface, ext_session_lock_manager_v1_interface.name)) { diya_shell_session_lock_register(registry, name); } + */ else if (strcmp(interface, wl_compositor_interface.name) == 0) { wayland->compositor = wl_registry_bind(registry, name, &wl_compositor_interface, 4); diff --git a/src/widgets/cairo-box.c b/src/widgets/cairo-box.c deleted file mode 100644 index c400602..0000000 --- a/src/widgets/cairo-box.c +++ /dev/null @@ -1,299 +0,0 @@ -#include -#include -#include "cairo-box.h" - -enum -{ - NO_PROP, - BOX_MODE, - N_PROPERTIES -}; -static GParamSpec *g_prop[N_PROPERTIES] = {0}; - -struct _DiyaCairoBox -{ - DiyaCairoContainer parent_object; - guint mode; -}; - -G_DEFINE_FINAL_TYPE(DiyaCairoBox, diya_cairo_box, DIYA_TYPE_CAIRO_CONTAINER) - -static void diya_cairo_box_dispose(GObject * object) -{ - g_debug("diya_cairo_box_dispose: %s", diya_object_to_string(object)); - G_OBJECT_CLASS(diya_cairo_box_parent_class)->dispose(object); -} - -static void diya_cairo_box_init(DiyaCairoBox* self) -{ - self->mode = DIYA_CAIRO_BOX_HORIZONTAL; -} - -static void diya_cairo_box_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) -{ - DiyaCairoBox * self = DIYA_CAIRO_BOX(object); - switch (property_id) - { - case BOX_MODE: - self->mode = g_value_get_uint(value); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); - break; - } -} - -static void diya_cairo_box_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec) -{ - DiyaCairoBox * self = DIYA_CAIRO_BOX(object); - switch (property_id) - { - case BOX_MODE: - g_value_set_uint(value, self->mode); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); - break; - } -} - -static gboolean cairo_box_draw(gpointer object, cairo_t * cairo) -{ - DIYA_CAIRO_WIDGET_CLASS(diya_cairo_box_parent_class)->draw(object, cairo); - GList * children = DIYA_CAIRO_CONTAINER_GET_CLASS(object)->children(object); - gpointer item; - G_LIST_FOREACH(item, children) - { - DIYA_CAIRO_WIDGET_GET_CLASS(DIYA_CAIRO_WIDGET(item))->draw(item, cairo); - } - return TRUE; -} - -static void cairo_box_update(gpointer object) -{ - diya_offset_t margin = {0}; - g_object_set( - object, - "halign", DIYA_CAIRO_WIDGET_ALIGN_START, - "valign", DIYA_CAIRO_WIDGET_ALIGN_START, - "margin", &margin, - NULL - ); - DIYA_CAIRO_WIDGET_CLASS(diya_cairo_box_parent_class)->update(object); - - assert(DIYA_IS_CAIRO_BOX(object)); - DiyaCairoBox * self = DIYA_CAIRO_BOX(object); - GList * children = DIYA_CAIRO_CONTAINER_GET_CLASS(object)->children(object); - if(!children) - { - return; - } - - diya_rect_t space = diya_cairo_widget_get_extent(object); - diya_offset_t * padding; - diya_stroke_t * stroke; - diya_rect_t * default_extent; - g_object_get(object,"padding", &padding, "stroke", &stroke, NULL); - gint stroke_size = ceil(stroke->size); - gpointer item; - guint n_extended = 0; - gint occupied_space = 2*stroke_size; - guint vspace, hspace; - guint cwidth, cheight; - // explore all other children - if(self->mode == DIYA_CAIRO_BOX_HORIZONTAL) - { - occupied_space += padding->left + padding->right; - } - else - { - occupied_space += padding->right + padding->bottom; - } - G_LIST_FOREACH(item, children) - { - g_object_get(item, "vspace", &vspace, "hspace", &hspace, "default-extent", &default_extent, NULL); - DIYA_CAIRO_WIDGET_GET_CLASS(item)->content_size(item, &cwidth, &cheight); - if(self->mode == DIYA_CAIRO_BOX_HORIZONTAL) - { - switch (hspace) - { - case DIYA_CAIRO_WIDGET_FILL_EXTEND: - n_extended++; - break; - case DIYA_CAIRO_WIDGET_FILL_CONTENT: - occupied_space += cwidth; - break; - case DIYA_CAIRO_WIDGET_FILL_NONE: - occupied_space += default_extent->width; - break; - default: - break; - } - } - else - { - switch (vspace) - { - case DIYA_CAIRO_WIDGET_FILL_EXTEND: - n_extended++; - break; - case DIYA_CAIRO_WIDGET_FILL_CONTENT: - occupied_space += cheight; - break; - case DIYA_CAIRO_WIDGET_FILL_NONE: - occupied_space += default_extent->height; - break; - default: - break; - } - } - } - - gint off_x = padding->left + stroke_size; - gint off_y = padding->top + stroke_size; - - G_LIST_FOREACH(item, children) - { - g_object_get(item, "vspace", &vspace, "hspace", &hspace, "default-extent", &default_extent, NULL); - DIYA_CAIRO_WIDGET_GET_CLASS(item)->content_size(item, &cwidth, &cheight); - - diya_rect_t rect = {0}; - rect.x = off_x; - rect.y = off_y; - if(self->mode == DIYA_CAIRO_BOX_HORIZONTAL) - { - rect.height = space.height - padding->top - padding->bottom - stroke_size*2; - - switch (hspace) - { - case DIYA_CAIRO_WIDGET_FILL_EXTEND: - rect.width = (occupied_space >= space.width)?0:(space.width - occupied_space) / n_extended; - off_x += rect.width; - break; - case DIYA_CAIRO_WIDGET_FILL_CONTENT: - rect.width = cwidth; - if(!DIYA_IS_CAIRO_BOX(item)) - { - rect.height = cheight; - } - off_x += cwidth; - break; - case DIYA_CAIRO_WIDGET_FILL_NONE: - rect.width = default_extent->width; - if(!DIYA_IS_CAIRO_BOX(item)) - { - rect.height = default_extent->height; - } - off_x += default_extent->width; - break; - default: - break; - } - } - else - { - rect.width = space.width - padding->left - padding->right - stroke_size*2; - switch (vspace) - { - case DIYA_CAIRO_WIDGET_FILL_EXTEND: - rect.height = (occupied_space >= space.height)?0:(space.height - occupied_space) / n_extended; - off_y += rect.height; - break; - case DIYA_CAIRO_WIDGET_FILL_CONTENT: - rect.height = cheight; - if(!DIYA_IS_CAIRO_BOX(item)) - { - rect.width = cwidth; - } - off_y += cheight; - break; - case DIYA_CAIRO_WIDGET_FILL_NONE: - rect.height = default_extent->height; - if(!DIYA_IS_CAIRO_BOX(item)) - { - rect.width = default_extent->width; - } - off_y += default_extent->height; - break; - default: - break; - } - } - diya_rect_t * item_extent = DIYA_CAIRO_WIDGET_GET_CLASS(item)->extent(item); - memcpy(item_extent, &rect, sizeof(rect)); - } - - G_LIST_FOREACH(item, children) - { - // back up vspace hspace - g_object_get(item, "vspace", &vspace, "hspace", &hspace, NULL); - g_object_set(item, - "vspace", DIYA_CAIRO_WIDGET_FILL_EXTEND, - "hspace", DIYA_CAIRO_WIDGET_FILL_EXTEND, - NULL); - DIYA_CAIRO_WIDGET_GET_CLASS(DIYA_CAIRO_WIDGET(item))->update(item); - g_object_set(item, - "vspace", vspace, - "hspace", hspace, - NULL); - } -} - -static diya_rect_t cairo_box_allocate_space(gpointer object, gpointer child) -{ - (void) object; - return diya_cairo_widget_get_extent(child); -} - -static void cairo_box_content_size(gpointer object, gint* width, gint * height) -{ - DiyaCairoBox * self = DIYA_CAIRO_BOX(object); - *width = 0; - *height = 0; - gpointer item; - GList * children = DIYA_CAIRO_CONTAINER_GET_CLASS(object)->children(object); - diya_stroke_t * stroke; - diya_offset_t * padding; - g_object_get(object, "stroke", &stroke,"padding", &padding, NULL); - gint stroke_size = ceil(stroke->size) * 2; - G_LIST_FOREACH(item, children) - { - gint cw,ch; - DIYA_CAIRO_WIDGET_GET_CLASS(item)->content_size(item,&cw,&ch); - if(self->mode == DIYA_CAIRO_BOX_HORIZONTAL) - { - *width += cw; - *height = MAX(*height,ch); - } - else - { - *height += ch; - *width = MAX(*width,cw); - } - } - *height += stroke_size + padding->bottom + padding->top; - *width += stroke_size + padding->left + padding->right; -} - -static void diya_cairo_box_class_init(DiyaCairoBoxClass * class) -{ - GObjectClass *gobject_class = G_OBJECT_CLASS(class); - DIYA_CAIRO_WIDGET_SET_NAME(class, "DiyaCairoBox"); - - DiyaCairoWidgetClass *wclass = DIYA_CAIRO_WIDGET_CLASS(class); - - wclass->draw = cairo_box_draw; - wclass->update = cairo_box_update; - wclass->alloc_space = cairo_box_allocate_space; - wclass->content_size = cairo_box_content_size; - - gobject_class->dispose = diya_cairo_box_dispose; - gobject_class->set_property = diya_cairo_box_set_property; - gobject_class->get_property = diya_cairo_box_get_property; - g_prop[BOX_MODE] = g_param_spec_uint( - "mode", NULL, - "Box mode", DIYA_CAIRO_BOX_HORIZONTAL, - DIYA_CAIRO_BOX_VERTICAL, DIYA_CAIRO_BOX_HORIZONTAL, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY); - g_object_class_install_properties (gobject_class, N_PROPERTIES, g_prop); -} \ No newline at end of file diff --git a/src/widgets/cairo-box.h b/src/widgets/cairo-box.h deleted file mode 100644 index a59ad76..0000000 --- a/src/widgets/cairo-box.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef CAIRO_BOX_H -#define CAIRO_BOX_H - -#include "cairo-widget.h" - -enum { - DIYA_CAIRO_BOX_HORIZONTAL, - DIYA_CAIRO_BOX_VERTICAL -}; - -#define DIYA_TYPE_CAIRO_BOX (diya_cairo_box_get_type ()) -G_DECLARE_FINAL_TYPE (DiyaCairoBox, diya_cairo_box, DIYA, CAIRO_BOX, DiyaCairoContainer) - -#endif \ No newline at end of file diff --git a/src/widgets/cairo-image.c b/src/widgets/cairo-image.c deleted file mode 100644 index 0acb363..0000000 --- a/src/widgets/cairo-image.c +++ /dev/null @@ -1,263 +0,0 @@ -#include -#include -#include "cairo-image.h" - -enum -{ - NO_PROP, - IMG_FILE, - IMG_ALPHA, - IMG_PIXBUF, - IMG_FIT, - N_PROPERTIES -}; -static GParamSpec *g_prop[N_PROPERTIES] = {0}; - -struct _DiyaCairoImage -{ - DiyaCairoWidget parent_object; - gchar * file; - GdkPixbuf * buffer; - gdouble alpha; - - gboolean fit; -}; - -G_DEFINE_FINAL_TYPE(DiyaCairoImage, diya_cairo_image, DIYA_TYPE_CAIRO_WIDGET) - -static void diya_cairo_image_dispose(GObject * object) -{ - g_debug("diya_cairo_image_dispose: %s", diya_object_to_string(object)); - DiyaCairoImage * self = DIYA_CAIRO_IMAGE(object); - if(self->file) - { - g_free(self->file); - } - if(self->buffer) - { - g_debug("diya_cairo_image_dispose: release image buffer"); - g_object_unref(self->buffer); - } - G_OBJECT_CLASS(diya_cairo_image_parent_class)->dispose(object); -} - -static void diya_cairo_set_pixbuf(DiyaCairoImage* self, GdkPixbuf * buf) -{ - if(self->buffer) - { - g_object_unref(self->buffer); - self->buffer = NULL; - } - self->buffer = buf; - diya_cairo_widget_set_size(self, - gdk_pixbuf_get_width(self->buffer), - gdk_pixbuf_get_height(self->buffer) - ); - diya_cairo_widget_damage(self); -} -static void diya_cairo_load_image_from_file(DiyaCairoImage* self, const gchar* path) -{ - if(self->file) - { - g_free(self->file); - } - self->file = g_strdup(path); - GError *error = NULL; - GdkPixbuf * buf = gdk_pixbuf_new_from_file(self->file,&error); - if(!buf) - { - g_error("diya_cairo_load_image_from_file: [%s] %s", self->file, error->message); - return; - } - diya_cairo_set_pixbuf(self,buf); -} - -static void diya_cairo_image_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) -{ - DiyaCairoImage * self = DIYA_CAIRO_IMAGE(object); - switch (property_id) - { - case IMG_FILE: - diya_cairo_load_image_from_file(self, g_value_get_pointer(value)); - break; - case IMG_ALPHA: - self->alpha = g_value_get_double(value); - break; - case IMG_FIT: - self->fit = g_value_get_boolean(value); - break; - case IMG_PIXBUF: - if(self->file) - { - g_free(self->file); - self->file = NULL; - } - diya_cairo_set_pixbuf(self,g_value_get_pointer(value)); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); - break; - } -} - -static void diya_cairo_image_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec) -{ - DiyaCairoImage * self = DIYA_CAIRO_IMAGE(object); - switch (property_id) - { - case IMG_FILE: - g_value_set_pointer(value, self->file); - break; - case IMG_ALPHA: - g_value_set_double(value, self->alpha); - break; - case IMG_FIT: - g_value_set_boolean(value, self->fit); - break; - case IMG_PIXBUF: - g_value_set_pointer(value, self->buffer); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); - break; - } -} - -static void diya_cairo_image_init(DiyaCairoImage * self) -{ - self->file = NULL; - self->buffer = NULL; - self->alpha = 1.0; - - self->fit = FALSE; -} - -static gboolean diya_cairo_image_draw(gpointer object, cairo_t * context) -{ - DiyaCairoImage * self = DIYA_CAIRO_IMAGE(object); - if(!self->buffer || !diya_cairo_widget_is_damaged(self) || !diya_cairo_widget_is_visible(self)) - { - return FALSE; - } - diya_rect_t view_port = diya_cairo_widget_get_view_port(object); - diya_rect_dump("view port: ", &view_port); - - if(diya_rect_is_empty(&view_port)) - { - return FALSE; - } - cairo_save(context); - cairo_rectangle(context, view_port.x, view_port.y, view_port.width, view_port.height); - cairo_clip(context); - - diya_color_t * color; - diya_stroke_t * stroke; - diya_point_t gpos = diya_cairo_widget_get_global_position(object); - diya_rect_t * default_extent; - guint halign, valign; - diya_offset_t * margin; - diya_rect_t extent = diya_cairo_widget_get_extent(object); - diya_rect_dump("extent: ", &extent); - g_object_get(object, - "fill", &color, - "stroke", &stroke, - "halign", &halign, - "valign", &valign, - "margin", &margin, - "default-extent", &default_extent, - NULL); - - gint img_width = default_extent->width; - gint img_height = default_extent->height; - gint stroke_size = ceil(stroke->size); - GdkPixbuf * buf = NULL; - if(self->fit) - { - img_width = extent.width; - img_height = extent.height; - buf = gdk_pixbuf_scale_simple(self->buffer,img_width, img_height, GDK_INTERP_BILINEAR); - } - else - { - buf = g_object_ref(self->buffer); - } - gint off_x = margin->left + stroke->size / 2.0; - gint off_y = margin->top + stroke->size / 2.0; - - switch (halign) - { - case DIYA_CAIRO_WIDGET_ALIGN_MIDDLE: - off_x += (extent.width - img_width) / 2; - break; - case DIYA_CAIRO_WIDGET_ALIGN_END: - off_x += extent.width - img_width; - break; - default: - break; - } - - switch (valign) - { - case DIYA_CAIRO_WIDGET_ALIGN_MIDDLE: - off_y += (extent.height - img_height) / 2; - break; - case DIYA_CAIRO_WIDGET_ALIGN_END: - off_y += extent.height - img_height; - break; - default: - break; - } - - //g_warning("Global position %d %d offset %d %d", gpos.x, gpos.y, off_x, off_y); - - if(color->a > 0) - { - //cairo_move_to(context, (double)gpos.x, (double)gpos.y); - cairo_rectangle(context, - gpos.x + margin->left + stroke_size, - gpos.y + margin->top + stroke_size, - extent.width - margin->left - margin->right - 2*stroke_size, - extent.height - margin->bottom - margin->top - 2*stroke_size); - cairo_set_source_rgba(context, color->r, color->g, color->b, color->a); - cairo_fill(context); - } - // draw image - gdk_cairo_set_source_pixbuf(context, buf, (double)(gpos.x + off_x), (double)(gpos.y + off_y)); - cairo_paint_with_alpha(context, self->alpha); - - if(stroke->size > 0 && stroke->color.a != 0) - { - //cairo_move_to(context, (double)gpos.x, (double)gpos.y); - cairo_rectangle(context, - gpos.x + margin->left + stroke_size, - gpos.y + margin->top + stroke_size, - extent.width - margin->left - margin->right - 2*stroke_size, - extent.height - margin->bottom - margin->top - 2*stroke_size); - cairo_set_source_rgba(context, stroke->color.r, stroke->color.g, stroke->color.b, stroke->color.a); - cairo_set_line_width(context,stroke->size); - cairo_stroke(context); - } - - g_object_unref(buf); - cairo_restore(context); - return TRUE; -} - -static void diya_cairo_image_class_init(DiyaCairoImageClass* class) -{ - GObjectClass *gobject_class = G_OBJECT_CLASS(class); - DiyaCairoWidgetClass *wclass = DIYA_CAIRO_WIDGET_CLASS(class); - - wclass->draw = diya_cairo_image_draw; - - DIYA_CAIRO_WIDGET_SET_NAME(class, "DiyaCairoImage"); - gobject_class->dispose = diya_cairo_image_dispose; - - gobject_class->set_property = diya_cairo_image_set_property; - gobject_class->get_property = diya_cairo_image_get_property; - g_prop[IMG_FILE] = g_param_spec_pointer("file", NULL, "Image file", G_PARAM_READWRITE ); - g_prop[IMG_ALPHA] = g_param_spec_pointer("alpha", NULL, "Image alpha", G_PARAM_READWRITE ); - g_prop[IMG_PIXBUF] = g_param_spec_pointer("pixbuf", NULL, "Image data from gdk_pixbuf", G_PARAM_READWRITE ); - g_prop[IMG_FIT] = g_param_spec_boolean("scale-to-fit", NULL, "Scale image to fit space", FALSE, G_PARAM_READWRITE ); - g_object_class_install_properties (gobject_class, N_PROPERTIES, g_prop); -} \ No newline at end of file diff --git a/src/widgets/cairo-image.h b/src/widgets/cairo-image.h deleted file mode 100644 index 5196505..0000000 --- a/src/widgets/cairo-image.h +++ /dev/null @@ -1,9 +0,0 @@ -#ifndef CAIRO_IMAGE_H -#define CAIRO_IMAGE_H - -#include "cairo-widget.h" - -#define DIYA_TYPE_CAIRO_IMAGE (diya_cairo_image_get_type ()) -G_DECLARE_FINAL_TYPE (DiyaCairoImage, diya_cairo_image, DIYA, CAIRO_IMAGE, DiyaCairoWidget) - -#endif \ No newline at end of file diff --git a/src/widgets/cairo-text.c b/src/widgets/cairo-text.c deleted file mode 100644 index 14345ef..0000000 --- a/src/widgets/cairo-text.c +++ /dev/null @@ -1,367 +0,0 @@ -#include -#include -#include -#include "cairo-text.h" - -#define FONT "Sans Bold 10" - -enum -{ - NO_PROP, - C_TEXT, - C_FONT_FAMILY, - C_FONT_SIZE, - C_FONT_STYLE, - C_FONT_WEIGHT, - C_COLOR, - C_WRAP, - N_PROPERTIES -}; -static GParamSpec *g_prop[N_PROPERTIES] = {0}; - -typedef struct _DiyaCairoTextPrivate -{ - DiyaCairoWidget parent_object; - - gchar *text; - gchar *family; - int size; - guint style; - guint wrap; - guint weight; - diya_color_t color; -} DiyaCairoTextPrivate; - -G_DEFINE_TYPE_WITH_PRIVATE(DiyaCairoText, diya_cairo_text, DIYA_TYPE_CAIRO_WIDGET) - -static void diya_cairo_text_dispose(GObject *object) -{ - DiyaCairoText *self = DIYA_CAIRO_TEXT(object); - DiyaCairoTextPrivate *priv = diya_cairo_text_get_instance_private(self); - g_debug("diya_cairo_text_dispose: %s", diya_object_to_string(object)); - if (priv->text) - { - g_free(priv->text); - } - if (priv->family) - { - g_free(priv->family); - } - G_OBJECT_CLASS(diya_cairo_text_parent_class)->dispose(object); -} - -static void diya_cairo_text_init(DiyaCairoText *self) -{ - DiyaCairoTextPrivate *priv = diya_cairo_text_get_instance_private(self); - priv->text = NULL; - priv->family = NULL; - priv->size = 10; - priv->style = DIYA_CAIRO_FONT_STYLE_NORMAL; - priv->weight = DIYA_CAIRO_FONT_WEIGHT_NORMAL; - priv->wrap = DIYA_CAIRO_TEXT_WRAP_WORD; -} - -static void diya_cairo_text_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) -{ - DiyaCairoText *self = DIYA_CAIRO_TEXT(object); - DiyaCairoTextPrivate *priv = diya_cairo_text_get_instance_private(self); - switch (property_id) - { - case C_TEXT: - if (priv->text) - { - g_free(priv->text); - } - priv->text = g_strdup(g_value_get_pointer(value)); - break; - case C_FONT_FAMILY: - if (priv->family) - { - g_free(priv->family); - } - priv->family = g_strdup(g_value_get_pointer(value)); - break; - case C_FONT_SIZE: - priv->size = g_value_get_int(value); - break; - case C_FONT_STYLE: - priv->style = g_value_get_uint(value); - break; - case C_WRAP: - priv->wrap = g_value_get_uint(value); - break; - case C_FONT_WEIGHT: - priv->weight = g_value_get_uint(value); - break; - case C_COLOR: - memcpy(&priv->color,g_value_get_pointer(value), sizeof(priv->color)); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); - break; - } -} - -static void diya_cairo_text_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec) -{ - DiyaCairoText *self = DIYA_CAIRO_TEXT(object); - DiyaCairoTextPrivate *priv = diya_cairo_text_get_instance_private(self); - switch (property_id) - { - case C_TEXT: - g_value_set_pointer(value, priv->text); - break; - case C_FONT_FAMILY: - g_value_set_pointer(value, priv->family); - break; - case C_FONT_SIZE: - g_value_set_int(value, priv->size); - break; - case C_FONT_STYLE: - g_value_set_uint(value, priv->style); - break; - case C_WRAP: - g_value_set_uint(value, priv->wrap); - break; - case C_FONT_WEIGHT: - g_value_set_uint(value, priv->weight); - break; - case C_COLOR: - g_value_set_pointer(value, &priv->color); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); - break; - } -} - -static PangoFontDescription *diya_cairo_text_get_pango_font_desc(DiyaCairoText *self) -{ - PangoFontDescription *desc = pango_font_description_new(); - DiyaCairoTextPrivate *priv = diya_cairo_text_get_instance_private(self); - if (priv->family) - { - pango_font_description_set_family(desc, priv->family); - } - pango_font_description_set_size(desc, priv->size * PANGO_SCALE); - pango_font_description_set_style(desc, priv->style); - pango_font_description_set_weight(desc, priv->weight); - return desc; -} - -static gboolean diya_cairo_text_draw(gpointer object, cairo_t *context) -{ - DiyaCairoText *self = DIYA_CAIRO_TEXT(object); - DiyaCairoTextPrivate *priv = diya_cairo_text_get_instance_private(self); - if(!diya_cairo_widget_is_damaged(object) || !diya_cairo_widget_is_visible(object)) - { - return FALSE; - } - DIYA_CAIRO_WIDGET_CLASS(diya_cairo_text_parent_class)->draw(object, context); - diya_rect_t view_port = diya_cairo_widget_get_view_port(object); - diya_rect_dump("diya_cairo_text_draw: ", &view_port); - - if(diya_rect_is_empty(&view_port)) - { - return FALSE; - } - cairo_save(context); - cairo_rectangle(context, view_port.x, view_port.y, view_port.width, view_port.height); - cairo_clip(context); - - diya_rect_t extent = diya_cairo_widget_get_extent(object); - g_warning("diya_cairo_widget_get_extent: width %d, %d", extent.width, extent.height); - diya_offset_t * padding, *margin; - diya_stroke_t *stroke; - diya_color_t *color; - guint halign, valign; - g_object_get(object, - "stroke", &stroke, - "halign", &halign, - "valign", &valign, - "margin", &margin, - "padding", &padding, - "color", &color, - NULL); - gint stroke_size = ceil(stroke->size); - diya_point_t gpos = diya_cairo_widget_get_global_position(object); - - PangoFontDescription *desc = diya_cairo_text_get_pango_font_desc(object); - cairo_set_source_rgba(context, color->r, color->g, color->b, color->a); - int display_w = extent.width - padding->left - padding->right - margin->left - margin->right - 2*stroke_size; - int display_h = extent.height - padding->top - padding->bottom - margin->top - margin->bottom - 2*stroke_size; - int off_x = padding->left + margin->left + stroke_size; - int off_y = padding->top + margin->top + stroke_size; - - PangoLayout *layout = pango_cairo_create_layout(context); - // take into account my padding setting - pango_layout_set_text(layout, priv->text, -1); - pango_layout_set_font_description(layout, desc); - pango_layout_set_width(layout,display_w*PANGO_SCALE); - pango_layout_set_height(layout, display_h*PANGO_SCALE); - pango_layout_set_ellipsize(layout, PANGO_ELLIPSIZE_END); - pango_layout_set_wrap(layout, priv->wrap); - switch(halign) - { - case DIYA_CAIRO_WIDGET_ALIGN_START: - pango_layout_set_alignment(layout, PANGO_ALIGN_LEFT); - break; - case DIYA_CAIRO_WIDGET_ALIGN_MIDDLE: - pango_layout_set_alignment(layout, PANGO_ALIGN_CENTER); - break; - case DIYA_CAIRO_WIDGET_ALIGN_END: - pango_layout_set_alignment(layout, PANGO_ALIGN_RIGHT); - break; - } - PangoRectangle text_rect = {0}; - pango_layout_get_extents(layout, NULL, &text_rect); - pango_extents_to_pixels(&text_rect, NULL); - // draw text - switch (valign) - { - case DIYA_CAIRO_WIDGET_ALIGN_MIDDLE: - off_y += (display_h - text_rect.height)/ 2; - break; - case DIYA_CAIRO_WIDGET_ALIGN_END: - off_y += display_h - text_rect.height; - break; - default: - break; - } - cairo_move_to(context, gpos.x + off_x, gpos.y + off_y); - pango_cairo_update_layout(context, layout); - pango_cairo_show_layout(context, layout); - - cairo_restore(context); - pango_font_description_free(desc); - g_object_unref(layout); - - return TRUE; -} - -static void diya_cairo_text_content_size(gpointer object, int *width, int *height) -{ - diya_offset_t* padding, *margin; - diya_stroke_t * stroke; - diya_rect_t * def_xtent; - guint hspace,vspace; - g_object_get(object, - "padding", &padding, - "margin", &margin, - "stroke", &stroke, - "hspace", &hspace, - "vspace", &vspace, - "default-extent", &def_xtent, - NULL); - gint stroke_size = ceil(stroke->size) * 2; - *width = padding->left + padding->right + margin->left + margin->right + stroke_size; - *height = padding->top + padding->bottom + margin->top + margin->bottom + stroke_size; - DiyaCairoText *self = DIYA_CAIRO_TEXT(object); - DiyaCairoTextPrivate *priv = diya_cairo_text_get_instance_private(self); - // diya_rect_t default_extent = DIYA_CAIRO_WIDGET_GET_CLASS(object)->default_extent(object); - int text_width = 0; - int text_height = 0; - if (priv->text) - { - cairo_surface_t *surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, 1, 1); - cairo_t *context = cairo_create(surface); - PangoLayout *layout = pango_cairo_create_layout(context); - PangoFontDescription *desc = diya_cairo_text_get_pango_font_desc(object); - pango_layout_set_font_description(layout, desc); - pango_layout_set_text(layout, priv->text, -1); - pango_layout_set_width(layout, -1); - pango_layout_set_height(layout, -1); - pango_layout_set_single_paragraph_mode(layout, FALSE); - //pango_layout_set_ellipsize(layout, PANGO_ELLIPSIZE_MIDDLE); - PangoRectangle rect = {0}; - pango_layout_get_extents(layout, NULL, &rect); - pango_extents_to_pixels(&rect, NULL); - //rect.width += 4; - text_width = rect.width; - text_height = rect.height; - cairo_destroy(context); - cairo_surface_destroy(surface); - pango_font_description_free(desc); - g_object_unref(layout); - } - - switch (hspace) - { - case DIYA_CAIRO_WIDGET_FILL_NONE: - *width = def_xtent->width; - break; - default: - *width += text_width; - break; - } - switch (vspace) - { - case DIYA_CAIRO_WIDGET_FILL_NONE: - *height = def_xtent->height; - break; - default: - *height += text_height; - break; - } -} - -static void diya_cairo_text_class_init(DiyaCairoTextClass *class) -{ - GObjectClass *gobject_class = G_OBJECT_CLASS(class); - DiyaCairoWidgetClass *wclass = DIYA_CAIRO_WIDGET_CLASS(class); - - class->set_text = diya_cairo_text_set_text; - class->get_text = diya_cairo_text_get_text; - - wclass->draw = diya_cairo_text_draw; - wclass->content_size = diya_cairo_text_content_size; - - DIYA_CAIRO_WIDGET_SET_NAME(class, "DiyaCairoText"); - gobject_class->dispose = diya_cairo_text_dispose; - gobject_class->set_property = diya_cairo_text_set_property; - gobject_class->get_property = diya_cairo_text_get_property; - - g_prop[C_TEXT] = g_param_spec_pointer("text", NULL, "text content", G_PARAM_READWRITE); - g_prop[C_FONT_FAMILY] = g_param_spec_pointer("font-family", NULL, "text font face", G_PARAM_READWRITE); - g_prop[C_COLOR] = g_param_spec_pointer("color", NULL, "text color", G_PARAM_READWRITE); - - g_prop[C_FONT_STYLE] = g_param_spec_uint( - "font-style", NULL, "text font style", - DIYA_CAIRO_FONT_STYLE_NORMAL, - DIYA_CAIRO_FONT_STYLE_ITALIC, - DIYA_CAIRO_FONT_STYLE_NORMAL, - G_PARAM_READWRITE); - g_prop[C_FONT_WEIGHT] = g_param_spec_uint( - "font-weight", NULL, "text font weight", - PANGO_WEIGHT_THIN, - PANGO_WEIGHT_ULTRAHEAVY, - DIYA_CAIRO_FONT_WEIGHT_NORMAL, - G_PARAM_READWRITE); - g_prop[C_FONT_SIZE] = g_param_spec_int( - "font-size", NULL, "text font size", - 0, - G_MAXINT, - 10, - G_PARAM_READWRITE); - g_prop[C_WRAP] = g_param_spec_uint( - "wrap", NULL, "text wrap mode", - DIYA_CAIRO_TEXT_WRAP_WORD, - DIYA_CAIRO_TEXT_WRAP_WORD_CHAR, - DIYA_CAIRO_TEXT_WRAP_WORD, - G_PARAM_READWRITE); - - g_object_class_install_properties(gobject_class, N_PROPERTIES, g_prop); -} - -void diya_cairo_text_set_text(gpointer object, const gchar *text) -{ - assert(DIYA_IS_CAIRO_TEXT(object)); - g_object_set(object, "text", text, NULL); -} -const gchar *diya_cairo_text_get_text(gpointer object) -{ - assert(DIYA_IS_CAIRO_TEXT(object)); - DiyaCairoText *self = DIYA_CAIRO_TEXT(object); - DiyaCairoTextPrivate *priv = diya_cairo_text_get_instance_private(self); - return priv->text; -} diff --git a/src/widgets/cairo-text.h b/src/widgets/cairo-text.h deleted file mode 100644 index 974fa7b..0000000 --- a/src/widgets/cairo-text.h +++ /dev/null @@ -1,31 +0,0 @@ -#ifndef CAIRO_TEXT_H -#define CAIRO_TEXT_H -#include -#include "cairo-widget.h" - - -#define DIYA_CAIRO_FONT_STYLE_NORMAL PANGO_STYLE_NORMAL -#define DIYA_CAIRO_FONT_STYLE_ITALIC PANGO_STYLE_ITALIC -#define DIYA_CAIRO_FONT_STYLE_OBLIQUE PANGO_STYLE_OBLIQUE - -#define DIYA_CAIRO_FONT_WEIGHT_NORMAL PANGO_WEIGHT_NORMAL -#define DIYA_CAIRO_FONT_WEIGHT_BOLD PANGO_WEIGHT_BOLD - -#define DIYA_CAIRO_TEXT_WRAP_WORD PANGO_WRAP_WORD -#define DIYA_CAIRO_TEXT_WRAP_CHAR PANGO_WRAP_CHAR -#define DIYA_CAIRO_TEXT_WRAP_WORD_CHAR PANGO_WRAP_WORD_CHAR - -#define DIYA_TYPE_CAIRO_TEXT (diya_cairo_text_get_type ()) -G_DECLARE_DERIVABLE_TYPE (DiyaCairoText, diya_cairo_text, DIYA, CAIRO_TEXT, DiyaCairoWidget) - - -struct _DiyaCairoTextClass -{ - DiyaCairoWidgetClass parent_class; - void (*set_text)(gpointer object, const gchar* text); - const gchar* (*get_text)(gpointer object); -}; - -void diya_cairo_text_set_text(gpointer object, const gchar* text); -const gchar* diya_cairo_text_get_text(gpointer object); -#endif \ No newline at end of file diff --git a/src/widgets/cairo-widget.c b/src/widgets/cairo-widget.c deleted file mode 100644 index 319e3d0..0000000 --- a/src/widgets/cairo-widget.c +++ /dev/null @@ -1,804 +0,0 @@ -#include -#include -#include -#include -#include -#include "cairo-widget.h" -/* -#include - -int main() -{ - cairo_surface_t *s = cairo_image_surface_create(CAIRO_FORMAT_RGB24, 150, 50); - cairo_t *cr = cairo_create(s); - - cairo_set_source_rgb(cr, 1, 0, 0); - cairo_paint(cr); - - cairo_rectangle(cr, 0, 0, 100, 100); - cairo_clip(cr); - cairo_move_to(cr, 50, 25); - cairo_set_source_rgb(cr, 0, 0, 0); - cairo_show_text(cr, "pretend that this string is > 100px wide"); - - cairo_destroy(cr); - cairo_surface_write_to_png(s, "out.png"); - cairo_surface_destroy(s); - - return 0; -} -*/ -enum -{ - CW_NO_PROP, - CW_EXTENT_DEF, - CW_EXTENT, - CW_PARENT, - CW_VISIBILITY, - CW_HALIGN, - CW_VALIGN, - CW_HSPACE, - CW_VSPACE, - CW_PADDING, - CW_PADDING_LEFT, - CW_PADDING_TOP, - CW_PADDING_BOTTOM, - CW_PADDING_RIGHT, - CW_MARGIN_LEFT, - CW_MARGIN_RIGHT, - CW_MARGIN_TOP, - CW_MARGIN_BOTTOM, - CW_MARGIN, - CW_FILL, - CW_STROKE, - CW_CORNER_RADIUS, - CW_N_PROPERTIES -}; -static GParamSpec *g_cw_prop[CW_N_PROPERTIES] = {0}; - -typedef struct _DiyaCairoWidgetPrivate -{ - DiyaObject parent_object; - diya_rect_t extent; - diya_rect_t default_extent; - DiyaCairoWidget * parent_widget; - - gchar string[64]; - - guint16 visibility; - guint16 halign; - guint16 valign; - guint16 hspace; - guint16 vspace; - - gdouble corner_radius; - - diya_offset_t margin; - diya_offset_t padding; - - diya_color_t fill; - - diya_stroke_t stroke; - - gboolean damaged; -} DiyaCairoWidgetPrivate; - -G_DEFINE_TYPE_WITH_PRIVATE(DiyaCairoWidget, diya_cairo_widget, DIYA_TYPE_OBJECT); - - -static void diya_cairo_widget_dispose(GObject* object) -{ - g_debug("diya_cairo_widget_dispose: %s", diya_object_to_string(object)); - G_OBJECT_CLASS(diya_cairo_widget_parent_class)->dispose(object); -} - -static void diya_cairo_widget_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) -{ - DiyaCairoWidget * self = DIYA_CAIRO_WIDGET(object); - DiyaCairoWidgetPrivate* priv = diya_cairo_widget_get_instance_private(self); - gpointer ptr; - switch (property_id) - { - case CW_PARENT: - priv->parent_widget = g_value_get_pointer(value); - assert(DIYA_IS_CAIRO_WIDGET(priv->parent_widget)); - break; - case CW_EXTENT_DEF: - ptr = g_value_get_pointer(value); - assert(ptr); - priv->default_extent = *(diya_rect_t*)ptr; - break; - case CW_EXTENT: - break; - case CW_VISIBILITY: - priv->visibility = (guint16) g_value_get_uint(value); - break; - case CW_HALIGN: - priv->halign = (guint16)g_value_get_uint(value); - break; - case CW_VALIGN: - priv->valign = (guint16)g_value_get_uint(value); - break; - case CW_HSPACE: - priv->hspace = (guint16)g_value_get_uint(value); - break; - case CW_VSPACE: - priv->vspace = (guint16)g_value_get_uint(value); - break; - case CW_PADDING: - ptr = g_value_get_pointer(value); - assert(ptr); - priv->padding = *(diya_offset_t*)ptr; - break; - case CW_PADDING_LEFT: - priv->padding.left = g_value_get_int(value); - break; - case CW_PADDING_RIGHT: - priv->padding.right = g_value_get_int(value); - break; - case CW_PADDING_BOTTOM: - priv->padding.bottom = g_value_get_int(value); - break; - case CW_PADDING_TOP: - priv->padding.top = g_value_get_int(value); - break; - case CW_MARGIN: - ptr = g_value_get_pointer(value); - assert(ptr); - priv->margin = *(diya_offset_t*)ptr; - break; - case CW_MARGIN_LEFT: - priv->margin.left = g_value_get_int(value); - break; - case CW_MARGIN_RIGHT: - priv->margin.right = g_value_get_int(value); - break; - case CW_MARGIN_BOTTOM: - priv->margin.bottom = g_value_get_int(value); - break; - case CW_MARGIN_TOP: - priv->margin.top = g_value_get_int(value); - break; - case CW_FILL: - ptr = g_value_get_pointer(value); - assert(ptr); - priv->fill = *(diya_color_t*)ptr; - break; - case CW_STROKE: - ptr = g_value_get_pointer(value); - assert(ptr); - priv->stroke = *(diya_stroke_t*) ptr; - break; - case CW_CORNER_RADIUS: - priv->corner_radius = g_value_get_double(value); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); - break; - } -} - -static void diya_cairo_widget_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec) -{ - DiyaCairoWidget * self = DIYA_CAIRO_WIDGET(object); - DiyaCairoWidgetPrivate* priv = diya_cairo_widget_get_instance_private(self); - switch (property_id) - { - case CW_PARENT: - g_value_set_pointer(value, priv->parent_widget); - break; - case CW_EXTENT_DEF: - g_value_set_pointer(value, &priv->default_extent); - break; - case CW_EXTENT: - g_value_set_pointer(value, &priv->extent); - break; - case CW_VISIBILITY: - g_value_set_uint(value, priv->visibility); - break; - case CW_HALIGN: - g_value_set_uint(value, priv->halign); - break; - case CW_VALIGN: - g_value_set_uint(value, priv->valign); - break; - case CW_HSPACE: - g_value_set_uint(value, priv->hspace); - break; - case CW_VSPACE: - g_value_set_uint(value, priv->vspace); - break; - case CW_PADDING: - g_value_set_pointer(value, &priv->padding); - break; - case CW_MARGIN: - g_value_set_pointer(value, &priv->margin); - break; - case CW_FILL: - g_value_set_pointer(value, &priv->fill); - break; - case CW_STROKE: - g_value_set_pointer(value, &priv->stroke); - break; - case CW_CORNER_RADIUS: - g_value_set_double(value, priv->corner_radius); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); - break; - } -} - -static void diya_cairo_widget_init(DiyaCairoWidget *self) -{ - DiyaCairoWidgetPrivate* priv = diya_cairo_widget_get_instance_private(self); - memset(&priv->extent,0,sizeof(priv->extent)); - memset(&priv->extent,0,sizeof(priv->default_extent)); - priv->parent_widget = NULL; - priv->string[0] = '\0'; - - priv->visibility = DIYA_CAIRO_WIDGET_VISIBLE_ON; - - priv->hspace = DIYA_CAIRO_WIDGET_FILL_EXTEND; - priv->vspace = DIYA_CAIRO_WIDGET_FILL_EXTEND; - - priv->halign = DIYA_CAIRO_WIDGET_ALIGN_MIDDLE; - priv->valign = DIYA_CAIRO_WIDGET_ALIGN_MIDDLE; - - memset(&priv->padding,0,sizeof(priv->padding)); - memset(&priv->margin,0,sizeof(priv->margin)); - memset(&priv->fill, 0, sizeof(priv->fill)); - - priv->damaged = TRUE; - priv->corner_radius = 0; -} - -static const gchar *diya_cairo_widget_to_string(DiyaObject *object) -{ - DiyaCairoWidget * self = DIYA_CAIRO_WIDGET(object); - DiyaCairoWidgetClass *class = DIYA_CAIRO_WIDGET_GET_CLASS(object); - DiyaCairoWidgetPrivate* priv = diya_cairo_widget_get_instance_private(self); - - diya_point_t gpos = diya_cairo_widget_get_global_position(object); - - g_snprintf(priv->string,sizeof(priv->string), - "%s (%dx%d) at %d@%d (local %d@%d)", - class->name, - priv->extent.width, priv->extent.height, - gpos.x, gpos.y, - priv->extent.x, priv->extent.y - ); - return priv->string; -} - -diya_rect_t diya_cairo_widget_get_view_port(gpointer object) -{ - DiyaCairoWidget * self = DIYA_CAIRO_WIDGET(object); - DiyaCairoWidgetPrivate* priv = diya_cairo_widget_get_instance_private(self); - diya_offset_t * margin; - g_object_get(object,"margin", &margin, NULL); - diya_point_t gpos = diya_cairo_widget_get_global_position(object); - diya_rect_t view = { - gpos.x + margin->left, - gpos.y + margin->top, - priv->extent.width - margin->left - margin->right, - priv->extent.height - margin->bottom - margin->top - }; - if(priv->parent_widget) - { - diya_rect_t parent_view = diya_cairo_widget_get_view_port(priv->parent_widget); - diya_offset_t* padding; - g_object_get(priv->parent_widget,"padding", &padding, NULL); - parent_view.x += padding->left; - parent_view.y += padding->top; - parent_view.width -= (padding->left + padding->right); - parent_view.height -= (padding->top + padding->bottom); - if(!diya_rect_overlap(&view, &parent_view)) - { - view.x = view.y = view.width = view.height = 0; - return view; - } - - view.width = MIN(view.x + view.width, parent_view.x + parent_view.width) ; - view.height = MIN(view.y + view.height, parent_view.y + parent_view.height); - - view.x = MAX(view.x, parent_view.x); - view.y = MAX(view.y, parent_view.y); - - view.width -= view.x; - view.height -= view.y; - - } - return view; -} - -static gboolean diya_cairo_widget_draw(gpointer object, cairo_t* context) -{ - DiyaCairoWidget * self = DIYA_CAIRO_WIDGET(object); - DiyaCairoWidgetPrivate* priv = diya_cairo_widget_get_instance_private(self); - if(!priv->damaged) - { - return FALSE; - } - if(priv->visibility != DIYA_CAIRO_WIDGET_VISIBLE_ON) - { - return FALSE; - } - - diya_rect_t view_port = diya_cairo_widget_get_view_port(object); - - if(diya_rect_is_empty(&view_port)) - { - return FALSE; - } - - cairo_save(context); - cairo_rectangle(context, view_port.x, view_port.y, view_port.width, view_port.height); - cairo_clip(context); - diya_point_t gpos = diya_cairo_widget_get_global_position(object); - //cairo_move_to(context, (double)gpos.x +, (double)gpos.y); - guint stroke_size = ceil(priv->stroke.size); - guint half_stroke_size = ceil(priv->stroke.size / 2.0); - - double width = (double)(priv->extent.width - priv->margin.left - priv->margin.right - stroke_size); - int height = (double)(priv->extent.height - priv->margin.bottom - priv->margin.top - stroke_size); - int x = (double)(gpos.x + priv->margin.left + half_stroke_size); - int y = (double)(gpos.y + priv->margin.top + half_stroke_size); - if(priv->corner_radius > 0) - { - double degrees = M_PI / 180.0; - cairo_new_sub_path(context); - cairo_arc (context, x + width - priv->corner_radius, y + priv->corner_radius, priv->corner_radius, -90 * degrees, 0); - cairo_arc (context, x + width - priv->corner_radius, y + height - priv->corner_radius, priv->corner_radius, 0, 90 * degrees); - cairo_arc (context, x + priv->corner_radius, y + height - priv->corner_radius, priv->corner_radius, 90 * degrees, 180 * degrees); - cairo_arc (context, x + priv->corner_radius, y + priv->corner_radius, priv->corner_radius, 180 * degrees, 270 * degrees); - cairo_close_path (context); - } - else - { - cairo_rectangle(context,x,y,width,height); - } - if(priv->fill.a > 0) - { - cairo_set_source_rgba(context, priv->fill.r, priv->fill.g, priv->fill.b, priv->fill.a); - cairo_fill_preserve(context); - } - if(priv->stroke.size > 0 && priv->stroke.color.a != 0) - { - cairo_set_source_rgba(context, priv->stroke.color.r, priv->stroke.color.g, priv->stroke.color.b, priv->stroke.color.a); - cairo_set_line_width(context,priv->stroke.size); - cairo_stroke(context); - } - cairo_restore(context); - priv->damaged = FALSE; - return TRUE; -} - -static void diya_cairo_widget_content_size(gpointer object, gint* width, gint* height) -{ - DiyaCairoWidget * self = DIYA_CAIRO_WIDGET(object); - DiyaCairoWidgetPrivate* priv = diya_cairo_widget_get_instance_private(self); - - gint stroke_size = ceil(priv->stroke.size) *2; - *width = priv->default_extent.width + priv->margin.left + priv->margin.right + stroke_size; - *height = priv->default_extent.height + priv->margin.top + priv->margin.bottom + stroke_size; -} - -static void diya_cairo_widget_update(gpointer object) -{ - assert(DIYA_IS_CAIRO_WIDGET(object)); - DiyaCairoWidget * self = DIYA_CAIRO_WIDGET(object); - DiyaCairoWidgetPrivate* priv = diya_cairo_widget_get_instance_private(self); - gint stroke_size = ceil(priv->stroke.size) *2; - if(priv->visibility == DIYA_CAIRO_WIDGET_VISIBLE_HIDDEN) - { - /** - * Item is hidden, set extent to empty - */ - if(!diya_rect_is_empty(&priv->extent)) - { - priv->damaged = TRUE; - } - priv->extent.width = 0; - priv->extent.height = 0; - priv->extent.x = 0; - priv->extent.y = 0; - return; - } - diya_rect_t space = { - 0, - 0, - priv->default_extent.width, - priv->default_extent.height }; - if(priv->parent_widget) - { - space = DIYA_CAIRO_WIDGET_GET_CLASS(priv->parent_widget)->alloc_space(priv->parent_widget, object); - } - gint width,height,cwidth = 0,cheight = 0; - DIYA_CAIRO_WIDGET_GET_CLASS(self)->content_size(object, &cwidth, &cheight); - switch(priv->hspace) - { - case DIYA_CAIRO_WIDGET_FILL_EXTEND: - width = space.width; - break; - case DIYA_CAIRO_WIDGET_FILL_CONTENT: - width = cwidth; - break; - default: - width = priv->default_extent.width + priv->margin.left + priv->margin.right + stroke_size; - break; - } - - switch(priv->vspace) - { - case DIYA_CAIRO_WIDGET_FILL_EXTEND: - height = space.height; - break; - case DIYA_CAIRO_WIDGET_FILL_CONTENT: - height = cheight; - break; - default: - height = priv->default_extent.height + priv->margin.top + priv->margin.bottom + stroke_size; - break; - } - - if(width != priv->extent.width || height != priv->extent.height) - { - priv->damaged = TRUE; - } - priv->extent.width = width; - priv->extent.height = height; - if(space.x != priv->extent.x || space.y != priv->extent.y) - { - priv->damaged = TRUE; - } - priv->extent.x = space.x; - priv->extent.y = space.y; - -} - -static diya_rect_t diya_cairo_widget_alloc_space(gpointer object, gpointer child) -{ - (void) child; - assert(object); - DiyaCairoWidget * self = DIYA_CAIRO_WIDGET(object); - DiyaCairoWidgetPrivate* priv = diya_cairo_widget_get_instance_private(self); - - diya_rect_t space = {0,0,priv->extent.width, priv->extent.height}; - guint stroke_size = ceil(priv->stroke.size); - space.x += priv->padding.left + priv->margin.left + stroke_size; - space.y += priv->padding.top + priv->margin.top + stroke_size; - space.width -= (priv->padding.right + priv->padding.left + priv->margin.left+ priv->margin.right + stroke_size*2); - space.height -= (priv->padding.bottom + priv->padding.top + priv->margin.top + priv->margin.bottom + stroke_size*2); - - return space; -} - -static diya_rect_t diya_cairo_widget_get_default_extent(gpointer object) -{ - DiyaCairoWidget * self = DIYA_CAIRO_WIDGET(object); - DiyaCairoWidgetPrivate* priv = diya_cairo_widget_get_instance_private(self); - return priv->default_extent; -} - -static diya_rect_t* diya_cairo_widget_get_extent_mut(gpointer object) -{ - assert(DIYA_IS_CAIRO_WIDGET(object)); - DiyaCairoWidget * self = DIYA_CAIRO_WIDGET(object); - DiyaCairoWidgetPrivate* priv = diya_cairo_widget_get_instance_private(self); - - return &priv->extent; -} - -static void diya_cairo_widget_class_init(DiyaCairoWidgetClass *class) -{ - GObjectClass *gobject_class = G_OBJECT_CLASS(class); - DiyaObjectClass *base_class = DIYA_OBJECT_CLASS(class); - DIYA_CAIRO_WIDGET_SET_NAME(class, "DiyaCairoWidget"); - gobject_class->dispose = diya_cairo_widget_dispose; - gobject_class->set_property = diya_cairo_widget_set_property; - gobject_class->get_property = diya_cairo_widget_get_property; - class->draw = diya_cairo_widget_draw; - class->update = diya_cairo_widget_update; - class->alloc_space = diya_cairo_widget_alloc_space; - class->content_size = diya_cairo_widget_content_size; - class->parent = diya_cairo_widget_get_parent; - class->position = diya_cairo_widget_get_position; - class->global_position = diya_cairo_widget_get_global_position; - class->extent = diya_cairo_widget_get_extent_mut; - class->view_port = diya_cairo_widget_get_view_port; - class->damaged = diya_cairo_widget_is_damaged; - class->default_extent = diya_cairo_widget_get_default_extent; - - g_cw_prop[CW_EXTENT_DEF] = g_param_spec_pointer("default-extent", NULL, "Widget actual extent relative to its parent", G_PARAM_READWRITE); // - g_cw_prop[CW_EXTENT] = g_param_spec_pointer("extent", NULL, "Widget default extent", G_PARAM_READABLE); - g_cw_prop[CW_PARENT] = g_param_spec_pointer("parent", NULL, "Parent widget", G_PARAM_READWRITE); // - g_cw_prop[CW_FILL] = g_param_spec_pointer("fill", NULL, "Fill color", G_PARAM_READWRITE); - g_cw_prop[CW_STROKE] = g_param_spec_pointer("stroke", NULL, "Border size and color", G_PARAM_READWRITE); - g_cw_prop[CW_VISIBILITY] = g_param_spec_uint( - "visibility", NULL, "Widget visibility", - DIYA_CAIRO_WIDGET_VISIBLE_ON, - DIYA_CAIRO_WIDGET_VISIBLE_MAX, - DIYA_CAIRO_WIDGET_VISIBLE_ON, - G_PARAM_READWRITE); - - g_cw_prop[CW_HALIGN] = g_param_spec_uint( - "halign", NULL, "Widget halign", - DIYA_CAIRO_WIDGET_ALIGN_START, - DIYA_CAIRO_WIDGET_ALIGN_MAX, - DIYA_CAIRO_WIDGET_ALIGN_MIDDLE, - G_PARAM_READWRITE); - - g_cw_prop[CW_VALIGN] = g_param_spec_uint( - "valign", NULL, "Widget valign", - DIYA_CAIRO_WIDGET_ALIGN_START, - DIYA_CAIRO_WIDGET_ALIGN_MAX, - DIYA_CAIRO_WIDGET_ALIGN_MIDDLE, - G_PARAM_READWRITE); - - g_cw_prop[CW_HSPACE] = g_param_spec_uint( - "hspace", NULL, "Widget hspace", - DIYA_CAIRO_WIDGET_FILL_NONE, - DIYA_CAIRO_WIDGET_FILL_MAX, - DIYA_CAIRO_WIDGET_FILL_EXTEND, - G_PARAM_READWRITE); - - g_cw_prop[CW_VSPACE] = g_param_spec_uint( - "vspace", NULL, "Widget vspace", - DIYA_CAIRO_WIDGET_FILL_NONE, - DIYA_CAIRO_WIDGET_FILL_MAX, - DIYA_CAIRO_WIDGET_FILL_EXTEND, - G_PARAM_READWRITE); - - g_cw_prop[CW_PADDING] = g_param_spec_pointer("padding", NULL, "Widget padding", G_PARAM_READWRITE); - g_cw_prop[CW_MARGIN] = g_param_spec_pointer("margin", NULL, "Widget margin", G_PARAM_READWRITE); - - g_cw_prop[CW_PADDING_LEFT] = g_param_spec_int( - "padding-left", NULL, "Widget padding-left", - G_MININT, - G_MAXINT, - 0, - G_PARAM_WRITABLE); - g_cw_prop[CW_PADDING_RIGHT] = g_param_spec_int( - "padding-right", NULL, "Widget padding-right", - INT_MIN, - INT_MAX, - 0, - G_PARAM_WRITABLE); - g_cw_prop[CW_PADDING_TOP] = g_param_spec_int( - "padding-top", NULL, "Widget padding-top", - INT_MIN, - INT_MAX, - 0, - G_PARAM_WRITABLE); - g_cw_prop[CW_PADDING_BOTTOM] = g_param_spec_int( - "padding-bottom", NULL, "Widget padding-bottom", - INT_MIN, - INT_MAX, - 0, - G_PARAM_WRITABLE); - - g_cw_prop[CW_MARGIN_LEFT] = g_param_spec_int( - "margin-left", NULL, "Widget margin-left", - INT_MIN, - INT_MAX, - 0, - G_PARAM_WRITABLE); - g_cw_prop[CW_MARGIN_RIGHT] = g_param_spec_int( - "margin-right", NULL, "Widget margin-right", - INT_MIN, - INT_MAX, - 0, - G_PARAM_WRITABLE); - g_cw_prop[CW_MARGIN_TOP] = g_param_spec_int( - "margin-top", NULL, "Widget margin-top", - INT_MIN, - INT_MAX, - 0, - G_PARAM_WRITABLE); - g_cw_prop[CW_MARGIN_BOTTOM] = g_param_spec_int( - "margin-bottom", NULL, "Widget margin-bottom", - INT_MIN, - INT_MAX, - 0, - G_PARAM_WRITABLE); - g_cw_prop[CW_CORNER_RADIUS] = g_param_spec_double( - "corner-radius", NULL, "Corner radius", - 0, - DBL_MAX, - 0, - G_PARAM_READWRITE); - - base_class->to_string = diya_cairo_widget_to_string; - - g_object_class_install_properties (gobject_class, CW_N_PROPERTIES, g_cw_prop); -} - -diya_point_t diya_cairo_widget_get_position(gpointer object) -{ - diya_point_t p = {0}; - assert(DIYA_IS_CAIRO_WIDGET(object)); - DiyaCairoWidget * self = DIYA_CAIRO_WIDGET(object); - DiyaCairoWidgetPrivate* priv = diya_cairo_widget_get_instance_private(self); - p.x = priv->extent.x; - p.y = priv->extent.y; - return p; -} -diya_point_t diya_cairo_widget_get_global_position(gpointer object) -{ - assert(DIYA_IS_CAIRO_WIDGET(object)); - DiyaCairoWidget * self = DIYA_CAIRO_WIDGET(object); - DiyaCairoWidgetPrivate* priv = diya_cairo_widget_get_instance_private(self); - diya_point_t p = {priv->extent.x, priv->extent.y}; - if(priv->parent_widget) - { - - diya_point_t parent_pos = diya_cairo_widget_get_global_position(priv->parent_widget); - p.x += parent_pos.x; - p.y += parent_pos.y; - } - return p; -} -DiyaCairoWidget* diya_cairo_widget_get_parent(gpointer object) -{ - assert(DIYA_IS_CAIRO_WIDGET(object)); - DiyaCairoWidget * self = DIYA_CAIRO_WIDGET(object); - DiyaCairoWidgetPrivate* priv = diya_cairo_widget_get_instance_private(self); - return priv->parent_widget; -} -diya_rect_t diya_cairo_widget_get_extent(gpointer object) -{ - assert(DIYA_IS_CAIRO_WIDGET(object)); - DiyaCairoWidget * self = DIYA_CAIRO_WIDGET(object); - DiyaCairoWidgetPrivate* priv = diya_cairo_widget_get_instance_private(self); - - return priv->extent; -} -gboolean diya_cairo_widget_is_visible(gpointer object) -{ - assert(DIYA_IS_CAIRO_WIDGET(object)); - DiyaCairoWidget * self = DIYA_CAIRO_WIDGET(object); - DiyaCairoWidgetPrivate* priv = diya_cairo_widget_get_instance_private(self); - return priv->visibility == DIYA_CAIRO_WIDGET_VISIBLE_ON; -} -gboolean diya_cairo_widget_is_hidden(gpointer object) -{ - assert(DIYA_IS_CAIRO_WIDGET(object)); - DiyaCairoWidget * self = DIYA_CAIRO_WIDGET(object); - DiyaCairoWidgetPrivate* priv = diya_cairo_widget_get_instance_private(self); - return priv->visibility == DIYA_CAIRO_WIDGET_VISIBLE_HIDDEN; -} - -void diya_cairo_widget_set_size(gpointer object, guint width, guint height) -{ - assert(DIYA_IS_CAIRO_WIDGET(object)); - DiyaCairoWidget * self = DIYA_CAIRO_WIDGET(object); - DiyaCairoWidgetPrivate* priv = diya_cairo_widget_get_instance_private(self); - - priv->default_extent.width = width; - priv->default_extent.height = height; - -} -void diya_cairo_widget_set_position(gpointer object, gint x, gint y) -{ - assert(DIYA_IS_CAIRO_WIDGET(object)); - DiyaCairoWidget * self = DIYA_CAIRO_WIDGET(object); - DiyaCairoWidgetPrivate* priv = diya_cairo_widget_get_instance_private(self); - - priv->default_extent.x = x; - priv->default_extent.y = y; - -} - -void diya_cairo_widget_fill(gpointer object, diya_color_t * color) -{ - assert(DIYA_IS_CAIRO_WIDGET(object)); - DiyaCairoWidget * self = DIYA_CAIRO_WIDGET(object); - DiyaCairoWidgetPrivate* priv = diya_cairo_widget_get_instance_private(self); - priv->fill = *color; -} -void diya_cairo_widget_set_stroke_size(gpointer object, gdouble size) -{ - assert(DIYA_IS_CAIRO_WIDGET(object)); - DiyaCairoWidget * self = DIYA_CAIRO_WIDGET(object); - DiyaCairoWidgetPrivate* priv = diya_cairo_widget_get_instance_private(self); - - priv->stroke.size = size; -} -void diya_cairo_widget_set_stroke_color(gpointer object, diya_color_t * color) -{ - assert(DIYA_IS_CAIRO_WIDGET(object)); - DiyaCairoWidget * self = DIYA_CAIRO_WIDGET(object); - DiyaCairoWidgetPrivate* priv = diya_cairo_widget_get_instance_private(self); - - priv->stroke.color = *color; -} - -gboolean diya_cairo_widget_is_damaged(gpointer object) -{ - assert(DIYA_IS_CAIRO_WIDGET(object)); - DiyaCairoWidget * self = DIYA_CAIRO_WIDGET(object); - DiyaCairoWidgetPrivate* priv = diya_cairo_widget_get_instance_private(self); - - return priv->damaged; -} - -void diya_cairo_widget_damage(gpointer object) -{ - assert(DIYA_IS_CAIRO_WIDGET(object)); - DiyaCairoWidget * self = DIYA_CAIRO_WIDGET(object); - DiyaCairoWidgetPrivate* priv = diya_cairo_widget_get_instance_private(self); - - priv->damaged = TRUE; -} - -/*Container API*/ - -typedef struct _DiyaCairoContainerPrivate -{ - DiyaCairoWidget parent_object; - GList* children; - -} DiyaCairoContainerPrivate; - -G_DEFINE_TYPE_WITH_PRIVATE(DiyaCairoContainer, diya_cairo_container, DIYA_TYPE_CAIRO_WIDGET) - -static void diya_cairo_container_dispose(GObject* object) -{ - DiyaCairoContainer * self = DIYA_CAIRO_CONTAINER(object); - DiyaCairoContainerPrivate* priv = diya_cairo_container_get_instance_private(self); - g_debug("diya_cairo_container_dispose: %s", diya_object_to_string(object)); - g_list_free_full(priv->children, g_object_unref); - G_OBJECT_CLASS(diya_cairo_container_parent_class)->dispose(object); -} - -static void diya_cairo_container_init(DiyaCairoContainer *self) -{ - DiyaCairoContainerPrivate* priv = diya_cairo_container_get_instance_private(self); - priv->children = NULL; -} - -static GList * diya_cairo_container_get_children(gpointer object) -{ - DiyaCairoContainerPrivate* priv = diya_cairo_container_get_instance_private(DIYA_CAIRO_CONTAINER(object)); - return priv->children; -} - -static void diya_cairo_container_class_init(DiyaCairoContainerClass *class) -{ - GObjectClass *gobject_class = G_OBJECT_CLASS(class); - //DiyaCairoWidgetClass *wclass = DIYA_CAIRO_WIDGET_CLASS(class); - DIYA_CAIRO_WIDGET_SET_NAME(class, "DiyaCairoContainer"); - gobject_class->dispose = diya_cairo_container_dispose; - class->children = diya_cairo_container_get_children; -} - -void diya_cairo_container_add(gpointer object, gpointer child) -{ - assert(DIYA_IS_CAIRO_WIDGET(child)); - assert(DIYA_IS_CAIRO_CONTAINER(object)); - DiyaCairoContainerPrivate* priv = diya_cairo_container_get_instance_private(DIYA_CAIRO_CONTAINER(object)); - g_object_set(child,"parent", object, NULL); - if(g_list_find (priv->children,child)) - { - return; - } - priv->children = g_list_append(priv->children, child); -} - -void diya_offset_normalize(diya_offset_t * offset) -{ - gint tmp; - if(offset->left > offset->right) - { - tmp = offset->left; - offset->left = offset->right; - offset->right = tmp; - } - if(offset->top > offset->bottom) - { - tmp = offset->top; - offset->top = offset->bottom; - offset->bottom = tmp; - } -} \ No newline at end of file diff --git a/src/widgets/cairo-widget.h b/src/widgets/cairo-widget.h deleted file mode 100644 index 30670a4..0000000 --- a/src/widgets/cairo-widget.h +++ /dev/null @@ -1,138 +0,0 @@ -#ifndef CAIRO_WIDGET_H -#define CAIRO_WIDGET_H - - -#include -#include "../base.h" - -// basic type - -typedef struct -{ - gint x; - gint y; - gint width; - gint height; -} diya_rect_t; - -typedef struct -{ - gint x; - gint y; -} -diya_point_t; - -typedef struct -{ - gint left; - gint top; - gint right; - gint bottom; -} -diya_offset_t; - -typedef struct -{ - gdouble r; - gdouble g; - gdouble b; - gdouble a; -} -diya_color_t; - -typedef struct -{ - gdouble size; - diya_color_t color; -} diya_stroke_t; - -#define BETWEEN(value,min,max) ((value >= min) && (value <= max)) - -#define diya_rect_is_empty(rect) (((rect)->width <= 0) || ((rect)->height <= 0)) -#define diya_rect_to_offset(rect) ({(rect)->x,(rect)->y,(rect)->y+(rect)->height, (rect)->x + (rect)->width}) -#define diya_rect_overlap(a,b) ( \ - (BETWEEN((a)->x, (b)->x, (b)->x + (b)->width) || BETWEEN((b)->x, (a)->x, (a)->x + (a)->width)) && \ - (BETWEEN((a)->y, (b)->y, (b)->y + (b)->height) || BETWEEN((b)->y, (a)->y, (a)->y + (a)->height))) - -#define diya_rect_dump(prefix, rect) (g_warning(prefix ": [%d@%d, %dx%d]", (rect)->x,(rect)->y, (rect)->width, (rect)->height)) - -#define G_LIST_FOREACH(item, list) for(GList *__glist = list; __glist && (item = __glist->data, TRUE); __glist = __glist->next) - - -void diya_offset_normalize(diya_offset_t * offset); - -#define DIYA_CAIRO_WIDGET_SET_NAME(c, n) (DIYA_CAIRO_WIDGET_CLASS(c)->name = n) -#define DIYA_TYPE_CAIRO_WIDGET (diya_cairo_widget_get_type ()) -G_DECLARE_DERIVABLE_TYPE (DiyaCairoWidget, diya_cairo_widget, DIYA, CAIRO_WIDGET, DiyaObject) - -enum -{ - /*Align enum*/ - DIYA_CAIRO_WIDGET_ALIGN_START, - DIYA_CAIRO_WIDGET_ALIGN_MIDDLE, - DIYA_CAIRO_WIDGET_ALIGN_END, - DIYA_CAIRO_WIDGET_ALIGN_DEFAULT, - DIYA_CAIRO_WIDGET_ALIGN_MAX, // not used - /*fill enum*/ - DIYA_CAIRO_WIDGET_FILL_NONE, // using extent size - DIYA_CAIRO_WIDGET_FILL_CONTENT, // extent calculated by its content - DIYA_CAIRO_WIDGET_FILL_EXTEND, // extend to the entire free space of the parent - DIYA_CAIRO_WIDGET_FILL_MAX, //not used - - /* Visibility enum*/ - DIYA_CAIRO_WIDGET_VISIBLE_ON, - DIYA_CAIRO_WIDGET_VISIBLE_OFF, // not show but take space - DIYA_CAIRO_WIDGET_VISIBLE_HIDDEN, // not show and does not take space - DIYA_CAIRO_WIDGET_VISIBLE_MAX, // not used - -}; - -struct _DiyaCairoWidgetClass -{ - DiyaObjectClass parent_class; - gboolean (*draw)(gpointer, cairo_t*); - void (*update)(gpointer); - void (*content_size)(gpointer, gint*, gint*); - diya_rect_t (*alloc_space)(gpointer, gpointer); - - DiyaCairoWidget* (*parent)(gpointer); - diya_point_t (*position)(gpointer); - diya_point_t (*global_position)(gpointer); - diya_rect_t* (*extent)(gpointer); - diya_rect_t (*default_extent)(gpointer); - diya_rect_t (*view_port)(gpointer); - gboolean (*damaged)(gpointer); - const gchar* name; -}; - -diya_point_t diya_cairo_widget_get_position(gpointer object); -diya_point_t diya_cairo_widget_get_global_position(gpointer object); -DiyaCairoWidget* diya_cairo_widget_get_parent(gpointer object); -diya_rect_t diya_cairo_widget_get_extent(gpointer object); -gboolean diya_cairo_widget_is_visible(gpointer object); -gboolean diya_cairo_widget_is_hidden(gpointer object); -gboolean diya_cairo_widget_is_damaged(gpointer object); -diya_rect_t diya_cairo_widget_get_view_port(gpointer object); - -void diya_cairo_widget_damage(gpointer object); - -void diya_cairo_widget_set_size(gpointer object, guint width, guint height); -void diya_cairo_widget_set_position(gpointer object, gint x, gint y); -void diya_cairo_widget_fill(gpointer object, diya_color_t * color); -void diya_cairo_widget_set_stroke_size(gpointer object, gdouble size); -void diya_cairo_widget_set_stroke_color(gpointer object, diya_color_t * color); - - -#define DIYA_TYPE_CAIRO_CONTAINER (diya_cairo_container_get_type ()) -G_DECLARE_DERIVABLE_TYPE (DiyaCairoContainer, diya_cairo_container, DIYA, CAIRO_CONTAINER, DiyaCairoWidget) - - -struct _DiyaCairoContainerClass -{ - DiyaCairoWidgetClass parent_class; - - GList* (*children)(gpointer); -}; - -void diya_cairo_container_add(gpointer object, gpointer child); -#endif \ No newline at end of file diff --git a/src/widgets/cairo-window.c b/src/widgets/cairo-window.c deleted file mode 100644 index cedfb6c..0000000 --- a/src/widgets/cairo-window.c +++ /dev/null @@ -1,139 +0,0 @@ -#include -#include "cairo-window.h" -#include "cairo-image.h" -/* -enum -{ - NO_PROP, - BOX_MODE, - N_PROPERTIES -}; -static GParamSpec *g_prop[N_PROPERTIES] = {0}; -*/ -struct _DiyaCairoWindow -{ - DiyaCairoWidget parent_object; - DiyaCairoWidget * root; - - gpointer background; -}; - -G_DEFINE_FINAL_TYPE(DiyaCairoWindow, diya_cairo_window, DIYA_TYPE_CAIRO_WIDGET) - -static void diya_cairo_window_dispose(GObject * object) -{ - g_debug("diya_cairo_window_dispose: %s", diya_object_to_string(object)); - DiyaCairoWindow * window = DIYA_CAIRO_WINDOW(object); - if(window->root) - { - g_object_unref(window->root); - } - if(window->background) - { - g_object_unref(window->background); - } - G_OBJECT_CLASS(diya_cairo_window_parent_class)->dispose(object); -} - -static void diya_cairo_window_init(DiyaCairoWindow * window) -{ - window->root = NULL; - window->background = NULL; -} - -static gboolean cairo_window_draw(gpointer object, cairo_t * cairo) -{ - DiyaCairoWindow * window = DIYA_CAIRO_WINDOW(object); - DIYA_CAIRO_WIDGET_CLASS(diya_cairo_window_parent_class)->draw(object, cairo); - if(window->background) - { - g_warning("drawing background"); - assert(DIYA_IS_CAIRO_IMAGE(window->background)); - DIYA_CAIRO_WIDGET_GET_CLASS(DIYA_CAIRO_WIDGET(window->background))->draw(window->background, cairo); - } - if(window->root) - { - DIYA_CAIRO_WIDGET_GET_CLASS(DIYA_CAIRO_WIDGET(window->root))->draw(window->root, cairo); - } - return TRUE; -} - -static void cairo_window_update(gpointer object) -{ - g_warning("Updating cairo window"); - DiyaCairoWindow * self = DIYA_CAIRO_WINDOW(object); - DIYA_CAIRO_WIDGET_CLASS(diya_cairo_window_parent_class)->update(object); - if(self->background) - { - g_warning("Updating cairo image"); - assert(DIYA_IS_CAIRO_IMAGE(self->background)); - DIYA_CAIRO_WIDGET_GET_CLASS(DIYA_CAIRO_WIDGET(self->background))->update(self->background); - } - if(self->root) - { - g_warning("Updating root"); - DIYA_CAIRO_WIDGET_GET_CLASS(DIYA_CAIRO_WIDGET(self->root))->update(self->root); - } -} - -static void diya_cairo_window_class_init(DiyaCairoWindowClass* class) -{ - GObjectClass *gobject_class = G_OBJECT_CLASS(class); - DiyaCairoWidgetClass *wclass = DIYA_CAIRO_WIDGET_CLASS(class); - wclass->draw = cairo_window_draw; - wclass->update = cairo_window_update; - // wclass->alloc_space = cairo_window_allocate_space; - DIYA_CAIRO_WIDGET_SET_NAME(class, "DiyaCairoWindow"); - gobject_class->dispose = diya_cairo_window_dispose; -} - -void diya_cairo_window_set_root(gpointer object, gpointer root) -{ - assert(DIYA_IS_CAIRO_WINDOW(object)); - assert(DIYA_IS_CAIRO_WIDGET(root)); - DiyaCairoWindow * window = DIYA_CAIRO_WINDOW(object); - window->root = DIYA_CAIRO_WIDGET(root); - diya_rect_t extent = diya_cairo_widget_get_extent(window); - g_object_set(root, - "parent", window, - "default-extent", &extent, - "vspace", DIYA_CAIRO_WIDGET_FILL_EXTEND, - "hspace", DIYA_CAIRO_WIDGET_FILL_EXTEND, - NULL - ); -} - -void diya_cairo_window_render(gpointer object, cairo_surface_t * surface) -{ - assert(DIYA_IS_CAIRO_WINDOW(object)); - DiyaCairoWidget * widget = DIYA_CAIRO_WIDGET(object); - cairo_t *cr = cairo_create(surface); - DIYA_CAIRO_WIDGET_GET_CLASS(widget)->draw(object,cr); - cairo_destroy(cr); -} - -void diya_cairo_window_update(gpointer object) -{ - assert(DIYA_IS_CAIRO_WINDOW(object)); - g_warning("update and damaged widget"); - DiyaCairoWidget * widget = DIYA_CAIRO_WIDGET(object); - assert(DIYA_IS_CAIRO_WIDGET(widget)); - DIYA_CAIRO_WIDGET_GET_CLASS(widget)->update(object); -} - -void diya_cairo_window_set_background_image(gpointer object, const char* path, gboolean scale_to_fit) -{ - assert(DIYA_IS_CAIRO_WINDOW(object)); - DiyaCairoWindow * self = DIYA_CAIRO_WINDOW(object); - - self->background = g_object_new(DIYA_TYPE_CAIRO_IMAGE, - "file",path, "parent", object, - "scale-to-fit", scale_to_fit, - "hspace", DIYA_CAIRO_WIDGET_FILL_EXTEND, - "vspace", DIYA_CAIRO_WIDGET_FILL_EXTEND, - "halign", DIYA_CAIRO_WIDGET_ALIGN_START, - "valign", DIYA_CAIRO_WIDGET_ALIGN_START, - NULL); - - -} \ No newline at end of file diff --git a/src/widgets/cairo-window.h b/src/widgets/cairo-window.h deleted file mode 100644 index 656067a..0000000 --- a/src/widgets/cairo-window.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef DIYA_CAIRO_WINDOW_H -#define DIYA_CAIRO_WINDOW_H - -#include "cairo-widget.h" - -#define DIYA_TYPE_CAIRO_WINDOW (diya_cairo_window_get_type ()) -G_DECLARE_FINAL_TYPE (DiyaCairoWindow, diya_cairo_window, DIYA, CAIRO_WINDOW, DiyaCairoWidget) - - -void diya_cairo_window_set_root(gpointer object, gpointer root); -void diya_cairo_window_render(gpointer object, cairo_surface_t * surface); -void diya_cairo_window_update(gpointer object); -void diya_cairo_window_set_background_image(gpointer object, const char * file, gboolean scale_to_fit); -#endif \ No newline at end of file