From e4c6acee55139a18d6118999c16d55aa1f36c9e8 Mon Sep 17 00:00:00 2001 From: Ole Loots Date: Tue, 17 Sep 2013 02:10:35 +0200 Subject: Treeview implementation adjusted (still requires changes at several places in the atari frontent) --- atari/treeview.c | 406 ++++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 372 insertions(+), 34 deletions(-) (limited to 'atari/treeview.c') diff --git a/atari/treeview.c b/atari/treeview.c index 7ea039c13..6dd43d3db 100644 --- a/atari/treeview.c +++ b/atari/treeview.c @@ -75,21 +75,370 @@ struct atari_treeview_window { struct atari_treeview_callbacks *io; }; -typedef struct atari_treeview_window *ATARI_TREEVIEW; - +enum treeview_area_e { + TREEVIEW_AREA_WORK = 0, + TREEVIEW_AREA_TOOLBAR, + TREEVIEW_AREA_CONTENT +}; /* native GUI event handlers: */ -static void __CDECL on_mbutton_event(struct atari_treeview_window tvw, +static void __CDECL on_mbutton_event(struct atari_treeview_window *tvw, EVMULT_OUT *ev_out, short msg[8]); -static void __CDECL on_keybd_event(struct atari_treeview_window tvw, +static void __CDECL on_keybd_event(struct atari_treeview_window *tvw, EVMULT_OUT *ev_out, short msg[8]); -static void __CDECL on_redraw_event(struct atari_treeview_window tvw, +static void __CDECL on_redraw_event(struct atari_treeview_window *tvw, EVMULT_OUT *ev_out, short msg[8]); -/* GEMTK event sink: */ + +/** + * Schedule a redraw of the treeview content + * + */ +static void atari_treeview_redraw_grect_request(struct core_window *cw, + GRECT *area) +{ + if (cw != NULL) { + ATARI_TREEVIEW_PTR tv = (ATARI_TREEVIEW_PTR) cw; + if( tv->redraw == false ){ + tv->redraw = true; + tv->rdw_area.g_x = area->g_x; + tv->rdw_area.g_y = area->g_y; + tv->rdw_area.g_w = area->g_w; + tv->rdw_area.g_h = area->g_h; + } else { + /* merge the redraw area to the new area.: */ + int newx1 = area->g_x+area->g_w; + int newy1 = area->g_y+area->g_h; + int oldx1 = tv->rdw_area.g_x + tv->rdw_area.g_w; + int oldy1 = tv->rdw_area.g_y + tv->rdw_area.g_h; + tv->rdw_area.g_x = MIN(tv->rdw_area.g_x, area->g_x); + tv->rdw_area.g_y = MIN(tv->rdw_area.g_y, area->g_y); + tv->rdw_area.g_w = ( oldx1 > newx1 ) ? oldx1 - tv->rdw_area.g_x : newx1 - tv->rdw_area.g_x; + tv->rdw_area.g_h = ( oldy1 > newy1 ) ? oldy1 - tv->rdw_area.g_y : newy1 - tv->rdw_area.g_y; + } + // dbg_grect("atari_treeview_request_redraw", &tv->rdw_area); + } +} + + +static void atari_treeview_get_grect(ATARI_TREEVIEW_PTR tptr, enum treeview_area_e mode, + GRECT *dest) +{ + + struct atari_treeview_window * tv = tptr; + + if (mode == TREEVIEW_AREA_CONTENT) { + gemtk_wm_get_grect(tv->window, GEMTK_WM_AREA_CONTENT, dest); + } + else if (mode == TREEVIEW_AREA_TOOLBAR) { + gemtk_wm_get_grect(tv->window, GEMTK_WM_AREA_TOOLBAR, dest); + } +} + + +void atari_treeview_redraw(struct atari_treeview_window *tv) +{ + static FONT_PLOTTER vdi_txt_plotter = NULL; + FONT_PLOTTER old_txt_plotter; + + VdiHdl plot_vdi_handle = 0; + long atari_plot_flags = 0; + + /* TODO: do not use the global vdi handle for plot actions! */ + /* TODO: implement getter/setter for the vdi handle */ + + if (tv != NULL) { + if( tv->redraw && ((atari_plot_flags & PLOT_FLAG_OFFSCREEN) == 0) ) { + + plot_vdi_handle = plot_get_vdi_handle(); + long atari_plot_flags = plot_get_flags(); + short todo[4]; + GRECT work; + short handle = gemtk_wm_get_handle(tv->window); + struct gemtk_wm_scroll_info_s *slid; + +/* + if (vdi_txt_plotter == NULL) { + int err = 0; + VdiHdl vdih = plot_get_vdi_handle(); + vdi_txt_plotter = new_font_plotter(vdih, (char*)"vdi", PLOT_FLAG_TRANS, + &err); + if(err) { + const char * desc = plot_err_str(err); + die(("Unable to load vdi font plotter %s -> %s", "vdi", desc )); + } + } +*/ + gemtk_wm_get_grect(tv->window, GEMTK_WM_AREA_CONTENT, &work); + slid = gemtk_wm_get_scroll_info(tv->window); + + struct redraw_context ctx = { + .interactive = true, + .background_images = true, + .plot = &atari_plotters + }; + plot_set_dimensions(work.g_x, work.g_y, work.g_w, work.g_h); + if (plot_lock() == false) + return; +/* + if(vdi_txt_plotter != NULL){ + old_txt_plotter = plot_get_text_plotter(); + plot_set_text_plotter(vdi_txt_plotter); + } +*/ + if( wind_get(handle, WF_FIRSTXYWH, + &todo[0], &todo[1], &todo[2], &todo[3] )!=0 ) { + while (todo[2] && todo[3]) { + + short pxy[4]; + pxy[0] = todo[0]; + pxy[1] = todo[1]; + pxy[2] = todo[0] + todo[2]-1; + pxy[3] = todo[1] + todo[3]-1; + vs_clip(plot_vdi_handle, 1, (short*)&pxy); + + /* convert screen to treeview coords: */ + todo[0] = todo[0] - work.g_x + slid->x_pos*slid->x_unit_px; + todo[1] = todo[1] - work.g_y + slid->y_pos*slid->y_unit_px; + 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((GRECT *)&tv->rdw_area,(GRECT *)&todo)) { + tv->io->draw(tv, -(slid->x_pos*slid->x_unit_px), + -(slid->y_pos*slid->y_unit_px), + todo[0], todo[1], todo[2], todo[3], &ctx); + } + vs_clip(plot_vdi_handle, 0, (short*)&pxy); + if (wind_get(handle, WF_NEXTXYWH, + &todo[0], &todo[1], &todo[2], &todo[3])==0) { + break; + } + } + } else { + /* + plot_set_text_plotter(old_txt_plotter); + */ + plot_unlock(); + return; + } + /* + plot_set_text_plotter(old_txt_plotter); + */ + plot_unlock(); + tv->redraw = false; + tv->rdw_area.g_x = 65000; + tv->rdw_area.g_y = 65000; + tv->rdw_area.g_w = -1; + tv->rdw_area.g_h = -1; + } else { + /* just copy stuff from the offscreen buffer */ + } + } +} + + +/** + * GEMTK event sink + * +*/ static short handle_event(GUIWIN *win, EVMULT_OUT *ev_out, short msg[8]) { + ATARI_TREEVIEW_PTR tv = (ATARI_TREEVIEW_PTR) gemtk_wm_get_user_data(win); + + if( (ev_out->emo_events & MU_MESAG) != 0 ) { + // handle message + switch (msg[0]) { + + case WM_REDRAW: + on_redraw_event(tv, ev_out, msg); + break; + + default: + break; + } + } + if( (ev_out->emo_events & MU_KEYBD) != 0 ) { + on_keybd_event(tv, ev_out, msg); + } + if( (ev_out->emo_events & MU_BUTTON) != 0 ) { + LOG(("Treeview click at: %d,%d\n", ev_out->emo_mouse.p_x, + ev_out->emo_mouse.p_y)); + on_mbutton_event(tv, ev_out, msg); + } + + if (tv) { + + } +/* + if(tv != NULL && tv->user_func != NULL){ + tv->user_func(win, ev_out, msg); + } +*/ + return(0); +} + + +static void __CDECL on_keybd_event(ATARI_TREEVIEW_PTR tptr, EVMULT_OUT *ev_out, + short msg[8]) +{ + bool r=false; + long kstate = 0; + long kcode = 0; + long ucs4; + long ik; + unsigned short nkc = 0; + unsigned short nks = 0; + unsigned char ascii; + struct atari_treeview_window * tv = tptr; + + kstate = ev_out->emo_kmeta; + kcode = ev_out->emo_kreturn; + nkc= gem_to_norm( (short)kstate, (short)kcode ); + ascii = (nkc & 0xFF); + ik = nkc_to_input_key(nkc, &ucs4); + + if (ik == 0) { + if (ascii >= 9) { + tv->io->keypress(tv, ucs4); + //r = tree_keypress(tv->tree, ucs4); + } + } else { + tv->io->keypress(tv, ik); + } +} + + +static void __CDECL on_redraw_event(ATARI_TREEVIEW_PTR tptr, EVMULT_OUT *ev_out, + short msg[8]) +{ + GRECT work, clip; + struct gemtk_wm_scroll_info_s *slid; + struct atari_treeview_window * tv = tptr; + + if (tv == NULL) + return; + + gemtk_wm_get_grect(tv->window, GEMTK_WM_AREA_CONTENT, &work); + slid = gemtk_wm_get_scroll_info(tv->window); + + clip = work; + if ( !rc_intersect( (GRECT*)&msg[4], &clip ) ) return; + clip.g_x -= work.g_x; + clip.g_y -= work.g_y; + if( clip.g_x < 0 ) { + clip.g_w = work.g_w + clip.g_x; + clip.g_x = 0; + } + if( clip.g_y < 0 ) { + clip.g_h = work.g_h + clip.g_y; + clip.g_y = 0; + } + if( clip.g_h > 0 && clip.g_w > 0 ) { + + GRECT rdrw_area; + + rdrw_area.g_x = (slid->x_pos*slid->x_unit_px) + clip.g_x; + rdrw_area.g_y =(slid->y_pos*slid->y_unit_px) + clip.g_y; + rdrw_area.g_w = clip.g_w; + rdrw_area.g_h = clip.g_h; + + atari_treeview_redraw_grect_request(tptr, &rdrw_area); + } +} + +static void __CDECL on_mbutton_event(ATARI_TREEVIEW_PTR tptr, EVMULT_OUT *ev_out, + short msg[8]) +{ + struct atari_treeview_window * tv = tptr; + struct gemtk_wm_scroll_info_s *slid; + GRECT work; + short mx, my; + int bms; + bool ignore=false; + short cur_rel_x, cur_rel_y, dummy, mbut; + + if(tv == NULL) + return; + + gemtk_wm_get_grect(tv->window, GEMTK_WM_AREA_CONTENT, &work); + slid = gemtk_wm_get_scroll_info(tv->window); + mx = ev_out->emo_mouse.p_x; + my = ev_out->emo_mouse.p_y; + + /* mouse click relative origin: */ + + short origin_rel_x = (mx-work.g_x) + + (slid->x_pos*slid->x_unit_px); + short origin_rel_y = (my-work.g_y) + + (slid->y_pos*slid->y_unit_px); + + /* Only pass on events in the content area: */ + if( origin_rel_x >= 0 && origin_rel_y >= 0 + && mx < work.g_x + work.g_w + && my < work.g_y + work.g_h ) + { + if (ev_out->emo_mclicks == 2) { + tv->io->mouse_action(tv, + BROWSER_MOUSE_CLICK_1|BROWSER_MOUSE_DOUBLE_CLICK, + origin_rel_x, origin_rel_y); + return; + } + graf_mkstate(&cur_rel_x, &cur_rel_y, &mbut, &dummy); + /* check for click or hold: */ + if( (mbut&1) == 0 ){ + bms = BROWSER_MOUSE_CLICK_1 | BROWSER_MOUSE_PRESS_1; + if(ev_out->emo_mclicks == 2 ) { + bms = BROWSER_MOUSE_DOUBLE_CLICK; + } + tv->io->mouse_action(tv, 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; + + gem_set_cursor(&gem_cursors.hand); + + tv->startdrag.x = origin_rel_x; + tv->startdrag.y = origin_rel_y; + + tv->io->mouse_action(tv, 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) { + tv->io->mouse_action(tv, + 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) { + // TODO: maybe GUI poll would fit better here? + // ... is gui_poll re-entrance save? + 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)+(slid->x_pos*slid->x_unit_px); + cur_rel_y = (cur_rel_y-work.g_y)+(slid->y_pos*slid->y_unit_px); + } while( mbut & 1 ); + + /* End drag: */ + tv->io->mouse_action(tv, BROWSER_MOUSE_HOVER, cur_rel_x, cur_rel_y); + gem_set_cursor(&gem_cursors.arrow); + } + } } @@ -97,15 +446,10 @@ struct atari_treeview_window * atari_treeview_create(GUIWIN *win, struct atari_treeview_callbacks * callbacks, uint32_t flags) { -/* - init_func(); - - sslcert_viewer_init(&cw_t, (struct core_window *)tree, - ssl_current_session); -*/ /* allocate the core_window struct: */ struct atari_treeview_window * cw; + struct gemtk_wm_scroll_info_s *slid; cw = calloc(sizeof(struct atari_treeview_window), 1); if (cw == NULL) { @@ -114,9 +458,24 @@ atari_treeview_create(GUIWIN *win, struct atari_treeview_callbacks * callbacks, return NULL; } + /* Store the window ref inside the new treeview: */ cw->window = win; cw->io = callbacks; + // Setup gemtk event handler function: + gemtk_wm_set_event_handler(win, handle_event); + + // bind window user data to treeview ref: + gemtk_wm_set_user_data(win, (void*)cw); + + // Get acces to the gemtk scroll info struct: + slid = gemtk_wm_get_scroll_info(cw->window); + + // Setup line and column height/width of the window, + // each scroll takes the configured steps: + slid->y_unit_px = 16; + slid->x_unit_px = 16; + assert(cw->io); assert(cw->io->init); @@ -145,7 +504,6 @@ void atari_treeview_delete(struct atari_treeview_window * cw) * Core Window Callbacks: */ - /** * Request a redraw of the window * @@ -158,27 +516,7 @@ void atari_treeview_redraw_request(struct core_window *cw, const struct rect *r) RECT_TO_GRECT(r, &area) - if (cw != NULL) { - ATARI_TREEVIEW tv = (ATARI_TREEVIEW) cw; - if( tv->redraw == false ){ - tv->redraw = true; - tv->rdw_area.g_x = area.g_x; - tv->rdw_area.g_y = area.g_y; - tv->rdw_area.g_w = area.g_w; - tv->rdw_area.g_h = area.g_h; - } else { - /* merge the redraw area to the new area.: */ - int newx1 = area.g_x+area.g_w; - int newy1 = area.g_y+area.g_h; - int oldx1 = tv->rdw_area.g_x + tv->rdw_area.g_w; - int oldy1 = tv->rdw_area.g_y + tv->rdw_area.g_h; - tv->rdw_area.g_x = MIN(tv->rdw_area.g_x, area.g_x); - tv->rdw_area.g_y = MIN(tv->rdw_area.g_y, area.g_y); - tv->rdw_area.g_w = ( oldx1 > newx1 ) ? oldx1 - tv->rdw_area.g_x : newx1 - tv->rdw_area.g_x; - tv->rdw_area.g_h = ( oldy1 > newy1 ) ? oldy1 - tv->rdw_area.g_y : newy1 - tv->rdw_area.g_y; - } - // dbg_grect("atari_treeview_request_redraw", &tv->rdw_area); - } + atari_treeview_redraw_grect_request(cw, &area); } /** -- cgit v1.2.3