/* This is the 'high level' hotspot function that will usually be called * by the widget code. * * It rebuilds the hotspot graph from the current divtree if necessary, finds * the hotspot closest to the mouse pointer, traverses the hotspot graph in * the indicated direction, and finds the new mouse pointer position. * * The direction is a HOTSPOT_* constant */ void hotspot_traverse(short direction) { struct hotspot *p; int x,y; struct divtree *dt; /* rebuild the graph */ if (!hotspotlist) { hotspot_build(dts->top->head,NULL); if (popup_toolbar_passthrough()) hotspot_build(dts->root->head,appmgr_nontoolbar_area()); hotspot_graph(); } /* Create the hotspotnav cursor if it doesn't exist */ if (!dts->top->hotspot_cursor) if (iserror(cursor_new(&dts->top->hotspot_cursor,NULL,-1))) return; /* Find the current node */ cursor_getposition(dts->top->hotspot_cursor,&x,&y,&dt); p = hotspot_closest(x,y); if (!p) return; /* If the closest node isn't really that close, just warp to * that closest node. Otherwise, traverse. * * NOTE: We used to test whether the hotspot cursor was within * the same divnode as the hotspot, but now that the hotspot cursor * is separate from all driver-controlled cursors we can do an * exact match. */ if (x==p->x && y==p->y) { /* traverse */ p = p->graph[direction]; if (!p) return; } /* Make sure the divnode is scrolled in and focused now */ if (p->div) request_focus(p->div->owner); /* Warp the hotspot cursor to the new hotspot location */ cursor_move(dts->top->hotspot_cursor,p->x,p->y,dt); }
static void recv_evt(mrp_transport_t *t, void *data, uint32_t type_id, void *user_data) { client_t *c = (client_t *)user_data; srs_msg_t *req = (srs_msg_t *)data; MRP_UNUSED(t); dump_message(data, type_id); switch (req->type) { case SRS_REQUEST_REGISTER: register_client(c, &req->reg_req); break; case SRS_REQUEST_UNREGISTER: unregister_client(c, &req->bye_req); break; case SRS_REQUEST_FOCUS: request_focus(c, &req->focus_req); break; case SRS_REQUEST_RENDERVOICE: request_voice(c, &req->voice_req); break; case SRS_REQUEST_CANCELVOICE: cancel_voice(c, &req->voice_ccl); break; case SRS_REQUEST_QUERYVOICES: query_voices(c, &req->voice_qry); break; default: break; } }
void textedit_trigger ( struct widget *self, s32 type, union trigparam *param) { int key; struct cursor * c; u32 v_height, v_top; struct font_metrics m; switch (type) { case PG_TRIGGER_DEACTIVATE: UNSET_FLAG(DATA->flags, TEXT_WIDGET_FOCUS); UNSET_FLAG(DATA->flags, TEXT_WIDGET_FLASH_ON); break; case PG_TRIGGER_ACTIVATE: SET_FLAG(DATA->flags, TEXT_WIDGET_FOCUS); SET_FLAG(DATA->flags, TEXT_WIDGET_FLASH_ON); post_event(PG_WE_FOCUS,self,1,0,NULL); /* Fall into PG_TRIGGER_TIMER to set up cursor flash */ case PG_TRIGGER_TIMER: if (!DATA->cursor_state) DATA->cursor_state++; else DATA->cursor_state--; DATA->cursor_grop->param[0] = VID(color_pgtohwr)(DATA->cursor_state ? CURSORCOLOR_ON : CURSORCOLOR_OFF ); add_update_region(self, DATA->cursor_grop->r.x, DATA->cursor_grop->r.y, DATA->cursor_grop->r.w, DATA->cursor_grop->r.h); if (GET_FLAG(DATA->flags, TEXT_WIDGET_FLASH_ON)) { /* Reset timer */ DATA->cursor_grop->r.w = CURSORWIDTH; install_timer(self, (DATA->cursor_state ? FLASHTIME_ON : FLASHTIME_OFF )); } else { DATA->cursor_grop->r.w = 0; } break; case PG_TRIGGER_DOWN: if (!GET_FLAG(DATA->flags, TEXT_WIDGET_FOCUS)) request_focus(self); if (!GET_FLAG(DATA->flags, TEXT_WIDGET_READONLY)) { if (param->mouse.x - self->in->div->r.x < DATA->width) { /* Move cursor. */ DATA->thumb_drag_start = -1; text_backend_cursor_move_xy ( DATA, param->mouse.x - self->in->div->r.x, param->mouse.y - self->in->div->r.y); grop_render(self->in->div, NULL); } else { text_backend_selection_unset(DATA); v_height = MAX(DATA->v_height, DATA->cursor_v_y + DATA->cursor_grop->r.h); /* In scrollbar region */ if ((param->mouse.y - self->in->div->r.y < DATA->thumb_top) || (param->mouse.y - self->in->div->r.y > DATA->thumb_top + DATA->thumb_size)) { /* Page up or down */ if (param->mouse.y - self->in->div->r.y < DATA->thumb_top) DATA->thumb_top -= DATA->thumb_size; else DATA->thumb_top += DATA->thumb_size; DATA->thumb_top = MAX(0, MIN(DATA->thumb_top, DATA->height - DATA->thumb_size)); v_top = (v_height * DATA->thumb_top) / DATA->height; /* Round to full screen lines */ DATA->fd->lib->getmetrics(DATA->fd,&m); if (v_top % m.lineheight) { v_top = (v_top - v_top % m.lineheight) + m.lineheight; } if (v_top != DATA->v_y_top) { DATA->scroll_lock = 1; text_backend_set_v_top(DATA, v_top); DATA->scroll_lock = 0; } div_rebuild(self->in->div->div); update(NULL,1); } else { DATA->thumb_drag_start = (param->mouse.y - self->in->div->r.y) - DATA->thumb_top; } } } break; case PG_TRIGGER_DRAG: if (param->mouse.btn) { if (DATA->thumb_drag_start < 0) { text_backend_selection_xy( DATA, param->mouse.x - self->in->div->r.x, param->mouse.y - self->in->div->r.y ); } else { v_height = MAX(DATA->v_height, DATA->cursor_v_y + DATA->cursor_grop->r.h); DATA->thumb_top = param->mouse.y - self->in->div->r.y - DATA->thumb_drag_start; DATA->thumb_top = MAX(0, MIN(DATA->thumb_top, DATA->height - DATA->thumb_size)); DATA->thumb_drag_start = param->mouse.y - self->in->div->r.y - DATA->thumb_top; v_top = (v_height * DATA->thumb_top) / DATA->height; /* Round to full screen lines */ DATA->fd->lib->getmetrics(DATA->fd,&m); if (v_top % m.lineheight) { v_top = (v_top - v_top % m.lineheight) + m.lineheight; } if (v_top != DATA->v_y_top) { DATA->scroll_lock = 1; text_backend_set_v_top(DATA, v_top); DATA->scroll_lock = 0; } div_rebuild(self->in->div->div); update(NULL,1); } } break; case PG_TRIGGER_KEYUP: if (GET_FLAG(DATA->flags, TEXT_WIDGET_READONLY) || !GET_FLAG(DATA->flags, TEXT_WIDGET_FOCUS)) return; param->kbd.consume++; return; case PG_TRIGGER_KEYDOWN: if (GET_FLAG(DATA->flags, TEXT_WIDGET_READONLY) || !GET_FLAG(DATA->flags, TEXT_WIDGET_FOCUS)) return; param->kbd.consume++; key = param->kbd.key; switch(key) { #ifdef DEBUG_TEXTEDIT case PGKEY_F1: print_data(DATA); break; case PGKEY_F2: print_tree(DATA); break; case PGKEY_F3: print_block(DATA, DATA->current); break; #endif /* DEBUG_TEXTEDIT */ case PGKEY_RETURN: text_backend_insert_char(DATA, '\n'); break; case PGKEY_BACKSPACE: case PGKEY_DELETE: /* Screw "backspace" vs. "delete". This is my widget, and * I say they're going to be the same thing. So, there. */ text_backend_delete_char(DATA); break; case PGKEY_TAB: if (param->kbd.mods & PGMOD_SHIFT) { /* Post event to app */ post_event(PG_WE_ACTIVATE,self,0,0,NULL); param->kbd.consume--; return; } else { text_backend_insert_char(DATA, '\t'); } break; case PGKEY_UP: case PGKEY_DOWN: case PGKEY_RIGHT: case PGKEY_LEFT: case PGKEY_HOME: case PGKEY_END: case PGKEY_PAGEUP: case PGKEY_PAGEDOWN: /* CURSOR_UP etc. match the PGKEY_UP etc. values */ if (param->kbd.mods & PGMOD_SHIFT) text_backend_selection_dir(DATA, key); else text_backend_cursor_move_dir(DATA, key); break; default: if ((key >= PGKEY_SPACE) && (key <= PGKEY_WORLD_95)) { if (param->kbd.mods & (PGMOD_SHIFT | PGMOD_CAPS)) { key = upper(key); } /* if ctrl key is pressed*/ if (param->kbd.mods & PGMOD_CTRL) { text_backend_cut_copy_paste(DATA, key); } else { text_backend_insert_char(DATA, key); } } else { /* Post key to app */ post_event(PG_WE_ACTIVATE,self,0,0,NULL); param->kbd.consume--; return; } } } textedit_draw_update(self); //update(NULL,1); }
void text_grab_focus(Text *text, Object *object) { text->focus.obj = object; request_focus(&text->focus); }
static void execute_user_command(client_t *c, int narg, char **args) { const char *cmd; cmd = args[0]; narg--; args++; switch (narg) { case 0: if (!strcmp(cmd, "register")) register_client(c); else if (!strcmp(cmd, "unregister")) unregister_client(c); else if (!strcmp(cmd, "exit")) quit_mainloop(c, 0); else if (!strcmp(cmd, "quit")) quit_mainloop(c, 0); else if (!strcmp(cmd, "help")) { print(c, "Available commands:"); print(c, " register - register to server"); print(c, " unregister - unregister from server"); print(c, " focus none|shared|exclusive - request voice focus"); print(c, " add command <command> - add new command"); print(c, " del command <command> - delete a command"); print(c, " render tts '<msg>' \\ - request TTS of <msg>"); print(c, " [-voice:<voice>] \\"); print(c, " [-timeout:<timeout>]\\"); print(c, " [-events]"); print(c, " cancel tts '<id>' - cancel given TTS " "request"); print(c, " list commands - list commands set"); print(c, " list voices - list available voices"); print(c, " help - show this help"); print(c, " exit - exit from client"); } else print(c, "Unknown command '%s'.", cmd); break; case 1: if (!strcmp(cmd, "focus")) { if (strcmp(args[0], "none") && strcmp(args[0], "shared") && strcmp(args[0], "exclusive")) { print(c, "Invalid focus '%s', valid foci are: " "none, shared, and exclusive.", args[0]); } else request_focus(c, args[0]); } else if (!strcmp(cmd, "reset") && !strcmp(args[0], "commands")) reset_commands(c); else if (!strcmp(cmd, "list" ) && !strcmp(args[0], "commands")) list_commands(c); else if (!strcmp(cmd, "list" ) && !strcmp(args[0], "voices")) query_voices(c, NULL); else if (!strcmp(cmd, "cancel" ) && !strcmp(args[0], "tts")) cancel_tts(c, 0, NULL); else print(c, "Invalid command."); break; case 2: if (!strcmp(cmd, "list" ) && !strcmp(args[0], "voices")) query_voices(c, args[1]); else if (!strcmp(cmd, "cancel")) cancel_tts(c, narg-1, args+1); else print(c, "Invalid command."); break; default: if (!strcmp(args[0], "command")) { if (!strcmp(cmd, "add" )) add_command(c, narg-1, args+1); else if (!strcmp(cmd, "del" ) || !strcmp(cmd, "delete")) del_command(c, narg-1, args+1); else print(c, "Invalid command."); } else if (!strcmp(args[0], "tts")) { if (!strcmp(cmd, "render")) request_tts(c, narg-1, args+1); else print(c, "Invalid TTS command."); } else print(c, "Invalid command."); break; } }