From a28e53019717e4bdceb3ccd29648fc262346da33 Mon Sep 17 00:00:00 2001 From: Eric Wertz Date: Mon, 9 Apr 2018 10:40:39 -0400 Subject: [PATCH] Updates to structure and rendering of icons/pager items --- dock_icon.c | 140 ++++++++++++++++++++++++++++++++++---- dock_icon.h | 19 ++---- dock_objects.h | 35 ++++++++++ main.c | 94 ++++++------------------- pager_item.c | 173 +++++++++++++++++++++++++++++++++++------------ pager_item.h | 18 ++--- tooltip_window.c | 148 ++++++++++++++++------------------------ tooltip_window.h | 6 ++ 8 files changed, 383 insertions(+), 250 deletions(-) create mode 100644 dock_objects.h diff --git a/dock_icon.c b/dock_icon.c index 4e6666e..0af949c 100644 --- a/dock_icon.c +++ b/dock_icon.c @@ -11,8 +11,118 @@ #include #include #include +#include -dock_icon* dock_icon_create( WnckWindow* window ) +//Refreshes the dock icon, if an item is provided try to use it otherwise use the top item +void dock_icon_refresh_icon( dock_icon* icon, pager_item* item ) +{ + if( !icon->pager_items ) + return; + + pager_item* top_item = (pager_item*)icon->pager_items->data; + + if( item == NULL ) + { + item = top_item; + } + + if( GDK_IS_PIXBUF( icon->icon_pixbuf ) ) + { + g_object_unref( icon->icon_pixbuf ); + } + icon->icon_pixbuf = get_icon( item->window, (int)SCALE_VALUE( 32.0 ) ); +} + +static gboolean dock_icon_draw( GtkWidget* widget, cairo_t* cr, dock_icon* icon ) +{ + int i, pager_count; + double width, rx, ry; + + icon->w->text_color.alpha = 0.25; + + cairo_set_operator( cr, CAIRO_OPERATOR_OVER ); + gdk_cairo_set_source_rgba( cr, &icon->w->text_color ); + if( icon->icon_state == ICON_STATE_HOVER ) + { + draw_rounded_rect( cr, 0, 0, icon->width, icon->height, SCALE_VALUE( 2.0 ) ); + cairo_fill( cr ); + } + if( icon->is_active ) + { + draw_rounded_rect( cr, 0, 0, icon->width, icon->height, SCALE_VALUE( 2.0 ) ); + cairo_fill( cr ); + } + + if( !GDK_IS_PIXBUF( icon->icon_pixbuf ) ) + { + printf( "Trying to draw without an icon\n" ); + dock_icon_refresh_icon( icon, NULL ); + return FALSE; + } + + gdk_cairo_set_source_pixbuf( cr, icon->icon_pixbuf, ( icon->width - SCALE_VALUE( 32.0 ) ) / 2.0, SCALE_VALUE( 2.0 ) ); + cairo_paint( cr ); + + pager_count = g_list_length( icon->pager_items ); + if( pager_count > 0 ) + { + //Draw rectangles + width = ( ( icon->width - SCALE_VALUE(8.0) ) / pager_count ); + ry = SCALE_VALUE(36.0); + icon->w->text_color.alpha = 0.5; + + //Shadow pass + cairo_set_source_rgba( cr, 1.0 - icon->w->text_color.red, 1.0 - icon->w->text_color.green, 1.0 - icon->w->text_color.blue, icon->w->text_color.alpha*0.5 ); + rx = SCALE_VALUE(4.0); + for( i = 0; i < pager_count; i++ ) + { + cairo_rectangle( cr, rx+SCALE_VALUE( 2.0 ), ry+SCALE_VALUE( 1.0 ), width-SCALE_VALUE( 2.0 ), SCALE_VALUE( 4.0 ) ); + rx += width; + } + cairo_fill( cr ); + + gdk_cairo_set_source_rgba( cr, &icon->w->text_color ); + rx = SCALE_VALUE(4.0); + for( i = 0; i < pager_count; i++ ) + { + cairo_rectangle( cr, rx+SCALE_VALUE( 1.0 ), ry, width-SCALE_VALUE( 2.0 ), SCALE_VALUE( 4.0 ) ); + rx += width; + } + cairo_fill( cr ); + } + + icon->w->text_color.alpha = 1.0; + + return TRUE; +} + +static void dock_icon_clicked( GtkButton* button, dock_icon* icon ) +{ + dock_icon_activate( icon, gdk_x11_get_server_time( gtk_widget_get_window( GTK_WIDGET( button ) ) ), TRUE ); +} + +gboolean dock_icon_leave( GtkWidget* widget, GdkEvent* event, dock_icon* icon ) +{ + icon->icon_state = ICON_STATE_NORMAL; + gtk_widget_queue_draw( widget ); + + return FALSE; +} + +gboolean dock_icon_motion( GtkWidget* widget, GdkEvent* event, dock_icon* icon ) +{ + icon->icon_state = ICON_STATE_HOVER; + gtk_widget_queue_draw( widget ); + + return FALSE; +} + +void dock_icon_remove( dock_icon* icon ) +{ + gtk_widget_destroy( icon->button ); +} + +dock_icon* dock_icon_create( WnckWindow* window, eric_window* w ) { dock_icon* icon = malloc( sizeof( dock_icon ) ); icon->class_group = wnck_window_get_class_group( window ); @@ -20,11 +130,23 @@ dock_icon* dock_icon_create( WnckWindow* window ) icon->icon_pixbuf = get_icon( window, (int)SCALE_VALUE( 32.0 ) ); icon->pager_items = NULL; icon->icon_state = ICON_STATE_NORMAL; + icon->w = w; printf( "Attempted dock icon get%s \n", wnck_class_group_get_id( icon->class_group ) ); icon->width = SCALE_VALUE( BAR_HEIGHT - 6.0 ); - icon->height = SCALE_VALUE( BAR_HEIGHT ); + icon->height = SCALE_VALUE( BAR_HEIGHT - 4.0 ); + + icon->button = gtk_button_new(); + gtk_widget_set_size_request( icon->button, icon->width, icon->height ); + gtk_widget_add_events( icon->button, GDK_POINTER_MOTION_MASK + | GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK + | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK ); + gtk_widget_set_app_paintable( icon->button, TRUE ); + g_signal_connect( G_OBJECT( icon->button ), "draw", G_CALLBACK( dock_icon_draw ), (void*)icon ); + g_signal_connect( G_OBJECT( icon->button ), "clicked", G_CALLBACK( dock_icon_clicked ), (void*)icon ); + g_signal_connect( G_OBJECT( icon->button ), "leave-notify-event", G_CALLBACK( dock_icon_leave ), (void*)icon ); + g_signal_connect( G_OBJECT( icon->button ), "motion-notify-event", G_CALLBACK( dock_icon_motion ), (void*)icon ); icon->selected_index = 0; @@ -75,6 +197,7 @@ void dock_icon_activate( dock_icon* icon, Time time, int from_click ) if( tooltip_window_icon != icon ) { + tooltip_window_clear_pager_list(); tooltip_window_icon = icon; tooltip_window_show(); icon->selected_index = 0; @@ -104,19 +227,6 @@ void dock_icon_activate( dock_icon* icon, Time time, int from_click ) icon->icon_state = ICON_STATE_NORMAL; } -void dock_icon_mouse_down( dock_icon* icon, double mx, double my, Time time ) -{ - double it, ib, il, ir; - - il = icon->x; ir = icon->x + icon->width; - it = icon->y; ib = icon->y + icon->height; - - if( il < mx && mx < ir && it < my && my < ib ) - { - dock_icon_activate( icon, time, TRUE ); - } -} - gchar* get_icon_from_desktop( const char* name ) { GKeyFile* key_file = g_key_file_new(); diff --git a/dock_icon.h b/dock_icon.h index 59a92f6..19b47c7 100644 --- a/dock_icon.h +++ b/dock_icon.h @@ -14,24 +14,15 @@ #include #include "pager_item.h" +#include "eric_window.h" +#include "dock_objects.h" -typedef struct -{ - WnckClassGroup* class_group; - GdkPixbuf* icon_pixbuf; - GList* pager_items; - double x, y; - double width, height; - int icon_state; - int is_active; - int selected_index; - gchar* instance_name; -} dock_icon; - -dock_icon* dock_icon_create( WnckWindow* window ); +dock_icon* dock_icon_create( WnckWindow* window, eric_window* w ); pager_item* dock_icon_get_next_pager_item( dock_icon* icon ); void dock_icon_clear_pager_item_state( dock_icon* icon ); void dock_icon_activate( dock_icon* icon, Time time, int from_click ); void dock_icon_mouse_down( dock_icon* icon, double mx, double my, Time time ); +void dock_icon_remove( dock_icon* icon ); GdkPixbuf* get_icon( WnckWindow* window, guint size ); char * strip_extension (const char *file); +void dock_icon_refresh_icon( dock_icon* icon, pager_item* item ); diff --git a/dock_objects.h b/dock_objects.h new file mode 100644 index 0000000..bf8559e --- /dev/null +++ b/dock_objects.h @@ -0,0 +1,35 @@ +#pragma once + +#include + +//Definitions for dock_icon and pager_item structs + +typedef struct +{ + WnckClassGroup* class_group; + eric_window* w; + GdkPixbuf* icon_pixbuf; + GList* pager_items; + double width, height; + int icon_state; + int is_active; + int selected_index; + gchar* instance_name; + GtkWidget* button; +} dock_icon; + +//Structure to hold actual pager items +typedef struct +{ + WnckWindow* window; + char name[256]; + GdkPixbuf* icon_pixbuf; + double x, y; + double width, height; + double text_height; + int icon_state; + dock_icon* parent; + GtkWidget* button; + PangoLayout* layout; + eric_window* w; +} pager_item; diff --git a/main.c b/main.c index 14f6b21..5a45631 100644 --- a/main.c +++ b/main.c @@ -8,6 +8,7 @@ #include "eric_window.h" GList* dock_icons = NULL; +GtkWidget* dock_icons_box; eric_window* dock_window = NULL; #include "clock.h" @@ -46,7 +47,7 @@ void add_window_to_pager( WnckWindow* window ) icon = (dock_icon*)icon_list->data; if( icon->instance_name != NULL && instance_name != NULL && strcmp( icon->instance_name, instance_name ) == 0 ) { - icon->pager_items = g_list_append( icon->pager_items, pager_item_create( window ) ); + pager_item_create( window, icon ); found_class_group = 1; break; } @@ -55,13 +56,12 @@ void add_window_to_pager( WnckWindow* window ) if( !found_class_group ) { //Add a new dock item - new_dock_icon = dock_icon_create( window ); - new_dock_icon->pager_items = g_list_append( - new_dock_icon->pager_items, - pager_item_create( window ) - ); + new_dock_icon = dock_icon_create( window, dock_window ); + pager_item_create( window, new_dock_icon ); dock_icons = g_list_append( dock_icons, new_dock_icon ); + gtk_container_add( GTK_CONTAINER( dock_icons_box ), new_dock_icon->button ); + gtk_widget_show( new_dock_icon->button ); } } @@ -143,72 +143,10 @@ GdkFilterReturn handle_x11_event( GdkXEvent *xevent, GdkEvent *event, gpointer d static gboolean draw_dock_window( GtkWidget* widget, cairo_t* cr, eric_window* w ) { - GList* icon_list = dock_icons; - dock_icon* icon; - double x, y; - double rx, ry, width; - int i, pager_count, icon_count; - - icon_count = g_list_length( dock_icons ); - x = floor( (double)(screen_width/2) - SCALE_VALUE( 47.0 * (double)icon_count / 2.0 ) ); - y = SCALE_VALUE( 5.0 ); - cairo_set_operator( cr, CAIRO_OPERATOR_OVER ); - for( icon_list = dock_icons; icon_list != NULL; icon_list = icon_list->next ) - { - icon = (dock_icon*)icon_list->data; + //Icon drawing is handled by their draw events - w->text_color.alpha = 0.25; - gdk_cairo_set_source_rgba( cr, &w->text_color ); - if( icon->icon_state == ICON_STATE_HOVER ) - { - draw_rounded_rect( cr, x, y-SCALE_VALUE( 2.0 ), SCALE_VALUE( 42.0 ), SCALE_VALUE( 42.0 ), SCALE_VALUE( 2.0 ) ); - cairo_fill( cr ); - } - if( icon->is_active ) - { - draw_rounded_rect( cr, x, y-SCALE_VALUE( 2.0 ), SCALE_VALUE( 42.0 ), SCALE_VALUE( 42.0 ), SCALE_VALUE( 2.0 ) ); - cairo_fill( cr ); - } - if( !GDK_IS_PIXBUF( icon->icon_pixbuf ) ) - { - printf( "Trying to draw without an icon\n" ); - icon->icon_pixbuf = gdk_pixbuf_copy( wnck_class_group_get_icon( icon->class_group ) ); - } - gdk_cairo_set_source_pixbuf( cr, icon->icon_pixbuf, x+SCALE_VALUE( 4.0 ), y ); - cairo_paint( cr ); - - pager_count = g_list_length( icon->pager_items ); - if( pager_count > 0 ) - { - //Draw rectangles - width = (SCALE_VALUE(32.0) / pager_count ); - ry = y + SCALE_VALUE(34.0); - w->text_color.alpha = 0.5; - - //Shadow pass - cairo_set_source_rgba( cr, 1.0 - w->text_color.red, 1.0 - w->text_color.green, 1.0 - w->text_color.blue, w->text_color.alpha*0.5 ); - rx = x + SCALE_VALUE(4.0); - for( i = 0; i < pager_count; i++ ) - { - cairo_rectangle( cr, rx+SCALE_VALUE( 2.0 ), ry+SCALE_VALUE( 1.0 ), width-SCALE_VALUE( 2.0 ), SCALE_VALUE( 4.0 ) ); - rx += width; - } - cairo_fill( cr ); - - gdk_cairo_set_source_rgba( cr, &w->text_color ); - rx = x + SCALE_VALUE(4.0); - for( i = 0; i < pager_count; i++ ) - { - cairo_rectangle( cr, rx+SCALE_VALUE( 1.0 ), ry, width-SCALE_VALUE( 2.0 ), SCALE_VALUE( 4.0 ) ); - rx += width; - } - cairo_fill( cr ); - } - icon->x = x; - icon->y = y; + cairo_set_operator( cr, CAIRO_OPERATOR_OVER ); - x += SCALE_VALUE( 47.0 ); - } double clock_width = clock_draw( cr, (double)screen_width-SCALE_VALUE(10), ( BAR_HEIGHT * UI_SCALE ) / 2.0, w ); if( show_battery_icon ) draw_battery_icon( cr, clock_width-SCALE_VALUE( 52.0 ), (( BAR_HEIGHT * UI_SCALE ) / 2.0)-SCALE_VALUE( 12 ), SCALE_VALUE( 24 ) ); @@ -236,7 +174,7 @@ void grab_keys() gboolean window_mouse_move( GtkWidget* widget, GdkEvent* event, gpointer user ) { - double mx, my; + /*double mx, my; double it, ib, il, ir; int old_state, state_changed; dock_icon* icon; @@ -267,14 +205,14 @@ gboolean window_mouse_move( GtkWidget* widget, GdkEvent* event, gpointer user ) if( state_changed ) gtk_widget_queue_draw( dock_window->window ); } - } + }*/ return FALSE; } void dock_window_mouse_down( GtkWidget* widget, GdkEvent* event, gpointer user ) { - GdkEventButton* e = (GdkEventButton*)event; + /*GdkEventButton* e = (GdkEventButton*)event; if( e->button != 1 ) return; @@ -287,7 +225,7 @@ void dock_window_mouse_down( GtkWidget* widget, GdkEvent* event, gpointer user ) { icon = (dock_icon*)icon_list->data; dock_icon_mouse_down( icon, mx, my, e->time ); - } + }*/ } void setup_dock_window() @@ -309,6 +247,13 @@ void setup_dock_window() g_signal_connect( G_OBJECT( dock_window->window ), "motion-notify-event", G_CALLBACK(window_mouse_move), NULL ); g_signal_connect( G_OBJECT( dock_window->window ), "button-press-event", G_CALLBACK(dock_window_mouse_down), NULL ); + //Add Dock icon box + dock_icons_box = gtk_button_box_new( GTK_ORIENTATION_HORIZONTAL ); + gtk_button_box_set_layout( GTK_BUTTON_BOX( dock_icons_box ), GTK_BUTTONBOX_CENTER ); + //gtk_button_box_set_child_non_homogeneous( GTK_BUTTON_BOX( dock_icons_box ), TRUE ); + gtk_container_add( GTK_CONTAINER( dock_window->window ), dock_icons_box ); + gtk_widget_show( dock_icons_box ); + gtk_widget_show_now( dock_window->window ); //Init clock drawing @@ -357,6 +302,7 @@ static void wnck_window_closed( WnckScreen* screen, WnckWindow* window, gpointer if( icon->pager_items == NULL ) { dock_icons = g_list_remove( dock_icons, icon ); + dock_icon_remove( icon ); free( icon ); printf( "Removed dock icon\n" ); break; diff --git a/pager_item.c b/pager_item.c index d213daa..272a4da 100644 --- a/pager_item.c +++ b/pager_item.c @@ -7,14 +7,25 @@ #include #include #include +#include +#include #include "ericdock.h" #include "drawing.h" #include "dock_icon.h" +#include "tooltip_window.h" void pager_item_name_changed( WnckWindow* window, pager_item* item ) { + PangoRectangle rect; + strcpy( item->name, wnck_window_get_name( window ) ); + if( item->layout != NULL ) + { + pango_layout_set_text( item->layout, item->name, strlen( item->name ) ); + pango_layout_get_pixel_extents( item->layout, NULL, &rect ); + item->text_height = rect.height; + } } void pager_item_icon_changed( WnckWindow* window, pager_item* item ) @@ -26,7 +37,7 @@ void pager_item_icon_changed( WnckWindow* window, pager_item* item ) printf( "Icon changed %s\n", item->name ); item->icon_pixbuf = get_icon( window, (int)SCALE_VALUE( 16.0 ) ); - gtk_widget_queue_draw( dock_window->window ); + dock_icon_refresh_icon( item->parent, item ); } void pager_item_state_changed( WnckWindow* window, WnckWindowState changed_mask, WnckWindowState new_state, pager_item* item ) @@ -35,75 +46,151 @@ void pager_item_state_changed( WnckWindow* window, WnckWindowState changed_mask, //item->icon_pixbuf = wnck_window_get_mini_icon( window ); } -pager_item* pager_item_create( WnckWindow* window ) +gboolean pager_item_leave( GtkWidget* widget, GdkEvent* event, pager_item* item ) +{ + item->icon_state = ICON_STATE_NORMAL; + gtk_widget_queue_draw( widget ); + + return FALSE; +} + +gboolean pager_item_motion( GtkWidget* widget, GdkEvent* event, pager_item* item ) +{ + item->icon_state = ICON_STATE_HOVER; + gtk_widget_queue_draw( widget ); + + return FALSE; +} + +static gboolean pager_item_draw( GtkWidget* widget, cairo_t* cr, pager_item* item ) +{ + double text_y; + + if( !GDK_IS_PIXBUF( item->icon_pixbuf ) ) + { + printf( "Attempting to draw pager item without icon\n" ); + item->icon_pixbuf = get_icon( item->window, (int)SCALE_VALUE( 16.0 ) ); + } + + if( item->icon_state == ICON_STATE_HOVER ) + { + item->w->text_color.alpha = 0.25; + gdk_cairo_set_source_rgba( cr, &item->w->text_color ); + draw_rounded_rect( cr, 0, 0, + item->width, item->height, SCALE_VALUE( 2.0 ) ); + cairo_fill( cr ); + } + + gdk_cairo_set_source_pixbuf( cr, item->icon_pixbuf, 0, 0 + SCALE_VALUE( 4.0 ) ); + cairo_paint( cr ); + + //Draw text + text_y = ( SCALE_VALUE(24.0) - item->text_height ) / 2.0; + + //Shadow Pass + item->w->text_color.alpha = 1.0; + cairo_set_source_rgba(cr,( 1.0 - item->w->text_color.red ), + ( 1.0 - item->w->text_color.green ), + ( 1.0 - item->w->text_color.blue ), + 0.25); + cairo_move_to( cr, SCALE_VALUE( 21.0 ), text_y + SCALE_VALUE( 1.0 ) ); + pango_cairo_layout_path( cr, item->layout ); + cairo_fill( cr ); + + //Final Pass + gdk_cairo_set_source_rgba( cr, &item->w->text_color ); + cairo_move_to( cr, SCALE_VALUE( 20.0 ), text_y ); + pango_cairo_layout_path( cr, item->layout ); + cairo_fill( cr ); + + item->w->text_color.alpha = 1.0; + + return TRUE; +} + +pager_item* pager_item_create( WnckWindow* window, dock_icon* parent ) { pager_item* item = malloc( sizeof( pager_item ) ); item->window = window; + item->parent = parent; strcpy( item->name, wnck_window_get_name( item->window ) ); - item->icon_pixbuf = get_icon( window, (int)SCALE_VALUE( 16.0 ) ); - item->icon_state = ICON_STATE_NORMAL; + + item->icon_pixbuf = NULL; + item->button = NULL; + item->layout = NULL; g_signal_connect( G_OBJECT( window ), "name-changed", G_CALLBACK( pager_item_name_changed ), (gpointer)item ); g_signal_connect( G_OBJECT( window ), "icon-changed", G_CALLBACK( pager_item_icon_changed ), (gpointer)item ); g_signal_connect( G_OBJECT( window ), "state-changed", G_CALLBACK( pager_item_state_changed ), (gpointer)item ); - item->width = SCALE_VALUE( 320 ); - item->height = SCALE_VALUE( 24.0 ); item->text_height = SCALE_VALUE( 16.0 ); + //Append to the icon + parent->pager_items = g_list_append( parent->pager_items, item ); + return item; } -/* Returns bool if state has changed */ -int pager_item_mouse_move( pager_item* item, double mx, double my ) +static void pager_item_clicked( GtkButton* button, pager_item* item ) { - double it, ib, il, ir; - int old_state; - - old_state = item->icon_state; + wnck_window_activate( item->window, gdk_x11_get_server_time( gtk_widget_get_window( GTK_WIDGET( button ) ) ) ); + tooltip_window_hide(); +} - il = item->x; ir = item->x + item->width; - it = item->y; ib = item->y + item->height; +GtkWidget* pager_item_create_widget( pager_item* item, int width, int height ) +{ + PangoRectangle rect; - if( il < mx && mx < ir && it < my && my < ib ) + if( GTK_IS_WIDGET( item->button ) ) { - item->icon_state = ICON_STATE_HOVER; - } - else - { - item->icon_state = ICON_STATE_NORMAL; + gtk_widget_destroy( item->button ); } - return old_state != item->icon_state; -} + item->width = width; + item->height = height; + item->button = gtk_button_new(); -void pager_item_draw( pager_item* item, cairo_t* cr, eric_window* w, cairo_pattern_t* pattern ) -{ - if( item->icon_pixbuf != NULL && !GDK_IS_PIXBUF( item->icon_pixbuf ) ) + if( !GDK_IS_PIXBUF( item->icon_pixbuf ) ) { item->icon_pixbuf = get_icon( item->window, (int)SCALE_VALUE( 16.0 ) ); - if( !GDK_IS_PIXBUF( item->icon_pixbuf ) ) - return; } + + gtk_widget_set_size_request( item->button, item->width, item->height ); + gtk_widget_add_events( item->button, GDK_POINTER_MOTION_MASK + | GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK + | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK ); + gtk_widget_set_app_paintable( item->button, TRUE ); + g_signal_connect( G_OBJECT( item->button ), "draw", G_CALLBACK( pager_item_draw ), (void*)item ); + g_signal_connect( G_OBJECT( item->button ), "clicked", G_CALLBACK( pager_item_clicked ), (void*)item ); + g_signal_connect( G_OBJECT( item->button ), "leave-notify-event", G_CALLBACK( pager_item_leave ), (void*)item ); + g_signal_connect( G_OBJECT( item->button ), "motion-notify-event", G_CALLBACK( pager_item_motion ), (void*)item ); + + //Pango stuff + item->layout = pango_layout_new( tooltip_window_get_pango_context() ); + pango_layout_set_wrap( item->layout, PANGO_WRAP_WORD ); + pango_layout_set_auto_dir( item->layout, FALSE ); + pango_layout_set_width( item->layout, ( item->width - SCALE_VALUE( 20.0 ) ) * PANGO_SCALE ); //Have to remove space for icon + pango_layout_set_height( item->layout, item->height * PANGO_SCALE ); + pango_layout_set_ellipsize( item->layout, PANGO_ELLIPSIZE_END ); + + pango_layout_set_text( item->layout, item->name, strlen( item->name ) ); + pango_layout_get_pixel_extents( item->layout, NULL, &rect ); + item->text_height = rect.height; + + return item->button; +} - if( item->icon_state == ICON_STATE_HOVER ) +void pager_item_destroy_widget( pager_item* item ) +{ + if( GDK_IS_PIXBUF( item->icon_pixbuf ) ) { - w->text_color.alpha = 0.25; - gdk_cairo_set_source_rgba( cr, &w->text_color ); - draw_rounded_rect( cr, item->x, item->y, - item->width, item->height, SCALE_VALUE( 2.0 ) ); - cairo_fill( cr ); + g_object_unref( item->icon_pixbuf ); + item->icon_pixbuf = NULL; } - - gdk_cairo_set_source_pixbuf( cr, item->icon_pixbuf, item->x, item->y + SCALE_VALUE( 6.0 ) ); - cairo_paint( cr ); - - cairo_set_source( cr, pattern ); - cairo_move_to( cr, item->x + SCALE_VALUE( 20.0 ), item->y + item->text_height ); - cairo_text_path( cr, item->name ); - - cairo_fill( cr ); - + //TODO: Destroy pango? + item->layout = NULL; + gtk_widget_destroy( item->button ); + item->button = NULL; } diff --git a/pager_item.h b/pager_item.h index dba3115..5d1b20a 100644 --- a/pager_item.h +++ b/pager_item.h @@ -10,22 +10,12 @@ #include "drawing.h" #include "eric_window.h" - -//Structure to hold actual pager items -typedef struct -{ - WnckWindow* window; - char name[256]; - GdkPixbuf* icon_pixbuf; - double x, y; - double width, height; - double text_height; - int icon_state; -} pager_item; +#include "dock_objects.h" void pager_item_name_changed( WnckWindow* window, pager_item* item ); void pager_item_icon_changed( WnckWindow* window, pager_item* item ); void pager_item_state_changed( WnckWindow* window, WnckWindowState changed_mask, WnckWindowState new_state, pager_item* item ); -pager_item* pager_item_create( WnckWindow* window ); +pager_item* pager_item_create( WnckWindow* window, dock_icon* parent ); int pager_item_mouse_move( pager_item* item, double mx, double my ); -void pager_item_draw( pager_item* item, cairo_t* cr, eric_window* w, cairo_pattern_t* pattern ); +GtkWidget* pager_item_create_widget( pager_item* item, int width, int height ); +void pager_item_destroy_widget( pager_item* item ); diff --git a/tooltip_window.c b/tooltip_window.c index dbc8f8b..4e429aa 100644 --- a/tooltip_window.c +++ b/tooltip_window.c @@ -9,11 +9,8 @@ eric_window* tooltip_window = NULL; dock_icon* tooltip_window_icon = NULL; -void tooltip_window_hide() -{ - tooltip_window_icon = NULL; - gtk_widget_hide( tooltip_window->window ); -} +GtkWidget* pager_items_box; +PangoContext* pango_context; gboolean tooltip_window_lose_focus( GtkWidget* widget, GdkEvent* event, gpointer user ) { @@ -21,89 +18,11 @@ gboolean tooltip_window_lose_focus( GtkWidget* widget, GdkEvent* event, gpointer return TRUE; } -void tooltip_window_mouse_down( GtkWidget* widget, GdkEvent* event, gpointer user ) +PangoContext* tooltip_window_get_pango_context() { - GdkEventButton* e = (GdkEventButton*)event; - if( e->button != 1 ) - return; - - pager_item* item; - GList* pager_list; - - double my; - my = e->y; - for( pager_list = tooltip_window_icon->pager_items; pager_list != NULL; pager_list = pager_list->next ) - { - item = pager_list->data; - if( my > item->y && my < item->y + SCALE_VALUE( 24.0 ) ) - { - wnck_window_activate( item->window, e->time ); - tooltip_window_hide(); - } - } + return pango_context; } -gboolean tooltip_window_mouse_move( GtkWidget* widget, GdkEvent* event, gpointer user ) -{ - double mx, my; - int state_changed; - pager_item* item; - GList *item_list; - GdkEventMotion* e = (GdkEventMotion*)event; - - mx = e->x; - my = e->y; - - for( item_list = tooltip_window_icon->pager_items; item_list != NULL; item_list = item_list->next ) - { - item = item_list->data; - - - if( pager_item_mouse_move( item, mx, my ) ) - state_changed = TRUE; - } - - if( state_changed ) - gtk_widget_queue_draw( tooltip_window->window ); - - return FALSE; -} - -gboolean tooltip_window_draw( GtkWidget* widget, cairo_t* cr, eric_window* w ) -{ - double x, y; - GList* pager_list; - pager_item* item; - cairo_pattern_t* pattern; - - cairo_set_operator( cr, CAIRO_OPERATOR_OVER ); - w->text_color.alpha = 1.0; - cairo_set_font_face( cr, cairo_toy_font_face_create( ERIC_DOCK_FONT, CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL ) ); - cairo_set_font_size( cr, SCALE_VALUE( 12.0 ) ); - - x = SCALE_VALUE( 5.0 ); //margin-left - y = SCALE_VALUE( 2.0 ); //margin-top - pattern = cairo_pattern_create_linear( SCALE_VALUE( ERIC_DOCK_TOOLTIP_WIDTH - 21.0 ), 0, SCALE_VALUE( ERIC_DOCK_TOOLTIP_WIDTH - 5.0 ), 0 ); - cairo_pattern_add_color_stop_rgba( pattern, 0.0, w->text_color.red, w->text_color.green, w->text_color.blue, 1.0 ); - cairo_pattern_add_color_stop_rgba( pattern, 1.0, w->text_color.red, w->text_color.green, w->text_color.blue, 0.0 ); - for( pager_list = tooltip_window_icon->pager_items; pager_list != NULL; pager_list = pager_list->next ) - { - item = (pager_item*)pager_list->data; - - item->x = x; - item->y = y; - pager_item_draw( item, cr, w, pattern ); - - y += SCALE_VALUE( 24.0 ); - } - - cairo_pattern_destroy( pattern ); - - return FALSE; -} - - - void tooltip_window_create( GtkWidget* dock_window ) { eric_window* w = eric_window_create( 10, 10, "" ); @@ -116,9 +35,20 @@ void tooltip_window_create( GtkWidget* dock_window ) gtk_widget_add_events( w->window, GDK_POINTER_MOTION_MASK | GDK_BUTTON_PRESS_MASK ); g_signal_connect( G_OBJECT( w->window ), "focus-out-event", G_CALLBACK(tooltip_window_lose_focus), NULL ); - g_signal_connect( G_OBJECT( w->window ), "motion-notify-event", G_CALLBACK(tooltip_window_mouse_move), NULL ); - g_signal_connect( G_OBJECT( w->window ), "button-press-event", G_CALLBACK(tooltip_window_mouse_down), NULL ); - w->draw_callback = tooltip_window_draw; + + //Add Dock icon box + pager_items_box = gtk_button_box_new( GTK_ORIENTATION_VERTICAL ); + gtk_button_box_set_layout( GTK_BUTTON_BOX( pager_items_box ), GTK_BUTTONBOX_CENTER ); + //gtk_button_box_set_child_non_homogeneous( GTK_BUTTON_BOX( dock_icons_box ), TRUE ); + gtk_container_add( GTK_CONTAINER( w->window ), pager_items_box ); + gtk_widget_show( pager_items_box ); + + //Pango stuff + char fontdesc[80]; + pango_context = gtk_widget_create_pango_context( w->window ); + sprintf( fontdesc, "Source Sans Pro Regular %ipx", (int)(SCALE_VALUE( 16 )) ); + PangoFontDescription* font = pango_font_description_from_string( fontdesc ); + pango_context_set_font_description( pango_context, font ); tooltip_window = w; } @@ -132,13 +62,51 @@ void tooltip_window_update_geometry() pager_count = g_list_length( tooltip_window_icon->pager_items ); gtk_window_get_position( GTK_WINDOW( dock_window->window ), &wx, &wy ); - gtk_window_resize( GTK_WINDOW( tooltip_window->window ), SCALE_VALUE(ERIC_DOCK_TOOLTIP_WIDTH), SCALE_VALUE( pager_count * 24 ) ); - gtk_window_move( GTK_WINDOW( tooltip_window->window ), wx + (int)tooltip_window_icon->x, wy - (int)SCALE_VALUE( pager_count * 24 ) ); + gtk_window_resize( GTK_WINDOW( tooltip_window->window ), SCALE_VALUE(ERIC_DOCK_TOOLTIP_WIDTH), SCALE_VALUE( pager_count * 22 ) ); + //TODO: Move window to appropriate dock icon here! } void tooltip_window_show() { + GList* pager_list; + pager_item* item; + GtkWidget* button; + tooltip_window_update_geometry(); gtk_widget_show_all( tooltip_window->window ); gtk_widget_queue_draw( tooltip_window->window ); + + for( pager_list = tooltip_window_icon->pager_items; pager_list != NULL; pager_list = pager_list->next ) + { + item = (pager_item*)pager_list->data; + button = pager_item_create_widget( item, SCALE_VALUE( ERIC_DOCK_TOOLTIP_WIDTH ), SCALE_VALUE( 22 )); + item->w = tooltip_window; + + gtk_container_add( GTK_CONTAINER( pager_items_box ), button ); + gtk_widget_show( button ); + } +} + +void tooltip_window_clear_pager_list() +{ + GList* pager_list; + pager_item* item; + + if( tooltip_window_icon != NULL ) + { + //Destroy any pager item widgets + for( pager_list = tooltip_window_icon->pager_items; pager_list != NULL; pager_list = pager_list->next ) + { + item = (pager_item*)pager_list->data; + pager_item_destroy_widget( item ); + } + } +} + +void tooltip_window_hide() +{ + tooltip_window_clear_pager_list(); + + tooltip_window_icon = NULL; + gtk_widget_hide( tooltip_window->window ); } diff --git a/tooltip_window.h b/tooltip_window.h index edf40cb..f32e97a 100644 --- a/tooltip_window.h +++ b/tooltip_window.h @@ -3,6 +3,10 @@ #include #include "eric_window.h" +#include + +extern eric_window* tooltip_window; + void tooltip_window_hide(); gboolean tooltip_window_lose_focus( GtkWidget* widget, GdkEvent* event, gpointer user ); void tooltip_window_mouse_down( GtkWidget* widget, GdkEvent* event, gpointer user ); @@ -11,3 +15,5 @@ gboolean tooltip_window_draw( GtkWidget* widget, cairo_t* cr, eric_window* w ); void tooltip_window_create( GtkWidget* dock_window ); void tooltip_window_update_geometry(); void tooltip_window_show(); +PangoContext* tooltip_window_get_pango_context(); +void tooltip_window_clear_pager_list(); -- 2.47.0