def __init__(self, master, theme): w,h = 32, 256 self.theme = theme self.master = master self.master.overrideredirect(True) # ========================================== # Main window frame # ========================================== topFrame = Frame(master, border=4, bg=hex_colour(theme.popup)) topFrame.pack() frame = LabelFrame(topFrame, border=3, relief=FLAT, fg=hex_colour(theme.text), bg=hex_colour(theme.menu_back), text=ADD_SCULPT_MESH_LABEL, labelanchor=NW) frame.pack(anchor=CENTER) # ========================================== # Geometry section (top left) # ========================================== upperFrame = Frame(frame, bg=hex_colour(theme.menu_back)) upperFrame.pack() f = LabelFrame(upperFrame, text="Geometry", bg= hex_colour(theme.menu_back), fg=hex_colour(theme.text)) f.pack(padx=5, pady=5, fill=BOTH, side=LEFT, anchor=CENTER ) ff = Frame(f, bg=hex_colour(theme.menu_back)) ff.pack() fx = Frame(ff, bg=hex_colour(theme.menu_back)) fx.pack() t = Label(fx, text="X Faces", justify=RIGHT, bg=hex_colour(theme.menu_back), fg=hex_colour(theme.text)) t.pack(padx=5, pady=5, side=LEFT) self.x_faces = IntVar(self.master, 8) s = Spinbox(fx, textvariable=self.x_faces, from_=1, to=256, width=3, bg=hex_colour(theme.num), fg=hex_colour(theme.text), activebackground=hex_colour(theme.setting)) s.pack(padx=5, pady=5, side=RIGHT) fy = Frame(ff, bg=hex_colour(theme.menu_back)) fy.pack() t = Label(fy, text="Y Faces", justify=RIGHT, bg=hex_colour(theme.menu_back), fg=hex_colour(theme.text)) t.pack(padx=5, pady=5, side=LEFT) self.y_faces = IntVar(self.master, 8) s = Spinbox(fy, textvariable=self.y_faces, from_=1, to=256, width=3, bg=hex_colour(theme.num), fg=hex_colour(theme.text), activebackground=hex_colour(theme.setting)) s.pack(padx=5, pady=5, side=RIGHT) self.clean_lods = BooleanVar( self.master, True ) c = Checkbutton(f, text="Clean LODs", variable=self.clean_lods, bg=hex_colour(theme.menu_back), fg=hex_colour(theme.text), activebackground=hex_colour(theme.setting), border=2, highlightthickness=0) c.pack(padx=0, pady=5, side=LEFT) # ========================================== # Subdivision section (top right) # ========================================== fs = LabelFrame(upperFrame, text="Subdivision", bg= hex_colour(theme.menu_back), fg=hex_colour(theme.text)) fs.pack(padx=5, pady=5, fill=BOTH, side=RIGHT, anchor=CENTER ) self.levels = IntVar(self.master, 2) fl = Frame(fs, bg=hex_colour(theme.menu_back)) fl.pack() t = Label(fl, text="Levels", justify=RIGHT, bg=hex_colour(theme.menu_back), fg=hex_colour(theme.text)) t.pack(padx=5, pady=5, side=LEFT) s = Spinbox(fl, textvariable=self.levels, from_=0, to=6, width=3, bg=hex_colour(theme.num), fg=hex_colour(theme.text), activebackground=hex_colour(theme.setting)) s.pack(padx=5, pady=5, side=RIGHT) self.subdivision = IntVar(self.master, 1) r = Frame(fs, bg=hex_colour(theme.menu_back)) r.pack(side=LEFT) Radiobutton(r, text="Catmull", variable=self.subdivision, highlightthickness=0, bg=hex_colour(theme.menu_back), value=1).pack() Radiobutton(r, text="Simple", variable=self.subdivision, highlightthickness=0, bg=hex_colour(theme.menu_back), value=0).pack() self.sub_type = IntVar(self.master, 1) r = Frame(fs, bg=hex_colour(theme.menu_back)) r.pack(side=RIGHT) Radiobutton(r, text="Subsurf", variable=self.sub_type, highlightthickness=0, bg=hex_colour(theme.menu_back), value=1).pack() Radiobutton(r, text="Multires", variable=self.sub_type, highlightthickness=0, bg=hex_colour(theme.menu_back), value=0).pack() # ========================================== # LOD display (bottom left) # ========================================== f = LabelFrame(frame, text="Map Image", bg=hex_colour(theme.menu_back), fg=hex_colour(theme.text)) f.pack(padx=6, ipadx=3, pady=3, fill=BOTH, side=LEFT, anchor=CENTER) self.lod_display = Label(f, text=sculpty.lod_info(w, h)[:-1], justify=LEFT, bg=hex_colour(theme.menu_back), fg=hex_colour(theme.text)) self.lod_display.pack(padx=5, pady=5, ipadx=3, ipady=3, side=LEFT) # ========================================== # Sculpty type selection (bottom right) # ========================================== controlFrame = Frame(frame,bg=hex_colour(theme.menu_back)) controlFrame.pack(padx=5, pady=6, fill=Y, side=RIGHT, anchor=N) self.map_type = Button(controlFrame, text="Type", command=self.set_map_type, border=1, bg=hex_colour(theme.menu_hilite), fg=hex_colour(theme.menu_text_hi), activebackground=hex_colour(theme.setting)) self.map_type.pack(padx=4, fill=X, pady=5, side=TOP, anchor=CENTER) self.sculpt_menu = Menu(controlFrame, tearoff=0, background=hex_colour(theme.menu_back), foreground=hex_colour(theme.menu_text), activebackground=hex_colour(theme.menu_hilite), activeforeground=hex_colour(theme.menu_text_hi) ) for sculpt_type in [ "Sphere", "Torus", "Plane", "Cylinder", "Hemi"]: def type_command( sculpt_type ): def new_command(): self.set_sculpt_type(sculpt_type) return new_command self.sculpt_menu.add_command(label=sculpt_type, command=type_command(sculpt_type)) library = sculpty.build_lib(LibDir=MenuDir, LibFile=MenuMap) library.add_to_menu(self, self.sculpt_menu) self.selector = self.map_type self.set_sculpt_type("Sphere") # TODO: retrieve settings from registry # ========================================== # Control section (bottom right) # ========================================== buttonFrame = Frame(controlFrame, bg=hex_colour(theme.menu_back)) buttonFrame.pack(side=BOTTOM, anchor=CENTER) # Cancel/Create buttons need layout tuning. createButton = Button(buttonFrame, text="Create", command=self.add, border=1, default=ACTIVE, bg=hex_colour(theme.action), activebackground=hex_colour(theme.action), fg=hex_colour(theme.text), activeforeground=hex_colour(theme.text_hi)) createButton.pack( ipadx=7 , padx=8, pady=0, side=RIGHT, anchor=SE) b = Button(buttonFrame, text="Cancel", command=self.master.quit, border=1, bg=hex_colour(theme.action), activebackground=hex_colour(theme.action), fg=hex_colour(theme.text), activeforeground=hex_colour(theme.text_hi)) b.pack( ipadx=7, padx=4, pady=0, side=LEFT, anchor=SW) # =============================================================== # Make master window sticky. # Bind <Leave> and <Enter> events to the top window # And preset "mouse is in app" and "no selection active" # =============================================================== self.master.wm_attributes("-topmost", 1) # Make sure window remains on top of all others self.master.bind( "<Leave>", self.mouse_leave_handler) # track leave main window self.master.bind( "<Enter>", self.mouse_enter_handler) # track enter main window self.set_mouse_in_app(True) self.selectorActive = False self.master.configure(takefocus=True) createButton.focus_force()
def __init__(self, master): self.master = master self.cube_icon = gui.BitmapImage( data="""#define cube_width 16 #define cube_height 16 static unsigned char cube_bits[] = { 0x00, 0x00, 0x80, 0x03, 0x70, 0x1c, 0x8c, 0x62, 0x94, 0x53, 0x64, 0x4c, 0xa4, 0x4b, 0x2c, 0x69, 0x34, 0x59, 0x64, 0x4d, 0xa4, 0x4b, 0x2c, 0x69, 0x30, 0x19, 0x40, 0x05, 0x80, 0x03, 0x00, 0x00 }; """ ) self.file_icon = gui.BitmapImage( data="""#define file_open_width 16 #define file_open_height 16 static unsigned char file_open_bits[] = { 0x00, 0x00, 0x08, 0x00, 0x0c, 0x00, 0xfe, 0x01, 0x0c, 0x02, 0x08, 0x04, 0x00, 0x04, 0xf0, 0x00, 0x08, 0x7f, 0xf8, 0x40, 0x08, 0x40, 0x08, 0x40, 0x08, 0x40, 0x08, 0x40, 0xf8, 0x7f, 0x00, 0x00 }; """ ) # ========================================== # Main window frame # ========================================== top_frame = gui.Frame(self.master, border=4) top_frame.pack() frame = gui.LabelFrame(top_frame, text=LABEL, labelanchor=NW) frame.pack() # ========================================== # Settings frame # ========================================== shape_frame = gui.Frame(frame) shape_frame.pack(fill=X) t = gui.Label(shape_frame, text="Shape", justify=RIGHT, font=("Helvetica", 9, "bold")) t.pack(side=LEFT) self.shape_name = StringVar(self.master) self.shape_name.set(settings["shape_name"]) self.shape_file = settings["shape_file"] self.map_type = gui.Button( shape_frame, textvariable=self.shape_name, command=self.set_map_type, cursor="based_arrow_down", background=gui.hex_color(gui.theme.ui.textfield), relief=SUNKEN, pady=1, anchor=NW, ) self.map_type.pack(expand=True, fill=X, side=LEFT) file_button = gui.Button( shape_frame, image=self.file_icon, compound=LEFT, command=self.set_file, default=ACTIVE ) file_button.pack(side=RIGHT) # ========================================== # Geometry section # ========================================== f = gui.LabelFrame(frame, text="Geometry") f.pack(side=LEFT, fill=Y) fx = gui.Frame(f) fx.pack(expand=True) t = gui.Label(fx, text="X Faces", justify=RIGHT) t.pack(side=LEFT) self.x_faces = IntVar(self.master) self.x_faces.set(settings["x_faces"]) self.x_faces_input = gui.Spinbox( fx, textvariable=self.x_faces, from_=1, to=256, width=3, command=self.update_info ) self.x_faces_input.bind("<Key>", self.update_info) self.x_faces_input.pack(side=RIGHT) fy = gui.Frame(f) fy.pack(expand=True) t = gui.Label(fy, text="Y Faces", justify=RIGHT) t.pack(side=LEFT) self.y_faces = IntVar(self.master) self.y_faces.set(settings["y_faces"]) self.y_faces_input = gui.Spinbox( fy, textvariable=self.y_faces, from_=1, to=256, width=3, command=self.update_info ) self.y_faces_input.bind("<Key>", self.update_info) self.y_faces_input.pack(side=RIGHT) fr = gui.Frame(f) fr.pack(expand=True) t = gui.Label(fr, text="Radius", justify=RIGHT) t.pack(side=LEFT) self.radius = DoubleVar(self.master) self.radius.set(settings["radius"]) self.radius_input = gui.Spinbox( fr, textvariable=self.radius, from_=0.05, to=0.5, increment=0.025, format="%4.3f", width=5 ) self.radius_input.pack(side=RIGHT) self.clean_lods = BooleanVar(self.master) self.clean_lods.set(settings["clean_lods"]) self.clean_lods_input = gui.Checkbutton( f, text="Clean LODs", variable=self.clean_lods, command=self.update_info ) self.clean_lods_input.pack(expand=True) # ========================================== # Subdivision section # ========================================== middle_frame = gui.Frame(frame) middle_frame.pack(side=LEFT, padx=4, fill=BOTH) fs = gui.LabelFrame(middle_frame, text="Subdivision") fs.pack(fill=X) self.levels = IntVar(self.master) self.levels.set(settings["levels"]) fl = gui.Frame(fs) fl.pack() t = gui.Label(fl, text="Levels", justify=RIGHT) t.pack(side=LEFT) self.levels_input = gui.Spinbox(fl, textvariable=self.levels, from_=0, to=6, width=3, command=self.update_info) self.levels_input.bind("<Key>", self.update_info) self.levels_input.pack(side=RIGHT) self.sub_type = IntVar(self.master) self.sub_type.set(settings["sub_type"]) r = gui.Frame(fs) r.pack(side=LEFT) gui.Radiobutton(r, text="Subsurf", variable=self.sub_type, value=1).pack() gui.Radiobutton(r, text="Multires", variable=self.sub_type, value=0).pack() self.subdivision = IntVar(self.master) self.subdivision.set(settings["subdivision"]) r = gui.Frame(fs) r.pack(side=RIGHT) gui.Radiobutton(r, text="Catmull", variable=self.subdivision, value=1).pack() gui.Radiobutton(r, text="Simple", variable=self.subdivision, value=0).pack() # ========================================== # Mesh Type Selection # ========================================== mesh_frame = gui.LabelFrame(middle_frame, text="Mesh Type") mesh_frame.pack(fill=X) self.quads = IntVar(self.master) self.quads.set(settings["quads"]) gui.Radiobutton(mesh_frame, text="Quads", variable=self.quads, value=1).pack(side=LEFT) gui.Radiobutton(mesh_frame, state=DISABLED, text="Triangles", variable=self.quads, value=0).pack(side=LEFT) # ========================================== # LOD display and Create button # ========================================== build_frame = gui.Frame(frame) build_frame.pack(fill=Y, side=LEFT) self.info_text = StringVar(self.master) self.info_frame = gui.LabelFrame(build_frame) self.info_frame.pack() self.lod_display = gui.Label(self.info_frame, textvariable=self.info_text, justify=LEFT) self.lod_display.pack() self.create_button = gui.Button( build_frame, text="Build", image=self.cube_icon, compound=LEFT, command=self.add, default=ACTIVE ) self.create_button.pack(fill=BOTH, expand=True, anchor=SE, pady=5) self.update_info() # ========================================== # Save settings frame # ========================================== self.save_defaults = BooleanVar(self.master) self.save_defaults.set(False) self.save_settings = BooleanVar(self.master) self.save_settings.set(settings["save"]) save_frame = gui.Frame(build_frame) save_frame.pack(fill=Y) t = gui.Checkbutton(save_frame, text="Save", variable=self.save_settings) t.pack(side=LEFT) t = gui.Checkbutton(save_frame, text="Defaults", variable=self.save_defaults) t.pack(side=LEFT) # ========================================== # Popup menu for base mesh shape # ========================================== self.sculpt_menu = gui.Menu(self.master, tearoff=0) for sculpt_type in ["Cylinder", "Hemi", "Plane", "Sphere", "Torus X", "Torus Z"]: def type_command(sculpt_type): def new_command(): self.set_shape(sculpt_type) return new_command self.sculpt_menu.add_command(label=sculpt_type, command=type_command(sculpt_type)) self.sculpt_menu.add_separator() library = sculpty.build_lib(LibDir=MenuDir, LibFile=MenuMap) library.add_to_menu(self, self.sculpt_menu) self.set_shape(settings["shape_name"], settings["shape_file"]) self.master.bind("<Button-1>", self.click_handler)
def __init__(self, master): self.master = master self.cube_icon = gui.BitmapImage(data="""#define cube_width 16 #define cube_height 16 static unsigned char cube_bits[] = { 0x00, 0x00, 0x80, 0x03, 0x70, 0x1c, 0x8c, 0x62, 0x94, 0x53, 0x64, 0x4c, 0xa4, 0x4b, 0x2c, 0x69, 0x34, 0x59, 0x64, 0x4d, 0xa4, 0x4b, 0x2c, 0x69, 0x30, 0x19, 0x40, 0x05, 0x80, 0x03, 0x00, 0x00 }; """) self.file_icon = gui.BitmapImage(data="""#define file_open_width 16 #define file_open_height 16 static unsigned char file_open_bits[] = { 0x00, 0x00, 0x08, 0x00, 0x0c, 0x00, 0xfe, 0x01, 0x0c, 0x02, 0x08, 0x04, 0x00, 0x04, 0xf0, 0x00, 0x08, 0x7f, 0xf8, 0x40, 0x08, 0x40, 0x08, 0x40, 0x08, 0x40, 0x08, 0x40, 0xf8, 0x7f, 0x00, 0x00 }; """) # ========================================== # Main window frame # ========================================== top_frame = gui.Frame(self.master, border=4) top_frame.pack() frame = gui.LabelFrame(top_frame, text=LABEL, labelanchor=NW) frame.pack() # ========================================== # Settings frame # ========================================== shape_frame = gui.Frame(frame) shape_frame.pack(fill=X) t = gui.Label(shape_frame, text="Shape", justify=RIGHT, font=('Helvetica', 9, 'bold')) t.pack(side=LEFT) self.shape_name = StringVar(self.master) self.shape_name.set(settings['shape_name']) self.shape_file = settings['shape_file'] self.map_type = gui.Button(shape_frame, textvariable=self.shape_name, command=self.set_map_type, cursor='based_arrow_down', background=gui.hex_color( gui.theme.ui.textfield), relief=SUNKEN, pady=1, anchor=NW) self.map_type.pack(expand=True, fill=X, side=LEFT) file_button = gui.Button(shape_frame, image=self.file_icon, compound=LEFT, command=self.set_file, default=ACTIVE) file_button.pack(side=RIGHT) # ========================================== # Geometry section # ========================================== f = gui.LabelFrame(frame, text="Geometry") f.pack(side=LEFT, fill=Y) fx = gui.Frame(f) fx.pack(expand=True) t = gui.Label(fx, text="X Faces", justify=RIGHT) t.pack(side=LEFT) self.x_faces = IntVar(self.master) self.x_faces.set(settings['x_faces']) self.x_faces_input = gui.Spinbox(fx, textvariable=self.x_faces, from_=1, to=256, width=3, command=self.update_info) self.x_faces_input.bind('<Key>', self.update_info) self.x_faces_input.pack(side=RIGHT) fy = gui.Frame(f) fy.pack(expand=True) t = gui.Label(fy, text="Y Faces", justify=RIGHT) t.pack(side=LEFT) self.y_faces = IntVar(self.master) self.y_faces.set(settings['y_faces']) self.y_faces_input = gui.Spinbox(fy, textvariable=self.y_faces, from_=1, to=256, width=3, command=self.update_info) self.y_faces_input.bind('<Key>', self.update_info) self.y_faces_input.pack(side=RIGHT) fr = gui.Frame(f) fr.pack(expand=True) t = gui.Label(fr, text="Radius", justify=RIGHT) t.pack(side=LEFT) self.radius = DoubleVar(self.master) self.radius.set(settings['radius']) self.radius_input = gui.Spinbox(fr, textvariable=self.radius, from_=0.05, to=0.5, increment=0.025, format="%4.3f", width=5) self.radius_input.pack(side=RIGHT) self.clean_lods = BooleanVar(self.master) self.clean_lods.set(settings['clean_lods']) self.clean_lods_input = gui.Checkbutton(f, text="Clean LODs", variable=self.clean_lods, command=self.update_info) self.clean_lods_input.pack(expand=True) # ========================================== # Subdivision section # ========================================== middle_frame = gui.Frame(frame) middle_frame.pack(side=LEFT, padx=4, fill=BOTH) fs = gui.LabelFrame(middle_frame, text="Subdivision") fs.pack(fill=X) self.levels = IntVar(self.master) self.levels.set(settings['levels']) fl = gui.Frame(fs) fl.pack() t = gui.Label(fl, text="Levels", justify=RIGHT) t.pack(side=LEFT) self.levels_input = gui.Spinbox(fl, textvariable=self.levels, from_=0, to=6, width=3, command=self.update_info) self.levels_input.bind('<Key>', self.update_info) self.levels_input.pack(side=RIGHT) self.sub_type = IntVar(self.master) self.sub_type.set(settings['sub_type']) r = gui.Frame(fs) r.pack(side=LEFT) gui.Radiobutton(r, text="Subsurf", variable=self.sub_type, value=1).pack() gui.Radiobutton(r, text="Multires", variable=self.sub_type, value=0).pack() self.subdivision = IntVar(self.master) self.subdivision.set(settings['subdivision']) r = gui.Frame(fs) r.pack(side=RIGHT) gui.Radiobutton(r, text="Catmull", variable=self.subdivision, value=1).pack() gui.Radiobutton(r, text="Simple", variable=self.subdivision, value=0).pack() # ========================================== # Mesh Type Selection # ========================================== mesh_frame = gui.LabelFrame(middle_frame, text="Mesh Type") mesh_frame.pack(fill=X) self.quads = IntVar(self.master) self.quads.set(settings['quads']) gui.Radiobutton(mesh_frame, text="Quads", variable=self.quads, value=1).pack(side=LEFT) gui.Radiobutton(mesh_frame, state=DISABLED, text="Triangles", variable=self.quads, value=0).pack(side=LEFT) # ========================================== # LOD display and Create button # ========================================== build_frame = gui.Frame(frame) build_frame.pack(fill=Y, side=LEFT) self.info_text = StringVar(self.master) self.info_frame = gui.LabelFrame(build_frame) self.info_frame.pack() self.lod_display = gui.Label(self.info_frame, textvariable=self.info_text, justify=LEFT) self.lod_display.pack() self.create_button = gui.Button(build_frame, text="Build", image=self.cube_icon, compound=LEFT, command=self.add, default=ACTIVE) self.create_button.pack(fill=BOTH, expand=True, anchor=SE, pady=5) self.update_info() # ========================================== # Save settings frame # ========================================== self.save_defaults = BooleanVar(self.master) self.save_defaults.set(False) self.save_settings = BooleanVar(self.master) self.save_settings.set(settings['save']) save_frame = gui.Frame(build_frame) save_frame.pack(fill=Y) t = gui.Checkbutton(save_frame, text="Save", variable=self.save_settings) t.pack(side=LEFT) t = gui.Checkbutton(save_frame, text="Defaults", variable=self.save_defaults) t.pack(side=LEFT) # ========================================== # Popup menu for base mesh shape # ========================================== self.sculpt_menu = gui.Menu(self.master, tearoff=0) for sculpt_type in [ "Cylinder", "Hemi", "Plane", "Sphere", "Torus X", "Torus Z" ]: def type_command(sculpt_type): def new_command(): self.set_shape(sculpt_type) return new_command self.sculpt_menu.add_command(label=sculpt_type, command=type_command(sculpt_type)) self.sculpt_menu.add_separator() library = sculpty.build_lib(LibDir=MenuDir, LibFile=MenuMap) library.add_to_menu(self, self.sculpt_menu) self.set_shape(settings['shape_name'], settings['shape_file']) self.master.bind('<Button-1>', self.click_handler)