예제 #1
0
파일: edit.c 프로젝트: jff/mathspad
void edit_set_number_of_lines(void *window, int numlin)
{
    EDITINFO *einf;
    void *pdata;
    Window pwin;

    (void) get_window_type(*(Window*) window, &pwin, &pdata);
    (void) get_window_type(pwin, &pwin, &pdata);
    einf = (EDITINFO*) pdata;
    scrollbar_set(einf->scrollver, line_number(einf->info), numlin);
}
예제 #2
0
/*
 * Exported function.  Documented in scrollbar.h
 */
void scrollbar_mouse_drag_end(struct scrollbar *s,
		browser_mouse_state mouse, int x, int y)
{
	struct scrollbar_msg_data msg;
	int val, drag_start_pos;

	assert(s->dragging);

	drag_start_pos = s->drag_start_pos;
	val = (s->horizontal ? x : y) - s->drag_start_coord;

	if (s->drag_content)
		val = -val;
	if (val != 0)
		scrollbar_set(s, drag_start_pos + val, !(s->drag_content));

	s->dragging = false;
	s->drag_content = false;

	if (s->pair_drag) {
		s->pair_drag = false;

		drag_start_pos = s->pair->drag_start_pos;
		val = (s->pair->horizontal ? x : y) - s->pair->drag_start_coord;

		if (s->pair->drag_content)
			val = -val;
		if (val != 0)
			scrollbar_set(s->pair, drag_start_pos + val,
					!(s->pair->drag_content));

		s->pair->dragging = false;
		s->pair->drag_content = false;
	}

	msg.scrollbar = s;
	msg.msg = SCROLLBAR_MSG_SCROLL_FINISHED;
	s->client_callback(s->client_data, &msg);
}
예제 #3
0
/*
 * Exported function.  Documented in scrollbar.h
 */
const char *scrollbar_mouse_action(struct scrollbar *s,
		browser_mouse_state mouse, int x, int y)
{
	int x0, y0, x1, y1;
	int val;
	const char *status;
	bool h;

	/* we want mouse presses and mouse drags that were not started at the
	 * scrollbar indication bar to be launching actions on the scroll area
	 */
	bool but1 = ((mouse & BROWSER_MOUSE_PRESS_1) ||
			((mouse & BROWSER_MOUSE_HOLDING_1) &&
			(mouse & BROWSER_MOUSE_DRAG_ON) &&
			!s->dragging));
	bool but2 = ((mouse & BROWSER_MOUSE_PRESS_2) ||
			((mouse & BROWSER_MOUSE_HOLDING_2) &&
			(mouse & BROWSER_MOUSE_DRAG_ON) &&
			!s->dragging));

	h = s->horizontal;

	x0 = 0;
	y0 = 0;
	x1 = h ? s->length : SCROLLBAR_WIDTH;
	y1 = h ? SCROLLBAR_WIDTH : s->length;

	if (!s->dragging && !(x >= x0 && x <= x1 && y >= y0 && y <= y1)) {
		/* Not a drag and mouse outside scrollbar widget */
		return NULL;
	}


	if (h)
		val = x;
	else
		val = y;

	if (s->dragging) {
		val -= s->drag_start_coord;
		if (s->drag_content)
			val = -val;
		if (val != 0)
			scrollbar_set(s, s->drag_start_pos + val,
					!(s->drag_content));
		if (s->pair_drag) {
			scrollbar_mouse_action(s->pair, mouse, x, y);
			status = messages_get("ScrollBoth");
		} else
			status = messages_get(h ? "ScrollH" : "ScrollV");

		return status;
	}

	if (val < SCROLLBAR_WIDTH) {
		/* left/up arrow */
		
		status = messages_get(h ? "ScrollLeft" : "ScrollUp");
		if (but1)
			scrollbar_set(s, s->offset - SCROLLBAR_WIDTH, false);
		else if (but2)
			scrollbar_set(s, s->offset + SCROLLBAR_WIDTH, false);

	} else if (val < SCROLLBAR_WIDTH + s->bar_pos) {
		/* well between left/up arrow and bar */

		status = messages_get(h ? "ScrollPLeft" : "ScrollPUp");

		if (but1)
			scrollbar_set(s, s->offset - s->length, false);
		else if (but2)
			scrollbar_set(s, s->offset + s->length, false);

	} else if (val > s->length - SCROLLBAR_WIDTH) {
		/* right/down arrow */

		status = messages_get(h ? "ScrollRight" : "ScrollDown");

		if (but1)
			scrollbar_set(s, s->offset + SCROLLBAR_WIDTH, false);
		else if (but2)
			scrollbar_set(s, s->offset - SCROLLBAR_WIDTH, false);

	} else if (val > SCROLLBAR_WIDTH + s->bar_pos +
			s->bar_len) {
		/* well between right/down arrow and bar */

		status = messages_get(h ? "ScrollPRight" : "ScrollPDown");
		if (but1)
			scrollbar_set(s, s->offset + s->length, false);
		else if (but2)
			scrollbar_set(s, s->offset - s->length, false);
	}
	else {
		/* scrollbar position indication bar */
		
		status = messages_get(h ? "ScrollH" : "ScrollV");
	}

	
	if (mouse & (BROWSER_MOUSE_DRAG_1 | BROWSER_MOUSE_DRAG_2) &&
		   	(val >= SCROLLBAR_WIDTH + s->bar_pos
		   	&& val < SCROLLBAR_WIDTH + s->bar_pos +
		   			s->bar_len))
		/* The mouse event is a drag start on the scrollbar position
		 * indication bar. */
		scrollbar_drag_start_internal(s, x, y, false,
				(mouse & BROWSER_MOUSE_DRAG_2) ? true : false);

	return status;
}
예제 #4
0
파일: edit.c 프로젝트: jff/mathspad
void edit_open(void)
{
    int x = INTERSPACE;
    int y = INTERSPACE;
    unsigned int w=4,h=4;
    int i;
    XSizeHints size_hints;
    EDITINFO *einf;

    state_window = NULL;
    if ( (einf = (EDITINFO *) malloc( sizeof(EDITINFO) )) == NULL)
	message(MP_ERROR, translate("Out of memory in edit."));
    else {
	if (!state_open)
	    if (!last_xpos && !last_ypos) {
		last_xpos = (display_width - last_width)/2;
		last_ypos = (display_height - last_height)/2;
	    }
	einf->xpos = last_xpos;
	einf->ypos = last_ypos;
	einf->width = last_width;
	einf->height = last_height;
	einf->saved = MP_True;
	einf->auto_saved = MP_True;
	einf->view_mode = MP_False;
	einf->empty = MP_True;
	einf->iconized  = MP_True;
	einf->shell = MP_False;
	einf->fini = MP_False;
	einf->strt = MP_False;
	einf->buflen=0;
	einf->pid=0;
	einf->prcsbuf=NULL;
	einf->win_id = XCreateWindow(display, root_window, einf->xpos,
				     einf->ypos, einf->width, einf->height,
				     BORDERWIDTH, CopyFromParent, InputOutput,
				     visual,
				     edit_mask, &edit_attr);
	if (state_open)
	    size_hints.flags = USPosition | USSize | PMinSize;
	else
	    size_hints.flags = PPosition | PSize | PMinSize;
	wm_hints.initial_state =
	    ((iconic || as_icon) ? IconicState : NormalState);
	size_hints.min_width =
	    size_hints.min_height = pos_y_with + SCROLLBARSIZE*3;
	XSetWMProperties(display, einf->win_id, NULL, NULL,
			 NULL, 0, &size_hints, &wm_hints, &class_hints);
	wm_hints.initial_state = NormalState;
	set_protocols(einf->win_id);

	i=0;
	einf->headername = NULL;
	einf->filename = NULL;
	einf->pathname = NULL;
	einf->outputname = NULL;
	if (set_name(einf, NULL) &&
	    add_window(einf->win_id, MAINEDITWINDOW,
		       root_window, (void *) einf, translate(helpname[EDITHELP]))) {
	    while (i<NR_BUTTON &&
		   button_make(i, einf->win_id, translate(editbutton[perm[i]]), &x, y, 1,
			       (void*) einf, helpname[edithelp[i]],
			       NULL, NULL, edit_handle_button,
			       edit_handle_button, edit_handle_button, NULL))
		i++,x+=BINTERSPACE;
	    w = sub_width(last_width);
	    h = sub_height(last_height);
	    if (i==NR_BUTTON) {
		einf->drawwin_id =
		    XCreateWindow(display, einf->win_id,
				  pos_x_with, pos_y_with, w-2, h-2, 1,
				  CopyFromParent, InputOutput,
				  visual,
				  edit_mask, &edit_attr);
		if (add_window(einf->drawwin_id, EDITWINDOW,
			       einf->win_id, NULL, translate(helpname[EDITSUBHELP])))
		    i++;
	    }
	    if (i==NR_BUTTON +1 &&
		(einf->scrollhor =
		 scrollbar_make(HORIZONTAL, einf->win_id, pos_x_with,
				pos_y_without, w, font_width(),
				edit_scrollto, (void*) einf)))
		i++;
	    if (i==NR_BUTTON+2 &&
		(einf->scrollver =
		 scrollbar_make(VERTICAL, einf->win_id, pos_x_without,
				pos_y_with, h, line_height(),
				edit_scrollto, (void*) einf)))
		i++;
	    
	}
	if (i<NR_BUTTON+3) {
	    free(einf->headername);
	    free(einf->pathname);
	    free(einf->filename);
	    XDestroyWindow(display, einf->win_id);
	    destroy_window(einf->win_id);
	} else {
	    is_opened = MP_True;
	    scrollbar_set(einf->scrollver, 0, 1);
	    scrollbar_set(einf->scrollhor, 0, 80);
	    move_selection = !as_icon;
	    einf->info = open_editwindow(&einf->drawwin_id, w-2, h-2);
	    move_selection = MP_False;
	    (void) window_changed(einf->info);
	    number_icon++;
	    number_open++;
	    edit_is_open = MP_True;
	    edit_iconized = (number_icon==number_open);
	    state_window = einf;
	    XMapSubwindows(display, einf->win_id);
	    XMapWindow(display, einf->win_id);
	}
    }
}
예제 #5
0
static nserror
html_object_callback(hlcache_handle *object,
		     const hlcache_event *event,
		     void *pw)
{
	struct content_html_object *o = pw;
	html_content *c = (html_content *) o->parent;
	int x, y;
	struct box *box;

	assert(c->base.status != CONTENT_STATUS_ERROR);

	box = o->box;
	if (box == NULL && event->type != CONTENT_MSG_ERROR) {
		return NSERROR_OK;
	}

	switch (event->type) {
	case CONTENT_MSG_LOADING:
		if (c->base.status != CONTENT_STATUS_LOADING && c->bw != NULL)
			content_open(object,
					c->bw, &c->base,
					box->object_params);
		break;

	case CONTENT_MSG_READY:
		if (content_can_reformat(object)) {
			/* TODO: avoid knowledge of box internals here */
			content_reformat(object, false,
					box->max_width != UNKNOWN_MAX_WIDTH ?
							box->width : 0,
					box->max_width != UNKNOWN_MAX_WIDTH ?
							box->height : 0);

			/* Adjust parent content for new object size */
			html_object_done(box, object, o->background);
			if (c->base.status == CONTENT_STATUS_READY ||
					c->base.status == CONTENT_STATUS_DONE)
				content__reformat(&c->base, false,
						c->base.available_width,
						c->base.height);
		}
		break;

	case CONTENT_MSG_DONE:
		c->base.active--;
		LOG("%d fetches active", c->base.active);

		html_object_done(box, object, o->background);

		if (c->base.status != CONTENT_STATUS_LOADING &&
				box->flags & REPLACE_DIM) {
			union content_msg_data data;

			if (!box_visible(box))
				break;

			box_coords(box, &x, &y);

			data.redraw.x = x + box->padding[LEFT];
			data.redraw.y = y + box->padding[TOP];
			data.redraw.width = box->width;
			data.redraw.height = box->height;
			data.redraw.full_redraw = true;

			content_broadcast(&c->base, CONTENT_MSG_REDRAW, data);
		}
		break;

	case CONTENT_MSG_ERROR:
		hlcache_handle_release(object);

		o->content = NULL;

		if (box != NULL) {
			c->base.active--;
			LOG("%d fetches active", c->base.active);

			content_add_error(&c->base, "?", 0);
			html_object_failed(box, c, o->background);
		}
		break;

	case CONTENT_MSG_REDRAW:
		if (c->base.status != CONTENT_STATUS_LOADING) {
			union content_msg_data data = event->data;

			if (!box_visible(box))
				break;

			box_coords(box, &x, &y);

			if (object == box->background) {
				/* Redraw request is for background */
				css_fixed hpos = 0, vpos = 0;
				css_unit hunit = CSS_UNIT_PX;
				css_unit vunit = CSS_UNIT_PX;
				int width = box->padding[LEFT] + box->width +
						box->padding[RIGHT];
				int height = box->padding[TOP] + box->height +
						box->padding[BOTTOM];
				int t, h, l, w;

				/* Need to know background-position */
				css_computed_background_position(box->style,
						&hpos, &hunit, &vpos, &vunit);

				w = content_get_width(box->background);
				if (hunit == CSS_UNIT_PCT) {
					l = (width - w) * hpos / INTTOFIX(100);
				} else {
					l = FIXTOINT(nscss_len2px(hpos, hunit,
							box->style));
				}

				h = content_get_height(box->background);
				if (vunit == CSS_UNIT_PCT) {
					t = (height - h) * vpos / INTTOFIX(100);
				} else {
					t = FIXTOINT(nscss_len2px(vpos, vunit,
							box->style));
				}

				/* Redraw area depends on background-repeat */
				switch (css_computed_background_repeat(
						box->style)) {
				case CSS_BACKGROUND_REPEAT_REPEAT:
					data.redraw.x = 0;
					data.redraw.y = 0;
					data.redraw.width = box->width;
					data.redraw.height = box->height;
					break;

				case CSS_BACKGROUND_REPEAT_REPEAT_X:
					data.redraw.x = 0;
					data.redraw.y += t;
					data.redraw.width = box->width;
					break;

				case CSS_BACKGROUND_REPEAT_REPEAT_Y:
					data.redraw.x += l;
					data.redraw.y = 0;
					data.redraw.height = box->height;
					break;

				case CSS_BACKGROUND_REPEAT_NO_REPEAT:
					data.redraw.x += l;
					data.redraw.y += t;
					break;

				default:
					break;
				}

				data.redraw.object_width = box->width;
				data.redraw.object_height = box->height;

				/* Add offset to box */
				data.redraw.x += x;
				data.redraw.y += y;
				data.redraw.object_x += x;
				data.redraw.object_y += y;

				content_broadcast(&c->base,
						CONTENT_MSG_REDRAW, data);
				break;

			} else {
				/* Non-background case */
				if (hlcache_handle_get_content(object) ==
						event->data.redraw.object) {

					int w = content_get_width(object);
					int h = content_get_height(object);

					if (w != 0) {
						data.redraw.x =
							data.redraw.x *
							box->width / w;
						data.redraw.width =
							data.redraw.width *
							box->width / w;
					}

					if (h != 0) {
						data.redraw.y =
							data.redraw.y *
							box->height / h;
						data.redraw.height =
							data.redraw.height *
							box->height / h;
					}

					data.redraw.object_width = box->width;
					data.redraw.object_height = box->height;
				}

				data.redraw.x += x + box->padding[LEFT];
				data.redraw.y += y + box->padding[TOP];
				data.redraw.object_x += x + box->padding[LEFT];
				data.redraw.object_y += y + box->padding[TOP];
			}

			content_broadcast(&c->base, CONTENT_MSG_REDRAW, data);
		}
		break;

	case CONTENT_MSG_REFRESH:
		if (content_get_type(object) == CONTENT_HTML) {
			/* only for HTML objects */
			guit->misc->schedule(event->data.delay * 1000,
					html_object_refresh, o);
		}

		break;

	case CONTENT_MSG_LINK:
		/* Don't care about favicons that aren't on top level content */
		break;

	case CONTENT_MSG_GETCTX:
		*(event->data.jscontext) = NULL;
		break;

	case CONTENT_MSG_SCROLL:
		if (box->scroll_x != NULL)
			scrollbar_set(box->scroll_x, event->data.scroll.x0,
					false);
		if (box->scroll_y != NULL)
			scrollbar_set(box->scroll_y, event->data.scroll.y0,
					false);
		break;

	case CONTENT_MSG_DRAGSAVE:
	{
		union content_msg_data msg_data;
		if (event->data.dragsave.content == NULL)
			msg_data.dragsave.content = object;
		else
			msg_data.dragsave.content =
					event->data.dragsave.content;

		content_broadcast(&c->base, CONTENT_MSG_DRAGSAVE, msg_data);
	}
		break;

	case CONTENT_MSG_SAVELINK:
	case CONTENT_MSG_POINTER:
	case CONTENT_MSG_SELECTMENU:
	case CONTENT_MSG_GADGETCLICK:
		/* These messages are for browser window layer.
		 * we're not interested, so pass them on. */
		content_broadcast(&c->base, event->type, event->data);
		break;

	case CONTENT_MSG_CARET:
	{
		union html_focus_owner focus_owner;
		focus_owner.content = box;

		switch (event->data.caret.type) {
		case CONTENT_CARET_REMOVE:
		case CONTENT_CARET_HIDE:
			html_set_focus(c, HTML_FOCUS_CONTENT, focus_owner,
					true, 0, 0, 0, NULL);
			break;
		case CONTENT_CARET_SET_POS:
			html_set_focus(c, HTML_FOCUS_CONTENT, focus_owner,
					false, event->data.caret.pos.x,
					event->data.caret.pos.y,
					event->data.caret.pos.height,
					event->data.caret.pos.clip);
			break;
		}
	}
		break;

	case CONTENT_MSG_DRAG:
	{
		html_drag_type drag_type = HTML_DRAG_NONE;
		union html_drag_owner drag_owner;
		drag_owner.content = box;

		switch (event->data.drag.type) {
		case CONTENT_DRAG_NONE:
			drag_type = HTML_DRAG_NONE;
			drag_owner.no_owner = true;
			break;
		case CONTENT_DRAG_SCROLL:
			drag_type = HTML_DRAG_CONTENT_SCROLL;
			break;
		case CONTENT_DRAG_SELECTION:
			drag_type = HTML_DRAG_CONTENT_SELECTION;
			break;
		}
		html_set_drag_type(c, drag_type, drag_owner,
				event->data.drag.rect);
	}
		break;

	case CONTENT_MSG_SELECTION:
	{
		html_selection_type sel_type;
		union html_selection_owner sel_owner;

		if (event->data.selection.selection) {
			sel_type = HTML_SELECTION_CONTENT;
			sel_owner.content = box;
		} else {
			sel_type = HTML_SELECTION_NONE;
			sel_owner.none = true;
		}
		html_set_selection(c, sel_type, sel_owner,
				event->data.selection.read_only);
	}
		break;

	default:
		break;
	}

	if (c->base.status == CONTENT_STATUS_READY && c->base.active == 0 &&
			(event->type == CONTENT_MSG_LOADING ||
			event->type == CONTENT_MSG_DONE ||
			event->type == CONTENT_MSG_ERROR)) {
		/* all objects have arrived */
		content__reformat(&c->base, false, c->base.available_width,
				c->base.height);
		content_set_done(&c->base);
	}

	/* If  1) the configuration option to reflow pages while objects are
	 *        fetched is set
	 *     2) an object is newly fetched & converted,
	 *     3) the box's dimensions need to change due to being replaced
	 *     4) the object's parent HTML is ready for reformat,
	 *     5) the time since the previous reformat is more than the
	 *        configured minimum time between reformats
	 * then reformat the page to display newly fetched objects */
	else if (nsoption_bool(incremental_reflow) &&
			event->type == CONTENT_MSG_DONE &&
			box != NULL && !(box->flags & REPLACE_DIM) &&
			(c->base.status == CONTENT_STATUS_READY ||
			 c->base.status == CONTENT_STATUS_DONE) &&
			(wallclock() > c->base.reformat_time)) {
		content__reformat(&c->base, false, c->base.available_width,
				c->base.height);
	}

	return NSERROR_OK;
}