Mercurial > audlegacy
annotate libaudacious/xentry.c @ 713:cf7b5a288564 trunk
[svn] rule for installing data
| author | nenolod |
|---|---|
| date | Sun, 26 Feb 2006 20:14:08 -0800 |
| 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 } |
