summaryrefslogtreecommitdiff
path: root/riscos
diff options
context:
space:
mode:
authorRichard Wilson <rjw@netsurf-browser.org>2006-07-11 23:04:13 +0000
committerRichard Wilson <rjw@netsurf-browser.org>2006-07-11 23:04:13 +0000
commit06429e69b5ea8c0343c73d5933015d4dcd160d6b (patch)
treed898f5fcb88f87fde79b982b35a881054057cabd /riscos
parent806fc97126c3d1bb2b8bdc9b071598ebdab8b585 (diff)
downloadnetsurf-06429e69b5ea8c0343c73d5933015d4dcd160d6b.tar.gz
netsurf-06429e69b5ea8c0343c73d5933015d4dcd160d6b.tar.bz2
Fix single line textareas, improve display of multiline ones.
svn path=/trunk/netsurf/; revision=2732
Diffstat (limited to 'riscos')
-rw-r--r--riscos/textarea.c287
-rw-r--r--riscos/textarea.h1
2 files changed, 146 insertions, 142 deletions
diff --git a/riscos/textarea.c b/riscos/textarea.c
index cd3a47257..57c61076f 100644
--- a/riscos/textarea.c
+++ b/riscos/textarea.c
@@ -30,6 +30,9 @@
#include "netsurf/utils/log.h"
#include "netsurf/utils/utf8.h"
+#define MARGIN_LEFT 8
+#define MARGIN_RIGHT 8
+
struct line_info {
unsigned int b_start; /**< Byte offset of line start */
unsigned int b_length; /**< Byte length of line */
@@ -56,7 +59,8 @@ static struct text_area {
char *font_family; /**< Font family of text */
unsigned int font_size; /**< Font size (16ths/pt) */
- int line_height; /**< Height of a line, given font size */
+ int line_height; /**< Total height of a line, given font size */
+ int line_spacing; /**< Height of line spacing, given font size */
unsigned int line_count; /**< Count of lines */
#define LINE_CHUNK_SIZE 256
@@ -148,11 +152,16 @@ uintptr_t textarea_create(wimp_w parent, wimp_i icon, unsigned int flags,
ret->font_size = font_size ? font_size : 192 /* 12pt */;
/** \todo Better line height calculation */
- ret->line_height = (int)(((ret->font_size * 1.25) / 16) * 2.0) + 1;
+ ret->line_height = (int)(((ret->font_size * 1.3) / 16) * 2.0) + 1;
+ ret->line_spacing = ret->line_height / 8;
ret->line_count = 0;
ret->lines = 0;
+ if (flags & TEXTAREA_READONLY)
+ text_area_definition.title_fg = 0xff;
+ else
+ text_area_definition.title_fg = wimp_COLOUR_BLACK;
error = xwimp_create_window(&text_area_definition, &ret->window);
if (error) {
LOG(("xwimp_create_window: 0x%x: %s",
@@ -188,11 +197,18 @@ uintptr_t textarea_create(wimp_w parent, wimp_i icon, unsigned int flags,
state.w = ret->window;
state.visible.x1 = state.visible.x0 + istate.icon.extent.x1 -
- ro_get_vscroll_width(ret->window);
- state.visible.x0 += istate.icon.extent.x0;
+ ro_get_vscroll_width(ret->window) - state.xscroll;
+ state.visible.x0 += istate.icon.extent.x0 + 2 - state.xscroll;
state.visible.y0 = state.visible.y1 + istate.icon.extent.y0 +
- ro_get_hscroll_height(ret->window);
- state.visible.y1 += istate.icon.extent.y1;
+ ro_get_hscroll_height(ret->window) - state.yscroll;
+ state.visible.y1 += istate.icon.extent.y1 - 2 - state.yscroll;
+
+ if (flags & TEXTAREA_READONLY) {
+ state.visible.x0 += 2;
+ state.visible.x1 -= 4;
+ state.visible.y0 += 4;
+ state.visible.y1 -= 2;
+ }
/* set our width/height */
ret->vis_width = state.visible.x1 - state.visible.x0;
@@ -222,12 +238,8 @@ uintptr_t textarea_create(wimp_w parent, wimp_i icon, unsigned int flags,
<< wimp_CHILD_YORIGIN_SHIFT |
wimp_CHILD_LINKS_PARENT_VISIBLE_BOTTOM_OR_LEFT
<< wimp_CHILD_LS_EDGE_SHIFT |
- wimp_CHILD_LINKS_PARENT_VISIBLE_TOP_OR_RIGHT
- << wimp_CHILD_BS_EDGE_SHIFT |
- wimp_CHILD_LINKS_PARENT_VISIBLE_TOP_OR_RIGHT
- << wimp_CHILD_RS_EDGE_SHIFT |
- wimp_CHILD_LINKS_PARENT_VISIBLE_TOP_OR_RIGHT
- << wimp_CHILD_TS_EDGE_SHIFT);
+ wimp_CHILD_LINKS_PARENT_VISIBLE_BOTTOM_OR_LEFT
+ << wimp_CHILD_RS_EDGE_SHIFT);
if (error) {
LOG(("xwimp_open_window_nested: 0x%x: %s",
error->errnum, error->errmess));
@@ -244,6 +256,9 @@ uintptr_t textarea_create(wimp_w parent, wimp_i icon, unsigned int flags,
text_areas->prev = ret;
text_areas = ret;
+ /* make available for immediate use */
+ textarea_reflow(ret, 0);
+
/* and register our event handlers */
ro_gui_wimp_event_register_mouse_click(ret->window,
textarea_mouse_click);
@@ -498,6 +513,11 @@ void textarea_set_caret(uintptr_t self, unsigned int caret)
struct text_area *ta;
size_t c_len, b_off;
unsigned int i;
+ size_t index;
+ int x;
+ os_coord os_line_height;
+ rufl_code code;
+ os_error *error;
ta = (struct text_area *)self;
if (!ta || ta->magic != MAGIC) {
@@ -521,12 +541,115 @@ void textarea_set_caret(uintptr_t self, unsigned int caret)
ta->caret_pos.line = i;
- /* Finally, calculate the char. offset of the caret in this line */
+ /* Now calculate the char. offset of the caret in this line */
for (c_len = 0, ta->caret_pos.char_off = 0;
c_len < b_off - ta->lines[i].b_start;
c_len = utf8_next(ta->text + ta->lines[i].b_start,
ta->lines[i].b_length, c_len))
ta->caret_pos.char_off++;
+
+
+ /* Finally, redraw the WIMP caret */
+ index = textarea_get_caret(self);
+ os_line_height.x = 0;
+ os_line_height.y = (int)((float)(ta->line_height - ta->line_spacing) * 0.62) + 1;
+ ro_convert_pixels_to_os_units(&os_line_height, (os_mode)-1);
+
+ for (b_off = 0; index-- > 0; b_off = utf8_next(ta->text, ta->text_len, b_off))
+ ; /* do nothing */
+
+ code = rufl_width(ta->font_family, rufl_WEIGHT_400, ta->font_size,
+ ta->text + ta->lines[ta->caret_pos.line].b_start,
+ b_off - ta->lines[ta->caret_pos.line].b_start, &x);
+ if (code != rufl_OK) {
+ if (code == rufl_FONT_MANAGER_ERROR)
+ LOG(("rufl_width: 0x%x: %s",
+ rufl_fm_error->errnum,
+ rufl_fm_error->errmess));
+ else
+ LOG(("rufl_width: 0x%x", code));
+ return;
+ }
+
+ error = xwimp_set_caret_position(ta->window, -1, x + MARGIN_LEFT,
+ -((ta->caret_pos.line + 1) * ta->line_height) -
+ ta->line_height / 4 + ta->line_spacing,
+ os_line_height.y, -1);
+ if (error) {
+ LOG(("xwimp_set_caret_position: 0x%x: %s",
+ error->errnum, error->errmess));
+ return;
+ }
+}
+
+/**
+ * Set the caret's position
+ *
+ * \param self Text area
+ * \param x X position of caret on the screen
+ * \param y Y position of caret on the screen
+ */
+void textarea_set_caret_xy(uintptr_t self, int x, int y)
+{
+ struct text_area *ta;
+ wimp_window_state state;
+ size_t b_off, c_off, temp;
+ int line;
+ os_coord os_line_height;
+ rufl_code code;
+ os_error *error;
+
+ ta = (struct text_area *)self;
+ if (!ta || ta->magic != MAGIC) {
+ LOG(("magic doesn't match"));
+ return;
+ }
+
+ if (ta->flags & TEXTAREA_READONLY)
+ return;
+
+ os_line_height.x = 0;
+ os_line_height.y = (int)((float)(ta->line_height - ta->line_spacing) * 0.62) + 1;
+ ro_convert_pixels_to_os_units(&os_line_height, (os_mode)-1);
+
+ state.w = ta->window;
+ error = xwimp_get_window_state(&state);
+ if (error) {
+ LOG(("xwimp_get_window_state: 0x%x: %s",
+ error->errnum, error->errmess));
+ return;
+ }
+
+ x = x - (state.visible.x0 - state.xscroll) - MARGIN_LEFT;
+ y = (state.visible.y1 - state.yscroll) - y;
+
+ line = y / ta->line_height;
+
+ if (line < 0)
+ line = 0;
+ if (ta->line_count - 1 < (unsigned)line)
+ line = ta->line_count - 1;
+
+ code = rufl_x_to_offset(ta->font_family, rufl_WEIGHT_400,
+ ta->font_size,
+ ta->text + ta->lines[line].b_start,
+ ta->lines[line].b_length,
+ x, &b_off, &x);
+ if (code != rufl_OK) {
+ if (code == rufl_FONT_MANAGER_ERROR)
+ LOG(("rufl_x_to_offset: 0x%x: %s",
+ rufl_fm_error->errnum,
+ rufl_fm_error->errmess));
+ else
+ LOG(("rufl_x_to_offset: 0x%x", code));
+ return;
+ }
+
+ for (temp = 0, c_off = 0; temp < b_off + ta->lines[line].b_start;
+ temp = utf8_next(ta->text, ta->text_len, temp))
+ c_off++;
+
+ textarea_set_caret((uintptr_t)ta, c_off);
}
/**
@@ -608,7 +731,7 @@ void textarea_reflow(struct text_area *ta, unsigned int line)
if (!(ta->flags & TEXTAREA_MULTILINE)) {
/* Single line */
ta->lines[line_count].b_start = 0;
- ta->lines[line_count++].b_length = ta->text_len;
+ ta->lines[line_count++].b_length = ta->text_len - 1;
ta->line_count = line_count;
@@ -618,7 +741,8 @@ void textarea_reflow(struct text_area *ta, unsigned int line)
for (len = ta->text_len - 1, text = ta->text; len > 0;
len -= b_off, text += b_off) {
code = rufl_split(ta->font_family, rufl_WEIGHT_400,
- ta->font_size, text, len, ta->vis_width,
+ ta->font_size, text, len,
+ ta->vis_width - MARGIN_LEFT - MARGIN_RIGHT,
&b_off, &x);
if (code != rufl_OK) {
if (code == rufl_FONT_MANAGER_ERROR)
@@ -691,7 +815,7 @@ void textarea_reflow(struct text_area *ta, unsigned int line)
extent.x0 = 0;
extent.y1 = 0;
extent.x1 = ta->vis_width;
- extent.y0 = -ta->line_height * (line_count + 1);
+ extent.y0 = -ta->line_height * line_count - ta->line_spacing;
if (extent.y0 > (int)-ta->vis_height)
/* haven't filled window yet */
@@ -789,75 +913,12 @@ void textarea_reflow(struct text_area *ta, unsigned int line)
bool textarea_mouse_click(wimp_pointer *pointer)
{
struct text_area *ta;
- wimp_window_state state;
- size_t b_off, c_off, temp;
- int x, y, line;
- os_coord os_line_height;
- rufl_code code;
- os_error *error;
-
+
ta = textarea_from_w(pointer->w);
if (!ta)
return false;
- /** \todo modify for selection model */
- if (ta->flags & TEXTAREA_READONLY)
- return true;
-
- os_line_height.x = 0;
- os_line_height.y = (int)((float)ta->line_height * 0.6) + 1;
- ro_convert_pixels_to_os_units(&os_line_height, (os_mode)-1);
-
- state.w = pointer->w;
- error = xwimp_get_window_state(&state);
- if (error) {
- LOG(("xwimp_get_window_state: 0x%x: %s",
- error->errnum, error->errmess));
- return false;
- }
-
- x = pointer->pos.x - (state.visible.x0 - state.xscroll);
- y = (state.visible.y1 - state.yscroll) - pointer->pos.y;
-
- line = y / ta->line_height;
-
- if (line < 0)
- line = 0;
- if (ta->line_count - 1 < (unsigned)line)
- line = ta->line_count - 1;
-
- code = rufl_x_to_offset(ta->font_family, rufl_WEIGHT_400,
- ta->font_size,
- ta->text + ta->lines[line].b_start,
- ta->lines[line].b_length,
- x, &b_off, &x);
- if (code != rufl_OK) {
- if (code == rufl_FONT_MANAGER_ERROR)
- LOG(("rufl_x_to_offset: 0x%x: %s",
- rufl_fm_error->errnum,
- rufl_fm_error->errmess));
- else
- LOG(("rufl_x_to_offset: 0x%x", code));
- return false;
- }
-
- for (temp = 0, c_off = 0; temp < b_off + ta->lines[line].b_start;
- temp = utf8_next(ta->text, ta->text_len, temp))
- c_off++;
-
- textarea_set_caret((uintptr_t)ta, c_off);
-
- error = xwimp_set_caret_position(state.w, -1,
- x,
- -((ta->caret_pos.line + 1) * ta->line_height) -
- ta->line_height / 4,
- os_line_height.y, -1);
- if (error) {
- LOG(("xwimp_set_caret_position: 0x%x: %s",
- error->errnum, error->errmess));
- return false;
- }
-
+ textarea_set_caret_xy((uintptr_t)ta, pointer->pos.x, pointer->pos.y);
return true;
}
@@ -1020,74 +1081,16 @@ bool textarea_key_press(wimp_key *key)
{
wimp_draw update;
- wimp_window_state state;
- size_t b_off, index;
- int x;
- os_coord os_line_height;
- rufl_code code;
unsigned int c_pos =
textarea_get_caret((uintptr_t)ta);
textarea_insert_text((uintptr_t)ta, c_pos, utf8);
textarea_set_caret((uintptr_t)ta, ++c_pos);
- index = c_pos;
-
- os_line_height.x = 0;
- os_line_height.y =
- (int)((float)ta->line_height * 0.6) + 1;
- ro_convert_pixels_to_os_units(&os_line_height,
- (os_mode)-1);
-
- for (b_off = 0; index-- > 0;
- b_off = utf8_next(ta->text,
- ta->text_len, b_off))
- ; /* do nothing */
-
- code = rufl_width(ta->font_family, rufl_WEIGHT_400,
- ta->font_size,
- ta->text + ta->lines[ta->caret_pos.
- line].b_start,
- b_off - ta->lines[ta->caret_pos.
- line].b_start,
- &x);
- if (code != rufl_OK) {
- if (code == rufl_FONT_MANAGER_ERROR)
- LOG(("rufl_width: 0x%x: %s",
- rufl_fm_error->errnum,
- rufl_fm_error->errmess));
- else
- LOG(("rufl_width: 0x%x", code));
-
- return true;
- }
-
- state.w = ta->window;
- error = xwimp_get_window_state(&state);
- if (error) {
- LOG(("xwimp_get_window_state: 0x%x: %s",
- error->errnum, error->errmess));
- return true;
- }
-
- error = xwimp_set_caret_position(ta->window, -1,
- x,
- -((ta->caret_pos.line + 1) *
- ta->line_height) -
- ta->line_height / 4,
- os_line_height.y, -1);
- if (error) {
- LOG(("xwimp_set_caret_position: 0x%x: %s",
- error->errnum, error->errmess));
- return true;
- }
-
update.w = ta->window;
update.box.x0 = 0;
update.box.y1 = 0;
update.box.x1 = ta->vis_width;
- update.box.y0 =
- -ta->line_height * (ta->line_count + 1);
-
+ update.box.y0 = -ta->line_height * (ta->line_count + 1);
textarea_redraw_internal(&update, true);
}
}
@@ -1196,10 +1199,10 @@ void textarea_redraw_internal(wimp_draw *redraw, bool update)
ta->font_size,
ta->text + ta->lines[line].b_start,
ta->lines[line].b_length,
- redraw->box.x0 - redraw->xscroll,
+ redraw->box.x0 - redraw->xscroll + MARGIN_LEFT,
redraw->box.y1 - redraw->yscroll -
((line + 1) *
- ta->line_height),
+ ta->line_height - ta->line_spacing),
rufl_BLEND_FONT);
if (code != rufl_OK) {
if (code == rufl_FONT_MANAGER_ERROR)
diff --git a/riscos/textarea.h b/riscos/textarea.h
index 461ee2665..a0d592d91 100644
--- a/riscos/textarea.h
+++ b/riscos/textarea.h
@@ -26,6 +26,7 @@ void textarea_insert_text(uintptr_t self, unsigned int index,
void textarea_replace_text(uintptr_t self, unsigned int start,
unsigned int end, const char *text);
void textarea_set_caret(uintptr_t self, unsigned int caret);
+void textarea_set_caret_xy(uintptr_t self, int x, int y);
unsigned int textarea_get_caret(uintptr_t self);