void ro_gui_download_update_status(struct gui_download_window *dw) { char *received; char *total_size; char *speed; char time[20] = "?"; struct timeval t; float dt; unsigned int left; float rate; os_error *error; int width; char *local_status; utf8_convert_ret err; gettimeofday(&t, 0); dt = (t.tv_sec + 0.000001 * t.tv_usec) - (dw->last_time.tv_sec + 0.000001 * dw->last_time.tv_usec); if (dt == 0) dt = 0.001; total_size = human_friendly_bytesize(max(dw->received, dw->total_size)); if (dw->ctx) { rate = (dw->received - dw->last_received) / dt; received = human_friendly_bytesize(dw->received); /* A simple 'modified moving average' download rate calculation * to smooth out rate fluctuations: chosen for simplicity. */ dw->average_points++; dw->average_rate = ((dw->average_points - 1) * dw->average_rate + rate) / dw->average_points; speed = human_friendly_bytesize(dw->average_rate); if (dw->total_size) { float f; if (dw->average_rate > 0) { left = (dw->total_size - dw->received) / dw->average_rate; sprintf(time, "%u:%.2u", left / 60, left % 60); } /* convert to local encoding */ err = utf8_to_local_encoding( messages_get("Download"), 0, &local_status); if (err != UTF8_CONVERT_OK) { /* badenc should never happen */ assert(err != UTF8_CONVERT_BADENC); /* hide nomem error */ snprintf(dw->status, sizeof dw->status, messages_get("Download"), received, total_size, speed, time); } else { snprintf(dw->status, sizeof dw->status, local_status, received, total_size, speed, time); free(local_status); } f = (float) dw->received / (float) dw->total_size; width = download_progress_width * f; } else { left = t.tv_sec - dw->start_time.tv_sec; sprintf(time, "%u:%.2u", left / 60, left % 60); err = utf8_to_local_encoding( messages_get("DownloadU"), 0, &local_status); if (err != UTF8_CONVERT_OK) { /* badenc should never happen */ assert(err != UTF8_CONVERT_BADENC); /* hide nomem error */ snprintf(dw->status, sizeof dw->status, messages_get("DownloadU"), received, speed, time); } else { snprintf(dw->status, sizeof dw->status, local_status, received, speed, time); free(local_status); } /* length unknown, stay at 0 til finished */ width = 0; } } else { left = dw->last_time.tv_sec - dw->start_time.tv_sec; if (left == 0) left = 1; rate = (float) dw->received / (float) left; sprintf(time, "%u:%.2u", left / 60, left % 60); speed = human_friendly_bytesize(rate); err = utf8_to_local_encoding(messages_get("Downloaded"), 0, &local_status); if (err != UTF8_CONVERT_OK) { /* badenc should never happen */ assert(err != UTF8_CONVERT_BADENC); /* hide nomem error */ snprintf(dw->status, sizeof dw->status, messages_get("Downloaded"), total_size, speed, time); } else { snprintf(dw->status, sizeof dw->status, local_status, total_size, speed, time); free(local_status); } /* all done */ width = download_progress_width; } dw->last_time = t; dw->last_received = dw->received; error = xwimp_resize_icon(dw->window, ICON_DOWNLOAD_PROGRESS, download_progress_x0, download_progress_y0, download_progress_x0 + width, download_progress_y1); if (error) { LOG(("xwimp_resize_icon: 0x%x: %s", error->errnum, error->errmess)); warn_user("WimpError", error->errmess); } error = xwimp_set_icon_state(dw->window, ICON_DOWNLOAD_STATUS, 0, 0); if (error) { LOG(("xwimp_set_icon_state: 0x%x: %s", error->errnum, error->errmess)); warn_user("WimpError", error->errmess); } if (dw->ctx) schedule(100, ro_gui_download_update_status_wrapper, dw); else schedule_remove(ro_gui_download_update_status_wrapper, dw); }
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; }
void ro_gui_history_redraw(wimp_draw *redraw) { osbool more; os_error *error; struct redraw_context ctx = { .interactive = true, .background_images = true, .plot = &ro_plotters }; error = xwimp_redraw_window(redraw, &more); if (error) { LOG(("xwimp_redraw_window: 0x%x: %s", error->errnum, error->errmess)); warn_user("WimpError", error->errmess); return; } while (more) { ro_plot_origin_x = redraw->box.x0 - redraw->xscroll; ro_plot_origin_y = redraw->box.y1 - redraw->yscroll; history_redraw(history_current, &ctx); error = xwimp_get_rectangle(redraw, &more); if (error) { LOG(("xwimp_get_rectangle: 0x%x: %s", error->errnum, error->errmess)); warn_user("WimpError", error->errmess); return; } } } /** * Handle mouse movements over the history window. */ void ro_gui_history_mouse_at(wimp_pointer *pointer) { int x, y; int width; const char *url; wimp_window_state state; wimp_icon_state ic; os_box box = {0, 0, 0, 0}; os_error *error; /* If the mouse hasn't moved, or if we don't want tooltips, exit */ if ((mouse_x == pointer->pos.x && mouse_y == pointer->pos.y) || !nsoption_bool(history_tooltip)) return; /* Update mouse position */ mouse_x = pointer->pos.x; mouse_y = pointer->pos.y; /* Find history tree entry under mouse */ state.w = history_window; 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; } x = (pointer->pos.x - (state.visible.x0 - state.xscroll)) / 2; y = -(pointer->pos.y - (state.visible.y1 - state.yscroll)) / 2; url = history_position_url(history_current, x, y); if (!url) { /* not over a tree entry => close tooltip window. */ error = xwimp_close_window(dialog_tooltip); if (error) { LOG(("xwimp_close_window: 0x%x: %s", error->errnum, error->errmess)); warn_user("WimpError", error->errmess); return; } return; } /* get width of string */ error = xwimptextop_string_width(url, strlen(url) > 256 ? 256 : strlen(url), &width); if (error) { LOG(("xwimptextop_string_width: 0x%x: %s", error->errnum, error->errmess)); warn_user("WimpError", error->errmess); return; } ro_gui_set_icon_string(dialog_tooltip, 0, url, true); /* resize icon appropriately */ ic.w = dialog_tooltip; ic.i = 0; error = xwimp_get_icon_state(&ic); if (error) { LOG(("xwimp_get_icon_state: 0x%x: %s", error->errnum, error->errmess)); warn_user("WimpError", error->errmess); return; } error = xwimp_resize_icon(dialog_tooltip, 0, ic.icon.extent.x0, ic.icon.extent.y0, width + 16, ic.icon.extent.y1); if (error) { LOG(("xwimp_resize_icon: 0x%x: %s", error->errnum, error->errmess)); warn_user("WimpError", error->errmess); return; } state.w = dialog_tooltip; 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; } /* update window extent */ box.x1 = width + 16; box.y0 = -36; error = xwimp_set_extent(dialog_tooltip, &box); if (error) { LOG(("xwimp_set_extent: 0x%x: %s", error->errnum, error->errmess)); warn_user("WimpError", error->errmess); return; } /* set visible area */ state.visible.x0 = pointer->pos.x + 24; state.visible.y0 = pointer->pos.y - 22 - 36; state.visible.x1 = pointer->pos.x + 24 + width + 16; state.visible.y1 = pointer->pos.y - 22; state.next = wimp_TOP; /* open window */ error = xwimp_open_window(PTR_WIMP_OPEN(&state)); if (error) { LOG(("xwimp_open_window: 0x%x: %s", error->errnum, error->errmess)); warn_user("WimpError", error->errmess); return; } }
void ro_gui_history_mouse_at(wimp_pointer *pointer, void *data) { int x, y; int width; const char *url; wimp_window_state state; wimp_icon_state ic; os_box box = {0, 0, 0, 0}; os_error *error; LOG(("Mouse at...")); /* If the mouse hasn't moved, or if we don't want tooltips, exit */ if ((mouse_x == pointer->pos.x && mouse_y == pointer->pos.y) || !nsoption_bool(history_tooltip)) return; /* Update mouse position */ mouse_x = pointer->pos.x; mouse_y = pointer->pos.y; /* Find history tree entry under mouse */ state.w = history_window; 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; } x = (pointer->pos.x - (state.visible.x0 - state.xscroll)) / 2; y = -(pointer->pos.y - (state.visible.y1 - state.yscroll)) / 2; url = history_position_url(history_current, x, y); if (!url) { /* not over a tree entry => close tooltip window. */ error = xwimp_close_window(dialog_tooltip); if (error) { LOG(("xwimp_close_window: 0x%x: %s", error->errnum, error->errmess)); warn_user("WimpError", error->errmess); return; } return; } /* get width of string */ error = xwimptextop_string_width(url, strlen(url) > 256 ? 256 : strlen(url), &width); if (error) { LOG(("xwimptextop_string_width: 0x%x: %s", error->errnum, error->errmess)); warn_user("WimpError", error->errmess); return; } ro_gui_set_icon_string(dialog_tooltip, 0, url, true); /* resize icon appropriately */ ic.w = dialog_tooltip; ic.i = 0; error = xwimp_get_icon_state(&ic); if (error) { LOG(("xwimp_get_icon_state: 0x%x: %s", error->errnum, error->errmess)); warn_user("WimpError", error->errmess); return; } error = xwimp_resize_icon(dialog_tooltip, 0, ic.icon.extent.x0, ic.icon.extent.y0, width + 16, ic.icon.extent.y1); if (error) { LOG(("xwimp_resize_icon: 0x%x: %s", error->errnum, error->errmess)); warn_user("WimpError", error->errmess); return; } state.w = dialog_tooltip; 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; } /* update window extent */ box.x1 = width + 16; box.y0 = -36; error = xwimp_set_extent(dialog_tooltip, &box); if (error) { LOG(("xwimp_set_extent: 0x%x: %s", error->errnum, error->errmess)); warn_user("WimpError", error->errmess); return; } /* set visible area */ state.visible.x0 = pointer->pos.x + 24; state.visible.y0 = pointer->pos.y - 22 - 36; state.visible.x1 = pointer->pos.x + 24 + width + 16; state.visible.y1 = pointer->pos.y - 22; state.next = wimp_TOP; /* open window */ error = xwimp_open_window(PTR_WIMP_OPEN(&state)); if (error) { LOG(("xwimp_open_window: 0x%x: %s", error->errnum, error->errmess)); warn_user("WimpError", error->errmess); return; } }