# New grid options dialog prototype # Copyright 2003 Nathan Hurst import pygtk pygtk.require('2.0') import gtk import pango def draw_pango_string(widget, gc, s, x, y): context = widget.get_pango_context() pfd = pango.FontDescription("Sans 10") context.set_font_description(pfd) pl = pango.Layout(context); pl.set_width(1024*1000); pl.set_markup(s); gtk.gdk.Drawable.draw_layout(widget.window, gc, x, y, pl); window = gtk.Window() vbox = gtk.VBox(gtk.FALSE, 0) notebook = gtk.Notebook() l = gtk.Label('') ; l.set_text_with_mnemonic('_Grid') notebook.append_page(vbox, l) hbox = gtk.HBox(gtk.TRUE, 0) vbox.pack_start(hbox, 0,0) show_grid = gtk.CheckButton("Show Grid") show_grid.set_active(1) hbox.pack_start(show_grid, 0, 0) enable_grid = gtk.CheckButton("Snap to Grid") enable_grid.set_active(1) hbox.pack_start(enable_grid, 0, 0) import math r = 50 gridlines = map(lambda t:(r*math.cos(2*t*math.pi/3), r*math.sin(2*t*math.pi/3)), range(3)) #gridlines[0] = (gridlines[0][0]/2,gridlines[0][1]/2) def redraw_da(widget, event): xsize,ysize = widget.get_allocation().width,widget.get_allocation().height cx = xsize /2 cy = ysize/2 drawable = widget.window black_gc = widget.get_style().black_gc gtk.gdk.Drawable.draw_line(drawable, black_gc, cx-2, cy, cx+2, cy) gtk.gdk.Drawable.draw_line(drawable, black_gc, cx, cy-2, cx, cy+2) for dx, dy in gridlines: gtk.gdk.Drawable.draw_line(drawable, black_gc, cx, cy, dx+cx,dy+cy) gtk.gdk.Drawable.draw_arc(drawable, black_gc, 1, dx+cx-5, dy+cy-5, 10,10, 0, 360*64) delta = math.hypot(xsize*dy, - ysize*dx) l = int(delta/(2*math.hypot(dx,dy))) ddx = dx/math.hypot(dx,dy) ddy = dy/math.hypot(dx,dy) for i in range(l): o = i-l/2 ox = ddy*delta oy = -ddx*delta x0 = dx*o - ox y0 = dy*o - oy x1 = dx*o + ox y1 = dy*o + oy gtk.gdk.Drawable.draw_line(drawable, black_gc, x0+cx, y0+cy, x1+cx,y1+cy) global selection if selection >= 0: dx,dy = gridlines[selection] draw_pango_string(widget, black_gc, "%.2fmm at\n%.2f°" % (math.hypot(dx,dy), math.atan2(-dy,dx)*180/math.pi), cx+dx, cy+dy) da = gtk.DrawingArea() vbox.pack_start(da, 1, 1, 5) da.set_size_request(200,200) da.connect('expose-event', redraw_da) add_vector = gtk.Button("Add a new gridline") vbox.pack_start(add_vector, 1, 0) def do_new_gridline(widget): global gridlines import random t = random.random() gridlines.append((r*math.cos(2*t*math.pi/3), r*math.sin(2*t*math.pi/3))) global da da.queue_draw() global selection selection = -1 add_vector.connect("clicked", do_new_gridline) selection = -1 vector_menu = gtk.Menu() deletemenuitem = gtk.MenuItem("Delete") vector_menu.append(deletemenuitem) deletemenuitem.show() def do_delete(widget): global selection if(selection >= 0): global gridlines gridlines = gridlines[:selection] + gridlines[selection+1:] selection = -1 deletemenuitem.connect("activate", do_delete) def mouse_click(widget,event): xsize,ysize = widget.get_allocation().width,widget.get_allocation().height cx = xsize /2 cy = ysize/2 global selection selection = 0 for dx, dy in gridlines: dist = math.hypot(event.x-cx-dx, event.y-cy-dy) if dist < 5: if event.button == 1: return if event.button == 3: global vector_menu vector_menu.popup(None, None, None, event.button, event.time) return selection += 1 selection = -1 def drag_motion(widget, event): xsize,ysize = widget.get_allocation().width,widget.get_allocation().height cx = xsize /2 cy = ysize/2 global selection if(selection >= 0): gridlines[selection] = (event.x-cx, event.y-cy) da.queue_draw() da.add_events(gtk.gdk.BUTTON_PRESS_MASK | gtk.gdk.BUTTON1_MOTION_MASK ) da.connect("button-press-event", mouse_click) da.connect("motion-notify-event", drag_motion) window.add(notebook) window.connect('destroy', lambda win: gtk.main_quit()) window.show_all() gtk.mainloop()