1 /* picture.c: GTK routines to draw the keyboard picture
2 Copyright (c) 2002-2005 Philip Kendall
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License along
15 with this program; if not, write to the Free Software Foundation, Inc.,
16 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17
18 Author contact information:
19
20 E-mail: philip-fuse@shadowmagic.org.uk
21
22 */
23
24 #include <config.h>
25
26 #include <gtk/gtk.h>
27
28 #include "gtkinternals.h"
29 #include "ui/ui.h"
30 #include "utils.h"
31
32 static int dialog_created = 0;
33
34 static GtkWidget *dialog;
35 static GdkPixbuf *pixbuf = NULL;
36
37 #if GTK_CHECK_VERSION( 3, 0, 0 )
38
39 static GdkPixbuf *scaled_pixbuf = NULL;
40
41 static gint
picture_size_allocate(GtkWidget * widget GCC_UNUSED,GdkRectangle * allocation,gpointer data GCC_UNUSED)42 picture_size_allocate( GtkWidget *widget GCC_UNUSED, GdkRectangle *allocation,
43 gpointer data GCC_UNUSED )
44 {
45 float scale_x, scale_y, scale_factor;
46 int scaled_width, scaled_height;
47
48 scale_x = (float)allocation->width / gdk_pixbuf_get_width( pixbuf );
49 scale_y = (float)allocation->height / gdk_pixbuf_get_height( pixbuf );
50 scale_factor = scale_x < scale_y ? scale_x : scale_y;
51
52 scaled_width = gdk_pixbuf_get_width( pixbuf ) * scale_factor;
53 scaled_height = gdk_pixbuf_get_height( pixbuf ) * scale_factor;
54
55 if( scaled_pixbuf != NULL ) g_object_unref( scaled_pixbuf );
56 scaled_pixbuf = gdk_pixbuf_scale_simple( pixbuf, scaled_width, scaled_height,
57 GDK_INTERP_BILINEAR );
58
59 return FALSE;
60 }
61
62 static gboolean
picture_draw(GtkWidget * widget,cairo_t * cr,gpointer user_data GCC_UNUSED)63 picture_draw( GtkWidget *widget, cairo_t *cr, gpointer user_data GCC_UNUSED )
64 {
65 int offset_x, offset_y;
66 int scaled_width, scaled_height;
67 int allocated_width, allocated_height;
68
69 allocated_width = gtk_widget_get_allocated_width( widget );
70 allocated_height = gtk_widget_get_allocated_height( widget );
71
72 scaled_width = gdk_pixbuf_get_width( scaled_pixbuf );
73 scaled_height = gdk_pixbuf_get_height( scaled_pixbuf );
74
75 offset_x = ( allocated_width - scaled_width ) / 2;
76 offset_y = ( allocated_height - scaled_height ) / 2;
77
78 gdk_cairo_set_source_pixbuf( cr, scaled_pixbuf, offset_x, offset_y );
79 cairo_paint(cr);
80
81 return FALSE;
82 }
83
84 #endif /* #if GTK_CHECK_VERSION( 3, 0, 0 ) */
85
86 int
gtkui_picture(const char * filename,int border GCC_UNUSED)87 gtkui_picture( const char *filename, int border GCC_UNUSED )
88 {
89 GtkWidget *content_area;
90
91 if( !dialog_created ) {
92
93 char path[PATH_MAX];
94
95 if( utils_find_file_path( filename, path, UTILS_AUXILIARY_LIB ) ) return 1;
96
97 pixbuf = gdk_pixbuf_new_from_file( path, NULL );
98 if( pixbuf == NULL ) {
99 ui_error( UI_ERROR_ERROR, "Failed to load keyboard image" );
100 return 1;
101 }
102
103 dialog = gtkstock_dialog_new( "Fuse - Keyboard",
104 G_CALLBACK( gtk_widget_hide ) );
105
106 content_area = gtk_dialog_get_content_area( GTK_DIALOG( dialog ) );
107
108 #if !GTK_CHECK_VERSION( 3, 0, 0 )
109
110 GtkWidget *image = gtk_image_new();
111 gtk_image_set_from_pixbuf( GTK_IMAGE( image ), pixbuf );
112 gtk_container_add( GTK_CONTAINER( content_area ), image );
113
114 /* Stop users resizing this window */
115 gtk_window_set_resizable( GTK_WINDOW( dialog ), FALSE );
116
117 #else
118
119 GtkWidget *box = gtk_box_new( GTK_ORIENTATION_VERTICAL, 0 );
120 gtk_container_add( GTK_CONTAINER( content_area ), box );
121
122 GtkWidget *drawing_area = gtk_drawing_area_new();
123 gtk_widget_set_vexpand( drawing_area, TRUE );
124 gtk_box_pack_start( GTK_BOX( box ), drawing_area, TRUE, TRUE, 0 );
125
126 g_signal_connect( G_OBJECT( drawing_area ), "draw",
127 G_CALLBACK( picture_draw ), NULL );
128 g_signal_connect( G_OBJECT( drawing_area ), "size-allocate",
129 G_CALLBACK( picture_size_allocate ), NULL );
130
131 gtk_widget_set_size_request( GTK_WIDGET( drawing_area ),
132 gdk_pixbuf_get_width( pixbuf ),
133 gdk_pixbuf_get_height( pixbuf ) );
134
135 #endif /* #if !GTK_CHECK_VERSION( 3, 0, 0 ) */
136
137 gtkstock_create_close( dialog, NULL, G_CALLBACK( gtk_widget_hide ),
138 FALSE );
139
140 dialog_created = 1;
141 }
142
143 gtk_widget_show_all( dialog );
144
145 return 0;
146 }
147