]> Eric's Git Repo - ericdock.git/commitdiff
Updates to structure and rendering of icons/pager items master
authorEric Wertz <ericdwertz@gmail.com>
Mon, 9 Apr 2018 14:40:39 +0000 (10:40 -0400)
committerEric Wertz <ericdwertz@gmail.com>
Mon, 9 Apr 2018 14:40:39 +0000 (10:40 -0400)
dock_icon.c
dock_icon.h
dock_objects.h [new file with mode: 0644]
main.c
pager_item.c
pager_item.h
tooltip_window.c
tooltip_window.h

index 4e6666e30e2aa20c5269d3e0cb391964f75889df..0af949c9f7061e5d32e8f17f576722ae5e8f9575 100644 (file)
 #include <stdio.h>
 #include <ctype.h>
 #include <glib.h>
+#include <gdk/gdkx.h>
 
-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();
index 59a92f620bc43b9762c4e1bcc8fd6d8c7297b1e4..19b47c7b825102fc305f2d25e9919d715ee0dde3 100644 (file)
 #include <libwnck/libwnck.h>
 
 #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 (file)
index 0000000..bf8559e
--- /dev/null
@@ -0,0 +1,35 @@
+#pragma once
+
+#include <pango/pango-context.h>
+
+//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 14f6b216053a28033159fb119f5811c9574fee7e..5a45631f7429ed94a2c978c64281fa622622481c 100644 (file)
--- 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;
index d213daa31c90acfbb5b3f3f39e3548676a2f3341..272a4dabf702311d62091dd5588ab3304a74cd97 100644 (file)
@@ -7,14 +7,25 @@
 #include <string.h>
 #include <stdlib.h>
 #include <gtk/gtk.h>
+#include <gdk/gdkx.h>
+#include <pango/pangocairo.h>
 
 #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;
 }
index dba3115f8f7d889e09588ff5113e123bc087f96e..5d1b20ac18e27bd559b470d96245cd4618e3ff52 100644 (file)
 
 #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 );
index dbc8f8bb051c8e8a0ed63dcbd98c3f54d977c7bc..4e429aa7af3f5374acca36578bef85a17b540722 100644 (file)
@@ -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 );
 }
index edf40cb204071c36124dfff30fc42dd068e13af1..f32e97a834213b8e647088e994757f1be9c55c19 100644 (file)
@@ -3,6 +3,10 @@
 #include <gtk/gtk.h>
 #include "eric_window.h"
 
+#include <pango/pango-context.h>
+
+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();