class UIColourChannelEditor(UIElement): """ This colour picker specific element lets us edit a single colour channel (Red, Green, Blue, Hue etc). It's bundled along with the colour picker class because I don't see much use for it outside of a colour picker, but it still seemed sensible to make a class for a pattern in the colour picker that is repeated six times. :param relative_rect: The relative rectangle for sizing and positioning the element, relative to the anchors. :param manager: The UI manager for the UI system. :param name: Name for this colour channel, (e.g 'R:' or 'B:'). Used for the label. :param channel_index: Index for the colour channel (e.g. red is 0, blue is 1, hue is also 0, saturation is 1) :param value_range: Range of values for this channel (0 to 255 for R,G,B - 0 to 360 for hue, 0 to 100 for the rest) :param initial_value: Starting value for this colour channel. :param container: UI container for this element. :param parent_element: An element to parent this element, used for theming hierarchies and events. :param object_id: A specific theming/event ID for this element. :param anchors: A dictionary of anchors used for setting up what this element's relative_rect is relative to. :param visible: Whether the element is visible by default. Warning - container visibility may override this. """ def __init__(self, relative_rect: pygame.Rect, manager: IUIManagerInterface, name: str, channel_index: int, value_range: Tuple[int, int], initial_value: int, container: Union[IContainerLikeInterface, None] = None, parent_element: UIElement = None, object_id: Union[ObjectID, str, None] = None, anchors: Dict[str, str] = None, visible: int = 1): super().__init__(relative_rect, manager, container, starting_height=1, layer_thickness=1, anchors=anchors, visible=visible) self._create_valid_ids(container=container, parent_element=parent_element, object_id=object_id, element_id='colour_channel_editor') self.range = value_range self.current_value = initial_value self.channel_index = channel_index self.set_image(self.ui_manager.get_universal_empty_surface()) self.element_container = UIContainer(relative_rect, self.ui_manager, container=self.ui_container, parent_element=self, anchors=anchors, visible=self.visible) default_sizes = { 'space_between': 3, 'label_width': 17, 'entry_width': 43, 'line_height': 29, 'slider_height': 21, 'slider_vert_space': 4 } self.label = UILabel(pygame.Rect(0, 0, -1, default_sizes['line_height']), text=name, manager=self.ui_manager, container=self.element_container, parent_element=self, anchors={ 'left': 'left', 'right': 'left', 'top': 'top', 'bottom': 'bottom' }) self.entry = UITextEntryLine(pygame.Rect(-default_sizes['entry_width'], 0, default_sizes['entry_width'], default_sizes['line_height']), manager=self.ui_manager, container=self.element_container, parent_element=self, anchors={ 'left': 'right', 'right': 'right', 'top': 'top', 'bottom': 'bottom' }) slider_width = (self.entry.rect.left - self.label.rect.right) - ( 2 * default_sizes['space_between']) self.slider = UIHorizontalSlider(pygame.Rect( (self.label.get_abs_rect().width + default_sizes['space_between']), default_sizes['slider_vert_space'], slider_width, default_sizes['slider_height']), start_value=initial_value, value_range=value_range, manager=self.ui_manager, container=self.element_container, parent_element=self, anchors={ 'left': 'left', 'right': 'right', 'top': 'top', 'bottom': 'bottom' }) self.entry.set_allowed_characters('numbers') self.entry.set_text(str(initial_value)) self.entry.set_text_length_limit(3) def process_event(self, event: pygame.event.Event) -> bool: """ Handles events that this UI element is interested in. In this case we are responding to the slider being moved and the user finishing entering text in the text entry element. :param event: The pygame Event to process. :return: True if event is consumed by this element and should not be passed on to other elements. """ consumed_event = super().process_event(event) if event.type == UI_TEXT_ENTRY_FINISHED and event.ui_element == self.entry: int_value = self.current_value try: int_value = int(self.entry.get_text()) except ValueError: int_value = 0 finally: self._set_value_from_entry(int_value) if event.type == UI_HORIZONTAL_SLIDER_MOVED and event.ui_element == self.slider: int_value = self.current_value try: int_value = int(self.slider.get_current_value()) except ValueError: int_value = 0 finally: self._set_value_from_slider(int_value) return consumed_event def _set_value_from_slider(self, new_value: int): """ For updating the value in the text entry element when we've moved the slider. Also sends out an event for the color picker. :param new_value: The new value to set. """ clipped_value = min(self.range[1], max(self.range[0], new_value)) if clipped_value != self.current_value: self.current_value = clipped_value self.entry.set_text(str(self.current_value)) # old event - to be removed in 0.8.0 event_data = { 'user_type': OldType(UI_COLOUR_PICKER_COLOUR_CHANNEL_CHANGED), 'value': self.current_value, 'channel_index': self.channel_index, 'ui_element': self, 'ui_object_id': self.most_specific_combined_id } pygame.event.post(pygame.event.Event(pygame.USEREVENT, event_data)) # new event event_data = { 'value': self.current_value, 'channel_index': self.channel_index, 'ui_element': self, 'ui_object_id': self.most_specific_combined_id } pygame.event.post( pygame.event.Event(UI_COLOUR_PICKER_COLOUR_CHANNEL_CHANGED, event_data)) def _set_value_from_entry(self, new_value: int): """ For updating the value the slider element is set to when we've edited the text entry. The slider may have much less precision than the text entry depending on it's available width so we need to be careful to make the change one way. Also sends out an event for the color picker and clips the value to within the allowed value range. :param new_value: The new value to set. """ clipped_value = min(self.range[1], max(self.range[0], new_value)) if clipped_value != new_value: self.entry.set_text(str(clipped_value)) if clipped_value != self.current_value: self.current_value = clipped_value self.slider.set_current_value(self.current_value) # old event - to be removed in 0.8.0 event_data = { 'user_type': OldType(UI_COLOUR_PICKER_COLOUR_CHANNEL_CHANGED), 'value': self.current_value, 'channel_index': self.channel_index, 'ui_element': self, 'ui_object_id': self.most_specific_combined_id } colour_channel_changed_event = pygame.event.Event( pygame.USEREVENT, event_data) pygame.event.post(colour_channel_changed_event) event_data = { 'value': self.current_value, 'channel_index': self.channel_index, 'ui_element': self, 'ui_object_id': self.most_specific_combined_id } colour_channel_changed_event = pygame.event.Event( UI_COLOUR_PICKER_COLOUR_CHANNEL_CHANGED, event_data) pygame.event.post(colour_channel_changed_event) def set_value(self, new_value: int): """ For when we need to set the value of the colour channel from outside, usually from adjusting the colour elsewhere in the colour picker. Makes sure the new value is within the allowed range. :param new_value: Value to set. """ clipped_value = min(self.range[1], max(self.range[0], new_value)) if clipped_value != self.current_value: self.current_value = clipped_value self.entry.set_text(str(self.current_value)) self.slider.set_current_value(self.current_value) def set_position(self, position: Union[pygame.math.Vector2, Tuple[int, int], Tuple[float, float]]): """ Sets the absolute screen position of this channel, updating all subordinate elements at the same time. :param position: The absolute screen position to set. """ super().set_position(position) self.element_container.set_relative_position( self.relative_rect.topleft) def set_relative_position(self, position: Union[pygame.math.Vector2, Tuple[int, int], Tuple[float, float]]): """ Sets the relative screen position of this channel, updating all subordinate elements at the same time. :param position: The relative screen position to set. """ super().set_relative_position(position) self.element_container.set_relative_position( self.relative_rect.topleft) def set_dimensions(self, dimensions: Union[pygame.math.Vector2, Tuple[int, int], Tuple[float, float]]): """ Method to directly set the dimensions of an element. :param dimensions: The new dimensions to set. """ super().set_dimensions(dimensions) self.element_container.set_dimensions(self.relative_rect.size) def show(self): """ In addition to the base UIElement.show() - call show() of the element_container - which will propagate to the sub-elements - label, entry and slider. """ super().show() self.element_container.show() def hide(self): """ In addition to the base UIElement.hide() - call hide() of the element_container - which will propagate to the sub-elements - label, entry and slider. """ super().hide() self.element_container.hide()
def __init__(self, relative_rect: pygame.Rect, manager: IUIManagerInterface, name: str, channel_index: int, value_range: Tuple[int, int], initial_value: int, container: Union[IContainerLikeInterface, None] = None, parent_element: UIElement = None, object_id: Union[ObjectID, str, None] = None, anchors: Dict[str, str] = None, visible: int = 1): super().__init__(relative_rect, manager, container, starting_height=1, layer_thickness=1, anchors=anchors, visible=visible) self._create_valid_ids(container=container, parent_element=parent_element, object_id=object_id, element_id='colour_channel_editor') self.range = value_range self.current_value = initial_value self.channel_index = channel_index self.set_image(self.ui_manager.get_universal_empty_surface()) self.element_container = UIContainer(relative_rect, self.ui_manager, container=self.ui_container, parent_element=self, anchors=anchors, visible=self.visible) default_sizes = { 'space_between': 3, 'label_width': 17, 'entry_width': 43, 'line_height': 29, 'slider_height': 21, 'slider_vert_space': 4 } self.label = UILabel(pygame.Rect(0, 0, -1, default_sizes['line_height']), text=name, manager=self.ui_manager, container=self.element_container, parent_element=self, anchors={ 'left': 'left', 'right': 'left', 'top': 'top', 'bottom': 'bottom' }) self.entry = UITextEntryLine(pygame.Rect(-default_sizes['entry_width'], 0, default_sizes['entry_width'], default_sizes['line_height']), manager=self.ui_manager, container=self.element_container, parent_element=self, anchors={ 'left': 'right', 'right': 'right', 'top': 'top', 'bottom': 'bottom' }) slider_width = (self.entry.rect.left - self.label.rect.right) - ( 2 * default_sizes['space_between']) self.slider = UIHorizontalSlider(pygame.Rect( (self.label.get_abs_rect().width + default_sizes['space_between']), default_sizes['slider_vert_space'], slider_width, default_sizes['slider_height']), start_value=initial_value, value_range=value_range, manager=self.ui_manager, container=self.element_container, parent_element=self, anchors={ 'left': 'left', 'right': 'right', 'top': 'top', 'bottom': 'bottom' }) self.entry.set_allowed_characters('numbers') self.entry.set_text(str(initial_value)) self.entry.set_text_length_limit(3)
def __init__(self, rect, ui_manager): super().__init__(rect, ui_manager, window_display_title='Everything Container', object_id='#everything_window', resizable=True) self.test_slider = UIHorizontalSlider(pygame.Rect( (int(self.rect.width / 2), int(self.rect.height * 0.70)), (240, 25)), 50.0, (0.0, 100.0), self.ui_manager, container=self) self.slider_label = UILabel( pygame.Rect( (int(self.rect.width / 2) + 250, int(self.rect.height * 0.70)), (27, 25)), str(int(self.test_slider.get_current_value())), self.ui_manager, container=self) self.test_text_entry = UITextEntryLine(pygame.Rect( (int(self.rect.width / 2), int(self.rect.height * 0.50)), (200, -1)), self.ui_manager, container=self) self.test_text_entry.set_forbidden_characters('numbers') current_resolution_string = 'Item 1' self.test_drop_down_menu = UIDropDownMenu( [ 'Item 1', 'Item 2', 'Item 3', 'Item 4', 'Item 5', 'Item 6', 'Item 7', 'Item 8', 'Item 9', 'Item 10', 'Item 11', 'Item 12', 'Item 13', 'Item 14', 'Item 15', 'Item 16', 'Item 17', 'Item 18', 'Item 19', 'Item 20', 'Item 21', 'Item 22', 'Item 23', 'Item 24', 'Item 25', 'Item 26', 'Item 27', 'Item 28', 'Item 29', 'Item 30' ], current_resolution_string, pygame.Rect( (int(self.rect.width / 2), int(self.rect.height * 0.3)), (200, 25)), self.ui_manager, container=self) self.health_bar = UIScreenSpaceHealthBar(pygame.Rect( (int(self.rect.width / 9), int(self.rect.height * 0.7)), (200, 20)), self.ui_manager, container=self) loaded_test_image = pygame.image.load( 'data/images/splat.png').convert_alpha() self.test_image = UIImage(pygame.Rect( (int(self.rect.width / 9), int(self.rect.height * 0.3)), loaded_test_image.get_rect().size), loaded_test_image, self.ui_manager, container=self)
def recreate_ui(self): self.ui_manager.set_window_resolution(self.options.resolution) self.ui_manager.clear_and_reset() self.background_surface = pygame.Surface(self.options.resolution) self.background_surface.fill(self.ui_manager.get_theme().get_colour( None, None, 'dark_bg')) self.test_button = UIButton( pygame.Rect((int(self.options.resolution[0] / 2), int(self.options.resolution[1] * 0.90)), (100, 40)), '', self.ui_manager, tool_tip_text="<font face=fira_code color=normal_text size=2>" "<b><u>Test Tool Tip</u></b>" "<br><br>" "A little <i>test</i> of the " "<font color=#FFFFFF><b>tool tip</b></font>" " functionality." "<br><br>" "Unleash the Kraken!" "</font>", object_id='#hover_me_button') self.test_button_2 = UIButton(pygame.Rect( (int(self.options.resolution[0] / 3), int(self.options.resolution[1] * 0.90)), (100, 40)), 'EVERYTHING', self.ui_manager, object_id='#everything_button') self.test_button_3 = UIButton(pygame.Rect( (int(self.options.resolution[0] / 6), int(self.options.resolution[1] * 0.90)), (100, 40)), 'Scaling?', self.ui_manager, object_id='#scaling_button') self.test_slider = UIHorizontalSlider(pygame.Rect( (int(self.options.resolution[0] / 2), int(self.options.resolution[1] * 0.70)), (240, 25)), 25.0, (0.0, 100.0), self.ui_manager, object_id='#cool_slider') self.test_text_entry = UITextEntryLine(pygame.Rect( (int(self.options.resolution[0] / 2), int(self.options.resolution[1] * 0.50)), (200, -1)), self.ui_manager, object_id='#main_text_entry') current_resolution_string = (str(self.options.resolution[0]) + 'x' + str(self.options.resolution[1])) self.test_drop_down = UIDropDownMenu( ['640x480', '800x600', '1024x768'], current_resolution_string, pygame.Rect((int(self.options.resolution[0] / 2), int(self.options.resolution[1] * 0.3)), (200, 25)), self.ui_manager) self.panel = UIPanel(pygame.Rect(50, 50, 200, 300), starting_layer_height=4, manager=self.ui_manager) UIButton(pygame.Rect(10, 10, 174, 30), 'Panel Button', manager=self.ui_manager, container=self.panel) UISelectionList(pygame.Rect(10, 50, 174, 200), item_list=[ 'Item 1', 'Item 2', 'Item 3', 'Item 4', 'Item 5', 'Item 6', 'Item 7', 'Item 8', 'Item 9', 'Item 10', 'Item 11', 'Item 12', 'Item 13', 'Item 14', 'Item 15', 'Item 16', 'Item 17', 'Item 18', 'Item 19', 'Item 20' ], manager=self.ui_manager, container=self.panel, allow_multi_select=True)
def __init__(self): pygame.init() pygame.display.set_caption("Pathfinding Algorithms") self.window_surface = pygame.display.set_mode((800, 600)) self.ui_manager = pygame_gui.UIManager( (800, 600), "pathfinding/data/ui_theme.json") self.ui_manager.preload_fonts([{ 'name': 'fira_code', 'point_size': 14, 'style': 'bold' }]) self.background_surface = pygame.Surface((800, 600)) self.background_surface.fill( self.ui_manager.get_theme().get_colour('dark_bg')) self.playing_pathfinder = False self.play_speed = 0.5 self.play_speed_acc = 0.0 pathfinding_algorithms = [ 'A*', "Breadth First", "Depth First", "Dijkstra's", "Uniform Cost" ] self.pathfinder_drop_down = UIDropDownMenu( pathfinding_algorithms, 'A*', pygame.Rect((620, 50), (150, 25)), self.ui_manager) self.pathfinder_label = pygame_gui.elements.UILabel( pygame.Rect((520, 50), (100, 25)), "Algorithm: ", self.ui_manager) map_sizes = ['20x20', "40x40", "80x80"] self.map_size_drop_down = UIDropDownMenu( map_sizes, '20x20', pygame.Rect((620, 225), (150, 25)), self.ui_manager) self.map_size_label = pygame_gui.elements.UILabel( pygame.Rect((520, 225), (100, 25)), "Map size: ", self.ui_manager) self.random_start_button = UIButton(pygame.Rect((620, 350), (150, 25)), "Random start", self.ui_manager) self.increment_pathfinder_button = UIButton( pygame.Rect((620, 385), (150, 25)), "Increment", self.ui_manager) self.play_button = UIButton(pygame.Rect((620, 420), (150, 25)), "Play", self.ui_manager) self.speed_slider = UIHorizontalSlider( pygame.Rect((620, 455), (150, 25)), self.play_speed, (1.0, 0.017), self.ui_manager) self.speed_slider_label = pygame_gui.elements.UILabel( pygame.Rect((520, 455), (100, 25)), "Play speed: ", self.ui_manager) self.tool_tip = None self.wall_colour = pygame.Color("#FFFFFF") self.available_maze_space = 450 self.wall_size = 4 self.maze_dimension = 20 self.maze_square_size = int( self.available_maze_space / self.maze_dimension) + 1 self.walls, self.junctions, self.entrance, self.exit = create_maze( top_left=(20, 20), square_size=self.maze_square_size, width=self.maze_dimension, height=self.maze_dimension) self.nav_node_graph = [ junction.nav_node for junction in self.junctions ] self.font = pygame.font.Font(None, 12) self.current_finder = AStarFinder(self.entrance.nav_node, self.exit.nav_node, incremental=True) self.clock = pygame.time.Clock() self.running = True
class PathfindingApp: def __init__(self): pygame.init() pygame.display.set_caption("Pathfinding Algorithms") self.window_surface = pygame.display.set_mode((800, 600)) self.ui_manager = pygame_gui.UIManager( (800, 600), "pathfinding/data/ui_theme.json") self.ui_manager.preload_fonts([{ 'name': 'fira_code', 'point_size': 14, 'style': 'bold' }]) self.background_surface = pygame.Surface((800, 600)) self.background_surface.fill( self.ui_manager.get_theme().get_colour('dark_bg')) self.playing_pathfinder = False self.play_speed = 0.5 self.play_speed_acc = 0.0 pathfinding_algorithms = [ 'A*', "Breadth First", "Depth First", "Dijkstra's", "Uniform Cost" ] self.pathfinder_drop_down = UIDropDownMenu( pathfinding_algorithms, 'A*', pygame.Rect((620, 50), (150, 25)), self.ui_manager) self.pathfinder_label = pygame_gui.elements.UILabel( pygame.Rect((520, 50), (100, 25)), "Algorithm: ", self.ui_manager) map_sizes = ['20x20', "40x40", "80x80"] self.map_size_drop_down = UIDropDownMenu( map_sizes, '20x20', pygame.Rect((620, 225), (150, 25)), self.ui_manager) self.map_size_label = pygame_gui.elements.UILabel( pygame.Rect((520, 225), (100, 25)), "Map size: ", self.ui_manager) self.random_start_button = UIButton(pygame.Rect((620, 350), (150, 25)), "Random start", self.ui_manager) self.increment_pathfinder_button = UIButton( pygame.Rect((620, 385), (150, 25)), "Increment", self.ui_manager) self.play_button = UIButton(pygame.Rect((620, 420), (150, 25)), "Play", self.ui_manager) self.speed_slider = UIHorizontalSlider( pygame.Rect((620, 455), (150, 25)), self.play_speed, (1.0, 0.017), self.ui_manager) self.speed_slider_label = pygame_gui.elements.UILabel( pygame.Rect((520, 455), (100, 25)), "Play speed: ", self.ui_manager) self.tool_tip = None self.wall_colour = pygame.Color("#FFFFFF") self.available_maze_space = 450 self.wall_size = 4 self.maze_dimension = 20 self.maze_square_size = int( self.available_maze_space / self.maze_dimension) + 1 self.walls, self.junctions, self.entrance, self.exit = create_maze( top_left=(20, 20), square_size=self.maze_square_size, width=self.maze_dimension, height=self.maze_dimension) self.nav_node_graph = [ junction.nav_node for junction in self.junctions ] self.font = pygame.font.Font(None, 12) self.current_finder = AStarFinder(self.entrance.nav_node, self.exit.nav_node, incremental=True) self.clock = pygame.time.Clock() self.running = True def set_current_pathfinder(self, finder_name): if self.current_finder is not None: self.current_finder.shutdown() if finder_name == "Breadth First": self.current_finder.shutdown() self.current_finder = BreadthFirstFinder(self.entrance.nav_node, self.exit.nav_node, incremental=True, allow_revisiting=False) elif finder_name == "A*": self.current_finder.shutdown() self.current_finder = AStarFinder(self.entrance.nav_node, self.exit.nav_node, incremental=True) elif finder_name == "Uniform Cost": self.current_finder.shutdown() self.current_finder = UniformCostFinder(self.entrance.nav_node, self.exit.nav_node, incremental=True, allow_revisiting=False) elif finder_name == "Depth First": self.current_finder.shutdown() self.current_finder = DepthFirstFinder(self.entrance.nav_node, self.exit.nav_node, incremental=True, allow_revisiting=False) elif finder_name == "Dijkstra's": self.current_finder.shutdown() self.current_finder = DijkstraFinder(self.entrance.nav_node, self.exit.nav_node, self.nav_node_graph, incremental=True) def run(self): while self.running: time_delta = self.clock.tick( 60) / 1000.0 # time_delta is time between loops in seconds for event in pygame.event.get(): if event.type == pygame.QUIT: self.running = False self.ui_manager.process_events(event) if event.type == pygame_gui.UI_BUTTON_PRESSED: if event.ui_element == self.increment_pathfinder_button: self.playing_pathfinder = False self.current_finder.increment_algorithm() if event.ui_element == self.play_button: if self.playing_pathfinder: self.playing_pathfinder = False self.play_button.set_text('Play') else: self.playing_pathfinder = True self.play_button.set_text('Stop') if event.ui_element == self.random_start_button: start_nav_node = random.choice(self.nav_node_graph) while start_nav_node == self.exit.nav_node: start_nav_node = random.choice(self.nav_node_graph) self.entrance = PathFinderNode(start_nav_node, None, 0) self.set_current_pathfinder( self.current_finder.get_name()) if event.type == pygame_gui.UI_DROP_DOWN_MENU_CHANGED: if event.ui_element == self.map_size_drop_down: self.maze_dimension = int(event.text.split('x')[0]) self.maze_square_size = int(self.available_maze_space / self.maze_dimension) + 1 result = create_maze(top_left=(20, 20), square_size=self.maze_square_size, width=self.maze_dimension, height=self.maze_dimension) self.walls = result[0] self.junctions = result[1] self.entrance = result[2] self.exit = result[3] self.nav_node_graph = [ junction.nav_node for junction in self.junctions ] self.set_current_pathfinder( self.current_finder.get_name()) elif event.ui_element == self.pathfinder_drop_down: self.set_current_pathfinder(event.text) if self.playing_pathfinder: self.play_speed = self.speed_slider.get_current_value() self.play_speed_acc += time_delta if self.play_speed_acc >= self.play_speed: self.play_speed_acc = 0.0 self.current_finder.increment_algorithm() self.ui_manager.update(time_delta) self.current_finder.update() self.window_surface.blit(self.background_surface, (0, 0)) for wall in self.walls: pygame.draw.line(self.window_surface, self.wall_colour, wall.start_pos, wall.end_pos, self.wall_size) self.current_finder.draw_information(self.window_surface, self.ui_manager, self.maze_square_size) if self.entrance is not None: entrance_rect = pygame.Rect(0, 0, self.maze_square_size, self.maze_square_size) entrance_rect.center = self.entrance.nav_node.position pygame.draw.rect(self.window_surface, pygame.Color('#FFCC00'), entrance_rect) if self.exit is not None: exit_rect = pygame.Rect(0, 0, self.maze_square_size, self.maze_square_size) exit_rect.center = self.exit.nav_node.position pygame.draw.rect(self.window_surface, pygame.Color('#FF7700'), exit_rect) self.ui_manager.draw_ui(self.window_surface) pygame.display.update()
def build_gui(self): super().build_gui() panel_rect = Rect( 0, 0, 500, self.display.get_rect().height - (get_param('panel_padding') * 2)) panel_rect.centerx = self.display.get_rect().centerx panel_rect.y = get_param('panel_padding') self.ui_elements['panel'] = UIPanel(panel_rect, 1, self.gui) # all other elements are relative scene_label_rect = Rect(0, 0, 400, get_param('element_height')) scene_label_rect.y = get_param('element_padding') scene_label_rect.centerx = panel_rect.w // 2 # midpoint of the panel self.ui_elements['scene_label'] = UILabel(scene_label_rect, "Generate Random Map", self.gui, self.ui_elements['panel']) # map size label_rect = Rect(0, 0, 150, get_param('element_height')) label_rect.y += scene_label_rect.bottom + get_param('element_padding') dd_rect = Rect(0, 0, 250, get_param('element_height')) dd_rect.y = label_rect.y label_rect.centerx = 125 dd_rect.centerx = 325 self.ui_elements['d_size_label'] = UILabel(label_rect, "Map Size", self.gui, self.ui_elements['panel']) self.ui_elements['dd_map_size'] = UIDropDownMenu( ['64', '128', '256'], '64', dd_rect, self.gui, self.ui_elements['panel']) # Seed label_rect.y += get_param('element_height') + get_param( 'element_padding') ip_rect = Rect(0, 0, 180, get_param('element_height')) ip_rect.centerx = (panel_rect.w // 2) + 30 ip_rect.y = label_rect.y s_btn_rect = Rect(0, 0, 60, get_param('element_height')) s_btn_rect.x = ip_rect.right + get_param('element_padding') s_btn_rect.y = ip_rect.y self.ui_elements['seed_label'] = UILabel(label_rect, 'Map Seed', self.gui, self.ui_elements['panel']) self.ui_elements['input_seed'] = UITextEntryLine( ip_rect, self.gui, self.ui_elements['panel']) self.ui_elements['btn_rnd_seed'] = UIButton(s_btn_rect, 'Random', self.gui, self.ui_elements['panel']) # I want to add two sliders, 1 for mountains and 1 for water, these would be used to control the upper # and lower limits of the height mapping. h_sl_ops = (0, 100) h_sl_sel = 50 label_rect.y += get_param('element_height') + get_param( 'element_padding') h_sl_rect = Rect(0, 0, 200, get_param('element_height')) h_sl_rect.centerx = (panel_rect.w // 2) + get_param('element_padding') + 30 h_sl_rect.y = label_rect.y self.ui_elements['hsl_grass'] = UILabel(label_rect, 'Grass', self.gui, self.ui_elements['panel']) self.ui_elements['hs_grass'] = UIHorizontalSlider( h_sl_rect, h_sl_sel, h_sl_ops, self.gui, self.ui_elements['panel']) label_rect.y += get_param('element_height') + get_param( 'element_padding') h_sl_rect.y = label_rect.y self.ui_elements['hsl_water'] = UILabel(label_rect, 'Water', self.gui, self.ui_elements['panel']) self.ui_elements['hs_water'] = UIHorizontalSlider( h_sl_rect, h_sl_sel, h_sl_ops, self.gui, self.ui_elements['panel']) label_rect.y += get_param('element_height') + get_param( 'element_padding') h_sl_rect.y = label_rect.y self.ui_elements['hsl_mountain'] = UILabel(label_rect, 'Mountain', self.gui, self.ui_elements['panel']) self.ui_elements['hs_mountain'] = UIHorizontalSlider( h_sl_rect, h_sl_sel, h_sl_ops, self.gui, self.ui_elements['panel']) # buttons button_rect = Rect(0, 0, 200, get_param('element_height')) button_rect.centerx = panel_rect.w // 2 button_rect.y = label_rect.bottom + get_param('element_padding') self.ui_elements['btn_preview'] = UIButton(button_rect, "Generate Preview", self.gui, self.ui_elements['panel']) button_rect.w = 200 button_rect.y += get_param('element_height') + get_param( 'element_padding') button_rect.centerx = (panel_rect.w // 2) - 100 self.ui_elements['btn_back'] = UIButton(button_rect, "Back", self.gui, self.ui_elements['panel']) # the apply button always starts off disabled button_rect.centerx = (panel_rect.w // 2) + 100 self.ui_elements['btn_next'] = UIButton(button_rect, "Next", self.gui, self.ui_elements['panel']) pv_rect = Rect(0, 0, 300, 300) pv_rect.centerx = panel_rect.w // 2 pv_rect.y = button_rect.bottom + get_param('element_padding') self.ui_elements['pv_image'] = UIImage(pv_rect, self.pv_img, self.gui, self.ui_elements['panel'])