Stick to OS features for drag feature - handle it almost blocking (improves user experience).

svn path=/trunk/netsurf/; revision=13233
This commit is contained in:
Ole Loots 2011-12-04 13:05:00 +00:00
parent c3be583d22
commit 7323f012ed
8 changed files with 202 additions and 278 deletions

View File

@ -58,13 +58,8 @@
#include "atari/ctxmenu.h" #include "atari/ctxmenu.h"
#include "cflib.h" #include "cflib.h"
extern browser_mouse_state bmstate;
extern int mouse_click_time[3];
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_y;
static void browser_process_scroll( struct gui_window * gw, LGRECT bwrect ); static void browser_process_scroll( struct gui_window * gw, LGRECT bwrect );
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,
@ -156,18 +151,17 @@ void browser_get_rect( struct gui_window * gw, enum browser_rect type, LGRECT *
LGRECT cur; LGRECT cur;
/* Query component for it's current size: */ /* Query component for it's current size: */
mt_CompGetLGrect(&app, gw->browser->comp, WF_WORKXYWH, &cur); mt_CompGetLGrect(&app, gw->browser->comp, WF_WORKXYWH, &cur);
/* And extract the different widget dimensions: */
/* Redraw area of html content: */ /* And extract the different widget dimensions: */
if( type == BR_CONTENT ){ if( type == BR_CONTENT ){
out->g_w = cur.g_w; out->g_w = cur.g_w;
out->g_h = cur.g_h; out->g_h = cur.g_h;
out->g_x = cur.g_x; out->g_x = cur.g_x;
out->g_y = cur.g_y; out->g_y = cur.g_y;
return;
} }
return;
} }
/* Report an resize to the COMPONENT interface */ /* Report an resize to the COMPONENT interface */
@ -216,22 +210,24 @@ static void __CDECL browser_evnt_destroy( COMPONENT * c, long buff[8], void * da
/* /*
Mouse Button handler for browser component. Mouse Button handler for browser component.
*/ */
static void __CDECL browser_evnt_mbutton( COMPONENT * c, long buff[8], void * data) static void __CDECL browser_evnt_mbutton( COMPONENT * c, long buff[8], void * data)
{ {
short mx, my, dummy, mbut; short mx, my, dummy, mbut;
uint32_t tnow = clock()*1000 / CLOCKS_PER_SEC; LGRECT cwork;
LGRECT cwork; browser_mouse_state bmstate = 0;
struct gui_window * gw = data; struct gui_window * gw = data;
if( input_window != gw ) { if( input_window != gw ) {
return; return;
} }
window_set_focus( gw, BROWSER, (void*)gw->browser ); window_set_focus( gw, BROWSER, (void*)gw->browser );
browser_get_rect( gw, BR_CONTENT, &cwork ); browser_get_rect( gw, BR_CONTENT, &cwork );
/* convert screen coords to component coords: */
mx = evnt.mx - cwork.g_x; mx = evnt.mx - cwork.g_x;
my = evnt.my - cwork.g_y; my = evnt.my - cwork.g_y;
LOG(("mevent (%d) within %s at %d / %d\n", evnt.nb_click, gw->browser->bw->name, mx, my ));
/* Translate GEM key state to netsurf mouse modifier */ /* Translate GEM key state to netsurf mouse modifier */
if( evnt.mkstate & (K_RSHIFT | K_LSHIFT) ){ if( evnt.mkstate & (K_RSHIFT | K_LSHIFT) ){
@ -248,49 +244,57 @@ static void __CDECL browser_evnt_mbutton( COMPONENT * c, long buff[8], void * da
bmstate |= BROWSER_MOUSE_MOD_3; bmstate |= BROWSER_MOUSE_MOD_3;
} else { } else {
bmstate &= ~(BROWSER_MOUSE_MOD_3); bmstate &= ~(BROWSER_MOUSE_MOD_3);
} }
int sx = (mx + gw->browser->scroll.current.x);
int sy = (my + gw->browser->scroll.current.y); /* convert component coords to scrolled content coords: */
int sx_origin = (mx + gw->browser->scroll.current.x);
int sy_origin = (my + gw->browser->scroll.current.y);
short rel_cur_x, rel_cur_y;
short prev_x=sx_origin, prev_y=sy_origin;
/* Detect left mouse button state and compare with event state: */ /* Detect left mouse button state and compare with event state: */
graf_mkstate(&dummy, &dummy, &mbut, &dummy); graf_mkstate(&rel_cur_x, &rel_cur_y, &mbut, &dummy);
if( (mbut & 1) && (evnt.mbut & 1) ) { if( (mbut & 1) && (evnt.mbut & 1) ){
if( mouse_hold_start[0] == 0 ) { /* Mouse still pressed, report drag */
mouse_hold_start[0] = tnow; rel_cur_x = (rel_cur_x - cwork.g_x) + gw->browser->scroll.current.x;
LOG(("Drag starts at %d,%d\n", sx, sy)); rel_cur_y = (rel_cur_y - cwork.g_y) + gw->browser->scroll.current.y;
browser_window_mouse_click(gw->browser->bw,BROWSER_MOUSE_PRESS_1,sx,sy); browser_window_mouse_click( gw->browser->bw,
bmstate |= BROWSER_MOUSE_HOLDING_1 | BROWSER_MOUSE_DRAG_ON; BROWSER_MOUSE_DRAG_ON|BROWSER_MOUSE_DRAG_1,
} else { sx_origin, sy_origin);
bmstate |= BROWSER_MOUSE_DRAG_1 | BROWSER_MOUSE_DRAG_ON; do{
} if( abs(prev_x-rel_cur_x) > 5 || abs(prev_y-rel_cur_y) > 5 ){
if( (abs(mx-last_drag_x)>5) || (abs(mx-last_drag_y)>5) ){ browser_window_mouse_track( gw->browser->bw,
browser_window_mouse_track( BROWSER_MOUSE_DRAG_ON|BROWSER_MOUSE_HOLDING_1,
gw->browser->bw, rel_cur_x, rel_cur_y);
bmstate, prev_x = rel_cur_x;
sx, sy prev_y = rel_cur_y;
); if( browser_redraw_required( gw ) ){
last_drag_x = mx; browser_redraw( gw );
last_drag_y = my; }
} }
graf_mkstate(&rel_cur_x, &rel_cur_y, &mbut, &dummy);
} else if( (evnt.mbut & 1) ) { rel_cur_x = (rel_cur_x - cwork.g_x) + gw->browser->scroll.current.x;
mouse_click_time[0] = tnow; /* clock in ms */ rel_cur_y = (rel_cur_y - cwork.g_y) + gw->browser->scroll.current.y;
/* check if this event was during an drag op, only handle if it wasn't: */ } while( mbut & 1 );
if( mouse_hold_start[0] == 0 ) { browser_window_mouse_track(gw->browser->bw, 0, rel_cur_x,rel_cur_y);
LOG(("Click within %s at %d / %d\n", gw->browser->bw->name, sx, sy )); } else {
browser_window_mouse_click(gw->browser->bw,BROWSER_MOUSE_PRESS_1,sx,sy); /* Right button pressed? */
browser_window_mouse_click(gw->browser->bw,BROWSER_MOUSE_CLICK_1,sx,sy); if( (evnt.mbut & 2 ) ) {
bmstate &= ~( BROWSER_MOUSE_HOLDING_1 | BROWSER_MOUSE_DRAG_1 | BROWSER_MOUSE_CLICK_1); context_popup( gw, evnt.mx, evnt.my );
} } else {
mouse_hold_start[0] = 0; browser_window_mouse_click(gw->browser->bw,
} bmstate|BROWSER_MOUSE_PRESS_1,
sx_origin,sy_origin);
browser_window_mouse_click(gw->browser->bw,
bmstate|BROWSER_MOUSE_CLICK_1,
sx_origin,sy_origin);
}
}
/* Right button pressed? */
if( (evnt.mbut & 2 ) ) { }
context_popup( gw, evnt.mx, evnt.my );
}
}
/* /*
Report scroll event to the browser component. Report scroll event to the browser component.

View File

@ -62,11 +62,6 @@
extern void * h_gem_rsrc; extern void * h_gem_rsrc;
extern struct gui_window *input_window; extern struct gui_window *input_window;
extern GEM_PLOTTER plotter; extern GEM_PLOTTER plotter;
extern int mouse_click_time[3];
extern int mouse_hold_start[3];
extern browser_mouse_state bmstate;
extern short last_drag_x;
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 * );
@ -92,77 +87,6 @@ static void __CDECL evnt_window_arrowed( WINDOW *win, short buff[8], void *data
/* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */
/*
track the mouse state and
finally checks for released buttons.
*/
static void window_track_mouse_state( LGRECT * bwrect, bool within, short mx, short my, short mbut, short mkstate ){
int i = 0;
int nx, ny;
struct gui_window * gw = input_window;
if( !gw ) {
bmstate = 0;
mouse_hold_start[0] = 0;
mouse_hold_start[1] = 0;
return;
}
/* todo: creat function find_browser_window( mx, my ) */
nx = (mx - bwrect->g_x + gw->browser->scroll.current.x);
ny = (my - bwrect->g_y + gw->browser->scroll.current.y);
if( mkstate & (K_RSHIFT | K_LSHIFT) ){
bmstate |= BROWSER_MOUSE_MOD_1;
} else {
bmstate &= ~(BROWSER_MOUSE_MOD_1);
}
if( (mkstate & K_CTRL) ){
bmstate |= BROWSER_MOUSE_MOD_2;
} else {
bmstate &= ~(BROWSER_MOUSE_MOD_2);
}
if( (mkstate & K_ALT) ){
bmstate |= BROWSER_MOUSE_MOD_3;
} else {
bmstate &= ~(BROWSER_MOUSE_MOD_3);
}
if( !(mbut&1) && !(mbut&2) ) {
if(bmstate & BROWSER_MOUSE_DRAG_ON )
bmstate &= ~( BROWSER_MOUSE_DRAG_ON );
}
/* todo: if we need right button click, increase loop count */
for( i = 1; i<2; i++ ) {
if( !(mbut & i) ) {
if( mouse_hold_start[i-1] > 0 ) {
mouse_hold_start[i-1] = 0;
if( i==1 ) {
LOG(("Drag for %d ended", i));
bmstate &= ~( BROWSER_MOUSE_HOLDING_1 | BROWSER_MOUSE_DRAG_1 ) ;
if( within ) {
/* drag end */
browser_window_mouse_track(
gw->browser->bw, 0, nx, ny
);
}
}
if( i==2 ) {
bmstate &= ~( BROWSER_MOUSE_HOLDING_2 | BROWSER_MOUSE_DRAG_2 ) ;
LOG(("Drag for %d ended", i));
if( within ) {
/* drag end */
browser_window_mouse_track(
gw->browser->bw, 0, nx, ny
);
}
}
}
}
}
}
int window_create( struct gui_window * gw, int window_create( struct gui_window * gw,
struct browser_window * bw, struct browser_window * bw,
unsigned long inflags ) unsigned long inflags )
@ -545,72 +469,48 @@ error:
static void __CDECL evnt_window_m1( WINDOW * win, short buff[8], void * data) 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;
short mx, my, mbut, mkstate; static short prev_x=0;
bool a = false; //flags if mouse is within controls or browser static short prev_y=0;
bool within = false; bool within = false;
LGRECT urlbox, bwbox, sbbox; LGRECT urlbox, bwbox, sbbox;
int nx, ny; // relative mouse position int nx, ny;
if( gw == NULL) if( gw == NULL)
return; return;
if( gw != input_window ){ if( prev_x == evnt.mx && prev_y == evnt.my ){
return; return;
} }
graf_mkstate(&mx, &my, &mbut, &mkstate);
browser_get_rect( gw, BR_CONTENT, &bwbox ); browser_get_rect( gw, BR_CONTENT, &bwbox );
if( gw->root->toolbar )
if( evnt.mx > bwbox.g_x && evnt.mx < bwbox.g_x + bwbox.g_w &&
evnt.my > bwbox.g_y && evnt.my < bwbox.g_y + bwbox.g_h ){
within = true;
browser_window_mouse_track(
input_window->browser->bw,
0,
evnt.mx - bwbox.g_x + gw->browser->scroll.current.x,
evnt.my - bwbox.g_y + gw->browser->scroll.current.y
);
}
if( gw->root->toolbar && within == false ) {
mt_CompGetLGrect(&app, gw->root->toolbar->url.comp, WF_WORKXYWH, &urlbox); mt_CompGetLGrect(&app, gw->root->toolbar->url.comp, WF_WORKXYWH, &urlbox);
if( gw->root->statusbar ) if( (evnt.mx > urlbox.g_x && evnt.mx < urlbox.g_x + urlbox.g_w ) &&
mt_CompGetLGrect(&app, gw->root->statusbar->comp, WF_WORKXYWH, &sbbox); (evnt.my > urlbox.g_y && evnt.my < + urlbox.g_y + urlbox.g_h )) {
gem_set_cursor( &gem_cursors.ibeam );
if( mx > bwbox.g_x && mx < bwbox.g_x + bwbox.g_w && prev_url = true;
my > bwbox.g_y && my < bwbox.g_y + bwbox.g_h ){ } else {
within = true;
}
if( evnt.m1_flag == MO_LEAVE ) {
if( MOUSE_IS_DRAGGING() ){
window_track_mouse_state( &bwbox, within, mx, my, mbut, mkstate );
}
if( gw->root->toolbar && within == false ) {
if( (mx > urlbox.g_x && mx < urlbox.g_x + urlbox.g_w ) &&
(my > urlbox.g_y && my < + urlbox.g_y + urlbox.g_h )) {
gem_set_cursor( &gem_cursors.ibeam );
prev_url = a = true;
}
}
if( !a ) {
if( prev_url ) { if( prev_url ) {
gem_set_cursor( &gem_cursors.arrow ); gem_set_cursor( &gem_cursors.arrow );
prev_url = false; prev_url = false;
} }
/* report mouse move in the browser window */
if( within ){
nx = mx - bwbox.g_x;
ny = my - bwbox.g_y;
if( ( abs(mx-last_drag_x)>5 || abs(mx-last_drag_y)>5 ) ||
!MOUSE_IS_DRAGGING() ){
browser_window_mouse_track(
input_window->browser->bw,
bmstate,
nx + gw->browser->scroll.current.x,
ny + gw->browser->scroll.current.y
);
if( MOUSE_IS_DRAGGING() ){
last_drag_x = mx;
last_drag_y = my;
}
}
}
} }
} else { }
/* set input window? */
} prev_x = evnt.mx;
prev_y = evnt.my;
} }
static void __CDECL evnt_window_destroy( WINDOW *win, short buff[8], void *data ) static void __CDECL evnt_window_destroy( WINDOW *win, short buff[8], void *data )

View File

@ -542,7 +542,6 @@ void bind_global_events( void )
EvntDataAttach( NULL, WM_XKEYBD, global_evnt_keybd, (void*)&evnt_data ); EvntDataAttach( NULL, WM_XKEYBD, global_evnt_keybd, (void*)&evnt_data );
EvntAttach( NULL, AP_TERM, global_evnt_apterm ); EvntAttach( NULL, AP_TERM, global_evnt_apterm );
EvntAttach( NULL, MN_SELECTED, global_evnt_menu ); EvntAttach( NULL, MN_SELECTED, global_evnt_menu );
/* EvntDataAttach( NULL, WM_XM1, global_evnt_m1, NULL ); */
/* TODO: maybe instant redraw after this is better! */ /* TODO: maybe instant redraw after this is better! */
set_menu_title( MAINMENU_T_FILE, "Page"); set_menu_title( MAINMENU_T_FILE, "Page");

View File

@ -55,9 +55,6 @@ struct s_menu_item_evnt {
Global & Menu event handlers Global & Menu event handlers
*/ */
/* Call this after each call to evnt_multi, to check for states that evnt_multi doesn't: */
void global_track_mouse_state( LGRECT * bwrect, bool within, short, short, short, short );
void bind_global_events( void ); void bind_global_events( void );
void unbind_global_events( void ); void unbind_global_events( void );

View File

@ -86,12 +86,7 @@ OBJECT * h_gem_menu;
OBJECT **rsc_trindex; OBJECT **rsc_trindex;
short vdih; short vdih;
short rsc_ntree; short rsc_ntree;
int mouse_click_time[3] = { INT_MAX, INT_MAX, INT_MAX };
int mouse_hold_start[3];
short last_drag_x;
short last_drag_y;
long next_poll; long next_poll;
browser_mouse_state bmstate;
/* Comandline / Options: */ /* Comandline / Options: */
int cfg_width; int cfg_width;
@ -110,61 +105,31 @@ void gui_poll(bool active)
short mx, my, dummy; short mx, my, dummy;
short aestop; short aestop;
evnt.timer = schedule_run(); evnt.timer = schedule_run();
wind_get( 0, WF_TOP, &aestop, &winloc[1], &winloc[2], &winloc[3]);
if( winloc[1] != _AESapid ){
aestop = 0;
}
if( (aestop > 0) && !active ) {
flags |= MU_M1;
wind_get( aestop, WF_WORKXYWH, &winloc[0],
&winloc[1], &winloc[2], &winloc[3] );
graf_mkstate( &mx, &my, &dummy, &dummy );
/* this can be improved a lot under XaAES - there is an event for mouse move */
if( mx >= winloc[0] && mx <= winloc[0] + winloc[2] &&
my >= winloc[1] && my <= winloc[1] + winloc[3] ){
/* Mouse is within the top window area */
evnt.m1_flag = MO_LEAVE;
evnt.m1_w = evnt.m1_h = 1;
evnt.m1_x = mx;
evnt.m1_y = my;
} else {
/* Mouse is outside of top window area. */
if( evnt.m1_flag == MO_LEAVE ) {
/* Previous move was inside the top window area */
struct gui_window * gw = input_window;
if(gw != NULL && gw->browser != NULL && gw->browser->bw != NULL ){
/* reset mouse state */
/* you could also track further, without reset, but */
/* when the mouse moves into native scroller area, the mouse is */
/* the native scroll bar code gets in between.. */
mouse_hold_start[0] = 0;
mouse_hold_start[1] = 0;
bmstate = 0;
browser_window_mouse_track( gw->browser->bw, bmstate, mx, my );
}
}
evnt.m1_flag = MO_ENTER;
evnt.m1_w = winloc[2];
evnt.m1_h = winloc[3];
evnt.m1_x = winloc[0];
evnt.m1_y = winloc[1];
}
}
/*printf("time: %d, active: %d\n", evnt.timer, active );*/
if( active ) { if( active ) {
if( clock() >= next_poll ) { if( clock() >= next_poll ) {
evnt.timer = 0; evnt.timer = 0;
flags |= MU_TIMER; flags |= MU_TIMER;
EvntWindom( flags ); EvntWindom( flags );
next_poll = clock() + CLOCKS_PER_SEC; next_poll = clock() + CLOCKS_PER_SEC;
} }
} else { } else {
if( input_window != NULL ){
wind_get( 0, WF_TOP, &aestop, &winloc[1], &winloc[2], &winloc[3]);
if( winloc[1] == _AESapid ){
/* only check for mouse move when netsurf is on top: */
// move that into m1 event handler
graf_mkstate( &mx, &my, &dummy, &dummy );
flags |= MU_M1;
evnt.m1_flag = MO_LEAVE;
evnt.m1_w = evnt.m1_h = 1;
evnt.m1_x = mx;
evnt.m1_y = my;
}
}
flags |= MU_TIMER; flags |= MU_TIMER;
EvntWindom( flags ); EvntWindom( flags );
} }
struct gui_window * g; struct gui_window * g;
@ -191,8 +156,6 @@ gui_create_browser_window(struct browser_window *bw,
bool new_tab) bool new_tab)
{ {
struct gui_window *gw=NULL; struct gui_window *gw=NULL;
struct gui_window * gwroot ;
short winloc[4];
LOG(( "gw: %p, BW: %p, clone %p, tab: %d\n" , gw, bw, clone, LOG(( "gw: %p, BW: %p, clone %p, tab: %d\n" , gw, bw, clone,
(int)new_tab (int)new_tab
)); ));
@ -260,7 +223,6 @@ void gui_window_destroy(struct gui_window *w)
w = NULL; w = NULL;
w = window_list; w = window_list;
int dummy=0;
while( w != NULL ) { while( w != NULL ) {
if( w->root ) { if( w->root ) {
input_window = w; input_window = w;
@ -325,7 +287,6 @@ void gui_window_redraw_window(struct gui_window *gw)
void gui_window_update_box(struct gui_window *gw, const struct rect *rect) void gui_window_update_box(struct gui_window *gw, const struct rect *rect)
{ {
LGRECT work;
CMP_BROWSER b; CMP_BROWSER b;
if (gw == NULL) if (gw == NULL)
return; return;
@ -542,10 +503,8 @@ void gui_window_stop_throbber(struct gui_window *w)
/* 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;
if (w == NULL) if (w == NULL)
return; return;
CMP_BROWSER b = w->browser;
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;
@ -563,10 +522,8 @@ void gui_window_place_caret(struct gui_window *w, int x, int y, int height)
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;
if( w->browser->caret.background.fd_addr != NULL ){ if( w->browser->caret.background.fd_addr != NULL ){
browser_restore_caret_background( w, NULL ); browser_restore_caret_background( w, NULL );
@ -850,12 +807,6 @@ void gui_cert_verify(const char *url, const struct ssl_cert_info *certs,
cb(bres, cbpw); cb(bres, cbpw);
} }
static void *myrealloc(void *ptr, size_t len, void *pw)
{
return realloc(ptr, len);
}
void gui_quit(void) void gui_quit(void)
{ {
LOG(("")); LOG((""));
@ -964,8 +915,7 @@ nsurl *gui_get_resource_url(const char *path)
static void gui_init(int argc, char** argv) static void gui_init(int argc, char** argv)
{ {
char buf[PATH_MAX], sbuf[PATH_MAX]; char buf[PATH_MAX];
int len;
OBJECT * cursors; OBJECT * cursors;
atari_find_resource(buf, "netsurf.rsc", "./res/netsurf.rsc"); atari_find_resource(buf, "netsurf.rsc", "./res/netsurf.rsc");
@ -1028,8 +978,6 @@ static void gui_init(int argc, char** argv)
static char *theapp = (char*)"NetSurf"; static char *theapp = (char*)"NetSurf";
static void gui_init2(int argc, char** argv) static void gui_init2(int argc, char** argv)
{ {
struct browser_window *bw;
const char *addr = NETSURF_HOMEPAGE;
MenuBar( h_gem_menu , 1 ); MenuBar( h_gem_menu , 1 );
bind_global_events(); bind_global_events();
menu_register( -1, theapp); menu_register( -1, theapp);

View File

@ -28,14 +28,6 @@ struct point_s {
int y; int y;
}; };
struct bbox_s {
int x0;
int y0;
int x1;
int y1;
};
typedef struct bbox_s BBOX;
typedef struct point_s POINT; typedef struct point_s POINT;
#define MFORM_EX_FLAG_USERFORM 0x01 #define MFORM_EX_FLAG_USERFORM 0x01
@ -136,6 +128,4 @@ struct gui_window {
extern struct gui_window *window_list; extern struct gui_window *window_list;
#define MOUSE_IS_DRAGGING() (mouse_hold_start[0] || mouse_hold_start[1])
#endif #endif

View File

@ -112,8 +112,92 @@ static void __CDECL evnt_tv_redraw( WINDOW *win, short buff[8], void * data )
} }
} }
static void __CDECL evnt_tv_mbutton( WINDOW *win, short buff[8], void * data )
{
GRECT work;
NSTREEVIEW tv = (NSTREEVIEW) data;
if( tv == NULL )
return;
if( evnt.mbut & 2 ) {
/* do not handle right click */
return;
}
WindGetGrect( tv->window, WF_WORKXYWH, &work );
/* mouse click relative origin: */
short origin_rel_x = (evnt.mx-work.g_x)+(win->xpos*win->w_u);
short origin_rel_y = (evnt.my-work.g_y)+(win->ypos*win->h_u);
if( origin_rel_x >= 0 && origin_rel_y >= 0
&& evnt.mx < work.g_x + work.g_w
&& evnt.my < work.g_y + work.g_h )
{
int bms;
bool ignore=false;
short cur_rel_x, cur_rel_y, dummy, mbut;
if( evnt.nb_click == 2 ){
tree_mouse_action(tv->tree,
BROWSER_MOUSE_CLICK_1 | BROWSER_MOUSE_DOUBLE_CLICK,
origin_rel_x, origin_rel_y );
return;
}
graf_mkstate(&cur_rel_x, &cur_rel_x, &mbut, &dummy);
if( (mbut&1) == 0 ){
bms = BROWSER_MOUSE_CLICK_1 | BROWSER_MOUSE_PRESS_1;
if( evnt.nb_click == 2 ) {
bms = BROWSER_MOUSE_DOUBLE_CLICK;
}
tree_mouse_action(tv->tree, bms, origin_rel_x, origin_rel_y );
} else {
/* button still pressed */
short prev_x = origin_rel_x;
short prev_y = origin_rel_y;
cur_rel_x = origin_rel_x;
cur_rel_y = origin_rel_y;
if( tree_is_edited(tv->tree) ){
gem_set_cursor(&gem_cursors.ibeam);
} else {
gem_set_cursor(&gem_cursors.hand);
}
tv->startdrag.x = origin_rel_x;
tv->startdrag.y = origin_rel_y;
tree_mouse_action( tv->tree,
BROWSER_MOUSE_DRAG_1 | BROWSER_MOUSE_DRAG_ON ,
cur_rel_x, cur_rel_y );
do{
if( abs(prev_x-cur_rel_x) > 5 || abs(prev_y-cur_rel_y) > 5 ){
tree_mouse_action( tv->tree,
BROWSER_MOUSE_HOLDING_1 | BROWSER_MOUSE_DRAG_ON,
cur_rel_x, cur_rel_y);
prev_x = cur_rel_x;
prev_y = cur_rel_y;
}
if( tv->redraw )
atari_treeview_redraw( tv );
/* sample mouse button state: */
graf_mkstate(&cur_rel_x, &cur_rel_y, &mbut, &dummy);
cur_rel_x = (cur_rel_x-work.g_x)+(win->xpos*win->w_u);
cur_rel_y = (cur_rel_y-work.g_y)+(win->ypos*win->h_u);
} while( mbut & 1 );
static void __CDECL evnt_tv_mbutton( WINDOW *win, short buff[8], void * data ) tree_drag_end(tv->tree, 0, tv->startdrag.x, tv->startdrag.y,
cur_rel_x, cur_rel_y );
gem_set_cursor(&gem_cursors.arrow);
}
}
}
static void __CDECL evnt_tv_mbutton__( WINDOW *win, short buff[8], void * data )
{ {
GRECT work; GRECT work;
bool ignore=false; bool ignore=false;
@ -156,20 +240,22 @@ static void __CDECL evnt_tv_mbutton( WINDOW *win, short buff[8], void * data )
bmstate = BROWSER_MOUSE_CLICK_1 | BROWSER_MOUSE_DOUBLE_CLICK; bmstate = BROWSER_MOUSE_CLICK_1 | BROWSER_MOUSE_DOUBLE_CLICK;
mouse_hold_start[0] = 0; mouse_hold_start[0] = 0;
} else { } else {
if( mbut & 1 ) { if( mbut & 1 ) {
bmstate |= BROWSER_MOUSE_DRAG_ON; bmstate |= BROWSER_MOUSE_DRAG_ON;
if( mouse_hold_start[0] == 0) { if( mouse_hold_start[0] == 0) {
// start of drag op
mouse_hold_start[0] = tnow; mouse_hold_start[0] = tnow;
tv->startdrag.x = rx; tv->startdrag.x = rx;
tv->startdrag.y = ry; tv->startdrag.y = ry;
bmstate |= BROWSER_MOUSE_DRAG_1; bmstate |= BROWSER_MOUSE_DRAG_1;
gem_set_cursor(&gem_cursors.cross); gem_set_cursor(&gem_cursors.cross);
} else { } else {
/* todo: add more isual indication (grafbox?) */ /* todo: add more visual indication (grafbox?) */
ignore = true; ignore = true;
gem_set_cursor(&gem_cursors.cross); gem_set_cursor(&gem_cursors.cross);
} }
} else { } else {
// mouse button up event
if( bmstate & BROWSER_MOUSE_DRAG_ON ){ if( bmstate & BROWSER_MOUSE_DRAG_ON ){
bmstate = 0; bmstate = 0;
tree_drag_end(tv->tree, bmstate, tv->startdrag.x, tv->startdrag.y, rx, ry); tree_drag_end(tv->tree, bmstate, tv->startdrag.x, tv->startdrag.y, rx, ry);
@ -231,7 +317,7 @@ NSTREEVIEW atari_treeview_create( uint32_t flags, WINDOW *win )
EvntDataAdd( new->window, WM_XBUTTON, evnt_tv_mbutton, new, EV_BOT ); EvntDataAdd( new->window, WM_XBUTTON, evnt_tv_mbutton, new, EV_BOT );
EvntDataAttach( new->window, WM_REDRAW, evnt_tv_redraw, new ); EvntDataAttach( new->window, WM_REDRAW, evnt_tv_redraw, new );
EvntDataAttach( new->window, WM_XKEYBD, evnt_tv_keybd, new ); EvntDataAttach( new->window, WM_XKEYBD, evnt_tv_keybd, new );
EvntDataAttach( new->window, WM_XM1, evnt_tv_m1, new ); //EvntDataAttach( new->window, WM_XM1, evnt_tv_m1, new );
return(new); return(new);
} }
@ -415,8 +501,8 @@ void atari_treeview_resized(struct tree *tree, int width, int height, void *pw)
void atari_treeview_scroll_visible(int y, int height, void *pw) void atari_treeview_scroll_visible(int y, int height, void *pw)
{ {
/* we don't support dragging within the treeview */ /* we don't support dragging outside the treeview */
/* so we don't need to implement this */ /* so we don't need to implement this? */
} }
/** /**

View File

@ -50,4 +50,4 @@ bool atari_treeview_mevent( NSTREEVIEW tv, browser_mouse_state bms, int x, int y
#endif #endif