void ro_gui_query_window_bring_to_front(query_id id) { struct gui_query_window *qw = ro_gui_query_window_lookup_id(id); if (qw) { os_error *error; ro_gui_dialog_open(qw->window); error = xwimp_set_caret_position(qw->window, (wimp_i)-1, 0, 0, 1 << 25, -1); if (error) { LOG(("xwimp_get_caret_position: 0x%x : %s", error->errnum, error->errmess)); warn_user("WimpError", error->errmess); } } }
void ro_gui_download_window_hide_caret(struct gui_download_window *dw) { wimp_caret caret; os_error *error; error = xwimp_get_caret_position(&caret); if (error) { LOG("xwimp_get_caret_position: 0x%x : %s", error->errnum, error->errmess); ro_warn_user("WimpError", error->errmess); } else if (caret.w == dw->window) { error = xwimp_set_caret_position(dw->window, (wimp_i)-1, 0, 0, 1 << 25, -1); if (error) { LOG("xwimp_get_caret_position: 0x%x : %s", error->errnum, error->errmess); ro_warn_user("WimpError", error->errmess); } } }
bool ro_gui_url_bar_take_caret(struct url_bar *url_bar) { os_error *error; if (url_bar == NULL || url_bar->hidden) return false; error = xwimp_set_caret_position(url_bar->window, url_bar->text_icon, -1, -1, -1, 0); if (error) { LOG(("xwimp_set_caret_position: 0x%x: %s", error->errnum, error->errmess)); warn_user("WimpError", error->errmess); return false; } return true; }
void ro_gui_url_bar_set_url(struct url_bar *url_bar, const char *url, bool is_utf8, bool set_caret) { wimp_caret caret; os_error *error; const char *set_url; if (url_bar == NULL || url_bar->text_buffer == NULL) return; if (url_bar->text_icon == -1) { strncpy(url_bar->text_buffer, url, url_bar->text_size); return; } ro_gui_set_icon_string(url_bar->window, url_bar->text_icon, url, is_utf8); error = xwimp_get_caret_position(&caret); if (error) { LOG(("xwimp_get_caret_position: 0x%x: %s", error->errnum, error->errmess)); warn_user("WimpError", error->errmess); return; } if (set_caret || (caret.w == url_bar->window && caret.i == url_bar->text_icon)) { set_url = ro_gui_get_icon_string(url_bar->window, url_bar->text_icon); error = xwimp_set_caret_position(url_bar->window, url_bar->text_icon, 0, 0, -1, strlen(set_url)); if (error) { LOG(("xwimp_set_caret_position: 0x%x: %s", error->errnum, error->errmess)); warn_user("WimpError", error->errmess); } } }
query_id query_user_xy(const char *query, const char *detail, const query_callback *cb, void *pw, const char *yes, const char *no, int x, int y) { struct gui_query_window *qw; char query_buffer[300]; os_error *error; wimp_icon *icn; int width; int len; int tx; char *local_text = NULL; nserror err; qw = malloc(sizeof(struct gui_query_window)); if (!qw) { warn_user("NoMemory", NULL); return QUERY_INVALID; } qw->cb = cb; qw->pw = pw; qw->id = next_id++; qw->default_confirm = false; if (next_id == QUERY_INVALID) next_id++; if (!yes) yes = messages_get("Yes"); if (!no) no = messages_get("No"); /* set the text of the 'Yes' button and size accordingly */ err = utf8_to_local_encoding(yes, 0, &local_text); if (err != NSERROR_OK) { assert(err != NSERROR_BAD_ENCODING); LOG(("utf8_to_local_encoding_failed")); local_text = NULL; } icn = &query_template->icons[ICON_QUERY_YES]; len = strlen(local_text ? local_text : yes); len = max(len, icn->data.indirected_text.size - 1); memcpy(icn->data.indirected_text.text, local_text ? local_text: yes, len); icn->data.indirected_text.text[len] = '\0'; free(local_text); local_text = NULL; error = xwimptextop_string_width(icn->data.indirected_text.text, len, &width); if (error) { LOG(("xwimptextop_string_width: 0x%x:%s", error->errnum, error->errmess)); width = len * 16; } if (!query_yes_width) query_yes_width = icn->extent.x1 - icn->extent.x0; width += 44; if (width < query_yes_width) width = query_yes_width; icn->extent.x0 = tx = icn->extent.x1 - width; /* set the text of the 'No' button and size accordingly */ err = utf8_to_local_encoding(no, 0, &local_text); if (err != NSERROR_OK) { assert(err != NSERROR_BAD_ENCODING); LOG(("utf8_to_local_encoding_failed")); local_text = NULL; } icn = &query_template->icons[ICON_QUERY_NO]; len = strlen(local_text ? local_text : no); len = max(len, icn->data.indirected_text.size - 1); memcpy(icn->data.indirected_text.text, local_text ? local_text : no, len); icn->data.indirected_text.text[len] = '\0'; free(local_text); local_text = NULL; if (!query_no_width) query_no_width = icn->extent.x1 - icn->extent.x0; icn->extent.x1 = tx - 16; error = xwimptextop_string_width(icn->data.indirected_text.text, len, &width); if (error) { LOG(("xwimptextop_string_width: 0x%x:%s", error->errnum, error->errmess)); width = len * 16; } width += 28; if (width < query_no_width) width = query_no_width; icn->extent.x0 = icn->extent.x1 - width; error = xwimp_create_window(query_template, &qw->window); if (error) { warn_user("WimpError", error->errmess); free(qw); return QUERY_INVALID; } snprintf(query_buffer, sizeof query_buffer, "%s %s", messages_get(query), detail ? detail : ""); query_buffer[sizeof query_buffer - 1] = 0; ro_gui_set_icon_string(qw->window, ICON_QUERY_MESSAGE, query_buffer, true); xwimp_set_icon_state(qw->window, ICON_QUERY_HELP, wimp_ICON_DELETED, wimp_ICON_DELETED); if (x >= 0 && y >= 0) { x -= tx - 8; y += (query_template->visible.y1 - query_template->visible.y0) / 2; ro_gui_dialog_open_xy(qw->window, x, y); } else ro_gui_dialog_open(qw->window); ro_gui_wimp_event_set_user_data(qw->window, qw); ro_gui_wimp_event_register_mouse_click(qw->window, ro_gui_query_click); ro_gui_wimp_event_register_cancel(qw->window, ICON_QUERY_NO); ro_gui_wimp_event_register_ok(qw->window, ICON_QUERY_YES, ro_gui_query_apply); ro_gui_wimp_event_register_close_window(qw->window, ro_gui_query_close); error = xwimp_set_caret_position(qw->window, (wimp_i)-1, 0, 0, 1 << 25, -1); if (error) { LOG(("xwimp_get_caret_position: 0x%x : %s", error->errnum, error->errmess)); warn_user("WimpError", error->errmess); } /* put this query window at the head of our list */ if (gui_query_window_list) gui_query_window_list->prev = qw; qw->prev = NULL; qw->next = gui_query_window_list; gui_query_window_list = qw; return qw->id; }
static bool ro_treeview_mouse_click(wimp_pointer *pointer) { os_error *error; ro_treeview *tv; wimp_window_state state; int xpos, ypos; browser_mouse_state mouse; bool handled = false; tv = (ro_treeview *) ro_gui_wimp_event_get_user_data(pointer->w); if (tv == NULL) { LOG(("NULL treeview block for window: 0x%x", (unsigned int) pointer->w)); return false; } state.w = tv->w; error = xwimp_get_window_state(&state); if (error) { LOG(("xwimp_get_window_state: 0x%x: %s", error->errnum, error->errmess)); warn_user("WimpError", error->errmess); return false; } /* Convert the returned mouse coordinates into NetSurf's internal * units. */ xpos = ((pointer->pos.x - state.visible.x0) + state.xscroll - tv->origin.x) / 2; ypos = ((state.visible.y1 - pointer->pos.y) - state.yscroll + tv->origin.y) / 2; /* Start to process the mouse click. * * Select and Adjust are processed normally. To get filer-like operation * with selections, Menu clicks are passed to the treeview first as * Select if there are no selected nodes in the tree. */ mouse = 0; if (pointer->buttons == wimp_CLICK_MENU) { if (!tree_node_has_selection(tree_get_root(tv->tree))) mouse |= BROWSER_MOUSE_CLICK_1; } else { mouse = ro_gui_mouse_click_state(pointer->buttons, wimp_BUTTON_DOUBLE_CLICK_DRAG); /* Give the window input focus on Select-clicks. This wouldn't * be necessary if the core used the RISC OS caret. */ if (mouse & BROWSER_MOUSE_CLICK_1) xwimp_set_caret_position(tv->w, -1, -100, -100, 32, -1); } if (mouse != 0) { handled = tree_mouse_action(tv->tree, mouse, xpos, ypos); tv->drag = tree_drag_status(tv->tree); if (tv->drag != TREE_NO_DRAG) { tv->drag_start.x = xpos; tv->drag_start.y = ypos; } /* If it's a visible drag, start the RO side of the visible * effects. */ if (tv->drag == TREE_SELECT_DRAG || tv->drag == TREE_MOVE_DRAG) ro_treeview_drag_start(tv, pointer, &state); if (tv->callbacks != NULL && tv->callbacks->toolbar_button_update != NULL) tv->callbacks->toolbar_button_update(); } /* Special actions for some mouse buttons. Adjust closes the dialog; * Menu opens a menu. For the latter, we assume that the owning module * will have attached a window menu to our parent window with the auto * flag unset (so that we can fudge the selection above). If it hasn't, * the call will quietly fail. * * \TODO -- Adjust-click close isn't a perfect copy of what the RO * version did: adjust clicks anywhere close the tree, and * selections persist. */ switch(pointer->buttons) { case wimp_CLICK_ADJUST: if (handled) ro_gui_dialog_close(tv->w); break; case wimp_CLICK_MENU: ro_gui_wimp_event_process_window_menu_click(pointer); break; } return true; }
/** * Set the caret's position * * \param self Text area * \param caret 0-based character index to place caret at */ void ro_textarea_set_caret(uintptr_t self, unsigned int caret) { struct text_area *ta; size_t c_len, b_off; unsigned int i; size_t index; int x; os_coord os_line_height; rufl_code code; os_error *error; ta = (struct text_area *)self; if (!ta || ta->magic != MAGIC) { LOG(("magic doesn't match")); return; } c_len = utf8_length(ta->text); if (caret > c_len) caret = c_len; /* Find byte offset of caret position */ for (b_off = 0; caret > 0; caret--) b_off = utf8_next(ta->text, ta->text_len, b_off); /* Now find line in which byte offset appears */ for (i = 0; i < ta->line_count - 1; i++) if (ta->lines[i + 1].b_start > b_off) break; ta->caret_pos.line = i; /* Now calculate the char. offset of the caret in this line */ for (c_len = 0, ta->caret_pos.char_off = 0; c_len < b_off - ta->lines[i].b_start; c_len = utf8_next(ta->text + ta->lines[i].b_start, ta->lines[i].b_length, c_len)) ta->caret_pos.char_off++; /* Finally, redraw the WIMP caret */ index = ro_textarea_get_caret(self); os_line_height.x = 0; os_line_height.y = (int)((float)(ta->line_height - ta->line_spacing) * 0.62) + 1; ro_convert_pixels_to_os_units(&os_line_height, (os_mode)-1); for (b_off = 0; index-- > 0; b_off = utf8_next(ta->text, ta->text_len, b_off)) ; /* do nothing */ code = rufl_width(ta->font_family, ta->font_style, ta->font_size, ta->text + ta->lines[ta->caret_pos.line].b_start, b_off - ta->lines[ta->caret_pos.line].b_start, &x); if (code != rufl_OK) { if (code == rufl_FONT_MANAGER_ERROR) LOG(("rufl_width: 0x%x: %s", rufl_fm_error->errnum, rufl_fm_error->errmess)); else LOG(("rufl_width: 0x%x", code)); return; } error = xwimp_set_caret_position(ta->window, -1, x + MARGIN_LEFT, -((ta->caret_pos.line + 1) * ta->line_height) - ta->line_height / 4 + ta->line_spacing, os_line_height.y, -1); if (error) { LOG(("xwimp_set_caret_position: 0x%x: %s", error->errnum, error->errmess)); return; } }
bool ro_gui_url_bar_icon_resize(struct url_bar *url_bar, bool full) { int x0, y0, x1, y1; int centre; os_error *error; os_coord eig = {1, 1}; wimp_caret caret; if (url_bar == NULL || url_bar->window == NULL) return false; /* calculate 1px in OS units */ ro_convert_pixels_to_os_units(&eig, (os_mode) -1); /* The vertical centre line of the widget's extent. */ centre = url_bar->extent.y0 + (url_bar->extent.y1 - url_bar->extent.y0) / 2; /* Position the container icon. */ if (url_bar->container_icon != -1) { x0 = url_bar->extent.x0; x1 = url_bar->extent.x1 - url_bar->suggest_x - URLBAR_GRIGHT_GUTTER; y0 = centre - (URLBAR_HEIGHT / 2); y1 = y0 + URLBAR_HEIGHT; error = xwimp_resize_icon(url_bar->window, url_bar->container_icon, x0, y0, x1, y1); if (error != NULL) { LOG(("xwimp_resize_icon: 0x%x: %s", error->errnum, error->errmess)); warn_user("WimpError", error->errmess); url_bar->container_icon = -1; return false; } } /* Position the URL Suggest icon. */ if (url_bar->suggest_icon != -1) { x0 = url_bar->extent.x1 - url_bar->suggest_x; x1 = url_bar->extent.x1; y0 = centre - (url_bar->suggest_y / 2); y1 = y0 + url_bar->suggest_y; error = xwimp_resize_icon(url_bar->window, url_bar->suggest_icon, x0, y0, x1, y1); if (error != NULL) { LOG(("xwimp_resize_icon: 0x%x: %s", error->errnum, error->errmess)); warn_user("WimpError", error->errmess); url_bar->suggest_icon = -1; return false; } } /* Position the Text icon. */ if (url_bar->text_icon != -1) { x0 = url_bar->extent.x0 + URLBAR_FAVICON_WIDTH; x1 = url_bar->extent.x1 - eig.x - url_bar->suggest_x - URLBAR_GRIGHT_GUTTER; y0 = centre - (URLBAR_HEIGHT / 2) + eig.y; y1 = y0 + URLBAR_HEIGHT - 2 * eig.y; error = xwimp_resize_icon(url_bar->window, url_bar->text_icon, x0, y0, x1, y1); if (error != NULL) { LOG(("xwimp_resize_icon: 0x%x: %s", error->errnum, error->errmess)); warn_user("WimpError", error->errmess); url_bar->text_icon = -1; return false; } if (xwimp_get_caret_position(&caret) == NULL) { if ((caret.w == url_bar->window) && (caret.i == url_bar->text_icon)) { xwimp_set_caret_position(url_bar->window, url_bar->text_icon, caret.pos.x, caret.pos.y, -1, caret.index); } } } /* Position the Favicon icon. */ url_bar->favicon_extent.x0 = url_bar->extent.x0 + eig.x; url_bar->favicon_extent.x1 = url_bar->extent.x0 + URLBAR_FAVICON_WIDTH; url_bar->favicon_extent.y0 = centre - (URLBAR_HEIGHT / 2) + eig.y; url_bar->favicon_extent.y1 = url_bar->favicon_extent.y0 + URLBAR_HEIGHT - 2 * eig.y; return true; }