예제 #1
0
    def __init__(self, component=None):
        GUIFrame.__init__(self)
        self.component = component
        if self.component is not None:
            self.component.component_update_callback = self.component_change_handler
        self.envedit_data = None
        self.property_fields = {}

        # GUI settings
        self.fit_height_to_content = True
        self.padding = 10
        self.set_bg_color((1, 1, 1, 0.2))

        layout = GUIStackLayout()
        self.set_child(layout)

        title_layout = GUIDockLayout()
        title_layout.bbox.height = 30
        layout.add_child(title_layout)

        self.title = GUILabel()
        self.title.text_size = 15
        self.title.set_text(self.component.name)
        title_layout.set_child_dock(self.title, GUIDockLayout.LEFT)

        options_dropdown = GUIDropdown(GUIDropdownVisualType.VERTICAL)
        title_layout.set_child_dock(options_dropdown, GUIDockLayout.RIGHT)

        move_up_option = GUIMenuItem()
        move_up_option.child.set_text("Move Component Up")
        move_up_option.data = self.component
        move_up_option.on_release = self.move_up_option_handler
        options_dropdown.menu.child.add_child(move_up_option)

        move_down_option = GUIMenuItem()
        move_down_option.child.set_text("Move Component Down")
        move_down_option.data = self.component
        move_down_option.on_release = self.move_down_option_handler
        options_dropdown.menu.child.add_child(move_down_option)

        del_option = GUIMenuItem()
        del_option.child.set_text("Delete Component")
        del_option.data = self.component
        del_option.on_release = self.del_option_handler
        options_dropdown.menu.child.add_child(del_option)

        self.properties_layout = GUIStackLayout()
        layout.add_child(self.properties_layout)

        self.setup_drawer()
예제 #2
0
    def __init__(self, visual=GUIDropdownVisualType.LABEL):
        GUIButton.__init__(self)
        self.bbox.height = 24
        self.padding = 2
        self.set_normal_color((0.1, 0.1, 0.1, 0))
        self.set_hover_color((1, 1, 1, 0.2))
        self.set_pressed_color((0.5, 0.5, 0.5, 1))

        if visual == GUIDropdownVisualType.LABEL:
            self.set_child(GUILabel())
        elif visual == GUIDropdownVisualType.VERTICAL:
            self.fit_width_to_content = True
            self.fit_height_to_content = True
            self.set_child(GUIFrame())
            self.child.bbox.width = 24
            self.child.bbox.height = 24
            self.child.set_bg_color((1, 1, 1, 0.9))
            self.child.set_bg_image("vertical_more.png")
        elif visual == GUIDropdownVisualType.HORIZONTAL:
            self.fit_width_to_content = True
            self.fit_height_to_content = True
            self.set_child(GUIFrame())
            self.child.bbox.width = 24
            self.child.bbox.height = 24
            self.child.set_bg_color((1, 1, 1, 0.9))
            self.child.set_bg_image("horizontal_more.png")
        self.child.receive_events = False

        self.menu = GUIContextMenu()
예제 #3
0
 def use_single_label(self):
     if self.child is not None:
         self.remove_child()
     self.set_child(GUILabel())
     self.child.set_text_color(self.curr_text_color)
     self.child.receive_events = False
     self.child.set_text(self.text)
     self.update()
예제 #4
0
    def __init__(self):
        GUIFrame.__init__(self)
        self.components = None
        self.envedit_data = None

        # GUI settings
        self.bg_color = (0, 0, 0, 0.8)
        self.bbox.width = 300
        self.padding = 10

        master_layout = GUIDockLayout()
        self.set_child(master_layout)

        self.layout = GUIStackLayout()
        master_layout.set_child_dock(self.layout, GUIDockLayout.TOP)

        title = GUILabel()
        title.text_size = 30
        title.set_font(GUISystem.get_font("default_light"))
        title.set_text("Components")
        self.layout.add_child(title)

        spacer = GUIComponent()
        spacer.bbox.height = 20
        self.layout.add_child(spacer)

        self.add_component_dropdown = GUIDropdown()
        self.add_component_dropdown.child.set_text("Add Component...")

        scroll_container = GUIScrollContainer(scroll_v=True, scroll_h=True)
        master_layout.set_child_dock(scroll_container, GUIDockLayout.CENTER)

        self.component_layout = GUIStackLayout()
        scroll_container.set_child(self.component_layout)
예제 #5
0
    def __init__(self):
        GUIFrame.__init__(self)

        # Scene graph
        self.envedit_data = None

        # GUI settings
        self.bg_color = (0, 0, 0, 0.8)
        self.bbox.width = 300
        self.padding = 10

        master_layout = GUIDockLayout()
        self.set_child(master_layout)

        layout = GUIStackLayout()
        master_layout.set_child_dock(layout, GUIDockLayout.TOP)

        title = GUILabel()
        title.text_size = 30
        title.set_font(GUISystem.get_font("default_light"))
        title.set_text("Scene Graph")
        layout.add_child(title)

        spacer = GUIComponent()
        spacer.bbox.height = 20
        layout.add_child(spacer)

        scroll_container = GUIScrollContainer(scroll_v=True, scroll_h=True)
        master_layout.set_child_dock(scroll_container, GUIDockLayout.CENTER)

        self.scene_list = GUIList()
        scroll_container.set_child(self.scene_list)
예제 #6
0
 def __init__(self):
     GUIButton.__init__(self)
     self.child = GUILabel()
     self.child.receive_events = False
     self.bbox.height = 20
     self.set_normal_color((0.2, 0.2, 0.2, 1))
     self.set_hover_color((0.4, 0.4, 0.4, 1))
     self.set_pressed_color((0.4, 0.4, 0.4, 1))
     self.padding = 1
예제 #7
0
    def __init__(self, text=""):
        GUIListItem.__init__(self)
        self.fit_width_to_content = False
        self.fit_height_to_content = True
        self.expanded = False
        self.sub_list = []
        self.parent = None
        self.level = 0

        self.level_spacer = GUIComponent()
        self.level_spacer.bbox.width = 0
        self.level_spacer.receive_events = False

        self.dropdown_button = GUIButton()
        self.dropdown_button.set_bg_image("right_arrow.png")
        self.dropdown_button.set_normal_color((1, 1, 1, 0.8))
        self.dropdown_button.set_hover_color((1, 1, 1, 0.8))
        self.dropdown_button.set_pressed_color((1, 1, 1, 0.8))
        self.dropdown_button.bbox.width = 16
        self.dropdown_button.on_click = self.on_dropdown_click

        self.spacer = GUIComponent()
        self.spacer.bbox.width = 6
        self.spacer.receive_events = False

        self.label = GUILabel()
        self.label.text_size = 15
        self.label.set_text(text)
        self.label.receive_events = False

        self.layout = GUIStackLayout(vertical=False)
        self.layout.padding = 12
        self.layout.bbox.height = 40
        self.layout.add_child(self.level_spacer)
        self.layout.add_child(self.dropdown_button)
        self.layout.add_child(self.spacer)
        self.layout.add_child(self.label)

        self.set_child(self.layout)
예제 #8
0
    def use_stacked_labels(self):
        if self.child is not None:
            self.remove_child()
        self.set_child(GUIStackLayout(vertical=False))
        self.child.bbox.height = self.bbox.height

        first_label = GUILabel()
        first_label.set_text_color(self.curr_text_color)
        first_label.receive_events = False
        self.child.add_child(first_label)

        cursor = GUIFrame()
        cursor.bbox.width = 1
        cursor.set_bg_color((1, 1, 1, 1))
        cursor.receive_events = False
        self.child.add_child(cursor)

        second_label = GUILabel()
        second_label.set_text_color(self.curr_text_color)
        second_label.receive_events = False
        self.child.add_child(second_label)

        self.update()
예제 #9
0
    def add_button_handler(self, button):
        # Add new element to array
        self.component.property_vals[button.data].append("")

        # Add new field to list of elements
        element_layout = GUIStackLayout(vertical=False)
        element_layout.padding = 4
        element_layout.bbox.height = 28
        self.property_fields[button.data].add_child(element_layout)

        inner_property_val = GUITextBox()
        inner_property_val.data = {
            "parent": button.data,
            "index": len(self.component.property_vals[button.data]) - 1
        }
        inner_property_val.set_text("")
        inner_property_val.on_text_changed = self.text_change_handler
        element_layout.add_child(inner_property_val)

        element_spacer = GUIComponent()
        element_spacer.bbox.width = 4
        element_layout.add_child(element_spacer)

        del_button = GUIButton()
        del_button.padding = 3
        del_button.bbox.width = 16
        del_button.bbox.height = 20
        del_button.set_normal_color((1, 0, 0, 0.8))
        del_button.set_hover_color((1, 0.4, 0.4, 0.8))
        del_button.set_pressed_color((0.4, 0, 0, 0.8))
        del_button.on_click = self.element_del_button_handler
        del_button.data = element_layout
        del_button_label = GUILabel()
        del_button_label.set_text("X")
        del_button_label.receive_events = False
        del_button.set_child(del_button_label)
        element_layout.add_child(del_button)
예제 #10
0
    def rename_lost_focus(self, item):
        # Check if name was changed
        if item.data.data.name != item.text:
            self.envedit_data.modify()

        # Replace textbox with list label
        item.data.data.name = item.text
        label = GUILabel()
        label.text_size = 12
        label.receive_events = False
        label.set_text(item.data.data.name)
        item.data.child.remove_child(item.data.child.children[3])
        item.data.child.add_child(label)
        item.data.update()
예제 #11
0
class GUIListDropdown(GUIListItem):
    def __init__(self, text=""):
        GUIListItem.__init__(self)
        self.fit_width_to_content = False
        self.fit_height_to_content = True
        self.expanded = False
        self.sub_list = []
        self.parent = None
        self.level = 0

        self.level_spacer = GUIComponent()
        self.level_spacer.bbox.width = 0
        self.level_spacer.receive_events = False

        self.dropdown_button = GUIButton()
        self.dropdown_button.set_bg_image("right_arrow.png")
        self.dropdown_button.set_normal_color((1, 1, 1, 0.8))
        self.dropdown_button.set_hover_color((1, 1, 1, 0.8))
        self.dropdown_button.set_pressed_color((1, 1, 1, 0.8))
        self.dropdown_button.bbox.width = 16
        self.dropdown_button.on_click = self.on_dropdown_click

        self.spacer = GUIComponent()
        self.spacer.bbox.width = 6
        self.spacer.receive_events = False

        self.label = GUILabel()
        self.label.text_size = 15
        self.label.set_text(text)
        self.label.receive_events = False

        self.layout = GUIStackLayout(vertical=False)
        self.layout.padding = 12
        self.layout.bbox.height = 40
        self.layout.add_child(self.level_spacer)
        self.layout.add_child(self.dropdown_button)
        self.layout.add_child(self.spacer)
        self.layout.add_child(self.label)

        self.set_child(self.layout)

    # Handles the dropdown button being clicked
    def on_dropdown_click(self, button):
        if self.expanded:
            self.collapse()
        else:
            self.expand()

    # Adds a sub-list item to the dropdown
    def add_sub_item(self, item):
        item.parent = self
        item.level = self.level + 1
        item.level_spacer.bbox.width = 22 * item.level
        self.sub_list.append(item)
        self.update()

    # Removes a sub-list item from the dropdown
    def remove_sub_item(self, item):
        item.parent = None
        self.sub_list.remove(item)
        self.update()

    # Expands this dropdown
    def expand(self):
        self.expanded = True
        self.dropdown_button.set_bg_image("down_arrow.png")
        self.list_container.add_sub_list(self)

    # Collapses this dropdown
    def collapse(self):
        self.expanded = False
        self.dropdown_button.set_bg_image("right_arrow.png")
        self.list_container.remove_sub_list(self)
        if self.list_container.selected_item in self.sub_list:
            self.select()
예제 #12
0
    def setup_drawer(self):
        if self.component is not None:
            for property in self.component.property_types:
                property_type = self.component.property_types[property]

                property_frame = GUIFrame()
                property_frame.bbox.height = 30
                property_frame.padding = 4
                self.properties_layout.add_child(property_frame)

                property_layout = GUIStackLayout(vertical=False)
                property_layout.bbox.height = 30
                property_frame.set_child(property_layout)

                property_name = GUILabel()
                property_name.set_text(property + ":")
                property_layout.add_child(property_name)

                spacer = GUIComponent()
                spacer.bbox.width = 20
                property_layout.add_child(spacer)

                if property_type == PropertyType.INT:
                    property_val = GUINumberBox(use_int=True)
                    property_val.text_box.data = property
                    property_val.text_box.set_text(
                        self.component.property_vals[property])
                    property_val.text_box.on_text_changed = self.text_change_handler
                    self.property_fields[property] = property_val
                    property_layout.add_child(property_val)
                elif property_type == PropertyType.FLOAT:
                    property_val = GUINumberBox()
                    property_val.text_box.data = property
                    property_val.text_box.set_text(
                        self.component.property_vals[property])
                    property_val.text_box.on_text_changed = self.text_change_handler
                    self.property_fields[property] = property_val
                    property_layout.add_child(property_val)
                elif property_type == PropertyType.BOOL:
                    property_val = GUITextBox()
                    property_val.data = property
                    property_val.set_text(
                        self.component.property_vals[property])
                    property_val.on_text_changed = self.text_change_handler
                    self.property_fields[property] = property_val
                    property_layout.add_child(property_val)
                elif property_type == PropertyType.STRING:
                    property_val = GUITextBox()
                    property_val.data = property
                    property_val.set_text(
                        self.component.property_vals[property])
                    property_val.on_text_changed = self.text_change_handler
                    self.property_fields[property] = property_val
                    property_layout.add_child(property_val)
                elif property_type == PropertyType.FILE:
                    property_val = GUITextBox()
                    property_val.data = property
                    property_val.set_text(
                        self.component.property_vals[property])
                    property_val.on_selected = self.file_open_handler
                    self.property_fields[property] = property_val
                    property_layout.add_child(property_val)
                elif property_type == PropertyType.ARRAY:
                    property_val = GUIStackLayout()
                    property_val.bbox.width = 124

                    add_button = GUIButton()
                    add_button.padding = 2
                    add_button.bbox.width = 20
                    add_button.bbox.height = 20
                    add_button.data = property
                    add_button.on_click = self.add_button_handler
                    button_label = GUILabel()
                    button_label.receive_events = False
                    button_label.set_text("Add Element")
                    add_button.set_child(button_label)
                    property_val.add_child(add_button)

                    vals = self.component.property_vals[property]
                    for i in range(len(vals)):
                        val = vals[i]

                        element_layout = GUIStackLayout(vertical=False)
                        element_layout.padding = 4
                        element_layout.bbox.height = 28
                        property_val.add_child(element_layout)

                        inner_property_val = GUITextBox()
                        inner_property_val.data = {
                            "parent": property,
                            "index": i
                        }
                        inner_property_val.set_text(val)
                        inner_property_val.on_text_changed = self.text_change_handler
                        element_layout.add_child(inner_property_val)

                        element_spacer = GUIComponent()
                        element_spacer.bbox.width = 4
                        element_layout.add_child(element_spacer)

                        del_button = GUIButton()
                        del_button.padding = 3
                        del_button.bbox.width = 16
                        del_button.bbox.height = 20
                        del_button.set_normal_color((1, 0, 0, 0.8))
                        del_button.set_hover_color((1, 0.4, 0.4, 0.8))
                        del_button.set_pressed_color((0.4, 0, 0, 0.8))
                        del_button.on_click = self.element_del_button_handler
                        del_button.data = element_layout
                        del_button_label = GUILabel()
                        del_button_label.set_text("X")
                        del_button_label.receive_events = False
                        del_button.set_child(del_button_label)
                        element_layout.add_child(del_button)

                    self.property_fields[property] = property_val
                    property_layout.add_child(property_val)
                    property_frame.fit_height_to_content = True
                    property_layout.bbox.height = property_val.bbox.height
                elif property_type == PropertyType.VECTOR3:
                    property_val = GUIStackLayout(vertical=False)

                    x_val = GUINumberBox()
                    x_val.text_box.data = {"parent": property, "index": 0}
                    x_val.bbox.width = 60
                    x_val.text_box.set_text(
                        str(self.component.property_vals[property][0]))
                    x_val.text_box.on_text_changed = self.text_change_handler
                    property_val.add_child(x_val)

                    spacer_1 = GUIComponent()
                    spacer_1.bbox.width = 10
                    property_val.add_child(spacer_1)

                    y_val = GUINumberBox()
                    y_val.text_box.data = {"parent": property, "index": 1}
                    y_val.bbox.width = 60
                    y_val.text_box.set_text(
                        str(self.component.property_vals[property][1]))
                    y_val.text_box.on_text_changed = self.text_change_handler
                    property_val.add_child(y_val)

                    spacer_2 = GUIComponent()
                    spacer_2.bbox.width = 10
                    property_val.add_child(spacer_2)

                    z_val = GUINumberBox()
                    z_val.text_box.data = {"parent": property, "index": 2}
                    z_val.bbox.width = 60
                    z_val.text_box.set_text(
                        str(self.component.property_vals[property][2]))
                    z_val.text_box.on_text_changed = self.text_change_handler
                    property_val.add_child(z_val)

                    self.property_fields[property] = property_val
                    property_layout.add_child(property_val)
예제 #13
0
class ComponentDrawer(GUIFrame):
    def __init__(self, component=None):
        GUIFrame.__init__(self)
        self.component = component
        if self.component is not None:
            self.component.component_update_callback = self.component_change_handler
        self.envedit_data = None
        self.property_fields = {}

        # GUI settings
        self.fit_height_to_content = True
        self.padding = 10
        self.set_bg_color((1, 1, 1, 0.2))

        layout = GUIStackLayout()
        self.set_child(layout)

        title_layout = GUIDockLayout()
        title_layout.bbox.height = 30
        layout.add_child(title_layout)

        self.title = GUILabel()
        self.title.text_size = 15
        self.title.set_text(self.component.name)
        title_layout.set_child_dock(self.title, GUIDockLayout.LEFT)

        options_dropdown = GUIDropdown(GUIDropdownVisualType.VERTICAL)
        title_layout.set_child_dock(options_dropdown, GUIDockLayout.RIGHT)

        move_up_option = GUIMenuItem()
        move_up_option.child.set_text("Move Component Up")
        move_up_option.data = self.component
        move_up_option.on_release = self.move_up_option_handler
        options_dropdown.menu.child.add_child(move_up_option)

        move_down_option = GUIMenuItem()
        move_down_option.child.set_text("Move Component Down")
        move_down_option.data = self.component
        move_down_option.on_release = self.move_down_option_handler
        options_dropdown.menu.child.add_child(move_down_option)

        del_option = GUIMenuItem()
        del_option.child.set_text("Delete Component")
        del_option.data = self.component
        del_option.on_release = self.del_option_handler
        options_dropdown.menu.child.add_child(del_option)

        self.properties_layout = GUIStackLayout()
        layout.add_child(self.properties_layout)

        self.setup_drawer()

    # Sets up the component drawer
    def setup_drawer(self):
        if self.component is not None:
            for property in self.component.property_types:
                property_type = self.component.property_types[property]

                property_frame = GUIFrame()
                property_frame.bbox.height = 30
                property_frame.padding = 4
                self.properties_layout.add_child(property_frame)

                property_layout = GUIStackLayout(vertical=False)
                property_layout.bbox.height = 30
                property_frame.set_child(property_layout)

                property_name = GUILabel()
                property_name.set_text(property + ":")
                property_layout.add_child(property_name)

                spacer = GUIComponent()
                spacer.bbox.width = 20
                property_layout.add_child(spacer)

                if property_type == PropertyType.INT:
                    property_val = GUINumberBox(use_int=True)
                    property_val.text_box.data = property
                    property_val.text_box.set_text(
                        self.component.property_vals[property])
                    property_val.text_box.on_text_changed = self.text_change_handler
                    self.property_fields[property] = property_val
                    property_layout.add_child(property_val)
                elif property_type == PropertyType.FLOAT:
                    property_val = GUINumberBox()
                    property_val.text_box.data = property
                    property_val.text_box.set_text(
                        self.component.property_vals[property])
                    property_val.text_box.on_text_changed = self.text_change_handler
                    self.property_fields[property] = property_val
                    property_layout.add_child(property_val)
                elif property_type == PropertyType.BOOL:
                    property_val = GUITextBox()
                    property_val.data = property
                    property_val.set_text(
                        self.component.property_vals[property])
                    property_val.on_text_changed = self.text_change_handler
                    self.property_fields[property] = property_val
                    property_layout.add_child(property_val)
                elif property_type == PropertyType.STRING:
                    property_val = GUITextBox()
                    property_val.data = property
                    property_val.set_text(
                        self.component.property_vals[property])
                    property_val.on_text_changed = self.text_change_handler
                    self.property_fields[property] = property_val
                    property_layout.add_child(property_val)
                elif property_type == PropertyType.FILE:
                    property_val = GUITextBox()
                    property_val.data = property
                    property_val.set_text(
                        self.component.property_vals[property])
                    property_val.on_selected = self.file_open_handler
                    self.property_fields[property] = property_val
                    property_layout.add_child(property_val)
                elif property_type == PropertyType.ARRAY:
                    property_val = GUIStackLayout()
                    property_val.bbox.width = 124

                    add_button = GUIButton()
                    add_button.padding = 2
                    add_button.bbox.width = 20
                    add_button.bbox.height = 20
                    add_button.data = property
                    add_button.on_click = self.add_button_handler
                    button_label = GUILabel()
                    button_label.receive_events = False
                    button_label.set_text("Add Element")
                    add_button.set_child(button_label)
                    property_val.add_child(add_button)

                    vals = self.component.property_vals[property]
                    for i in range(len(vals)):
                        val = vals[i]

                        element_layout = GUIStackLayout(vertical=False)
                        element_layout.padding = 4
                        element_layout.bbox.height = 28
                        property_val.add_child(element_layout)

                        inner_property_val = GUITextBox()
                        inner_property_val.data = {
                            "parent": property,
                            "index": i
                        }
                        inner_property_val.set_text(val)
                        inner_property_val.on_text_changed = self.text_change_handler
                        element_layout.add_child(inner_property_val)

                        element_spacer = GUIComponent()
                        element_spacer.bbox.width = 4
                        element_layout.add_child(element_spacer)

                        del_button = GUIButton()
                        del_button.padding = 3
                        del_button.bbox.width = 16
                        del_button.bbox.height = 20
                        del_button.set_normal_color((1, 0, 0, 0.8))
                        del_button.set_hover_color((1, 0.4, 0.4, 0.8))
                        del_button.set_pressed_color((0.4, 0, 0, 0.8))
                        del_button.on_click = self.element_del_button_handler
                        del_button.data = element_layout
                        del_button_label = GUILabel()
                        del_button_label.set_text("X")
                        del_button_label.receive_events = False
                        del_button.set_child(del_button_label)
                        element_layout.add_child(del_button)

                    self.property_fields[property] = property_val
                    property_layout.add_child(property_val)
                    property_frame.fit_height_to_content = True
                    property_layout.bbox.height = property_val.bbox.height
                elif property_type == PropertyType.VECTOR3:
                    property_val = GUIStackLayout(vertical=False)

                    x_val = GUINumberBox()
                    x_val.text_box.data = {"parent": property, "index": 0}
                    x_val.bbox.width = 60
                    x_val.text_box.set_text(
                        str(self.component.property_vals[property][0]))
                    x_val.text_box.on_text_changed = self.text_change_handler
                    property_val.add_child(x_val)

                    spacer_1 = GUIComponent()
                    spacer_1.bbox.width = 10
                    property_val.add_child(spacer_1)

                    y_val = GUINumberBox()
                    y_val.text_box.data = {"parent": property, "index": 1}
                    y_val.bbox.width = 60
                    y_val.text_box.set_text(
                        str(self.component.property_vals[property][1]))
                    y_val.text_box.on_text_changed = self.text_change_handler
                    property_val.add_child(y_val)

                    spacer_2 = GUIComponent()
                    spacer_2.bbox.width = 10
                    property_val.add_child(spacer_2)

                    z_val = GUINumberBox()
                    z_val.text_box.data = {"parent": property, "index": 2}
                    z_val.bbox.width = 60
                    z_val.text_box.set_text(
                        str(self.component.property_vals[property][2]))
                    z_val.text_box.on_text_changed = self.text_change_handler
                    property_val.add_child(z_val)

                    self.property_fields[property] = property_val
                    property_layout.add_child(property_val)

    def move_up_option_handler(self, item):
        list_index = self.envedit_data.target_node.data.index(item.data)
        if list_index == 0:
            return
        self.envedit_data.target_node.remove_component(item.data)
        self.envedit_data.target_node.insert_component(item.data,
                                                       list_index - 1)

        self.envedit_data.modify()
        self.envedit_data.update()

    def move_down_option_handler(self, item):
        list_index = self.envedit_data.target_node.data.index(item.data)
        if list_index + 1 == len(self.envedit_data.target_node.data):
            return
        self.envedit_data.target_node.remove_component(item.data)
        self.envedit_data.target_node.insert_component(item.data,
                                                       list_index + 1)

        self.envedit_data.modify()
        self.envedit_data.update()

    def del_option_handler(self, item):
        self.envedit_data.target_node.remove_component(item.data)
        self.envedit_data.modify()
        self.envedit_data.update()

    def set_envedit_data(self, data):
        self.envedit_data = data

    # Handles the text change
    def text_change_handler(self, text_box):
        if isinstance(text_box.data, dict):
            self.component.property_vals[text_box.data["parent"]][
                text_box.data["index"]] = text_box.text
        else:
            self.component.property_vals[text_box.data] = text_box.text
        self.component.node.component_property_changed_selected()
        self.envedit_data.modify()
        self.envedit_data.update()

    # Handles the add button for array component drawer
    def add_button_handler(self, button):
        # Add new element to array
        self.component.property_vals[button.data].append("")

        # Add new field to list of elements
        element_layout = GUIStackLayout(vertical=False)
        element_layout.padding = 4
        element_layout.bbox.height = 28
        self.property_fields[button.data].add_child(element_layout)

        inner_property_val = GUITextBox()
        inner_property_val.data = {
            "parent": button.data,
            "index": len(self.component.property_vals[button.data]) - 1
        }
        inner_property_val.set_text("")
        inner_property_val.on_text_changed = self.text_change_handler
        element_layout.add_child(inner_property_val)

        element_spacer = GUIComponent()
        element_spacer.bbox.width = 4
        element_layout.add_child(element_spacer)

        del_button = GUIButton()
        del_button.padding = 3
        del_button.bbox.width = 16
        del_button.bbox.height = 20
        del_button.set_normal_color((1, 0, 0, 0.8))
        del_button.set_hover_color((1, 0.4, 0.4, 0.8))
        del_button.set_pressed_color((0.4, 0, 0, 0.8))
        del_button.on_click = self.element_del_button_handler
        del_button.data = element_layout
        del_button_label = GUILabel()
        del_button_label.set_text("X")
        del_button_label.receive_events = False
        del_button.set_child(del_button_label)
        element_layout.add_child(del_button)

    # Handles the delete button for array component drawer
    def element_del_button_handler(self, button):
        property_name = button.data.children[0].data["parent"]
        element_index = button.data.children[0].data["index"]

        # Remove element from array
        self.component.property_vals[property_name].pop(element_index)

        # Remove element from list of elements
        self.property_fields[property_name].remove_child(button.data)

        # Reset the element indices
        for i in range(len(self.property_fields[property_name].children)):
            element = self.property_fields[property_name].children[i]
            if isinstance(element, GUIStackLayout):
                element.children[0].data["parent"] = property_name
                element.children[0].data["index"] = i - 1

    # Handles component changing values
    def component_change_handler(self, property_name):
        property_type = self.component.property_types[property_name]
        property_val = self.property_fields[property_name]

        if property_type == PropertyType.INT:
            property_val.text_box.set_text(
                self.component.property_vals[property_name])
        elif property_type == PropertyType.FLOAT:
            property_val.text_box.set_text(
                str(
                    int(
                        float(self.component.property_vals[property_name]) *
                        1000) / 1000))
        elif property_type == PropertyType.BOOL:
            property_val.set_text(self.component.property_vals[property_name])
        elif property_type == PropertyType.STRING:
            property_val.set_text(self.component.property_vals[property_name])
        elif property_type == PropertyType.FILE:
            property_val.set_text(self.component.property_vals[property_name])
        # TODO: Fix array statement so it actually sets the values
        elif property_type == PropertyType.ARRAY:
            property_val.set_text(self.component.property_vals[property_name])
        elif property_type == PropertyType.VECTOR3:
            property_val.children[0].text_box.set_text(
                self.component.property_vals[property_name][0])
            property_val.children[2].text_box.set_text(
                self.component.property_vals[property_name][1])
            property_val.children[4].text_box.set_text(
                self.component.property_vals[property_name][2])

    # Handles file property type being clicked
    def file_open_handler(self, text_box):
        file_path = filedialog.askopenfilename()
        if file_path != "":
            file_path = Path(file_path)
            rel_path = file_path.relative_to(Path(os.getcwd()) / "resources")
            text_box.set_text(str(rel_path.parent / rel_path.stem))

            if isinstance(text_box.data, dict):
                self.component.property_vals[text_box.data["parent"]][
                    text_box.data["index"]] = text_box.text
            else:
                self.component.property_vals[text_box.data] = text_box.text

            self.component.node.component_property_changed_selected()
            self.envedit_data.modify()
            self.envedit_data.update()