Mercurial > audlegacy
annotate libaudacious/xentry.c @ 1021:1e6c0a3f2d15 trunk
[svn] - 2.1 beta
author | nenolod |
---|---|
date | Wed, 10 May 2006 14:44:20 -0700 |
parents | 0a73d1faeb4e |
children | f12d7e208b43 |
rev | line source |
---|---|
0 | 1 /* GTK - The GIMP Toolkit |
2 * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald | |
3 * | |
4 * This library is free software; you can redistribute it and/or | |
5 * modify it under the terms of the GNU Library General Public | |
6 * License as published by the Free Software Foundation; either | |
7 * version 2 of the License, or (at your option) any later version. | |
8 * | |
9 * This library 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 GNU | |
12 * Library General Public License for more details. | |
13 * | |
14 * You should have received a copy of the GNU Library General Public | |
15 * License along with this library; if not, write to the | |
16 * Free Software Foundation, Inc., 59 Temple Place - Suite 330, | |
17 * Boston, MA 02111-1307, USA. | |
18 */ | |
19 | |
20 /* | |
21 * Modified by the GTK+ Team and others 1997-1999. See the AUTHORS | |
22 * file for a list of people on the GTK+ Team. See the ChangeLog | |
23 * files for a list of changes. These files are distributed with | |
24 * GTK+ at ftp://ftp.gtk.org/pub/gtk/. | |
25 */ | |
26 | |
27 /* | |
28 * Small modification of the entry widget where keyboard navigation | |
29 * works even when the entry is not editable. | |
30 * Copyright 2003 Haavard Kvaalen <havardk@xmms.org> | |
31 */ | |
32 | |
33 #include <glib.h> | |
34 #include <gtk/gtk.h> | |
35 #include <gdk/gdkkeysyms.h> | |
36 #include <ctype.h> | |
37 #include <string.h> | |
38 | |
39 #include "xentry.h" | |
40 | |
41 static gint gtk_entry_key_press(GtkWidget * widget, GdkEventKey * event); | |
42 static void gtk_entry_move_cursor(GtkOldEditable * editable, int x); | |
43 | |
44 static void gtk_move_forward_character(GtkEntry * entry); | |
45 static void gtk_move_backward_character(GtkEntry * entry); | |
46 static void gtk_move_forward_word(GtkEntry * entry); | |
47 static void gtk_move_backward_word(GtkEntry * entry); | |
48 static void gtk_move_beginning_of_line(GtkEntry * entry); | |
49 static void gtk_move_end_of_line(GtkEntry * entry); | |
50 | |
51 | |
52 static const GtkTextFunction control_keys[26] = { | |
53 (GtkTextFunction) gtk_move_beginning_of_line, /* a */ | |
54 (GtkTextFunction) gtk_move_backward_character, /* b */ | |
55 (GtkTextFunction) gtk_editable_copy_clipboard, /* c */ | |
56 NULL, /* d */ | |
57 (GtkTextFunction) gtk_move_end_of_line, /* e */ | |
58 (GtkTextFunction) gtk_move_forward_character, /* f */ | |
59 }; | |
60 | |
61 static const GtkTextFunction alt_keys[26] = { | |
62 NULL, /* a */ | |
63 (GtkTextFunction) gtk_move_backward_word, /* b */ | |
64 NULL, /* c */ | |
65 NULL, /* d */ | |
66 NULL, /* e */ | |
67 (GtkTextFunction) gtk_move_forward_word, /* f */ | |
68 }; | |
69 | |
70 | |
71 static void | |
72 xmms_entry_class_init(GtkEntryClass * class) | |
73 { | |
74 GtkWidgetClass *widget_class = (GtkWidgetClass *) class; | |
75 | |
76 widget_class->key_press_event = gtk_entry_key_press; | |
77 } | |
78 | |
79 GtkType | |
80 xmms_entry_get_type(void) | |
81 { | |
82 static GtkType entry_type = 0; | |
83 | |
84 if (!entry_type) { | |
85 static const GtkTypeInfo entry_info = { | |
86 "XmmsEntry", | |
87 sizeof(XmmsEntry), | |
88 sizeof(XmmsEntryClass), | |
89 (GtkClassInitFunc) xmms_entry_class_init, | |
90 NULL, | |
91 /* reserved_1 */ NULL, | |
92 /* reserved_2 */ NULL, | |
93 (GtkClassInitFunc) NULL, | |
94 }; | |
95 | |
96 entry_type = gtk_type_unique(GTK_TYPE_ENTRY, &entry_info); | |
97 } | |
98 | |
99 return entry_type; | |
100 } | |
101 | |
102 GtkWidget * | |
103 xmms_entry_new(void) | |
104 { | |
105 return GTK_WIDGET(gtk_type_new(XMMS_TYPE_ENTRY)); | |
106 } | |
107 | |
108 static int | |
109 gtk_entry_key_press(GtkWidget * widget, GdkEventKey * event) | |
110 { | |
111 GtkEntry *entry; | |
112 GtkOldEditable *editable; | |
113 | |
114 int return_val; | |
115 guint initial_pos, sel_start_pos, sel_end_pos; | |
116 int extend_selection; | |
117 gboolean extend_start = FALSE; | |
118 | |
119 g_return_val_if_fail(widget != NULL, FALSE); | |
120 g_return_val_if_fail(XMMS_IS_ENTRY(widget), FALSE); | |
121 g_return_val_if_fail(event != NULL, FALSE); | |
122 | |
123 entry = GTK_ENTRY(widget); | |
124 editable = GTK_OLD_EDITABLE(widget); | |
125 return_val = FALSE; | |
126 | |
127 if (editable->editable) | |
128 /* Let the regular entry handler do it */ | |
129 return FALSE; | |
130 | |
131 initial_pos = gtk_editable_get_position(GTK_EDITABLE(editable)); | |
132 | |
133 extend_selection = event->state & GDK_SHIFT_MASK; | |
134 | |
135 sel_start_pos = editable->selection_start_pos; | |
136 sel_end_pos = editable->selection_end_pos; | |
137 | |
138 if (extend_selection) { | |
139 if (sel_start_pos == sel_end_pos) { | |
140 sel_start_pos = editable->current_pos; | |
141 sel_end_pos = editable->current_pos; | |
142 } | |
143 | |
144 extend_start = (editable->current_pos == sel_start_pos); | |
145 } | |
146 | |
147 switch (event->keyval) { | |
148 case GDK_Insert: | |
149 return_val = TRUE; | |
150 if (event->state & GDK_CONTROL_MASK) | |
151 gtk_editable_copy_clipboard(GTK_EDITABLE(editable)); | |
152 break; | |
153 case GDK_Home: | |
154 return_val = TRUE; | |
155 gtk_move_beginning_of_line(entry); | |
156 break; | |
157 case GDK_End: | |
158 return_val = TRUE; | |
159 gtk_move_end_of_line(entry); | |
160 break; | |
161 case GDK_Left: | |
162 return_val = TRUE; | |
163 if (!extend_selection && sel_start_pos != sel_end_pos) { | |
164 gtk_editable_set_position(GTK_EDITABLE(editable), | |
165 MIN(sel_start_pos, sel_end_pos)); | |
166 /* Force redraw below */ | |
167 initial_pos = -1; | |
168 } | |
169 else | |
170 gtk_move_backward_character(entry); | |
171 break; | |
172 case GDK_Right: | |
173 return_val = TRUE; | |
174 if (!extend_selection && sel_start_pos != sel_end_pos) { | |
175 gtk_editable_set_position(GTK_EDITABLE(editable), | |
176 MAX(sel_start_pos, sel_end_pos)); | |
177 /* Force redraw below */ | |
178 initial_pos = -1; | |
179 } | |
180 else | |
181 gtk_move_forward_character(entry); | |
182 break; | |
183 case GDK_Return: | |
184 return_val = TRUE; | |
185 gtk_widget_activate(widget); | |
186 break; | |
187 default: | |
188 if ((event->keyval >= 0x20) && (event->keyval <= 0xFF)) { | |
189 int key = event->keyval; | |
190 | |
191 if (key >= 'A' && key <= 'Z') | |
192 key -= 'A' - 'a'; | |
193 | |
194 if (key >= 'a' && key <= 'z') | |
195 key -= 'a'; | |
196 else | |
197 break; | |
198 | |
199 if (event->state & GDK_CONTROL_MASK) { | |
200 if (control_keys[key]) { | |
201 (*control_keys[key]) (editable, event->time); | |
202 return_val = TRUE; | |
203 } | |
204 break; | |
205 } | |
206 else if (event->state & GDK_MOD1_MASK) { | |
207 if (alt_keys[key]) { | |
208 (*alt_keys[key]) (editable, event->time); | |
209 return_val = TRUE; | |
210 } | |
211 break; | |
212 } | |
213 } | |
214 } | |
215 | |
216 if (return_val && (editable->current_pos != initial_pos)) { | |
217 if (extend_selection) { | |
625
0a73d1faeb4e
[svn] GCC 4.1 warning fixes by Diego 'Flameeyes' Petteno from Gentoo.
chainsaw
parents:
0
diff
changeset
|
218 size_t cpos = gtk_editable_get_position(GTK_EDITABLE(editable)); |
0 | 219 if (cpos < sel_start_pos) |
220 sel_start_pos = cpos; | |
221 else if (cpos > sel_end_pos) | |
222 sel_end_pos = cpos; | |
223 else { | |
224 if (extend_start) | |
225 sel_start_pos = cpos; | |
226 else | |
227 sel_end_pos = cpos; | |
228 } | |
229 } | |
230 else { | |
231 sel_start_pos = 0; | |
232 sel_end_pos = 0; | |
233 } | |
234 | |
235 gtk_editable_select_region(GTK_EDITABLE(editable), sel_start_pos, | |
236 sel_end_pos); | |
237 } | |
238 | |
239 return return_val; | |
240 } | |
241 | |
242 static void | |
243 gtk_entry_move_cursor(GtkOldEditable * editable, int x) | |
244 { | |
245 int set, pos = gtk_editable_get_position(GTK_EDITABLE(editable)); | |
246 if (pos + x < 0) | |
247 set = 0; | |
248 else | |
249 set = pos + x; | |
250 gtk_editable_set_position(GTK_EDITABLE(editable), set); | |
251 } | |
252 | |
253 static void | |
254 gtk_move_forward_character(GtkEntry * entry) | |
255 { | |
256 gtk_entry_move_cursor(GTK_OLD_EDITABLE(entry), 1); | |
257 } | |
258 | |
259 static void | |
260 gtk_move_backward_character(GtkEntry * entry) | |
261 { | |
262 gtk_entry_move_cursor(GTK_OLD_EDITABLE(entry), -1); | |
263 } | |
264 | |
265 static void | |
266 gtk_move_forward_word(GtkEntry * entry) | |
267 { | |
268 GtkOldEditable *editable; | |
269 GdkWChar *text; | |
270 int i; | |
271 | |
272 editable = GTK_OLD_EDITABLE(entry); | |
273 | |
274 /* Prevent any leak of information */ | |
275 if (!editable->visible) { | |
276 gtk_editable_set_position(GTK_EDITABLE(entry), -1); | |
277 return; | |
278 } | |
279 | |
280 if (entry->text && (editable->current_pos < entry->text_length)) { | |
281 text = (GdkWChar *) entry->text; | |
282 i = editable->current_pos; | |
283 | |
284 /* if ((entry->use_wchar && !gdk_iswalnum(text[i])) || | |
285 !isalnum(text[i])) | |
286 for (; i < entry->text_length; i++) | |
287 { | |
288 if (entry->use_wchar) | |
289 { | |
290 if (gdk_iswalnum(text[i])) | |
291 break; | |
292 else if (isalnum(text[i])) | |
293 break; | |
294 } | |
295 } | |
296 | |
297 for (; i < entry->text_length; i++) | |
298 { | |
299 if (entry->use_wchar) | |
300 { | |
301 if (gdk_iswalnum(text[i])) | |
302 break; | |
303 else if (isalnum(text[i])) | |
304 break; | |
305 } | |
306 } | |
307 | |
308 */ | |
309 | |
310 gtk_editable_set_position(GTK_EDITABLE(entry), i); | |
311 } | |
312 } | |
313 | |
314 static void | |
315 gtk_move_backward_word(GtkEntry * entry) | |
316 { | |
317 GtkOldEditable *editable; | |
318 GdkWChar *text; | |
319 int i; | |
320 | |
321 editable = GTK_OLD_EDITABLE(entry); | |
322 | |
323 /* Prevent any leak of information */ | |
324 if (!editable->visible) { | |
325 gtk_editable_set_position(GTK_EDITABLE(entry), 0); | |
326 return; | |
327 } | |
328 | |
329 if (entry->text && editable->current_pos > 0) { | |
330 text = (GdkWChar *) entry->text; | |
331 i = editable->current_pos; | |
332 | |
333 /* if ((entry->use_wchar && !gdk_iswalnum(text[i])) || | |
334 !isalnum(text[i])) | |
335 for (; i >= 0; i--) | |
336 { | |
337 if (entry->use_wchar) | |
338 { | |
339 if (gdk_iswalnum(text[i])) | |
340 break; | |
341 else if (isalnum(text[i])) | |
342 break; | |
343 } | |
344 } | |
345 for (; i >= 0; i--) | |
346 { | |
347 if ((entry->use_wchar && !gdk_iswalnum(text[i])) || | |
348 !isalnum(text[i])) | |
349 { | |
350 i++; | |
351 break; | |
352 } | |
353 } | |
354 */ | |
355 if (i < 0) | |
356 i = 0; | |
357 | |
358 gtk_editable_set_position(GTK_EDITABLE(entry), i); | |
359 } | |
360 } | |
361 | |
362 static void | |
363 gtk_move_beginning_of_line(GtkEntry * entry) | |
364 { | |
365 gtk_editable_set_position(GTK_EDITABLE(entry), 0); | |
366 } | |
367 | |
368 static void | |
369 gtk_move_end_of_line(GtkEntry * entry) | |
370 { | |
371 gtk_editable_set_position(GTK_EDITABLE(entry), -1); | |
372 } |