void LineEdit::selection_delete() { if (selection.enabled) delete_text(selection.begin,selection.end); selection_clear(); }
void LineEdit::select(int p_from, int p_to) { if (p_from==0 && p_to==0) { selection_clear(); return; } int len = text.length(); if (p_from<0) p_from=0; if (p_from>len) p_from=len; if (p_to<0 || p_to>len) p_to=len; if (p_from>=p_to) return; selection.enabled=true; selection.begin=p_from; selection.end=p_to; selection.creating=false; selection.doubleclick=false; update(); }
/* * Redraw window after exposure or size change */ static void resize_window1 (unsigned int width, unsigned int height) { static short first_time = 1; int new_ncol = (width - szHint.base_width) / TermWin.fwidth; int new_nrow = (height - szHint.base_height) / TermWin.fheight; if (first_time || (new_ncol != TermWin.ncol) || (new_nrow != TermWin.nrow)) { int curr_screen = -1; /* scr_reset only works on the primary screen */ if (!first_time) /* this is not the first time thru */ { selection_clear (); curr_screen = scr_change_screen (PRIMARY); } TermWin.ncol = new_ncol; TermWin.nrow = new_nrow; resize_subwindows (width, height); scr_reset (); if (curr_screen >= 0) /* this is not the first time thru */ scr_change_screen (curr_screen); first_time = 0; } }
void LineEdit::shift_selection_check_pre(bool p_shift) { if (!selection.enabled && p_shift) { selection.cursor_start=cursor_pos; } if (!p_shift) selection_clear(); }
/** * Handle key presses in a browser window. * * \param bw The root browser window * \param key The UCS4 character codepoint * \return true if key handled, false otherwise */ bool browser_window_key_press(struct browser_window *bw, uint32_t key) { struct browser_window *focus = bw->focus; assert(bw->window != NULL); /* keys that take effect wherever the caret is positioned */ switch (key) { case KEY_SELECT_ALL: selection_select_all(bw->cur_sel); return true; case KEY_COPY_SELECTION: gui_copy_to_clipboard(bw->cur_sel); return true; case KEY_CLEAR_SELECTION: selection_clear(bw->cur_sel, true); return true; case KEY_ESCAPE: if (bw->cur_sel && selection_defined(bw->cur_sel)) { selection_clear(bw->cur_sel, true); return true; } /* if there's no selection, * leave Escape for the caller */ return false; } /* pass on to the appropriate field */ if (!focus->caret_callback) return false; return focus->caret_callback(focus, key, focus->caret_p1, focus->caret_p2); }
LineEdit::LineEdit() { align = ALIGN_LEFT; cached_width = 0; cursor_pos=0; window_pos=0; window_has_focus=true; max_length = 0; pass=false; placeholder_alpha=0.6; selection_clear(); set_focus_mode( FOCUS_ALL ); editable=true; set_default_cursor_shape(CURSOR_IBEAM); set_stop_mouse(true); draw_caret=true; caret_blink_enabled=false; caret_blink_timer = memnew(Timer); add_child(caret_blink_timer); caret_blink_timer->set_wait_time(0.65); caret_blink_timer->connect("timeout", this,"_toggle_draw_caret"); cursor_set_blink_enabled(false); menu = memnew( PopupMenu ); add_child(menu); menu->add_item(TTR("Cut"),MENU_CUT,KEY_MASK_CMD|KEY_X); menu->add_item(TTR("Copy"),MENU_COPY,KEY_MASK_CMD|KEY_C); menu->add_item(TTR("Paste"),MENU_PASTE,KEY_MASK_CMD|KEY_V); menu->add_separator(); menu->add_item(TTR("Select All"),MENU_SELECT_ALL,KEY_MASK_CMD|KEY_A); menu->add_item(TTR("Clear"),MENU_CLEAR); menu->add_separator(); menu->add_item(TTR("Undo"),MENU_UNDO,KEY_MASK_CMD|KEY_Z); menu->connect("item_pressed",this,"menu_option"); expand_to_text_length=false; }
static void free_matches(struct search_context *context) { struct list_entry *a; struct list_entry *b; a = context->found->next; /* empty the list before clearing and deleting the * selections because the the clearing updates the * screen immediately, causing nested accesses to the list */ context->found->prev = NULL; context->found->next = NULL; for (; a; a = b) { b = a->next; if (a->sel) { selection_clear(a->sel, true); selection_destroy(a->sel); } free(a); } }
/* Exported function documented in search.h */ void search_show_all(bool all, struct search_context *context) { struct list_entry *a; for (a = context->found->next; a; a = a->next) { bool add = true; if (!all && a != context->current) { add = false; if (a->sel) { selection_clear(a->sel, true); selection_destroy(a->sel); a->sel = NULL; } } if (add && !a->sel) { if (context->is_html == true) { html_content *html = (html_content *)context->c; a->sel = selection_create(context->c, true); if (!a->sel) continue; selection_init(a->sel, html->layout, &html->len_ctx); } else { a->sel = selection_create(context->c, false); if (!a->sel) continue; selection_init(a->sel, NULL, NULL); } selection_set_start(a->sel, a->start_idx); selection_set_end(a->sel, a->end_idx); } } }
/* read an X event */ void ReadXServer (void) { static XEvent event; int old_cursor = 0, keypress; Item *item, *old_item; KeySym ks; char *sp, *dp; static unsigned char buf[10]; /* unsigned for international */ static int n; while (FEventsQueued(dpy, QueuedAfterReading)) { FNextEvent(dpy, &event); if (event.xany.window == CF.frame) { switch (event.type) { case ClientMessage: { if(event.xclient.format == 32 && event.xclient.data.l[0] == wm_del_win) { exit(0); } } break; case ConfigureNotify: /* has window be reconfigured */ { XEvent tmpe; while (FCheckTypedWindowEvent( dpy, CF.frame, ConfigureNotify, &tmpe)) { if (!tmpe.xconfigure.send_event) continue; event.xconfigure.x = tmpe.xconfigure.x; event.xconfigure.y = tmpe.xconfigure.y; event.xconfigure.send_event = True; } if (CF.max_width != event.xconfigure.width || CF.total_height != event.xconfigure.height) { /* adjust yourself... do noting */ ResizeFrame(); CF.max_width = event.xconfigure.width; CF.total_height = event.xconfigure.height; UpdateRootTransapency(False, True); if (!CSET_IS_TRANSPARENT(colorset)) { RedrawFrame(NULL); } } else if (event.xconfigure.send_event) { UpdateRootTransapency(False, True); } } break; #if 0 case SelectionClear: selection_clear (); break; case SelectionNotify: selection_paste (); break; case SelectionRequest: selection_send (); break; #endif case Expose: { int ex = event.xexpose.x; int ey = event.xexpose.y; int ex2 = event.xexpose.x + event.xexpose.width; int ey2 = event.xexpose.y + event.xexpose.height; while (FCheckTypedWindowEvent(dpy, CF.frame, Expose, &event)) { ex = min(ex, event.xexpose.x); ey = min(ey, event.xexpose.y); ex2 = max(ex2, event.xexpose.x + event.xexpose.width); ey2 = max(ey2 , event.xexpose.y + event.xexpose.height); } event.xexpose.x = ex; event.xexpose.y = ey; event.xexpose.width = ex2 - ex; event.xexpose.height = ey2 - ey; RedrawFrame(&event); if (CF.grab_server && !CF.server_grabbed) { if (GrabSuccess == XGrabPointer(dpy, CF.frame, True, 0, GrabModeAsync, GrabModeAsync, None, None, CurrentTime)) CF.server_grabbed = 1; } } break; case VisibilityNotify: if (CF.server_grabbed && event.xvisibility.state != VisibilityUnobscured) { /* raise our window to the top */ XRaiseWindow(dpy, CF.frame); XSync(dpy, 0); } break; case KeyPress: /* we do text input here */ n = XLookupString(&event.xkey, (char *)buf, sizeof(buf), &ks, NULL); keypress = buf[0]; myfprintf((stderr, "Keypress [%s]\n", buf)); if (n == 0) { /* not a regular key, translate it into one */ switch (ks) { case XK_Home: case XK_Begin: buf[0] = '\001'; /* ^A */ break; case XK_End: buf[0] = '\005'; /* ^E */ break; case XK_Left: buf[0] = '\002'; /* ^B */ break; case XK_Right: buf[0] = '\006'; /* ^F */ break; case XK_Up: buf[0] = '\020'; /* ^P */ break; case XK_Down: buf[0] = '\016'; /* ^N */ break; default: if (ks >= XK_F1 && ks <= XK_F35) { buf[0] = '\0'; keypress = 257 + ks - XK_F1; } else goto no_redraw; /* no action for this event */ } } switch (ks) { /* regular key, may need adjustment */ case XK_Tab: #ifdef XK_XKB_KEYS case XK_ISO_Left_Tab: #endif if (event.xkey.state & ShiftMask) { /* shifted key */ buf[0] = '\020'; /* chg shift tab to ^P */ } break; case '>': if (event.xkey.state & Mod1Mask) { /* Meta, shift > */ process_history(1); goto redraw_newcursor; } break; case '<': if (event.xkey.state & Mod1Mask) { /* Meta, shift < */ process_history(-1); goto redraw_newcursor; } break; } if (!CF.cur_input) { /* no text input fields */ for (item = root_item_ptr; item != 0; item = item->header.next) {/* all items */ if (item->type == I_BUTTON && item->button.keypress == keypress) { RedrawItem(item, 1, NULL); usleep(MICRO_S_FOR_10MS); RedrawItem(item, 0, NULL); DoCommand(item); goto no_redraw; } } break; } else if (CF.cur_input == CF.cur_input->input.next_input) { /* 1 ip field */ switch (buf[0]) { case '\020': /* ^P previous field */ process_history(-1); goto redraw_newcursor; break; case '\016': /* ^N next field */ process_history(1); goto redraw_newcursor; break; } /* end switch */ } /* end one input field */ switch (buf[0]) { case '\001': /* ^A */ old_cursor = CF.abs_cursor; CF.rel_cursor = 0; CF.abs_cursor = 0; CF.cur_input->input.left = 0; goto redraw_newcursor; break; case '\005': /* ^E */ old_cursor = CF.abs_cursor; CF.rel_cursor = CF.cur_input->input.n; if ((CF.cur_input->input.left = CF.rel_cursor - CF.cur_input->input.size) < 0) CF.cur_input->input.left = 0; CF.abs_cursor = CF.rel_cursor - CF.cur_input->input.left; goto redraw_newcursor; break; case '\002': /* ^B */ old_cursor = CF.abs_cursor; if (CF.rel_cursor > 0) { CF.rel_cursor--; CF.abs_cursor--; if (CF.abs_cursor <= 0 && CF.rel_cursor > 0) { CF.abs_cursor++; CF.cur_input->input.left--; } } goto redraw_newcursor; break; case '\006': /* ^F */ old_cursor = CF.abs_cursor; if (CF.rel_cursor < CF.cur_input->input.n) { CF.rel_cursor++; CF.abs_cursor++; if (CF.abs_cursor >= CF.cur_input->input.size && CF.rel_cursor < CF.cur_input->input.n) { CF.abs_cursor--; CF.cur_input->input.left++; } } goto redraw_newcursor; break; case '\010': /* ^H */ old_cursor = CF.abs_cursor; if (CF.rel_cursor > 0) { sp = CF.cur_input->input.value + CF.rel_cursor; dp = sp - 1; for (; *dp = *sp, *sp != '\0'; dp++, sp++); CF.cur_input->input.n--; CF.rel_cursor--; if (CF.rel_cursor < CF.abs_cursor) { CF.abs_cursor--; if (CF.abs_cursor <= 0 && CF.rel_cursor > 0) { CF.abs_cursor++; CF.cur_input->input.left--; } } else CF.cur_input->input.left--; } goto redraw_newcursor; break; case '\177': /* DEL */ case '\004': /* ^D */ if (CF.rel_cursor < CF.cur_input->input.n) { sp = CF.cur_input->input.value + CF.rel_cursor + 1; dp = sp - 1; for (; *dp = *sp, *sp != '\0'; dp++, sp++); CF.cur_input->input.n--; goto redraw_newcursor; } break; case '\013': /* ^K */ CF.cur_input->input.value[CF.rel_cursor] = '\0'; CF.cur_input->input.n = CF.rel_cursor; goto redraw_newcursor; case '\025': /* ^U */ CF.cur_input->input.value[0] = '\0'; CF.cur_input->input.n = CF.cur_input->input.left = 0; CF.rel_cursor = CF.abs_cursor = 0; goto redraw_newcursor; case '\020': /* ^P previous field */ old_item = CF.cur_input; CF.cur_input = old_item->input.prev_input; /* new current input fld */ RedrawItem(old_item, 1, NULL); CF.rel_cursor = CF.abs_cursor = 0; /* home cursor in new input field */ goto redraw; break; case '\t': case '\n': case '\015': case '\016': /* LINEFEED, TAB, RETURN, ^N, jump to the next field */ switch (process_tabtypes(&buf[0])) { case 0: goto no_redraw;break; case 1: goto redraw;break; } break; default: old_cursor = CF.abs_cursor; if((buf[0] >= ' ' && buf[0] < '\177') || (buf[0] >= 160)) { /* regular or intl char */ process_regular_char_input(&buf[0]); /* insert into input field */ goto redraw_newcursor; } /* unrecognized key press, check for buttons */ for (item = root_item_ptr; item != 0; item = item->header.next) { /* all items */ myfprintf((stderr, "Button: keypress==%d\n", item->button.keypress)); if (item->type == I_BUTTON && item->button.keypress == keypress) { RedrawItem(item, 1, NULL); usleep(MICRO_S_FOR_10MS); /* .1 seconds */ RedrawItem(item, 0, NULL); DoCommand(item); goto no_redraw; } } break; } redraw_newcursor: { XSetForeground(dpy, CF.cur_input->header.dt_ptr->dt_item_GC, CF.cur_input->header.dt_ptr->dt_colors[c_item_bg]); /* Since DrawString is being used, I changed this to clear the entire input field. dje 10/24/99. */ XClearArea(dpy, CF.cur_input->header.win, BOX_SPC + TEXT_SPC - 1, BOX_SPC, CF.cur_input->header.size_x - (2 * BOX_SPC) - 2 - TEXT_SPC, (CF.cur_input->header.size_y - 1) - 2 * BOX_SPC + 1, False); } redraw: { int len, x, dy; len = CF.cur_input->input.n - CF.cur_input->input.left; XSetForeground(dpy, CF.cur_input->header.dt_ptr->dt_item_GC, CF.cur_input->header.dt_ptr->dt_colors[c_item_fg]); if (len > CF.cur_input->input.size) len = CF.cur_input->input.size; CF.cur_input->header.dt_ptr->dt_Fstr->win = CF.cur_input->header.win; CF.cur_input->header.dt_ptr->dt_Fstr->gc = CF.cur_input->header.dt_ptr->dt_item_GC; CF.cur_input->header.dt_ptr->dt_Fstr->flags.has_colorset = False; if (itemcolorset >= 0) { CF.cur_input->header.dt_ptr->dt_Fstr->colorset = &Colorset[itemcolorset]; CF.cur_input->header.dt_ptr->dt_Fstr->flags.has_colorset = True; } CF.cur_input->header.dt_ptr->dt_Fstr->str = CF.cur_input->input.value; CF.cur_input->header.dt_ptr->dt_Fstr->x = BOX_SPC + TEXT_SPC; CF.cur_input->header.dt_ptr->dt_Fstr->y = BOX_SPC + TEXT_SPC + CF.cur_input->header.dt_ptr->dt_Ffont->ascent; CF.cur_input->header.dt_ptr->dt_Fstr->len = len; FlocaleDrawString(dpy, CF.cur_input->header.dt_ptr->dt_Ffont, CF.cur_input->header.dt_ptr->dt_Fstr, FWS_HAVE_LENGTH); x = BOX_SPC + TEXT_SPC + FlocaleTextWidth(CF.cur_input->header.dt_ptr->dt_Ffont, CF.cur_input->input.value,CF.abs_cursor) - 1; dy = CF.cur_input->header.size_y - 1; XDrawLine(dpy, CF.cur_input->header.win, CF.cur_input->header.dt_ptr->dt_item_GC, x, BOX_SPC, x, dy - BOX_SPC); myfprintf((stderr,"Line %d/%d - %d/%d (char)\n", x, BOX_SPC, x, dy - BOX_SPC)); } no_redraw: break; /* end of case KeyPress */ } /* end of switch (event.type) */ continue; } /* end of if (event.xany.window == CF.frame) */ for (item = root_item_ptr; item != 0; item = item->header.next) { /* all items */ if (event.xany.window == item->header.win) { switch (event.type) { case Expose: { int ex = event.xexpose.x; int ey = event.xexpose.y; int ex2 = event.xexpose.x + event.xexpose.width; int ey2 = event.xexpose.y + event.xexpose.height; while (FCheckTypedWindowEvent( dpy, item->header.win, Expose, &event)) { ex = min(ex, event.xexpose.x); ey = min(ey, event.xexpose.y); ex2 = max(ex2, event.xexpose.x + event.xexpose.width); ey2 = max(ey2 , event.xexpose.y + event.xexpose.height); } event.xexpose.x = ex; event.xexpose.y = ey; event.xexpose.width = ex2 - ex; event.xexpose.height = ey2 - ey; RedrawItem(item, 0, &event); } break; case ButtonPress: if (item->type == I_INPUT) { old_item = CF.cur_input; CF.cur_input = item; RedrawItem(old_item, 1, NULL); { Bool done = False; CF.abs_cursor = 0; while(CF.abs_cursor <= item->input.size && !done) { if (FlocaleTextWidth(item->header.dt_ptr->dt_Ffont, item->input.value, CF.abs_cursor) >= event.xbutton.x - BOX_SPC - TEXT_SPC) { done = True; CF.abs_cursor--; } else { CF.abs_cursor++; } } } if (CF.abs_cursor < 0) CF.abs_cursor = 0; if (CF.abs_cursor > item->input.size) CF.abs_cursor = item->input.size; CF.rel_cursor = CF.abs_cursor + item->input.left; if (CF.rel_cursor < 0) CF.rel_cursor = 0; if (CF.rel_cursor > item->input.n) CF.rel_cursor = item->input.n; if (CF.rel_cursor > 0 && CF.rel_cursor == item->input.left) item->input.left--; if (CF.rel_cursor < item->input.n && CF.rel_cursor == item->input.left + item->input.size) item->input.left++; CF.abs_cursor = CF.rel_cursor - item->input.left; if (event.xbutton.button == Button2) { /* if paste request */ process_paste_request (&event, item); } RedrawItem(item, 0, NULL); } if (item->type == I_CHOICE) ToggleChoice(item); if (item->type == I_BUTTON) { RedrawItem(item, 1, NULL); /* push button in */ if (CF.activate_on_press) { usleep(MICRO_S_FOR_10MS); /* make sure its visible */ RedrawItem(item, 0, NULL); /* pop button out */ DoCommand(item); /* execute the button command */ } else { XGrabPointer(dpy, item->header.win, False, /* owner of events */ ButtonReleaseMask, /* events to report */ GrabModeAsync, /* keyboard mode */ GrabModeAsync, /* pointer mode */ None, /* confine to */ /* I sort of like this, the hand points in the other direction and the color is reversed. I don't know what other GUIs do, Java doesn't do anything, neither does anything else I can find...dje */ CF.pointer[button_in_pointer], /* cursor */ CurrentTime); } /* end activate on press */ } break; case ButtonRelease: if (!CF.activate_on_press) { RedrawItem(item, 0, NULL); if (CF.grab_server && CF.server_grabbed) { /* You have to regrab the pointer, or focus can go to another window. grab... */ XGrabPointer(dpy, CF.frame, True, 0, GrabModeAsync, GrabModeAsync, None, None, CurrentTime); XFlush(dpy); } else { XUngrabPointer(dpy, CurrentTime); XFlush(dpy); } if (event.xbutton.x >= 0 && event.xbutton.x < item->header.size_x && event.xbutton.y >= 0 && event.xbutton.y < item->header.size_y) { DoCommand(item); } } break; } } } /* end of for (i = 0) */ } /* while loop */ }
void html_mouse_action(struct content *c, struct browser_window *bw, browser_mouse_state mouse, int x, int y) { html_content *html = (html_content *) c; enum { ACTION_NONE, ACTION_SUBMIT, ACTION_GO } action = ACTION_NONE; const char *title = 0; nsurl *url = 0; const char *target = 0; char status_buffer[200]; const char *status = 0; browser_pointer_shape pointer = BROWSER_POINTER_DEFAULT; bool imagemap = false; int box_x = 0, box_y = 0; int gadget_box_x = 0, gadget_box_y = 0; int html_object_pos_x = 0, html_object_pos_y = 0; int text_box_x = 0; struct box *url_box = 0; struct box *gadget_box = 0; struct box *text_box = 0; struct box *box; struct form_control *gadget = 0; hlcache_handle *object = NULL; struct box *html_object_box = NULL; struct browser_window *iframe = NULL; struct box *next_box; struct box *drag_candidate = NULL; struct scrollbar *scrollbar = NULL; plot_font_style_t fstyle; int scroll_mouse_x = 0, scroll_mouse_y = 0; int padding_left, padding_right, padding_top, padding_bottom; browser_drag_type drag_type = browser_window_get_drag_type(bw); union content_msg_data msg_data; struct dom_node *node = NULL; if (drag_type != DRAGGING_NONE && !mouse && html->visible_select_menu != NULL) { /* drag end: select menu */ form_select_mouse_drag_end(html->visible_select_menu, mouse, x, y); } if (html->visible_select_menu != NULL) { box = html->visible_select_menu->box; box_coords(box, &box_x, &box_y); box_x -= box->border[LEFT].width; box_y += box->height + box->border[BOTTOM].width + box->padding[BOTTOM] + box->padding[TOP]; status = form_select_mouse_action(html->visible_select_menu, mouse, x - box_x, y - box_y); if (status != NULL) { msg_data.explicit_status_text = status; content_broadcast(c, CONTENT_MSG_STATUS, msg_data); } else { int width, height; form_select_get_dimensions(html->visible_select_menu, &width, &height); html->visible_select_menu = NULL; browser_window_redraw_rect(bw, box_x, box_y, width, height); } return; } if (!mouse && html->scrollbar != NULL) { /* drag end: scrollbar */ html_overflow_scroll_drag_end(html->scrollbar, mouse, x, y); } if (html->scrollbar != NULL) { struct html_scrollbar_data *data = scrollbar_get_data(html->scrollbar); box = data->box; box_coords(box, &box_x, &box_y); if (scrollbar_is_horizontal(html->scrollbar)) { scroll_mouse_x = x - box_x ; scroll_mouse_y = y - (box_y + box->padding[TOP] + box->height + box->padding[BOTTOM] - SCROLLBAR_WIDTH); status = scrollbar_mouse_action(html->scrollbar, mouse, scroll_mouse_x, scroll_mouse_y); } else { scroll_mouse_x = x - (box_x + box->padding[LEFT] + box->width + box->padding[RIGHT] - SCROLLBAR_WIDTH); scroll_mouse_y = y - box_y; status = scrollbar_mouse_action(html->scrollbar, mouse, scroll_mouse_x, scroll_mouse_y); } msg_data.explicit_status_text = status; content_broadcast(c, CONTENT_MSG_STATUS, msg_data); return; } /* Content related drags handled by now */ browser_window_set_drag_type(bw, DRAGGING_NONE, NULL); /* search the box tree for a link, imagemap, form control, or * box with scrollbars */ box = html->layout; /* Consider the margins of the html page now */ box_x = box->margin[LEFT]; box_y = box->margin[TOP]; /* descend through visible boxes setting more specific values for: * box - deepest box at point * html_object_box - html object * html_object_pos_x - html object * html_object_pos_y - html object * object - non html object * iframe - iframe * url - href or imagemap * target - href or imagemap or gadget * url_box - href or imagemap * imagemap - imagemap * gadget - gadget * gadget_box - gadget * gadget_box_x - gadget * gadget_box_y - gadget * title - title * pointer * * drag_candidate - first box with scroll * padding_left - box with scroll * padding_right * padding_top * padding_bottom * scrollbar - inside padding box stops decent * scroll_mouse_x - inside padding box stops decent * scroll_mouse_y - inside padding box stops decent * * text_box - text box * text_box_x - text_box */ while ((next_box = box_at_point(box, x, y, &box_x, &box_y)) != NULL) { box = next_box; if ((box->style != NULL) && (css_computed_visibility(box->style) == CSS_VISIBILITY_HIDDEN)) { continue; } if (box->node != NULL) { node = box->node; } if (box->object) { if (content_get_type(box->object) == CONTENT_HTML) { html_object_box = box; html_object_pos_x = box_x; html_object_pos_y = box_y; } else { object = box->object; } } if (box->iframe) { iframe = box->iframe; } if (box->href) { url = box->href; target = box->target; url_box = box; } if (box->usemap) { url = imagemap_get(html, box->usemap, box_x, box_y, x, y, &target); if (url) { imagemap = true; url_box = box; } } if (box->gadget) { gadget = box->gadget; gadget_box = box; gadget_box_x = box_x; gadget_box_y = box_y; if (gadget->form) target = gadget->form->target; } if (box->title) { title = box->title; } pointer = get_pointer_shape(box, false); if ((box->scroll_x != NULL) || (box->scroll_y != NULL)) { if (drag_candidate == NULL) { drag_candidate = box; } padding_left = box_x + scrollbar_get_offset(box->scroll_x); padding_right = padding_left + box->padding[LEFT] + box->width + box->padding[RIGHT]; padding_top = box_y + scrollbar_get_offset(box->scroll_y); padding_bottom = padding_top + box->padding[TOP] + box->height + box->padding[BOTTOM]; if ((x > padding_left) && (x < padding_right) && (y > padding_top) && (y < padding_bottom)) { /* mouse inside padding box */ if ((box->scroll_y != NULL) && (x > (padding_right - SCROLLBAR_WIDTH))) { /* mouse above vertical box scroll */ scrollbar = box->scroll_y; scroll_mouse_x = x - (padding_right - SCROLLBAR_WIDTH); scroll_mouse_y = y - padding_top; break; } else if ((box->scroll_x != NULL) && (y > (padding_bottom - SCROLLBAR_WIDTH))) { /* mouse above horizontal box scroll */ scrollbar = box->scroll_x; scroll_mouse_x = x - padding_left; scroll_mouse_y = y - (padding_bottom - SCROLLBAR_WIDTH); break; } } } if (box->text && !box->object) { text_box = box; text_box_x = box_x; } } /* use of box_x, box_y, or content below this point is probably a * mistake; they will refer to the last box returned by box_at_point */ if (scrollbar) { status = scrollbar_mouse_action(scrollbar, mouse, scroll_mouse_x, scroll_mouse_y); pointer = BROWSER_POINTER_DEFAULT; } else if (gadget) { switch (gadget->type) { case GADGET_SELECT: status = messages_get("FormSelect"); pointer = BROWSER_POINTER_MENU; if (mouse & BROWSER_MOUSE_CLICK_1 && nsoption_bool(core_select_menu)) { html->visible_select_menu = gadget; form_open_select_menu(c, gadget, form_select_menu_callback, c); pointer = BROWSER_POINTER_DEFAULT; } else if (mouse & BROWSER_MOUSE_CLICK_1) gui_create_form_select_menu(bw, gadget); break; case GADGET_CHECKBOX: status = messages_get("FormCheckbox"); if (mouse & BROWSER_MOUSE_CLICK_1) { gadget->selected = !gadget->selected; html__redraw_a_box(html, gadget_box); } break; case GADGET_RADIO: status = messages_get("FormRadio"); if (mouse & BROWSER_MOUSE_CLICK_1) form_radio_set(html, gadget); break; case GADGET_IMAGE: if (mouse & BROWSER_MOUSE_CLICK_1) { gadget->data.image.mx = x - gadget_box_x; gadget->data.image.my = y - gadget_box_y; } /* drop through */ case GADGET_SUBMIT: if (gadget->form) { snprintf(status_buffer, sizeof status_buffer, messages_get("FormSubmit"), gadget->form->action); status = status_buffer; pointer = get_pointer_shape(gadget_box, false); if (mouse & (BROWSER_MOUSE_CLICK_1 | BROWSER_MOUSE_CLICK_2)) action = ACTION_SUBMIT; } else { status = messages_get("FormBadSubmit"); } break; case GADGET_TEXTAREA: status = messages_get("FormTextarea"); pointer = get_pointer_shape(gadget_box, false); if (mouse & (BROWSER_MOUSE_PRESS_1 | BROWSER_MOUSE_PRESS_2)) { if (text_box && selection_root(&html->sel) != gadget_box) selection_init(&html->sel, gadget_box); textinput_textarea_click(c, mouse, gadget_box, gadget_box_x, gadget_box_y, x - gadget_box_x, y - gadget_box_y); } if (text_box) { int pixel_offset; size_t idx; font_plot_style_from_css(text_box->style, &fstyle); nsfont.font_position_in_string(&fstyle, text_box->text, text_box->length, x - gadget_box_x - text_box->x, &idx, &pixel_offset); selection_click(&html->sel, mouse, text_box->byte_offset + idx); if (selection_dragging(&html->sel)) { browser_window_set_drag_type(bw, DRAGGING_SELECTION, NULL); status = messages_get("Selecting"); } } else if (mouse & BROWSER_MOUSE_PRESS_1) selection_clear(&html->sel, true); break; case GADGET_TEXTBOX: case GADGET_PASSWORD: status = messages_get("FormTextbox"); pointer = get_pointer_shape(gadget_box, false); if ((mouse & BROWSER_MOUSE_PRESS_1) && !(mouse & (BROWSER_MOUSE_MOD_1 | BROWSER_MOUSE_MOD_2))) { textinput_input_click(c, gadget_box, gadget_box_x, gadget_box_y, x - gadget_box_x, y - gadget_box_y); } if (text_box) { int pixel_offset; size_t idx; if (mouse & (BROWSER_MOUSE_DRAG_1 | BROWSER_MOUSE_DRAG_2)) selection_init(&html->sel, gadget_box); font_plot_style_from_css(text_box->style, &fstyle); nsfont.font_position_in_string(&fstyle, text_box->text, text_box->length, x - gadget_box_x - text_box->x, &idx, &pixel_offset); selection_click(&html->sel, mouse, text_box->byte_offset + idx); if (selection_dragging(&html->sel)) browser_window_set_drag_type(bw, DRAGGING_SELECTION, NULL); } else if (mouse & BROWSER_MOUSE_PRESS_1) selection_clear(&html->sel, true); break; case GADGET_HIDDEN: /* not possible: no box generated */ break; case GADGET_RESET: status = messages_get("FormReset"); break; case GADGET_FILE: status = messages_get("FormFile"); break; case GADGET_BUTTON: /* This gadget cannot be activated */ status = messages_get("FormButton"); break; } } else if (object && (mouse & BROWSER_MOUSE_MOD_2)) { if (mouse & BROWSER_MOUSE_DRAG_2) { msg_data.dragsave.type = CONTENT_SAVE_NATIVE; msg_data.dragsave.content = object; content_broadcast(c, CONTENT_MSG_DRAGSAVE, msg_data); } else if (mouse & BROWSER_MOUSE_DRAG_1) { msg_data.dragsave.type = CONTENT_SAVE_ORIG; msg_data.dragsave.content = object; content_broadcast(c, CONTENT_MSG_DRAGSAVE, msg_data); } /* \todo should have a drag-saving object msg */ } else if (iframe) { int pos_x, pos_y; float scale = browser_window_get_scale(bw); browser_window_get_position(iframe, false, &pos_x, &pos_y); pos_x /= scale; pos_y /= scale; if (mouse & BROWSER_MOUSE_CLICK_1 || mouse & BROWSER_MOUSE_CLICK_2) { browser_window_mouse_click(iframe, mouse, x - pos_x, y - pos_y); } else { browser_window_mouse_track(iframe, mouse, x - pos_x, y - pos_y); } } else if (html_object_box) { if (mouse & BROWSER_MOUSE_CLICK_1 || mouse & BROWSER_MOUSE_CLICK_2) { content_mouse_action(html_object_box->object, bw, mouse, x - html_object_pos_x, y - html_object_pos_y); } else { content_mouse_track(html_object_box->object, bw, mouse, x - html_object_pos_x, y - html_object_pos_y); } } else if (url) { if (title) { snprintf(status_buffer, sizeof status_buffer, "%s: %s", nsurl_access(url), title); status = status_buffer; } else status = nsurl_access(url); pointer = get_pointer_shape(url_box, imagemap); if (mouse & BROWSER_MOUSE_CLICK_1 && mouse & BROWSER_MOUSE_MOD_1) { /* force download of link */ browser_window_go_post(bw, nsurl_access(url), 0, 0, false, nsurl_access(content_get_url(c)), true, true, 0); } else if (mouse & BROWSER_MOUSE_CLICK_2 && mouse & BROWSER_MOUSE_MOD_1) { msg_data.savelink.url = nsurl_access(url); msg_data.savelink.title = title; content_broadcast(c, CONTENT_MSG_SAVELINK, msg_data); } else if (mouse & (BROWSER_MOUSE_CLICK_1 | BROWSER_MOUSE_CLICK_2)) action = ACTION_GO; } else { bool done = false; /* frame resizing */ if (browser_window_frame_resize_start(bw, mouse, x, y, &pointer)) { if (mouse & (BROWSER_MOUSE_DRAG_1 | BROWSER_MOUSE_DRAG_2)) { status = messages_get("FrameDrag"); } done = true; } /* if clicking in the main page, remove the selection from any * text areas */ if (!done) { struct box *layout = html->layout; if (mouse && (mouse < BROWSER_MOUSE_MOD_1) && selection_root(&html->sel) != layout) { selection_init(&html->sel, layout); } if (text_box) { int pixel_offset; size_t idx; font_plot_style_from_css(text_box->style, &fstyle); nsfont.font_position_in_string(&fstyle, text_box->text, text_box->length, x - text_box_x, &idx, &pixel_offset); if (selection_click(&html->sel, mouse, text_box->byte_offset + idx)) { /* key presses must be directed at the * main browser window, paste text * operations ignored */ if (selection_dragging(&html->sel)) { browser_window_set_drag_type(bw, DRAGGING_SELECTION, NULL); status = messages_get( "Selecting"); } done = true; } } else if (mouse & BROWSER_MOUSE_PRESS_1) selection_clear(&html->sel, true); } if (!done) { if (title) status = title; if (mouse & BROWSER_MOUSE_DRAG_1) { if (mouse & BROWSER_MOUSE_MOD_2) { msg_data.dragsave.type = CONTENT_SAVE_COMPLETE; msg_data.dragsave.content = NULL; content_broadcast(c, CONTENT_MSG_DRAGSAVE, msg_data); } else { if (drag_candidate == NULL) { browser_window_page_drag_start( bw, x, y); } else { html_box_drag_start( drag_candidate, x, y); } pointer = BROWSER_POINTER_MOVE; } } else if (mouse & BROWSER_MOUSE_DRAG_2) { if (mouse & BROWSER_MOUSE_MOD_2) { msg_data.dragsave.type = CONTENT_SAVE_SOURCE; msg_data.dragsave.content = NULL; content_broadcast(c, CONTENT_MSG_DRAGSAVE, msg_data); } else { if (drag_candidate == NULL) { browser_window_page_drag_start( bw, x, y); } else { html_box_drag_start( drag_candidate, x, y); } pointer = BROWSER_POINTER_MOVE; } } } if (mouse && mouse < BROWSER_MOUSE_MOD_1) { /* ensure key presses still act on the browser window */ browser_window_remove_caret(bw); } } if (!iframe && !html_object_box) { msg_data.explicit_status_text = status; content_broadcast(c, CONTENT_MSG_STATUS, msg_data); msg_data.pointer = pointer; content_broadcast(c, CONTENT_MSG_POINTER, msg_data); } /* fire dom click event */ if ((mouse & BROWSER_MOUSE_CLICK_1) || (mouse & BROWSER_MOUSE_CLICK_2)) { js_fire_event(html->jscontext, "click", html->document, node); } /* deferred actions that can cause this browser_window to be destroyed * and must therefore be done after set_status/pointer */ switch (action) { case ACTION_SUBMIT: form_submit(content_get_url(c), browser_window_find_target(bw, target, mouse), gadget->form, gadget); break; case ACTION_GO: browser_window_go(browser_window_find_target(bw, target, mouse), nsurl_access(url), nsurl_access(content_get_url(c)), true); break; case ACTION_NONE: break; } }
/* main() for usual operation */ int tray_main(int argc, char **argv) { XEvent ev; /* Interpret those settings that need an open display */ interpret_settings(); #ifdef DEBUG ewmh_list_supported_atoms(tray_data.dpy); #endif /* Create and show tray window */ tray_create_window(argc, argv); tray_acquire_selection(); tray_show_window(); #ifndef NO_NATIVE_KDE kde_tray_init(tray_data.dpy); #endif xembed_init(); #ifndef NO_NATIVE_KDE kde_icons_update(); #endif /* Main event loop */ while ("my guitar gently wheeps") { /* This is ugly and extra dependency. But who cares? * Rationale: we want to block unless absolutely needed. * This way we ensure that stalonetray does not show up * in powertop (i.e. does not eat unnecessary power and * CPU cycles) * Drawback: handling of signals is very limited. XNextEvent() * does not if signal occurs. This means that graceful * exit on e.g. Ctrl-C cannot be implemented without hacks. */ while (XPending(tray_data.dpy) || tray_data.scrollbars_data.scrollbar_down == -1) { XNextEvent(tray_data.dpy, &ev); xembed_handle_event(ev); scrollbars_handle_event(ev); switch (ev.type) { case VisibilityNotify: LOG_TRACE(("VisibilityNotify (0x%x, state=%d)\n", ev.xvisibility.window, ev.xvisibility.state)); visibility_notify(ev.xvisibility); break; case Expose: LOG_TRACE(("Expose (0x%x)\n", ev.xexpose.window)); expose(ev.xexpose); break; case PropertyNotify: LOG_TRACE(("PropertyNotify(0x%x)\n", ev.xproperty.window)); property_notify(ev.xproperty); break; case DestroyNotify: LOG_TRACE(("DestroyNotify(0x%x)\n", ev.xdestroywindow.window)); destroy_notify(ev.xdestroywindow); break; case ClientMessage: LOG_TRACE(("ClientMessage(from 0x%x?)\n", ev.xclient.window)); client_message(ev.xclient); break; case ConfigureNotify: LOG_TRACE(("ConfigureNotify(0x%x)\n", ev.xconfigure.window)); configure_notify(ev.xconfigure); break; case MapNotify: LOG_TRACE(("MapNotify(0x%x)\n", ev.xmap.window)); map_notify(ev.xmap); break; case ReparentNotify: LOG_TRACE(("ReparentNotify(0x%x to 0x%x)\n", ev.xreparent.window, ev.xreparent.parent)); reparent_notify(ev.xreparent); break; case SelectionClear: LOG_TRACE(("SelectionClear (0x%x has lost selection)\n", ev.xselectionclear.window)); selection_clear(ev.xselectionclear); break; case SelectionNotify: LOG_TRACE(("SelectionNotify\n")); break; case SelectionRequest: LOG_TRACE(("SelectionRequest (from 0x%x to 0x%x)\n", ev.xselectionrequest.requestor, ev.xselectionrequest.owner)); break; case UnmapNotify: LOG_TRACE(("UnmapNotify(0x%x)\n", ev.xunmap.window)); unmap_notify(ev.xunmap); break; default: #if defined(DEBUG) && defined(TRACE_EVENTS) LOG_TRACE(("Unhandled event: %s, serial: %d, window: 0x%x\n", x11_event_names[ev.type], ev.xany.serial, ev.xany.window)); #endif break; } if (tray_data.terminated) goto bailout; /* Perform all periodic tasks but for scrollbars */ perform_periodic_tasks(PT_MASK_ALL & (~PT_MASK_SB)); } perform_periodic_tasks(PT_MASK_ALL); my_usleep(500000L); } bailout: LOG_TRACE(("Clean exit\n")); return 0; }
void LineEdit::_input_event(InputEvent p_event) { switch(p_event.type) { case InputEvent::MOUSE_BUTTON: { const InputEventMouseButton &b = p_event.mouse_button; if (b.pressed && b.button_index==BUTTON_RIGHT) { menu->set_pos(get_global_transform().xform(get_local_mouse_pos())); menu->set_size(Vector2(1,1)); menu->popup(); grab_focus(); return; } if (b.button_index!=BUTTON_LEFT) break; _reset_caret_blink_timer(); if (b.pressed) { shift_selection_check_pre(b.mod.shift); set_cursor_at_pixel_pos(b.x); if (b.mod.shift) { selection_fill_at_cursor(); selection.creating=true; } else { if (b.doubleclick) { selection.enabled=true; selection.begin=0; selection.end=text.length(); selection.doubleclick=true; } selection.drag_attempt=false; if ((cursor_pos<selection.begin) || (cursor_pos>selection.end) || !selection.enabled) { selection_clear(); selection.cursor_start=cursor_pos; selection.creating=true; } else if (selection.enabled) { selection.drag_attempt=true; } } // if (!editable) // non_editable_clicked_signal.call(); update(); } else { if ( (!selection.creating) && (!selection.doubleclick)) { selection_clear(); } selection.creating=false; selection.doubleclick=false; if (OS::get_singleton()->has_virtual_keyboard()) OS::get_singleton()->show_virtual_keyboard(text,get_global_rect()); } update(); } break; case InputEvent::MOUSE_MOTION: { const InputEventMouseMotion& m=p_event.mouse_motion; if (m.button_mask&BUTTON_LEFT) { if (selection.creating) { set_cursor_at_pixel_pos(m.x); selection_fill_at_cursor(); } } } break; case InputEvent::KEY: { const InputEventKey &k =p_event.key; if (!k.pressed) return; unsigned int code = k.scancode; if (k.mod.command) { bool handled=true; switch (code) { case (KEY_X): { // CUT if(editable) { cut_text(); } } break; case (KEY_C): { // COPY copy_text(); } break; case (KEY_V): { // PASTE if(editable) { paste_text(); } } break; case (KEY_Z): { // Simple One level undo if(editable) { undo(); } } break; case (KEY_U): { // Delete from start to cursor if(editable) { selection_clear(); undo_text = text; text = text.substr(cursor_pos,text.length()-cursor_pos); Ref<Font> font = get_font("font"); cached_width = 0; if (font != NULL) { for (int i = 0; i < text.length(); i++) cached_width += font->get_char_size(text[i]).width; } set_cursor_pos(0); _text_changed(); } } break; case (KEY_Y): { // PASTE (Yank for unix users) if(editable) { paste_text(); } } break; case (KEY_K): { // Delete from cursor_pos to end if(editable) { selection_clear(); undo_text = text; text = text.substr(0,cursor_pos); _text_changed(); } } break; case (KEY_A): { //Select All select(); } break; default: { handled=false; } } if (handled) { accept_event(); return; } } _reset_caret_blink_timer(); if (!k.mod.meta) { bool handled=true; switch (code) { case KEY_ENTER: case KEY_RETURN: { emit_signal( "text_entered",text ); if (OS::get_singleton()->has_virtual_keyboard()) OS::get_singleton()->hide_virtual_keyboard(); return; } break; case KEY_BACKSPACE: { if (!editable) break; if (selection.enabled) { undo_text=text; selection_delete(); break; } #ifdef APPLE_STYLE_KEYS if (k.mod.alt) { #else if (k.mod.alt) { handled=false; break; } else if (k.mod.command) { #endif int cc=cursor_pos; bool prev_char=false; while (cc>0) { bool ischar=_is_text_char(text[cc-1]); if (prev_char && !ischar) break; prev_char=ischar; cc--; } delete_text(cc, cursor_pos); set_cursor_pos(cc); } else { undo_text=text; delete_char(); } } break; case KEY_KP_4: { if (k.unicode != 0) { handled = false; break; } // numlock disabled. fallthrough to key_left } case KEY_LEFT: { #ifndef APPLE_STYLE_KEYS if (!k.mod.alt) #endif shift_selection_check_pre(k.mod.shift); #ifdef APPLE_STYLE_KEYS if (k.mod.command) { set_cursor_pos(0); } else if (k.mod.alt) { #else if (k.mod.alt) { handled=false; break; } else if (k.mod.command) { #endif bool prev_char=false; int cc=cursor_pos; while (cc>0) { bool ischar=_is_text_char(text[cc-1]); if (prev_char && !ischar) break; prev_char=ischar; cc--; } set_cursor_pos(cc); } else { set_cursor_pos(get_cursor_pos()-1); } shift_selection_check_post(k.mod.shift); } break; case KEY_KP_6: { if (k.unicode != 0) { handled = false; break; } // numlock disabled. fallthrough to key_right } case KEY_RIGHT: { shift_selection_check_pre(k.mod.shift); #ifdef APPLE_STYLE_KEYS if (k.mod.command) { set_cursor_pos(text.length()); } else if (k.mod.alt) { #else if (k.mod.alt) { handled=false; break; } else if (k.mod.command) { #endif bool prev_char=false; int cc=cursor_pos; while (cc<text.length()) { bool ischar=_is_text_char(text[cc]); if (prev_char && !ischar) break; prev_char=ischar; cc++; } set_cursor_pos(cc); } else { set_cursor_pos(get_cursor_pos()+1); } shift_selection_check_post(k.mod.shift); } break; case KEY_DELETE: { if (!editable) break; if (k.mod.shift && !k.mod.command && !k.mod.alt) { cut_text(); break; } if (selection.enabled) { undo_text=text; selection_delete(); break; } int text_len = text.length(); if (cursor_pos==text_len) break; // nothing to do #ifdef APPLE_STYLE_KEYS if (k.mod.alt) { #else if (k.mod.alt) { handled=false; break; } else if (k.mod.command) { #endif int cc=cursor_pos; bool prev_char=false; while (cc<text.length()) { bool ischar=_is_text_char(text[cc]); if (prev_char && !ischar) break; prev_char=ischar; cc++; } delete_text(cursor_pos,cc); } else { undo_text=text; set_cursor_pos(cursor_pos+1); delete_char(); } } break; case KEY_KP_7: { if (k.unicode != 0) { handled = false; break; } // numlock disabled. fallthrough to key_home } case KEY_HOME: { shift_selection_check_pre(k.mod.shift); set_cursor_pos(0); shift_selection_check_post(k.mod.shift); } break; case KEY_KP_1: { if (k.unicode != 0) { handled = false; break; } // numlock disabled. fallthrough to key_end } case KEY_END: { shift_selection_check_pre(k.mod.shift); set_cursor_pos(text.length()); shift_selection_check_post(k.mod.shift); } break; default: { handled=false; } break; } if (handled) { accept_event(); } else if (!k.mod.alt && !k.mod.command) { if (k.unicode>=32 && k.scancode!=KEY_DELETE) { if (editable) { selection_delete(); CharType ucodestr[2]= {(CharType)k.unicode,0}; append_at_cursor(ucodestr); _text_changed(); accept_event(); } } else { return; } } update(); } return; } break; } } void LineEdit::set_align(Align p_align) { ERR_FAIL_INDEX(p_align, 4); align = p_align; update(); } LineEdit::Align LineEdit::get_align() const { return align; } Variant LineEdit::get_drag_data(const Point2& p_point) { if (selection.drag_attempt && selection.enabled) { String t = text.substr(selection.begin, selection.end - selection.begin); Label *l = memnew( Label ); l->set_text(t); set_drag_preview(l); return t; } return Variant(); } bool LineEdit::can_drop_data(const Point2& p_point,const Variant& p_data) const { return p_data.get_type()==Variant::STRING; } void LineEdit::drop_data(const Point2& p_point,const Variant& p_data) { if (p_data.get_type()==Variant::STRING) { set_cursor_at_pixel_pos(p_point.x); int selected = selection.end - selection.begin; Ref<Font> font = get_font("font"); if (font != NULL) { for (int i = selection.begin; i < selection.end; i++) cached_width -= font->get_char_size(text[i]).width; } text.erase(selection.begin, selected); append_at_cursor(p_data); selection.begin = cursor_pos-selected; selection.end = cursor_pos; } } void LineEdit::_notification(int p_what) { switch(p_what) { #ifdef TOOLS_ENABLED case NOTIFICATION_ENTER_TREE: { if (get_tree()->is_editor_hint()) { cursor_set_blink_enabled(EDITOR_DEF("text_editor/caret_blink", false)); cursor_set_blink_speed(EDITOR_DEF("text_editor/caret_blink_speed", 0.65)); if (!EditorSettings::get_singleton()->is_connected("settings_changed",this,"_editor_settings_changed")) { EditorSettings::get_singleton()->connect("settings_changed",this,"_editor_settings_changed"); } } } break; #endif case NOTIFICATION_RESIZED: { set_cursor_pos( get_cursor_pos() ); } break; case MainLoop::NOTIFICATION_WM_FOCUS_IN: { window_has_focus = true; draw_caret = true; update(); } break; case MainLoop::NOTIFICATION_WM_FOCUS_OUT: { window_has_focus = false; draw_caret = false; update(); } break; case NOTIFICATION_DRAW: { if ((!has_focus() && !menu->has_focus()) || !window_has_focus) { draw_caret = false; } int width,height; Size2 size=get_size(); width=size.width; height=size.height; RID ci = get_canvas_item(); Ref<StyleBox> style = get_stylebox("normal"); if (!is_editable()) style=get_stylebox("read_only"); Ref<Font> font=get_font("font"); style->draw( ci, Rect2( Point2(), size ) ); if (has_focus()) { get_stylebox("focus")->draw( ci, Rect2( Point2(), size ) ); } int x_ofs=0; switch (align) { case ALIGN_FILL: case ALIGN_LEFT: { x_ofs=style->get_offset().x; } break; case ALIGN_CENTER: { x_ofs=int(size.width-(cached_width))/2; } break; case ALIGN_RIGHT: { x_ofs=int(size.width-style->get_offset().x-(cached_width)); } break; } int ofs_max=width-style->get_minimum_size().width; int char_ofs=window_pos; int y_area=height-style->get_minimum_size().height; int y_ofs=style->get_offset().y; int font_ascent=font->get_ascent(); Color selection_color=get_color("selection_color"); Color font_color=get_color("font_color"); Color font_color_selected=get_color("font_color_selected"); Color cursor_color=get_color("cursor_color"); const String& t = text.empty() ? placeholder : text; // draw placeholder color if(text.empty()) font_color.a *= placeholder_alpha; int caret_height = font->get_height() > y_area ? y_area : font->get_height(); while(true) { //end of string, break! if (char_ofs>=t.length()) break; CharType cchar=pass?'*':t[char_ofs]; CharType next=pass?'*':t[char_ofs+1]; int char_width=font->get_char_size( cchar,next ).width; // end of widget, break! if ((x_ofs + char_width) > ofs_max) break; bool selected=selection.enabled && char_ofs>=selection.begin && char_ofs<selection.end; if (selected) VisualServer::get_singleton()->canvas_item_add_rect(ci, Rect2(Point2(x_ofs, y_ofs), Size2(char_width, caret_height)), selection_color); font->draw_char(ci, Point2(x_ofs, y_ofs + font_ascent), cchar, next, selected ? font_color_selected : font_color); if (char_ofs==cursor_pos && draw_caret) { VisualServer::get_singleton()->canvas_item_add_rect(ci, Rect2( Point2( x_ofs , y_ofs ), Size2( 1, caret_height ) ), cursor_color ); } x_ofs+=char_width; char_ofs++; } if (char_ofs==cursor_pos && draw_caret) {//may be at the end VisualServer::get_singleton()->canvas_item_add_rect(ci, Rect2( Point2( x_ofs , y_ofs ), Size2( 1, caret_height ) ), cursor_color ); } } break; case NOTIFICATION_FOCUS_ENTER: { if (!caret_blink_enabled) { draw_caret = true; } if (OS::get_singleton()->has_virtual_keyboard()) OS::get_singleton()->show_virtual_keyboard(text,get_global_rect()); } break; case NOTIFICATION_FOCUS_EXIT: { if (OS::get_singleton()->has_virtual_keyboard()) OS::get_singleton()->hide_virtual_keyboard(); } break; } } void LineEdit::copy_text() { if(selection.enabled) { OS::get_singleton()->set_clipboard(text.substr(selection.begin, selection.end - selection.begin)); } } void LineEdit::cut_text() { if(selection.enabled) { undo_text = text; OS::get_singleton()->set_clipboard(text.substr(selection.begin, selection.end - selection.begin)); selection_delete(); } } void LineEdit::paste_text() { String paste_buffer = OS::get_singleton()->get_clipboard(); if(paste_buffer != "") { if(selection.enabled) selection_delete(); append_at_cursor(paste_buffer); _text_changed(); } } void LineEdit::undo() { int old_cursor_pos = cursor_pos; text = undo_text; Ref<Font> font = get_font("font"); cached_width = 0; for (int i = 0; i<text.length(); i++) cached_width += font->get_char_size(text[i]).width; if(old_cursor_pos > text.length()) { set_cursor_pos(text.length()); } else { set_cursor_pos(old_cursor_pos); } _text_changed(); }
rxvt_term::~rxvt_term () { termlist.erase (find (termlist.begin (), termlist.end(), this)); emergency_cleanup (); #if ENABLE_STYLES for (int i = RS_styleCount; --i; ) if (fontset[i] != fontset[0]) delete fontset[i]; #endif delete fontset[0]; #ifdef HAVE_BG_PIXMAP bgPixmap.destroy (); #endif #ifdef HAVE_AFTERIMAGE if (asv) destroy_asvisual (asv, 0); if (asimman) destroy_image_manager (asimman, 0); #endif if (display) { selection_clear (); #ifdef USE_XIM im_destroy (); #endif scrollBar.destroy (); if (gc) XFreeGC (dpy, gc); delete drawable; // destroy all windows if (parent[0]) XDestroyWindow (dpy, parent[0]); for (int i = 0; i < TOTAL_COLORS; i++) if (ISSET_PIXCOLOR (i)) { pix_colors_focused [i].free (this); #if OFF_FOCUS_FADING pix_colors_unfocused [i].free (this); #endif } clear (); display->flush (); /* ideally .put should do this */ displays.put (display); } scr_release (); /* clear all resources */ for (int i = 0; i < allocated.size (); i++) free (allocated [i]); free (selection.text); // TODO: manage env vars in child only(!) free (env_display); free (env_term); free (locale); free (v_buffer); free (incr_buf); delete envv; delete argv; #ifdef KEYSYM_RESOURCE delete keyboard; #endif #ifndef NO_RESOURCES XrmDestroyDatabase (option_db); #endif }
void SYSTRAY_event_filter(XEvent *e) { XEvent ev; if (!tray_data.dpy) return; ev = *e; xembed_handle_event(ev); //scrollbars_handle_event(ev); switch (ev.type) { case VisibilityNotify: LOG_TRACE(("VisibilityNotify (0x%x, state=%d)\n", ev.xvisibility.window, ev.xvisibility.state)); visibility_notify(ev.xvisibility); break; case Expose: LOG_TRACE(("Expose (0x%x)\n", ev.xexpose.window)); expose(ev.xexpose); break; case PropertyNotify: LOG_TRACE(("PropertyNotify(0x%x)\n", ev.xproperty.window)); property_notify(ev.xproperty); break; case DestroyNotify: LOG_TRACE(("DestroyNotify(0x%x)\n", ev.xdestroywindow.window)); destroy_notify(ev.xdestroywindow); break; case ClientMessage: LOG_TRACE(("ClientMessage(from 0x%x?)\n", ev.xclient.window)); client_message(ev.xclient); break; case ConfigureNotify: LOG_TRACE(("ConfigureNotify(0x%x)\n", ev.xconfigure.window)); configure_notify(ev.xconfigure); break; case MapNotify: LOG_TRACE(("MapNotify(0x%x)\n", ev.xmap.window)); map_notify(ev.xmap); break; case ReparentNotify: LOG_TRACE(("ReparentNotify(0x%x to 0x%x)\n", ev.xreparent.window, ev.xreparent.parent)); reparent_notify(ev.xreparent); break; case SelectionClear: LOG_TRACE(("SelectionClear (0x%x has lost selection)\n", ev.xselectionclear.window)); selection_clear(ev.xselectionclear); break; case SelectionNotify: LOG_TRACE(("SelectionNotify\n")); break; case SelectionRequest: LOG_TRACE(("SelectionRequest (from 0x%x to 0x%x)\n", ev.xselectionrequest.requestor, ev.xselectionrequest.owner)); break; case UnmapNotify: LOG_TRACE(("UnmapNotify(0x%x)\n", ev.xunmap.window)); unmap_notify(ev.xunmap); break; default: #if defined(DEBUG) && defined(TRACE_EVENTS) LOG_TRACE(("Unhandled event: %s, serial: %d, window: 0x%x\n", x11_event_names[ev.type], ev.xany.serial, ev.xany.window)); #endif break; } // TODO: perform_periodic_tasks(PT_MASK_ALL); #if 0 if (tray_data.terminated) goto bailout; /* Perform all periodic tasks but for scrollbars */ perform_periodic_tasks(PT_MASK_ALL & (~PT_MASK_SB)); }