I'm actually trying to simplify the frontend code, changes:

- Optimized browser window caret, uses back-buffer now. ( So no content redraw is scheduled by the frontend just for a caret move ) 
- Fixed a double redraw issue when the browser reformat is pending and the AES also sends an redraw request because of the resize. 
- Started to use netsurfs textarea instead of a custom implementation ( to reduce code size ). 

svn path=/trunk/netsurf/; revision=13191
This commit is contained in:
Ole Loots 2011-11-28 23:23:28 +00:00
parent a7ba1b7ccd
commit 999410adc8
18 changed files with 779 additions and 839 deletions

View File

@ -38,6 +38,7 @@ S_ATARI := gui.c findfile.c filetype.c misc.c bitmap.c schedule.c \
search.c font.c \
plot.c plot/plotter.c plot/plotter_vdi.c plot/eddi.s \
plot/font_vdi.c plot/font_freetype.c plot/font_internal.c \
redrawslots.c encoding.c \
browser_win.c toolbar.c statusbar.c browser.c \
global_evnt.c osspec.c dragdrop.c system_colour.c \
ctxmenu.c

View File

@ -50,10 +50,11 @@
#include "atari/misc.h"
#include "atari/global_evnt.h"
#include "atari/res/netsurf.rsh"
#include "atari/redrawslots.h"
#include "atari/browser.h"
#include "atari/plot/plotter.h"
#include "atari/plot.h"
#include "atari/font.h"
#include "atari/encoding.h"
#include "atari/ctxmenu.h"
#include "cflib.h"
@ -65,10 +66,17 @@ extern struct gui_window *input_window;
extern short last_drag_x;
extern short last_drag_y;
static void __CDECL browser_evnt_wdestroy( WINDOW * c, short buff[8], void * data);
COMPONENT *comp_widget_create( APPvar *app, WINDOW *win, int size, int flex );
static void browser_process_scroll( struct gui_window * gw, LGRECT bwrect );
static void browser_redraw_content( struct gui_window * gw, int xoff, int yoff,
struct rect * area );
static void __CDECL browser_evnt_resize( COMPONENT * c, long buff[8],
void * data);
static void __CDECL browser_evnt_destroy( COMPONENT * c, long buff[8],
void * data);
static void __CDECL browser_evnt_redraw( COMPONENT * c, long buff[8],
void * data);
static void __CDECL browser_evnt_mbutton( COMPONENT * c, long buff[8],
void * data);
/*
@ -98,7 +106,7 @@ struct s_browser * browser_create
bw->scale = clone->scale;
else
bw->scale = 1;
bnew->redraw.areas_used = 0;
redraw_slots_init( &bnew->redraw, MAX_REDRW_SLOTS );
bnew->comp = (COMPONENT*)mt_CompCreate(&app, CLT_HORIZONTAL, 100, 1);
if( bnew->comp == NULL ) {
free(bnew);
@ -115,6 +123,9 @@ struct s_browser * browser_create
mt_CompEvntDataAttach( &app, bnew->comp, WM_DESTROY,
browser_evnt_destroy, (void*)bnew
);
mt_CompEvntDataAttach( &app, bnew->comp, WM_SIZED,
browser_evnt_resize, (void*)gw
);
/* Set the gui_window owner. */
/* it is an link to the netsurf window system */
@ -124,6 +135,7 @@ struct s_browser * browser_create
bnew->scroll.requested.x = 0;
bnew->scroll.current.x = 0;
bnew->scroll.current.y = 0;
bnew->reformat_pending = false;
}
return( bnew );
@ -196,6 +208,13 @@ void browser_set_content_size(struct gui_window * gw, int w, int h)
}
}
static void __CDECL browser_evnt_resize( COMPONENT * c, long buff[8], void * data)
{
/* Just a dummy to prevent second redraw (already handled within browser_win)*/
printf("browser evnt resize");
return;
}
static void __CDECL browser_evnt_destroy( COMPONENT * c, long buff[8], void * data)
{
struct s_browser * b = (struct s_browser*)data;
@ -468,6 +487,9 @@ static void browser_process_scroll( struct gui_window * gw, LGRECT bwrect )
}
b->scroll.requested.y = 0;
b->scroll.requested.x = 0;
if( b->caret.requested.g_w > 0 ){
b->caret.redraw = true;
}
gw->root->handle->xpos = b->scroll.current.x;
gw->root->handle->ypos = b->scroll.current.y;
@ -477,7 +499,7 @@ static void browser_process_scroll( struct gui_window * gw, LGRECT bwrect )
/*
Report keypress to browser component.
The browser component doesn't list for keyinput by itself.
The browser component doesn't listen for keyinput by itself.
parameter:
- gui_window ( compocnent owner ).
- unsigned short nkc ( CFLIB normalised key code )
@ -487,154 +509,58 @@ bool browser_input( struct gui_window * gw, unsigned short nkc )
LGRECT work;
bool r = false;
unsigned char ascii = (nkc & 0xFF);
nkc = (nkc & (NKF_CTRL|NKF_SHIFT|0xFF));
browser_get_rect(gw, BR_CONTENT, &work);
long ucs4;
long ik = nkc_to_input_key( nkc, &ucs4 );
if( (nkc & NKF_CTRL) != 0 ) {
switch ( ascii ) {
case 'A':
r = browser_window_key_press(gw->browser->bw, KEY_SELECT_ALL);
break;
// pass event to specific control?
case 'C':
r = browser_window_key_press(gw->browser->bw, KEY_COPY_SELECTION);
break;
case 'X':
r = browser_window_key_press(gw->browser->bw, KEY_CUT_SELECTION);
break;
case 'V':
r = browser_window_key_press(gw->browser->bw, KEY_PASTE);
break;
default:
break;
}
}
if( (nkc & NKF_SHIFT) != 0 ) {
switch( ascii ) {
case NK_TAB:
r = browser_window_key_press(gw->browser->bw, KEY_SHIFT_TAB);
break;
case NK_LEFT:
if( browser_window_key_press(gw->browser->bw, KEY_LINE_START) == false) {
browser_scroll( gw, WA_LFPAGE, work.g_w, false );
r = true;
}
break;
case NK_RIGHT:
if( browser_window_key_press(gw->browser->bw, KEY_LINE_END) == false) {
browser_scroll( gw, WA_RTPAGE, work.g_w, false );
r = true;
}
break;
case NK_UP:
if ( browser_window_key_press(gw->browser->bw, KEY_PAGE_UP) ==false ){
browser_scroll( gw, WA_UPPAGE, work.g_h, false );
r = true;
}
break;
case NK_DOWN:
if (browser_window_key_press(gw->browser->bw, KEY_PAGE_DOWN) == false) {
browser_scroll( gw, WA_DNPAGE, work.g_h, false );
r = true;
}
break;
default:
break;
}
}
if( (nkc & (NKF_SHIFT|NKF_CTRL) ) == 0 ) {
switch( ascii ) {
case NK_BS:
r = browser_window_key_press(gw->browser->bw, KEY_DELETE_LEFT);
break;
case NK_DEL:
r = browser_window_key_press(gw->browser->bw, KEY_DELETE_RIGHT);
break;
case NK_TAB:
r = browser_window_key_press(gw->browser->bw, KEY_TAB);
break;
case NK_ENTER:
r = browser_window_key_press(gw->browser->bw, KEY_NL);
break;
case NK_RET:
r = browser_window_key_press(gw->browser->bw, KEY_CR);
break;
case NK_ESC:
r = browser_window_key_press(gw->browser->bw, KEY_ESCAPE);
break;
case NK_CLRHOME:
r = browser_window_key_press(gw->browser->bw, KEY_TEXT_START);
break;
case NK_RIGHT:
if (browser_window_key_press(gw->browser->bw, KEY_RIGHT) == false){
browser_scroll( gw, WA_RTLINE, 16, false );
r = true;
}
break;
case NK_LEFT:
if (browser_window_key_press(gw->browser->bw, KEY_LEFT) == false) {
browser_scroll( gw, WA_LFLINE, 16, false );
r = true;
}
break;
case NK_UP:
if (browser_window_key_press(gw->browser->bw, KEY_UP) == false) {
browser_scroll( gw, WA_UPLINE, 16, false);
r = true;
}
break;
case NK_DOWN:
if (browser_window_key_press(gw->browser->bw, KEY_DOWN) == false) {
browser_scroll( gw, WA_DNLINE, 16, false);
r = true;
}
break;
case NK_M_PGUP:
if ( browser_window_key_press(gw->browser->bw, KEY_PAGE_UP) ==false ) {
browser_scroll( gw, WA_UPPAGE, work.g_h, false );
r = true;
}
break;
case NK_M_PGDOWN:
if (browser_window_key_press(gw->browser->bw, KEY_PAGE_DOWN) == false) {
browser_scroll( gw, WA_DNPAGE, work.g_h, false );
r = true;
}
break;
default:
break;
}
}
if( r == false && ( (nkc & NKF_CTRL)==0) ) {
if( ik == 0 ){
if (ascii >= 9 ) {
int ucs4 = atari_to_ucs4(ascii);
r = browser_window_key_press(gw->browser->bw, ucs4 );
}
} else {
r = browser_window_key_press(gw->browser->bw, ik );
if( r == false ){
browser_get_rect(gw, BR_CONTENT, &work);
switch( ik ){
case KEY_LINE_START:
browser_scroll( gw, WA_LFPAGE, work.g_w, false );
break;
case KEY_LINE_END:
browser_scroll( gw, WA_RTPAGE, work.g_w, false );
break;
case KEY_PAGE_UP:
browser_scroll( gw, WA_UPPAGE, work.g_h, false );
break;
case KEY_PAGE_DOWN:
browser_scroll( gw, WA_DNPAGE, work.g_h, false );
break;
case KEY_RIGHT:
browser_scroll( gw, WA_RTLINE, 16, false );
break;
case KEY_LEFT:
browser_scroll( gw, WA_LFLINE, 16, false );
break;
case KEY_UP:
browser_scroll( gw, WA_UPLINE, 16, false);
break;
case KEY_DOWN:
browser_scroll( gw, WA_DNLINE, 16, false);
break;
default:
break;
}
}
}
return( r );
}
@ -647,6 +573,10 @@ bool browser_redraw_required( struct gui_window * gw)
if( b->bw->current_content == NULL )
return ( false );
/* disable redraws when the browser awaits WM_REDRAW caused by resize */
if( b->reformat_pending )
return( false );
ret = ( ((b->redraw.areas_used > 0) )
|| b->scroll.required
|| b->caret.redraw);
@ -670,22 +600,6 @@ void browser_schedule_redraw_rect(struct gui_window * gw, short x, short y, shor
browser_schedule_redraw( gw, x, y, x+w, y+h );
}
static inline bool rect_intersect( struct rect * box1, struct rect * box2 )
{
if (box2->x1 < box1->x0)
return false;
if (box2->y1 < box1->y0)
return false;
if (box2->x0 > box1->x1)
return false;
if (box2->y0 > box1->y1)
return false;
return true;
}
/*
schedule a redraw of content, coords are relative to the framebuffer
@ -707,50 +621,13 @@ void browser_schedule_redraw(struct gui_window * gw, short x0, short y0, short x
if( y0 > work.g_h )
return;
area.x0 = x0;
area.y0 = y0;
area.x1 = x1;
area.y1 = y1;
redraw_slot_schedule( &b->redraw, x0, y0, x1, y1 );
for( i=0; i<b->redraw.areas_used; i++) {
if( b->redraw.areas[i].x0 <= x0
&& b->redraw.areas[i].x1 >= x1
&& b->redraw.areas[i].y0 <= y0
&& b->redraw.areas[i].y1 >= y1 ){
/* the area is already queued for redraw */
return;
} else {
if( rect_intersect(&b->redraw.areas[i], &area ) ){
b->redraw.areas[i].x0 = MIN(b->redraw.areas[i].x0, x0);
b->redraw.areas[i].y0 = MIN(b->redraw.areas[i].y0, y0);
b->redraw.areas[i].x1 = MAX(b->redraw.areas[i].x1, x1);
b->redraw.areas[i].y1 = MAX(b->redraw.areas[i].y1, y1);
return;
}
}
}
if( b->redraw.areas_used < MAX_REDRW_SLOTS ) {
b->redraw.areas[b->redraw.areas_used].x0 = x0;
b->redraw.areas[b->redraw.areas_used].x1 = x1;
b->redraw.areas[b->redraw.areas_used].y0 = y0;
b->redraw.areas[b->redraw.areas_used].y1 = y1;
b->redraw.areas_used++;
} else {
/*
we are out of available slots, merge box with last slot
this is dumb... but also a very rare case.
*/
b->redraw.areas[MAX_REDRW_SLOTS-1].x0 = MIN(b->redraw.areas[i].x0, x0);
b->redraw.areas[MAX_REDRW_SLOTS-1].y0 = MIN(b->redraw.areas[i].y0, y0);
b->redraw.areas[MAX_REDRW_SLOTS-1].x1 = MAX(b->redraw.areas[i].x1, x1);
b->redraw.areas[MAX_REDRW_SLOTS-1].y1 = MAX(b->redraw.areas[i].y1, y1);
}
done:
return;
}
static void browser_redraw_content( struct gui_window * gw, int xoff, int yoff )
static void browser_redraw_content( struct gui_window * gw, int xoff, int yoff,
struct rect * area )
{
LGRECT work;
CMP_BROWSER b = gw->browser;
@ -760,38 +637,98 @@ static void browser_redraw_content( struct gui_window * gw, int xoff, int yoff )
.plot = &atari_plotters
};
LOG(("%s : %d,%d - %d,%d\n", b->bw->name, b->redraw.area.x0,
b->redraw.area.y0, b->redraw.area.x1, b->redraw.area.y1
LOG(("%s : %d,%d - %d,%d\n", b->bw->name, area->x0,
area->y0, area->x1, area->y1
));
browser_window_redraw( b->bw, -b->scroll.current.x,
-b->scroll.current.y, &b->redraw.area, &ctx );
-b->scroll.current.y, area, &ctx );
}
void browser_redraw_caret( struct gui_window * gw, GRECT * area )
/*
area: the browser canvas
*/
void browser_restore_caret_background( struct gui_window * gw, LGRECT * area)
{
GRECT caret;
CMP_BROWSER b = gw->browser;
LGRECT rect;
if( area == NULL ){
browser_get_rect( gw, BR_CONTENT, &rect );
area = &rect;
}
/* This call restores the background and releases the memory: */
// TODO: only release memory/clear flag when the caret is not clipped.
// TODO: apply clipping.
w_put_bkgr( &app,
area->g_x-b->scroll.current.x+b->caret.current.g_x,
area->g_y-b->scroll.current.y+b->caret.current.g_y,
gw->browser->caret.current.g_w,
gw->browser->caret.current.g_h,
&gw->browser->caret.background
);
gw->browser->caret.background.fd_addr = NULL;
}
/*
area: the browser canvas
*/
void browser_redraw_caret( struct gui_window * gw, LGRECT * area )
{
// TODO: only redraw caret when window is topped.
if( gw->browser->caret.redraw && gw->browser->caret.requested.g_w > 0 ){
LGRECT caret;
struct s_browser * b = gw->browser;
if( b->caret.redraw == true ){
struct rect old_clip;
struct rect clip;
if( b->caret.current.g_w > 0 && b->caret.background.fd_addr != NULL ){
browser_restore_caret_background( gw, area );
}
caret = b->caret.requested;
caret.g_x -= gw->browser->scroll.current.x;
caret.g_y -= gw->browser->scroll.current.y;
clip.x0 = caret.g_x - 1;
clip.y0 = caret.g_y - 1;
clip.x1 = caret.g_x + caret.g_w + 1;
clip.y1 = caret.g_y + caret.g_h + 1;
caret.g_x -= b->scroll.current.x - area->g_x;
caret.g_y -= b->scroll.current.y - area->g_y;
if( !rc_lintersect( area, &caret ) ) {
return;
}
MFDB screen;
short pxy[8];
/* save background: */
//assert( b->caret.background.fd_addr == NULL );
init_mfdb( app.nplanes, caret.g_w, caret.g_h, 0,
&b->caret.background );
init_mfdb( 0, caret.g_w, caret.g_h, 0, &screen );
pxy[0] = caret.g_x;
pxy[1] = caret.g_y;
pxy[2] = caret.g_x + caret.g_w - 1;
pxy[3] = caret.g_y + caret.g_h - 1;
pxy[4] = 0;
pxy[5] = 0;
pxy[6] = caret.g_w - 1;
pxy[7] = caret.g_h - 1;
/* hide the mouse */
v_hide_c ( app.graf.handle);
/* copy screen image */
vro_cpyfm ( app.graf.handle, S_ONLY, pxy, &screen, &b->caret.background);
/* restore the mouse */
v_show_c ( app.graf.handle, 1);
/* draw caret: */
caret.g_x -= area->g_x;
caret.g_y -= area->g_y;
clip.x0 = caret.g_x;
clip.y0 = caret.g_y;
clip.x1 = caret.g_x + caret.g_w-1;
clip.y1 = caret.g_y + caret.g_h-1;
/* store old clip before adjusting it: */
plot_get_clip( &old_clip );
/* clip to cursor: */
plot_clip( &clip );
plot_rectangle( caret.g_x, caret.g_y,
caret.g_x+caret.g_w, caret.g_y+caret.g_h,
plot_line( caret.g_x, caret.g_y, caret.g_x, caret.g_y + caret.g_h,
plot_style_caret );
/* restore old clip area: */
plot_clip( &old_clip );
@ -808,6 +745,8 @@ void browser_redraw( struct gui_window * gw )
struct s_browser * b = gw->browser;
short todo[4];
struct rect clip;
/* used for clipping of content redraw: */
struct rect redraw_area;
if( b->attached == false || b->bw->current_content == NULL ) {
return;
@ -864,11 +803,11 @@ void browser_redraw( struct gui_window * gw )
area.g_w = b->redraw.areas[i].x1 - b->redraw.areas[i].x0;
area.g_h = b->redraw.areas[i].y1 - b->redraw.areas[i].y0;
if (rc_intersect((GRECT *)&fbwork,(GRECT *)&area)) {
b->redraw.area.x0 = area.g_x;
b->redraw.area.y0 = area.g_y;
b->redraw.area.x1 = area.g_x + area.g_w;
b->redraw.area.y1 = area.g_y + area.g_h;
browser_redraw_content( gw, 0, 0 );
redraw_area.x0 = area.g_x;
redraw_area.y0 = area.g_y;
redraw_area.x1 = area.g_x + area.g_w;
redraw_area.y1 = area.g_y + area.g_h;
browser_redraw_content( gw, 0, 0, &redraw_area );
} else {
/*
the area should be kept scheduled for later redraw, but because this
@ -890,7 +829,7 @@ void browser_redraw( struct gui_window * gw )
b->redraw.areas_used = 0;
}
if( b->caret.redraw == true && b->bw->current_content != NULL ) {
GRECT area;
LGRECT area;
todo[0] = bwrect.g_x;
todo[1] = bwrect.g_y;
todo[2] = todo[0] + bwrect.g_w;
@ -913,15 +852,8 @@ static void __CDECL browser_evnt_redraw( COMPONENT * c, long buff[8], void * dat
short pxy[8];
struct gui_window * gw = (struct gui_window *) data;
CMP_BROWSER b = gw->browser;
LGRECT work, lclip, rwork;
LGRECT work, lclip;
// TODO: maybe implement something like validate_gw()
// to fetch spurious redraw events? the function should
// traverse all gui_windows and see if gw exists in the list
int xoff,yoff,width,heigth;
short cw, ch, cellw, cellh;
/* use that instead of browser_find_root() ? */
browser_get_rect( gw, BR_CONTENT, &work );
lclip = work;
if ( !rc_lintersect( (LGRECT*)&buff[4], &lclip ) ) return;
@ -954,12 +886,23 @@ static void __CDECL browser_evnt_redraw( COMPONENT * c, long buff[8], void * dat
lclip.g_y = 0;
}
if( lclip.g_h > 0 && lclip.g_w > 0 ) {
if( gw->browser->reformat_pending == true ){
LGRECT newsize;
gw->browser->reformat_pending = false;
browser_get_rect(gw, BR_CONTENT, &newsize);
/* this call will also schedule an redraw for the complete */
/* area. */
/* Resize must be handled here, because otherwise */
/* a redraw is scheduled twice (1. by the frontend, 2. by AES) */
browser_window_reformat(b->bw, false, newsize.g_w, newsize.g_h );
} else {
browser_schedule_redraw( gw, lclip.g_x, lclip.g_y,
lclip.g_x + lclip.g_w, lclip.g_y + lclip.g_h
);
}
}
return;
}

View File

@ -19,6 +19,8 @@
#ifndef NS_ATARI_BROWSER_H
#define NS_ATARI_BROWSER_H
#include "atari/redrawslots.h"
/*
Each browser_window in the Atari Port is represented by an struct s_browser,
which consist mainly of an WinDom COMPONENT.
@ -30,13 +32,6 @@
*/
#define BROWSER_SCROLL_SVAL 64
/*
MAX_REDRW_SLOTS
This is the number of redraw requests that an browser window can queue.
If a redraw is scheduled and all slots are used, the rectangle will
be merged to one of the existing slots.
*/
#define MAX_REDRW_SLOTS 32
enum browser_rect
{
@ -65,21 +60,10 @@ struct s_scroll_info
*/
struct s_caret
{
GRECT requested;
GRECT current;
LGRECT requested;
LGRECT current;
bool redraw;
};
/*
This struct holds scheduled redraw requests.
*/
struct rect;
struct s_browser_redrw_info
{
struct rect areas[MAX_REDRW_SLOTS];
short areas_used;
/* used for clipping of content redraw: */
struct rect area;
MFDB background;
};
/*
@ -99,9 +83,10 @@ struct s_browser
COMPONENT * comp;
struct browser_window * bw;
struct s_scroll_info scroll;
struct s_browser_redrw_info redraw;
struct s_redrw_slots redraw;
struct s_caret caret;
bool attached;
bool reformat_pending;
};
struct s_browser * browser_create( struct gui_window * gw, struct browser_window * clone, struct browser_window *bw, int lt, int w, int flex );
@ -113,8 +98,10 @@ void browser_set_content_size(struct gui_window * gw, int w, int h);
void browser_scroll( struct gui_window * gw, short MODE, int value, bool abs );
struct gui_window * browser_find_root( struct gui_window * gw );
bool browser_redraw_required( struct gui_window * gw);
static void browser_process_scroll( struct gui_window * gw, LGRECT bwrect );
void browser_redraw_caret( struct gui_window * gw, LGRECT * area);
void browser_restore_caret_background(struct gui_window * gw, LGRECT * area);
/* update loc / size of the browser widgets: */
void browser_update_rects(struct gui_window * gw );
/*
This queues an redraw to one of the slots.
The following strategy is used:
@ -126,17 +113,7 @@ static void browser_process_scroll( struct gui_window * gw, LGRECT bwrect );
4. if no slot is available, it will simply merge the new rectangle with
the last available slot.
*/
void browser_redraw_caret( struct gui_window * gw, GRECT * area );
static void browser_redraw_content( struct gui_window * gw, int xoff, int yoff );
/* update loc / size of the browser widgets: */
void browser_update_rects(struct gui_window * gw );
void browser_schedule_redraw_rect(struct gui_window * gw, short x, short y, short w, short h);
void browser_schedule_redraw(struct gui_window * gw, short x, short y, short w, short h );
static void __CDECL browser_evnt_resize( COMPONENT * c, long buff[8], void * data);
static void __CDECL browser_evnt_destroy( COMPONENT * c, long buff[8], void * data);
static void __CDECL browser_evnt_redraw( COMPONENT * c, long buff[8], void * data);
static void __CDECL browser_evnt_mbutton( COMPONENT * c, long buff[8], void * data);
#endif

View File

@ -69,6 +69,26 @@ extern short last_drag_y;
void __CDECL std_szd( WINDOW * win, short buff[8], void * );
void __CDECL std_mvd( WINDOW * win, short buff[8], void * );
/* -------------------------------------------------------------------------- */
/* Static module methods follow here: */
/* -------------------------------------------------------------------------- */
static void evnt_toolbar_click(WINDOW * win, short buf[8], void * data);
static void __CDECL evnt_window_redraw( WINDOW *win, short buff[8], void *data );
static void __CDECL evnt_window_icondraw( WINDOW *win, short buff[8], void *data );
static void __CDECL evnt_window_newtop( WINDOW *win, short buff[8], void *data );
void __CDECL evnt_window_resize( WINDOW *win, short buff[8], void * data );
static void __CDECL evnt_window_move( WINDOW *win, short buff[8], void * data );
static void __CDECL evnt_window_rt_resize( WINDOW *win, short buff[8], void * date );
static void __CDECL evnt_window_close( WINDOW *win, short buff[8], void *data );
static void __CDECL evnt_window_dd( WINDOW *win, short wbuff[8], void * data ) ;
static void __CDECL evnt_window_destroy( WINDOW *win, short buff[8], void *data );
static void __CDECL evnt_window_keybd(WINDOW *win, short buff[8], void *data );
static void __CDECL evnt_window_mbutton(WINDOW *win, short buff[8], void *data );
static void __CDECL evnt_window_m1( WINDOW * win, short buff[8], void * data);
static void __CDECL evnt_window_slider( WINDOW * win, short buff[8], void * data);
static void __CDECL evnt_window_arrowed( WINDOW *win, short buff[8], void *data );
/* -------------------------------------------------------------------------- */
/* Module public functions: */
/* -------------------------------------------------------------------------- */
@ -260,6 +280,7 @@ int window_destroy( struct gui_window * gw)
/* needed? */ /*listRemove( (LINKABLE*)gw->root->cmproot ); */
if( gw->root ) {
/* TODO: check if no other browser is bound to this root window! */
/* only needed for tabs */
if( gw->root->title )
free( gw->root->title );
if( gw->root->cmproot )
@ -298,6 +319,7 @@ void window_open( struct gui_window * gw)
if( gw->root->statusbar != NULL ){
gw->root->statusbar->attached = true;
}
tb_adjust_size( gw );
/*TBD: get already present content and set size? */
}
@ -358,6 +380,7 @@ bool window_widget_has_focus( struct gui_window * gw, enum focus_element_type t,
return( ( element == gw->root->focus.element && t == gw->root->focus.type) );
}
/* -------------------------------------------------------------------------- */
/* Event Handlers: */
/* -------------------------------------------------------------------------- */
@ -392,6 +415,7 @@ static void __CDECL evnt_window_arrowed( WINDOW *win, short buff[8], void *data
browser_scroll( input_window, buff[4], value, abs );
}
static void __CDECL evnt_window_dd( WINDOW *win, short wbuff[8], void * data )
{
struct gui_window * gw = (struct gui_window *)data;
@ -516,7 +540,6 @@ static void __CDECL evnt_window_m1( WINDOW * win, short buff[8], void * data)
{
struct gui_window * gw = input_window;
static bool prev_url = false;
static bool prev_sb = false;
short mx, my, mbut, mkstate;
bool a = false; //flags if mouse is within controls or browser
bool within = false;
@ -555,21 +578,10 @@ static void __CDECL evnt_window_m1( WINDOW * win, short buff[8], void * data)
prev_url = a = true;
}
}
if( gw->root->statusbar && within == false /* && a == false */ ) {
if( mx >= sbbox.g_x + (sbbox.g_w-MOVER_WH) && mx <= sbbox.g_x + sbbox.g_w &&
my >= sbbox.g_y + (sbbox.g_h-MOVER_WH) && my <= sbbox.g_y + sbbox.g_h ) {
/* mouse within sizer box ( bottom right ) */
prev_sb = a = true;
gem_set_cursor( &gem_cursors.sizenwse );
}
}
if( !a ) {
if( prev_sb )
gw->root->statusbar->resize_init = true;
if( prev_url || prev_sb ) {
if( prev_url ) {
gem_set_cursor( &gem_cursors.arrow );
prev_url = false;
prev_sb = false;
}
/* report mouse move in the browser window */
if( within ){
@ -639,7 +651,8 @@ static void __CDECL evnt_window_slider( WINDOW * win, short buff[8], void * data
return;
}
/* update the sliders _before_ we call redraw (which might depend on the slider possitions) */
/* update the sliders _before_ we call redraw
(which might depend on the slider possitions) */
WindSlider( win, (dx?HSLIDER:0) | (dy?VSLIDER:0) );
if( dy > 0 )
@ -650,6 +663,8 @@ static void __CDECL evnt_window_slider( WINDOW * win, short buff[8], void * data
browser_scroll( gw, WA_RTPAGE, abs(dx), false );
else if( dx < 0 )
browser_scroll( gw, WA_LFPAGE, abs(dx), false );
}
@ -741,25 +756,23 @@ static void __CDECL evnt_window_rt_resize( WINDOW *win, short buff[8], void * da
if(gw->root->loc.g_w != w || gw->root->loc.g_h != h ){
/* report resize to component interface: */
browser_update_rects( gw );
mt_WindGetGrect( &app, gw->root->handle, WF_CURRXYWH, (GRECT*)&gw->root->loc);
browser_get_rect( gw, BR_CONTENT, &rect );
if( gw->browser->bw->current_content != NULL )
browser_window_reformat(gw->browser->bw, false, rect.g_w, rect.g_h );
else
tb_adjust_size( gw );
if( gw->browser->bw->current_content != NULL ){
/* Reformat will happen when next redraw message arrives: */
gw->browser->reformat_pending = true;
if( sys_XAAES() ){
if( gw->root->loc.g_w > w || gw->root->loc.g_h > h ){
ApplWrite( _AESapid, WM_REDRAW, gw->root->handle->handle,
gw->root->loc.g_x, gw->root->loc.g_y,
gw->root->loc.g_w, gw->root->loc.g_h );
}
}
mt_WindGetGrect( &app, gw->root->handle, WF_CURRXYWH,
(GRECT*)&gw->root->loc);
}
else {
WindClear( gw->root->handle );
gw->root->toolbar->url.scrollx = 0;
/* send complete redraw to toolbar & statusbar: */
mt_CompGetLGrect(&app, gw->root->toolbar->comp, WF_WORKXYWH, &rect);
ApplWrite( _AESapid, WM_REDRAW, gw->root->handle->handle,
rect.g_x, rect.g_y, rect.g_w, rect.g_h
);
mt_CompGetLGrect(&app, gw->root->statusbar->comp, WF_WORKXYWH, &rect);
ApplWrite( _AESapid, WM_REDRAW, gw->root->handle->handle,
rect.g_x, rect.g_y, rect.g_w, rect.g_h
);
/* TODO: recalculate scroll position, instead of zeroing? */
}
} else {
if(gw->root->loc.g_x != x || gw->root->loc.g_y != y ){
mt_WindGetGrect( &app, gw->root->handle, WF_CURRXYWH, (GRECT*)&gw->root->loc);

View File

@ -64,23 +64,4 @@ void window_set_icon(struct gui_window * gw, struct bitmap * bmp );
/* Public event handlers: */
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
/* Static module methods follow here: */
/* -------------------------------------------------------------------------- */
static void evnt_toolbar_click(WINDOW * win, short buf[8], void * data);
static void __CDECL evnt_window_redraw( WINDOW *win, short buff[8], void *data );
static void __CDECL evnt_window_icondraw( WINDOW *win, short buff[8], void *data );
static void __CDECL evnt_window_newtop( WINDOW *win, short buff[8], void *data );
void __CDECL evnt_window_resize( WINDOW *win, short buff[8], void * data );
static void __CDECL evnt_window_move( WINDOW *win, short buff[8], void * data );
static void __CDECL evnt_window_rt_resize( WINDOW *win, short buff[8], void * date );
static void __CDECL evnt_window_close( WINDOW *win, short buff[8], void *data );
static void __CDECL evnt_window_dd( WINDOW *win, short wbuff[8], void * data ) ;
static void __CDECL evnt_window_destroy( WINDOW *win, short buff[8], void *data );
static void __CDECL evnt_window_keybd(WINDOW *win, short buff[8], void *data );
static void __CDECL evnt_window_mbutton(WINDOW *win, short buff[8], void *data );
static void __CDECL evnt_window_m1( WINDOW * win, short buff[8], void * data);
static void __CDECL evnt_window_slider( WINDOW * win, short buff[8], void * data);
static void __CDECL evnt_window_arrowed( WINDOW *win, short buff[8], void *data );
#endif

View File

@ -150,6 +150,7 @@ void context_popup( struct gui_window * gw, short x, short y )
FILE * fp_tmpfile;
char * tempfile;
int err = 0;
char cmdline[128];
pop = get_tree( POP_CTX );
if( pop == NULL )
@ -252,10 +253,17 @@ void context_popup( struct gui_window * gw, short x, short y )
if( fp_tmpfile ){
fwrite( data, size, 1, fp_tmpfile );
fclose( fp_tmpfile );
err = ShelWrite( option_atari_editor, tempfile , NULL, 1, 0);
// TODO: check if app is runnin, if not, use pexec or such.
/*sprintf((char*)&cmdline, "%s \"%s\"", option_atari_editor, tempfile );
system( (char*)&cmdline );
*/
//err = ShelWrite( option_atari_editor, tempfile , option_atari_editor, 1, 0);
LOG(("launched: %s %s (%d)\n", option_atari_editor, tempfile, err ));
}
}
} else {
LOG(("Please set option_atari_editor!"));
}
break;

50
atari/encoding.c Normal file
View File

@ -0,0 +1,50 @@
#include "atari/encoding.h"
/* TODO: this need a rework..., encoding to atari st doesn|t always work.
( gui_add_to_clipboard...) */
utf8_convert_ret utf8_to_local_encoding(const char *string,
size_t len,
char **result)
{
utf8_convert_ret r;
r = utf8_to_enc(string, "ATARIST", len, result);
if(r != UTF8_CONVERT_OK) {
r = utf8_to_enc(string, "UTF-8", len, result);
assert( r == UTF8_CONVERT_OK );
}
return r;
}
utf8_convert_ret local_encoding_to_utf8(const char *string,
size_t len,
char **result)
{
return utf8_from_enc(string, "ATARIST", len, result);
}
/* borrowed from highwire project: */
static const uint16_t Atari_to_Unicode[] = {
/* .0 .1 .2 .3 .4 .5 .6 .7 .8 .9 .A .B .C .D .E .F */
/* 7F */ 0x0394,
/* 8. */ 0x00C7,0x00FC,0x00E9,0x00E2,0x00E4,0x00E0,0x00E5,0x00E7,0x00EA,0x00EB,0x00E8,0x00EF,0x00EE,0x00EC,0x00C4,0x00C5,
/* 9. */ 0x00C9,0x00E6,0x00C6,0x00F4,0x00F6,0x00F2,0x00FB,0x00F9,0x00FF,0x00D6,0x00DC,0x00A2,0x00A3,0x00A5,0x00DF,0x0192,
/* A. */ 0x00E1,0x00ED,0x00F3,0x00FA,0x00F1,0x00D1,0x00AA,0x00BA,0x00BF,0x2310,0x00AC,0x00BD,0x00BC,0x00A1,0x00AB,0x00BB,
/* B. */ 0x00C3,0x00F5,0x00D8,0x00F8,0x0153,0x0152,0x00C0,0x00C3,0x00D5,0x00A8,0x00B4,0x2020,0x00B6,0x00A9,0x00AE,0x2122,
/* C. */ 0x0133,0x0132,0x05D0,0x05D1,0x05D2,0x05D3,0x05D4,0x05D5,0x05D6,0x05D7,0x05D8,0x05D9,0x05DB,0x05DC,0x05DE,0x05E0,
/* D. */ 0x05E1,0x05E2,0x05E4,0x05E6,0x05E7,0x05E8,0x05E9,0x05EA,0x05DF,0x05DA,0x05DD,0x05E3,0x05E5,0x00A7,0x2038,0x221E,
/* E. */ 0x03B1,0x03B2,0x0393,0x03C0,0x03A3,0x03C3,0x00B5,0x03C4,0x03A6,0x0398,0x03A9,0x03B4,0x222E,0x03C6,0x2208,0x2229,
/* F. */ 0x2261,0x00B1,0x2265,0x2264,0x2320,0x2321,0x00F7,0x2248,0x00B0,0x2022,0x00B7,0x221A,0x207F,0x00B2,0x00B3,0x00AF
};
#define BEG_Atari_to_Unicode 0x7F
int atari_to_ucs4(unsigned char atari)
{
uint32_t ucs4 = 0xfffd;
if ( atari >= BEG_Atari_to_Unicode && atari <= 0xFE )
ucs4 = (int)Atari_to_Unicode[(short)atari - BEG_Atari_to_Unicode];
else
ucs4 = (int)atari;
return( ucs4 );
}

19
atari/encoding.h Normal file
View File

@ -0,0 +1,19 @@
#ifndef NS_ATARI_ENCODING_H
#define NS_ATARI_ENCODING_H
#include <inttypes.h>
#include <assert.h>
#include <stdbool.h>
#include <windom.h>
#include "css/css.h"
#include "render/font.h"
#include "utils/utf8.h"
utf8_convert_ret local_encoding_to_utf8(const char *string,
size_t len,
char **result);
int atari_to_ucs4( unsigned char atarichar);
#endif

View File

@ -21,11 +21,6 @@
#include <stdbool.h>
#include <windom.h>
/*
#include <ft2build.h>
#include FT_CACHE_H
*/
#include "css/css.h"
#include "render/font.h"
#include "utils/utf8.h"
@ -45,53 +40,6 @@
extern GEM_FONT_PLOTTER fplotter;
/* TODO: this need a rework..., encoding to atari st doesn|t always work. ( gui_add_to_clipboard...) */
utf8_convert_ret utf8_to_local_encoding(const char *string,
size_t len,
char **result)
{
utf8_convert_ret r;
r = utf8_to_enc(string, "ATARIST", len, result);
if(r != UTF8_CONVERT_OK) {
r = utf8_to_enc(string, "UTF-8", len, result);
assert( r == UTF8_CONVERT_OK );
}
return r;
}
utf8_convert_ret local_encoding_to_utf8(const char *string,
size_t len,
char **result)
{
return utf8_from_enc(string, "ATARIST", len, result);
}
/* borrowed from highwire project: */
static const uint16_t Atari_to_Unicode[] = {
/* .0 .1 .2 .3 .4 .5 .6 .7 .8 .9 .A .B .C .D .E .F */
/* 7F */ 0x0394,
/* 8. */ 0x00C7,0x00FC,0x00E9,0x00E2,0x00E4,0x00E0,0x00E5,0x00E7,0x00EA,0x00EB,0x00E8,0x00EF,0x00EE,0x00EC,0x00C4,0x00C5,
/* 9. */ 0x00C9,0x00E6,0x00C6,0x00F4,0x00F6,0x00F2,0x00FB,0x00F9,0x00FF,0x00D6,0x00DC,0x00A2,0x00A3,0x00A5,0x00DF,0x0192,
/* A. */ 0x00E1,0x00ED,0x00F3,0x00FA,0x00F1,0x00D1,0x00AA,0x00BA,0x00BF,0x2310,0x00AC,0x00BD,0x00BC,0x00A1,0x00AB,0x00BB,
/* B. */ 0x00C3,0x00F5,0x00D8,0x00F8,0x0153,0x0152,0x00C0,0x00C3,0x00D5,0x00A8,0x00B4,0x2020,0x00B6,0x00A9,0x00AE,0x2122,
/* C. */ 0x0133,0x0132,0x05D0,0x05D1,0x05D2,0x05D3,0x05D4,0x05D5,0x05D6,0x05D7,0x05D8,0x05D9,0x05DB,0x05DC,0x05DE,0x05E0,
/* D. */ 0x05E1,0x05E2,0x05E4,0x05E6,0x05E7,0x05E8,0x05E9,0x05EA,0x05DF,0x05DA,0x05DD,0x05E3,0x05E5,0x00A7,0x2038,0x221E,
/* E. */ 0x03B1,0x03B2,0x0393,0x03C0,0x03A3,0x03C3,0x00B5,0x03C4,0x03A6,0x0398,0x03A9,0x03B4,0x222E,0x03C6,0x2208,0x2229,
/* F. */ 0x2261,0x00B1,0x2265,0x2264,0x2320,0x2321,0x00F7,0x2248,0x00B0,0x2022,0x00B7,0x221A,0x207F,0x00B2,0x00B3,0x00AF
};
#define BEG_Atari_to_Unicode 0x7F
int atari_to_ucs4(unsigned char atari)
{
uint32_t ucs4 = 0xfffd;
if ( atari >= BEG_Atari_to_Unicode && atari <= 0xFE )
ucs4 = (int)Atari_to_Unicode[(short)atari - BEG_Atari_to_Unicode];
else
ucs4 = (int)atari;
return( ucs4 );
}
static bool atari_font_position_in_string(const plot_font_style_t * fstyle,const char *string,
size_t length,int x, size_t *char_offset, int *actual_x )
{

View File

@ -16,16 +16,10 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef NS_ATARI_FT_FONT_H
#define NS_ATARI_FT_FONT_H
#ifndef NS_ATARI_FONT_H
#define NS_ATARI_FONT_H
#include "utils/utf8.h"
utf8_convert_ret local_encoding_to_utf8(const char *string,
size_t len,
char **result);
int atari_to_ucs4( unsigned char atarichar);
#endif /* NETSURF_FB_FONT_H */

View File

@ -68,7 +68,7 @@
#include "atari/hotlist.h"
#include "atari/login.h"
#include "atari/global_evnt.h"
#include "atari/font.h"
#include "atari/encoding.h"
#include "atari/res/netsurf.rsh"
#include "atari/plot.h"
#include "atari/clipboard.h"
@ -172,10 +172,15 @@ void gui_poll(bool active)
if( browser_redraw_required( g ) ){
browser_redraw( g );
}
if( g->root->toolbar ){
if(g->root->toolbar->url.redraw ){
tb_url_redraw( g );
}
}
}
if( evnt.timer != 0 && !active ){
/* this suits for stuff with lower priority */
//hotlist_redraw();
/* TBD: really be spare on redraws??? */
atari_treeview_redraw( hl.tv );
}
}
@ -541,16 +546,9 @@ void gui_window_place_caret(struct gui_window *w, int x, int y, int height)
gui_window_remove_caret( w );
w->browser->caret.requested.g_x = x;
w->browser->caret.requested.g_y = y;
w->browser->caret.requested.g_w = 2;
w->browser->caret.requested.g_w = 1;
w->browser->caret.requested.g_h = height;
w->browser->caret.redraw = true;
browser_schedule_redraw_rect(
w,
x - b->scroll.current.x,
y - b->scroll.current.y,
w->browser->caret.requested.g_w,
w->browser->caret.requested.g_h
);
return;
}
@ -561,25 +559,23 @@ void gui_window_place_caret(struct gui_window *w, int x, int y, int height)
void
gui_window_remove_caret(struct gui_window *w)
{
LGRECT rect;
if (w == NULL)
return;
CMP_BROWSER b = w->browser;
if( w->browser->caret.background.fd_addr != NULL ){
browser_restore_caret_background( w, NULL );
w->browser->caret.requested.g_w = 0;
w->browser->caret.redraw = true;
browser_schedule_redraw_rect( w,
w->browser->caret.current.g_x - b->scroll.current.x,
w->browser->caret.current.g_y - b->scroll.current.y,
w->browser->caret.current.g_w,
w->browser->caret.current.g_h
);
w->browser->caret.current.g_w = 0;
}
return;
}
void
gui_window_set_icon(struct gui_window *g, hlcache_handle *icon)
{
/* Untestet, favicon support has been dropped, so this is dead code. */
g->icon = (icon != NULL) ? content_get_bitmap(icon) : NULL;
}
void
@ -871,8 +867,6 @@ void gui_quit(void)
hotlist_destroy();
/* send WM_DESTROY to windows purely managed by windom: */
urldb_save_cookies(option_cookie_file);
urldb_save(option_url_file);
@ -1025,10 +1019,6 @@ static void gui_init(int argc, char** argv)
atari_plotter_init( option_atari_screen_driver, option_atari_font_driver );
LOG(("Knockout rendering: %s\n", option_atari_knockout ? "yes" : "no"));
plot_set_knockout( option_atari_knockout );
/* Interface colours */
option_gui_colour_bg_1 = 0xFFFFFF; /** Background (bbggrr) */
option_gui_colour_fg_1 = 0xFF0000; /** Foreground (bbggrr) */
option_gui_colour_fg_2 = 0x000000; /** Foreground selected (bbggrr) */
}
static char *theapp = (char*)"NetSurf";

View File

@ -21,6 +21,7 @@
void global_history_add_recent(const char *url)
{
}
char **global_history_get_recent(int *count)

View File

@ -32,5 +32,6 @@ void plot_set_knockout( int set );
bool plot_get_clip(struct rect * out);
bool plot_clip(const struct rect *clip);
bool plot_rectangle( int x0, int y0, int x1, int y1,const plot_style_t *style );
bool plot_line( int x0, int y0, int x1, int y1, const plot_style_t *style );
#endif

79
atari/redrawslots.c Normal file
View File

@ -0,0 +1,79 @@
#include <stdbool.h>
#include "windom.h"
#include "utils/types.h"
#include "atari/redrawslots.h"
void redraw_slots_init(struct s_redrw_slots * slots, short size)
{
slots->size = MIN( MAX_REDRW_SLOTS , size);
slots->areas_used = 0;
}
static inline bool rect_intersect( struct rect * box1, struct rect * box2 )
{
if (box2->x1 < box1->x0)
return false;
if (box2->y1 < box1->y0)
return false;
if (box2->x0 > box1->x1)
return false;
if (box2->y0 > box1->y1)
return false;
return true;
}
/*
schedule a slots, coords are relative.
*/
void redraw_slot_schedule(struct s_redrw_slots * slots, short x0, short y0, short x1, short y1)
{
int i;
struct rect area;
area.x0 = x0;
area.y0 = y0;
area.x1 = x1;
area.y1 = y1;
for( i=0; i<slots->areas_used; i++) {
if( slots->areas[i].x0 <= x0
&& slots->areas[i].x1 >= x1
&& slots->areas[i].y0 <= y0
&& slots->areas[i].y1 >= y1 ){
/* the area is already queued for redraw */
return;
} else {
if( rect_intersect(&slots->areas[i], &area ) ){
slots->areas[i].x0 = MIN(slots->areas[i].x0, x0);
slots->areas[i].y0 = MIN(slots->areas[i].y0, y0);
slots->areas[i].x1 = MAX(slots->areas[i].x1, x1);
slots->areas[i].y1 = MAX(slots->areas[i].y1, y1);
return;
}
}
}
if( slots->areas_used < slots->size ) {
slots->areas[slots->areas_used].x0 = x0;
slots->areas[slots->areas_used].x1 = x1;
slots->areas[slots->areas_used].y0 = y0;
slots->areas[slots->areas_used].y1 = y1;
slots->areas_used++;
} else {
/*
we are out of available slots, merge box with last slot
this is dumb... but also a very rare case.
*/
slots->areas[slots->size-1].x0 = MIN(slots->areas[i].x0, x0);
slots->areas[slots->size-1].y0 = MIN(slots->areas[i].y0, y0);
slots->areas[slots->size-1].x1 = MAX(slots->areas[i].x1, x1);
slots->areas[slots->size-1].y1 = MAX(slots->areas[i].y1, y1);
}
done:
return;
}

27
atari/redrawslots.h Normal file
View File

@ -0,0 +1,27 @@
#ifndef ATARI_REDRAW_SLOTS_H
#define ATARI_REDRAW_SLOTS_H
/*
MAX_REDRW_SLOTS
This is the number of redraw requests that the slotlist can store.
If a redraw is scheduled and all slots are used, the rectangle will
be merged to one of the existing slots.
*/
#define MAX_REDRW_SLOTS 32
/*
This struct holds scheduled redraw requests.
*/
struct rect;
struct s_redrw_slots
{
struct rect areas[MAX_REDRW_SLOTS];
short size;
short areas_used;
};
void redraw_slots_init(struct s_redrw_slots * slots, short size);
void redraw_slot_schedule(struct s_redrw_slots * slots, short x0, short y0, short x1, short y1);
#endif

View File

@ -34,6 +34,7 @@
#include "desktop/netsurf.h"
#include "desktop/browser.h"
#include "desktop/mouse.h"
#include "desktop/plot_style.h"
#include "desktop/plotters.h"
#include "atari/clipboard.h"
#include "atari/gui.h"
@ -43,13 +44,26 @@
#include "atari/clipboard.h"
#include "atari/misc.h"
#include "atari/global_evnt.h"
#include "atari/plot.h"
#include "cflib.h"
#include "atari/res/netsurf.rsh"
#include "atari/plot/plotter.h"
extern char * cfg_homepage_url;
extern short vdih;
extern void * h_gem_rsrc;
extern GEM_PLOTTER plotter;
static OBJECT * throbber_form = NULL;
static const plot_font_style_t font_style_url = {
.family = PLOT_FONT_FAMILY_SANS_SERIF,
.size = TOOLBAR_URL_TEXT_SIZE_PT*FONT_SIZE_SCALE,
.weight = 400,
.flags = FONTF_NONE,
.background = 0xffffff,
.foreground = 0x0
};
/* prototypes & order for button widgets: */
static struct s_tb_button tb_buttons[] =
@ -62,8 +76,7 @@ static struct s_tb_button tb_buttons[] =
{ 0, NULL, NULL }
};
static OBJECT * throbber_form = NULL;
static void tb_txt_request_redraw(void *data, int x, int y, int w, int h);
static void __CDECL button_redraw( COMPONENT *c, long buff[8])
{
@ -220,114 +233,65 @@ static
void __CDECL evnt_url_redraw( COMPONENT *c, long buff[8] )
{
LGRECT work, clip;
struct gui_window * gw;
short pxy[10];
short i;
short d;
short mchars;
struct gui_window * gw = (struct gui_window *)mt_CompDataSearch(&app, c, CDT_OWNER);
assert( gw != NULL );
assert( gw->browser != NULL );
assert( gw->root != NULL );
assert( gw->browser->bw != NULL );
CMP_TOOLBAR tb = gw->root->toolbar;
gw = (struct gui_window *)mt_CompDataSearch(&app, c, CDT_OWNER);
if( gw == NULL )
return;
mt_CompGetLGrect(&app, c, WF_WORKXYWH, &work);
CMP_TOOLBAR tb = gw->root->toolbar;
mt_CompGetLGrect(&app, tb->url.comp, WF_WORKXYWH, &work);
// this last pixel is drawn by the root component of the toolbar:
// it's the black border, so we leave it out:
work.g_h--;
clip = work;
if ( !rc_lintersect( (LGRECT*)&buff[4], &clip ) ) return;
pxy[0] = clip.g_x;
pxy[1] = clip.g_y;
pxy[2] = clip.g_w + clip.g_x;
pxy[3] = clip.g_h + clip.g_y;
pxy[2] = clip.g_w + clip.g_x-1;
pxy[3] = clip.g_h + clip.g_y-1;
vs_clip( vdih, 1, (short*)&pxy );
mchars = (work.g_w-6 / tb->url.char_size); /* subtract 6px -> 3px padding around text on each side */
vswr_mode( vdih, MD_REPLACE);
vsf_perimeter( vdih, 0 );
vsf_interior( vdih , 1 );
vsf_color( vdih, LWHITE );
vst_point( vdih, 10, &pxy[0], &pxy[1], &pxy[2], &pxy[3] );
vst_alignment(vdih, 0, 5, &d, &d );
vst_effects( vdih, 0 );
vst_color( vdih, BLACK );
/* gray the whole component: */
//left margin:
pxy[0] = work.g_x;
pxy[1] = work.g_y;
pxy[2] = work.g_x + work.g_w;
pxy[3] = work.g_y + work.g_h-2;
v_bar( vdih, (short*)&pxy );
/* draw outer line, left top: */
pxy[0] = work.g_x + 2;
pxy[1] = work.g_y + ((TOOLBAR_HEIGHT - URLBOX_HEIGHT)/2);
/* right, top: */
pxy[2] = work.g_x + work.g_w - 4;
pxy[3] = work.g_y + ((TOOLBAR_HEIGHT - URLBOX_HEIGHT)/2);
/* right, bottom: */
pxy[4] = work.g_x + work.g_w - 4;
pxy[5] = work.g_y + ((TOOLBAR_HEIGHT - URLBOX_HEIGHT)/2) + URLBOX_HEIGHT;
/* left, bottom: */
pxy[6] = work.g_x + 2;
pxy[7] = work.g_y + ((TOOLBAR_HEIGHT - URLBOX_HEIGHT)/2) + URLBOX_HEIGHT;
/* left, top again: */
pxy[8] = work.g_x + 2;
pxy[9] = work.g_y + ((TOOLBAR_HEIGHT - URLBOX_HEIGHT)/2);
vsf_interior( vdih, FIS_SOLID );
vsf_style( vdih, 1);
vsl_color( vdih, BLACK);
v_pline( vdih, 5, pxy );
/* draw white txt box: */
pxy[0] = pxy[0] + 1;
pxy[1] = pxy[1] + ((TOOLBAR_HEIGHT - URLBOX_HEIGHT)/2) - 1;
pxy[2] = pxy[2] - 1;
pxy[3] = work.g_y + ((TOOLBAR_HEIGHT - URLBOX_HEIGHT)/2) + URLBOX_HEIGHT ;
vsf_color( vdih, WHITE);
pxy[2] = work.g_x + TOOLBAR_URL_MARGIN_LEFT-1;
pxy[3] = work.g_y + work.g_h-1;
v_bar( vdih, pxy );
if( gw->root->toolbar->url.used > 1 ) {
short curx;
short vqw[4];
char t[2];
short cw = 0;
t[0]=tb->url.text[0];
t[1]=0;
if( atari_sysinfo.sfont_monospaced ) {
vqt_width( vdih, t[0], &vqw[0], &vqw[1], &vqw[2] );
cw = vqw[0];
}
int maxx = (clip.g_x + clip.g_w) - cw;
for( curx = work.g_x + 3, i=tb->url.scrollx ; curx < maxx && i < tb->url.used-1; i++ ){
t[0] = tb->url.text[i];
v_gtext( vdih, curx, work.g_y + ((TOOLBAR_HEIGHT - URLBOX_HEIGHT)/2) + 2, (char*)&t );
if( !atari_sysinfo.sfont_monospaced ) {
vqt_width( vdih, t[0], &vqw[0], &vqw[1], &vqw[2] );
curx += vqw[0];
} else {
curx += cw;
}
}
}
if( window_url_widget_has_focus( gw ) ) {
/* draw caret: */
pxy[0] = 3 + work.g_x + ((tb->url.caret_pos - tb->url.scrollx) * tb->url.char_size);
pxy[1] = pxy[1] + 1;
pxy[2] = 3 + work.g_x + ((tb->url.caret_pos - tb->url.scrollx) * tb->url.char_size);
pxy[3] = pxy[3] - 1 ;
v_pline( vdih, 2, pxy );
/* draw selection: */
if( tb->url.selection_len != 0 ) {
vswr_mode( vdih, MD_XOR);
vsl_color( vdih, BLACK);
pxy[0] = 3 + work.g_x + ((tb->url.caret_pos - tb->url.scrollx) * tb->url.char_size);
pxy[2] = pxy[0] + ( gw->root->toolbar->url.selection_len * tb->url.char_size);
// right margin:
pxy[0] = work.g_x+work.g_w-TOOLBAR_URL_MARGIN_RIGHT;
pxy[1] = work.g_y;
pxy[2] = work.g_x+work.g_w-1;
pxy[3] = work.g_y+work.g_h-1;
v_bar( vdih, pxy );
vswr_mode( vdih, MD_REPLACE );
}
}
// top margin:
pxy[0] = work.g_x;
pxy[1] = work.g_y;
pxy[2] = work.g_x+work.g_w-1;
pxy[3] = work.g_y+TOOLBAR_URL_MARGIN_TOP-1;
v_bar( vdih, pxy );
// bottom margin:
pxy[0] = work.g_x;
pxy[1] = work.g_y+work.g_h-TOOLBAR_URL_MARGIN_BOTTOM;
pxy[2] = work.g_x+work.g_w-1;
pxy[3] = work.g_y+work.g_h-1;
v_bar( vdih, pxy );
vs_clip( vdih, 0, (short*)&pxy );
// TBD: request redraw of textarea for specific region.
clip.g_x -= work.g_x+TOOLBAR_URL_MARGIN_LEFT;
clip.g_y -= work.g_y+TOOLBAR_URL_MARGIN_TOP;
tb_txt_request_redraw( tb, clip.g_x, clip.g_y, clip.g_w, clip.g_h );
}
static
@ -342,37 +306,45 @@ void __CDECL evnt_url_click( COMPONENT *c, long buff[8] )
assert( gw != NULL );
CMP_TOOLBAR tb = gw->root->toolbar;
mt_CompGetLGrect(&app, c, WF_WORKXYWH, &work);
mx = evnt.mx - work.g_x;
my = evnt.my - work.g_y;
mx = evnt.mx - (work.g_x + TOOLBAR_URL_MARGIN_LEFT);
my = evnt.my - (work.g_y + TOOLBAR_URL_MARGIN_TOP);
/* TODO: reset mouse state of browser window? */
/* select whole text when newly focused, otherwise set caret to end of text */
if( !window_url_widget_has_focus(gw) ) {
tb_url_place_caret( gw, strlen(tb->url.text), true);
tb->url.selection_len = -tb->url.caret_pos;
// TODO select all ( needs textarea change )
window_set_focus( gw, URL_WIDGET, (void*)&tb->url );
textarea_mouse_action( tb->url.textarea, BROWSER_MOUSE_PRESS_1, mx, my );
} else {
if( mb & 1 ) {
/* if the button is dragging, place selection: */
old = tb->url.selection_len;
tb->url.selection_len = (tb->url.scrollx + (mx / tb->url.char_size)) - tb->url.caret_pos;
if(tb->url.caret_pos + tb->url.selection_len > (int)strlen(tb->url.text) )
tb->url.selection_len = strlen(tb->url.text) - tb->url.caret_pos;
if( old == tb->url.selection_len )
/* avoid redraw when nothing changed */
return;
/* TODO: if the button is dragging, report draw event */
} else {
/* TODO: recognize click + shift key */
tb->url.selection_len = 0;
tb_url_place_caret( gw, tb->url.scrollx + (mx / tb->url.char_size), true);
int mstate = BROWSER_MOUSE_PRESS_1;
if( (kstat & (K_LSHIFT|K_RSHIFT)) != 0 )
mstate = BROWSER_MOUSE_MOD_1;
textarea_mouse_action( tb->url.textarea, BROWSER_MOUSE_PRESS_1, mx, my );
}
}
// TODO: do not send an complete redraw!
ApplWrite( _AESapid, WM_REDRAW, gw->root->handle->handle,
work.g_x, work.g_y, work.g_w, work.g_h );
}
void tb_adjust_size( struct gui_window * gw )
{
LGRECT work;
CMP_TOOLBAR t = gw->root->toolbar;
mt_CompGetLGrect( &app, t->url.comp, WF_WORKXYWH, &work);
work.g_w -= (TOOLBAR_URL_MARGIN_LEFT + TOOLBAR_URL_MARGIN_RIGHT);
/* do not overwrite the black border, because of that, add 1 */
work.g_h -= (TOOLBAR_URL_MARGIN_TOP + TOOLBAR_URL_MARGIN_BOTTOM+1);
textarea_set_dimensions( t->url.textarea, work.g_w, work.g_h );
tb_txt_request_redraw( t, 0,0, work.g_w-1, work.g_h-1);
}
static void __CDECL evnt_toolbar_redraw( COMPONENT *c, long buff[8], void *data )
{
LGRECT work, clip;
@ -395,6 +367,109 @@ static void __CDECL evnt_toolbar_redraw( COMPONENT *c, long buff[8], void *data
}
static void tb_txt_request_redraw(void *data, int x, int y, int w, int h)
{
LGRECT work;
if( data == NULL )
return;
CMP_TOOLBAR t = data;
if( t->url.redraw == false ){
t->url.redraw = true;
t->url.rdw_area.g_x = x;
t->url.rdw_area.g_y = y;
t->url.rdw_area.g_w = w;
t->url.rdw_area.g_h = h;
} else {
/* merge the redraw area to the new area.: */
int newx1 = x+w;
int newy1 = y+h;
int oldx1 = t->url.rdw_area.g_x + t->url.rdw_area.g_w;
int oldy1 = t->url.rdw_area.g_y + t->url.rdw_area.g_h;
t->url.rdw_area.g_x = MIN(t->url.rdw_area.g_x, x);
t->url.rdw_area.g_y = MIN(t->url.rdw_area.g_y, y);
t->url.rdw_area.g_w = ( oldx1 > newx1 ) ?
oldx1 - t->url.rdw_area.g_x : newx1 - t->url.rdw_area.g_x;
t->url.rdw_area.g_h = ( oldy1 > newy1 ) ?
oldy1 - t->url.rdw_area.g_y : newy1 - t->url.rdw_area.g_y;
}
}
void tb_url_redraw( struct gui_window * gw )
{
CMP_TOOLBAR t = gw->root->toolbar;
if (t != NULL) {
if( t->url.redraw && ((plotter->flags & PLOT_FLAG_OFFSCREEN) == 0) ) {
const struct redraw_context ctx = {
.interactive = true,
.plot = &atari_plotters
};
short todo[4];
LGRECT work;
mt_CompGetLGrect(&app, gw->root->toolbar->url.comp, WF_WORKXYWH, &work);
work.g_x += TOOLBAR_URL_MARGIN_RIGHT;
work.g_y += TOOLBAR_URL_MARGIN_LEFT;
work.g_w -= TOOLBAR_URL_MARGIN_RIGHT;
work.g_h -= TOOLBAR_URL_MARGIN_BOTTOM;
plotter->resize(plotter, work.g_w, work.g_h );
plotter->move(plotter, work.g_x, work.g_y );
plotter->lock( plotter );
todo[0] = work.g_x;
todo[1] = work.g_y;
todo[2] = todo[0] + work.g_w-1;
todo[3] = todo[1] + work.g_h-1;
vs_clip(plotter->vdi_handle, 1, (short*)&todo );
if( wind_get(gw->root->handle->handle, WF_FIRSTXYWH,
&todo[0], &todo[1], &todo[2], &todo[3] )!=0 ) {
while (todo[2] && todo[3]) {
/* convert screen to relative coords: */
todo[0] = todo[0] - work.g_x;
todo[1] = todo[1] - work.g_y;
if( todo[0] < 0 ){
todo[2] = todo[2] + todo[0];
todo[0] = 0;
}
if( todo[1] < 0 ){
todo[3] = todo[3] + todo[1];
todo[1] = 0;
}
if (rc_intersect(&t->url.rdw_area,(GRECT *)&todo)) {
struct rect clip = {
.x0 = todo[0],
.y0 = todo[1],
.x1 = todo[0]+todo[2],
.y1 = todo[1]+todo[3]
};
textarea_redraw( t->url.textarea, 0, 0, &clip, &ctx );
}
if (wind_get(gw->root->handle->handle, WF_NEXTXYWH,
&todo[0], &todo[1], &todo[2], &todo[3])==0) {
break;
}
}
} else {
plotter->unlock( plotter );
return;
}
plotter->unlock( plotter );
vs_clip(plotter->vdi_handle, 0, (short*)&todo);
t->url.redraw = false;
t->url.rdw_area.g_x = 65000;
t->url.rdw_area.g_y = 65000;
t->url.rdw_area.g_w = -1;
t->url.rdw_area.g_h = -1;
} else {
/* just copy stuff from the offscreen buffer */
}
}
}
CMP_TOOLBAR tb_create( struct gui_window * gw )
{
int i;
@ -435,11 +510,13 @@ CMP_TOOLBAR tb_create( struct gui_window * gw )
}
/* create the url widget: */
t->url.char_size = 8;
t->url.text = malloc( 2*URL_WIDGET_BSIZE );
strcpy( t->url.text, "http://" );
t->url.allocated = 2*URL_WIDGET_BSIZE;
t->url.scrollx = 0;
t->url.textarea = textarea_create( 300, TOOLBAR_TEXTAREA_HEIGHT, 0,
&font_style_url, tb_txt_request_redraw,
t );
if( t->url.textarea != NULL ){
textarea_set_text(t->url.textarea, "http://");
}
t->url.comp = (COMPONENT*)mt_CompCreate(&app, CLT_HORIZONTAL, TOOLBAR_HEIGHT, 1);
mt_CompEvntAttach( &app, t->url.comp, WM_REDRAW, evnt_url_redraw );
mt_CompEvntAttach( &app, t->url.comp, WM_XBUTTON, evnt_url_click );
@ -476,8 +553,7 @@ void tb_destroy( CMP_TOOLBAR tb )
i++;
}
free( tb->buttons );
if( tb->url.text != NULL )
free( tb->url.text );
textarea_destroy( tb->url.textarea );
mt_CompDelete( &app, tb->comp);
free( tb );
}
@ -535,7 +611,6 @@ void tb_update_buttons( struct gui_window * gw )
((OBJECT*)mt_CompDataSearch(&app, bt->comp, CDT_OBJECT))->ob_state &= ~OS_DISABLED;
}
mt_CompEvntRedraw( &app, bt->comp );
}
@ -555,67 +630,19 @@ void tb_url_set( struct gui_window * gw, char * text )
struct s_url_widget * url = &gw->root->toolbar->url;
if( len+1 > url->allocated ) {
newsize = (len / (URL_WIDGET_BSIZE-1))+1;
newtext = realloc( url->text, newsize*URL_WIDGET_BSIZE );
if(newtext != NULL) {
url->text = newtext;
url->allocated = newsize * URL_WIDGET_BSIZE;
}
}
if( len+1 < url->allocated - URL_WIDGET_BSIZE
&& url->allocated - URL_WIDGET_BSIZE > URL_WIDGET_BSIZE*2 ) {
newsize = (len / (URL_WIDGET_BSIZE-1) )+1;
newtext = realloc( url->text, newsize*URL_WIDGET_BSIZE );
if(newtext != NULL) {
url->text = newtext;
url->allocated = newsize * URL_WIDGET_BSIZE;
}
}
assert( gw != NULL );
assert( gw->browser != NULL );
assert( gw->root != NULL );
assert( gw->browser->bw != NULL );
strncpy((char*)url->text, text, url->allocated-1 );
url->used = MIN(len+1,url->allocated );
tb_url_place_caret( gw, 0, true);
url->scrollx = 0;
mt_CompGetLGrect(&app, url->comp, WF_WORKXYWH, &work);
ApplWrite( _AESapid, WM_REDRAW, gw->root->handle->handle,
(short)work.g_x, (short)work.g_y, (short)work.g_w, (short)work.g_h );
}
textarea_set_text(url->textarea, text);
/* place the caret and adjust scrolling position */
void tb_url_place_caret( struct gui_window * gw, int steps, bool abs)
{
LGRECT work;
CMP_TOOLBAR tb = gw->root->toolbar;
assert(tb!=NULL);
mt_CompGetLGrect(&app, tb->url.comp, WF_WORKXYWH, &work);
int ws = (work.g_w / tb->url.char_size)-1; /* widget size in chars */
if(abs) {
tb->url.caret_pos = steps;
} else {
tb->url.caret_pos = tb->url.caret_pos + steps;
}
if( (int)tb->url.caret_pos > (int)strlen(tb->url.text) )
tb->url.caret_pos = strlen(tb->url.text);
if( tb->url.caret_pos > tb->url.allocated-2 )
tb->url.caret_pos = tb->url.allocated-2;
if( tb->url.caret_pos < 0)
tb->url.caret_pos = 0;
if( tb->url.caret_pos < tb->url.scrollx ) {
/* the caret has moved out of the widget to the left */
tb->url.scrollx -= ws;
}
if( tb->url.caret_pos > tb->url.scrollx + ws ) {
/* the caret has moved out of the widget to the right */
if(!abs)
tb->url.scrollx += steps;
else
tb->url.scrollx = tb->url.caret_pos - ws;
}
if(tb->url.scrollx < 0)
tb->url.scrollx = 0;
mt_CompGetLGrect( &app, gw->root->toolbar->url.comp, WF_WORKXYWH, &work);
work.g_w -= (TOOLBAR_URL_MARGIN_LEFT + TOOLBAR_URL_MARGIN_RIGHT);
/* do not overwrite the black border, because of that, add 1 */
work.g_h -= (TOOLBAR_URL_MARGIN_TOP + TOOLBAR_URL_MARGIN_BOTTOM+1);
tb_txt_request_redraw( gw->root->toolbar, 0,0,work.g_w,work.g_h );
return;
}
@ -628,153 +655,30 @@ bool tb_url_input( struct gui_window * gw, short nkc )
CMP_TOOLBAR tb = gw->root->toolbar;
assert(tb!=NULL);
LGRECT work;
int start = 0;
int i;
char * newtext;
short newsize;
char backup;
bool ctrl = (nkc & NKF_CTRL);
bool shift = (nkc & NKF_SHIFT);
bool alt = (nkc & NKF_ALT);
bool ret = (ctrl) ? false : true;
char code = (nkc & 0xFF);
bool ret = false;
assert( gw != NULL );
if( (code == NK_LEFT) && !shift ){
/* TODO: recognize shift + click */
tb->url.selection_len = 0;
tb_url_place_caret( gw, -1, false );
}
else if( (code == NK_RIGHT) && !shift ) {
/* TODO: recognize shift + click */
tb->url.selection_len = 0;
tb_url_place_caret( gw, +1, false );
}
else if( (ctrl && code == 'C') ) {
if( tb->url.selection_len != 0 ) {
char * from;
char tmp[abs(tb->url.selection_len)+1];
int len;
if( tb->url.selection_len < 0 ) {
from = &tb->url.text[tb->url.caret_pos+tb->url.selection_len];
} else {
from = &tb->url.text[tb->url.caret_pos];
}
len = MIN( abs(tb->url.selection_len), (int)strlen(from) ) ;
memcpy(&tmp, from, len);
tmp[len] = 0;
int r = scrap_txt_write(&app, (char*)&tmp);
ret = true;
long ucs4;
long ik = nkc_to_input_key( nkc, &ucs4 );
if( ik == 0 ){
if ( (nkc&0xFF) >= 9 ) {
ret = textarea_keypress( tb->url.textarea, ucs4 );
}
}
else if( (ctrl && code == 'V') || code == NK_INS ) {
char * clip = scrap_txt_read( &app );
if( clip != NULL ) {
size_t l = strlen( clip );
unsigned int i = 0;
for( i = 0; i<l; i++) {
tb_url_input( gw, clip[i] );
}
free( clip );
ret = true;
}
}
else if( (code == NK_DEL) ) {
if( tb->url.selection_len != 0 ) {
if( tb->url.selection_len < 0 ) {
strcpy(
&tb->url.text[tb->url.caret_pos+tb->url.selection_len],
&tb->url.text[tb->url.caret_pos]
);
tb_url_place_caret( gw, tb->url.selection_len, false );
} else {
strcpy(
&tb->url.text[tb->url.caret_pos],
&tb->url.text[tb->url.caret_pos+tb->url.selection_len]
);
}
tb->url.used = strlen( tb->url.text ) + 1;
} else {
if( tb->url.caret_pos < tb->url.used -1) {
strcpy(
&tb->url.text[tb->url.caret_pos+tb->url.selection_len],
&tb->url.text[tb->url.caret_pos+1]
);
tb->url.used--;
}
}
tb->url.selection_len = 0;
}
else if( code == NK_BS ) {
if( tb->url.caret_pos > 0 &&
tb->url.selection_len != 0 ) {
if( tb->url.selection_len < 0 ) {
strcpy(&tb->url.text[tb->url.caret_pos+tb->url.selection_len], &tb->url.text[tb->url.caret_pos]);
tb_url_place_caret( gw, tb->url.selection_len, false );
} else {
strcpy(&tb->url.text[tb->url.caret_pos], &tb->url.text[tb->url.caret_pos+tb->url.selection_len]);
}
tb->url.used = strlen( tb->url.text ) + 1;
} else {
tb->url.text[tb->url.caret_pos-1] = 0;
tb->url.used--;
strcat(tb->url.text, &tb->url.text[tb->url.caret_pos]);
tb_url_place_caret( gw , -1, false );
}
tb->url.selection_len = 0;
}
else if( code == NK_ESC ) {
tb->url.text[0] = 0;
tb->url.scrollx = 0;
tb->url.used = 1;
tb_url_place_caret( gw, 0, true );
}
else if( code == NK_CLRHOME ) {
tb_url_place_caret( gw, 0, true );
}
else if( code == NK_M_END ) {
tb_url_place_caret( gw,
strlen((char*)&tb->url.text)-1,
true
);
}
else if( code == NK_ENTER || code == NK_RET ) {
tb_url_place_caret( gw, 0, true );
else if( ik == KEY_CR || ik == KEY_NL ){
char tmp_url[PATH_MAX];
if( textarea_get_text( tb->url.textarea, tmp_url, PATH_MAX) > 0 ) {
window_set_focus( gw, BROWSER, gw->browser->bw);
browser_window_go(gw->browser->bw, (const char*)tb->url.text, 0, true);
}
else if( code > 30 ) {
if( tb->url.used+1 > tb->url.allocated ){
newsize = ( (tb->url.used+1) / (URL_WIDGET_BSIZE-1))+1;
newtext = realloc(tb->url.text, newsize*URL_WIDGET_BSIZE );
if(newtext) {
tb->url.text = newtext;
tb->url.allocated = newsize * URL_WIDGET_BSIZE;
browser_window_go(gw->browser->bw, (const char*)&tmp_url, 0, true);
ret = true;
}
}
i = tb->url.caret_pos;
backup = tb->url.text[tb->url.caret_pos];
while( i < tb->url.allocated - 1) {
tb->url.text[i] = code;
if( tb->url.text[i] == (char)0 )
break;
code = backup;
i++;
backup = tb->url.text[i];
else {
ret = textarea_keypress( tb->url.textarea, ik );
}
tb->url.used++;
tb->url.text[tb->url.allocated-1] = 0;
tb_url_place_caret( gw, +1, false );
tb->url.selection_len = 0;
} else {
ret = false;
}
if(tb->url.used < 1)
tb->url.used = 1; /* at least one byte (0) is used */
mt_CompGetLGrect(&app, tb->url.comp, WF_WORKXYWH, &work);
ApplWrite( _AESapid, WM_REDRAW, gw->root->handle->handle,
work.g_x, work.g_y, work.g_w, work.g_h );
return( ret );
}

View File

@ -19,6 +19,10 @@
#ifndef NS_ATARI_TOOLBAR_H
#define NS_ATARI_TOOLBAR_H
#include "desktop/textarea.h"
#include "desktop/textinput.h"
#include "atari/browser.h"
#define TB_BUTTON_WIDTH 32
#define TB_BUTTON_HEIGHT 21 /* includes 1px 3d effect */
#define TOOLBAR_HEIGHT 25
@ -27,13 +31,13 @@
#define THROBBER_MAX_INDEX 12
#define THROBBER_INACTIVE_INDEX 13
#define URLBOX_HEIGHT 21
/*
URL Widget Block size: size of memory block to allocated
when input takes more memory than currently allocated:
*/
#define URL_WIDGET_BSIZE 64
#define URL_WIDGET_MAX_MEM 60000
#define TOOLBAR_URL_TEXT_SIZE_PT 14
#define TOOLBAR_TEXTAREA_HEIGHT 19
#define TOOLBAR_URL_MARGIN_LEFT 2
#define TOOLBAR_URL_MARGIN_RIGHT 2
#define TOOLBAR_URL_MARGIN_TOP 2
#define TOOLBAR_URL_MARGIN_BOTTOM 2
struct s_tb_button
{
short rsc_id;
@ -44,15 +48,10 @@ struct s_tb_button
struct s_url_widget
{
short selection_len; /* len & direction of selection */
short caret_pos; /* cursor pos */
short char_size; /* size of one character (width & hight) */
short scrollx; /* current scroll position */
bool redraw; /* widget is only redrawn when this flag is set */
char * text; /* dynamicall allocated URL string */
unsigned short allocated;
unsigned short used; /* memory used by URL (strlen + 1) */
struct text_area *textarea;
COMPONENT * comp;
GRECT rdw_area;
};
struct s_throbber_widget
@ -69,7 +68,8 @@ struct s_toolbar
struct gui_window * owner;
struct s_url_widget url;
struct s_throbber_widget throbber;
GRECT btdim; /* size & location of buttons */
GRECT btdim;
/* size & location of buttons: */
struct s_tb_button * buttons;
int btcnt;
};
@ -82,6 +82,8 @@ static void __CDECL evnt_toolbar_redraw( COMPONENT *c, long buff[8], void *data
//static void __CDECL evnt_toolbar_mbutton( COMPONENT *c, long buff[8], void *data );
static void __CDECL evnt_toolbar_resize( COMPONENT *c, long buff[8], void *data );
/* recalculate size/position of nested controls within the toolbar: */
void tb_adjust_size( struct gui_window * gw );
/* report click to toolbar, relative coords : */
void tb_click( struct gui_window * gw, short mx, short my, short mb, short kstat );
void tb_back_click( struct gui_window * gw );
@ -96,10 +98,10 @@ void tb_update_buttons( struct gui_window * gw );
void tb_url_click( struct gui_window * gw, short mx, short my, short mb, short kstat );
/* handle keybd event while url widget has focus:*/
bool tb_url_input( struct gui_window * gw, short keycode );
/* place the caret and adjust scrolling position: */
void tb_url_place_caret( struct gui_window * gw, int steps, bool abs);
/* set the url: */
void tb_url_set( struct gui_window * gw, char * text );
/* perform redraw of invalidated url textinput areas: */
void tb_url_redraw( struct gui_window * gw );
struct gui_window * tb_gui_window( CMP_TOOLBAR tb );

View File

@ -104,7 +104,9 @@ static void __CDECL evnt_tv_redraw( WINDOW *win, short buff[8], void * data )
clip.g_y = 0;
}
if( clip.g_h > 0 && clip.g_w > 0 ) {
atari_treeview_request_redraw( win->xpos*win->w_u + clip.g_x, win->ypos*win->h_u + clip.g_y,
atari_treeview_request_redraw(
win->xpos*win->w_u + clip.g_x,
win->ypos*win->h_u + clip.g_y,
clip.g_w, clip.g_h, tv
);
}