def choose_player(self): if self.painter.board is not None: title = gui.Label("Choose player") table = gui.Table() players = list(sorted(self.painter.board.players)) radios = gui.Group(value=self.player_input.value) for player in players: table.td(gui.Radio(radios, value=str(player)), style=td_style) table.tr() for player in players: table.td( ImageWidget(image=self.items[self.amount][player], style=td_style, width=request("map_editor.view_width"), height=request("map_editor.view_height"))) button = gui.Button(" Apply ") table.tr() table.td(button, style=td_style) dialog = gui.Dialog(title, table) def on_click(): dialog.value = int(radios.value) dialog.send(gui.CHANGE) dialog.close() button.connect(gui.CLICK, on_click) dialog.connect(gui.CHANGE, lambda: self.new_player(dialog.value)) dialog.open()
def __init__(self): self.desktop = gui.Desktop(theme=self.theme) self.desktop.connect(gui.QUIT, self.on_quit) self.table = gui.Table(width=request("main_menu.width"), height=request("main_menu.height")) self.table.tr() self.table.td(gui.Label("Menu"), colspan=4) self.table.tr() self.new_game_button = gui.Button("New game") self.new_game_button.connect(gui.CLICK, self.new_game) self.table.td(self.new_game_button) self.table.tr() self.load_last_button = gui.Button("Load") self.load_last_button.connect(gui.CLICK, self.load_game) self.table.td(self.load_last_button) self.table.tr() self.map_editor_button = gui.Button("Map editor") self.map_editor_button.connect(gui.CLICK, self.to_map_editor) self.table.td(self.map_editor_button) self.table.tr() self.rules_button = gui.Button("Rules") self.rules_button.connect(gui.CLICK, self.show_rules) self.table.td(self.rules_button) self.table.tr() self.quit_button = gui.Button("Quit") self.quit_button.connect(gui.CLICK, self.quit) self.table.td(self.quit_button) # self.menu = gui.Menus(menu_data) # self.table.td(self.menu, rowspan=10, colspan=10, columnspan=5) self.desktop.run(self.table)
def set_map(self, board): self.surface.fill(self.color) self.font = core.load_font(request("preview.font.name"), request("preview.font.size")) self.cell_size = core.calculate_cell_size(min_size=min( self.width, self.height), board=board) self.items = core.transformed_items(items=Preview.items, cell_size=self.cell_size) self.shift = board.shift # bg for pos in board: pygame.draw.rect(self.surface, request("board.cell_color"), self.expand4(pos, self.shift, margin=1)) # clips for pos, pair in board.items(): if pair[1] != 0: self.surface.blit(self.items[pair[1]][pair[0]], self.expand2(pos, self.shift)) if self.display_players: # players for pos, pair in board.items(): if pair[1] != 0: text = self.font.render(str(pair[0]), True, request("preview.font.color")) self.surface.blit(text, self.expand2(pos, self.shift)) self.repaint()
def jump(self, pos): x, y = self.expand2(pos, self.shift) start_time = time() progress = -1 while progress < 1: self.draw_background() self.draw_selections() for p in ((x - 1, y), (x, y - 1), (x + 1, y), (x, y + 1)): self.draw_selection(p) self.draw_items() self.draw_stat() shift = 2 * self.cell_size * ( 1 - cos(progress)) # shift [1; 0; 1] when progress [-1; 0; +1] width = height = int(round(shift)) h_item = pygame.transform.smoothscale(self.items[1][self.player], (width, self.cell_size)) v_item = pygame.transform.smoothscale(self.items[1][self.player], (self.cell_size, height)) if progress < 0: self.surface.blit(h_item, (x + self.cell_size - shift, y)) # right self.surface.blit(h_item, (x, y)) # left self.surface.blit(v_item, (x, y + self.cell_size - shift)) # bottom self.surface.blit(v_item, (x, y)) # top else: self.surface.blit(h_item, (x + self.cell_size, y)) # right self.surface.blit(h_item, (x - shift, y)) # left self.surface.blit(v_item, (x, y + self.cell_size)) # bottom self.surface.blit(v_item, (x, y - shift)) # top pygame.display.update() self.clock.tick(request("game.fps")) progress = 1000 * (time() - start_time) / request("game.blast_time") - 1
def start(self): if request("game.autosave"): self.save_preset() self.save() # pygame pygame.init() self.font = core.load_font() self.width = self.height = max(request("game.width"), request("game.height")) if self.surface is None: self.surface = pygame.display.set_mode((self.width, self.height)) self.cell_size = core.calculate_cell_size(min_size=min( self.width, self.height), board=self.board) self.items = core.transformed_items(items=Game.items, cell_size=self.cell_size) self.clock = pygame.time.Clock() pygame.display.set_caption('Clonium') pygame.display.set_icon(pygame.image.load(preference.game_icon())) self.news = set() self.shift = self.board.shift self.draw() while not self.end: self.next_turn() players = self.board.players if players: self.win_end() else: self.draw_end() # print(self.board) self.quit()
class Preview(gui.Widget): width = request("preview.width") height = request("preview.height") color = request("preview.background_color") items = core.load_items() def __init__(self, display_players=True, **params): gui.Widget.__init__(self, width=self.width, height=self.height, **params) self.display_players = display_players self.surface = pygame.Surface((self.width, self.height)) self.shift = (0, 0) self.surface.fill(self.color) self.repaint() def clear(self): self.surface.fill(self.color) self.repaint() def set_map(self, board): self.surface.fill(self.color) self.font = core.load_font(request("preview.font.name"), request("preview.font.size")) self.cell_size = core.calculate_cell_size(min_size=min( self.width, self.height), board=board) self.items = core.transformed_items(items=Preview.items, cell_size=self.cell_size) self.shift = board.shift # bg for pos in board: pygame.draw.rect(self.surface, request("board.cell_color"), self.expand4(pos, self.shift, margin=1)) # clips for pos, pair in board.items(): if pair[1] != 0: self.surface.blit(self.items[pair[1]][pair[0]], self.expand2(pos, self.shift)) if self.display_players: # players for pos, pair in board.items(): if pair[1] != 0: text = self.font.render(str(pair[0]), True, request("preview.font.color")) self.surface.blit(text, self.expand2(pos, self.shift)) self.repaint() def paint(self, surface): surface.blit(self.surface, (0, 0)) def expand4(self, pos, shift=(0, 0), margin=0): return core.expand4(self.cell_size, pos, shift, margin=margin) def expand2(self, pos, shift=(0, 0), margin=0): return core.expand2(self.cell_size, pos, shift, margin=margin)
def new_map(self): self.open_dialog.close() self.filename = self.open_dialog.value loader = self.open_dialog.format.map_loader self.painter.set_map(board=loader(self.filename)) self.set_brush() name, ext = op.splitext(self.filename) self.filename = request("map_editor.autosave_pattern").format( name=name, ext=request("formats.map.extension")) self.filename_input.value = op.split(self.filename)[-1]
def display_text(self, text, pos=None, color=request("core.font.color")): if pos is None: pos = (self.width // 2, self.height // 2) core.display_text(surface=self.surface, text=text, pos=pos, font=self.font, color=color)
def explode(self, pos, x=None): player = self.board[pos][0] self.board.decrease_level(pos, 4) explosive_animations[request("game.explosive_animation")](self, pos) for p in core.safe_cross(self.board, pos): self.board.increase_level(p, player=player) self.news.add(p) self.draw()
def __init__(self, width, height, **params): gui.Widget.__init__(self, width=width, height=height, **params) self.board = None self.shift = None self.width = width self.height = height self.surface = pygame.Surface((width, height)) self.overlay = pygame.Surface((width, height), pygame.SRCALPHA, 32) self.brush = None self.player = None self.amount = None self.state = 0 # 1 = draw with self.brush self.shown_brush = request("map_editor.show_brush") self.background_color = request("map_editor.background_color") self.cell_color = request("board.cell_color") self.overlay_color = request("map_editor.overlay_color") self.surface.fill(self.background_color) self.overlay.fill(self.overlay_color) self.repaint()
def __init__(self, filename=request("dialog.new_map_dialog.filename")): self.filename = filename title = gui.Label("New map") self.table = table = gui.Table() table.tr() table.td(gui.Label("Width"), style=td_style) table.td(gui.Label("Height"), style=td_style) table.tr() self.width_input = gui.Input(str( request("dialog.new_map_dialog.board_width")), size=5) table.td(self.width_input, style=td_style) self.height_input = gui.Input( request("dialog.new_map_dialog.board_height"), size=5) table.td(self.height_input, style=td_style) add_event_handler(self.width_input, enter_pressed, lambda e: self.new_size()) add_event_handler(self.height_input, enter_pressed, lambda e: self.new_size()) table.tr() show_button = gui.Button('Show') show_button.connect(gui.CLICK, self.new_size) table.td(show_button, style=td_style) self.board = Board.new_rectangle( request("dialog.new_map_dialog.board_width"), request("dialog.new_map_dialog.board_height")) self.preview = Preview() table.tr() table.td(self.preview, style=td_style) self.preview.set_map(self.board) table.tr() self.filename_input = gui.Input(self.filename) table.td(self.filename_input) table.tr() button = gui.Button(' Ok ') table.td(button, style=td_style) button.connect(gui.CLICK, self.ok_clicked) gui.Dialog.__init__(self, title, table)
def show_player_preference(self, i): self.preference_title = gui.Label("Player #{} preference".format(i)) self.preference_form = gui.Form() self.preference_table = gui.Table() self.preference_table.td(gui.Label("Bot"), style=td_style) self.bot_switcher = gui.Switch(self.bot_buttons[i].value) self.preference_table.td(self.bot_switcher, style=td_style) self.preference_table.tr() self.preference_table.td(gui.Label("Strategy"), style=td_style) self.preference_table.tr() self.selector = gui.Select( value=self.bots.get(i, None) or request("core.bot")) for name, value in sorted(request("core.bots").items()): self.selector.add(name, value) self.preference_table.td(self.selector, style=td_style) self.preference_table.tr() self.apply_button = gui.Button(" Apply ") self.apply_button.connect(gui.CLICK, self.deep_bot, i) self.preference_table.td(self.apply_button, style=td_style, align=0) self.preference_dialog = gui.Dialog(self.preference_title, self.preference_table) self.preference_dialog.open()
def next_turn(self): for event in pygame.event.get(): if event.type == QUIT or event.type == KEYUP and event.key in ( K_ESCAPE, ): self.quit() self.draw() # self.__display() poss = self.board.player_poss(self.player) if poss: self.news = set() pygame.time.delay(request("game.delay")) if self.player in self.bots: pos = self.bot_choice(poss) else: pos = self.player_choice(poss) self.news.add(pos) if request("game.autosave"): self.history.append((self.player, pos)) self.save() self.board.increase_level(pos, player=self.player) wave = self.board[pos][1] > core.N # do delays between waves delay = False while wave: if delay: pygame.time.delay(request("game.blast_time")) delay = True for pos in self.board.overflowed_poss: self.explode(pos) wave = any(pair[1] > core.N for pair in self.board.values()) for player in self.order: if not self.board.player_alive( player) and player not in self.loosers: self.loosers.append(player) self.order.remove(player) self.player = core.shift_player(self.player, self.order, self.board) self.end = len(self.board.players) <= 1
def rotate(self, pos): x, y = self.expand2(pos, self.shift) start_time = time() progress = -1 while progress < 1: self.draw_background() self.draw_selections() for p in ((x - 1, y), (x, y - 1), (x + 1, y), (x, y + 1)): self.draw_selection(p) self.draw_items() self.draw_stat() shift = self.cell_size * (1 + progress) / 2 # item = self.items[1][self.player] item = pygame.transform.rotate( self.items[1][self.player], request("game.tps") * (1 + progress) / 2) self.surface.blit(item, (x + shift, y)) # right self.surface.blit(item, (x - shift, y)) # left self.surface.blit(item, (x, y + shift)) # bottom self.surface.blit(item, (x, y - shift)) # top pygame.display.update() self.clock.tick(request("game.fps")) progress = 1000 * (time() - start_time) / request("game.blast_time") - 1
def undo(self): "undo round => now current player can redo previous turn" player, turn = self.history.pop(-1) while player != self.player: player, turn = self.history.pop(-1) self.board = core.make_turns(self.initial_board, self.history) self.order = [ player for player in self.initial_order if player in self.board.players ] self.player = core.shift_player( self.history[-1][0], self.order, self.board) if self.history else self.order[0] if request('game.autosave'): self.save() self.draw()
def show_players_preference(self): self.players = self.map.players self.bots = {} self.bot_buttons = {} if self.preview is None: self.preview = Preview() self.table.td(self.preview, style=td_style) self.preview.set_map(self.map) if self.players_table: self.table.remove(self.players_table) self.players_table = gui.Table() init_td_style(self.players_table, style=td_style) self.players_table.td(gui.Label("Players:"), style=td_style) self.players_table.tr() self.strategy_labels = {} for i in sorted(self.players): self.players_table.td(gui.Label("Player #{}:".format(i)), style=td_style) self.players_table.td(gui.Label("Bot"), style=td_style) self.bot_buttons[i] = gui.Switch(False) self.bot_buttons[i].connect(gui.CHANGE, self.tune_bot, i) self.players_table.td(self.bot_buttons[i], style=td_style) self.preference_button = gui.Button("Settings") self.preference_button.connect(gui.CLICK, self.show_player_preference, i) self.players_table.td(self.preference_button, style=td_style) self.strategy_labels[i] = gui.Input('', size=10) self.players_table.td(self.strategy_labels[i], style=td_style) self.players_table.tr() self.table.td(self.players_table, style=td_style) self.save_name_input = gui.Input(request("paths.autosave_name")) self.save_name_input.connect(gui.CHANGE, self.new_name) self.new_name() self.players_table.td(self.save_name_input) self.players_table.tr() self.start_button = gui.Button(" Start ") self.start_button.connect(gui.CLICK, self.send, gui.CHANGE) self.players_table.td(self.start_button, style=td_style)
def tune_bot(self, i): if self.bot_buttons[i].value: self.bots[i] = self.strategy_labels[i].value = request("core.bot") else: del self.bots[i] self.strategy_labels[i].value = ''
def __init__(self, board=None, callback=None, **params): pygame.display.set_mode( (request("map_editor.width"), request("map_editor.height"))) gui.Desktop.__init__(self, theme=self.theme, **params) self.callback = callback or (lambda *_, **__: None) self.connect(gui.QUIT, self.quit) self.board = board self.filename = None container = gui.Container(width=request("map_editor.width"), height=request("map_editor.height")) spacer = request("map_editor.space_size") self.new_dialog = NewMapDialog() self.new_dialog.connect(gui.CHANGE, self.action_new) self.open_dialog = FileDialog("Choose map", "Choose", path=folder('map'), preview=Preview(display_players=False), exts=['map', 'preset', 'state']) self.open_dialog.connect(gui.CHANGE, self.new_map) self.save_dialog = FileDialog("Enter filename to save with", "Choose", path=folder('map'), exts=['map'], save=True) self.save_dialog.connect(gui.CHANGE, self.action_saveas) # self.help_dialog = HelpDialog() # QUESTION: may be put it into json: {"<menu>": "<method name>", ...} self.menus = menus = gui.Menus([ ('File/New', self.new_dialog.open, None), ('File/Open', self.open_dialog.open, None), ('File/Save', self.action_save, None), ('File/Save As', self.save_as, None), ('File/Exit', self.quit, None), ('Add/Extend', self.extend, None), ('Add/Add top row', self.add_top_row, None), ('Add/Add bottom row', self.add_bottom_row, None), ('Add/Add left column', self.add_left_column, None), ('Add/Add right column', self.add_right_column, None), ('Add/Add cells', self.add_cells, None), ('Remove/Reduce', self.reduce, None), ('Remove/Remove top row', self.remove_top_row, None), ('Remove/Remove bottom row', self.remove_bottom_row, None), ('Remove/Remove left column', self.remove_left_column, None), ('Remove/Remove right column', self.remove_right_column, None), ('Remove/Remove the same checkers', self.remove_same_checkers, None), ('Remove/Remove checkers with the same owner', self.remove_same_player_checkers, None), ('Remove/Remove checkers with the same level', self.remove_same_level_checkers, None), ('Remove/Remove all checkers', self.remove_checkers, None), ('Remove/Remove cells', self.remove_cells, None), ('Edit/Permute cells', self.permute_cells, None), ('Edit/Permute players', self.permute_players, None), ('Edit/Permute checkers', self.permute_checkers, None) # ('Help/Help', self.help_dialog.open) ]) container.add(self.menus, 0, 0) self.menus.rect.w, self.menus.rect.h = menus.resize() self.filename_input = gui.Input("") container.add(self.filename_input, self.menus.rect.w + spacer, 0) # # new :: # self.mode = mode = gui.Group(name="brushes", value='player') # cell_tool = gui.Tool(self.mode, "Cell", 'cell') # empty_tool = gui.Tool(self.mode, "Empty", 'none') # player_tool = gui.Tool(self.mode, "Player", 'player') # # :: new self.mode = mode = gui.Toolbox([('Cell', 'cell'), ('Empty', 'none'), ('Player', 'player')], cols=1, value='player') # NOTE: DEPERECATED self.mode.connect(gui.CHANGE, self.set_brush) self.player = request("map_editor.player") self.amount = request("map_editor.amount") container.add(mode, 0, self.menus.rect.bottom + spacer) # # new :: # container.add(cell_tool, 0, self.menus.rect.bottom + spacer) # container.add(empty_tool, 0, cell_tool.rect.bottom + spacer) # container.add(cell_tool, 0, empty_tool.rect.bottom + spacer) # # :: new mode.rect.x, mode.rect.y = mode.style.x, mode.style.y mode.rect.w, mode.rect.h = mode.resize() self.player_table = gui.Table() self.player_table.td(gui.Label("Holes")) self.player_table.tr() self.selector = gui.Select(value=request("map_editor.amount")) for i in sorted(self.items.keys()): self.selector.add(str(i), i) self.selector.connect(gui.CHANGE, self.new_amount) self.player_table.td(self.selector, style=td_style) self.player_table.tr() self.player_table.tr() self.player_button = gui.Button('Player') self.player_table.td(self.player_button, style=td_style) self.player_button.connect(gui.CLICK, self.choose_player) self.player_table.tr() self.player_input = gui.Input(str(self.player), size=5) add_event_handler(self.player_input, enter_pressed, lambda e: self.new_player()) self.player_table.td(self.player_input, style=td_style) self.player_table.tr() self.checker = ImageWidget(image=self.items[self.amount][self.player], width=request("map_editor.view_width"), height=request("map_editor.view_height")) self.player_table.td(self.checker, style=td_style) self.player_table.tr() # self.color = gui.Color("#000000", width=mode.rect.w, height=mode.rect.w) # self.color.connect(gui.CLICK, self.choose_player) # self.player_table.td(self.color, style=td_style) container.add(self.player_table, 0, mode.rect.bottom + spacer) self.painter = Painter( width=container.rect.w - mode.rect.w - spacer * 2, height=container.rect.h - self.menus.rect.h - spacer * 2, style={'border': 1}) container.add(self.painter, mode.rect.w + spacer, self.menus.rect.h + spacer) if board: self.painter.set_map(board) self.painter.rect.w, self.painter.rect.h = self.painter.resize() self.widget = container
class MapEditor(gui.Desktop): items = core.load_items() items = core.transformed_items(items, cell_size=request("map_editor.cell_size")) theme = gui.Theme(preference.theme()) def __init__(self, board=None, callback=None, **params): pygame.display.set_mode( (request("map_editor.width"), request("map_editor.height"))) gui.Desktop.__init__(self, theme=self.theme, **params) self.callback = callback or (lambda *_, **__: None) self.connect(gui.QUIT, self.quit) self.board = board self.filename = None container = gui.Container(width=request("map_editor.width"), height=request("map_editor.height")) spacer = request("map_editor.space_size") self.new_dialog = NewMapDialog() self.new_dialog.connect(gui.CHANGE, self.action_new) self.open_dialog = FileDialog("Choose map", "Choose", path=folder('map'), preview=Preview(display_players=False), exts=['map', 'preset', 'state']) self.open_dialog.connect(gui.CHANGE, self.new_map) self.save_dialog = FileDialog("Enter filename to save with", "Choose", path=folder('map'), exts=['map'], save=True) self.save_dialog.connect(gui.CHANGE, self.action_saveas) # self.help_dialog = HelpDialog() # QUESTION: may be put it into json: {"<menu>": "<method name>", ...} self.menus = menus = gui.Menus([ ('File/New', self.new_dialog.open, None), ('File/Open', self.open_dialog.open, None), ('File/Save', self.action_save, None), ('File/Save As', self.save_as, None), ('File/Exit', self.quit, None), ('Add/Extend', self.extend, None), ('Add/Add top row', self.add_top_row, None), ('Add/Add bottom row', self.add_bottom_row, None), ('Add/Add left column', self.add_left_column, None), ('Add/Add right column', self.add_right_column, None), ('Add/Add cells', self.add_cells, None), ('Remove/Reduce', self.reduce, None), ('Remove/Remove top row', self.remove_top_row, None), ('Remove/Remove bottom row', self.remove_bottom_row, None), ('Remove/Remove left column', self.remove_left_column, None), ('Remove/Remove right column', self.remove_right_column, None), ('Remove/Remove the same checkers', self.remove_same_checkers, None), ('Remove/Remove checkers with the same owner', self.remove_same_player_checkers, None), ('Remove/Remove checkers with the same level', self.remove_same_level_checkers, None), ('Remove/Remove all checkers', self.remove_checkers, None), ('Remove/Remove cells', self.remove_cells, None), ('Edit/Permute cells', self.permute_cells, None), ('Edit/Permute players', self.permute_players, None), ('Edit/Permute checkers', self.permute_checkers, None) # ('Help/Help', self.help_dialog.open) ]) container.add(self.menus, 0, 0) self.menus.rect.w, self.menus.rect.h = menus.resize() self.filename_input = gui.Input("") container.add(self.filename_input, self.menus.rect.w + spacer, 0) # # new :: # self.mode = mode = gui.Group(name="brushes", value='player') # cell_tool = gui.Tool(self.mode, "Cell", 'cell') # empty_tool = gui.Tool(self.mode, "Empty", 'none') # player_tool = gui.Tool(self.mode, "Player", 'player') # # :: new self.mode = mode = gui.Toolbox([('Cell', 'cell'), ('Empty', 'none'), ('Player', 'player')], cols=1, value='player') # NOTE: DEPERECATED self.mode.connect(gui.CHANGE, self.set_brush) self.player = request("map_editor.player") self.amount = request("map_editor.amount") container.add(mode, 0, self.menus.rect.bottom + spacer) # # new :: # container.add(cell_tool, 0, self.menus.rect.bottom + spacer) # container.add(empty_tool, 0, cell_tool.rect.bottom + spacer) # container.add(cell_tool, 0, empty_tool.rect.bottom + spacer) # # :: new mode.rect.x, mode.rect.y = mode.style.x, mode.style.y mode.rect.w, mode.rect.h = mode.resize() self.player_table = gui.Table() self.player_table.td(gui.Label("Holes")) self.player_table.tr() self.selector = gui.Select(value=request("map_editor.amount")) for i in sorted(self.items.keys()): self.selector.add(str(i), i) self.selector.connect(gui.CHANGE, self.new_amount) self.player_table.td(self.selector, style=td_style) self.player_table.tr() self.player_table.tr() self.player_button = gui.Button('Player') self.player_table.td(self.player_button, style=td_style) self.player_button.connect(gui.CLICK, self.choose_player) self.player_table.tr() self.player_input = gui.Input(str(self.player), size=5) add_event_handler(self.player_input, enter_pressed, lambda e: self.new_player()) self.player_table.td(self.player_input, style=td_style) self.player_table.tr() self.checker = ImageWidget(image=self.items[self.amount][self.player], width=request("map_editor.view_width"), height=request("map_editor.view_height")) self.player_table.td(self.checker, style=td_style) self.player_table.tr() # self.color = gui.Color("#000000", width=mode.rect.w, height=mode.rect.w) # self.color.connect(gui.CLICK, self.choose_player) # self.player_table.td(self.color, style=td_style) container.add(self.player_table, 0, mode.rect.bottom + spacer) self.painter = Painter( width=container.rect.w - mode.rect.w - spacer * 2, height=container.rect.h - self.menus.rect.h - spacer * 2, style={'border': 1}) container.add(self.painter, mode.rect.w + spacer, self.menus.rect.h + spacer) if board: self.painter.set_map(board) self.painter.rect.w, self.painter.rect.h = self.painter.resize() self.widget = container def extend(self, *pargs): if self.painter.board is not None: self.painter.set_map(self.painter.board.extend()) def reduce(self, *pargs): if self.painter.board is not None: self.painter.set_map(self.painter.board.reduce()) def add_top_row(self, *pargs): if self.painter.board is not None: self.painter.set_map(self.painter.board.add_top_row()) def add_bottom_row(self, *pargs): if self.painter.board is not None: self.painter.set_map(self.painter.board.add_bottom_row()) def add_left_column(self, *pargs): if self.painter.board is not None: self.painter.set_map(self.painter.board.add_left_column()) def add_right_column(self, *pargs): if self.painter.board is not None: self.painter.set_map(self.painter.board.add_right_column()) def remove_top_row(self, *pargs): if self.painter.board is not None: self.painter.set_map(self.painter.board.remove_top_row()) def remove_bottom_row(self, *pargs): if self.painter.board is not None: self.painter.set_map(self.painter.board.remove_bottom_row()) def remove_left_column(self, *pargs): if self.painter.board is not None: self.painter.set_map(self.painter.board.remove_left_column()) def remove_right_column(self, *pargs): if self.painter.board is not None: self.painter.set_map(self.painter.board.remove_right_column()) def remove_same_checkers(self, *pargs): if self.painter.board is not None: self.painter.set_map( self.painter.board.empty_cells( condition=lambda cell: cell == (self.player, self.amount))) def remove_same_player_checkers(self, *pargs): if self.painter.board is not None: self.painter.set_map( self.painter.board.empty_cells( condition=lambda cell: cell[0] == self.player)) def remove_same_level_checkers(self, *pargs): if self.painter.board is not None: self.painter.set_map( self.painter.board.empty_cells( condition=lambda cell: cell[1] == self.amount)) def remove_checkers(self, *pargs): if self.painter.board is not None: self.painter.set_map(self.painter.board.empty_cells()) def remove_cells(self, *pargs): if self.painter.board is not None: self.painter.set_map(self.painter.board.remove_all_cells()) def add_cells(self, *pargs): if self.painter.board is not None: self.painter.set_map(self.painter.board.fill_cells()) def permute_players(self, *pargs): if self.painter.board is not None: self.painter.set_map(self.painter.board.permute_players()) def permute_checkers(self, *pargs): if self.painter.board is not None: self.painter.set_map(self.painter.board.permute_checkers()) def permute_cells(self, *pargs): if self.painter.board is not None: self.painter.set_map(self.painter.board.permute_cells()) def choose_player(self): if self.painter.board is not None: title = gui.Label("Choose player") table = gui.Table() players = list(sorted(self.painter.board.players)) radios = gui.Group(value=self.player_input.value) for player in players: table.td(gui.Radio(radios, value=str(player)), style=td_style) table.tr() for player in players: table.td( ImageWidget(image=self.items[self.amount][player], style=td_style, width=request("map_editor.view_width"), height=request("map_editor.view_height"))) button = gui.Button(" Apply ") table.tr() table.td(button, style=td_style) dialog = gui.Dialog(title, table) def on_click(): dialog.value = int(radios.value) dialog.send(gui.CHANGE) dialog.close() button.connect(gui.CLICK, on_click) dialog.connect(gui.CHANGE, lambda: self.new_player(dialog.value)) dialog.open() def parse_player(self): s = self.player_input.value if s.isdigit(): return int(s) else: print("WARNING: Wrong `player`: '{}', `player` must be an integer". format(s)) def new_player(self, player=None): if player is None: player = self.parse_player() if player in range(len(self.items[1])): self.player = player self.player_input.value = str(self.player) self.checker.new_image(self.items[self.amount][self.player]) if self.painter.board is not None: self.set_brush() else: print( "WARNING: Wrong `player`: '{}', applicable players: {}".format( player, list(range(len(self.items[1]))))) def new_amount(self): if self.selector.value in self.items.keys(): self.amount = self.selector.value self.checker.new_image(self.items[self.amount][self.player]) self.set_brush() else: print("WARNING: Wrong amount: {}, applicable amounts: {}".format( self.selector.value, list(self.items.keys()))) def set_brush(self): self.painter.set_brush(brush=self.mode.value, player=self.player, amount=self.amount) def action_new(self): self.new_dialog.close() self.filename = self.new_dialog.filename self.filename_input.value = op.split(self.filename)[-1] board = self.new_dialog.value self.painter.set_map(board) self.set_brush() def action_save(self, *pargs): if self.painter.board is not None: core.save_map(self.painter.board, self.filename, full=True) else: print("WARNING: Nothing done, nothing to save") def quit(self, *_, **__): gui.Desktop.quit(self) # BUG with closing: doesn't resize sys_exit() # self.callback(board=self.board, filename=self.filename) def save_as(self, *pargs): if self.painter.board is not None: self.save_dialog.new_filename(self.filename_input.value) self.save_dialog.open() else: print("WARNING: Nothing done, nothing to save") def action_saveas(self): self.save_dialog.close() self.filename = self.save_dialog.value self.filename_input.value = op.split(self.filename)[-1] core.save_map(self.painter.board, self.filename, full=True) def new_map(self): self.open_dialog.close() self.filename = self.open_dialog.value loader = self.open_dialog.format.map_loader self.painter.set_map(board=loader(self.filename)) self.set_brush() name, ext = op.splitext(self.filename) self.filename = request("map_editor.autosave_pattern").format( name=name, ext=request("formats.map.extension")) self.filename_input.value = op.split(self.filename)[-1]
import pygame import os.path as op from sys import exit as sys_exit import pgu_gui as gui from widgets import FileDialog, Preview, ImageWidget, NewMapDialog, add_event_handler, enter_pressed from preference import request, folder import preference import core td_style = request("core.style") class MapEditor(gui.Desktop): items = core.load_items() items = core.transformed_items(items, cell_size=request("map_editor.cell_size")) theme = gui.Theme(preference.theme()) def __init__(self, board=None, callback=None, **params): pygame.display.set_mode( (request("map_editor.width"), request("map_editor.height"))) gui.Desktop.__init__(self, theme=self.theme, **params) self.callback = callback or (lambda *_, **__: None) self.connect(gui.QUIT, self.quit) self.board = board self.filename = None container = gui.Container(width=request("map_editor.width"), height=request("map_editor.height"))
def paint(self, surface): surface.fill(request("preview.background_color")) surface.blit(self.image, self.image_place)
def quit(self): self.print_results() if request('game.autosave'): self.save() pygame.quit() sys_exit()
class FileDialog(gui.Dialog): """All-purpose file dialog class, partially borrowed from pgu/gui""" LIST_WIDTH = request("dialog.file_dialog.list_width") LIST_HEIGHT = request("dialog.file_dialog.list_height") def __init__(self, title_text="File Browser", button_text="Okay", cls="dialog", path=None, preview=None, exts=['any'], save=False): """ title_text -- title button_text -- button text path -- initial path preview -- instance of Preview class or None load_condition -- lambda filename: True/False ext -- initial format name exts -- [Format(...), ...] save -- check filename on existance (default: False) """ if exts is None: exts = ['any'] if 'any' not in exts: exts.append('any') self.formats = {name: formats[name] for name in exts} self.formats['any'] = formats['any'] self.ext = exts[0] self.exts = exts self.save = save cls1 = "filedialog" if not path: self.curdir = os.getcwd() else: self.curdir = path self.dir_img = gui.Image( gui.pguglobals.app.theme.get(cls1 + ".folder", "", 'image')) self.title = gui.Label(title_text, cls=cls + ".title.label") self.body = gui.Table() self.list = gui.List(width=self.LIST_WIDTH, height=self.LIST_HEIGHT) self.input_dir = gui.Input() self.input_file = gui.Input() self.selector = gui.Select(value=self.ext) for name in self.exts: self.selector.add(formats[name].description, name) self.selector.connect(gui.CHANGE, self._new_ext) self._list_dir() self.button_ok = gui.Button(button_text) self.body.tr() self.body.td(gui.Label("Folder"), style=td_style, align=-1) self.body.td(self.input_dir, style=td_style) add_event_handler(self.input_dir, enter_pressed, self._dir_enter) self.body.tr() self.body.td(self.list, colspan=3, style=td_style) self.list.connect(gui.CHANGE, self._new_item) self.button_ok.connect(gui.CLICK, self._button_okay_clicked) self.preview = preview if preview is not None: self.body.td(self.preview, style=td_style) self.body.tr() self.body.td(gui.Label("File"), style=td_style, align=-1) add_event_handler(self.input_file, enter_pressed, self._file_enter) # self.input_file.event = _extended_event_handler(self.input_file, enter_pressed, self._file_enter) self.body.td(self.input_file, style=td_style) self.body.td(self.selector, style=td_style) self.body.td(self.button_ok, style=td_style) self.value = None gui.Dialog.__init__(self, self.title, self.body) arrow_pressed = lambda e: e.type == gui.KEYDOWN and e.key in ( K_UP, K_DOWN, K_LEFT, K_RIGHT) add_event_handler(self, arrow_pressed, self._on_arrow_pressed) def _list_dir(self): self.list.clear() ext_filter = formats[self.selector.value].filter self.input_dir.value = self.curdir self.input_dir.pos = len(self.curdir) self.input_dir.vpos = 0 dirs = [] files = [] try: for i in os.listdir(self.curdir): if op.isdir(op.join(self.curdir, i)): dirs.append(i) elif fnmatch.fnmatch(i, ext_filter): files.append(i) except: self.input_file.value = "NO ACCESS" #if '..' not in dirs: dirs.append('..') dirs.sort() dirs = ['..'] + dirs files.sort() for i in dirs: #item = ListItem(image=self.dir_img, text=i, value=i) self.list.add(i, image=self.dir_img, value=i) for i in files: #item = ListItem(image=None, text=i, value=i) self.list.add(i, value=i) #self.list.resize() self.list.set_vertical_scroll(0) #self.list.repaintall() def _new_item(self): self.input_file.value = self.list.value filename = op.abspath(op.join(self.curdir, self.input_file.value)) if op.isdir(filename): self.input_file.value = "" self.curdir = filename self._list_dir() if self.preview is not None: self.preview.clear() elif self.preview is not None and op.isfile(filename): f = formats[self.selector.value] if f.map_loader is not None and f.check(filename): self.preview.set_map(f.map_loader(filename)) elif f.map_loader is None: fs = [ formats[name] for name in self.exts if formats[name].map_loader is not None and formats[name].check(filename) ] if fs: self.preview.set_map(fs[0].map_loader(filename)) else: self.preview.clear() else: self.preview.clear() def _new_ext(self): self.ext = self.selector.value f = formats[self.ext] if self.preview is not None: filename = op.abspath(op.join(self.curdir, self.input_file.value)) if f.map_loader is not None and f.check(filename): self.preview.set_map(f.map_loader(filename)) elif f.map_loader is None: fs = [ formats[name] for name in self.exts if formats[name].map_loader is not None and formats[name].check(filename) ] if fs: self.preview.set_map(fs[0].map_loader(filename)) else: self.preview.clear() else: self.preview.clear() self._list_dir() def new_filename(self, filename): self.input_file.value = filename def _dir_enter(self, event): if op.isdir(self.input_dir.value) and op.abspath( self.input_dir.value) != op.abspath(self.curdir): self.input_file.value = "" self.curdir = op.abspath(self.input_dir.value) self.list.clear() self._list_dir() if self.preview is not None: self.preview.clear() def _on_arrow_pressed(self, e): # BUG: arrows selection does not cancel previously selected items # but they deselected when mouse hover on them widgets = self.list.group.widgets value = self.list.value apt_widgets = [w for w in widgets if w.value == value] if widgets and apt_widgets: widget = [w for w in widgets if w.value == value][0] i = widgets.index(widget) if e.key == K_UP and i > 0: next_value = widgets[i - 1].value if formats[self.ext].check(next_value): self.list.group.value = next_value elif e.key == K_DOWN and i < len(widgets) - 1: next_value = widgets[i + 1].value if formats[self.ext].check(next_value): self.list.group.value = next_value if e.key == K_LEFT: self.input_dir.value = op.split(self.input_dir.value)[0] self._dir_enter(None) def _file_enter(self, event): self._button_okay_clicked() def _button_okay_clicked(self): filename = op.join(self.curdir, self.input_file.value) if self.save: if formats[self.ext].check(filename): self.value = filename self.format = formats[self.selector.value] self.send(gui.CHANGE) self.close() else: self.input_file.value = "WRONG FORMAT" else: if formats[self.ext].loader != None: if op.isfile(filename) and formats[self.ext].check(filename): self.value = filename self.format = formats[self.selector.value] self.send(gui.CHANGE) self.close() else: self.input_file.value = "WRONG FORMAT" else: fs = [ formats[name] for name in self.exts if formats[name].loader is not None and formats[name].check(filename) ] if fs: self.selector.value = fs[0].name self.selector.send(gui.CHANGE) else: self.input_file.value = "WRONG FORMAT"