class GuessPanel: ### ### STATIC ### def card_from_text(dropdown: UIDropDownMenu, items: Enum, cardType: CardType) -> Card: text = dropdown.selected_option for item in items: if text == item.pretty(): return Card(item, cardType) raise Exception("enum value not found " + text + " " + str(items)) manager: UIManager panel: UIPanel player: HumanPlayer on_end_turn: Callable _weapon_menu: UIDropDownMenu _character_menu: UIDropDownMenu _room_menu: UIDropDownMenu _guess_button: UIButton _room_menu_rect: pygame.Rect guess: Solution is_guess: bool def __init__(self, manager: UIManager, screen_width: int, screen_height: int, player: HumanPlayer, \ on_end_turn: Callable): self.manager = manager self.player = player self.on_end_turn = on_end_turn self._create_panel(manager, screen_width, screen_height) def _create_panel(self, manager: UIManager, screen_width: int, screen_height: int): self.width = 300 self.height = 355 rect = create_modal_rect(screen_width, screen_height, self.width, self.height) self.panel = UIPanel(rect, 0, manager, element_id='guess_panel') y_offset = 20 self.make_label("Make a guess", y_offset) y_offset += 20 + 20 self._character_menu = self.make_drop_down(Character, y_offset) y_offset += 25 + 10 self.make_label("in the", y_offset) y_offset += 20 + 10 self._room_menu = self.make_drop_down(Room, y_offset) y_offset += 25 + 10 self.make_label("with the", y_offset) y_offset += 20 + 10 self._weapon_menu = self.make_drop_down(Weapon, y_offset) y_offset += 20 + 50 button_rect = pygame.Rect((50, y_offset), (200, 30)) self._guess_button = UIButton(button_rect, '', manager, container=self.panel) self.panel.hide() def make_label(self, text: str, y_offset): rect = pygame.Rect((0, y_offset), (self.width, 20)) UILabel(rect, text, self.manager, container=self.panel) def make_drop_down(self, enum: Enum, y_offset: int) -> UIDropDownMenu: items = list(map(lambda i: i.pretty(), enum)) rect = pygame.Rect((int((self.width - 200) / 2), y_offset), (200, 25)) if enum == Room: self._room_menu_rect = rect return UIDropDownMenu(items, items[0], rect, self.manager, container=self.panel) def show_guess(self): self.is_guess = True self._guess_button.set_text('Guess!') rect = self._room_menu_rect.copy() items = list(map(lambda i: i.pretty(), Room)) self._room_menu.kill() self._room_menu = UIDropDownMenu(items, self.player.room.pretty(), rect, self.manager, container=self.panel) #self._room_menu.rebuild() self._room_menu.disable() self._show() def show_accuse(self): self.is_guess = False self._guess_button.set_text('Make Accusation!') self._room_menu.enable() self._show() def _show(self): self.guess = Solution(None, None, None) self._update_weapon() self._update_character() self._update_room() self.panel.show() def process_events(self, event): if not self.panel.visible: return self.panel.process_event(event) if event.type != pygame.USEREVENT: return if event.user_type == pygame_gui.UI_DROP_DOWN_MENU_CHANGED: if event.ui_element == self._weapon_menu: self._update_weapon() elif event.ui_element == self._character_menu: self._update_character() elif event.ui_element == self._room_menu: self._update_room() if event.user_type == pygame_gui.UI_BUTTON_PRESSED and event.ui_element == self._guess_button: print("guessing " + str(self.guess)) self.panel.hide() if self.is_guess: self.player.make_guess(self.guess) else: self.player.accuse(self.guess) self.on_end_turn() def _update_weapon(self): self.guess.weapon = GuessPanel.card_from_text(self._weapon_menu, Weapon, CardType.WEAPON) def _update_character(self): self.guess.character = GuessPanel.card_from_text(self._character_menu, Character, CardType.CHARACTER) def _update_room(self): self.guess.room = GuessPanel.card_from_text(self._room_menu, Room, CardType.ROOM)
class StartTurnPanel: player: HumanPlayer panel: UIPanel player_roll: PlayerRoll guess_panel: GuessPanel manager: UIManager _roll_button: UIButton _guess_button: UIButton _accuse_button: UIButton _guess_rect: pygame.Rect def __init__(self, manager: UIManager, screen_width: int, screen_height: int, player_roll: PlayerRoll, \ guess_panel: GuessPanel, player: HumanPlayer): self.manager = manager self._create_panel(screen_width, screen_height) self.player_roll = player_roll self.guess_panel = guess_panel self.player = player def _create_panel(self, screen_width: int, screen_height: int): self.width = 300 self.height = 275 rect = create_modal_rect(screen_width, screen_height, self.width, self.height) self.panel = UIPanel(rect, 0, self.manager, element_id='start_turn') UILabel(pygame.Rect((0, 10), (self.width, 20)), "Your Turn", self.manager, container=self.panel, object_id="windowTitle") y_offset = 10 + 10 roll_button_rect = pygame.Rect((50, y_offset + 25), (200, 50)) self._roll_button = UIButton(roll_button_rect, 'Roll', self.manager, container=self.panel) y_offset += 25 + 50 self._guess_rect = pygame.Rect((50, y_offset + 25), (200, 50)) self._make_guess_button() y_offset += 25 + 50 rect = pygame.Rect((50, y_offset + 25), (200, 50)) self._accuse_button = UIButton(rect, 'Accuse', self.manager, container=self.panel) self.hide() def show(self): self._guess_button.kill() self._make_guess_button() if self.player.room is None: self._guess_button.disable() else: self._guess_button.enable() self.panel.show() def _make_guess_button(self): self._guess_button = UIButton(self._guess_rect.copy(), 'Guess', self.manager, container=self.panel) def hide(self): self.panel.hide() def process_events(self, event): if not self.panel.visible: return self.panel.process_event(event) if event.type != pygame.USEREVENT: return if event.user_type == pygame_gui.UI_BUTTON_PRESSED: self._button_press(event) def _button_press(self, event): if event.ui_element == self._roll_button: self.hide() self.player_roll.roll() elif event.ui_element == self._guess_button: self.hide() self.guess_panel.show_guess() elif event.ui_element == self._accuse_button: self.hide() self.guess_panel.show_accuse()
class UrizenGuiApp: def __init__(self): pygame.init() pygame.display.set_caption('Urizen 0.2.5') self.opt = GUIOptions() self.gen_state = GeneratorsState() if self.opt.fullscreen: self.window_surface = pygame.display.set_mode( self.opt.resolution, pygame.FULLSCREEN) else: self.window_surface = pygame.display.set_mode( self.opt.resolution, pygame.RESIZABLE) self.background_surface = None self.ui_manager = UIManager( self.opt.resolution, PackageResource('urizen.data.themes', 'gui_theme.json')) self.ui_manager.preload_fonts([{ 'name': 'fira_code', 'point_size': 10, 'style': 'bold' }, { 'name': 'fira_code', 'point_size': 10, 'style': 'regular' }, { 'name': 'fira_code', 'point_size': 10, 'style': 'italic' }, { 'name': 'fira_code', 'point_size': 14, 'style': 'italic' }, { 'name': 'fira_code', 'point_size': 14, 'style': 'bold' }]) self.panel = None self.message_window = None self.active_panel = None self.recreate_ui() self.clock = pygame.time.Clock() self.time_delta_stack = deque([]) self.button_response_timer = pygame.time.Clock() self.running = True def recreate_ui(self): self.ui_manager.set_window_resolution(self.opt.resolution) self.ui_manager.clear_and_reset() self.background_surface = pygame.Surface(self.opt.resolution) self.background_surface.fill( self.ui_manager.get_theme().get_colour('dark_bg')) self.btn_gen_explore = UIButton( pygame.Rect(5, 5, 48, 48), '', manager=self.ui_manager, container=None, object_id='#btn_gen_explore', ) self.btn_gen_search = UIButton( pygame.Rect(5, 58, 48, 48), '', manager=self.ui_manager, container=None, object_id='#btn_gen_search', tool_tip_text='Not yet implemented', ) self.btn_tiles_explore = UIButton( pygame.Rect(5, 111, 48, 48), '', manager=self.ui_manager, container=None, object_id='#btn_tiles_explore', tool_tip_text='Not yet implemented', ) self.btn_tiles_search = UIButton( pygame.Rect(5, 164, 48, 48), '', manager=self.ui_manager, container=None, object_id='#btn_tiles_search', tool_tip_text='Not yet implemented', ) self.main_area = pygame.Rect(5 + 48 + 5, 5, self.opt.W - (5 + 48 + 5 + 5), self.opt.H - (5 + 5)) self.pnl_empty = UIPanel(self.main_area, starting_layer_height=1, manager=self.ui_manager) self.construct_gen_explore() self.construct_gen_search() self.btn_gen_search.disable() self.construct_tiles_explore() self.btn_tiles_explore.disable() self.construct_tiles_search() self.btn_tiles_search.disable() if self.active_panel: self.active_panel.show() def construct_gen_explore(self): #self.gen_explore_bg_surface = pygame.Surface(self.opt.resolution) #self.gen_explore_bg_surface.fill(self.ui_manager.get_theme().get_colour('dark_bg')) self.pnl_gen_explore = UIPanel(self.main_area, starting_layer_height=0, manager=self.ui_manager) self.gen_explore_label = UILabel( pygame.Rect(5, 5, 350, 35), 'Explore generators', self.ui_manager, container=self.pnl_gen_explore, ) self.gen_list = UISelectionList( relative_rect=pygame.Rect(5, 75, 350, self.opt.H - 95), item_list=self.gen_state.get_current_gen_list(), manager=self.ui_manager, container=self.pnl_gen_explore, allow_multi_select=False, object_id='#gen_list', ) self.btn_gen_explore_save_as_png = None self.gen_explore_map_image = None self.gen_explore_image = None self.file_dialog_gen_explore_save_as_png = None self.pnl_gen_explore.hide() def construct_gen_search(self): self.pnl_gen_search = UIPanel(self.main_area, starting_layer_height=0, manager=self.ui_manager) self.pnl_gen_search.hide() def construct_tiles_explore(self): self.pnl_tiles_explore = UIPanel(self.main_area, starting_layer_height=0, manager=self.ui_manager) self.pnl_tiles_explore.hide() def construct_tiles_search(self): self.pnl_tiles_search = UIPanel(self.main_area, starting_layer_height=0, manager=self.ui_manager) self.pnl_tiles_search.hide() def process_events(self): for event in pygame.event.get(): if event.type == pygame.QUIT: self.running = False self.ui_manager.process_events(event) if event.type == pygame.VIDEORESIZE: self.opt.W = event.w self.opt.H = event.h self.opt.resolution = (event.w, event.h) self.recreate_ui() if event.type == pygame.USEREVENT: if event.user_type == pygame_gui.UI_BUTTON_PRESSED: if event.ui_element == self.btn_gen_explore: self.pnl_gen_explore.show() self.pnl_gen_search.hide() self.pnl_tiles_explore.hide() self.pnl_tiles_search.hide() self.active_panel = self.pnl_gen_explore elif event.ui_element == self.btn_gen_search: self.pnl_gen_explore.hide() self.pnl_gen_search.show() self.pnl_tiles_explore.hide() self.pnl_tiles_search.hide() self.active_panel = self.btn_gen_search elif event.ui_element == self.btn_tiles_explore: self.pnl_gen_explore.hide() self.pnl_gen_search.hide() self.pnl_tiles_explore.show() self.pnl_tiles_search.hide() self.active_panel = self.btn_tiles_explore elif event.ui_element == self.btn_tiles_search: self.pnl_gen_explore.hide() self.pnl_gen_search.hide() self.pnl_tiles_explore.hide() self.pnl_tiles_search.show() self.active_panel = self.pnl_tiles_search elif event.ui_element == self.btn_gen_explore_save_as_png: self.file_dialog_gen_explore_save_as_png = UIFileDialog( pygame.Rect(self.opt.W // 4, self.opt.H // 4, self.opt.W // 2, self.opt.H // 2), self.ui_manager, window_title='Save as PNG', initial_file_path='map.png', object_id='#file_dialog_gen_explore_save_as_png') if event.user_type == pygame_gui.UI_FILE_DIALOG_PATH_PICKED: if event.ui_element == self.file_dialog_gen_explore_save_as_png: self.gen_explore_image.save(event.text) if event.user_type == pygame_gui.UI_WINDOW_CLOSE: if event.ui_element == self.file_dialog_gen_explore_save_as_png: self.file_dialog_gen_explore_save_as_png = None if event.user_type == pygame_gui.UI_SELECTION_LIST_DOUBLE_CLICKED_SELECTION: if event.ui_element == self.gen_list: if self.gen_state.is_generator(event.text): M = self.gen_state.get_generator(event.text)() surface_w = self.opt.W - 435 surface_h = self.opt.H - 95 self.gen_explore_image = construct_bounded_map_image( M, surface_w, surface_h) image_bytes = self.gen_explore_image.tobytes() im_w, im_h = self.gen_explore_image.size shift_x = (surface_w - im_w) // 2 shift_y = (surface_h - im_h) // 2 if not self.gen_explore_map_image: self.gen_explore_map_image = UIImage( relative_rect=pygame.Rect( 360 + shift_x, 75 + shift_y, im_w, im_h), image_surface=pygame.image.fromstring( image_bytes, self.gen_explore_image.size, self.gen_explore_image.mode), manager=self.ui_manager, container=self.pnl_gen_explore, object_id='#gen_explore_map_image', ) else: self.gen_explore_map_image.set_relative_position( pygame.Rect(360 + shift_x, 75 + shift_y, im_w, im_h)) self.gen_explore_map_image.image = pygame.image.fromstring( image_bytes, self.gen_explore_image.size, self.gen_explore_image.mode) if not self.btn_gen_explore_save_as_png: self.btn_gen_explore_save_as_png = UIButton( pygame.Rect(self.opt.W - 265, 5, 190, 50), 'Save as PNG', manager=self.ui_manager, container=self.pnl_gen_explore, object_id='#btn_gen_explore_save_as_png', starting_height=10, ) else: self.gen_state.change_state(event.text) self.gen_list.set_item_list( self.gen_state.get_current_gen_list()) def run(self): while self.running: time_delta = self.clock.tick() / 1000.0 self.time_delta_stack.append(time_delta) if len(self.time_delta_stack) > 2000: self.time_delta_stack.popleft() # check for input self.process_events() # respond to input self.ui_manager.update(time_delta) # draw graphics self.window_surface.blit(self.background_surface, (0, 0)) self.ui_manager.draw_ui(self.window_surface) pygame.display.update()
class MatchPickPanel: panel: UIPanel player: HumanPlayer pick: Card on_end_turn: Callable manager: UIManager _weapon_button: UIButton _character_button: UIButton _room_button: UIButton _solution: Solution _weapon_button_rect: pygame.Rect _character_button_rect: pygame.Rect _room_button_rect: pygame.Rect def __init__(self, manager: UIManager, screen_width: int, screen_height: int, player: HumanPlayer, \ on_end_turn: Callable): self.manager = manager self.player = player self.on_end_turn = on_end_turn self._create_panel(manager, screen_width, screen_height) def _create_panel(self, manager: UIManager, screen_width: int, screen_height: int): self.width = 300 self.height = 275 rect = create_modal_rect(screen_width, screen_height, self.width, self.height) self.panel = UIPanel(rect, 0, manager, element_id='match_pick_panel') UILabel(pygame.Rect((0, 10), (self.width, 20)), "Pick a card to show", manager, container=self.panel) y_offset = 10 + 10 self._weapon_button_rect = pygame.Rect((50, y_offset + 25), (200, 50)) self._make_weapon_button('') y_offset += 25 + 50 self._character_button_rect = pygame.Rect((50, y_offset + 25), (200, 50)) self._make_character_button('') y_offset += 25 + 50 self._room_button_rect = pygame.Rect((50, y_offset + 25), (200, 50)) self._make_room_button('') self.panel.hide() def _make_weapon_button(self, text): self._weapon_button = UIButton(self._weapon_button_rect.copy(), text, self.manager, container=self.panel) def _make_character_button(self, text): self._character_button = UIButton(self._character_button_rect.copy(), text, self.manager, container=self.panel) def _make_room_button(self, text): self._room_button = UIButton(self._room_button_rect.copy(), text, self.manager, container=self.panel) def show(self, turn_data: PickMatchTurn): solution = turn_data.match self._solution = solution self._weapon_button.kill() self._character_button.kill() self._room_button.kill() self._make_weapon_button(str(turn_data.guess.weapon)) self._make_character_button(str(turn_data.guess.character)) self._make_room_button(str(turn_data.guess.room)) if solution.weapon is None: self._weapon_button.disable() else: self._weapon_button.enable() if solution.character is None: self._character_button.disable() else: self._character_button.enable() if solution.room is None: self._room_button.disable() else: self._room_button.enable() self.panel.show() def process_events(self, event): if not self.panel.visible: return self.panel.process_event(event) if event.type != pygame.USEREVENT: return if event.user_type == pygame_gui.UI_BUTTON_PRESSED: done = False if event.ui_element == self._weapon_button: self.player.set_card_to_show(self._solution.weapon) done = True elif event.ui_element == self._character_button: self.player.set_card_to_show(self._solution.character) done = True elif event.ui_element == self._room_button: self.player.set_card_to_show(self._solution.room) done = True if done: self.panel.hide() self.on_end_turn()
class LogBookPanel: CHECKED_IMG = pygame.image.load('assets/checked.png') UNCHECKED_IMG = pygame.image.load('assets/unchecked.png') PANEL_WIDTH = 200 panel: UIPanel _checkboxes: Dict[UIImage, bool] def __init__(self, manager: UIManager): self.manager = manager self._checkboxes = dict() panel_rect = pygame.Rect((0,0), (LogBookPanel.PANEL_WIDTH, 1000)) self.panel = UIPanel(panel_rect, 0, manager, element_id='log_book_panel') UILabel(pygame.Rect((0,0), (LogBookPanel.PANEL_WIDTH, 20)), "Player Logbook", manager, container=self.panel, object_id="categoryLabel") height = self._create_section("Chacater", Character, 20) height = self._create_section("Room", Room, height) self._create_section("Weapon", Weapon, height) self.panel.hide() def show(self): self.panel.show() def process_events(self, event): if event.type == pygame.MOUSEBUTTONUP: pos = pygame.mouse.get_pos() # check if click is inside panel first? for cb in self._checkboxes.keys(): if cb.get_abs_rect().collidepoint(pos): self._toggle_img(cb) break def _create_section(self, title: str, items: Enum, y_offset) -> int: item_height = 35 label_rect = pygame.Rect((0, y_offset), (LogBookPanel.PANEL_WIDTH, item_height)) label_text = "<strong>" + title + "</strong>" title_label = UITextBox(label_text, label_rect, self.manager, container=self.panel) y_offset += item_height item_label_width = LogBookPanel.PANEL_WIDTH - 30 for item in items: img_rect = pygame.Rect((5, y_offset + 6), (24, 24)) checkbox_img = UIImage(img_rect, LogBookPanel.UNCHECKED_IMG, self.manager, container=self.panel) label_rect = pygame.Rect((30, y_offset), (item_label_width, item_height)) item_button = UITextBox(item.pretty(), label_rect, self.manager, container=self.panel) self._checkboxes[checkbox_img] = False y_offset += item_height return y_offset def _toggle_img(self, checkbox: UIImage): if self._checkboxes.get(checkbox): checkbox.set_image(LogBookPanel.UNCHECKED_IMG) self._checkboxes[checkbox] = False else: checkbox.set_image(LogBookPanel.CHECKED_IMG) self._checkboxes[checkbox] = True