NetSurf on ARMv7 platforms
by John-Mark Bell
Afternoon,
So, NetSurf runs mostly ok on ARMv7 platforms with their backwards
incompatible unaligned LDR behaviour turned on. Tinct, however, appears
to perform some LDRs from unaligned addresses, resulting in crashes.
Here's a backtrace:
> Fatal signal received: Segmentation fault
>
> Stack backtrace:
>
> Running thread 0x59e53c
> ( 5a7ee0) pc: 462860 lr: 74f4c sp: 5a7ee4 __write_backtrace()
> ( 5a7f10) pc: 74d64 lr: 463298 sp: 5a7f14 ^ro_gui_signal()
> ( 5a7f38) pc: 463288 lr: 462f58 sp: 5a7f3c __unixlib_exec_sig()
> ( 5a7fa0) pc: 462a18 lr: 463870 sp: 5a7fa4 __unixlib_raise_signal()
> ( 5a7fb0) pc: 463774 lr: 5a6c48 sp: 5a6c04 __h_cback()
>
> Register dump at 005a7fb4:
>
> a1: 12f a2: 2d a3: 1f4 a4: 0
> v1: 0 v2: 0 v3: 202513b4 v4: 1
> v5: 3d5 v6: 0 sl: 41b78d39 fp: 67197124
> ip: 20248394 sp: 5a6c04 lr: 5a6c48 pc: 2024609c
> cpsr: 80000113
>
> 20246088 : .p.â : e21a7003 : ANDS R7,R10,#3
> 2024608c : .... : 0a000008 : BEQ &202460B4
> 20246090 : .àgâ : e267e003 : RSB R14,R7,#3
> 20246094 : ..^á : e15e0000 : CMP R14,R0
> 20246098 : .à Á : c1a0e000 : MOVGT R14,R0
> 2024609c : .??å : e59a9000 : LDR R9,[R10,#0]
> 202460a0 : ..@Ð : d040000e : SUBLE R0,R0,R14
> 202460a4 : ..?Ò : d2800003 : ADDLE R0,R0,#3
> 202460a8 : ..?À : c0800007 : ADDGT R0,R0,R7
>
> Invalid pc address bebeec
For reference, Tinct is loaded at 202416B4.
J.
13 years
Framebuffer dependencies clarification
by Bill Randle
I am building netsurf for an ARM9 Linux system and want to use nsfb. I
read the BUILDING-Framebuffer and it mentions required dependencies of
libglade, libxml2, librsvg and curl. For a cross-compile environment,
it wasn't completely clear if these dependencies are required only on
the build machine or if they are [also] required on the target
machine for runtime linking.
If these are required on the target system, it adds a lot of extra
code, as libglade requires gtk+ and librsvg requires cairo, which in
turn requires directfb. If I have to build gtk+ for use with glade,
what's the savings (in code space) over using the native gtk+ interface
for netsurf?
I did browse the last 6 months or so of the mailing list archives and
didn't see a clear answer to this, so please excuse me if it was
discussed a long time ago and I didn't go back far enough.
-Bill
13 years, 6 months
RISC OS Development - Anyone Else?
by Steve Fryatt
It's taken a lot longer than I'd expected, but I think I'm now in a position
to spend a bit of time looking at NetSurf's RISC OS front-end.
While I'm not expecting it to be a problem, I don't really want to waste
time (and the limited resources we seem to have) duplicating work that
others are doing. I have already contacted the people I'm aware of who were
also thinking about taking a look, but has anyone else been considering the
RISC OS bits of NetSurf since August?
--
Steve Fryatt - Leeds, England
http://www.stevefryatt.org.uk/
13 years, 6 months
Building on OpenBSD
by Anthony Bentley
Hi guys,
I have been hoping to try out Netsurf, but the build fails on my
OpenBSD box.
Initially it stopped due to undefined references to libcurl; replacing
“pkg-config --libs libcurl” in the makefile with “curl-config --libs”
fixed these.
$ pkg-config --libs libcurl
-L/usr/local/lib -lcurl
$ curl-config --libs
-L/usr/local/lib -lcurl -L/usr/local/lib -lidn -lssl -lcrypto -lz
Now it stops with errors apparently related to hubbub. Yes, hubbub is
installed…
$ pkg-config --libs libhubbub
-L/usr/local/lib -lhubbub -lparserutils
$ sudo gmake
M.CONFIG: building with JPEG support
M.CONFIG: building with JNG/MNG/PNG support
M.CONFIG: building without PDF export
M.CONFIG: building with glibc internal iconv
M.CONFIG: auto-enabled SVG rendering (librsvg-2.0).
M.CONFIG: building with NetSurf BMP decoder
M.CONFIG: auto-enabled NetSurf BMP decoder (libnsbmp).
M.CONFIG: building with NetSurf GIF decoder
M.CONFIG: auto-enabled NetSurf GIF decoder (libnsgif).
M.CONFIG: building with PNG support
M.CONFIG: auto-enabled PNG support (libpng).
Package openssl was not found in the pkg-config search path
Package openssl was not found in the pkg-config search path
LINK: nsgtk
/usr/local/lib/libglib-2.0.so.1802.0: warning: vsprintf() is often
misused, please use vsnprintf()
build-OpenBSD-gtk/content_urldb.o(.text+0x1e17): In function
`urldb_add_path':
content/urldb.c:1742: warning: strcpy() is almost always misused,
please use strlcpy()
build-OpenBSD-gtk/gtk_gtk_gui.o(.text+0x58): In function
`find_resource':
gtk/gtk_gui.c:119: warning: strcat() is almost always misused, please
use strlcat()
build-OpenBSD-gtk/content_urldb.o(.text+0x2f1e): In function
`urldb_get_cookie':
content/urldb.c:2664: warning: sprintf() is often misused, please use
snprintf()
build-OpenBSD-gtk/gtk_gtk_gui.o(.text+0x43a): In function `gui_init':
gtk/gtk_gui.c:207: undefined reference to `hubbub_initialise'
build-OpenBSD-gtk/gtk_gtk_gui.o(.text+0x1164): In function `gui_quit':
gtk/gtk_gui.c:433: undefined reference to `hubbub_finalise'
build-OpenBSD-gtk/render_hubbub_binding.o(.text+0x97): In function
`binding_create_tree':
render/hubbub_binding.c:155: undefined reference to
`hubbub_parser_create'
build-OpenBSD-gtk/render_hubbub_binding.o(.text+0x11d):render/hubbub_binding.c:181:
undefined reference to `hubbub_parser_setopt'
build-OpenBSD-gtk/render_hubbub_binding.o(.text+0x141):render/hubbub_binding.c:185:
undefined reference to `hubbub_parser_setopt'
build-OpenBSD-gtk/render_hubbub_binding.o(.text+0x15a):render/hubbub_binding.c:167:
undefined reference to `hubbub_parser_destroy'
build-OpenBSD-gtk/render_hubbub_binding.o(.text+0x1c1): In function
`binding_destroy_tree':
render/hubbub_binding.c:200: undefined reference to
`hubbub_parser_destroy'
build-OpenBSD-gtk/render_hubbub_binding.o(.text+0x1de): In function
`binding_parse_chunk':
render/hubbub_binding.c:219: undefined reference to
`hubbub_parser_parse_chunk'
build-OpenBSD-gtk/render_hubbub_binding.o(.text+0x208): In function
`binding_parse_completed':
render/hubbub_binding.c:231: undefined reference to
`hubbub_parser_completed'
build-OpenBSD-gtk/render_hubbub_binding.o(.text+0xc0a): In function
`change_encoding':
render/hubbub_binding.c:781: undefined reference to
`hubbub_parser_read_charset'
build-OpenBSD-gtk/render_textplain.o(.text+0xc4): In function
`textplain_create':
render/textplain.c:98: undefined reference to `iconv_open'
build-OpenBSD-gtk/render_textplain.o(.text+0x1c3):render/textplain.c:101:
undefined reference to `iconv_open'
build-OpenBSD-gtk/render_textplain.o(.text+0x2cf): In function
`textplain_process_data':
render/textplain.c:152: undefined reference to `iconv'
build-OpenBSD-gtk/render_textplain.o(.text+0x426): In function
`textplain_convert':
render/textplain.c:200: undefined reference to `iconv_close'
build-OpenBSD-gtk/render_textplain.o(.text+0x741): In function
`textplain_destroy':
render/textplain.c:312: undefined reference to `iconv_close'
build-OpenBSD-gtk/utils_utf8.o(.text+0x1c1): In function
`utf8_finalise':
utils/utf8.c:190: undefined reference to `iconv_close'
build-OpenBSD-gtk/utils_utf8.o(.text+0x34e): In function
`utf8_convert':
utils/utf8.c:312: undefined reference to `iconv'
build-OpenBSD-gtk/utils_utf8.o(.text+0x3d9):utils/utf8.c:316:
undefined reference to `iconv_close'
build-OpenBSD-gtk/utils_utf8.o(.text+0x3ea):utils/utf8.c:282:
undefined reference to `iconv_open'
build-OpenBSD-gtk/utils_utf8.o(.text+0x433):utils/utf8.c:292:
undefined reference to `iconv_close'
collect2: ld returned 1 exit status
gmake: *** [nsgtk] Error 1
Just what causes these errors?
Thanks,
—Anthony Bentley
13 years, 6 months
Re: RISC OS Christmas Show 2009
by Rob Kendrick
On Wed, 18 Nov 2009 20:45:33 +0100
rickman(a)argonet.co.uk wrote:
> you wrote:
>
> > On Wed, 18 Nov 2009 17:58:53 +0100
> > rickman(a)argonet.co.uk wrote:
>
> >> Hello NetSurf
> >> I sent this message to rjek(a)nesturf-browser.org but don't know if
> >> he received it. So I am trying the general help id.
>
> > Yes, I did; I forwarded it to our developer list asking if anybody
> > else would be able to manage it, as I do not feel comfortable
> > manning a stand single-handedly. So far, nobody else has
> > volunteered. If anybody does in the next day or so, I will let you
> > know, otherwise I suspect NetSurf will not be able to exhibit.
>
> We should have about 10 MUG club members at the show. Would it help
> if one of them were to volunteer to assist on your stand?
Do they know how to answer the question "When will NetSurf have
JavaScript?" If so, they are fully qualified. :)
Unfortunately, if it's just me, I'll be arriving by train, which means
no famous banner, no twin 24" LCDs and A9 Homes. It'll be just me with
my laptop demonstrating the Linux version of NetSurf.
Will there be interwebs at the show?
B.
13 years, 6 months
Re: RISC OS Christmas Show 2009
by Rob Kendrick
On Thu, 19 Nov 2009 23:16:32 +0000
Steve Fryatt <lists(a)stevefryatt.org.uk> wrote:
> I don't know if that's any help or not? I think I can answer the
> qualifying question, though. :-)
I think that might be a go-er. I'll bring two laptops, one running
nsgtk and the other running RPCemu. Alas, I won't be able to bring our
banner or any promotional material at all.
B.
13 years, 6 months
Re: r9656 chris_y - /trunk/netsurf/amiga/misc.c
by John-Mark Bell
On Sun, 2009-11-01 at 16:01 +0000, netsurf(a)semichrome.net wrote:
> Author: chris_y
> Date: Sun Nov 1 10:01:07 2009
> New Revision: 9656
>
> URL: http://source.netsurf-browser.org?rev=9656&view=rev
> Log:
> Support file://(/)localhost/ as well as file://(/)
> As NetSurf insists on adding a third slash after file://, it is not possible to open
> any local files which are in subdirectory "localhost" of the current directory.
> Workaround is to type the "localhost" part in something other than fully lowercase.
> In practice it is incredibly unlikely that even the workaround will need to be used.
I don't understand the need for this.
File URIs take the form:
file://<hostname>/<path>
However, the hostname may be completely omitted, and localhost inferred.
The '/' between the hostname and the path may not be omitted, even if
the hostname is.
NetSurf does not support opening files on hosts that are not the local
host. Additionally, it omits the hostname part, as it's unnecessary.
Therefore, all file URIs in NetSurf are of the form:
file:///<path>
This is correct, per spec.
The path component of a file: URI is a standard URI path. That is, it is
a '/'-separated list of directories, with a trailing filename. Note:
this is the case on all platforms, regardless of what the given
platform's native path format is.
Given the above, I don't understand what the issue you are encountering
is.
J.
13 years, 7 months
Porting to VxWorks
by Håkan Gustavsson
Hi,
I'm studying how much work it will be to port NetSurf to VxWorks in our IP-phones.
Do you have any suggestions on how this can be best done?
Which port is best to base my port on, GTK or Frame buffer?
We use WindML as a media layer and Tilcon as graphical engine.
Best regards,
Håkan
\\\|/// <file://%7c/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////ofile://////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////%7C///>
\\ <file:// /> ~ ~ //
( =@=@= )
+-----------------------------oOOo---(_)---oOOo------------------------------+
| |
| Håkan Gustavsson Aastra Telecom Sweden AB |
| End User Product Development |
| Telephone : +46 8 568 67605 SE-126 37 Hägersten, Sweden |
| Telefax : +46 8 719 6181 Office: LM Ericssons väg 30 |
| Mobile : +46 730 371344 Telefonplan |
| Email: hakan.gustavsson(a)aastra.com |
| |
| .oooO Oooo. |
| ( ) ( ) |
+--------------------------------\ (-----) /---------------------------------+
\_) (_/
This communication is confidential and intended solely for the addressee(s). Any unauthorized review, use, disclosure or distribution is prohibited. If you believe this message has been sent to you in error, please notify the sender by replying to this transmission and delete the message without disclosing it. Thank you.
E-mail including attachments is susceptible to data corruption, interruption, unauthorized amendment, tampering and viruses, and we only send and receive e-mails on the basis that we are not liable for any such corruption, interception, amendment, tampering or viruses or any consequences thereof.
13 years, 7 months
Review: Paul Blokus -- select/scroll
by Michael Drake
Added files
Index: desktop/scroll.c
===================================================================
--- /dev/null 2009-07-16 10:59:57.000000000 +0100
+++ desktop/scroll.c 2009-08-10 21:36:53.000000000 +0100
@@ -0,0 +1,695 @@
+/*
+ * Copyright 2004-2008 James Bursa <bursa(a)users.sourceforge.net>
+ * Copyright 2008 Michael Drake <tlsa(a)netsurf-browser.org>
+ * Copyright 2009 Paul Blokus <paul_pl(a)users.sourceforge.net>
+ *
+ * This file is part of NetSurf, http://www.netsurf-browser.org/
+ *
+ * NetSurf is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * NetSurf is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/** \file
+ * Scroll widget (implementation).
+ */
+
+#include <stdbool.h>
+#include <stdlib.h>
+
+#include "desktop/scroll.h"
+#include "desktop/plotters.h"
+#include "desktop/plot_style.h"
+#include "utils/log.h"
+#include "utils/messages.h"
+#include "utils/utils.h"
+
+struct scroll {
+ bool horizontal; /* horizontal scroll if true vertical if false
+ */
+ int length; /* Length of the scroll */
+
+ int scrolled_d; /* The dimension of the scrolled area */
+ int scrolled_vis; /* The visible part of the scrolled area */
+
+ int area_scroll; /* scroll value of the scrolled area */
+ int bar_off; /* offset of the scrollbar */
+ int bar_len; /* length of the scrollbar */
+
+ scroll_client_callback client_callback;
+ void *client_data;
+
+ bool dragging;
+ int drag_start_coord;
+ int drag_start_bar_off;
+ bool reverse;
+};
+
+/** Overflow scrollbar colours
+ *
+ * Overflow scrollbar colours can be set by front end code to try to match
+ * scrollbar colours used on the desktop.
+ *
+ * If a front end doesn't set scrollbar colours, these defaults are used.
+ */
+colour css_scrollbar_fg_colour = 0x00d9d9d9; /* light grey */
+colour css_scrollbar_bg_colour = 0x006b6b6b; /* mid grey */
+colour css_scrollbar_arrow_colour = 0x00444444; /* dark grey */
+
+/**
+ * Create a scroll.
+ *
+ * \param horizontal true for a horizontal scrollbar false for a
+ * vertical one
+ * \param length full length of the scrollbar
+ * \param scrolled_dimension full length of the scrolled area
+ * \param scrolled_visible length of the visible part of the scrolled area
+ * \param client_data data for th client callback
+ * \param client_callback client callback for scroll events
+ * \param scroll_pt gets updated to point at te newly created scroll
+ * \return true if the scroll has been created succesfully
+ * or false on memory exhaustion
+ */
+bool scroll_create(bool horizontal, int length,
+ int scrolled_dimension, int scrolled_visible,
+ void *client_data, scroll_client_callback client_callback,
+ struct scroll **scroll_pt)
+{
+ struct scroll *scroll;
+ int well_length;
+ struct scroll_msg_data msg;
+
+ scroll = malloc(sizeof(struct scroll));
+ if (scroll == NULL) {
+ LOG(("malloc failed"));
+ warn_user("NoMemory", 0);
+ *scroll_pt = NULL;
+ return false;
+ }
+
+ scroll->horizontal = horizontal;
+ scroll->length = length;
+ scroll->scrolled_d = scrolled_dimension;
+ scroll->scrolled_vis = scrolled_visible;
+ scroll->area_scroll = 0;
+ scroll->bar_off = 0;
+ scroll->reverse = false;
+
+ well_length = length - 2 * SCROLLBAR_WIDTH;
+ scroll->bar_len = ((float) well_length * scrolled_visible) /
+ scrolled_dimension;
+
+ scroll->client_callback = client_callback;
+ scroll->client_data = client_data;
+
+ scroll->dragging = false;
+
+ *scroll_pt = scroll;
+
+ msg.scroll = scroll;
+ msg.msg = SCROLL_MSG_REDRAW;
+ msg.x0 = 0;
+ msg.y0 = 0;
+ msg.x1 = horizontal ? length : SCROLLBAR_WIDTH;
+ msg.y1 = horizontal ? SCROLLBAR_WIDTH : length;
+
+ client_callback(client_data, &msg);
+
+ return true;
+}
+
+/**
+ * Destroy a scroll.
+ *
+ * \param scroll the scroll to be destroyed
+ */
+void scroll_destroy(struct scroll *scroll)
+{
+ free(scroll);
+}
+
+/**
+ * Draw an outline rectangle common to a few of scroll elements.
+ *
+ * \param x0 left border of the outline
+ * \param y0 top border of the outline
+ * \param x1 right border of the outline
+ * \param y1 bottom border of the outline
+ * \param c base colour of the outline, the other colours are created by
+ * lightening or darkening this one
+ * \param inset true for inset outline, false for an outset one
+ * \return
+ */
+static inline bool scroll_redraw_scrollbar_rectangle(
+ int x0, int y0, int x1, int y1, colour c, bool inset)
+{
+ static plot_style_t c0 = {
+ .stroke_type = PLOT_OP_TYPE_SOLID,
+ .stroke_width = 1,
+ };
+
+ static plot_style_t c1 = {
+ .stroke_type = PLOT_OP_TYPE_SOLID,
+ .stroke_width = 1,
+ };
+
+ static plot_style_t c2 = {
+ .stroke_type = PLOT_OP_TYPE_SOLID,
+ .stroke_width = 1,
+ };
+
+ if (inset) {
+ c0.stroke_colour = darken_colour(c);
+ c1.stroke_colour = lighten_colour(c);
+ } else {
+ c0.stroke_colour = lighten_colour(c);
+ c1.stroke_colour = darken_colour(c);
+ }
+ c2.stroke_colour = blend_colour(c0.stroke_colour, c1.stroke_colour);
+
+ if (!plot.line(x0, y0, x1, y0, &c0)) return false;
+ if (!plot.line(x1, y0, x1, y1 + 1, &c1)) return false;
+ if (!plot.line(x1, y0, x1, y0 + 1, &c2)) return false;
+ if (!plot.line(x1, y1, x0, y1, &c1)) return false;
+ if (!plot.line(x0, y1, x0, y0, &c0)) return false;
+ if (!plot.line(x0, y1, x0, y1 + 1, &c2)) return false;
+ return true;
+}
+
+/**
+ * Redraw a part of the scroll.
+ *
+ * \param scroll the scroll to be redrawn
+ * \param x the X coordinate to draw the scroll at
+ * \param y the Y coordinate to draw the scroll at
+ * \param clip_x0 minimum x of the clipping rectangle
+ * \param clip_y0 minimum y of the clipping rectangle
+ * \param clip_x1 maximum x of the clipping rectangle
+ * \param clip_y1 maximum y of the clipping rectangle
+ * \param scale scale for the redraw
+ * \return true on succes false otherwise
+ */
+bool scroll_redraw(struct scroll *scroll, int x, int y,
+ int clip_x0, int clip_y0, int clip_x1, int clip_y1,
+ float scale)
+{
+ int w = SCROLLBAR_WIDTH;
+ int well_length, bar_off, bar_c0, bar_c1;
+ int v[6]; /* array of triangle vertices */
+ int x0, y0, x1, y1;
+ plot_style_t pstyle_css_scrollbar_bg_colour = {
+ .fill_type = PLOT_OP_TYPE_SOLID,
+ .fill_colour = css_scrollbar_bg_colour,
+ };
+ plot_style_t pstyle_css_scrollbar_fg_colour = {
+ .fill_type = PLOT_OP_TYPE_SOLID,
+ .fill_colour = css_scrollbar_fg_colour,
+ };
+ plot_style_t pstyle_css_scrollbar_arrow_colour = {
+ .fill_type = PLOT_OP_TYPE_SOLID,
+ .fill_colour = css_scrollbar_arrow_colour,
+ };
+
+ well_length = scroll->length - 2 * SCROLLBAR_WIDTH;
+ x0 = x;
+ y0 = y;
+ x1 = x + (scroll->horizontal ?
+ scroll->length : SCROLLBAR_WIDTH) - 1;
+ y1 = y + (scroll->horizontal ? SCROLLBAR_WIDTH : scroll->length) - 1;
+ bar_off = scroll->bar_off;
+ bar_c1 = (scroll->horizontal ? x0 : y0) + SCROLLBAR_WIDTH +
+ scroll->bar_off + scroll->bar_len - 1;
+
+ if (scale != 1.0) {
+ w *= scale;
+ well_length *= scale;
+ x0 *= scale;
+ y0 *= scale;
+ x1 *= scale;
+ y1 *= scale;
+ bar_off *= scale;
+ bar_c1 *= scale;
+ }
+
+ bar_c0 = (scroll->horizontal ? x0 : y0) + w + bar_off;
+
+ if (clip_x0 < x0)
+ clip_x0 = x0;
+
+ if (clip_y0 < y0)
+ clip_y0 = y0;
+
+ if (clip_x1 > x1 + 1)
+ clip_x1 = x1 + 1;
+
+ if (clip_y1 > y1 + 1)
+ clip_y1 = y1 + 1;
+
+ /* return if the clipping rectangle is outside the scrollbar area */
+ if (clip_x0 > clip_x1 || clip_y0 > clip_y1)
+ return true;
+
+ plot.clip(clip_x0, clip_y0, clip_x1, clip_y1);
+
+ /* horizontal scrollbar */
+ if (scroll->horizontal) {
+ /* scrollbar outline */
+ if (!scroll_redraw_scrollbar_rectangle(x0, y0, x1, y1,
+ css_scrollbar_bg_colour, true))
+ return false;
+ /* left arrow icon border */
+ if (!scroll_redraw_scrollbar_rectangle(x0 + 1,
+ y0 + 1,
+ x0 + w - 2,
+ y1 - 1,
+ css_scrollbar_fg_colour, false))
+ return false;
+ /* left arrow icon background */
+ if (!plot.rectangle(x0 + 2,
+ y0 + 2,
+ x0 + w - 2,
+ y1 - 1,
+ &pstyle_css_scrollbar_fg_colour))
+ return false;
+ /* left arrow */
+ v[0] = x0 + w / 4;
+ v[1] = y0 + w / 2;
+ v[2] = x0 + w * 3 / 4;
+ v[3] = y0 + w / 4;
+ v[4] = x0 + w * 3 / 4;
+ v[5] = y0 + w * 3 / 4;
+ if (!plot.polygon(v, 3, &pstyle_css_scrollbar_arrow_colour))
+ return false;
+ /* scroll well background */
+ if (!plot.rectangle(x0 + w - 1,
+ y0 + 1,
+ x1 - w + 2,
+ y1,
+ &pstyle_css_scrollbar_bg_colour))
+ return false;
+ /* scroll position indicator bar */
+ if (!scroll_redraw_scrollbar_rectangle(bar_c0,
+ y0 + 1,
+ bar_c1,
+ y1 - 1,
+ css_scrollbar_fg_colour, false))
+ return false;
+ if (!plot.rectangle(bar_c0 + 1,
+ y0 + 2,
+ bar_c1,
+ y1 - 1,
+ &pstyle_css_scrollbar_fg_colour))
+ return false;
+ /* right arrow icon border */
+ if (!scroll_redraw_scrollbar_rectangle(x1 - w + 2,
+ y0 + 1,
+ x1 - 1,
+ y1 - 1,
+ css_scrollbar_fg_colour, false))
+ return false;
+ /* right arrow icon background */
+ if (!plot.rectangle(x1 - w + 3,
+ y0 + 2,
+ x1 - 1,
+ y1 - 1,
+ &pstyle_css_scrollbar_fg_colour))
+ return false;
+ /* right arrow */
+ v[0] = x1 - w / 4 + 1;
+ v[1] = y0 + w / 2;
+ v[2] = x1 - w * 3 / 4 + 1;
+ v[3] = y0 + w / 4;
+ v[4] = x1 - w * 3 / 4 + 1;
+ v[5] = y0 + w * 3 / 4;
+ if (!plot.polygon(v, 3, &pstyle_css_scrollbar_arrow_colour))
+ return false;
+ } else {
+ /* outline */
+ if (!scroll_redraw_scrollbar_rectangle(x0, y0, x1, y1,
+ css_scrollbar_bg_colour,
+ true))
+ return false;
+ /* top arrow background */
+ if (!scroll_redraw_scrollbar_rectangle(x0 + 1,
+ y0 + 1,
+ x1 - 1,
+ y0 + w - 2,
+ css_scrollbar_fg_colour,
+ false))
+ return false;
+ if (!plot.rectangle(x0 + 2,
+ y0 + 2,
+ x1 - 1,
+ y0 + w - 2,
+ &pstyle_css_scrollbar_fg_colour))
+ return false;
+ /* up arrow */
+ v[0] = x0 + w / 2;
+ v[1] = y0 + w / 4;
+ v[2] = x0 + w / 4;
+ v[3] = y0 + w * 3 / 4;
+ v[4] = x0 + w * 3 / 4;
+ v[5] = y0 + w * 3 / 4;
+ if (!plot.polygon(v, 3, &pstyle_css_scrollbar_arrow_colour))
+ return false;
+ /* scroll well background */
+ if (!plot.rectangle(x0 + 1,
+ y0 + w - 1,
+ x1,
+ y1 - w + 2,
+ &pstyle_css_scrollbar_bg_colour))
+ return false;
+ /* scroll position indicator bar */
+ if (!scroll_redraw_scrollbar_rectangle(x0 + 1,
+ bar_c0,
+ x1 - 1,
+ bar_c1,
+ css_scrollbar_fg_colour, false))
+ return false;
+ if (!plot.rectangle(x0 + 2,
+ bar_c0 + 1,
+ x1 - 1,
+ bar_c1,
+ &pstyle_css_scrollbar_fg_colour))
+ return false;
+ /* bottom arrow background */
+ if (!scroll_redraw_scrollbar_rectangle(x0 + 1,
+ y1 - w + 2,
+ x1 - 1,
+ y1 - 1,
+ css_scrollbar_fg_colour, false))
+ return false;
+ if (!plot.rectangle(x0 + 2,
+ y1 - w + 3,
+ x1 - 1,
+ y1 - 1,
+ &pstyle_css_scrollbar_fg_colour))
+ return false;
+ /* down arrow */
+ v[0] = x0 + w / 2;
+ v[1] = y1 - w / 4 + 1;
+ v[2] = x0 + w / 4;
+ v[3] = y1 - w * 3 / 4 + 1;
+ v[4] = x0 + w * 3 / 4;
+ v[5] = y1 - w * 3 / 4 + 1;
+ if (!plot.polygon(v, 3, &pstyle_css_scrollbar_arrow_colour))
+ return false;
+ }
+
+ return true;
+}
+
+/**
+ * Set the value of the scroll.
+ *
+ * \param scroll the scroll to have the value set
+ * \param scroll_val the new value to be set
+ * \param bar true if the value is for the scroll indication bar
+ * offset, false if it is for the scrolled area one
+ */
+void scroll_set(struct scroll *scroll, int scroll_val, bool bar)
+{
+ int well_length;
+ struct scroll_msg_data msg;
+
+ if (scroll_val < 0)
+ scroll_val = 0;
+
+ if (scroll->scrolled_d == scroll->scrolled_vis)
+ return;
+
+ well_length = scroll->length - 2 * SCROLLBAR_WIDTH;
+ if (bar) {
+ if (scroll_val > well_length - scroll->bar_len)
+ scroll->bar_off = well_length - scroll->bar_len;
+ else
+ scroll->bar_off = scroll_val;
+
+ scroll->area_scroll = (float) (scroll->scrolled_d -
+ scroll->scrolled_vis) *
+ (float) (scroll->bar_off)/
+ (float) (well_length - scroll->bar_len);
+
+ } else {
+ if (scroll_val > scroll->scrolled_d - scroll->scrolled_vis)
+ scroll->area_scroll = scroll->scrolled_d -
+ scroll->scrolled_vis;
+ else
+ scroll->area_scroll = scroll_val;
+
+ scroll->bar_off = (float) well_length *
+ (float) scroll->area_scroll /
+ (float) scroll->scrolled_d;
+ }
+
+ msg.scroll = scroll;
+ msg.msg = SCROLL_MSG_MOVED;
+ msg.new_scroll = scroll->area_scroll;
+ scroll->client_callback(scroll->client_data, &msg);
+
+ /* TODO: redraw only the necessary part */
+ msg.msg = SCROLL_MSG_REDRAW;
+ msg.x0 = 0;
+ msg.y0 = 0;
+ msg.x1 = (scroll->horizontal ? scroll->length : SCROLLBAR_WIDTH);
+ msg.y1 = (scroll->horizontal ?
+ SCROLLBAR_WIDTH : scroll->length);
+ scroll->client_callback(scroll->client_data, &msg);
+}
+
+/**
+ * Get the value of the scroll.
+ *
+ * \param scroll the scroll to get the value of
+ * \return scroll offset for the scrolled area
+ */
+int scroll_get(struct scroll *scroll)
+{
+ if (scroll == NULL)
+ return 0;
+ return scroll->area_scroll;
+}
+
+
+/**
+ * Set the length of the scroll and the visible part of the scrolled area.
+ *
+ * \param scroll the scroll to set the values for
+ * \param length the new scroll length to be set
+ * \param scrolled_visible the new value of the visible part of the
+ * scrolled area to be set
+ */
+void scroll_set_length_and_visible(struct scroll *scroll, int length,
+ int scrolled_visible)
+{
+ int well_length;
+
+ scroll->length = length;
+ scroll->scrolled_vis = scrolled_visible;
+ well_length = length - 2 * SCROLLBAR_WIDTH;
+
+ scroll->bar_len = ((float) well_length * scrolled_visible) /
+ scroll->scrolled_d;
+}
+
+/**
+ * Check the orientation of the scroll.
+ *
+ * \param scroll the scroll to check the orientation of
+ * \return true for a horizontal scroll, false for a vertical one
+ */
+bool scroll_is_horizontal(struct scroll *scroll)
+{
+ return scroll->horizontal;
+}
+
+/**
+ * Handle mouse actions other then movements and drag ends.
+ *
+ * \param scroll the scroll which gets the mouse action
+ * \param mouse mouse state
+ * \param x X coordinate of the mouse
+ * \param y Y coordinate of the mouse
+ * \return message for the status bar or NULL on failure
+ */
+const char *scroll_mouse_action(struct scroll *scroll,
+ browser_mouse_state mouse, int x, int y)
+{
+ struct scroll_msg_data msg;
+ int x0, y0, x1, y1;
+ int val;
+ const char *status;
+ bool h;
+ bool but1 = ((mouse & BROWSER_MOUSE_PRESS_1) ||
+ ((mouse & BROWSER_MOUSE_HOLDING_1) &&
+ (mouse & BROWSER_MOUSE_DRAG_ON) &&
+ !scroll->dragging));
+ bool but2 = ((mouse & BROWSER_MOUSE_PRESS_2) ||
+ ((mouse & BROWSER_MOUSE_HOLDING_2) &&
+ (mouse & BROWSER_MOUSE_DRAG_ON) &&
+ !scroll->dragging));
+
+ h = scroll->horizontal;
+
+ x0 = 0;
+ y0 = 0;
+ x1 = h ? scroll->length : SCROLLBAR_WIDTH;
+ y1 = h ? SCROLLBAR_WIDTH : scroll->length;
+
+ if (!scroll->dragging && !(x >= x0 && x <= x1 && y >= y0 && y <= y1)) {
+ return NULL;
+ }
+
+
+ if (h)
+ val = x;
+ else
+ val = y;
+
+ /* left/up arrow */
+ if (val < SCROLLBAR_WIDTH) {
+ status = messages_get(h ? "ScrollLeft" : "ScrollUp");
+ if (but1)
+ scroll_set(scroll, scroll->bar_off - SCROLLBAR_WIDTH,
+ true);
+ else if (but2)
+ scroll_set(scroll, scroll->bar_off + SCROLLBAR_WIDTH,
+ true);
+
+ /* well between left/up arrow and bar */
+ } else if (val < SCROLLBAR_WIDTH + scroll->bar_off) {
+
+ status = messages_get(h ? "ScrollPLeft" : "ScrollPUp");
+
+ if (but1)
+ scroll_set(scroll, scroll->area_scroll - scroll->length,
+ false);
+ else if (but2)
+ scroll_set(scroll, scroll->area_scroll + scroll->length,
+ false);
+
+ /* right/down arrow*/
+ } else if (val > scroll->length - SCROLLBAR_WIDTH) {
+
+ status = messages_get(h ? "ScrollRight" : "ScrollDown");
+
+ if (but1)
+ scroll_set(scroll, scroll->bar_off + SCROLLBAR_WIDTH,
+ true);
+ else if (but2)
+ scroll_set(scroll, scroll->bar_off - SCROLLBAR_WIDTH,
+ true);
+
+ /* well between right/down arrow and bar */
+ } else if (val > SCROLLBAR_WIDTH + scroll->bar_off + scroll->bar_len) {
+
+ status = messages_get(h ? "ScrollPRight" : "ScrollPDown");
+ if (but1)
+ scroll_set(scroll, scroll->area_scroll + scroll->length,
+ false);
+ else if (but2)
+ scroll_set(scroll, scroll->area_scroll - scroll->length,
+ false);
+ }
+ else {
+ status = messages_get(h ? "ScrollH" : "ScrollV");
+ }
+
+ if (scroll->dragging) {
+ val -= scroll->drag_start_coord;
+ if (scroll->reverse)
+ val = -val;
+ if (val != 0)
+ scroll_set(scroll, scroll->drag_start_bar_off + val,
+ true);
+ return status;
+ }
+
+ if (mouse & (BROWSER_MOUSE_DRAG_1 | BROWSER_MOUSE_DRAG_2) &&
+ (val >= SCROLLBAR_WIDTH + scroll->bar_off
+ && val < SCROLLBAR_WIDTH + scroll->bar_off +
+ scroll->bar_len)) {
+
+ scroll->drag_start_coord = scroll->horizontal ? x : y;
+ scroll->drag_start_bar_off = scroll->bar_off;
+
+ scroll->dragging = true;
+
+ msg.scroll = scroll;
+ msg.msg = SCROLL_MSG_CAPTURE_MOUSE;
+ scroll->client_callback(scroll->client_data, &msg);
+ if (mouse & BROWSER_MOUSE_DRAG_2) {
+ msg.msg = SCROLL_MSG_2D_DRAG;
+ msg.x0 = x;
+ msg.y0 = y;
+ scroll->client_callback(scroll->client_data,
+ &msg);
+ }
+ }
+
+ return status;
+}
+
+/**
+ * Handle end of mouse drags.
+ *
+ * \param scroll the scroll for which the drag ends
+ * \param mouse mouse state
+ * \param x X coordinate of the mouse
+ * \param y Y coordinate of the mouse
+ */
+void scroll_mouse_drag_end(struct scroll *scroll, browser_mouse_state mouse,
+ int x, int y)
+{
+ struct scroll_msg_data msg;
+ int val;
+
+ assert(scroll->dragging);
+
+ val = (scroll->horizontal ? x : y) - scroll->drag_start_coord;
+ if (scroll->reverse)
+ val = -val;
+ if (val != 0)
+ scroll_set(scroll, scroll->drag_start_bar_off + val, true);
+
+ scroll->dragging = false;
+ scroll->reverse = false;
+ msg.scroll = scroll;
+ msg.msg = SCROLL_MSG_RELEASE_MOUSE;
+ scroll->client_callback(scroll->client_data, &msg);
+}
+
+/**
+ * Force a drag to be started. This is used when a 2D drag was started on the
+ * parpendicular scroll and we want the future mouse actions to take effect for
+ * this scroll too.
+ *
+ * \param scroll the scroll for which the drag start will be forced
+ * \param x X coordinate of mouse during drag start
+ * \param y Y coordinate of mouse during drag start
+ * \param reverse if true mouse moves will cause the scroll to move in the
+ * opposite direction
+ */
+void scroll_force_drag_start(struct scroll *scroll, int x, int y, bool reverse)
+{
+ struct scroll_msg_data msg;
+
+
+ scroll->reverse = reverse;
+
+ scroll->drag_start_coord = scroll->horizontal ? x : y;
+ scroll->drag_start_bar_off = scroll->bar_off;
+
+ scroll->dragging = true;
+ msg.scroll = scroll;
+ msg.msg = SCROLL_MSG_CAPTURE_MOUSE;
+ scroll->client_callback(scroll->client_data, &msg);
+}
Index: desktop/scroll.h
===================================================================
--- /dev/null 2009-07-16 10:59:57.000000000 +0100
+++ desktop/scroll.h 2009-08-10 21:36:53.000000000 +0100
@@ -0,0 +1,89 @@
+/*
+ * Copyright 2009 Paul Blokus <paul_pl(a)users.sourceforge.net>
+ *
+ * This file is part of NetSurf, http://www.netsurf-browser.org/
+ *
+ * NetSurf is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * NetSurf is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/** \file
+ * Scroll widget (interface).
+ */
+
+#ifndef _NETSURF_DESKTOP_SCROLL_H_
+#define _NETSURF_DESKTOP_SCROLL_H_
+
+#include <stdbool.h>
+
+#include "desktop/browser.h"
+
+#define SCROLLBAR_WIDTH 16
+
+struct scroll;
+
+typedef enum {
+ SCROLL_MSG_REDRAW, /* the scrollbar requests a redraw */
+ SCROLL_MSG_MOVED, /* the scroll value has changed */
+ SCROLL_MSG_CAPTURE_MOUSE, /* all mouse events should be passed to
+ * the scrollbar regardless of the
+ * coordinates
+ */
+ SCROLL_MSG_RELEASE_MOUSE, /* cancel the above */
+ SCROLL_MSG_2D_DRAG /* the user started a DRAG_2 drag on the
+ * scroll which means that, if present,
+ * the parpendicular scroll schould be
+ * dragged together with this one to
+ * provide 2D scrolling functionallity
+ */
+} scroll_msg;
+
+struct scroll_msg_data {
+ struct scroll *scroll;
+ scroll_msg msg;
+ int new_scroll;
+ int x0, y0, x1, y1;
+};
+
+/**
+ * Client callback for the scroll.
+ *
+ * \param client_data user data passed at scroll creation
+ * \param scroll_data struct all necessary message data
+ */
+typedef void(*scroll_client_callback)(void *client_data,
+ struct scroll_msg_data *scroll_data);
+
+bool scroll_create(bool horizontal, int length,
+ int scrolled_dimension, int scrolled_visible,
+ void *client_data, scroll_client_callback client_callback,
+ struct scroll **scroll_pt);
+void scroll_destroy(struct scroll *scroll);
+bool scroll_redraw(struct scroll *scroll, int x, int y,
+ int clip_x0, int clip_y0, int clip_x1, int clip_y1,
+ float scale);
+
+void scroll_set(struct scroll *scroll, int scroll_val, bool bar);
+int scroll_get(struct scroll *scroll);
+
+void scroll_set_length_and_visible(struct scroll *scroll, int length,
+ int scrolled_visible);
+
+bool scroll_is_horizontal(struct scroll *scroll);
+
+const char *scroll_mouse_action(struct scroll *scroll,
+ browser_mouse_state mouse, int x, int y);
+void scroll_mouse_drag_end(struct scroll *scroll, browser_mouse_state mouse,
+ int x, int y);
+void scroll_force_drag_start(struct scroll *scroll, int x, int y, bool reverse);
+
+#endif
Changed files
!NetSurf/Resources/de/Messages | 4
!NetSurf/Resources/en/Messages | 4
!NetSurf/Resources/fr/Messages | 6
!NetSurf/Resources/it/Messages | 4
!NetSurf/Resources/nl/Messages | 4
Makefile.sources | 2
amiga/thumbnail.c | 2
desktop/browser.c | 577 ++++++++++++++++++++++-------------------
desktop/browser.h | 20 -
desktop/textinput.c | 61 ++--
framebuffer/gui.c | 5
gtk/gtk_plotters.h | 1
gtk/gtk_scaffolding.c | 1
gtk/gtk_window.c | 15 -
render/box.c | 73 +++--
render/box.h | 13
render/form.c | 475 +++++++++++++++++++++++++++++++++
render/form.h | 24 +
render/html_redraw.c | 497 ++++++++++-------------------------
render/layout.c | 7
render/layout.h | 2
21 files changed, 1112 insertions(+), 685 deletions(-)
Index: render/form.c
===================================================================
--- render/form.c (revision 9172)
+++ render/form.c (working copy)
@@ -2,6 +2,7 @@
* Copyright 2004 James Bursa <bursa(a)users.sourceforge.net>
* Copyright 2003 Phil Mellor <monkeyson(a)users.sourceforge.net>
* Copyright 2005-9 John-Mark Bell <jmb(a)netsurf-browser.org>
+ * Copyright 2009 Paul Blokus <paul_pl(a)users.sourceforge.net>
*
* This file is part of NetSurf, http://www.netsurf-browser.org/
*
@@ -29,18 +30,60 @@
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
+#include "css/css.h"
+#include "css/utils.h"
+#include "desktop/gui.h"
+#include "desktop/knockout.h"
+#include "desktop/plot_style.h"
+#include "desktop/plotters.h"
+#include "desktop/scroll.h"
#include "render/box.h"
+#include "render/font.h"
#include "render/form.h"
+#include "render/layout.h"
#include "utils/log.h"
+#include "utils/messages.h"
#include "utils/url.h"
#include "utils/utf8.h"
#include "utils/utils.h"
+#define MAX_SELECT_HEIGHT 210
+#define SELECT_LINE_SPACING 0.2
+#define SELECT_BORDER_WIDTH 1
+#define SELECT_SELECTED_COLOUR 0xDB9370
+struct form_select_menu {
+ int line_height;
+ int width, height;
+ struct scroll *scroll;
+ int f_size;
+ bool scroll_capture;
+ select_menu_callback callback;
+ void *client_data;
+ struct browser_window *bw;
+};
+
+static plot_style_t plot_style_fill_selected = {
+ .fill_type = PLOT_OP_TYPE_SOLID,
+ .fill_colour = SELECT_SELECTED_COLOUR,
+};
+
+static plot_font_style_t plot_fstyle_entry = {
+ .family = PLOT_FONT_FAMILY_SANS_SERIF,
+ .weight = 400,
+ .flags = FONTF_NONE,
+ .background = 0xffffff,
+ .foreground = 0x000000,
+};
+
static char *form_textarea_value(struct form_control *textarea);
static char *form_acceptable_charset(struct form *form);
static char *form_encode_item(const char *item, const char *charset,
const char *fallback);
+static void form_select_menu_clicked(struct form_control *control,
+ int x, int y);
+static void form_select_menu_scroll_callback(void *client_data,
+ struct scroll_msg_data *scroll_data);
/**
* Create a struct form.
@@ -199,6 +242,8 @@
free(option->value);
free(option);
}
+ if (control->data.select.menu != NULL)
+ form_free_select_menu(control);
}
free(control);
@@ -812,3 +857,433 @@
return ret;
}
+/**
+ * Open a select menu for a select form control, creating it if necessary.
+ *
+ * \param client_data data passed to the redraw callback
+ * \param control the select form control for which the menu is being
+ * opened
+ * \param callback redraw callback for the select menu
+ * \param bw the browser window in which the select menu is being
+ * opened
+ * \return false on memory exhaustion, true otherwise
+ */
+bool form_open_select_menu(void *client_data,
+ struct form_control *control,
+ select_menu_callback callback,
+ struct browser_window *bw)
+{
+ int i, line_height_with_spacing, scroll;
+ struct form_option *option;
+ struct box *box;
+ plot_font_style_t fstyle;
+ int total_height;
+ struct form_select_menu *menu;
+
+
+ /* if the menu is opened for the first time */
+ if (control->data.select.menu == NULL) {
+
+ menu = calloc(1, sizeof (struct form_select_menu));
+ if (menu == NULL) {
+ warn_user("NoMemory", 0);
+ return false;
+ }
+
+ control->data.select.menu = menu;
+
+ box = control->box;
+
+ menu->width = box->width +
+ box->border[RIGHT].width +
+ box->border[LEFT].width +
+ box->padding[RIGHT] + box->padding[LEFT];
+
+ font_plot_style_from_css(control->box->style,
+ &fstyle);
+ menu->f_size = fstyle.size;
+
+ menu->line_height =
+ FIXTOINT(FDIVI((FMUL(FLTTOFIX(1.2),
+ FMULI(nscss_screen_dpi,
+ (fstyle.size / FONT_SIZE_SCALE)))), 72));
+
+ line_height_with_spacing = menu->line_height +
+ menu->line_height *
+ SELECT_LINE_SPACING;
+
+ total_height = control->data.select.num_items *
+ line_height_with_spacing;
+ menu->height = total_height;
+
+ scroll = 0;
+ if (menu->height > MAX_SELECT_HEIGHT) {
+
+ menu->height = MAX_SELECT_HEIGHT;
+
+ if (control->data.select.num_selected > 0) {
+ i = 0;
+ option = control->data.select.items;
+ while (!option->selected) {
+ option = option->next;
+ i++;
+ }
+
+ if ((i + 1) * line_height_with_spacing >
+ MAX_SELECT_HEIGHT)
+ scroll = (i + 1) *
+ line_height_with_spacing
+ - MAX_SELECT_HEIGHT;
+ }
+ }
+ menu->client_data = client_data;
+ menu->callback = callback;
+ if (!scroll_create(false,
+ menu->height,
+ total_height,
+ menu->height,
+ control,
+ form_select_menu_scroll_callback,
+ &(menu->scroll))) {
+ free(menu);
+ return false;
+ }
+ menu->bw = bw;
+ }
+ else menu = control->data.select.menu;
+
+ menu->callback(client_data, 0, 0, menu->width, menu->height);
+
+ return true;
+}
+
+
+/**
+ * Destroy a select menu and free allocated memory.
+ *
+ * \param control the select form control owning the select menu being
+ * destroyed
+ */
+void form_free_select_menu(struct form_control *control)
+{
+ if (control->data.select.menu->scroll != NULL)
+ scroll_destroy(control->data.select.menu->scroll);
+ free(control->data.select.menu);
+ control->data.select.menu = NULL;
+}
+
+/**
+ * Redraw an opened select menu.
+ *
+ * \param control the select menu being redrawn
+ * \param x the X coordinate to draw the menu at
+ * \param x the Y coordinate to draw the menu at
+ * \param scale current redraw scale
+ * \param clip_x0 minimum x of clipping rectangle
+ * \param clip_y0 minimum y of clipping rectangle
+ * \param clip_x1 maximum x of clipping rectangle
+ * \param clip_y1 maximum y of clipping rectangle
+ * \return true on success, false otherwise
+ */
+bool form_redraw_select_menu(struct form_control *control, int x, int y,
+ float scale, int clip_x0, int clip_y0, int clip_x1, int clip_y1)
+{
+ struct box *box;
+ struct form_select_menu *menu = control->data.select.menu;
+ struct form_option *option;
+ bool result;
+ int line_height, line_height_with_spacing;
+ int width, height;
+ int x0, y0, x1, scrollbar_x, y1, y2, y3;
+ int item_y;
+ int text_pos_offset, text_x;
+ int scrollbar_width = SCROLLBAR_WIDTH;
+ int i;
+ int scroll;
+ int x_cp, y_cp;
+
+ box = control->box;
+
+ x_cp = x;
+ y_cp = y;
+ width = menu->width;
+ height = menu->height;
+ line_height = menu->line_height;
+
+ line_height_with_spacing = line_height +
+ line_height * SELECT_LINE_SPACING;
+ scroll = scroll_get(menu->scroll);
+
+ if (scale != 1.0) {
+ x *= scale;
+ y *= scale;
+ width *= scale;
+ height *= scale;
+ scrollbar_width *= scale;
+
+ i = scroll / line_height_with_spacing;
+ scroll -= i * line_height_with_spacing;
+ line_height *= scale;
+ line_height_with_spacing *= scale;
+ scroll *= scale;
+ scroll += i * line_height_with_spacing;
+ }
+
+
+ x0 = x;
+ y0 = y;
+ x1 = x + width - 1;
+ y1 = y + height - 1;
+ scrollbar_x = x1 - scrollbar_width;
+
+ result = plot.clip(x0, y0, x1 + 1, y1 + 1);
+ result &= plot.rectangle(x0, y0, x1, y1 ,plot_style_stroke_darkwbasec);
+
+
+ x0 = x0 + SELECT_BORDER_WIDTH;
+ y0 = y0 + SELECT_BORDER_WIDTH;
+ x1 = x1 - SELECT_BORDER_WIDTH;
+ y1 = y1 - SELECT_BORDER_WIDTH;
+ height = height - 2 * SELECT_BORDER_WIDTH;
+
+ result = plot.clip(x0, y0, x1 + 1, y1 + 1);
+ result &= plot.rectangle(x0, y0, x1 + 1, y1 + 1,
+ plot_style_fill_lightwbasec);
+ option = control->data.select.items;
+ item_y = line_height_with_spacing;
+
+ while (item_y < scroll) {
+ option = option->next;
+ item_y += line_height_with_spacing;
+ }
+ item_y -= line_height_with_spacing;
+ text_pos_offset = y - scroll +
+ (int) (line_height * (0.75 + SELECT_LINE_SPACING));
+ text_x = x + (box->border[LEFT].width + box->padding[LEFT]) * scale;
+
+ plot_fstyle_entry.size = menu->f_size;
+
+ while (option && item_y - scroll < height) {
+
+ if (option->selected) {
+ y2 = y + item_y - scroll;
+ y3 = y + item_y + line_height_with_spacing - scroll;
+ result &= plot.rectangle(x0, (y0 > y2 ? y0 : y2),
+ scrollbar_x + 1,
+ (y3 < y1 + 1 ? y3 : y1 + 1),
+ &plot_style_fill_selected);
+ }
+
+ y2 = text_pos_offset + item_y;
+ result &= plot.text(text_x, y2, option->text,
+ strlen(option->text), &plot_fstyle_entry);
+
+ item_y += line_height_with_spacing;
+ option = option->next;
+ }
+
+ result &= scroll_redraw(menu->scroll,
+ x_cp + menu->width - SCROLLBAR_WIDTH,
+ y_cp,
+ clip_x0, clip_y0, clip_x1, clip_y1, scale);
+
+ return result;
+}
+
+/**
+ * Check whether a clipping rectangle is completely contained in the
+ * select menu.
+ *
+ * \param control the select menu to check the clipping rectangle for
+ * \param scale the current browser window scale
+ * \param clip_x0 minimum x of clipping rectangle
+ * \param clip_y0 minimum y of clipping rectangle
+ * \param clip_x1 maximum x of clipping rectangle
+ * \param clip_y1 maximum y of clipping rectangle
+ * \return true if inside false otherwise
+ */
+bool form_clip_inside_select_menu(struct form_control *control, float scale,
+ int clip_x0, int clip_y0, int clip_x1, int clip_y1)
+{
+ struct form_select_menu *menu = control->data.select.menu;
+ int width, height;
+
+
+ width = menu->width;
+ height = menu->height;
+
+ if (scale != 1.0) {
+ width *= scale;
+ height *= scale;
+ }
+
+ if (clip_x0 >= 0 && clip_x1 <= width &&
+ clip_y0 >= 0 && clip_y1 <= height)
+ return true;
+
+ return false;
+}
+
+/**
+ * Handle a click on the area of the currently opened select menu.
+ *
+ * \param control the select menu which received the click
+ * \param x X coordinate of click
+ * \param y Y coordinate of click
+ */
+void form_select_menu_clicked(struct form_control *control, int x, int y)
+{
+ struct form_select_menu *menu = control->data.select.menu;
+ struct form_option *option;
+ int line_height, line_height_with_spacing;
+ int item_bottom_y;
+ int scroll, i;
+
+ scroll = scroll_get(menu->scroll);
+
+ line_height = menu->line_height;
+ line_height_with_spacing = line_height +
+ line_height * SELECT_LINE_SPACING;
+
+ option = control->data.select.items;
+ item_bottom_y = line_height_with_spacing;
+ i = 0;
+ while (option && item_bottom_y < scroll + y) {
+ item_bottom_y += line_height_with_spacing;
+ option = option->next;
+ i++;
+ }
+
+ if (option != NULL)
+ browser_window_form_select(menu->bw, control, i);
+
+ menu->callback(menu->client_data, 0, 0, menu->width, menu->height);
+}
+
+/**
+ * Handle mouse action for the currently opened select menu.
+ *
+ * \param control the select menu which received the mouse action
+ * \param mouse current mouse state
+ * \param x X coordinate of click
+ * \param y Y coordinate of click
+ * \return text for the browser status bar or NULL on failure
+ */
+const char *form_select_mouse_action(struct form_control *control,
+ browser_mouse_state mouse, int x, int y)
+{
+ struct form_select_menu *menu = control->data.select.menu;
+ int x0, y0, x1, y1, x3;
+ const char *status = NULL;
+ bool closed = false;
+
+ x0 = 0;
+ y0 = 0;
+ x1 = menu->width;
+ y1 = menu->height;
+ x3 = x1 - SCROLLBAR_WIDTH;
+
+ if (menu->scroll_capture ||
+ (x > x3 && x < x1 && y > y0 && y < y1)) {
+ x -= menu->width - SCROLLBAR_WIDTH;
+ return scroll_mouse_action(menu->scroll,
+ mouse, x, y);
+ }
+
+ if (mouse & BROWSER_MOUSE_CLICK_1) {
+ if (x > x0 && x < x1 && y > y0 && y < y1) {
+ if (x < x1 - SCROLLBAR_WIDTH)
+ form_select_menu_clicked(control, x, y);
+ else {
+ x -= menu->width - SCROLLBAR_WIDTH;
+ status = scroll_mouse_action(menu->scroll,
+ mouse, x, y);
+ }
+ }
+ else
+ closed = true;
+ }
+ if (status == NULL && !closed)
+ status = messages_get(control->data.select.multiple ?
+ "SelectMClick" : "SelectClick");
+ return status;
+}
+
+/**
+ * Handle mouse drag end for the currently opened select menu.
+ *
+ * \param control the select menu which received the mouse drag end
+ * \param mouse current mouse state
+ * \param x X coordinate of drag end
+ * \param y Y coordinate of drag end
+ */
+void form_select_mouse_drag_end(struct form_control *control,
+ browser_mouse_state mouse, int x, int y)
+{
+ int x0, y0, x1, y1;
+ struct form_select_menu *menu = control->data.select.menu;
+
+ if (menu->scroll_capture) {
+ x -= menu->width - SCROLLBAR_WIDTH;
+ scroll_mouse_drag_end(menu->scroll,
+ mouse, x, y);
+ return;
+ }
+
+ x0 = 0;
+ y0 = 0;
+ x1 = menu->width;
+ y1 = menu->height;
+
+ if (x > x0 && x < x1 - SCROLLBAR_WIDTH && y > y0 && y < y1)
+ form_select_menu_clicked(control, x, y);
+}
+
+/**
+ * Callback for the select menus scroll
+ */
+void form_select_menu_scroll_callback(void *client_data,
+ struct scroll_msg_data *scroll_data)
+{
+ struct form_control *control = client_data;
+ struct form_select_menu *menu = control->data.select.menu;
+
+ switch (scroll_data->msg) {
+ case SCROLL_MSG_REDRAW:
+ menu->callback(menu->client_data,
+ menu->width -
+ SCROLLBAR_WIDTH + scroll_data->x0,
+ scroll_data->y0,
+ scroll_data->x1 - scroll_data->x0,
+ scroll_data->y1 - scroll_data->y0);
+ break;
+ case SCROLL_MSG_MOVED:
+ menu->callback(menu->client_data,
+ 0, 0,
+ menu->width - SCROLLBAR_WIDTH,
+ menu->height);
+ break;
+ case SCROLL_MSG_CAPTURE_MOUSE:
+ menu->scroll_capture = true;
+ break;
+ case SCROLL_MSG_RELEASE_MOUSE:
+ menu->scroll_capture = false;
+ break;
+ default:
+ break;
+ }
+}
+
+/**
+ * Get the dimensions of a select menu.
+ *
+ * \param control the select menu to get the dimensions of
+ * \param width gets updated to menu width
+ * \param height gets updated to menu height
+ */
+void form_select_get_dimensions(struct form_control *control,
+ int *width, int *height)
+{
+ *width = control->data.select.menu->width;
+ *height = control->data.select.menu->height;
+}
Index: render/form.h
===================================================================
--- render/form.h (revision 9172)
+++ render/form.h (working copy)
@@ -1,6 +1,7 @@
/*
* Copyright 2003 Phil Mellor <monkeyson(a)users.sourceforge.net>
* Copyright 2003 James Bursa <bursa(a)users.sourceforge.net>
+ * Copyright 2009 Paul Blokus <paul_pl(a)users.sourceforge.net>
*
* This file is part of NetSurf, http://www.netsurf-browser.org/
*
@@ -25,11 +26,13 @@
#define _NETSURF_RENDER_FORM_H_
#include <stdbool.h>
+#include "desktop/browser.h"
#include "utils/config.h"
struct box;
struct form_control;
struct form_option;
+struct form_select_menu;
/** Form submit method. */
typedef enum {
@@ -105,6 +108,7 @@
int num_selected;
/** Currently selected item, if num_selected == 1. */
struct form_option *current;
+ struct form_select_menu *menu;
} select;
} data;
@@ -129,6 +133,9 @@
struct form_successful_control *next; /**< Next in linked list. */
};
+typedef void(*select_menu_callback)(void *client_data,
+ int x, int y, int width, int height);
+
struct form *form_new(void *node, const char *action, const char *target,
form_method method, const char *charset,
const char *doc_charset);
@@ -145,4 +152,21 @@
struct form_successful_control *control);
void form_free_successful(struct form_successful_control *control);
+bool form_open_select_menu(void *client_data,
+ struct form_control *control,
+ select_menu_callback redraw_callback,
+ struct browser_window *bw);
+void form_free_select_menu(struct form_control *control);
+bool form_redraw_select_menu(struct form_control *control, int x, int y,
+ float scale,
+ int clip_x0, int clip_y0, int clip_x1, int clip_y1);
+bool form_clip_inside_select_menu(struct form_control *control, float scale,
+ int clip_x0, int clip_y0, int clip_x1, int clip_y1);
+const char *form_select_mouse_action(struct form_control *control,
+ browser_mouse_state mouse, int x, int y);
+void form_select_mouse_drag_end(struct form_control *control,
+ browser_mouse_state mouse, int x, int y);
+void form_select_get_dimensions(struct form_control *control,
+ int *width, int *height);
+
#endif
Index: render/html_redraw.c
===================================================================
--- render/html_redraw.c (revision 9172)
+++ render/html_redraw.c (working copy)
@@ -5,6 +5,7 @@
* Copyright 2005-2006 Adrian Lees <adrianl(a)users.sourceforge.net>
* Copyright 2006 Rob Kendrick <rjek(a)netsurf-browser.org>
* Copyright 2008 Michael Drake <tlsa(a)netsurf-browser.org>
+ * Copyright 2009 Paul Blokus <paul_pl(a)users.sourceforge.net>
*
* This file is part of NetSurf, http://www.netsurf-browser.org/
*
@@ -40,6 +41,7 @@
#include "desktop/textinput.h"
#include "desktop/options.h"
#include "desktop/print.h"
+#include "desktop/scroll.h"
#include "image/bitmap.h"
#include "render/box.h"
#include "render/font.h"
@@ -89,23 +91,9 @@
float scale, colour colour, float ratio);
static bool html_redraw_text_decoration_block(struct box *box, int x, int y,
float scale, colour colour, float ratio);
-static bool html_redraw_scrollbars(struct box *box, float scale,
- int x, int y, int padding_width, int padding_height,
- colour background_colour);
bool html_redraw_debug = false;
-/** Overflow scrollbar colours
- *
- * Overflow scrollbar colours can be set by front end code to try to match
- * scrollbar colours used on the desktop.
- *
- * If a front end doesn't set scrollbar colours, these defaults are used.
- */
-colour css_scrollbar_fg_colour = 0x00d9d9d9; /* light grey */
-colour css_scrollbar_bg_colour = 0x006b6b6b; /* mid grey */
-colour css_scrollbar_arrow_colour = 0x00444444; /* dark grey */
-
/**
* Draw a CONTENT_HTML using the current set of plotters (plot).
*
@@ -131,7 +119,8 @@
float scale, colour background_colour)
{
struct box *box;
- bool result, want_knockout;
+ bool result = true, want_knockout;
+ bool select, select_only;
plot_style_t pstyle_fill_bg = {
.fill_type = PLOT_OP_TYPE_SOLID,
.fill_colour = background_colour,
@@ -144,18 +133,53 @@
if (want_knockout)
knockout_plot_start(&plot);
- /* clear to background colour */
- result = plot.clip(clip_x0, clip_y0, clip_x1, clip_y1);
+ /* The select menu needs special treating because, when opened, it
+ * reaches beyond its layout box.
+ */
+ select = false;
+ select_only = false;
+ if (current_redraw_browser != NULL &&
+ current_redraw_browser->visible_select_menu != NULL) {
+ struct form_control *control =
+ current_redraw_browser->visible_select_menu;
+ select = true;
+ /* check if the redraw rectangle is completely inside of the
+ select menu */
+ select_only = form_clip_inside_select_menu(control, scale,
+ clip_x0, clip_y0, clip_x1, clip_y1);
+ }
+
+ if (!select_only) {
+ /* clear to background colour */
+ result = plot.clip(clip_x0, clip_y0, clip_x1, clip_y1);
+
+ if (c->data.html.background_colour != NS_TRANSPARENT)
+ pstyle_fill_bg.fill_colour =
+ c->data.html.background_colour;
+
+ result &= plot.rectangle(clip_x0, clip_y0, clip_x1, clip_y1,
+ &pstyle_fill_bg);
+
+ result &= html_redraw_box(box, x, y,
+ clip_x0, clip_y0, clip_x1, clip_y1,
+ scale, pstyle_fill_bg.fill_colour);
+ }
- if (c->data.html.background_colour != NS_TRANSPARENT)
- pstyle_fill_bg.fill_colour = c->data.html.background_colour;
-
- result &= plot.rectangle(clip_x0, clip_y0, clip_x1, clip_y1, &pstyle_fill_bg);
-
- result &= html_redraw_box(box, x, y,
- clip_x0, clip_y0, clip_x1, clip_y1,
- scale, pstyle_fill_bg.fill_colour);
-
+ if (select) {
+ int menu_x, menu_y;
+ box = current_redraw_browser->visible_select_menu->box;
+ box_coords(box, &menu_x, &menu_y);
+
+ menu_x -= box->border[LEFT].width;
+ menu_y += box->height + box->border[BOTTOM].width +
+ box->padding[BOTTOM] + box->padding[TOP];
+ result &= form_redraw_select_menu(
+ current_redraw_browser->visible_select_menu,
+ x + menu_x, y + menu_y,
+ current_redraw_browser->scale,
+ clip_x0, clip_y0, clip_x1, clip_y1);
+ }
+
if (want_knockout)
knockout_plot_end();
@@ -195,6 +219,7 @@
int x_scrolled, y_scrolled;
struct box *bg_box = NULL;
css_color bgcol = 0;
+ bool has_x_scroll, has_y_scroll;
if (html_redraw_printing && box->printed)
return true;
@@ -622,8 +647,8 @@
return false;
if (box->object) {
- x_scrolled = x - box->scroll_x * scale;
- y_scrolled = y - box->scroll_y * scale;
+ x_scrolled = x - scroll_get(box->scroll_x) * scale;
+ y_scrolled = y - scroll_get(box->scroll_y) * scale;
if (!content_redraw(box->object,
x_scrolled + padding_left,
y_scrolled + padding_top,
@@ -664,24 +689,51 @@
/* list marker */
if (box->list_marker)
if (!html_redraw_box(box->list_marker,
- x_parent + box->x - box->scroll_x,
- y_parent + box->y - box->scroll_y,
+ x_parent + box->x - scroll_get(box->scroll_x),
+ y_parent + box->y - scroll_get(box->scroll_y),
clip_x0, clip_y0, clip_x1, clip_y1,
scale, current_background_color))
return false;
/* scrollbars */
- if (box->style && box->type != BOX_BR && box->type != BOX_TABLE &&
- box->type != BOX_INLINE &&
+ if (current_redraw_browser && box->style && box->type != BOX_BR &&
+ box->type != BOX_TABLE && box->type != BOX_INLINE &&
(css_computed_overflow(box->style) ==
CSS_OVERFLOW_SCROLL ||
css_computed_overflow(box->style) ==
- CSS_OVERFLOW_AUTO))
- if (!html_redraw_scrollbars(box, scale, x, y,
- padding_width, padding_height,
- current_background_color))
+ CSS_OVERFLOW_AUTO)) {
+
+ has_x_scroll = false;
+ has_y_scroll = false;
+
+ has_x_scroll = box_hscrollbar_present(box);
+
+ has_y_scroll = box_vscrollbar_present(box);
+
+ if (!box_handle_scrollbars(box,
+ x_parent + box->x, y_parent + box->y,
+ has_x_scroll, has_y_scroll))
return false;
+
+ if (box->scroll_x != NULL)
+ scroll_redraw(box->scroll_x,
+ x_parent + box->x,
+ y_parent + box->y + box->padding[TOP] +
+ box->height + box->padding[BOTTOM] -
+ SCROLLBAR_WIDTH,
+ clip_x0, clip_y0, clip_x1, clip_y1,
+ scale);
+ if (box->scroll_y != NULL)
+ scroll_redraw(box->scroll_y,
+ x_parent + box->x + box->padding[LEFT] +
+ box->width + box->padding[RIGHT] -
+ SCROLLBAR_WIDTH,
+ y_parent + box->y,
+ clip_x0, clip_y0, clip_x1, clip_y1,
+ scale);
+ }
+
if (box->type == BOX_BLOCK || box->type == BOX_INLINE_BLOCK ||
box->type == BOX_TABLE_CELL || box->object)
if (!plot.clip(clip_x0, clip_y0, clip_x1, clip_y1))
@@ -717,16 +769,18 @@
if (c->type != BOX_FLOAT_LEFT && c->type != BOX_FLOAT_RIGHT)
if (!html_redraw_box(c,
- x_parent + box->x - box->scroll_x,
- y_parent + box->y - box->scroll_y,
+ x_parent + box->x -
+ scroll_get(box->scroll_x),
+ y_parent + box->y -
+ scroll_get(box->scroll_y),
clip_x0, clip_y0, clip_x1, clip_y1,
scale, current_background_color))
return false;
}
for (c = box->float_children; c; c = c->next_float)
if (!html_redraw_box(c,
- x_parent + box->x - box->scroll_x,
- y_parent + box->y - box->scroll_y,
+ x_parent + box->x - scroll_get(box->scroll_x),
+ y_parent + box->y - scroll_get(box->scroll_y),
clip_x0, clip_y0, clip_x1, clip_y1,
scale, current_background_color))
return false;
@@ -1958,318 +2012,69 @@
return true;
}
-static inline bool
-html_redraw_scrollbar_rectangle(int x0, int y0, int x1, int y1, colour c,
- bool inset)
-{
- static plot_style_t c0 = {
- .stroke_type = PLOT_OP_TYPE_SOLID,
- .stroke_width = 1,
- };
-
- static plot_style_t c1 = {
- .stroke_type = PLOT_OP_TYPE_SOLID,
- .stroke_width = 1,
- };
-
- static plot_style_t c2 = {
- .stroke_type = PLOT_OP_TYPE_SOLID,
- .stroke_width = 1,
- };
-
- if (inset) {
- c0.stroke_colour = darken_colour(c);
- c1.stroke_colour = lighten_colour(c);
- } else {
- c0.stroke_colour = lighten_colour(c);
- c1.stroke_colour = darken_colour(c);
- }
- c2.stroke_colour = blend_colour(c0.stroke_colour, c1.stroke_colour);
-
- if (!plot.line(x0, y0, x1, y0, &c0)) return false;
- if (!plot.line(x1, y0, x1, y1 + 1, &c1)) return false;
- if (!plot.line(x1, y0, x1, y0 + 1, &c2)) return false;
- if (!plot.line(x1, y1, x0, y1, &c1)) return false;
- if (!plot.line(x0, y1, x0, y0, &c0)) return false;
- if (!plot.line(x0, y1, x0, y1 + 1, &c2)) return false;
- return true;
-}
-
/**
- * Plot scrollbars for a scrolling box.
+ * Applies the given scroll setup to a box. This includes scroll
+ * creation/deletion as well as scroll dimension updates.
*
- * \param box scrolling box
- * \param scale scale for redraw
- * \param x coordinate of box
- * \param y coordinate of box
- * \param padding_width width of padding box
- * \param padding_height height of padding box
- * \return true if successful, false otherwise
+ * \param box the box to handle the scrolls for
+ * \param x X coordinate of the box
+ * \param y Y coordinate of the box
+ * \param bottom whether the horizontal scrollbar should be present
+ * \param right whether the vertical scrollbar should be present
+ * \return true on success false otherwise
*/
-
-bool html_redraw_scrollbars(struct box *box, float scale,
- int x, int y, int padding_width, int padding_height,
- colour background_colour)
+bool box_handle_scrollbars(struct box *box, int x, int y, bool bottom,
+ bool right)
{
- const int w = SCROLLBAR_WIDTH * scale;
- bool vscroll, hscroll;
- int well_height, bar_top, bar_height;
- int well_width, bar_left, bar_width;
- int v[6]; /* array of triangle vertices */
- plot_style_t pstyle_css_scrollbar_bg_colour = {
- .fill_type = PLOT_OP_TYPE_SOLID,
- .fill_colour = css_scrollbar_bg_colour,
- };
- plot_style_t pstyle_css_scrollbar_fg_colour = {
- .fill_type = PLOT_OP_TYPE_SOLID,
- .fill_colour = css_scrollbar_fg_colour,
- };
- plot_style_t pstyle_css_scrollbar_arrow_colour = {
- .fill_type = PLOT_OP_TYPE_SOLID,
- .fill_colour = css_scrollbar_arrow_colour,
- };
-
- box_scrollbar_dimensions(box, padding_width, padding_height, w,
- &vscroll, &hscroll,
- &well_height, &bar_top, &bar_height,
- &well_width, &bar_left, &bar_width);
-
-
- /* horizontal scrollbar */
- if (hscroll) {
- /* scrollbar outline */
- if (!html_redraw_scrollbar_rectangle(x,
- y + padding_height - w,
- x + padding_width - 1,
- y + padding_height - 1,
- css_scrollbar_bg_colour, true))
- return false;
- /* left arrow icon border */
- if (!html_redraw_scrollbar_rectangle(x + 1,
- y + padding_height - w + 1,
- x + w - 2,
- y + padding_height - 2,
- css_scrollbar_fg_colour, false))
- return false;
- /* left arrow icon background */
- if (!plot.rectangle(x + 2,
- y + padding_height - w + 2,
- x + w - 2,
- y + padding_height - 2,
- &pstyle_css_scrollbar_fg_colour))
- return false;
- /* left arrow */
- v[0] = x + w / 4;
- v[1] = y + padding_height - w / 2;
- v[2] = x + w * 3 / 4;
- v[3] = y + padding_height - w * 3 / 4;
- v[4] = x + w * 3 / 4;
- v[5] = y + padding_height - w / 4;
- if (!plot.polygon(v, 3, &pstyle_css_scrollbar_arrow_colour))
- return false;
- /* scroll well background */
- if (!plot.rectangle(x + w - 1,
- y + padding_height - w + 1,
- x + w + well_width + (vscroll ? 2 : 1),
- y + padding_height - 1,
- &pstyle_css_scrollbar_bg_colour))
- return false;
- /* scroll position indicator bar */
- if (!html_redraw_scrollbar_rectangle(x + w + bar_left,
- y + padding_height - w + 1,
- x + w + bar_left + bar_width + (vscroll? 1 : 0),
- y + padding_height - 2,
- css_scrollbar_fg_colour, false))
- return false;
- if (!plot.rectangle(x + w + bar_left + 1,
- y + padding_height - w + 2,
- x + w + bar_left + bar_width + (vscroll? 1 : 0),
- y + padding_height - 2,
- &pstyle_css_scrollbar_fg_colour))
- return false;
- /* right arrow icon border */
- if (!html_redraw_scrollbar_rectangle(x + w + well_width + 2,
- y + padding_height - w + 1,
- x + w + well_width + w - (vscroll ? 1 : 2),
- y + padding_height - 2,
- css_scrollbar_fg_colour, false))
- return false;
- /* right arrow icon background */
- if (!plot.rectangle(x + w + well_width + 3,
- y + padding_height - w + 2,
- x + w + well_width + w - (vscroll ? 1 : 2),
- y + padding_height - 2,
- &pstyle_css_scrollbar_fg_colour))
- return false;
- /* right arrow */
- v[0] = x + w + well_width + w * 3 / 4 + (vscroll ? 1 : 0);
- v[1] = y + padding_height - w / 2;
- v[2] = x + w + well_width + w / 4 + (vscroll ? 1 : 0);
- v[3] = y + padding_height - w * 3 / 4;
- v[4] = x + w + well_width + w / 4 + (vscroll ? 1 : 0);
- v[5] = y + padding_height - w / 4;
- if (!plot.polygon(v, 3, &pstyle_css_scrollbar_arrow_colour))
- return false;
+ int padding_width, padding_height;
+
+ padding_width = box->width + box->padding[RIGHT] + box->padding[LEFT];
+ padding_height = box->height + box->padding[TOP] + box->padding[BOTTOM];
+
+ if (!bottom && box->scroll_x != NULL) {
+ scroll_destroy(box->scroll_x);
+ box->scroll_x = NULL;
}
-
- /* vertical scrollbar */
- if (vscroll) {
- /* outline */
- if (!html_redraw_scrollbar_rectangle(x + padding_width - w,
- y,
- x + padding_width - 1,
- y + padding_height - 1,
- css_scrollbar_bg_colour,
- true))
- return false;
- /* top arrow background */
- if (!html_redraw_scrollbar_rectangle(x + padding_width - w + 1,
- y + 1,
- x + padding_width - 2,
- y + w - 2,
- css_scrollbar_fg_colour,
- false))
- return false;
- if (!plot.rectangle(x + padding_width - w + 2,
- y + 2,
- x + padding_width - 2,
- y + w - 2,
- &pstyle_css_scrollbar_fg_colour))
- return false;
- /* up arrow */
- v[0] = x + padding_width - w / 2;
- v[1] = y + w / 4;
- v[2] = x + padding_width - w * 3 / 4;
- v[3] = y + w * 3 / 4;
- v[4] = x + padding_width - w / 4;
- v[5] = y + w * 3 / 4;
- if (!plot.polygon(v, 3, &pstyle_css_scrollbar_arrow_colour))
- return false;
- /* scroll well background */
- if (!plot.rectangle(x + padding_width - w + 1,
- y + w - 1,
- x + padding_width - 1,
- y + padding_height - w + 1,
- &pstyle_css_scrollbar_bg_colour))
- return false;
- /* scroll position indicator bar */
- if (!html_redraw_scrollbar_rectangle(x + padding_width - w + 1,
- y + w + bar_top,
- x + padding_width - 2,
- y + w + bar_top + bar_height,
- css_scrollbar_fg_colour, false))
- return false;
- if (!plot.rectangle(x + padding_width - w + 2,
- y + w + bar_top + 1,
- x + padding_width - 2,
- y + w + bar_top + bar_height,
- &pstyle_css_scrollbar_fg_colour))
- return false;
- /* bottom arrow background */
- if (!html_redraw_scrollbar_rectangle(x + padding_width - w + 1,
- y + padding_height - w + 1,
- x + padding_width - 2,
- y + padding_height - 2,
- css_scrollbar_fg_colour, false))
- return false;
- if (!plot.rectangle(x + padding_width - w + 2,
- y + padding_height - w + 2,
- x + padding_width - 2,
- y + padding_height - 2,
- &pstyle_css_scrollbar_fg_colour))
- return false;
- /* down arrow */
- v[0] = x + padding_width - w / 2;
- v[1] = y + w + well_height + w * 3 / 4;
- v[2] = x + padding_width - w * 3 / 4;
- v[3] = y + w + well_height + w / 4;
- v[4] = x + padding_width - w / 4;
- v[5] = y + w + well_height + w / 4;
- if (!plot.polygon(v, 3, &pstyle_css_scrollbar_arrow_colour))
- return false;
+
+ if (!right && box->scroll_y != NULL) {
+ scroll_destroy(box->scroll_y);
+ box->scroll_y = NULL;
}
-
- return true;
-}
-
-
-/**
- * Determine if a box has a vertical scrollbar.
- *
- * \param box scrolling box
- * \return the box has a vertical scrollbar
- */
-
-bool box_vscrollbar_present(const struct box * const box)
-{
- return box->descendant_y0 < -box->border[TOP].width ||
- box->padding[TOP] + box->height + box->padding[BOTTOM] +
- box->border[BOTTOM].width < box->descendant_y1;
-}
-
-
-/**
- * Determine if a box has a horizontal scrollbar.
- *
- * \param box scrolling box
- * \return the box has a horizontal scrollbar
- */
-
-bool box_hscrollbar_present(const struct box * const box)
-{
- return box->descendant_x0 < -box->border[LEFT].width ||
- box->padding[LEFT] + box->width + box->padding[RIGHT] +
- box->border[RIGHT].width < box->descendant_x1;
-}
-
-
-/**
- * Calculate scrollbar dimensions and positions for a box.
- *
- * \param box scrolling box
- * \param padding_width scaled width of padding box
- * \param padding_height scaled height of padding box
- * \param w scaled scrollbar width
- * \param vscroll updated to vertical scrollbar present
- * \param hscroll updated to horizontal scrollbar present
- * \param well_height updated to vertical well height
- * \param bar_top updated to top position of vertical scrollbar
- * \param bar_height updated to height of vertical scrollbar
- * \param well_width updated to horizontal well width
- * \param bar_left updated to left position of horizontal scrollbar
- * \param bar_width updated to width of horizontal scrollbar
- */
-
-void box_scrollbar_dimensions(const struct box * const box,
- const int padding_width, const int padding_height, const int w,
- bool * const vscroll, bool * const hscroll,
- int * const well_height,
- int * const bar_top, int * const bar_height,
- int * const well_width,
- int * const bar_left, int * const bar_width)
-{
- *vscroll = box_vscrollbar_present(box);
- *hscroll = box_hscrollbar_present(box);
- *well_height = padding_height - w - w;
- *bar_top = 0;
- *bar_height = *well_height;
- if (box->descendant_y1 - box->descendant_y0 != 0) {
- *bar_top = (float) *well_height * (float) box->scroll_y /
- (float) (box->descendant_y1 -
- box->descendant_y0);
- *bar_height = (float) *well_height * (float) box->height /
- (float) (box->descendant_y1 -
- box->descendant_y0);
+
+ if (!bottom && !right)
+ return true;
+
+ if (right) {
+ if (box->scroll_y == NULL) {
+ if (!scroll_create(false,
+ padding_height,
+ box->descendant_y1 - box->descendant_y0,
+ box->height,
+ current_redraw_browser,
+ browser_scroll_callback,
+ &(box->scroll_y)))
+ return false;
+ } else
+ scroll_set_length_and_visible(box->scroll_y,
+ padding_height, box->height);
}
- *well_width = padding_width - w - w - (*vscroll ? w : 0);
- *bar_left = 0;
- *bar_width = *well_width;
- if (box->descendant_x1 - box->descendant_x0 != 0) {
- *bar_left = (float) *well_width * (float) box->scroll_x /
- (float) (box->descendant_x1 -
- box->descendant_x0);
- *bar_width = (float) *well_width * (float) box->width /
- (float) (box->descendant_x1 -
- box->descendant_x0);
+ if (bottom) {
+ if (box->scroll_x == NULL) {
+ if (!scroll_create(true,
+ padding_width -
+ (right ? SCROLLBAR_WIDTH : 0),
+ box->descendant_x1 - box->descendant_x0,
+ box->width,
+ current_redraw_browser,
+ browser_scroll_callback,
+ &box->scroll_x))
+ return false;
+ } else
+ scroll_set_length_and_visible(box->scroll_x,
+ padding_width -
+ (right ? SCROLLBAR_WIDTH : 0),
+ box->width);
}
+
+ return true;
}
Index: render/layout.c
===================================================================
--- render/layout.c (revision 9172)
+++ render/layout.c (working copy)
@@ -44,6 +44,7 @@
#include "content/content.h"
#include "desktop/gui.h"
#include "desktop/options.h"
+#include "desktop/scroll.h"
#include "render/box.h"
#include "render/font.h"
#include "render/form.h"
@@ -1990,7 +1991,8 @@
opt_maxwidth =opt_width;
}
- b->width = opt_maxwidth;
+ b->width = opt_maxwidth +
+ SCROLLBAR_WIDTH;
} else {
font_func->font_width(&fstyle, b->text,
b->length, &b->width);
@@ -2623,7 +2625,8 @@
opt_maxwidth =opt_width;
}
- b->width = opt_maxwidth;
+ b->width = opt_maxwidth +
+ SCROLLBAR_WIDTH;
} else {
font_func->font_width(&fstyle, b->text,
b->length, &b->width);
Index: render/layout.h
===================================================================
--- render/layout.h (revision 9172)
+++ render/layout.h (working copy)
@@ -27,8 +27,6 @@
#ifndef _NETSURF_RENDER_LAYOUT_H_
#define _NETSURF_RENDER_LAYOUT_H_
-#define SCROLLBAR_WIDTH 16
-
struct box;
bool layout_document(struct content *content, int width, int height);
Index: render/box.c
===================================================================
--- render/box.c (revision 9172)
+++ render/box.c (working copy)
@@ -29,6 +29,7 @@
#include "content/content.h"
#include "css/css.h"
#include "css/dump.h"
+#include "desktop/scroll.h"
#include "desktop/options.h"
#include "render/box.h"
#include "render/form.h"
@@ -80,7 +81,7 @@
box->descendant_x1 = box->descendant_y1 = 0;
for (i = 0; i != 4; i++)
box->margin[i] = box->padding[i] = box->border[i].width = 0;
- box->scroll_x = box->scroll_y = 0;
+ box->scroll_x = box->scroll_y = NULL;
box->min_width = 0;
box->max_width = UNKNOWN_MAX_WIDTH;
box->byte_offset = 0;
@@ -226,6 +227,10 @@
if (!box->clone) {
if (box->gadget)
form_free_control(box->gadget);
+ if (box->scroll_x != NULL)
+ scroll_destroy(box->scroll_x);
+ if (box->scroll_y != NULL)
+ scroll_destroy(box->scroll_y);
}
talloc_free(box);
@@ -251,8 +256,8 @@
} while (!box->float_children);
} else
box = box->parent;
- *x += box->x - box->scroll_x;
- *y += box->y - box->scroll_y;
+ *x += box->x - scroll_get(box->scroll_x);
+ *y += box->y - scroll_get(box->scroll_y);
}
}
@@ -328,8 +333,8 @@
/* consider floats second, since they will often overlap other boxes */
for (child = box->float_children; child; child = child->next_float) {
if (box_contains_point(child, x - bx, y - by, &physically)) {
- *box_x = bx + child->x - child->scroll_x;
- *box_y = by + child->y - child->scroll_y;
+ *box_x = bx + child->x - scroll_get(child->scroll_x);
+ *box_y = by + child->y - scroll_get(child->scroll_y);
if (physically)
return child;
@@ -345,8 +350,8 @@
if (box_is_float(child))
continue;
if (box_contains_point(child, x - bx, y - by, &physically)) {
- *box_x = bx + child->x - child->scroll_x;
- *box_y = by + child->y - child->scroll_y;
+ *box_x = bx + child->x - scroll_get(child->scroll_x);
+ *box_y = by + child->y - scroll_get(child->scroll_y);
if (physically)
return child;
@@ -370,16 +375,16 @@
/* siblings and siblings of ancestors */
while (box) {
if (box_is_float(box)) {
- bx -= box->x - box->scroll_x;
- by -= box->y - box->scroll_y;
+ bx -= box->x - scroll_get(box->scroll_x);
+ by -= box->y - scroll_get(box->scroll_y);
for (sibling = box->next_float; sibling;
sibling = sibling->next_float) {
if (box_contains_point(sibling,
x - bx, y - by, &physically)) {
- *box_x = bx + sibling->x -
- sibling->scroll_x;
- *box_y = by + sibling->y -
- sibling->scroll_y;
+ *box_x = bx + sibling->x - scroll_get(
+ sibling->scroll_x);
+ *box_y = by + sibling->y - scroll_get(
+ sibling->scroll_y);
if (physically)
return sibling;
@@ -398,18 +403,18 @@
goto non_float_children;
} else {
- bx -= box->x - box->scroll_x;
- by -= box->y - box->scroll_y;
+ bx -= box->x - scroll_get(box->scroll_x);
+ by -= box->y - scroll_get(box->scroll_y);
for (sibling = box->next; sibling;
sibling = sibling->next) {
if (box_is_float(sibling))
continue;
if (box_contains_point(sibling, x - bx, y - by,
&physically)) {
- *box_x = bx + sibling->x -
- sibling->scroll_x;
- *box_y = by + sibling->y -
- sibling->scroll_y;
+ *box_x = bx + sibling->x - scroll_get(
+ sibling->scroll_x);
+ *box_y = by + sibling->y - scroll_get(
+ sibling->scroll_y);
if (physically)
return sibling;
@@ -978,3 +983,33 @@
box->next_float = box_dict_element->new;
}
}
+
+
+/**
+ * Determine if a box has a vertical scrollbar.
+ *
+ * \param box scrolling box
+ * \return the box has a vertical scrollbar
+ */
+
+bool box_vscrollbar_present(const struct box * const box)
+{
+ return box->descendant_y0 < -box->border[TOP].width ||
+ box->padding[TOP] + box->height + box->padding[BOTTOM] +
+ box->border[BOTTOM].width < box->descendant_y1;
+}
+
+
+/**
+ * Determine if a box has a horizontal scrollbar.
+ *
+ * \param box scrolling box
+ * \return the box has a horizontal scrollbar
+ */
+
+bool box_hscrollbar_present(const struct box * const box)
+{
+ return box->descendant_x0 < -box->border[LEFT].width ||
+ box->padding[LEFT] + box->width + box->padding[RIGHT] +
+ box->border[RIGHT].width < box->descendant_x1;
+}
Index: render/box.h
===================================================================
--- render/box.h (revision 9172)
+++ render/box.h (working copy)
@@ -167,8 +167,8 @@
int padding[4]; /**< Padding: TOP, RIGHT, BOTTOM, LEFT. */
struct box_border border[4]; /**< Border: TOP, RIGHT, BOTTOM, LEFT. */
- int scroll_x; /**< Horizontal scroll of descendants. */
- int scroll_y; /**< Vertical scroll of descendants. */
+ struct scroll *scroll_x; /**< Horizontal scroll. */
+ struct scroll *scroll_y; /**< Vertical scroll. */
/** Width of box taking all line breaks (including margins etc). Must
* be non-negative. */
@@ -314,15 +314,10 @@
void box_dump(FILE *stream, struct box *box, unsigned int depth);
bool box_extract_link(const char *rel, const char *base, char **result);
+bool box_handle_scrollbars(struct box *box, int x, int y, bool bottom,
+ bool right);
bool box_vscrollbar_present(const struct box *box);
bool box_hscrollbar_present(const struct box *box);
-void box_scrollbar_dimensions(const struct box *box,
- int padding_width, int padding_height, int w,
- bool *vscroll, bool *hscroll,
- int *well_height,
- int *bar_top, int *bar_height,
- int *well_width,
- int *bar_left, int *bar_width);
bool xml_to_box(xmlNode *n, struct content *c);
Index: framebuffer/gui.c
===================================================================
--- framebuffer/gui.c (revision 9172)
+++ framebuffer/gui.c (working copy)
@@ -41,6 +41,7 @@
#include "utils/messages.h"
#include "utils/utils.h"
#include "desktop/textinput.h"
+#include "render/form.h"
#include "framebuffer/gui.h"
#include "framebuffer/fbtk.h"
@@ -292,14 +293,15 @@
nsfb_claim(fbtk_get_nsfb(widget), &bwidget->redraw_box);
/* redraw bounding box is relative to window */
+ current_redraw_browser = bw;
content_redraw(c,
x - bwidget->scrollx, y - bwidget->scrolly,
width, height,
bwidget->redraw_box.x0, bwidget->redraw_box.y0,
bwidget->redraw_box.x1, bwidget->redraw_box.y1,
bw->scale, 0xFFFFFF);
+ current_redraw_browser = NULL;
-
nsfb_release(fbtk_get_nsfb(widget), &bwidget->redraw_box);
bwidget->redraw_box.y0 = bwidget->redraw_box.x0 = INT_MAX;
@@ -1281,6 +1283,7 @@
void gui_create_form_select_menu(struct browser_window *bw,
struct form_control *control)
{
+ form_open_select_menu(bw, control, browser_select_menu_callback);
}
void gui_launch_url(const char *url)
Index: gtk/gtk_window.c
===================================================================
--- gtk/gtk_window.c (revision 9172)
+++ gtk/gtk_window.c (working copy)
@@ -305,8 +305,8 @@
if (c->type == CONTENT_HTML)
scale = 1;
- current_widget = widget;
- current_drawable = widget->window;
+ current_widget = (GtkWidget *)g->drawing_area;
+ current_drawable = current_widget->window;
current_gc = gdk_gc_new(current_drawable);
#ifdef CAIRO_VERSION
current_cr = gdk_cairo_create(current_drawable);
@@ -315,6 +315,7 @@
plot = nsgtk_plotters;
nsgtk_plot_set_scale(g->bw->scale);
current_redraw_browser = g->bw;
+
content_redraw(c, 0, 0,
widget->allocation.width * scale,
widget->allocation.height * scale,
@@ -328,6 +329,7 @@
if (g->careth != 0)
nsgtk_plot_caret(g->caretx, g->carety, g->careth);
+ current_widget = NULL;
g_object_unref(current_gc);
#ifdef CAIRO_VERSION
cairo_destroy(current_cr);
@@ -442,7 +444,8 @@
browser_window_mouse_click(g->bw, g->mouse->state, event->x / g->bw->scale,
event->y / g->bw->scale);
else
- browser_window_mouse_drag_end(g->bw, 0, event->x, event->y);
+ browser_window_mouse_drag_end(g->bw, 0, event->x / g->bw->scale,
+ event->y / g->bw->scale);
g->mouse->state = 0;
return TRUE;
@@ -654,8 +657,10 @@
return;
gtk_widget_queue_draw_area(GTK_WIDGET(g->drawing_area),
- data->redraw.x, data->redraw.y,
- data->redraw.width, data->redraw.height);
+ data->redraw.x * g->bw->scale,
+ data->redraw.y * g->bw->scale,
+ data->redraw.width * g->bw->scale,
+ data->redraw.height * g->bw->scale);
}
bool gui_window_get_scroll(struct gui_window *g, int *sx, int *sy)
Index: gtk/gtk_scaffolding.c
===================================================================
--- gtk/gtk_scaffolding.c (revision 9172)
+++ gtk/gtk_scaffolding.c (working copy)
@@ -1182,6 +1182,7 @@
history_redraw(bw->history);
+ current_widget = NULL;
g_object_unref(current_gc);
#ifdef CAIRO_VERSION
cairo_destroy(current_cr);
Index: gtk/gtk_plotters.h
===================================================================
--- gtk/gtk_plotters.h (revision 9172)
+++ gtk/gtk_plotters.h (working copy)
@@ -29,6 +29,7 @@
extern const struct plotter_table nsgtk_plotters;
+/* make sure this is NULL if no redraw is in progress */
extern GtkWidget *current_widget;
extern GdkDrawable *current_drawable;
extern GdkGC *current_gc;
Index: !NetSurf/Resources/de/Messages
===================================================================
--- !NetSurf/Resources/de/Messages (revision 9172)
+++ !NetSurf/Resources/de/Messages (working copy)
@@ -700,6 +700,10 @@
ScrollPRight:Anklicken scrollt eine Seite nach rechts
ScrollRight:Pfeil anklicken scrollt rechts
+# Select menu - displayed in status bar
+#
+SelectClick:Click on entry to select it
+SelectMClick:Click on entry to select it, (Ctrl + click) for multiple select)
# Saving
# ======
Index: !NetSurf/Resources/en/Messages
===================================================================
--- !NetSurf/Resources/en/Messages (revision 9172)
+++ !NetSurf/Resources/en/Messages (working copy)
@@ -705,6 +705,10 @@
ScrollPRight:Click to scroll right one page
ScrollRight:Click the arrow to scroll right
+# Select menu - displayed in status bar
+#
+SelectClick:Click on entry to select it
+SelectMClick:Click on entry to select it, (Ctrl + click) for multiple select)
# Saving
# ======
Index: !NetSurf/Resources/fr/Messages
===================================================================
--- !NetSurf/Resources/fr/Messages (revision 9172)
+++ !NetSurf/Resources/fr/Messages (working copy)
@@ -700,6 +700,10 @@
ScrollPRight:Cliquez pour faire défiler d'une page vers la droite
ScrollRight:Cliquez sur la flÚche pour faire défiler vers la droite
+# Select menu - displayed in status bar
+#
+SelectClick:Click on entry to select it
+SelectMClick:Click on entry to select it, (Ctrl + click) for multiple select)
# Saving
# ======
@@ -761,7 +765,7 @@
HelpToolbar4:\Tle bouton Accueil.|M\Saller à votre page d'accueil.
HelpToolbar5:\Tle bouton d'historique.|M\Souvrir la \w d'historique locale.|M\Aopen the global history \w.
HelpToolbar6:\Tle bouton de sauvegarde.|M\Ssauver le document en cours.
-HelpToolbar7:\Tle bouton d'impression.|M\Simprimer cette page.|MOuvre une boîte de dialogue pour l'impression.
+HelpToolbar7:\Tle bouton d'impression.|M\Simprimer cette page.|MOuvre une boᅵte de dialogue pour l'impression.
HelpToolbar8:\Tle bouton de favoris.|M\Souvrir la \w de gestion des favoris.|M\Aajouter cette adresse aux favoris.
HelpToolbar9:\Tle bouton de changement d'échelle.|M\Sredimensionner la page, texte et images comprises.
HelpToolbar10:\Tle bouton de recherche.|M\Strouver des occurences de fragment de texte dans une page.
Index: !NetSurf/Resources/nl/Messages
===================================================================
--- !NetSurf/Resources/nl/Messages (revision 9172)
+++ !NetSurf/Resources/nl/Messages (working copy)
@@ -700,6 +700,10 @@
ScrollPRight:Click to scroll right one page
ScrollRight:Click the arrow to scroll right
+# Select menu - displayed in status bar
+#
+SelectClick:Click on entry to select it
+SelectMClick:Click on entry to select it, (Ctrl + click) for multiple select)
# Saving
# ======
Index: !NetSurf/Resources/it/Messages
===================================================================
--- !NetSurf/Resources/it/Messages (revision 9172)
+++ !NetSurf/Resources/it/Messages (working copy)
@@ -707,6 +707,10 @@
ScrollPRight:Clicca per scrollare a destra di una pagina
ScrollRight:Clicca sulla freccia per scrollare a destra
+# Select menu - displayed in status bar
+#
+SelectClick:Click on entry to select it
+SelectMClick:Click on entry to select it, (Ctrl + click) for multiple select)
# Saving
# ======
Index: Makefile.sources
===================================================================
--- Makefile.sources (revision 9172)
+++ Makefile.sources (working copy)
@@ -14,7 +14,7 @@
S_UTILS := base64.c filename.c hashtable.c locale.c messages.c talloc.c \
url.c utf8.c utils.c useragent.c
S_DESKTOP := knockout.c options.c print.c tree.c version.c textarea.c \
- plot_style.c
+ plot_style.c scroll.c
# S_COMMON are sources common to all builds
S_COMMON := $(addprefix content/,$(S_CONTENT)) \
Index: desktop/textinput.c
===================================================================
--- desktop/textinput.c (revision 9172)
+++ desktop/textinput.c (working copy)
@@ -30,6 +30,7 @@
#include "desktop/browser.h"
#include "desktop/gui.h"
+#include "desktop/scroll.h"
#include "desktop/selection.h"
#include "desktop/textinput.h"
#include "render/box.h"
@@ -279,11 +280,11 @@
textarea->gadget->caret_box_offset = char_offset;
textarea->gadget->caret_pixel_offset = pixel_offset;
- box_x += textarea->scroll_x;
- box_y += textarea->scroll_y;
+ box_x += scroll_get(textarea->scroll_x);
+ box_y += scroll_get(textarea->scroll_y);
scrolled = ensure_caret_visible(textarea);
- box_x -= textarea->scroll_x;
- box_y -= textarea->scroll_y;
+ box_x -= scroll_get(textarea->scroll_x);
+ box_y -= scroll_get(textarea->scroll_y);
browser_window_place_caret(bw,
box_x + inline_container->x + text_box->x +
@@ -332,8 +333,8 @@
(int) text_box->length, text_box->text));
box_coords(textarea, &box_x, &box_y);
- box_x -= textarea->scroll_x;
- box_y -= textarea->scroll_y;
+ box_x -= scroll_get(textarea->scroll_x);
+ box_y -= scroll_get(textarea->scroll_y);
if (!(key <= 0x001F || (0x007F <= key && key <= 0x009F))) {
/* normal character insertion */
@@ -756,8 +757,8 @@
assert(text_box);
assert(char_offset <= text_box->length);
/* Scroll back to the left */
- box_x += textarea->scroll_x;
- textarea->scroll_x = 0;
+ box_x += scroll_get(textarea->scroll_x);
+ scroll_set(textarea->scroll_x, 0, false);
} else {
assert(!text_box->next ||
(text_box->next &&
@@ -778,11 +779,11 @@
textarea->gadget->caret_box_offset = char_offset;
textarea->gadget->caret_pixel_offset = pixel_offset;
- box_x += textarea->scroll_x;
- box_y += textarea->scroll_y;
+ box_x += scroll_get(textarea->scroll_x);
+ box_y += scroll_get(textarea->scroll_y);
scrolled = ensure_caret_visible(textarea);
- box_x -= textarea->scroll_x;
- box_y -= textarea->scroll_y;
+ box_x -= scroll_get(textarea->scroll_x);
+ box_y -= scroll_get(textarea->scroll_y);
browser_window_place_caret(bw,
box_x + inline_container->x + text_box->x +
@@ -1398,11 +1399,11 @@
textarea->gadget->caret_pixel_offset = pixel_offset;
box_coords(textarea, &box_x, &box_y);
- box_x += textarea->scroll_x;
- box_y += textarea->scroll_y;
+ box_x += scroll_get(textarea->scroll_x);
+ box_y += scroll_get(textarea->scroll_y);
ensure_caret_visible(textarea);
- box_x -= textarea->scroll_x;
- box_y -= textarea->scroll_y;
+ box_x -= scroll_get(textarea->scroll_x);
+ box_y -= scroll_get(textarea->scroll_y);
browser_window_place_caret(bw,
box_x + inline_container->x + text_box->x +
@@ -1518,8 +1519,8 @@
font_plot_style_from_css(text_box->style, &fstyle);
box_coords(textarea, &box_x, &box_y);
- box_x -= textarea->scroll_x;
- box_y -= textarea->scroll_y;
+ box_x -= scroll_get(textarea->scroll_x);
+ box_y -= scroll_get(textarea->scroll_y);
nsfont.font_width(&fstyle, text_box->text,
char_offset, &pixel_offset);
@@ -2191,8 +2192,8 @@
assert(textarea->gadget);
- scrollx = textarea->scroll_x;
- scrolly = textarea->scroll_y;
+ scrollx = scroll_get(textarea->scroll_x);
+ scrolly = scroll_get(textarea->scroll_y);
/* Calculate the caret coordinates */
cx = textarea->gadget->caret_pixel_offset +
@@ -2200,29 +2201,31 @@
cy = textarea->gadget->caret_text_box->y;
/* Ensure they are visible */
- if (!box_hscrollbar_present(textarea)) {
+ if (textarea->scroll_x == NULL) {
scrollx = 0;
- } else if (cx-textarea->scroll_x < 0) {
+ } else if (cx - scroll_get(textarea->scroll_x) < 0) {
scrollx = cx;
- } else if (cx > textarea->scroll_x + textarea->width) {
+ } else if (cx > scroll_get(textarea->scroll_x) + textarea->width) {
scrollx = cx - textarea->width;
}
- if (!box_vscrollbar_present(textarea)) {
+ if (textarea->scroll_y == NULL) {
scrolly = 0;
- } else if (cy - textarea->scroll_y < 0) {
+ } else if (cy - scroll_get(textarea->scroll_y) < 0) {
scrolly = cy;
} else if (cy + textarea->gadget->caret_text_box->height >
- textarea->scroll_y + textarea->height) {
+ scroll_get(textarea->scroll_y) + textarea->height) {
scrolly = (cy + textarea->gadget->caret_text_box->height) -
textarea->height;
}
- if ((scrollx == textarea->scroll_x) && (scrolly == textarea->scroll_y))
+ if ((scrollx == scroll_get(textarea->scroll_x)) &&
+ (scrolly == scroll_get(textarea->scroll_y)))
return false;
- textarea->scroll_x = scrollx;
- textarea->scroll_y = scrolly;
+
+ scroll_set(textarea->scroll_x, scrollx, false);
+ scroll_set(textarea->scroll_y, scrolly, false);
return true;
}
Index: desktop/browser.c
===================================================================
--- desktop/browser.c (revision 9172)
+++ desktop/browser.c (working copy)
@@ -5,6 +5,7 @@
* Copyright 2004 John Tytgat <joty(a)netsurf-browser.org>
* Copyright 2006 Richard Wilson <info(a)tinct.net>
* Copyright 2008 Michael Drake <tlsa(a)netsurf-browser.org>
+ * Copyright 2009 Paul Blokus <paul_pl(a)users.sourceforge.net>
*
* This file is part of NetSurf, http://www.netsurf-browser.org/
*
@@ -46,6 +47,7 @@
#include "desktop/history_core.h"
#include "desktop/gui.h"
#include "desktop/options.h"
+#include "desktop/scroll.h"
#include "desktop/selection.h"
#include "desktop/textinput.h"
#include "render/box.h"
@@ -109,9 +111,6 @@
browser_mouse_state mouse, int x, int y);
static void browser_window_mouse_track_text(struct browser_window *bw,
browser_mouse_state mouse, int x, int y);
-static const char *browser_window_scrollbar_click(struct browser_window *bw,
- browser_mouse_state mouse, struct box *box,
- int box_x, int box_y, int x, int y);
static void browser_radio_set(struct content *content,
struct form_control *radio);
static gui_pointer_shape get_pointer_shape(struct browser_window *bw,
@@ -126,10 +125,9 @@
int x, int y, int dir, int *dx, int *dy);
static void browser_window_page_drag_start(struct browser_window *bw,
int x, int y);
-static void browser_window_scroll_box(struct browser_window *bw,
- struct box *box, int scroll_x, int scroll_y);
+static void browser_window_box_drag_start(struct browser_window *bw,
+ struct box *box, int x, int y);
-
/**
* Create and open a new browser window with the given page.
*
@@ -444,6 +442,8 @@
bw->loading_content = NULL;
browser_window_remove_caret(bw);
bw->scrolling_box = NULL;
+ bw->scroll_x = NULL;
+ bw->scroll_y = NULL;
gui_window_new_content(bw->window);
if (bw->current_content) {
browser_window_refresh_url_bar(bw,
@@ -515,6 +515,8 @@
bw->current_content = 0;
browser_window_remove_caret(bw);
bw->scrolling_box = NULL;
+ bw->scroll_x = NULL;
+ bw->scroll_y = NULL;
selection_init(bw->sel, NULL);
}
browser_window_stop_throbber(bw);
@@ -592,6 +594,8 @@
bw->current_content = 0;
browser_window_remove_caret(bw);
bw->scrolling_box = NULL;
+ bw->scroll_x = NULL;
+ bw->scroll_y = NULL;
selection_init(bw->sel, NULL);
}
browser_window_stop_throbber(bw);
@@ -607,6 +611,8 @@
bw->current_content = 0;
browser_window_remove_caret(bw);
bw->scrolling_box = NULL;
+ bw->scroll_x = NULL;
+ bw->scroll_y = NULL;
selection_init(bw->sel, NULL);
}
browser_window_stop_throbber(bw);
@@ -1103,6 +1109,8 @@
assert(bw);
assert(url);
+
+ bw->visible_select_menu = NULL;
if (frag == NULL) {
/* With no fragment, we may as well pass url straight through
@@ -1392,11 +1400,9 @@
bool imagemap = false;
int box_x = 0, box_y = 0;
int gadget_box_x = 0, gadget_box_y = 0;
- int scroll_box_x = 0, scroll_box_y = 0;
int text_box_x = 0;
struct box *url_box = 0;
struct box *gadget_box = 0;
- struct box *scroll_box = 0;
struct box *text_box = 0;
struct content *c = bw->current_content;
struct box *box;
@@ -1405,8 +1411,58 @@
struct form_control *gadget = 0;
struct content *object = NULL;
struct box *next_box;
+ struct box *drag_candidate = NULL;
+ struct scroll *scroll = NULL;
plot_font_style_t fstyle;
+ int scroll_mouse_x = 0, scroll_mouse_y = 0;
+
+ if (bw->visible_select_menu != NULL) {
+ box = bw->visible_select_menu->box;
+ box_coords(box, &box_x, &box_y);
+
+ box_x -= box->border[LEFT].width;
+ box_y += box->height + box->border[BOTTOM].width +
+ box->padding[BOTTOM] + box->padding[TOP];
+ status = form_select_mouse_action(bw->visible_select_menu,
+ mouse, x - box_x, y - box_y);
+ if (status != NULL)
+ browser_window_set_status(bw, status);
+ else {
+ int width, height;
+ form_select_get_dimensions(bw->visible_select_menu,
+ &width, &height);
+ bw->visible_select_menu = NULL;
+ browser_window_redraw_rect(bw, box_x, box_y,
+ width, height);
+ }
+ return;
+ }
+
+ if (bw->scroll_x != NULL || bw->scroll_y != NULL) {
+ box = bw->scrolling_box;
+ box_coords(box, &box_x, &box_y);
+ if (bw->scroll_x != NULL) {
+ scroll_mouse_x = x - box_x ;
+ scroll_mouse_y = y - (box_y + box->padding[TOP] +
+ box->height + box->padding[BOTTOM] -
+ SCROLLBAR_WIDTH);
+ status = scroll_mouse_action(bw->scroll_x, mouse,
+ scroll_mouse_x, scroll_mouse_y);
+ }
+ if (bw->scroll_y != NULL) {
+ scroll_mouse_x = x - (box_x + box->padding[LEFT] +
+ box->width + box->padding[RIGHT] -
+ SCROLLBAR_WIDTH);
+ scroll_mouse_y = y - box_y;
+ status = scroll_mouse_action(bw->scroll_y, mouse,
+ scroll_mouse_x, scroll_mouse_y);
+ }
+
+ browser_window_set_status(bw, status);
+ return;
+ }
+
bw->drag_type = DRAGGING_NONE;
bw->scrolling_box = NULL;
@@ -1465,20 +1521,38 @@
if (box->style)
overflow = css_computed_overflow(box->style);
- if (box->style && box->type != BOX_BR &&
- box->type != BOX_INLINE &&
- box->type != BOX_TEXT &&
- (overflow == CSS_OVERFLOW_SCROLL ||
- overflow == CSS_OVERFLOW_AUTO) &&
- ((box_vscrollbar_present(box) &&
- box_x + box->scroll_x + box->padding[LEFT] +
- box->width < x) ||
- (box_hscrollbar_present(box) &&
- box_y + box->scroll_y + box->padding[TOP] +
- box->height < y))) {
- scroll_box = box;
- scroll_box_x = box_x + box->scroll_x;
- scroll_box_y = box_y + box->scroll_y;
+ if ((box->scroll_x != NULL || box->scroll_y != NULL) &&
+ drag_candidate == NULL)
+ drag_candidate = box;
+
+ if (box->scroll_y != NULL &&
+ x > box_x + scroll_get(box->scroll_x) +
+ box->padding[LEFT] + box->width +
+ box->padding[RIGHT] - SCROLLBAR_WIDTH) {
+ bw->scrolling_box = box;
+ scroll = box->scroll_y;
+ scroll_mouse_x = x - (box_x +
+ scroll_get(box->scroll_x) +
+ box->padding[LEFT] +
+ box->width + box->padding[RIGHT] -
+ SCROLLBAR_WIDTH);
+ scroll_mouse_y = y -
+ (box_y + scroll_get(box->scroll_y));
+ break;
+ } else if (box->scroll_x != NULL &&
+ y > box_y + scroll_get(box->scroll_y) +
+ box->padding[TOP] + box->height +
+ box->padding[BOTTOM] - SCROLLBAR_WIDTH) {
+ bw->scrolling_box = box;
+ scroll = box->scroll_x;
+ scroll_mouse_x = x -
+ (box_x + scroll_get(box->scroll_x));
+ scroll_mouse_y = y - (box_y +
+ scroll_get(box->scroll_y) +
+ box->padding[TOP] +
+ box->height + box->padding[BOTTOM] -
+ SCROLLBAR_WIDTH);
+ break;
}
if (box->text && !box->object) {
@@ -1490,18 +1564,22 @@
/* use of box_x, box_y, or content below this point is probably a
* mistake; they will refer to the last box returned by box_at_point */
- if (scroll_box) {
- status = browser_window_scrollbar_click(bw, mouse, scroll_box,
- scroll_box_x, scroll_box_y,
- x - scroll_box_x, y - scroll_box_y);
+ if (scroll) {
+ status = scroll_mouse_action(scroll, mouse,
+ scroll_mouse_x, scroll_mouse_y);
pointer = GUI_POINTER_DEFAULT;
} else if (gadget) {
switch (gadget->type) {
case GADGET_SELECT:
status = messages_get("FormSelect");
pointer = GUI_POINTER_MENU;
- if (mouse & BROWSER_MOUSE_CLICK_1)
- gui_create_form_select_menu(bw, gadget);
+ if (mouse & BROWSER_MOUSE_CLICK_1) {
+ bw->visible_select_menu = gadget;
+ form_open_select_menu(bw, gadget,
+ browser_select_menu_callback,
+ bw);
+ pointer = GUI_POINTER_DEFAULT;
+ }
break;
case GADGET_CHECKBOX:
status = messages_get("FormCheckbox");
@@ -1749,8 +1827,15 @@
gui_drag_save_object(GUI_SAVE_COMPLETE,
c, bw->window);
} else {
- browser_window_page_drag_start(bw,
- x, y);
+ if (drag_candidate == NULL)
+ browser_window_page_drag_start(
+ bw, x, y);
+ else {
+ browser_window_box_drag_start(
+ bw,
+ drag_candidate,
+ x, y);
+ }
pointer = GUI_POINTER_MOVE;
}
}
@@ -1759,8 +1844,15 @@
gui_drag_save_object(GUI_SAVE_SOURCE,
c, bw->window);
} else {
- browser_window_page_drag_start(bw,
- x, y);
+ if (drag_candidate == NULL)
+ browser_window_page_drag_start(
+ bw, x, y);
+ else {
+ browser_window_box_drag_start(
+ bw,
+ drag_candidate,
+ x, y);
+ }
pointer = GUI_POINTER_MOVE;
}
}
@@ -1926,54 +2018,8 @@
void browser_window_mouse_track_html(struct browser_window *bw,
browser_mouse_state mouse, int x, int y)
{
+
switch (bw->drag_type) {
- case DRAGGING_HSCROLL:
- case DRAGGING_VSCROLL:
- case DRAGGING_2DSCROLL: {
- struct box *box = bw->scrolling_box;
- int scroll_y;
- int scroll_x;
-
- assert(box);
-
- if (bw->drag_type == DRAGGING_HSCROLL) {
- scroll_y = box->scroll_y;
- } else {
- scroll_y = bw->drag_start_scroll_y +
- (float) (y - bw->drag_start_y) /
- (float) bw->drag_well_height *
- (float) (box->descendant_y1 -
- box->descendant_y0);
- if (scroll_y < box->descendant_y0)
- scroll_y = box->descendant_y0;
- else if (box->descendant_y1 - box->height <
- scroll_y)
- scroll_y = box->descendant_y1 -
- box->height;
- if (scroll_y == box->scroll_y)
- return;
- }
-
- if (bw->drag_type == DRAGGING_VSCROLL) {
- scroll_x = box->scroll_x;
- } else {
- scroll_x = bw->drag_start_scroll_x +
- (float) (x - bw->drag_start_x) /
- (float) bw->drag_well_width *
- (float) (box->descendant_x1 -
- box->descendant_x0);
- if (scroll_x < box->descendant_x0)
- scroll_x = box->descendant_x0;
- else if (box->descendant_x1 - box->width <
- scroll_x)
- scroll_x = box->descendant_x1 -
- box->width;
- }
-
- browser_window_scroll_box(bw, box, scroll_x, scroll_y);
- }
- break;
-
case DRAGGING_SELECTION: {
struct box *box;
int dir = -1;
@@ -2052,6 +2098,43 @@
void browser_window_mouse_drag_end(struct browser_window *bw,
browser_mouse_state mouse, int x, int y)
{
+ struct box *box;
+ int scroll_mouse_x, scroll_mouse_y, box_x, box_y;
+
+ if (bw->visible_select_menu != NULL) {
+ box = bw->visible_select_menu->box;
+ box_coords(box, &box_x, &box_y);
+
+ box_x -= box->border[LEFT].width;
+ box_y += box->height + box->border[BOTTOM].width +
+ box->padding[BOTTOM] + box->padding[TOP];
+ form_select_mouse_drag_end(bw->visible_select_menu,
+ mouse, x - box_x, y - box_y);
+ return;
+ }
+
+ if (bw->scroll_x != NULL || bw->scroll_y != NULL) {
+ box = bw->scrolling_box;
+ box_coords(box, &box_x, &box_y);
+ if (bw->scroll_x != NULL) {
+ scroll_mouse_x = x - box_x;
+ scroll_mouse_y = y - box_y + box->padding[TOP] +
+ box->height + box->padding[BOTTOM] -
+ SCROLLBAR_WIDTH;
+ scroll_mouse_drag_end(bw->scroll_x, mouse,
+ scroll_mouse_x, scroll_mouse_y);
+ }
+ if (bw->scroll_y != NULL) {
+ scroll_mouse_x = x - box_x + box->padding[LEFT] +
+ box->width + box->padding[RIGHT] -
+ SCROLLBAR_WIDTH;
+ scroll_mouse_y = y - box_y;
+ scroll_mouse_drag_end(bw->scroll_y, mouse,
+ scroll_mouse_x, scroll_mouse_y);
+ }
+ return;
+ }
+
switch (bw->drag_type) {
case DRAGGING_SELECTION: {
struct content *c = bw->current_content;
@@ -2104,13 +2187,6 @@
}
break;
- case DRAGGING_2DSCROLL:
- case DRAGGING_PAGE_SCROLL:
- case DRAGGING_FRAME:
- browser_window_set_pointer(bw->window,
- GUI_POINTER_DEFAULT);
- break;
-
default:
break;
}
@@ -2120,157 +2196,6 @@
/**
- * Handle mouse clicks in a box scrollbar.
- *
- * \param bw browser window
- * \param mouse state of mouse buttons and modifier keys
- * \param box scrolling box
- * \param box_x position of box in global document coordinates
- * \param box_y position of box in global document coordinates
- * \param x coordinate of click relative to box position
- * \param y coordinate of click relative to box position
- * \return status bar message
- */
-
-const char *browser_window_scrollbar_click(struct browser_window *bw,
- browser_mouse_state mouse, struct box *box,
- int box_x, int box_y, int x, int y)
-{
- bool but1 = ((mouse & BROWSER_MOUSE_PRESS_1) ||
- ((mouse & BROWSER_MOUSE_HOLDING_1) &&
- (mouse & BROWSER_MOUSE_DRAG_ON)));
- bool but2 = ((mouse & BROWSER_MOUSE_PRESS_2) ||
- ((mouse & BROWSER_MOUSE_HOLDING_2) &&
- (mouse & BROWSER_MOUSE_DRAG_ON)));
- const int w = SCROLLBAR_WIDTH;
- bool vscroll, hscroll;
- int well_height, bar_top, bar_height;
- int well_width, bar_left, bar_width;
- const char *status = 0;
- bool vert;
- int z, scroll, bar_start, bar_size, well_size, page;
-
- box_scrollbar_dimensions(box,
- box->padding[LEFT] + box->width + box->padding[RIGHT],
- box->padding[TOP] + box->height + box->padding[BOTTOM],
- w,
- &vscroll, &hscroll,
- &well_height, &bar_top, &bar_height,
- &well_width, &bar_left, &bar_width);
-
- /* store some data for scroll drags */
- bw->scrolling_box = box;
- bw->drag_start_x = box_x + x;
- bw->drag_start_y = box_y + y;
- bw->drag_start_scroll_x = box->scroll_x;
- bw->drag_start_scroll_y = box->scroll_y;
- bw->drag_well_width = well_width;
- bw->drag_well_height = well_height;
-
- /* determine which scrollbar was clicked */
- if (box_vscrollbar_present(box) &&
- box->padding[LEFT] + box->width < x) {
- vert = true;
- z = y;
- scroll = box->scroll_y;
- well_size = well_height;
- bar_start = bar_top;
- bar_size = bar_height;
- page = box->height;
- } else {
- vert = false;
- z = x;
- scroll = box->scroll_x;
- well_size = well_width;
- bar_start = bar_left;
- bar_size = bar_width;
- page = box->width;
- }
-
- /* find icon in scrollbar and calculate scroll */
- if (z < w) {
- /* on scrollbar bump arrow button */
- status = messages_get(vert ? "ScrollUp" : "ScrollLeft");
- if (but1)
- scroll -= 16;
- else if (but2)
- scroll += 16;
- } else if (z < w + bar_start + w / 4) {
- /* in scrollbar well */
- status = messages_get(vert ? "ScrollPUp" : "ScrollPLeft");
- if (but1)
- scroll -= page;
- else if (but2)
- scroll += page;
- } else if (z < w + bar_start + bar_size - w / 4) {
- /* in scrollbar */
- status = messages_get(vert ? "ScrollV" : "ScrollH");
-
- if (mouse & (BROWSER_MOUSE_HOLDING_1 |
- BROWSER_MOUSE_HOLDING_2)) {
- int x0 = 0, x1 = 0;
- int y0 = 0, y1 = 0;
-
- if (mouse & BROWSER_MOUSE_HOLDING_1) {
- bw->drag_type = vert ? DRAGGING_VSCROLL :
- DRAGGING_HSCROLL;
- } else
- bw->drag_type = DRAGGING_2DSCROLL;
-
- /* \todo - some proper numbers please! */
- if (bw->drag_type != DRAGGING_VSCROLL) {
- x0 = -1024;
- x1 = 1024;
- }
- if (bw->drag_type != DRAGGING_HSCROLL) {
- y0 = -1024;
- y1 = 1024;
- }
- gui_window_box_scroll_start(bw->window, x0, y0, x1, y1);
- if (bw->drag_type == DRAGGING_2DSCROLL)
- gui_window_hide_pointer(bw->window);
- }
- } else if (z < w + well_size) {
- /* in scrollbar well */
- status = messages_get(vert ? "ScrollPDown" : "ScrollPRight");
- if (but1)
- scroll += page;
- else if (but2)
- scroll -= page;
- } else {
- /* on scrollbar bump arrow button */
- status = messages_get(vert ? "ScrollDown" : "ScrollRight");
- if (but1)
- scroll += 16;
- else if (but2)
- scroll -= 16;
- }
-
- /* update box and redraw */
- if (vert) {
- if (scroll < box->descendant_y0)
- scroll = box->descendant_y0;
- else if (box->descendant_y1 - box->height < scroll)
- scroll = box->descendant_y1 - box->height;
- if (scroll != box->scroll_y)
- browser_window_scroll_box(bw, box, box->scroll_x,
- scroll);
-
- } else {
- if (scroll < box->descendant_x0)
- scroll = box->descendant_x0;
- else if (box->descendant_x1 - box->width < scroll)
- scroll = box->descendant_x1 - box->width;
- if (scroll != box->scroll_x)
- browser_window_scroll_box(bw, box, scroll,
- box->scroll_y);
- }
-
- return status;
-}
-
-
-/**
* Set a radio form control and clear the others in the group.
*
* \param content content containing the form, of type CONTENT_TYPE
@@ -2380,27 +2305,6 @@
/**
- * Update the scroll offsets of a box within a browser window
- * (In future, copying where possible, rather than redrawing the entire box)
- *
- * \param bw browser window
- * \param box box to be updated
- * \param scroll_x new horizontal scroll offset
- * \param scroll_y new vertical scroll offset
- */
-
-void browser_window_scroll_box(struct browser_window *bw, struct box *box,
- int scroll_x, int scroll_y)
-{
- box->scroll_x = scroll_x;
- box->scroll_y = scroll_y;
-
- /* fall back to redrawing the whole box */
- browser_redraw_box(bw->current_content, box);
-}
-
-
-/**
* Process a selection from a form select menu.
*
* \param bw browser window with menu
@@ -2643,8 +2547,117 @@
free(url);
}
+/**
+ * Callback for in-page scrolls.
+ */
+void browser_scroll_callback(void *client_data,
+ struct scroll_msg_data *scroll_data)
+{
+ struct browser_window *bw = client_data;
+ struct box *box = bw->scrolling_box;
+ int x0 = 0, x1 = 0;
+ int y0 = 0, y1 = 0;
+ int x = 0, y = 0, box_x, box_y, diff_x = 0, diff_y = 0;
+
+ if (box != NULL) {
+ diff_x = box->padding[LEFT] + box->width + box->padding[RIGHT] -
+ SCROLLBAR_WIDTH;
+ diff_y = box->padding[TOP] + box->height + box->padding[BOTTOM] -
+ SCROLLBAR_WIDTH;
+
+ box_coords(box, &box_x, &box_y);
+ if (scroll_is_horizontal(scroll_data->scroll)) {
+ x = box_x + scroll_get(box->scroll_x);
+ y = box_y + scroll_get(box->scroll_y) + diff_y;
+ } else {
+ x = box_x + scroll_get(box->scroll_x) + diff_x;
+ y = box_y + scroll_get(box->scroll_y);
+ }
+ }
+
+ switch(scroll_data->msg) {
+ case SCROLL_MSG_REDRAW:
+ browser_window_redraw_rect(bw,
+ x + scroll_data->x0,
+ y + scroll_data->y0,
+ scroll_data->x1 - scroll_data->x0,
+ scroll_data->y1 - scroll_data->y0);
+ break;
+ case SCROLL_MSG_MOVED:
+ browser_redraw_box(bw->current_content, box);
+ break;
+ case SCROLL_MSG_CAPTURE_MOUSE:
+ if (scroll_is_horizontal(scroll_data->scroll))
+ bw->scroll_x = scroll_data->scroll;
+ else
+ bw->scroll_y = scroll_data->scroll;
+ /* \todo - some proper numbers please! */
+ if (bw->scroll_y != NULL && bw->scroll_x != NULL) {
+ x0 = -1024;
+ x1 = 1024;
+ y0 = -1024;
+ y1 = 1024;
+ } else if (bw->scroll_y != NULL) {
+ y0 = -1024;
+ y1 = 1024;
+ } else if (bw->scroll_x != NULL) {
+ x0 = -1024;
+ x1 = 1024;
+ }
+ gui_window_box_scroll_start(bw->window, x0, y0, x1, y1);
+ break;
+ case SCROLL_MSG_RELEASE_MOUSE:
+ if (scroll_data->scroll == bw->scroll_x)
+ bw->scroll_x = NULL;
+ else
+ bw->scroll_y = NULL;
+
+ if (bw->scroll_x == NULL && bw->scroll_y == NULL)
+ bw->scrolling_box = NULL;
+
+ browser_window_set_pointer(bw->window,
+ GUI_POINTER_DEFAULT);
+ break;
+ case SCROLL_MSG_2D_DRAG:
+ if (scroll_data->scroll == bw->scroll_x &&
+ box->scroll_y != NULL) {
+ scroll_force_drag_start(box->scroll_y,
+ scroll_data->x0 - diff_x,
+ scroll_data->y0 + diff_y,
+ false);
+ } else if (scroll_data->scroll == bw->scroll_y &&
+ box->scroll_x != NULL) {
+ scroll_force_drag_start(box->scroll_x,
+ scroll_data->x0 + diff_x,
+ scroll_data->y0 - diff_y,
+ false);
+ }
+ break;
+ }
+}
+/**
+ * Callback for the core select menu.
+ */
+void browser_select_menu_callback(void *client_data,
+ int x, int y, int width, int height)
+{
+ struct browser_window *bw = client_data;
+ int menu_x, menu_y;
+ struct box *box;
+
+ box = bw->visible_select_menu->box;
+ box_coords(box, &menu_x, &menu_y);
+
+ menu_x -= box->border[LEFT].width;
+ menu_y += box->height + box->border[BOTTOM].width +
+ box->padding[BOTTOM] +
+ box->padding[TOP];
+ browser_window_redraw_rect(bw, menu_x + x, menu_y + y,
+ width, height);
+}
+
/**
* Check whether box is nearer mouse coordinates than current nearest box
*
@@ -2766,11 +2779,11 @@
while (child) {
if (child->type == BOX_FLOAT_LEFT ||
child->type == BOX_FLOAT_RIGHT) {
- c_bx = fx + child->x - child->scroll_x;
- c_by = fy + child->y - child->scroll_y;
+ c_bx = fx + child->x - scroll_get(child->scroll_x);
+ c_by = fy + child->y - scroll_get(child->scroll_y);
} else {
- c_bx = bx + child->x - child->scroll_x;
- c_by = by + child->y - child->scroll_y;
+ c_bx = bx + child->x - scroll_get(child->scroll_x);
+ c_by = by + child->y - scroll_get(child->scroll_y);
}
if (child->float_children) {
c_fx = c_bx;
@@ -2880,12 +2893,50 @@
bw->drag_start_x = x;
bw->drag_start_y = y;
- gui_window_get_scroll(bw->window, &bw->drag_start_scroll_x, &bw->drag_start_scroll_y);
+ gui_window_get_scroll(bw->window, &bw->drag_start_scroll_x,
+ &bw->drag_start_scroll_y);
gui_window_scroll_start(bw->window);
}
+/**
+ * Start drag scrolling the contents of a box
+ *
+ * \param bw browser window
+ * \param box the box to be scrolled
+ * \param x x ordinate of initial mouse position
+ * \param y y ordinate
+ */
+void browser_window_box_drag_start(struct browser_window *bw,
+ struct box *box, int x, int y)
+{
+ int box_x, box_y, scroll_mouse_x, scroll_mouse_y;
+
+ box_coords(box, &box_x, &box_y);
+
+ if (box->scroll_x != NULL) {
+ scroll_mouse_x = x - box_x ;
+ scroll_mouse_y = y - (box_y + box->padding[TOP] +
+ box->height + box->padding[BOTTOM] -
+ SCROLLBAR_WIDTH);
+ bw->scrolling_box = box;
+ scroll_force_drag_start(box->scroll_x,
+ scroll_mouse_x, scroll_mouse_y, true);
+ }
+ if (box->scroll_y != NULL) {
+ scroll_mouse_x = x - (box_x + box->padding[LEFT] +
+ box->width + box->padding[RIGHT] -
+ SCROLLBAR_WIDTH);
+ scroll_mouse_y = y - box_y;
+
+ bw->scrolling_box = box;
+ scroll_force_drag_start(box->scroll_y,
+ scroll_mouse_x, scroll_mouse_y, true);
+ }
+}
+
+
/**
* Check availability of Back action for a given browser window
*
Index: desktop/browser.h
===================================================================
--- desktop/browser.h (revision 9172)
+++ desktop/browser.h (working copy)
@@ -27,6 +27,7 @@
#include <inttypes.h>
#include <stdbool.h>
#include <time.h>
+
#include "render/html.h"
struct box;
@@ -40,8 +41,8 @@
struct browser_window;
struct url_data;
struct bitmap;
+struct scroll_msg_data;
-
typedef bool (*browser_caret_callback)(struct browser_window *bw,
uint32_t key, void *p);
typedef bool (*browser_paste_callback)(struct browser_window *bw,
@@ -88,11 +89,8 @@
/** Current drag status. */
enum {
DRAGGING_NONE,
- DRAGGING_VSCROLL,
- DRAGGING_HSCROLL,
DRAGGING_SELECTION,
DRAGGING_PAGE_SCROLL,
- DRAGGING_2DSCROLL,
DRAGGING_FRAME
} drag_type;
@@ -104,14 +102,15 @@
/** Scroll offsets at start of current scroll draw. */
int drag_start_scroll_x;
int drag_start_scroll_y;
- /** Well dimensions for current scroll drag. */
- int drag_well_width;
- int drag_well_height;
/** Frame resize directions for current frame resize drag. */
unsigned int drag_resize_left : 1;
unsigned int drag_resize_right : 1;
unsigned int drag_resize_up : 1;
unsigned int drag_resize_down : 1;
+
+ /** Scrolls capturing all mouse events */
+ struct scroll *scroll_x;
+ struct scroll *scroll_y;
/** Referrer for current fetch, or 0. */
char *referer;
@@ -174,6 +173,8 @@
/** Last time a link was followed in this window */
unsigned int last_action;
+
+ struct form_control *visible_select_menu;
};
@@ -257,6 +258,11 @@
void browser_form_submit(struct browser_window *bw, struct browser_window *target,
struct form *form, struct form_control *submit_button);
+void browser_scroll_callback(void *client_data,
+ struct scroll_msg_data *scroll_data);
+void browser_select_menu_callback(void *client_data,
+ int x, int y, int width, int height);
+
void browser_window_redraw_rect(struct browser_window *bw, int x, int y,
int width, int height);
Index: amiga/thumbnail.c
===================================================================
--- amiga/thumbnail.c (revision 9172)
+++ amiga/thumbnail.c (working copy)
@@ -26,6 +26,7 @@
#include "amiga/bitmap.h"
#include "amiga/options.h"
#include "content/urldb.h"
+#include "desktop/plotters.h"
bool thumbnail_create(struct content *content, struct bitmap *bitmap,
const char *url)
@@ -39,6 +40,7 @@
bitmap->nativebmwidth = bitmap->width;
bitmap->nativebmheight = bitmap->height;
ami_clearclipreg(&browserglob.rp);
+ plot = amiplot;
content_redraw(content, 0, 0, content->width, content->width,
0, 0, content->width, content->width, 1.0, 0xFFFFFF);
Conflicted files
Removed files
13 years, 7 months