Beispiel #1
0
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 Pointer Entering Window events the history window.
 *
 * \param *entering		The Wimp_PointerEnteringWindow block.
 */

void ro_gui_history_pointer_entering(wimp_entering *entering)
{
	ro_mouse_track_start(ro_gui_history_track_end,
			ro_gui_history_mouse_at, NULL);
} 
Beispiel #2
0
void ro_gui_debugwin_redraw(wimp_draw *redraw)
{
	osbool more;
	os_error *error;

	/* Select RISC OS plotters */
	plot = ro_plotters;
	ro_plot_set_scale(1.0);

	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) {
		int clip_x0, clip_y0, clip_x1, clip_y1;

		/* Sep plot origin */
		ro_plot_origin_x = redraw->box.x0 - redraw->xscroll;
		ro_plot_origin_y = redraw->box.y1 - redraw->yscroll;

		/* Set clip rectangle */
		clip_x0 = (redraw->clip.x0 - ro_plot_origin_x) / 2; /* left   */
		clip_y0 = (ro_plot_origin_y - redraw->clip.y1) / 2; /* top    */
		clip_x1 = (redraw->clip.x1 - ro_plot_origin_x) / 2; /* right  */
		clip_y1 = (ro_plot_origin_y - redraw->clip.y0) / 2; /* bottom */
		plot.clip(clip_x0, clip_y0, clip_x1, clip_y1);

		/* Render the content debug table */
		debugwin_redraw(clip_x0, clip_y0, clip_x1, clip_y1);

		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;
		}
	}
}
Beispiel #3
0
void ro_treeview_redraw_loop(wimp_draw *redraw, ro_treeview *tv, osbool more)
{
	os_error *error;
	struct redraw_context ctx = {
		.interactive = true,
		.background_images = true,
		.plot = &ro_plotters
	};

	while (more) {
		ro_plot_origin_x = redraw->box.x0 - redraw->xscroll;
		ro_plot_origin_y = redraw->box.y1 - redraw->yscroll;

		if (tv != NULL && tv->tree != NULL) {
			struct rect clip;
			tree_draw(tv->tree, tv->origin.x/2, -(tv->origin.y/2),
					(redraw->clip.x0
					-(ro_plot_origin_x+tv->origin.x))/2,
					((ro_plot_origin_y+tv->origin.y)
					-redraw->clip.y1)/2,
					(redraw->clip.x1 - redraw->clip.x0)/2,
					(redraw->clip.y1 - redraw->clip.y0)/2,
					&ctx);

			/* Put the graphcis window back how the Wimp set it. */
			clip.x0 = (redraw->clip.x0 - ro_plot_origin_x) / 2;
			clip.y0 = (ro_plot_origin_y - redraw->clip.y1) / 2;
			clip.x1 = (redraw->clip.x1 - ro_plot_origin_x) / 2;
			clip.y1 = (ro_plot_origin_y - redraw->clip.y0) / 2;
			ro_plotters.clip(&clip);
	 	}

		error = xwimp_get_rectangle(redraw, &more);
		if (error) {
			LOG(("xwimp_redraw_window: 0x%x: %s",
					error->errnum, error->errmess));
			warn_user("WimpError", error->errmess);
			return;
		}
	}
}

/**
 * Callback to notify us of a new overall tree size.
 *
 * \param  tree		The tree being resized.
 * \param  width	The new width of the window.
 * \param  height	The new height of the window.
 * \param  *pw		The treeview object to be resized.
 */

void ro_treeview_resized(struct tree *tree, int width, int height,
		void *pw)
{
	if (pw != NULL) {
		ro_treeview		*tv = (ro_treeview *) pw;

		/* Store the width and height in terms of RISC OS work area. */

		tv->size.x = width * 2;
		tv->size.y = -(height * 2);

		/* Resize the window. */

		ro_treeview_set_window_extent(tv, tv->size.x, tv->size.y);
	}
}

/**
 * Callback to request that a section of the tree is scrolled into view.
 *
 * \param  y			The Y coordinate of top of the area in NS units.
 * \param  height		The height of the area in NS units.
 * \param  *pw			The treeview object affected.
 */

void ro_treeview_scroll_visible(int y, int height, void *pw)
{
	if (pw != NULL) {
		ro_treeview		*tv = (ro_treeview *) pw;
		os_error		*error;
		wimp_window_state	state;
		int			visible_t, visible_b;
		int			request_t, request_b;

		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;
		}

		/* Work out top and bottom of both the currently visible and
		 * the required areas, in terms of the RO work area.
		 */

		 visible_t = state.yscroll;
		 visible_b = state.yscroll
		 		- (state.visible.y1 - state.visible.y0);

		 request_t = -(2 * y);// - tv->origin.y;
		 request_b = -(2 * (y + height));// - tv->origin.y;

		 /* If the area is outside the visible window, then scroll it
		  * in to view.
		  */

		 if (request_t > visible_t || request_b < visible_b) {
		 	if (request_t > visible_t) {
		 		state.yscroll = request_t;
		 	} else if (request_b < visible_b) {
		 		state.yscroll = request_b + tv->origin.y
		 			+ (state.visible.y1 - state.visible.y0);

		 		/* If the required area is bigger than the
		 		 * visible extent, then align to the top and
		 		 * let the bottom disappear out of view.
		 		 */

		 		if (state.yscroll < request_t)
		 			state.yscroll = request_t;
		 	}

		 	error = xwimp_open_window((wimp_open *) &state);
		 	if (error) {
				LOG(("xwimp_open_window: 0x%x: %s",
						error->errnum, error->errmess));
				warn_user("WimpError", error->errmess);
				return;
			}
		}
	}
}

/**
 * Callback to return the tree window dimensions to the treeview system.
 *
 * \param  *width		Return the window width.
 * \param  *height		Return the window height.
 * \param  *pw			The treeview object to use.
 */

void ro_treeview_get_window_dimensions(int *width, int *height,
		void *pw)
{
	if (pw != NULL && (width != NULL || height != NULL)) {
		ro_treeview		*tv = (ro_treeview *) pw;
		os_error		*error;
		wimp_window_state	state;

		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;
		}

		if (width != NULL)
			*width = (state.visible.x1 - state.visible.x0) / 2;

		if (height != NULL)
			*height = (state.visible.y1 - state.visible.y0) / 2;
	}
}

/**
 * Resize the RISC OS window extent of a treeview.
 *
 * \param  *tv			The RISC OS treeview object to resize.
 * \param  width		The new width of the work area, in RO units.
 * \param  height		The new height of the work area, in RO units.
 */

void ro_treeview_set_window_extent(ro_treeview *tv, int width, int height)
{
	if (tv != NULL) {
		os_error		*error;
		os_box			extent;
		wimp_window_state	state;
		int			new_x, new_y;
		int			visible_x, visible_y;
		int			new_x_scroll, new_y_scroll;

		/* Calculate the new window extents, in RISC OS units. */

		new_x = width + tv->origin.x;
		new_y = height + tv->origin.y;

		/* Get details of the existing window, and start to sanity
		 * check the new extents.
		 */

		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;
		}

		/* If the extent is smaller than the current visible area,
		 * then extend it so that it matches the visible area.
		 */

		if (new_x < (state.visible.x1 - state.visible.x0))
			new_x = state.visible.x1 - state.visible.x0;

		if (new_y > (state.visible.y0 - state.visible.y1))
			new_y = state.visible.y0 - state.visible.y1;

		/* Calculate the maximum visible coordinates of the existing
		 * window.
		 */

		visible_x = state.xscroll +
				(state.visible.x1 - state.visible.x0);
		visible_y = state.yscroll +
				(state.visible.y0 - state.visible.y1);

		/* If the window is currently open, and the exising visible
		 * area is bigger than the new extent, then we need to reopen
		 * the window in an appropriare position before setting the
		 * new extent.
		 */

		if ((state.flags & wimp_WINDOW_OPEN) &&
				(visible_x > new_x || visible_y < new_y)) {
			new_x_scroll = state.xscroll;
			new_y_scroll = state.yscroll;

			if (visible_x > new_x)
				new_x_scroll = new_x - (state.visible.x1
						- state.visible.x0);

			if (visible_y < new_y)
				new_y_scroll = new_y - (state.visible.y0
						- state.visible.y1);

			if (new_x_scroll < 0) {
				state.visible.x1 -= new_x_scroll;
				state.xscroll = 0;
			} else {
				state.xscroll = new_x_scroll;
			}

			if (new_y_scroll > 0) {
				state.visible.y0 += new_y_scroll;
				state.yscroll = 0;
			} else {
				state.yscroll = new_y_scroll;
			}

			error = xwimp_open_window((wimp_open *) &state);
			if (error) {
				LOG(("xwimp_get_window_state: 0x%x: %s",
						error->errnum, error->errmess));
				warn_user("WimpError", error->errmess);
				return;
			}

			/* \todo -- Not sure if we need to reattach the
			 * toolbar here: the nested wimp seems to take care
			 * of it for us?
			 */
		}

		/* Now that the new extent fits into the visible window, we
		 * can resize the work area.  If we succeed, the values are
		 * recorded to save having to ask the Wimp for them
		 * each time.
		 */

		extent.x0 = 0;
		extent.y0 = new_y;
		extent.x1 = new_x;
		extent.y1 = 0;

		error = xwimp_set_extent(tv->w, &extent);
		if (error) {
			LOG(("xwimp_set_extent: 0x%x: %s",
					error->errnum, error->errmess));
			warn_user("WimpError", error->errmess);
			return;
		}

		tv->extent.x = new_x;
		tv->extent.y = new_y;
	}
}

/**
 * Handle RISC OS Window Open events for a treeview window.
 *
 * \param  *open		Pointer to the Window Open Event block.
 */

static void ro_treeview_open(wimp_open *open)
{
	ro_treeview	*tv;
	os_error	*error;
	os_box		extent;
	int		width, height;

	tv = (ro_treeview *) ro_gui_wimp_event_get_user_data(open->w);
	if (tv == NULL) {
		LOG(("NULL treeview block for window: ox%x",
				(unsigned int) open->w));
		return;
	}

	/* Calculate the window work area.  It must be at least the same as
	 * the current visible area of the window, and needs to contain the
	 * tree as defined by size.x + offset.x and size.y + offset.y (note
	 * that the offset.y should be set to cover any toolbar, so we can
	 * ignore the size of that).
	 */

	width = open->visible.x1 - open->visible.x0;
	height = open->visible.y0 - open->visible.y1;

	if (tv->size.x != 0 && width < (tv->origin.x + tv->size.x))
		width = (tv->origin.x + tv->size.x);

	if (tv->size.y != 0 && height > (tv->size.y + tv->origin.y))
		height = (tv->size.y + tv->origin.y);

	if (width != tv->extent.x || height != tv->extent.y) {
		extent.x0 = 0;
		extent.y0 = height;
		extent.x1 = width;
		extent.y1 = 0;

		error = xwimp_set_extent(tv->w, &extent);
		if (error) {
			LOG(("xwimp_set_extent: 0x%x: %s",
					error->errnum, error->errmess));
			warn_user("WimpError", error->errmess);
			return;
		}

		tv->extent.x = width;
		tv->extent.y = height;
	}

	/* \todo -- Might need to add vertical scrollbar hiding back in here? */

	error = xwimp_open_window(open);
	if (error) {
		LOG(("xwimp_open_window: 0x%x: %s",
				error->errnum, error->errmess));
		warn_user("WimpError", error->errmess);
	}

	if (tv->tb)
		ro_toolbar_process(tv->tb, -1, false);
}
Beispiel #4
0
/**
 * Internal textarea redraw routine
 *
 * \param redraw Redraw/update request block
 * \param update True if update, false if full redraw
 */
void ro_textarea_redraw_internal(wimp_draw *redraw, bool update)
{
	struct text_area *ta;
	int clip_x0, clip_y0, clip_x1, clip_y1;
	int line0, line1, line;
	osbool more;
	rufl_code code;
	os_error *error;

	ta = (struct text_area *)ro_gui_wimp_event_get_user_data(redraw->w);

	if (update)
		error = xwimp_update_window(redraw, &more);
	else
		error = xwimp_redraw_window(redraw, &more);
	if (error) {
		LOG(("xwimp_redraw_window: 0x%x: %s",
				error->errnum, error->errmess));
		return;
	}

	while (more) {
		clip_x0 = redraw->clip.x0 - (redraw->box.x0-redraw->xscroll);
		clip_y0 = (redraw->box.y1-redraw->yscroll) - redraw->clip.y1;
		clip_x1 = redraw->clip.x1 - (redraw->box.x0-redraw->xscroll);
		clip_y1 = (redraw->box.y1-redraw->yscroll) - redraw->clip.y0;

		error = xcolourtrans_set_gcol(
				(ta->flags & TEXTAREA_READONLY) ? 0xD9D9D900
								: 0xFFFFFF00,
				colourtrans_SET_BG_GCOL | colourtrans_USE_ECFS_GCOL,
				os_ACTION_OVERWRITE, 0, 0);
		if (error) {
			LOG(("xcolourtrans_set_gcol: 0x%x: %s",
					error->errnum, error->errmess));
			return;
		}

		error = xos_clg();
		if (error) {
			LOG(("xos_clg: 0x%x: %s",
					error->errnum, error->errmess));
			return;
		}

		if (!ta->lines)
			/* Nothing to redraw */
			return;

		line0 = clip_y0 / ta->line_height - 1;
		line1 = clip_y1 / ta->line_height + 1;

		if (line0 < 0)
			line0 = 0;
		if (line1 < 0)
			line1 = 0;
		if (ta->line_count - 1 < (unsigned)line0)
			line0 = ta->line_count - 1;
		if (ta->line_count - 1 < (unsigned)line1)
			line1 = ta->line_count - 1;
		if (line1 < line0)
			line1 = line0;

		for (line = line0; line <= line1; line++) {
			if (ta->lines[line].b_length == 0)
				continue;

			error = xcolourtrans_set_font_colours(font_CURRENT,
					(ta->flags & TEXTAREA_READONLY) ?
						0xD9D9D900 : 0xFFFFFF00,
					0x00000000, 14, 0, 0, 0);
			if (error) {
				LOG(("xcolourtrans_set_font_colours: 0x%x: %s",
					error->errnum, error->errmess));
				return;
			}

			code = rufl_paint(ta->font_family, ta->font_style,
					ta->font_size,
					ta->text + ta->lines[line].b_start,
					ta->lines[line].b_length,
					redraw->box.x0 - redraw->xscroll + MARGIN_LEFT,
					redraw->box.y1 - redraw->yscroll -
						((line + 1) *
						ta->line_height - ta->line_spacing),
					rufl_BLEND_FONT);
			if (code != rufl_OK) {
				if (code == rufl_FONT_MANAGER_ERROR)
					LOG(("rufl_paint: rufl_FONT_MANAGER_ERROR: 0x%x: %s",
						rufl_fm_error->errnum,
						rufl_fm_error->errmess));
				else
					LOG(("rufl_paint: 0x%x", code));
			}
		}

		error = xwimp_get_rectangle(redraw, &more);
		if (error) {
			LOG(("xwimp_get_rectangle: 0x%x: %s",
					error->errnum, error->errmess));
			return;
		}
	}
}
Beispiel #5
0
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;
	}
}
Beispiel #6
0
bool
RiscosGui::run()
{
    GNASH_REPORT_FUNCTION;

    os_t t, now;
    wimp_block block;
    wimp_event_no event;
    osbool more;
    os_error *error;

    t = os_read_monotonic_time();

    while (!_quit) {
        error = xwimp_poll_idle(wimp_SAVE_FP, &block, t, NULL, &event);
        if (error) {
            log_debug("%s\n", error->errmess);
            return false;
        }

        switch (event) {
        case wimp_NULL_REASON_CODE:
            now = os_read_monotonic_time();
            if (now > t) {
                if (_timeout > now) {
                    _quit = true;
                } else {
                    // TODO: pay attention to interval
//            if ((os_t)_interval <= (now - t) * 10) {
                    advance_movie(this);
//            }
                    now = os_read_monotonic_time();
                    t = now + 10;
                }
            }
            break;
        case wimp_REDRAW_WINDOW_REQUEST:
            error = xwimp_redraw_window(&block.redraw, &more);
            if (error) {
                log_debug("%s\n", error->errmess);
                return false;
            }
            while (more) {
//          rect bounds(block.redraw.clip.x0 / 2, block.redraw.clip.y0 / 2,
//                      block.redraw.clip.x1 / 2, block.redraw.clip.y1 / 2);
//          log_debug("Clip rect: (%d, %d)(%d, %d)\n",
//                  block.redraw.clip.x0 / 2, block.redraw.clip.y0 / 2,
//                  block.redraw.clip.x1 / 2, block.redraw.clip.y1 / 2);
                // TODO: Make this use the clipping rectangle (convert to TWIPS)
                rect bounds(-1e10f, -1e10f, 1e10f, 1e10f);
#ifdef RENDERER_AGG
                setInvalidatedRegion(bounds);
#endif
                renderBuffer();
                error = xwimp_get_rectangle(&block.redraw, &more);
                if (error) {
                    log_debug("%s\n", error->errmess);
                    return false;
                }
            }
            break;
        case wimp_OPEN_WINDOW_REQUEST:
            error = xwimp_open_window(&block.open);
            if (error)
                log_debug("%s\n", error->errmess);
            break;
        case wimp_CLOSE_WINDOW_REQUEST:
            _quit = true;
            break;
        case wimp_POINTER_LEAVING_WINDOW:
            break;
        case wimp_POINTER_ENTERING_WINDOW:
            break;
        case wimp_MOUSE_CLICK:
            break;
        case wimp_USER_DRAG_BOX:
            break;
        case wimp_MENU_SELECTION:
            break;
        case wimp_SCROLL_REQUEST:
            break;
        case wimp_LOSE_CARET:
            break;
        case wimp_GAIN_CARET:
            break;
        case wimp_POLLWORD_NON_ZERO:
            break;
        case wimp_USER_MESSAGE:
        case wimp_USER_MESSAGE_RECORDED:
        case wimp_USER_MESSAGE_ACKNOWLEDGE:
            switch (block.message.action) {
            case message_QUIT:
                _quit = true;
                break;
            default:
//          user_message(event, &(block.message));
                break;
            }
            break;
        }
    }

    return true;
}