#include #include /********************************************************************* * Parameters */ boolean retained = false; boolean savebehind = false; boolean resizable = false; boolean dragable = true; persist(dragframeonly); canvastype cv = nullcanvas; /********************************************************************* * create and manage the canvas */ void canvaspath() { path(); } void oninit() { visible = false; super.oninit(); } boolean mapped() { return visible; } void map() { if (!visible) { visible = true; onopen(); } } void unmap() { if (visible) { onclose(); visible = false; } } void gstart() { if (!promoted(/cv)) { cv = new_canvas(framebuffer); cv.SaveBehind = savebehind; cv.Retained = retained; greset(); map_canvas(cv); gsave(); setcanvas(cv); setcolor(BG); clippath(); fill(); grestore(); } } void gstop() { if (promoted(/cv)) { unmap_canvas(cv); unpromote(/cv); } } void greset() { drawable m; if (promoted(/cv)) { gsave(); setcanvas(framebuffer); concat(mx); canvaspath(); reshape_canvas(cv); forall (; m ; members) m.greset(); grestore(); } } void ginit() { setcanvas(cv); } /********************************************************************* * Paint a nice border */ void Paint() { clippath(); setcolor(BG); fill(); setcolor(FG); rectpath(0,1,w-1,h-1); stroke(); } /********************************************************************* * Move the canvas */ void move(float X, float Y) { if ((x != X) || (y != Y)) { softpromote(/mx,mtranslate(mx,X,Y)); if (promoted(/cv)) move_canvas(cv,X,Y); } } /********************************************************************* * Dragging */ void trackdragcanvas() { rmove(trackdx,trackdy); track_start_event(track_event); } void dragcanvas() { gsave(); setcanvas(cv.Parent); track(/trackdragcanvas); grestore(); } void trackdragframe() { gsave(); concat(mtranslate(mx,x + trackdx,y + trackdy)); path(); stroke(); grestore(); } void dragframe() { gsave(); setcanvas(cv.Parent); if (track_overlay(/trackdragframe) == /mouse_up) rmove(trackdx,trackdy); grestore(); } void drag() { if (dragable) { if (dragframeonly) dragframe(); else dragcanvas(); } } /********************************************************************* * Resizing */ float trackmx; float trackmy; float trackfx; float trackfy; rectangle resizerect() { float X, Y, W, H; if (trackfx < trackmx) { X = trackfx; W = max(minwidth,(trackmx + trackdx) - trackfx); } else { X = min(trackfx-minwidth,trackmx + trackdx); W = trackfx - X; } if (trackfy < trackmy) { Y = trackfy; H = max(minwidth,(trackmy + trackdy) - trackfy); } else { Y = min(trackfy-minwidth,trackmy + trackdy); H = trackfy - Y; } return [X,Y,W,H]; } void resizetrack() { rectpath(resizerect()); stroke(); } void resizeframe(float MX, float MY, float FX, float FY) { rectangle r; if (dragable && resizable) { trackmx = MX; trackmy = MY; trackfx = FX; trackfy = FY; gsave(); setcanvas(cv.Parent); translate(x,y); track_overlay(/resizetrack); r = resizerect(); reshape(x + r[0], y + r[1],r[2],r[3]); grestore(); unpromote(/trackmx); unpromote(/trackmy); unpromote(/trackfx); unpromote(/trackfy); } } void resizeSW() { resizeframe(0,0,w,h); } void resizeNW() { resizeframe(0,h,w,0); } void resizeNE() { resizeframe(w,h,0,0); } void resizeSE() { resizeframe(w,0,0,h); } /********************************************************************* * top/bottom */ void totop() { if (promoted(/cv)) totop_canvas(cv); Send totop() to @freezer; } void tobottom() { if (promoted(/cv)) tobottom_canvas(cv); } /********************************************************************* * Open/Close */ void open() { map(); } void close() { unmap(); } /********************************************************************* * Focus management */ void set_focus(drawable newfocus) { drawable oldfocus; if ((oldfocus = @focus) == newfocus) return; if (oldfocus) { unpromote(/@focus); Send focus_change() to oldfocus; } if (newfocus) Send focus_change() to @focus = (drawable)soften(newfocus); } void handle_key(int k) { if ((!edit_mode) && (!@freezer)) Send onkey(k) to @focus; } void handle_enter() { if ((!edit_mode) && (!@freezer)) { Send focus_change(); Send focus_change() to @focus; } } void handle_exit() { if ((!edit_mode) && (!@freezer)) { Send focus_change() to @focus; Send focus_change(); } } /********************************************************************* * freezing */ void fost_change() { } void freeze(drawable freezer) { if (!promoted(/@freezer)) { @freezer = freezer; Send focus_change(); Send frost_change(); } } void defrost() { if (promoted(/@freezer)) { unpromote(/@freezer); Send frost_change(); Send focus_change(); } else if (@freezer) Send defrost() to @parent; } /********************************************************************* * Event management */ void OnSelect2() { } void OnSelect() { switch (track_state()) { case /mouse_drag: Send drag(); break; case /mouse_click: if (mouselevel >= 2) Send OnSelect2(); else Send totop(); break; case /mouse_cancel: break; } } /********************************************************************* * Event management */ void select_click() { drawable d; if (!edit_mode) { if (@freezer) totop(); else if (d = hit(mouseevent)) Send onselect() to d; else onselect(); } } void adjust_click() { drawable d; if (!edit_mode) { if (@freezer) totop(); else if (d = hit(mouseevent)) Send onadjust() to d; else onadjust(); } } void menu_click() { drawable d; if (!edit_mode) { if (@freezer) totop(); else if (d = hit(mouseevent)) Send onmenu() to d; else onmenu(); } } void handle_select_click() { Send select_click(); } void handle_adjust_click() { Send adjust_click(); } void handle_menu_click() { Send menu_click(); } /* void paint() { int t = currenttimems, i, N = 5; for (i = 0 ; i < N ; i++) super.paint(); DEBUG("paint = %ms",[(currenttimems - t)/N]); } void fix() { int t = currenttimems, i, N = 5; for (i = 0 ; i < N ; i++) super.fix(); DEBUG("fix = %ms",[(currenttimems - t)/N]); } */ void handle_damage() { Send fix(); } void handle_function(name f) { } void test_save() { save_object(file("test.window","w"),self); DEBUG("window % saved to ~/test.window",[namestr]); }