def __init__(self, shell): Screen.__init__(self, shell) self.model = DemoControlsModel() width_field = FloatField(ref=AttrRef(self.model, 'width')) height_field = FloatField(ref=AttrRef(self.model, 'height')) area_display = ValueDisplay(ref=AttrRef(self.model, 'area'), format="%.2f") shape = AttrRef(self.model, 'shape') shape_choices = Row([ RadioButton(setting='rectangle', ref=shape), Label("Rectangle"), RadioButton(setting='triangle', ref=shape), Label("Triangle"), RadioButton(setting='ellipse', ref=shape), Label("Ellipse"), ProgressBar(100, 50, ref=AttrRef(self.model, 'area')), ]) grid = Grid([ [Label("Width"), width_field], [Label("Height"), height_field], [Label("Shape"), shape_choices], [Label("Area"), area_display], ]) back = Button("Menu", action=shell.show_menu) contents = Column([grid, back]) self.add_centered(contents) width_field.focus()
def showProgress(progressText, progressIterator, cancel=False): """Show the progress for a long-running synchronous operation. progressIterator should be a generator-like object that can return either None, for an indeterminate indicator, A float value between 0.0 and 1.0 for a determinate indicator, A string, to update the progress info label or a tuple of (float value, string) to set the progress and update the label""" class ProgressWidget(Dialog): progressFraction = 0.0 firstDraw = False def draw(self, surface): Widget.draw(self, surface) frameStart = datetime.now() frameInterval = timedelta(0, 1, 0) / 2 amount = None try: while datetime.now() < frameStart + frameInterval: amount = progressIterator.next() if self.firstDraw is False: self.firstDraw = True break except StopIteration: self.dismiss() infoText = "" if amount is not None: if isinstance(amount, tuple): if len(amount) > 2: infoText = ": " + amount[2] amount, max = amount[:2] else: max = amount maxwidth = (self.width - self.margin * 2) if amount is None: self.progressBar.width = maxwidth self.progressBar.bg_color = (255, 255, 25, 255) elif isinstance(amount, basestring): self.statusText = amount else: self.progressAmount = amount if isinstance(amount, (int, float)): self.progressFraction = float(amount) / (float(max) or 1) self.progressBar.width = maxwidth * self.progressFraction self.statusText = str("{0} / {1}".format(amount, max)) else: self.statusText = str(amount) if infoText: self.statusText += infoText @property def estimateText(self): delta = ((datetime.now() - self.startTime)) progressPercent = (int(self.progressFraction * 10000)) left = delta * (10000 - progressPercent) / (progressPercent or 1) return "Time left: {0}".format(left) def cancel(self): if cancel: self.dismiss(False) def idleevent(self, evt): self.invalidate() widget = ProgressWidget() widget.progressText = progressText widget.statusText = "" widget.progressAmount = 0.0 progressLabel = ValueDisplay(ref=AttrRef(widget, 'progressText'), width=550) statusLabel = ValueDisplay(ref=AttrRef(widget, 'statusText'), width=550) estimateLabel = ValueDisplay(ref=AttrRef(widget, 'estimateText'), width=550) progressBar = Widget(size=(550, 20), bg_color=(150, 150, 150, 255)) widget.progressBar = progressBar col = (progressLabel, statusLabel, estimateLabel, progressBar) if cancel: cancelButton = Button("Cancel", action=widget.cancel, fg_color=(255, 0, 0, 255)) col += (Column((cancelButton, ), align="r"), ) widget.add(Column(col)) widget.shrink_wrap() widget.startTime = datetime.now() if widget.present(): return widget.progressAmount else: return "Canceled"
def editMonsterSpawner(self, point): mobs = self.mobs tileEntity = self.editor.level.tileEntityAt(*point) undoBackupEntityTag = copy.deepcopy(tileEntity) if not tileEntity: tileEntity = pymclevel.TAG_Compound() tileEntity["id"] = pymclevel.TAG_String("MobSpawner") tileEntity["x"] = pymclevel.TAG_Int(point[0]) tileEntity["y"] = pymclevel.TAG_Int(point[1]) tileEntity["z"] = pymclevel.TAG_Int(point[2]) tileEntity["Delay"] = pymclevel.TAG_Short(120) tileEntity["EntityId"] = pymclevel.TAG_String(mobs[0]) self.editor.level.addTileEntity(tileEntity) panel = Dialog() def addMob(id): if id not in mobs: mobs.insert(0, id) mobTable.selectedIndex = 0 def selectTableRow(i, evt): if mobs[i] == "[Custom]": id = input_text("Type in an EntityID for this spawner. Invalid IDs may crash Minecraft.", 150) if id: addMob(id) else: return mobTable.selectedIndex = mobs.index(id) else: mobTable.selectedIndex = i if evt.num_clicks == 2: panel.dismiss() mobTable = TableView(columns=( TableColumn("", 200), ) ) mobTable.num_rows = lambda: len(mobs) mobTable.row_data = lambda i: (mobs[i],) mobTable.row_is_selected = lambda x: x == mobTable.selectedIndex mobTable.click_row = selectTableRow mobTable.selectedIndex = 0 def selectedMob(): return mobs[mobTable.selectedIndex] id = tileEntity["EntityId"].value addMob(id) mobTable.selectedIndex = mobs.index(id) choiceCol = Column((ValueDisplay(width=200, get_value=lambda: selectedMob() + " spawner"), mobTable)) okButton = Button("OK", action=panel.dismiss) panel.add(Column((choiceCol, okButton))) panel.shrink_wrap() panel.present() class MonsterSpawnerEditOperation(Operation): def __init__(self, tool, level): self.tool = tool self.level = level self.undoBackupEntityTag = undoBackupEntityTag self.canUndo = False def perform(self, recordUndo=True): if self.level.saving: alert("Cannot perform action while saving is taking place") return self.level.addTileEntity(tileEntity) self.canUndo = True def undo(self): self.redoBackupEntityTag = copy.deepcopy(tileEntity) self.level.addTileEntity(self.undoBackupEntityTag) return pymclevel.BoundingBox(pymclevel.TileEntity.pos(tileEntity), (1, 1, 1)) def redo(self): self.level.addTileEntity(self.redoBackupEntityTag) return pymclevel.BoundingBox(pymclevel.TileEntity.pos(tileEntity), (1, 1, 1)) if id != selectedMob(): tileEntity["EntityId"] = pymclevel.TAG_String(selectedMob()) op = MonsterSpawnerEditOperation(self.editor, self.editor.level) self.editor.addOperation(op) if op.canUndo: self.editor.addUnsavedEdit()