/** Routine called when text events occour in writeable widget. * * @param widget The widget reciving input events. * @param cbi The callback parameters. * @return The callback result. */ static int text_input(fbtk_widget_t *widget, fbtk_callback_info *cbi) { int value; static uint8_t modifier = 0; char *temp; if (cbi->event == NULL) { /* gain focus */ if (widget->u.text.text == NULL) widget->u.text.text = calloc(1,1); widget->u.text.idx = strlen(widget->u.text.text); fbtk_request_redraw(widget); return 0; } value = cbi->event->value.keycode; if (cbi->event->type != NSFB_EVENT_KEY_DOWN) { switch (value) { case NSFB_KEY_RSHIFT: modifier &= ~1; break; case NSFB_KEY_LSHIFT: modifier &= ~(1<<1); break; default: break; } return 0; } switch (value) { case NSFB_KEY_BACKSPACE: if (widget->u.text.idx <= 0) break; widget->u.text.idx--; widget->u.text.text[widget->u.text.idx] = 0; break; case NSFB_KEY_RETURN: widget->u.text.enter(widget->u.text.pw, widget->u.text.text); break; case NSFB_KEY_PAGEUP: case NSFB_KEY_PAGEDOWN: case NSFB_KEY_RIGHT: case NSFB_KEY_LEFT: case NSFB_KEY_UP: case NSFB_KEY_DOWN: /* Not handling any of these correctly yet, but avoid putting * charcters in the text widget when they're pressed. */ break; case NSFB_KEY_RSHIFT: modifier |= 1; break; case NSFB_KEY_LSHIFT: modifier |= 1<<1; break; default: /* allow for new character and null */ temp = realloc(widget->u.text.text, widget->u.text.idx + 2); if (temp != NULL) { widget->u.text.text = temp; widget->u.text.text[widget->u.text.idx] = fbtk_keycode_to_ucs4(value, modifier); widget->u.text.text[widget->u.text.idx + 1] = '\0'; widget->u.text.idx++; } break; } fbtk_request_redraw(widget); return 0; }
static int fb_browser_window_input(fbtk_widget_t *widget, fbtk_callback_info *cbi) { struct gui_window *gw = cbi->context; static fbtk_modifier_type modifier = FBTK_MOD_CLEAR; int ucs4 = -1; LOG(("got value %d", cbi->event->value.keycode)); switch (cbi->event->type) { case NSFB_EVENT_KEY_DOWN: switch (cbi->event->value.keycode) { case NSFB_KEY_DELETE: browser_window_key_press(gw->bw, KEY_DELETE_RIGHT); break; case NSFB_KEY_PAGEUP: if (browser_window_key_press(gw->bw, KEY_PAGE_UP) == false) widget_scroll_y(gw, -fbtk_get_height( gw->browser), false); break; case NSFB_KEY_PAGEDOWN: if (browser_window_key_press(gw->bw, KEY_PAGE_DOWN) == false) widget_scroll_y(gw, fbtk_get_height( gw->browser), false); break; case NSFB_KEY_RIGHT: if (modifier & FBTK_MOD_RCTRL || modifier & FBTK_MOD_LCTRL) { /* CTRL held */ if (browser_window_key_press(gw->bw, KEY_LINE_END) == false) widget_scroll_x(gw, INT_MAX, true); } else if (modifier & FBTK_MOD_RSHIFT || modifier & FBTK_MOD_LSHIFT) { /* SHIFT held */ if (browser_window_key_press(gw->bw, KEY_WORD_RIGHT) == false) widget_scroll_x(gw, fbtk_get_width( gw->browser), false); } else { /* no modifier */ if (browser_window_key_press(gw->bw, KEY_RIGHT) == false) widget_scroll_x(gw, 100, false); } break; case NSFB_KEY_LEFT: if (modifier & FBTK_MOD_RCTRL || modifier & FBTK_MOD_LCTRL) { /* CTRL held */ if (browser_window_key_press(gw->bw, KEY_LINE_START) == false) widget_scroll_x(gw, 0, true); } else if (modifier & FBTK_MOD_RSHIFT || modifier & FBTK_MOD_LSHIFT) { /* SHIFT held */ if (browser_window_key_press(gw->bw, KEY_WORD_LEFT) == false) widget_scroll_x(gw, -fbtk_get_width( gw->browser), false); } else { /* no modifier */ if (browser_window_key_press(gw->bw, KEY_LEFT) == false) widget_scroll_x(gw, -100, false); } break; case NSFB_KEY_UP: if (browser_window_key_press(gw->bw, KEY_UP) == false) widget_scroll_y(gw, -100, false); break; case NSFB_KEY_DOWN: if (browser_window_key_press(gw->bw, KEY_DOWN) == false) widget_scroll_y(gw, 100, false); break; case NSFB_KEY_RSHIFT: modifier |= FBTK_MOD_RSHIFT; break; case NSFB_KEY_LSHIFT: modifier |= FBTK_MOD_LSHIFT; break; case NSFB_KEY_RCTRL: modifier |= FBTK_MOD_RCTRL; break; case NSFB_KEY_LCTRL: modifier |= FBTK_MOD_LCTRL; break; case NSFB_KEY_y: case NSFB_KEY_z: if (cbi->event->value.keycode == NSFB_KEY_z && (modifier & FBTK_MOD_RCTRL || modifier & FBTK_MOD_LCTRL) && (modifier & FBTK_MOD_RSHIFT || modifier & FBTK_MOD_LSHIFT)) { /* Z pressed with CTRL and SHIFT held */ browser_window_key_press(gw->bw, KEY_REDO); break; } else if (cbi->event->value.keycode == NSFB_KEY_z && (modifier & FBTK_MOD_RCTRL || modifier & FBTK_MOD_LCTRL)) { /* Z pressed with CTRL held */ browser_window_key_press(gw->bw, KEY_UNDO); break; } else if (cbi->event->value.keycode == NSFB_KEY_y && (modifier & FBTK_MOD_RCTRL || modifier & FBTK_MOD_LCTRL)) { /* Y pressed with CTRL held */ browser_window_key_press(gw->bw, KEY_REDO); break; } /* Z or Y pressed but not undo or redo; * Fall through to default handling */ default: ucs4 = fbtk_keycode_to_ucs4(cbi->event->value.keycode, modifier); if (ucs4 != -1) browser_window_key_press(gw->bw, ucs4); break; } break; case NSFB_EVENT_KEY_UP: switch (cbi->event->value.keycode) { case NSFB_KEY_RSHIFT: modifier &= ~FBTK_MOD_RSHIFT; break; case NSFB_KEY_LSHIFT: modifier &= ~FBTK_MOD_LSHIFT; break; case NSFB_KEY_RCTRL: modifier &= ~FBTK_MOD_RCTRL; break; case NSFB_KEY_LCTRL: modifier &= ~FBTK_MOD_LCTRL; break; default: break; } break; default: break; } return 0; }
/** Routine called when text events occour in writeable widget. * * @param widget The widget reciving input events. * @param cbi The callback parameters. * @return The callback result. */ static int text_input(fbtk_widget_t *widget, fbtk_callback_info *cbi) { int value; static fbtk_modifier_type modifier = FBTK_MOD_CLEAR; char *temp; plot_font_style_t font_style; int fh; int border; bool caret_moved = false; fb_text_font_style(widget, &fh, &border, &font_style); if (cbi->event == NULL) { /* gain focus */ if (widget->u.text.text == NULL) widget->u.text.text = calloc(1,1); return 0; } value = cbi->event->value.keycode; if (cbi->event->type != NSFB_EVENT_KEY_DOWN) { switch (value) { case NSFB_KEY_RSHIFT: modifier &= ~FBTK_MOD_RSHIFT; break; case NSFB_KEY_LSHIFT: modifier &= ~FBTK_MOD_LSHIFT; break; case NSFB_KEY_RCTRL: modifier &= ~FBTK_MOD_RCTRL; break; case NSFB_KEY_LCTRL: modifier &= ~FBTK_MOD_LCTRL; break; default: break; } return 0; } switch (value) { case NSFB_KEY_BACKSPACE: if (widget->u.text.idx <= 0) break; memmove(widget->u.text.text + widget->u.text.idx - 1, widget->u.text.text + widget->u.text.idx, widget->u.text.len - widget->u.text.idx); widget->u.text.idx--; widget->u.text.len--; widget->u.text.text[widget->u.text.len] = 0; nsfont.font_width(&font_style, widget->u.text.text, widget->u.text.len, &widget->u.text.width); caret_moved = true; break; case NSFB_KEY_RETURN: widget->u.text.enter(widget->u.text.pw, widget->u.text.text); break; case NSFB_KEY_RIGHT: if (widget->u.text.idx < widget->u.text.len) { if (modifier == FBTK_MOD_CLEAR) widget->u.text.idx++; else widget->u.text.idx = widget->u.text.len; caret_moved = true; } break; case NSFB_KEY_LEFT: if (widget->u.text.idx > 0) { if (modifier == FBTK_MOD_CLEAR) widget->u.text.idx--; else widget->u.text.idx = 0; caret_moved = true; } break; case NSFB_KEY_PAGEUP: case NSFB_KEY_PAGEDOWN: case NSFB_KEY_UP: case NSFB_KEY_DOWN: /* Not handling any of these correctly yet, but avoid putting * charcters in the text widget when they're pressed. */ break; case NSFB_KEY_RSHIFT: modifier |= FBTK_MOD_RSHIFT; break; case NSFB_KEY_LSHIFT: modifier |= FBTK_MOD_LSHIFT; break; case NSFB_KEY_RCTRL: modifier |= FBTK_MOD_RCTRL; break; case NSFB_KEY_LCTRL: modifier |= FBTK_MOD_LCTRL; break; default: if (modifier & FBTK_MOD_LCTRL || modifier & FBTK_MOD_RCTRL) { /* CTRL pressed, don't enter any text */ if (value == NSFB_KEY_u) { /* CTRL+U: clear writable */ widget->u.text.idx = 0; widget->u.text.len = 0; widget->u.text.text[widget->u.text.len] = '\0'; widget->u.text.width = 0; caret_moved = true; } break; } /* allow for new character and null */ temp = realloc(widget->u.text.text, widget->u.text.len + 2); if (temp == NULL) { break; } widget->u.text.text = temp; memmove(widget->u.text.text + widget->u.text.idx + 1, widget->u.text.text + widget->u.text.idx, widget->u.text.len - widget->u.text.idx); widget->u.text.text[widget->u.text.idx] = fbtk_keycode_to_ucs4(value, modifier); widget->u.text.idx++; widget->u.text.len++; widget->u.text.text[widget->u.text.len] = '\0'; nsfont.font_width(&font_style, widget->u.text.text, widget->u.text.len, &widget->u.text.width); caret_moved = true; break; } if (caret_moved) { nsfont.font_width(&font_style, widget->u.text.text, widget->u.text.idx, &widget->u.text.idx_offset); fbtk_set_caret(widget, true, widget->u.text.idx_offset + border, border, widget->height - border - border, fb_text_input_remove_caret_cb); } fbtk_request_redraw(widget); return 0; }