Esempio n. 1
0
	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()		
Esempio n. 2
0
    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)
Esempio n. 3
0
    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)