summaryrefslogtreecommitdiff
path: root/desktop
diff options
context:
space:
mode:
authorMichael Drake <tlsa@netsurf-browser.org>2011-09-04 17:24:45 +0000
committerMichael Drake <tlsa@netsurf-browser.org>2011-09-04 17:24:45 +0000
commit19317c76bade273b6d71cef4e6aa33e50479f9d9 (patch)
tree22a36f9997db02379618a74c6687071d28d97917 /desktop
parente82474afed92abfa5344be7b06fcd99535bb9dfb (diff)
downloadnetsurf-19317c76bade273b6d71cef4e6aa33e50479f9d9.tar.gz
netsurf-19317c76bade273b6d71cef4e6aa33e50479f9d9.tar.bz2
Implement frames in the core.
svn path=/trunk/netsurf/; revision=12709
Diffstat (limited to 'desktop')
-rw-r--r--desktop/browser.c330
-rw-r--r--desktop/frames.c66
2 files changed, 284 insertions, 112 deletions
diff --git a/desktop/browser.c b/desktop/browser.c
index 7701ad9d4..b4c5cc200 100644
--- a/desktop/browser.c
+++ b/desktop/browser.c
@@ -147,7 +147,7 @@ bool browser_window_redraw(struct browser_window *bw, int x, int y,
return false;
}
- if (bw->current_content == NULL) {
+ if (bw->current_content == NULL && bw->children == NULL) {
/* Browser window has no content, render blank fill */
ctx->plot->clip(clip);
return ctx->plot->rectangle(clip->x0, clip->y0,
@@ -155,15 +155,73 @@ bool browser_window_redraw(struct browser_window *bw, int x, int y,
plot_style_fill_white);
}
- if (bw->browser_window_type != BROWSER_WINDOW_IFRAME &&
- ctx->plot->option_knockout) {
+ /* Browser window has content OR children (frames) */
+
+ if (bw->window != NULL && ctx->plot->option_knockout) {
+ /* Root browser window: start knockout */
knockout_plot_start(ctx, &new_ctx);
}
- /* Browser window has content */
-
new_ctx.plot->clip(clip);
+ /* Handle redraw of any browser window children */
+ if (bw->children) {
+ struct browser_window *child;
+ int cur_child;
+ int children = bw->rows * bw->cols;
+
+ if (bw->window != NULL)
+ /* Root browser window; start with blank fill */
+ plot_ok &= new_ctx.plot->rectangle(clip->x0, clip->y0,
+ clip->x1, clip->y1,
+ plot_style_fill_white);
+
+ /* Loop through all children of bw */
+ for (cur_child = 0; cur_child < children; cur_child++) {
+ /* Set current child */
+ child = &bw->children[cur_child];
+
+ /* Get frame edge box in global coordinates */
+ content_clip.x0 = (x + child->x) * child->scale;
+ content_clip.y0 = (y + child->y) * child->scale;
+ content_clip.x1 = content_clip.x0 +
+ child->width * child->scale;
+ content_clip.y1 = content_clip.y0 +
+ child->height * child->scale;
+
+ /* Intersect it with clip rectangle */
+ if (content_clip.x0 < clip->x0)
+ content_clip.x0 = clip->x0;
+ if (content_clip.y0 < clip->y0)
+ content_clip.y0 = clip->y0;
+ if (clip->x1 < content_clip.x1)
+ content_clip.x1 = clip->x1;
+ if (clip->y1 < content_clip.y1)
+ content_clip.y1 = clip->y1;
+
+ /* Skip this frame if it lies outside clip rectangle */
+ if (content_clip.x0 >= content_clip.x1 ||
+ content_clip.y0 >= content_clip.y1)
+ continue;
+
+ /* Redraw frame */
+ plot_ok &= browser_window_redraw(child,
+ x + child->x, y + child->y,
+ &content_clip, &new_ctx);
+ }
+
+ /* Nothing else to redraw for browser windows with children;
+ * cleanup and return */
+ if (bw->window != NULL && ctx->plot->option_knockout) {
+ /* Root browser window: knockout end */
+ knockout_plot_end();
+ }
+
+ return plot_ok;
+ }
+
+ /* Handle browser windows with content to redraw */
+
content_type = content_get_type(bw->current_content);
if (content_type != CONTENT_HTML && content_type != CONTENT_TEXTPLAIN) {
/* Set render area according to scale */
@@ -229,8 +287,8 @@ bool browser_window_redraw(struct browser_window *bw, int x, int y,
}
}
- if (bw->browser_window_type != BROWSER_WINDOW_IFRAME &&
- ctx->plot->option_knockout) {
+ if (bw->window != NULL && ctx->plot->option_knockout) {
+ /* Root browser window: end knockout */
knockout_plot_end();
}
@@ -254,16 +312,12 @@ bool browser_window_redraw_ready(struct browser_window *bw)
/* exported interface, documented in browser.h */
void browser_window_update_extent(struct browser_window *bw)
{
- switch (bw->browser_window_type) {
- default:
- /* Fall through until core frame(set)s are implemented */
- case BROWSER_WINDOW_NORMAL:
+ if (bw->window != NULL)
+ /* Front end window */
gui_window_update_extent(bw->window);
- break;
- case BROWSER_WINDOW_IFRAME:
+ else
+ /* Core-managed browser window */
browser_window_handle_scrollbars(bw);
- break;
- }
}
/* exported interface, documented in browser.h */
@@ -277,16 +331,22 @@ void browser_window_get_position(struct browser_window *bw, bool root,
while (bw) {
switch (bw->browser_window_type) {
- default:
- /* fall through to NORMAL until frame(set)s are handled
- * in the core */
+
+ case BROWSER_WINDOW_FRAME:
+ case BROWSER_WINDOW_FRAMESET:
+ *pos_x += bw->x * bw->scale;
+ *pos_y += bw->y * bw->scale;
+ break;
+
case BROWSER_WINDOW_NORMAL:
/* There is no offset to the root browser window */
break;
- case BROWSER_WINDOW_IFRAME:
- *pos_x += (bw->x - scrollbar_get_offset(bw->scroll_x)) * bw->scale;
- *pos_y += (bw->y - scrollbar_get_offset(bw->scroll_y)) * bw->scale;
+ case BROWSER_WINDOW_IFRAME:
+ *pos_x += (bw->x - scrollbar_get_offset(bw->scroll_x)) *
+ bw->scale;
+ *pos_y += (bw->y - scrollbar_get_offset(bw->scroll_y)) *
+ bw->scale;
break;
}
@@ -305,18 +365,13 @@ void browser_window_set_position(struct browser_window *bw, int x, int y)
{
assert(bw != NULL);
- switch (bw->browser_window_type) {
- default:
- /* fall through to NORMAL until frame(set)s are handled
- * in the core */
- case BROWSER_WINDOW_NORMAL:
- /* TODO: Not implemented yet */
- break;
- case BROWSER_WINDOW_IFRAME:
-
+ if (bw->window == NULL) {
+ /* Core managed browser window */
bw->x = x;
bw->y = y;
- break;
+ } else {
+ LOG(("Asked to set position of front end window."));
+ assert(0);
}
}
@@ -388,21 +443,16 @@ void browser_window_scroll_visible(struct browser_window *bw,
{
assert(bw != NULL);
- switch (bw->browser_window_type) {
- default:
- /* fall through to NORMAL until frame(set)s are handled
- * in the core */
- case BROWSER_WINDOW_NORMAL:
+ if (bw->window != NULL) {
+ /* Front end window */
gui_window_scroll_visible(bw->window,
rect->x0, rect->y0, rect->x1, rect->y1);
- break;
-
- case BROWSER_WINDOW_IFRAME:
+ } else {
+ /* Core managed browser window */
if (bw->scroll_x != NULL)
scrollbar_set(bw->scroll_x, rect->x0, false);
if (bw->scroll_y != NULL)
scrollbar_set(bw->scroll_y, rect->y0, false);
- break;
}
}
@@ -936,6 +986,14 @@ nserror browser_window_callback(hlcache_handle *c,
.x1 = event->data.redraw.x + event->data.redraw.width,
.y1 = event->data.redraw.y + event->data.redraw.height
};
+
+ if (bw->browser_window_type == BROWSER_WINDOW_FRAME) {
+ rect.x0 -= scrollbar_get_offset(bw->scroll_x);
+ rect.y0 -= scrollbar_get_offset(bw->scroll_y);
+ rect.x1 -= scrollbar_get_offset(bw->scroll_x);
+ rect.y1 -= scrollbar_get_offset(bw->scroll_y);
+ }
+
browser_window_update_box(bw, &rect);
}
break;
@@ -974,20 +1032,13 @@ void browser_window_get_dimensions(struct browser_window *bw,
{
assert(bw);
- switch (bw->browser_window_type) {
- case BROWSER_WINDOW_IFRAME:
+ if (bw->window == NULL) {
+ /* Core managed browser window */
*width = bw->width;
*height = bw->height;
- break;
-
- case BROWSER_WINDOW_FRAME:
- case BROWSER_WINDOW_FRAMESET:
- case BROWSER_WINDOW_NORMAL:
- /* root window (or frame(set), currently); browser window is
- * size of gui window viewport */
- assert(bw->window);
+ } else {
+ /* Front end window */
gui_window_get_dimensions(bw->window, width, height, scaled);
- break;
}
}
@@ -1005,17 +1056,13 @@ void browser_window_set_dimensions(struct browser_window *bw,
{
assert(bw);
- switch (bw->browser_window_type) {
- case BROWSER_WINDOW_IFRAME:
+ if (bw->window == NULL) {
+ /* Core managed browser window */
bw->width = width;
bw->height = height;
- break;
-
- case BROWSER_WINDOW_FRAME:
- case BROWSER_WINDOW_FRAMESET:
- case BROWSER_WINDOW_NORMAL:
- /* TODO: Not implemented yet */
- break;
+ } else {
+ LOG(("Asked to set dimensions of front end window."));
+ assert(0);
}
}
@@ -1183,9 +1230,7 @@ void browser_window_update(struct browser_window *bw, bool scroll_to_top)
return;
switch (bw->browser_window_type) {
- default:
- /* Fall through to normal
- * (frame(set)s aren't handled by the core yet) */
+
case BROWSER_WINDOW_NORMAL:
/* Root browser window, constituting a front end window/tab */
gui_window_set_title(bw->window,
@@ -1206,6 +1251,7 @@ void browser_window_update(struct browser_window *bw, bool scroll_to_top)
gui_window_redraw_window(bw->window);
break;
+
case BROWSER_WINDOW_IFRAME:
/* Internal iframe browser window */
@@ -1223,6 +1269,35 @@ void browser_window_update(struct browser_window *bw, bool scroll_to_top)
html_redraw_a_box(bw->parent->current_content, bw->box);
break;
+
+ case BROWSER_WINDOW_FRAME:
+ {
+ struct rect rect;
+ browser_window_update_extent(bw);
+
+ if (scroll_to_top)
+ browser_window_set_scroll(bw, 0, 0);
+
+ /* if frag_id exists, then try to scroll to it */
+ /** \TODO don't do this if the user has scrolled */
+ if (bw->frag_id && html_get_id_offset(bw->current_content,
+ bw->frag_id, &x, &y)) {
+ browser_window_set_scroll(bw, x, y);
+ }
+
+ rect.x0 = 0;
+ rect.y0 = 0;
+ rect.x1 = bw->width;
+ rect.y1 = bw->height;
+
+ browser_window_update_box(bw, &rect);
+ }
+ break;
+
+ default:
+ case BROWSER_WINDOW_FRAMESET:
+ /* Nothing to do */
+ break;
}
}
@@ -1233,15 +1308,13 @@ void browser_window_update_box(struct browser_window *bw, struct rect *rect)
int pos_y;
struct browser_window *top;
- switch (bw->browser_window_type) {
- default:
- /* fall through for frame(set)s,
- * until they are handled by core */
- case BROWSER_WINDOW_NORMAL:
- gui_window_update_box(bw->window, rect);
- break;
+ assert(bw);
- case BROWSER_WINDOW_IFRAME:
+ if (bw->window != NULL) {
+ /* Front end window */
+ gui_window_update_box(bw->window, rect);
+ } else {
+ /* Core managed browser window */
browser_window_get_position(bw, true, &pos_x, &pos_y);
top = browser_window_get_root(bw);
@@ -1252,7 +1325,6 @@ void browser_window_update_box(struct browser_window *bw, struct rect *rect)
rect->y1 += pos_y / bw->scale;
gui_window_update_box(top->window, rect);
- break;
}
}
@@ -1535,6 +1607,8 @@ void browser_window_destroy_internal(struct browser_window *bw)
*
* \param bw The browser window to find the owner of
* \return the browser window's owner
+ *
+ * TODO: REMOVE THIS FUNCTION
*/
struct browser_window *browser_window_owner(struct browser_window *bw)
@@ -1579,7 +1653,10 @@ void browser_window_reformat(struct browser_window *bw, bool background,
/* Iframe dimensions are already scaled in parent's layout */
width /= bw->scale;
height /= bw->scale;
- } else {
+ }
+
+ if (bw->window == NULL) {
+ /* Core managed browser window; subtract scrollbar width */
width -= bw->scroll_y ? SCROLLBAR_WIDTH : 0;
height -= bw->scroll_x ? SCROLLBAR_WIDTH : 0;
@@ -1865,22 +1942,64 @@ void browser_window_mouse_track(struct browser_window *bw,
const char *status = NULL;
gui_pointer_shape pointer = GUI_POINTER_DEFAULT;
- if (bw->window != NULL) {
- /* root browser window */
- if (bw->drag_window && bw != bw->drag_window) {
- /* There's an active drag in a sub window.
- * Pass the mouse action straight on to that bw. */
- int off_x = 0;
- int off_y = 0;
-
- browser_window_get_position(bw->drag_window, true,
- &off_x, &off_y);
+ if (bw->window != NULL && bw->drag_window && bw != bw->drag_window) {
+ /* This is the root browser window and there's an active drag
+ * in a sub window.
+ * Pass the mouse action straight on to that bw. */
+ struct browser_window *drag_bw = bw->drag_window;
+ int off_x = 0;
+ int off_y = 0;
- browser_window_mouse_track(bw->drag_window, mouse,
+ browser_window_get_position(drag_bw, true, &off_x, &off_y);
+
+ if (drag_bw->browser_window_type == BROWSER_WINDOW_FRAME) {
+ off_x -= scrollbar_get_offset(drag_bw->scroll_x);
+ off_y -= scrollbar_get_offset(drag_bw->scroll_y);
+
+ browser_window_mouse_track(drag_bw, mouse,
+ x - off_x, y - off_y);
+
+ } else if (drag_bw->browser_window_type ==
+ BROWSER_WINDOW_IFRAME) {
+ browser_window_mouse_track(drag_bw, mouse,
x - off_x / bw->scale,
y - off_y / bw->scale);
+ }
+ return;
+ }
+
+ if (bw->children) {
+ /* Browser window has children (frames) */
+ struct browser_window *child;
+ int cur_child;
+ int children = bw->rows * bw->cols;
+
+ for (cur_child = 0; cur_child < children; cur_child++) {
+
+ child = &bw->children[cur_child];
+
+ if (x < child->x || y < child->y ||
+ child->x + child->width < x ||
+ child->y + child->height < y) {
+ /* Click not in this child */
+ continue;
+ }
+
+ /* It's this child that contains the mouse; pass
+ * mouse action on to child */
+ browser_window_mouse_track(child, mouse,
+ x - child->x + scrollbar_get_offset(
+ child->scroll_x),
+ y - child->y + scrollbar_get_offset(
+ child->scroll_y));
+
+ /* Mouse action was for this child, we're done */
return;
}
+
+ /* Odd if we reached here, but nothing else can use the click
+ * when there are children. */
+ return;
}
if (c == NULL && bw->drag_type != DRAGGING_FRAME)
@@ -1978,6 +2097,38 @@ void browser_window_mouse_click(struct browser_window *bw,
const char *status = NULL;
gui_pointer_shape pointer = GUI_POINTER_DEFAULT;
+ if (bw->children) {
+ /* Browser window has children (frames) */
+ struct browser_window *child;
+ int cur_child;
+ int children = bw->rows * bw->cols;
+
+ for (cur_child = 0; cur_child < children; cur_child++) {
+
+ child = &bw->children[cur_child];
+
+ if (x < child->x || y < child->y ||
+ child->x + child->width < x ||
+ child->y + child->height < y) {
+ /* Click not in this child */
+ continue;
+ }
+
+ /* It's this child that contains the click; pass it
+ * on to child. */
+ browser_window_mouse_click(child, mouse,
+ x - child->x + scrollbar_get_offset(
+ child->scroll_x),
+ y - child->y + scrollbar_get_offset(
+ child->scroll_y));
+
+ /* Mouse action was for this child, we're done */
+ return;
+ }
+
+ return;
+ }
+
if (!c)
return;
@@ -2136,19 +2287,16 @@ void browser_window_page_drag_start(struct browser_window *bw, int x, int y)
bw->drag_start_x = x;
bw->drag_start_y = y;
- switch (bw->browser_window_type) {
- default:
- /* fall through until frame(set)s are handled in core */
- case BROWSER_WINDOW_NORMAL:
+ if (bw->window != NULL) {
+ /* Front end window */
gui_window_get_scroll(bw->window, &bw->drag_start_scroll_x,
&bw->drag_start_scroll_y);
gui_window_scroll_start(bw->window);
- break;
- case BROWSER_WINDOW_IFRAME:
+ } else {
+ /* Core managed browser window */
bw->drag_start_scroll_x = scrollbar_get_offset(bw->scroll_x);
bw->drag_start_scroll_y = scrollbar_get_offset(bw->scroll_y);
- break;
}
}
diff --git a/desktop/frames.c b/desktop/frames.c
index f1710437f..5cf82f9d5 100644
--- a/desktop/frames.c
+++ b/desktop/frames.c
@@ -61,7 +61,18 @@ void browser_window_scroll_callback(void *client_data,
/* TODO: Is this needed? */
break;
case SCROLLBAR_MSG_MOVED:
- html_redraw_a_box(bw->parent->current_content, bw->box);
+ if (bw->browser_window_type == BROWSER_WINDOW_IFRAME) {
+ html_redraw_a_box(bw->parent->current_content, bw->box);
+ } else {
+ struct rect rect;
+
+ rect.x0 = 0;
+ rect.y0 = 0;
+ rect.x1 = bw->width;
+ rect.y1 = bw->height;
+
+ browser_window_update_box(bw, &rect);
+ }
break;
case SCROLLBAR_MSG_SCROLL_START:
if (scrollbar_is_horizontal(scrollbar_data->scrollbar))
@@ -315,15 +326,12 @@ void browser_window_create_frameset(struct browser_window *bw,
warn_user("NoMemory", 0);
}
- /* TODO: When frames are handled in core:
- * window->cur_sel = bw->cur_sel; */
+ window->cur_sel = bw->cur_sel;
+ window->scale = bw->scale;
/* linking */
window->parent = bw;
- /* gui window */
- window->window = gui_create_browser_window(window, bw, false);
-
if (window->name)
LOG(("Created frame '%s'", window->name));
else
@@ -393,19 +401,20 @@ void browser_window_recalculate_frameset(struct browser_window *bw) {
float relative;
int size, extent;
int x, y;
+ int new_width, new_height;
assert(bw);
/* window dimensions */
if (!bw->parent) {
- gui_window_get_dimensions(bw->window, &bw_width, &bw_height, false);
- bw->x0 = 0;
- bw->y0 = 0;
- bw->x1 = bw_width;
- bw->y1 = bw_height;
+ browser_window_get_dimensions(bw, &bw_width, &bw_height, true);
+ bw->x = 0;
+ bw->y = 0;
+ bw->width = bw_width;
+ bw->height = bw_height;
} else {
- bw_width = bw->x1 - bw->x0;
- bw_height = bw->y1 - bw->y0;
+ bw_width = bw->width;
+ bw_height = bw->height;
}
bw_width++;
bw_height++;
@@ -471,8 +480,6 @@ void browser_window_recalculate_frameset(struct browser_window *bw) {
widths[col][row] = bw_width;
} else {
size = bw_width * widths[col][row] / extent;
- bw_width -= size;
- extent -= widths[col][row];
widths[col][row] = size;
}
}
@@ -543,8 +550,6 @@ void browser_window_recalculate_frameset(struct browser_window *bw) {
heights[col][row] = bw_height;
} else {
size = bw_height * heights[col][row] / extent;
- bw_height -= size;
- extent -= heights[col][row];
heights[col][row] = size;
}
}
@@ -561,10 +566,27 @@ void browser_window_recalculate_frameset(struct browser_window *bw) {
y = 0;
for (row2 = 0; row2 < row; row2++)
y+= heights[col][row2];
- gui_window_position_frame(window->window, x, y,
- x + widths[col][row] - 1,
- y + heights[col][row] - 1);
+
+ window->x = x;
+ window->y = y;
+
+ new_width = widths[col][row] - 1;
+ new_height = heights[col][row] - 1;
+
+ if (window->width != new_width ||
+ window->height != new_height) {
+ /* Change in frame size */
+ browser_window_reformat(window, false,
+ new_width * bw->scale,
+ new_height * bw->scale);
+ window->width = new_width;
+ window->height = new_height;
+
+ browser_window_handle_scrollbars(window);
+ }
+
x += widths[col][row];
+
if (window->children)
browser_window_recalculate_frameset(window);
}
@@ -827,7 +849,9 @@ bool browser_window_resize_frames(struct browser_window *bw, browser_mouse_state
bw->drag_resize_right = right;
bw->drag_resize_up = up;
bw->drag_resize_down = down;
- gui_window_frame_resize_start(bw->window);
+
+ /* TODO: sort this out:
+ gui_window_frame_resize_start(bw->window); */
*status = messages_get("FrameDrag");
*action = true;