% ************************************* % % FUNCTIONS FOR MANIPULATING THE WINDOW % % ************************************* % % This datatype describes the current state of the window % datatype wstate(w_window, % The bounding boxes for different zoom levels % [((float,float),(float,float))], % The points and their values % [(float,(float,float))], % The segments drawn on the window along with their color and width % [([((float,float),(float,float))],int,int)], % The arrows drawn on the window along with their color % [((float,float),(float,float))],int); function empty_window_state(win,bounding_box) = let segs = [] ([((float,float),(float,float))],int,int); arrows = ([] ((float,float),(float,float)),w_red); wpoints = [] (float,(float,float)); box = w_get_named_box("mesh",win); ignore = w_clear_box(box); in wstate(win,[bounding_box],wpoints,segs,arrows) $ function add_segments(segs,width,color,window_state) = let wstate(win,bbox,pts,seg_list,alist) = window_state; box = w_get_named_box("mesh",win); foo = w_clip_and_draw_segments(segs,width,color,box); seg_list = seg_list++[(segs,width,color)]; in wstate(win,bbox,pts,seg_list,alist) $ function add_arrows(arrows,color,window_state) = let wstate(win,bbox,pts,seg_list,alist) = window_state; box = w_get_named_box("mesh",win); scale = w_box_scale(box); scale = (5./max_val({sqrt(xg^2+yg^2): (x0,y0),(xg,yg) in arrows}))/scale; arrows = {let xd,yd = xg*scale,yg*scale in (x0-xd,y0-yd),(x0+xd,y0+yd) : (x0,y0),(xg,yg) in arrows}; ignore = {w_draw_arrow(arrow,1,(7,5),color,box): arrow in arrows}; in wstate(win,bbox,pts,seg_list,(arrows,color)) $ function add_points(points,window_state) = let wstate(win,bbox,pts,seg_list,alist) = window_state; box = w_get_named_box("mesh",win); ignore = {w_draw_big_point(pt,5,round(x*62.),box): (x,pt) in points}; in wstate(win,bbox,points,seg_list,alist) $ function draw_triangles(triangles,window_state) = let wstate(win,bbox,pts,seg_list,alist) = window_state; box = w_get_named_box("mesh",win); ignore = {w_shade_polygon(poly,w_yellow,box): poly in triangles}; in window_state $ % Redraws the current window using the bounding box at the top of the list of bounding boxes % function draw(window_state) = let wstate(win,bboxes,points,seg_list,(arrows,acol)) = window_state; box = w_get_named_box("mesh",win); win,box = w_reset_box_size("mesh",bboxes[0],win); ignore = w_clear_box(box); ignore = {w_clip_and_draw_segments(segs,w,c,box) : (segs,w,c) in seg_list}; ignore = {w_draw_big_point(pt,5,round(x*62.),box): (x,pt) in points}; ignore = {w_draw_arrow(arrow,1,(7,5),acol,box): arrow in arrows}; in wstate(win,bboxes,points,seg_list,(arrows,acol)) $ function write_note(str,window_state) = let wstate(win,rest) = window_state; in w_write_paragraph(str,w_black,w_get_named_box("note",win)) $ function write_help(str,window_state) = let wstate(win,rest) = window_state; in w_write_paragraph(str,w_black,w_get_named_box("help",win)) $ function nobox(pt,(d,h)) = (d == 0.0) or (h == 0.0) $ function get_zoom_box(pt,window_state) = let wstate(win,topbox,rest) = window_state; box = w_get_named_box("mesh",win); in w_get_zoom_box(pt,2,box) $ function find_point((x0,y0),points) = min_index({(x0-x)^2+(y0-y)^2 : (v,(x,y)) in points}) $ function zoom_loop(window_state) = let wstate(win,bound_boxes,points,segs,arrows) = window_state; type,name,pt,(state,button),ch = w_get_input(win); in % QUIT % if (eql(type,"button") and eql(name,"quit")) or (ch==`q) then f,window_state % STEP % else if (eql(type,"button") and eql(name,"step")) then t,window_state %else if eql(type,"click") and (button == 1) then let foo = print_line(@find_point(pt,points)); in zoom_loop(window_state)% % ZOOM IN ON MIDDLE BUTTON CLICK % else if eql(type,"click") and (button == 2) then let zbox = get_zoom_box(pt,window_state); in if nobox(zbox) then zoom_loop(window_state) else zoom_loop(draw(wstate(win,[zbox]++bound_boxes,points,segs, arrows))) % ZOOM OUT % else if (eql(type,"button") and eql(name,"zoom up")) then let window_state= if #bound_boxes == 1 then window_state else draw(wstate(win,drop(bound_boxes,1),points,segs, arrows)) in zoom_loop(window_state) else zoom_loop(window_state) $ function wait_for_step(window_state) = let foo = write_help("Use the middle button to Zoom In: Press and Drag", window_state); fl,window_state = zoom_loop(window_state); foo = write_help("Hold on, Working...",window_state); in fl,window_state $