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 \ search.c font.c \
plot.c plot/plotter.c plot/plotter_vdi.c plot/eddi.s \ plot.c plot/plotter.c plot/plotter_vdi.c plot/eddi.s \
plot/font_vdi.c plot/font_freetype.c plot/font_internal.c \ 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 \ browser_win.c toolbar.c statusbar.c browser.c \
global_evnt.c osspec.c dragdrop.c system_colour.c \ global_evnt.c osspec.c dragdrop.c system_colour.c \
ctxmenu.c ctxmenu.c

View File

@ -49,12 +49,13 @@
#include "atari/browser_win.h" #include "atari/browser_win.h"
#include "atari/misc.h" #include "atari/misc.h"
#include "atari/global_evnt.h" #include "atari/global_evnt.h"
#include "atari/res/netsurf.rsh" #include "atari/res/netsurf.rsh"
#include "atari/redrawslots.h"
#include "atari/browser.h" #include "atari/browser.h"
#include "atari/plot/plotter.h" #include "atari/plot/plotter.h"
#include "atari/plot.h" #include "atari/plot.h"
#include "atari/font.h" #include "atari/encoding.h"
#include "atari/ctxmenu.h" #include "atari/ctxmenu.h"
#include "cflib.h" #include "cflib.h"
extern browser_mouse_state bmstate; extern browser_mouse_state bmstate;
@ -63,13 +64,20 @@ extern int mouse_hold_start[3];
extern GEM_PLOTTER plotter; extern GEM_PLOTTER plotter;
extern struct gui_window *input_window; extern struct gui_window *input_window;
extern short last_drag_x; extern short last_drag_x;
extern short last_drag_y; 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);
/* /*
Create an browser component. Create an browser component.
@ -97,8 +105,8 @@ struct s_browser * browser_create
if(clone) if(clone)
bw->scale = clone->scale; bw->scale = clone->scale;
else else
bw->scale = 1; 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); bnew->comp = (COMPONENT*)mt_CompCreate(&app, CLT_HORIZONTAL, 100, 1);
if( bnew->comp == NULL ) { if( bnew->comp == NULL ) {
free(bnew); free(bnew);
@ -114,6 +122,9 @@ struct s_browser * browser_create
); );
mt_CompEvntDataAttach( &app, bnew->comp, WM_DESTROY, mt_CompEvntDataAttach( &app, bnew->comp, WM_DESTROY,
browser_evnt_destroy, (void*)bnew browser_evnt_destroy, (void*)bnew
);
mt_CompEvntDataAttach( &app, bnew->comp, WM_SIZED,
browser_evnt_resize, (void*)gw
); );
/* Set the gui_window owner. */ /* Set the gui_window owner. */
@ -124,6 +135,7 @@ struct s_browser * browser_create
bnew->scroll.requested.x = 0; bnew->scroll.requested.x = 0;
bnew->scroll.current.x = 0; bnew->scroll.current.x = 0;
bnew->scroll.current.y = 0; bnew->scroll.current.y = 0;
bnew->reformat_pending = false;
} }
return( bnew ); return( bnew );
@ -170,12 +182,12 @@ void browser_get_rect( struct gui_window * gw, enum browser_rect type, LGRECT *
void browser_update_rects(struct gui_window * gw ) void browser_update_rects(struct gui_window * gw )
{ {
short buff[8]; short buff[8];
LGRECT cmprect; LGRECT cmprect;
mt_WindGetGrect( &app, gw->root->handle, WF_CURRXYWH, (GRECT*)&buff[4]); mt_WindGetGrect( &app, gw->root->handle, WF_CURRXYWH, (GRECT*)&buff[4]);
buff[0] = CM_REFLOW; buff[0] = CM_REFLOW;
buff[1] = _AESapid; buff[1] = _AESapid;
buff[2] = 0; buff[2] = 0;
EvntExec(gw->root->handle, buff); EvntExec(gw->root->handle, buff);
} }
void browser_set_content_size(struct gui_window * gw, int w, int h) void browser_set_content_size(struct gui_window * gw, int w, int h)
@ -194,6 +206,13 @@ void browser_set_content_size(struct gui_window * gw, int w, int h)
/* force update of scrollbars: */ /* force update of scrollbars: */
b->scroll.required = true; b->scroll.required = true;
} }
}
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) static void __CDECL browser_evnt_destroy( COMPONENT * c, long buff[8], void * data)
@ -419,7 +438,7 @@ static void browser_process_scroll( struct gui_window * gw, LGRECT bwrect )
dst.g_h = src.g_h; dst.g_h = src.g_h;
plotter->copy_rect( plotter, src, dst ); plotter->copy_rect( plotter, src, dst );
b->scroll.current.y += b->scroll.requested.y; b->scroll.current.y += b->scroll.requested.y;
browser_schedule_redraw( gw, 0, 0, bwrect.g_w, h ) ; browser_schedule_redraw( gw, 0, 0, bwrect.g_w, h );
} }
if( b->scroll.requested.y > 0 ) { if( b->scroll.requested.y > 0 ) {
@ -467,7 +486,10 @@ static void browser_process_scroll( struct gui_window * gw, LGRECT bwrect )
browser_schedule_redraw( gw, bwrect.g_w - w, 0, bwrect.g_w, bwrect.g_h ); browser_schedule_redraw( gw, bwrect.g_w - w, 0, bwrect.g_w, bwrect.g_h );
} }
b->scroll.requested.y = 0; b->scroll.requested.y = 0;
b->scroll.requested.x = 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->xpos = b->scroll.current.x;
gw->root->handle->ypos = b->scroll.current.y; 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. 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: parameter:
- gui_window ( compocnent owner ). - gui_window ( compocnent owner ).
- unsigned short nkc ( CFLIB normalised key code ) - unsigned short nkc ( CFLIB normalised key code )
@ -487,154 +509,58 @@ bool browser_input( struct gui_window * gw, unsigned short nkc )
LGRECT work; LGRECT work;
bool r = false; bool r = false;
unsigned char ascii = (nkc & 0xFF); unsigned char ascii = (nkc & 0xFF);
nkc = (nkc & (NKF_CTRL|NKF_SHIFT|0xFF)); long ucs4;
browser_get_rect(gw, BR_CONTENT, &work); long ik = nkc_to_input_key( nkc, &ucs4 );
if( (nkc & NKF_CTRL) != 0 ) { // pass event to specific control?
switch ( ascii ) {
case 'A': if( ik == 0 ){
r = browser_window_key_press(gw->browser->bw, KEY_SELECT_ALL);
break;
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 (ascii >= 9 ) { if (ascii >= 9 ) {
int ucs4 = atari_to_ucs4(ascii);
r = browser_window_key_press(gw->browser->bw, ucs4 ); 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 ); return( r );
} }
@ -645,11 +571,15 @@ bool browser_redraw_required( struct gui_window * gw)
CMP_BROWSER b = gw->browser; CMP_BROWSER b = gw->browser;
if( b->bw->current_content == NULL ) if( b->bw->current_content == NULL )
return ( false ); 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) ) ret = ( ((b->redraw.areas_used > 0) )
|| b->scroll.required || b->scroll.required
|| b->caret.redraw ); || b->caret.redraw);
return( ret ); return( ret );
} }
@ -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 ); 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 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 ) if( y0 > work.g_h )
return; return;
area.x0 = x0; redraw_slot_schedule( &b->redraw, x0, y0, x1, y1 );
area.y0 = y0;
area.x1 = x1;
area.y1 = 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; 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; LGRECT work;
CMP_BROWSER b = gw->browser; CMP_BROWSER b = gw->browser;
@ -760,44 +637,104 @@ static void browser_redraw_content( struct gui_window * gw, int xoff, int yoff )
.plot = &atari_plotters .plot = &atari_plotters
}; };
LOG(("%s : %d,%d - %d,%d\n", b->bw->name, b->redraw.area.x0, LOG(("%s : %d,%d - %d,%d\n", b->bw->name, area->x0,
b->redraw.area.y0, b->redraw.area.x1, b->redraw.area.y1 area->y0, area->x1, area->y1
)); ));
browser_window_redraw( b->bw, -b->scroll.current.x, 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)
{
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 )
{ {
GRECT caret; // TODO: only redraw caret when window is topped.
struct s_browser * b = gw->browser; if( gw->browser->caret.redraw && gw->browser->caret.requested.g_w > 0 ){
if( b->caret.redraw == true ){ LGRECT caret;
struct s_browser * b = gw->browser;
struct rect old_clip; struct rect old_clip;
struct rect 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 = b->caret.requested;
caret.g_x -= gw->browser->scroll.current.x; caret.g_x -= b->scroll.current.x - area->g_x;
caret.g_y -= gw->browser->scroll.current.y; caret.g_y -= b->scroll.current.y - area->g_y;
clip.x0 = caret.g_x - 1;
clip.y0 = caret.g_y - 1; if( !rc_lintersect( area, &caret ) ) {
clip.x1 = caret.g_x + caret.g_w + 1; return;
clip.y1 = caret.g_y + caret.g_h + 1; }
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: */ /* store old clip before adjusting it: */
plot_get_clip( &old_clip ); plot_get_clip( &old_clip );
/* clip to cursor: */ /* clip to cursor: */
plot_clip( &clip ); plot_clip( &clip );
plot_rectangle( caret.g_x, caret.g_y, plot_line( caret.g_x, caret.g_y, caret.g_x, caret.g_y + caret.g_h,
caret.g_x+caret.g_w, caret.g_y+caret.g_h, plot_style_caret );
plot_style_caret );
/* restore old clip area: */ /* restore old clip area: */
plot_clip( &old_clip ); plot_clip( &old_clip );
b->caret.current.g_x = caret.g_x + gw->browser->scroll.current.x; b->caret.current.g_x = caret.g_x + gw->browser->scroll.current.x;
b->caret.current.g_y = caret.g_y + gw->browser->scroll.current.y; b->caret.current.g_y = caret.g_y + gw->browser->scroll.current.y;
b->caret.current.g_w = caret.g_w; b->caret.current.g_w = caret.g_w;
b->caret.current.g_h = caret.g_h; b->caret.current.g_h = caret.g_h;
} }
} }
@ -807,13 +744,15 @@ void browser_redraw( struct gui_window * gw )
LGRECT bwrect; LGRECT bwrect;
struct s_browser * b = gw->browser; struct s_browser * b = gw->browser;
short todo[4]; short todo[4];
struct rect clip; struct rect clip;
/* used for clipping of content redraw: */
struct rect redraw_area;
if( b->attached == false || b->bw->current_content == NULL ) { if( b->attached == false || b->bw->current_content == NULL ) {
return; return;
} }
browser_get_rect(gw, BR_CONTENT, &bwrect); browser_get_rect(gw, BR_CONTENT, &bwrect);
plotter->resize(plotter, bwrect.g_w, bwrect.g_h); plotter->resize(plotter, bwrect.g_w, bwrect.g_h);
plotter->move(plotter, bwrect.g_x, bwrect.g_y ); plotter->move(plotter, bwrect.g_x, bwrect.g_y );
@ -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_w = b->redraw.areas[i].x1 - b->redraw.areas[i].x0;
area.g_h = b->redraw.areas[i].y1 - b->redraw.areas[i].y0; area.g_h = b->redraw.areas[i].y1 - b->redraw.areas[i].y0;
if (rc_intersect((GRECT *)&fbwork,(GRECT *)&area)) { if (rc_intersect((GRECT *)&fbwork,(GRECT *)&area)) {
b->redraw.area.x0 = area.g_x; redraw_area.x0 = area.g_x;
b->redraw.area.y0 = area.g_y; redraw_area.y0 = area.g_y;
b->redraw.area.x1 = area.g_x + area.g_w; redraw_area.x1 = area.g_x + area.g_w;
b->redraw.area.y1 = area.g_y + area.g_h; redraw_area.y1 = area.g_y + area.g_h;
browser_redraw_content( gw, 0, 0 ); browser_redraw_content( gw, 0, 0, &redraw_area );
} else { } else {
/* /*
the area should be kept scheduled for later redraw, but because this the area should be kept scheduled for later redraw, but because this
@ -889,8 +828,8 @@ void browser_redraw( struct gui_window * gw )
} }
b->redraw.areas_used = 0; b->redraw.areas_used = 0;
} }
if( b->caret.redraw == true && b->bw->current_content != NULL ) { if( b->caret.redraw == true && b->bw->current_content != NULL ) {
GRECT area; LGRECT area;
todo[0] = bwrect.g_x; todo[0] = bwrect.g_x;
todo[1] = bwrect.g_y; todo[1] = bwrect.g_y;
todo[2] = todo[0] + bwrect.g_w; 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]; short pxy[8];
struct gui_window * gw = (struct gui_window *) data; struct gui_window * gw = (struct gui_window *) data;
CMP_BROWSER b = gw->browser; 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 ); browser_get_rect( gw, BR_CONTENT, &work );
lclip = work; lclip = work;
if ( !rc_lintersect( (LGRECT*)&buff[4], &lclip ) ) return; if ( !rc_lintersect( (LGRECT*)&buff[4], &lclip ) ) return;
@ -953,12 +885,23 @@ static void __CDECL browser_evnt_redraw( COMPONENT * c, long buff[8], void * dat
lclip.g_h = work.g_h + lclip.g_y; lclip.g_h = work.g_h + lclip.g_y;
lclip.g_y = 0; lclip.g_y = 0;
} }
if( lclip.g_h > 0 && lclip.g_w > 0 ) { if( lclip.g_h > 0 && lclip.g_w > 0 ) {
browser_schedule_redraw( gw, lclip.g_x, lclip.g_y,
lclip.g_x + lclip.g_w, lclip.g_y + lclip.g_h 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; return;

View File

@ -17,7 +17,9 @@
*/ */
#ifndef NS_ATARI_BROWSER_H #ifndef NS_ATARI_BROWSER_H
#define 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, Each browser_window in the Atari Port is represented by an struct s_browser,
@ -30,13 +32,6 @@
*/ */
#define BROWSER_SCROLL_SVAL 64 #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 enum browser_rect
{ {
@ -65,21 +60,10 @@ struct s_scroll_info
*/ */
struct s_caret struct s_caret
{ {
GRECT requested; LGRECT requested;
GRECT current; LGRECT current;
bool redraw; bool redraw;
}; MFDB background;
/*
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;
}; };
/* /*
@ -99,9 +83,10 @@ struct s_browser
COMPONENT * comp; COMPONENT * comp;
struct browser_window * bw; struct browser_window * bw;
struct s_scroll_info scroll; struct s_scroll_info scroll;
struct s_browser_redrw_info redraw; struct s_redrw_slots redraw;
struct s_caret caret; struct s_caret caret;
bool attached; 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 ); 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 ); void browser_scroll( struct gui_window * gw, short MODE, int value, bool abs );
struct gui_window * browser_find_root( struct gui_window * gw ); struct gui_window * browser_find_root( struct gui_window * gw );
bool browser_redraw_required( 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. This queues an redraw to one of the slots.
The following strategy is used: 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 4. if no slot is available, it will simply merge the new rectangle with
the last available slot. 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_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 ); 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 #endif

View File

@ -67,7 +67,27 @@ extern short last_drag_x;
extern short last_drag_y; extern short last_drag_y;
void __CDECL std_szd( WINDOW * win, short buff[8], void * ); void __CDECL std_szd( WINDOW * win, short buff[8], void * );
void __CDECL std_mvd( 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: */ /* Module public functions: */
@ -259,7 +279,8 @@ int window_destroy( struct gui_window * gw)
/* needed? */ /*listRemove( (LINKABLE*)gw->root->cmproot ); */ /* needed? */ /*listRemove( (LINKABLE*)gw->root->cmproot ); */
if( gw->root ) { if( gw->root ) {
/* TODO: check if no other browser is bound to this root window! */ /* TODO: check if no other browser is bound to this root window! */
/* only needed for tabs */
if( gw->root->title ) if( gw->root->title )
free( gw->root->title ); free( gw->root->title );
if( gw->root->cmproot ) if( gw->root->cmproot )
@ -289,7 +310,7 @@ void window_open( struct gui_window * gw)
mt_CompEvntExec( gl_appvar, gw->browser->comp, lfbuff ); mt_CompEvntExec( gl_appvar, gw->browser->comp, lfbuff );
/* recompute the nested component sizes and positions: */ /* recompute the nested component sizes and positions: */
browser_update_rects( gw ); browser_update_rects( gw );
mt_WindGetGrect( &app, gw->root->handle, WF_CURRXYWH, (GRECT*)&gw->root->loc); mt_WindGetGrect( &app, gw->root->handle, WF_CURRXYWH, (GRECT*)&gw->root->loc);
browser_get_rect( gw, BR_CONTENT, &br ); browser_get_rect( gw, BR_CONTENT, &br );
plotter->move( plotter, br.g_x, br.g_y ); plotter->move( plotter, br.g_x, br.g_y );
@ -298,6 +319,7 @@ void window_open( struct gui_window * gw)
if( gw->root->statusbar != NULL ){ if( gw->root->statusbar != NULL ){
gw->root->statusbar->attached = true; gw->root->statusbar->attached = true;
} }
tb_adjust_size( gw );
/*TBD: get already present content and set size? */ /*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) ); return( ( element == gw->root->focus.element && t == gw->root->focus.type) );
} }
/* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */
/* Event Handlers: */ /* Event Handlers: */
/* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */
@ -390,7 +413,8 @@ static void __CDECL evnt_window_arrowed( WINDOW *win, short buff[8], void *data
break; break;
} }
browser_scroll( input_window, buff[4], value, abs ); browser_scroll( input_window, buff[4], value, abs );
} }
static void __CDECL evnt_window_dd( WINDOW *win, short wbuff[8], void * data ) static void __CDECL evnt_window_dd( WINDOW *win, short wbuff[8], void * data )
{ {
@ -516,7 +540,6 @@ static void __CDECL evnt_window_m1( WINDOW * win, short buff[8], void * data)
{ {
struct gui_window * gw = input_window; struct gui_window * gw = input_window;
static bool prev_url = false; static bool prev_url = false;
static bool prev_sb = false;
short mx, my, mbut, mkstate; short mx, my, mbut, mkstate;
bool a = false; //flags if mouse is within controls or browser bool a = false; //flags if mouse is within controls or browser
bool within = false; bool within = false;
@ -555,21 +578,10 @@ static void __CDECL evnt_window_m1( WINDOW * win, short buff[8], void * data)
prev_url = a = true; 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( !a ) {
if( prev_sb ) if( prev_url ) {
gw->root->statusbar->resize_init = true;
if( prev_url || prev_sb ) {
gem_set_cursor( &gem_cursors.arrow ); gem_set_cursor( &gem_cursors.arrow );
prev_url = false; prev_url = false;
prev_sb = false;
} }
/* report mouse move in the browser window */ /* report mouse move in the browser window */
if( within ){ if( within ){
@ -632,14 +644,15 @@ static void __CDECL evnt_window_slider( WINDOW * win, short buff[8], void * data
int dy = buff[5]; int dy = buff[5];
GRECT work, screen; GRECT work, screen;
struct gui_window * gw = data; struct gui_window * gw = data;
if (!dx && !dy) return; if (!dx && !dy) return;
if( input_window == NULL || input_window != gw ) { if( input_window == NULL || input_window != gw ) {
return; 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) ); WindSlider( win, (dx?HSLIDER:0) | (dy?VSLIDER:0) );
if( dy > 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 ); browser_scroll( gw, WA_RTPAGE, abs(dx), false );
else if( dx < 0 ) else if( dx < 0 )
browser_scroll( gw, WA_LFPAGE, abs(dx), false ); browser_scroll( gw, WA_LFPAGE, abs(dx), false );
} }
@ -707,7 +722,7 @@ static void __CDECL evnt_window_move( WINDOW *win, short buff[8], void * data )
void __CDECL evnt_window_resize( WINDOW *win, short buff[8], void * data ) void __CDECL evnt_window_resize( WINDOW *win, short buff[8], void * data )
{ {
short wx, wy, wh, ww, nw, nh; short wx, wy, wh, ww, nw, nh;
short r; short r;
wind_get( win->handle, WF_CURRXYWH, &wx, &wy, &ww, &wh ); wind_get( win->handle, WF_CURRXYWH, &wx, &wy, &ww, &wh );
r = graf_rubberbox(wx, wy, 20, 20, &nw, &nh); r = graf_rubberbox(wx, wy, 20, 20, &nw, &nh);
@ -726,8 +741,8 @@ static void __CDECL evnt_window_rt_resize( WINDOW *win, short buff[8], void * da
{ {
short x,y,w,h; short x,y,w,h;
struct gui_window * gw; struct gui_window * gw;
LGRECT rect; LGRECT rect;
if(buff[0] == WM_FORCE_MOVE ) { if(buff[0] == WM_FORCE_MOVE ) {
std_mvd(win, buff, &app); std_mvd(win, buff, &app);
std_szd(win, buff, &app); std_szd(win, buff, &app);
@ -736,30 +751,28 @@ static void __CDECL evnt_window_rt_resize( WINDOW *win, short buff[8], void * da
wind_get( win->handle, WF_CURRXYWH, &x, &y, &w, &h ); wind_get( win->handle, WF_CURRXYWH, &x, &y, &w, &h );
gw = (struct gui_window *)data; gw = (struct gui_window *)data;
assert( gw != NULL ); assert( gw != NULL );
if(gw->root->loc.g_w != w || gw->root->loc.g_h != h ){ if(gw->root->loc.g_w != w || gw->root->loc.g_h != h ){
/* report resize to component interface: */ /* report resize to component interface: */
browser_update_rects( gw ); browser_update_rects( gw );
mt_WindGetGrect( &app, gw->root->handle, WF_CURRXYWH, (GRECT*)&gw->root->loc); tb_adjust_size( gw );
browser_get_rect( gw, BR_CONTENT, &rect ); if( gw->browser->bw->current_content != NULL ){
if( gw->browser->bw->current_content != NULL ) /* Reformat will happen when next redraw message arrives: */
browser_window_reformat(gw->browser->bw, false, rect.g_w, rect.g_h ); gw->browser->reformat_pending = true;
else if( sys_XAAES() ){
WindClear( gw->root->handle ); if( gw->root->loc.g_w > w || gw->root->loc.g_h > h ){
gw->root->toolbar->url.scrollx = 0; ApplWrite( _AESapid, WM_REDRAW, gw->root->handle->handle,
gw->root->loc.g_x, gw->root->loc.g_y,
/* send complete redraw to toolbar & statusbar: */ gw->root->loc.g_w, gw->root->loc.g_h );
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_WindGetGrect( &app, gw->root->handle, WF_CURRXYWH,
); (GRECT*)&gw->root->loc);
mt_CompGetLGrect(&app, gw->root->statusbar->comp, WF_WORKXYWH, &rect); }
ApplWrite( _AESapid, WM_REDRAW, gw->root->handle->handle, else {
rect.g_x, rect.g_y, rect.g_w, rect.g_h WindClear( gw->root->handle );
); }
/* TODO: recalculate scroll position, instead of zeroing? */
} else { } else {
if(gw->root->loc.g_x != x || gw->root->loc.g_y != y ){ 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); 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: */ /* 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 #endif

View File

@ -96,7 +96,7 @@ static struct s_context_info * get_context_info( struct gui_window * gw, short m
memset( &ctxinfo.ccdata, sizeof(struct contextual_content), 0 ); memset( &ctxinfo.ccdata, sizeof(struct contextual_content), 0 );
browser_window_get_contextual_content( browser_window_get_contextual_content(
gw->browser->bw, gw->browser->bw,
mx+gw->browser->scroll.current.x, mx+gw->browser->scroll.current.x,
my+gw->browser->scroll.current.y, my+gw->browser->scroll.current.y,
(struct contextual_content*)&ctxinfo.ccdata (struct contextual_content*)&ctxinfo.ccdata
); );
@ -149,7 +149,8 @@ void context_popup( struct gui_window * gw, short x, short y )
char * data; char * data;
FILE * fp_tmpfile; FILE * fp_tmpfile;
char * tempfile; char * tempfile;
int err = 0; int err = 0;
char cmdline[128];
pop = get_tree( POP_CTX ); pop = get_tree( POP_CTX );
if( pop == NULL ) if( pop == NULL )
@ -251,11 +252,18 @@ void context_popup( struct gui_window * gw, short x, short y )
fp_tmpfile = fopen( tempfile, "w" ); fp_tmpfile = fopen( tempfile, "w" );
if( fp_tmpfile ){ if( fp_tmpfile ){
fwrite( data, size, 1, fp_tmpfile ); fwrite( data, size, 1, fp_tmpfile );
fclose( 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 )); LOG(("launched: %s %s (%d)\n", option_atari_editor, tempfile, err ));
} }
} }
} else {
LOG(("Please set option_atari_editor!"));
} }
break; 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 <stdbool.h>
#include <windom.h> #include <windom.h>
/*
#include <ft2build.h>
#include FT_CACHE_H
*/
#include "css/css.h" #include "css/css.h"
#include "render/font.h" #include "render/font.h"
#include "utils/utf8.h" #include "utils/utf8.h"
@ -45,68 +40,21 @@
extern GEM_FONT_PLOTTER fplotter; extern GEM_FONT_PLOTTER fplotter;
/* TODO: this need a rework..., encoding to atari st doesn|t always work. ( gui_add_to_clipboard...) */ static bool atari_font_position_in_string(const plot_font_style_t * fstyle,const char *string,
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 ) size_t length,int x, size_t *char_offset, int *actual_x )
{ {
fplotter->pixel_pos(fplotter, fstyle, string, length, x, char_offset, actual_x ); fplotter->pixel_pos(fplotter, fstyle, string, length, x, char_offset, actual_x );
return( true ); return( true );
} }
static bool atari_font_split( const plot_font_style_t * fstyle, const char *string, static bool atari_font_split( const plot_font_style_t * fstyle, const char *string,
size_t length,int x, size_t *char_offset, int *actual_x ) size_t length,int x, size_t *char_offset, int *actual_x )
{ {
fplotter->str_split( fplotter, fstyle, string, length, x, char_offset, actual_x ); fplotter->str_split( fplotter, fstyle, string, length, x, char_offset, actual_x );
return( true ); return( true );
} }
static bool atari_font_width( const plot_font_style_t *fstyle, const char * str, static bool atari_font_width( const plot_font_style_t *fstyle, const char * str,
size_t length, int * width ) size_t length, int * width )
{ {
fplotter->str_width( fplotter, fstyle, str, length, width ); fplotter->str_width( fplotter, fstyle, str, length, width );

View File

@ -16,16 +16,10 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef NS_ATARI_FT_FONT_H #ifndef NS_ATARI_FONT_H
#define NS_ATARI_FT_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 */ #endif /* NETSURF_FB_FONT_H */

View File

@ -68,7 +68,7 @@
#include "atari/hotlist.h" #include "atari/hotlist.h"
#include "atari/login.h" #include "atari/login.h"
#include "atari/global_evnt.h" #include "atari/global_evnt.h"
#include "atari/font.h" #include "atari/encoding.h"
#include "atari/res/netsurf.rsh" #include "atari/res/netsurf.rsh"
#include "atari/plot.h" #include "atari/plot.h"
#include "atari/clipboard.h" #include "atari/clipboard.h"
@ -171,11 +171,16 @@ void gui_poll(bool active)
for( g = window_list; g != NULL; g=g->next ) { for( g = window_list; g != NULL; g=g->next ) {
if( browser_redraw_required( g ) ){ if( browser_redraw_required( g ) ){
browser_redraw( g ); browser_redraw( g );
}
if( g->root->toolbar ){
if(g->root->toolbar->url.redraw ){
tb_url_redraw( g );
}
} }
} }
if( evnt.timer != 0 && !active ){ if( evnt.timer != 0 && !active ){
/* this suits for stuff with lower priority */ /* this suits for stuff with lower priority */
//hotlist_redraw(); /* TBD: really be spare on redraws??? */
atari_treeview_redraw( hl.tv ); atari_treeview_redraw( hl.tv );
} }
} }
@ -310,7 +315,7 @@ void gui_window_redraw_window(struct gui_window *gw)
if (gw == NULL) if (gw == NULL)
return; return;
b = gw->browser; b = gw->browser;
browser_get_rect( gw, BR_CONTENT, &rect ); browser_get_rect( gw, BR_CONTENT, &rect );
browser_schedule_redraw( gw, 0, 0, rect.g_w, rect.g_h ); browser_schedule_redraw( gw, 0, 0, rect.g_w, rect.g_h );
} }
@ -326,7 +331,7 @@ void gui_window_update_box(struct gui_window *gw, const struct rect *rect)
int y0 = rect->y0 - b->scroll.current.y; int y0 = rect->y0 - b->scroll.current.y;
int w,h; int w,h;
w = rect->x1 - rect->x0; w = rect->x1 - rect->x0;
h = rect->y1 - rect->y0; h = rect->y1 - rect->y0;
browser_schedule_redraw_rect( gw, x0, y0, w,h); browser_schedule_redraw_rect( gw, x0, y0, w,h);
} }
@ -367,7 +372,7 @@ void gui_window_set_scroll(struct gui_window *w, int sx, int sy)
void gui_window_scroll_visible(struct gui_window *w, int x0, int y0, int x1, int y1) void gui_window_scroll_visible(struct gui_window *w, int x0, int y0, int x1, int y1)
{ {
LOG(("%s:(%p, %d, %d, %d, %d)", __func__, w, x0, y0, x1, y1)); LOG(("%s:(%p, %d, %d, %d, %d)", __func__, w, x0, y0, x1, y1));
gui_window_set_scroll(w,x0,y0); gui_window_set_scroll(w,x0,y0);
browser_schedule_redraw_rect( w, 0, 0, x1-x0,y1-y0); browser_schedule_redraw_rect( w, 0, 0, x1-x0,y1-y0);
} }
@ -530,7 +535,7 @@ void gui_window_stop_throbber(struct gui_window *w)
work.g_x, work.g_y, work.g_w, work.g_h ); work.g_x, work.g_y, work.g_w, work.g_h );
} }
/* Place caret in window */ /* Place caret in window */
void gui_window_place_caret(struct gui_window *w, int x, int y, int height) void gui_window_place_caret(struct gui_window *w, int x, int y, int height)
{ {
LGRECT work; LGRECT work;
@ -540,46 +545,37 @@ void gui_window_place_caret(struct gui_window *w, int x, int y, int height)
if( w->browser->caret.current.g_w > 0 ) if( w->browser->caret.current.g_w > 0 )
gui_window_remove_caret( w ); gui_window_remove_caret( w );
w->browser->caret.requested.g_x = x; w->browser->caret.requested.g_x = x;
w->browser->caret.requested.g_y = y; 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.requested.g_h = height;
w->browser->caret.redraw = true; 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; return;
} }
/** /**
* clear window caret * clear window caret
*/ */
void void
gui_window_remove_caret(struct gui_window *w) gui_window_remove_caret(struct gui_window *w)
{ {
LGRECT rect;
if (w == NULL) if (w == NULL)
return; return;
CMP_BROWSER b = w->browser; CMP_BROWSER b = w->browser;
w->browser->caret.requested.g_w = 0;
w->browser->caret.redraw = true; if( w->browser->caret.background.fd_addr != NULL ){
browser_schedule_redraw_rect( w, browser_restore_caret_background( w, NULL );
w->browser->caret.current.g_x - b->scroll.current.x, w->browser->caret.requested.g_w = 0;
w->browser->caret.current.g_y - b->scroll.current.y, w->browser->caret.current.g_w = 0;
w->browser->caret.current.g_w, }
w->browser->caret.current.g_h return;
);
} }
void void
gui_window_set_icon(struct gui_window *g, hlcache_handle *icon) 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; g->icon = (icon != NULL) ? content_get_bitmap(icon) : NULL;
} }
void void
@ -871,8 +867,6 @@ void gui_quit(void)
hotlist_destroy(); hotlist_destroy();
/* send WM_DESTROY to windows purely managed by windom: */
urldb_save_cookies(option_cookie_file); urldb_save_cookies(option_cookie_file);
urldb_save(option_url_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 ); atari_plotter_init( option_atari_screen_driver, option_atari_font_driver );
LOG(("Knockout rendering: %s\n", option_atari_knockout ? "yes" : "no")); LOG(("Knockout rendering: %s\n", option_atari_knockout ? "yes" : "no"));
plot_set_knockout( option_atari_knockout ); 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"; static char *theapp = (char*)"NetSurf";

View File

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

View File

@ -31,6 +31,7 @@ int atari_plotter_finalise( void );
void plot_set_knockout( int set ); void plot_set_knockout( int set );
bool plot_get_clip(struct rect * out); bool plot_get_clip(struct rect * out);
bool plot_clip(const struct rect *clip); 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_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 #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

@ -33,7 +33,8 @@
#include "desktop/history_core.h" #include "desktop/history_core.h"
#include "desktop/netsurf.h" #include "desktop/netsurf.h"
#include "desktop/browser.h" #include "desktop/browser.h"
#include "desktop/mouse.h" #include "desktop/mouse.h"
#include "desktop/plot_style.h"
#include "desktop/plotters.h" #include "desktop/plotters.h"
#include "atari/clipboard.h" #include "atari/clipboard.h"
#include "atari/gui.h" #include "atari/gui.h"
@ -43,13 +44,26 @@
#include "atari/clipboard.h" #include "atari/clipboard.h"
#include "atari/misc.h" #include "atari/misc.h"
#include "atari/global_evnt.h" #include "atari/global_evnt.h"
#include "atari/plot.h"
#include "cflib.h" #include "cflib.h"
#include "atari/res/netsurf.rsh" #include "atari/res/netsurf.rsh"
#include "atari/plot/plotter.h" #include "atari/plot/plotter.h"
extern char * cfg_homepage_url; extern char * cfg_homepage_url;
extern short vdih; extern short vdih;
extern void * h_gem_rsrc; 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: */ /* prototypes & order for button widgets: */
static struct s_tb_button tb_buttons[] = static struct s_tb_button tb_buttons[] =
@ -60,10 +74,9 @@ static struct s_tb_button tb_buttons[] =
{ TOOLBAR_BT_RELOAD, tb_reload_click, NULL }, { TOOLBAR_BT_RELOAD, tb_reload_click, NULL },
{ TOOLBAR_BT_STOP, tb_stop_click, NULL }, { TOOLBAR_BT_STOP, tb_stop_click, NULL },
{ 0, NULL, NULL } { 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]) static void __CDECL button_redraw( COMPONENT *c, long buff[8])
{ {
@ -218,116 +231,67 @@ void __CDECL evnt_throbber_redraw( COMPONENT *c, long buff[8])
static static
void __CDECL evnt_url_redraw( COMPONENT *c, long buff[8] ) void __CDECL evnt_url_redraw( COMPONENT *c, long buff[8] )
{ {
LGRECT work, clip; LGRECT work, clip;
struct gui_window * gw;
short pxy[10]; short pxy[10];
short i; gw = (struct gui_window *)mt_CompDataSearch(&app, c, CDT_OWNER);
short d; if( gw == NULL )
short mchars; return;
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;
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; clip = work;
if ( !rc_lintersect( (LGRECT*)&buff[4], &clip ) ) return; if ( !rc_lintersect( (LGRECT*)&buff[4], &clip ) ) return;
pxy[0] = clip.g_x; pxy[0] = clip.g_x;
pxy[1] = clip.g_y; pxy[1] = clip.g_y;
pxy[2] = clip.g_w + clip.g_x; pxy[2] = clip.g_w + clip.g_x-1;
pxy[3] = clip.g_h + clip.g_y; pxy[3] = clip.g_h + clip.g_y-1;
vs_clip( vdih, 1, (short*)&pxy ); 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_perimeter( vdih, 0 );
vsf_interior( vdih , 1 ); vsf_interior( vdih , 1 );
vsf_color( vdih, LWHITE ); vsf_color( vdih, LWHITE );
vst_point( vdih, 10, &pxy[0], &pxy[1], &pxy[2], &pxy[3] );
vst_alignment(vdih, 0, 5, &d, &d ); //left margin:
vst_effects( vdih, 0 );
vst_color( vdih, BLACK );
/* gray the whole component: */
pxy[0] = work.g_x; pxy[0] = work.g_x;
pxy[1] = work.g_y; pxy[1] = work.g_y;
pxy[2] = work.g_x + work.g_w; pxy[2] = work.g_x + TOOLBAR_URL_MARGIN_LEFT-1;
pxy[3] = work.g_y + work.g_h-2; pxy[3] = work.g_y + work.g_h-1;
v_bar( vdih, (short*)&pxy ); v_bar( vdih, pxy );
/* draw outer line, left top: */ // right margin:
pxy[0] = work.g_x + 2; pxy[0] = work.g_x+work.g_w-TOOLBAR_URL_MARGIN_RIGHT;
pxy[1] = work.g_y + ((TOOLBAR_HEIGHT - URLBOX_HEIGHT)/2); pxy[1] = work.g_y;
/* right, top: */ pxy[2] = work.g_x+work.g_w-1;
pxy[2] = work.g_x + work.g_w - 4; pxy[3] = work.g_y+work.g_h-1;
pxy[3] = work.g_y + ((TOOLBAR_HEIGHT - URLBOX_HEIGHT)/2); v_bar( vdih, pxy );
/* right, bottom: */
pxy[4] = work.g_x + work.g_w - 4; // top margin:
pxy[5] = work.g_y + ((TOOLBAR_HEIGHT - URLBOX_HEIGHT)/2) + URLBOX_HEIGHT; pxy[0] = work.g_x;
/* left, bottom: */ pxy[1] = work.g_y;
pxy[6] = work.g_x + 2; pxy[2] = work.g_x+work.g_w-1;
pxy[7] = work.g_y + ((TOOLBAR_HEIGHT - URLBOX_HEIGHT)/2) + URLBOX_HEIGHT; pxy[3] = work.g_y+TOOLBAR_URL_MARGIN_TOP-1;
/* left, top again: */ v_bar( vdih, pxy );
pxy[8] = work.g_x + 2;
pxy[9] = work.g_y + ((TOOLBAR_HEIGHT - URLBOX_HEIGHT)/2); // bottom margin:
vsf_interior( vdih, FIS_SOLID ); pxy[0] = work.g_x;
vsf_style( vdih, 1); pxy[1] = work.g_y+work.g_h-TOOLBAR_URL_MARGIN_BOTTOM;
vsl_color( vdih, BLACK); pxy[2] = work.g_x+work.g_w-1;
v_pline( vdih, 5, pxy ); pxy[3] = work.g_y+work.g_h-1;
v_bar( vdih, pxy );
/* draw white txt box: */
pxy[0] = pxy[0] + 1; vs_clip( vdih, 0, (short*)&pxy );
pxy[1] = pxy[1] + ((TOOLBAR_HEIGHT - URLBOX_HEIGHT)/2) - 1;
pxy[2] = pxy[2] - 1; // TBD: request redraw of textarea for specific region.
pxy[3] = work.g_y + ((TOOLBAR_HEIGHT - URLBOX_HEIGHT)/2) + URLBOX_HEIGHT ; clip.g_x -= work.g_x+TOOLBAR_URL_MARGIN_LEFT;
vsf_color( vdih, WHITE); clip.g_y -= work.g_y+TOOLBAR_URL_MARGIN_TOP;
v_bar( vdih, pxy ); tb_txt_request_redraw( tb, clip.g_x, clip.g_y, clip.g_w, clip.g_h );
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);
v_bar( vdih, pxy );
vswr_mode( vdih, MD_REPLACE );
}
}
vs_clip( vdih, 0, (short*)&pxy );
} }
static static
@ -342,37 +306,45 @@ void __CDECL evnt_url_click( COMPONENT *c, long buff[8] )
assert( gw != NULL ); assert( gw != NULL );
CMP_TOOLBAR tb = gw->root->toolbar; CMP_TOOLBAR tb = gw->root->toolbar;
mt_CompGetLGrect(&app, c, WF_WORKXYWH, &work); mt_CompGetLGrect(&app, c, WF_WORKXYWH, &work);
mx = evnt.mx - work.g_x; mx = evnt.mx - (work.g_x + TOOLBAR_URL_MARGIN_LEFT);
my = evnt.my - work.g_y; my = evnt.my - (work.g_y + TOOLBAR_URL_MARGIN_TOP);
/* TODO: reset mouse state of browser window? */ /* TODO: reset mouse state of browser window? */
/* select whole text when newly focused, otherwise set caret to end of text */ /* select whole text when newly focused, otherwise set caret to end of text */
if( !window_url_widget_has_focus(gw) ) { if( !window_url_widget_has_focus(gw) ) {
tb_url_place_caret( gw, strlen(tb->url.text), true); // TODO select all ( needs textarea change )
tb->url.selection_len = -tb->url.caret_pos; window_set_focus( gw, URL_WIDGET, (void*)&tb->url );
window_set_focus( gw, URL_WIDGET, (void*)&tb->url ); textarea_mouse_action( tb->url.textarea, BROWSER_MOUSE_PRESS_1, mx, my );
} else { } else {
if( mb & 1 ) { if( mb & 1 ) {
/* if the button is dragging, place selection: */ /* TODO: if the button is dragging, report draw event */
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;
} else { } else {
/* TODO: recognize click + shift key */ /* TODO: recognize click + shift key */
tb->url.selection_len = 0; int mstate = BROWSER_MOUSE_PRESS_1;
tb_url_place_caret( gw, tb->url.scrollx + (mx / tb->url.char_size), true); 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, ApplWrite( _AESapid, WM_REDRAW, gw->root->handle->handle,
work.g_x, work.g_y, work.g_w, work.g_h ); 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 ) static void __CDECL evnt_toolbar_redraw( COMPONENT *c, long buff[8], void *data )
{ {
LGRECT work, clip; LGRECT work, clip;
@ -392,9 +364,112 @@ static void __CDECL evnt_toolbar_redraw( COMPONENT *c, long buff[8], void *data
pxy[1] = pxy[3] = work.g_y + work.g_h-1 ; pxy[1] = pxy[3] = work.g_y + work.g_h-1 ;
pxy[2] = clip.g_x + clip.g_w; pxy[2] = clip.g_x + clip.g_w;
v_pline( vdih, 2, (short*)&pxy ); v_pline( vdih, 2, (short*)&pxy );
}
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 ) CMP_TOOLBAR tb_create( struct gui_window * gw )
{ {
int i; int i;
@ -404,7 +479,7 @@ CMP_TOOLBAR tb_create( struct gui_window * gw )
if( t == NULL ) if( t == NULL )
return( NULL ); return( NULL );
t->owner = gw; t->owner = gw;
/* create the root component: */ /* create the root component: */
t->comp = (COMPONENT*)mt_CompCreate(&app, CLT_HORIZONTAL, TOOLBAR_HEIGHT, 0); t->comp = (COMPONENT*)mt_CompCreate(&app, CLT_HORIZONTAL, TOOLBAR_HEIGHT, 0);
@ -435,11 +510,13 @@ CMP_TOOLBAR tb_create( struct gui_window * gw )
} }
/* create the url widget: */ /* create the url widget: */
t->url.char_size = 8; t->url.textarea = textarea_create( 300, TOOLBAR_TEXTAREA_HEIGHT, 0,
t->url.text = malloc( 2*URL_WIDGET_BSIZE ); &font_style_url, tb_txt_request_redraw,
strcpy( t->url.text, "http://" ); t );
t->url.allocated = 2*URL_WIDGET_BSIZE; if( t->url.textarea != NULL ){
t->url.scrollx = 0; textarea_set_text(t->url.textarea, "http://");
}
t->url.comp = (COMPONENT*)mt_CompCreate(&app, CLT_HORIZONTAL, TOOLBAR_HEIGHT, 1); 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_REDRAW, evnt_url_redraw );
mt_CompEvntAttach( &app, t->url.comp, WM_XBUTTON, evnt_url_click ); mt_CompEvntAttach( &app, t->url.comp, WM_XBUTTON, evnt_url_click );
@ -475,9 +552,8 @@ void tb_destroy( CMP_TOOLBAR tb )
mt_ObjcFree( &app, (OBJECT*)mt_CompDataSearch(&app, tb->buttons[i].comp, CDT_OBJECT) ); mt_ObjcFree( &app, (OBJECT*)mt_CompDataSearch(&app, tb->buttons[i].comp, CDT_OBJECT) );
i++; i++;
} }
free( tb->buttons ); free( tb->buttons );
if( tb->url.text != NULL ) textarea_destroy( tb->url.textarea );
free( tb->url.text );
mt_CompDelete( &app, tb->comp); mt_CompDelete( &app, tb->comp);
free( tb ); 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; ((OBJECT*)mt_CompDataSearch(&app, bt->comp, CDT_OBJECT))->ob_state &= ~OS_DISABLED;
} }
mt_CompEvntRedraw( &app, bt->comp ); mt_CompEvntRedraw( &app, bt->comp );
} }
@ -553,69 +628,21 @@ void tb_url_set( struct gui_window * gw, char * text )
if( gw->browser->attached == false ) if( gw->browser->attached == false )
return; return;
struct s_url_widget * url = &gw->root->toolbar->url; struct s_url_widget * url = &gw->root->toolbar->url;
if( len+1 > url->allocated ) { assert( gw != NULL );
newsize = (len / (URL_WIDGET_BSIZE-1))+1; assert( gw->browser != NULL );
newtext = realloc( url->text, newsize*URL_WIDGET_BSIZE ); assert( gw->root != NULL );
if(newtext != NULL) { assert( gw->browser->bw != NULL );
url->text = newtext;
url->allocated = newsize * URL_WIDGET_BSIZE; textarea_set_text(url->textarea, text);
}
} mt_CompGetLGrect( &app, gw->root->toolbar->url.comp, WF_WORKXYWH, &work);
if( len+1 < url->allocated - URL_WIDGET_BSIZE work.g_w -= (TOOLBAR_URL_MARGIN_LEFT + TOOLBAR_URL_MARGIN_RIGHT);
&& url->allocated - URL_WIDGET_BSIZE > URL_WIDGET_BSIZE*2 ) { /* do not overwrite the black border, because of that, add 1 */
newsize = (len / (URL_WIDGET_BSIZE-1) )+1; work.g_h -= (TOOLBAR_URL_MARGIN_TOP + TOOLBAR_URL_MARGIN_BOTTOM+1);
newtext = realloc( url->text, newsize*URL_WIDGET_BSIZE ); tb_txt_request_redraw( gw->root->toolbar, 0,0,work.g_w,work.g_h );
if(newtext != NULL) { return;
url->text = newtext;
url->allocated = newsize * URL_WIDGET_BSIZE;
}
}
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 );
}
/* 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;
} }
@ -628,153 +655,30 @@ bool tb_url_input( struct gui_window * gw, short nkc )
CMP_TOOLBAR tb = gw->root->toolbar; CMP_TOOLBAR tb = gw->root->toolbar;
assert(tb!=NULL); assert(tb!=NULL);
LGRECT work; LGRECT work;
int start = 0; bool ret = false;
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);
assert( gw != NULL ); assert( gw != NULL );
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( 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*)&tmp_url, 0, true);
ret = true;
}
}
else {
ret = textarea_keypress( tb->url.textarea, ik );
}
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;
}
}
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 );
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;
}
}
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];
}
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 ); return( ret );
} }

View File

@ -17,7 +17,11 @@
*/ */
#ifndef NS_ATARI_TOOLBAR_H #ifndef NS_ATARI_TOOLBAR_H
#define 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_WIDTH 32
#define TB_BUTTON_HEIGHT 21 /* includes 1px 3d effect */ #define TB_BUTTON_HEIGHT 21 /* includes 1px 3d effect */
@ -27,13 +31,13 @@
#define THROBBER_MAX_INDEX 12 #define THROBBER_MAX_INDEX 12
#define THROBBER_INACTIVE_INDEX 13 #define THROBBER_INACTIVE_INDEX 13
#define URLBOX_HEIGHT 21 #define URLBOX_HEIGHT 21
/*
URL Widget Block size: size of memory block to allocated #define TOOLBAR_URL_TEXT_SIZE_PT 14
when input takes more memory than currently allocated: #define TOOLBAR_TEXTAREA_HEIGHT 19
*/ #define TOOLBAR_URL_MARGIN_LEFT 2
#define URL_WIDGET_BSIZE 64 #define TOOLBAR_URL_MARGIN_RIGHT 2
#define URL_WIDGET_MAX_MEM 60000 #define TOOLBAR_URL_MARGIN_TOP 2
#define TOOLBAR_URL_MARGIN_BOTTOM 2
struct s_tb_button struct s_tb_button
{ {
short rsc_id; short rsc_id;
@ -44,15 +48,10 @@ struct s_tb_button
struct s_url_widget 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 */ bool redraw; /* widget is only redrawn when this flag is set */
char * text; /* dynamicall allocated URL string */ struct text_area *textarea;
unsigned short allocated; COMPONENT * comp;
unsigned short used; /* memory used by URL (strlen + 1) */ GRECT rdw_area;
COMPONENT * comp;
}; };
struct s_throbber_widget struct s_throbber_widget
@ -62,14 +61,15 @@ struct s_throbber_widget
short max_index; short max_index;
bool running; bool running;
}; };
struct s_toolbar struct s_toolbar
{ {
COMPONENT * comp; COMPONENT * comp;
struct gui_window * owner; struct gui_window * owner;
struct s_url_widget url; struct s_url_widget url;
struct s_throbber_widget throbber; struct s_throbber_widget throbber;
GRECT btdim; /* size & location of buttons */ GRECT btdim;
/* size & location of buttons: */
struct s_tb_button * buttons; struct s_tb_button * buttons;
int btcnt; int btcnt;
}; };
@ -81,7 +81,9 @@ void tb_destroy( CMP_TOOLBAR tb );
static void __CDECL evnt_toolbar_redraw( COMPONENT *c, long buff[8], void *data ); 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_mbutton( COMPONENT *c, long buff[8], void *data );
static void __CDECL evnt_toolbar_resize( 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 : */ /* report click to toolbar, relative coords : */
void tb_click( struct gui_window * gw, short mx, short my, short mb, short kstat ); void tb_click( struct gui_window * gw, short mx, short my, short mb, short kstat );
void tb_back_click( struct gui_window * gw ); 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 ); void tb_url_click( struct gui_window * gw, short mx, short my, short mb, short kstat );
/* handle keybd event while url widget has focus:*/ /* handle keybd event while url widget has focus:*/
bool tb_url_input( struct gui_window * gw, short keycode ); 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: */ /* set the url: */
void tb_url_set( struct gui_window * gw, char * text ); 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 ); struct gui_window * tb_gui_window( CMP_TOOLBAR tb );

View File

@ -104,8 +104,10 @@ static void __CDECL evnt_tv_redraw( WINDOW *win, short buff[8], void * data )
clip.g_y = 0; clip.g_y = 0;
} }
if( clip.g_h > 0 && clip.g_w > 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(
clip.g_w, clip.g_h, tv win->xpos*win->w_u + clip.g_x,
win->ypos*win->h_u + clip.g_y,
clip.g_w, clip.g_h, tv
); );
} }
} }
@ -355,7 +357,7 @@ void atari_treeview_redraw( NSTREEVIEW tv)
*/ */
void atari_treeview_request_redraw(int x, int y, int w, int h, void *pw) void atari_treeview_request_redraw(int x, int y, int w, int h, void *pw)
{ {
if (pw != NULL) { if ( pw != NULL ) {
NSTREEVIEW tv = (NSTREEVIEW) pw; NSTREEVIEW tv = (NSTREEVIEW) pw;
if( tv->redraw == false ){ if( tv->redraw == false ){
tv->redraw = true; tv->redraw = true;