コード例 #1
0
class ROISelector(BoxLayout):
    def __init__(self, **kwargs):
        super(ROISelector, self).__init__(**kwargs)

        self.dropdown = DropDown()
        self.dropdown.bind(on_select=lambda obj, x: setattr(
            self.ids.mainbutton_id, 'text', "ROI {0}".format(x)))

        self.roi_list = App.get_running_app().roi_list
        self.roi_list.bind(on_roi_added=self.add_roi_button)
        self.roi_list.bind(on_roi_selected=lambda obj, index: self.dropdown.
                           select(obj.values[index]))
        self.roi_list.bind(on_roi_removed=self.remove_roi_button)

        add_roi_btn = Button(text="Add new ROI…", size_hint_y=None, height=44)
        add_roi_btn.bind(on_release=lambda obj: self.roi_list.add() or self.
                         roi_list.select(len(self.roi_list.values) - 1))
        self.dropdown.add_widget(add_roi_btn)

        self.roi_buttons = []

    def add_roi_button(self, obj, new_value):
        color = roi_colors[new_value % len(roi_colors)]
        btn = Button(text="ROI {0}".format(new_value),
                     size_hint_y=None,
                     height=44,
                     background_color=color)
        btn.bind(on_release=lambda instance: self.roi_list.select(
            self.roi_buttons.index(btn)))
        self.dropdown.add_widget(btn)
        self.roi_buttons.append(btn)

    def remove_roi_button(self, obj, index):
        self.dropdown.remove_widget(self.roi_buttons[index])
        del self.roi_buttons[index]
        self.ids.mainbutton_id.text = "Select ROI…"
コード例 #2
0
ファイル: tangle_ui.py プロジェクト: galencm/machinic-tangle
class DropDownInput(TextInput):
    def __init__(self,
                 preload=None,
                 preload_attr=None,
                 preload_clean=True,
                 **kwargs):
        self.multiline = False
        self.drop_down = DropDown()
        self.drop_down.bind(on_select=self.on_select)
        self.bind(on_text_validate=self.add_text)
        self.preload = preload
        self.preload_attr = preload_attr
        self.preload_clean = preload_clean
        self.not_preloaded = set()
        super(DropDownInput, self).__init__(**kwargs)
        self.add_widget(self.drop_down)

    def add_text(self, *args):
        if args[0].text not in [
                btn.text for btn in self.drop_down.children[0].children
                if hasattr(btn, "text")
        ]:
            btn = Button(text=args[0].text, size_hint_y=None, height=44)
            self.drop_down.add_widget(btn)
            btn.bind(on_release=lambda btn: self.drop_down.select(btn.text))
            if "preload" not in args:
                self.not_preloaded.add(btn)

    def on_select(self, *args):
        self.text = args[1]
        if args[1] not in [
                btn.text for btn in self.drop_down.children[0].children
                if hasattr(btn, "text")
        ]:
            self.drop_down.append(Button(text=args[1]))
        # call on_text_validate after selection
        # to avoid having to select textinput and press enter
        self.dispatch("on_text_validate")

    def on_touch_down(self, touch):
        preloaded = set()
        if self.preload:
            for thing in self.preload:
                if self.preload_attr:
                    # use operator to allow dot access of attributes
                    thing_string = str(
                        operator.attrgetter(self.preload_attr)(thing))
                else:
                    thing_string = str(thing)
                self.add_text(Button(text=thing_string), "preload")
                preloaded.add(thing_string)

        # preload_clean removes entries that
        # are not in the preload source anymore
        if self.preload_clean is True:
            added_through_widget = [
                btn.text for btn in self.not_preloaded if hasattr(btn, "text")
            ]
            for btn in self.drop_down.children[0].children:
                try:
                    if (btn.text not in preloaded
                            and btn.text not in added_through_widget):
                        self.drop_down.remove_widget(btn)
                except Exception as ex:
                    pass

        return super(DropDownInput, self).on_touch_down(touch)

    def on_touch_up(self, touch):
        if touch.grab_current == self:
            self.drop_down.open(self)
        return super(DropDownInput, self).on_touch_up(touch)
コード例 #3
0
class ClassSummary(CustomBoxLayout):
    def __init__(self, *args, **kwargs):
        super(ClassSummary, self).__init__(*args, **kwargs)

        # The first item in this panel should be a dropdown containing
        # all of the contours in the current image.
        self.contour_select_dropdown = DropDown()
        self.contour_select_dropdown.auto_dismiss = False

        self.editor_box = CustomBoxLayout(orientation='vertical',
                                          padding=[8, 8, 8, 8],
                                          spacing=5)

        self.class_select_dropdown = DropDown()
        self.class_select_dropdown.auto_dismiss = False

        self.class_select_button = Button(text='Select Class',
                                          size_hint_y=None,
                                          height=30)

        self.class_select_button.bind(on_press=self._class_select_pressed)

        self.name_input = TextInput(text='Item Name',
                                    multiline=False,
                                    size_hint_y=None,
                                    height=30)
        self.comment_input = TextInput(text='Comments',
                                       multiline=True,
                                       size_hint_y=None,
                                       height=120)

        self.name_input.bind(text=self._name_text_changed)
        self.comment_input.bind(text=self._comment_text_changed)

        self.editor_box.add_widget(self.class_select_button)
        self.editor_box.add_widget(self.name_input)
        self.editor_box.add_widget(self.comment_input)

        self.dropdown_activator = DropDownContourItem(
            class_color=hex_color('#000000'), index=-1, class_name='none')

        self.dropdown_activator.bind(on_press=self._activator_pressed)

        self.add_widget(self.dropdown_activator)
        self.add_widget(self.editor_box)

        self.dropdown_open = False
        self.current_entry = None
        self.dataset = None
        self.contours = []
        self.contour_dropdown_items = []
        self.current_contour = None
        self.class_names = []
        self.class_buttons = []

    def _name_text_changed(self, inst, val):
        self.current_contour['name'] = val

    def _comment_text_changed(self, inst, val):
        self.current_contour['comment'] = val

    def writeChangesToMemory(self):
        if self.current_entry is None:
            raise Exception("Nothing is currently being edited.")

        entry = self.dataset.meta_structure['entries'][self.current_key]
        for idx, contour in enumerate(self.contours):
            entry[idx]['class_idx'] = contour['class_idx']
            entry[idx]['name'] = contour['name']
            entry[idx]['comment'] = contour['comment']

    def clearCurrentEntry(self):
        if self.current_entry is not None:
            for item in self.contour_dropdown_items:
                self.contour_select_dropdown.remove_widget(item)

        self.contours = []
        self.contour_dropdown_items = []

    def addContour(self, contour):
        item_class_idx = contour['class_idx']
        item_class_color = self.dataset.meta_structure['classes'][
            item_class_idx]['color']
        item_class_name = self.dataset.meta_structure['classes'][
            item_class_idx]['name']

        proper_name = item_class_name
        if contour['name'] != '':
            if not contour['name'].isspace():
                proper_name = self.current_contour['name']

        dropdown_item = DropDownContourItem(class_color=item_class_color,
                                            index=item_class_idx,
                                            class_name=proper_name)
        self.contour_select_dropdown.add_widget(dropdown_item)
        dropdown_item.bind(on_press=self._item_selected)

        self.contours.append(contour)
        self.contour_dropdown_items.append(dropdown_item)

    def setCurrentContour(self, contour):
        self.current_contour = contour
        item_class_idx = contour['class_idx']
        item_class_color = self.dataset.meta_structure['classes'][
            item_class_idx]['color']
        item_class_name = self.dataset.meta_structure['classes'][
            item_class_idx]['name']

        proper_name = item_class_name
        if self.current_contour['name'] != '':
            if not self.current_contour['name'].isspace():
                proper_name = self.current_contour['name']

        self.dropdown_activator.setProperties(item_class_color, item_class_idx,
                                              proper_name)

        self.name_input.text = contour['name']
        self.comment_input.text = contour['comment']
        self.class_select_button.text = item_class_name

        self.contour_select_dropdown.dismiss()
        self.dropdown_open = False

    def populateClassDropdown(self):
        for button in self.class_buttons:
            self.class_select_dropdown.remove_widget(button)

        self.class_names = []
        self.class_buttons = []
        for _class in self.dataset.meta_structure['classes']:
            self.class_names.append(_class['name'])
            button = Button(text=_class['name'], size_hint_y=None, height=30)
            self.class_buttons.append(button)
            self.class_select_dropdown.add_widget(button)
            button.bind(on_press=self._class_selected)

    def setCurrentEntry(self, key, dataset):
        if self.current_entry is not None:
            self.clearCurrentEntry()

        self.dataset = dataset
        self.current_entry = self.dataset.meta_structure['entries'][key]
        self.current_key = key

        self.populateClassDropdown()

        # Add each of these to the internal structure, and therefore the
        # image display.
        for contour in self.current_entry:
            self.addContour(contour)

        if len(self.current_entry) > 0:
            self.setCurrentContour(self.current_entry[0])

    def _activator_pressed(self, inst):
        if not self.dropdown_open:
            self.contour_select_dropdown.open(inst)
            self.dropdown_open = True
        else:
            self.dropdown_open = False
            self.contour_select_dropdown.dismiss()

    def _class_select_pressed(self, inst):
        self.class_select_dropdown.open(inst)

    def _class_selected(self, inst):
        self.class_select_button.text = inst.text
        self.current_contour['class_idx'] = self.class_names.index(inst.text)
        self.class_select_dropdown.dismiss()

        # We need to change the item in the dropdown list of contours to match.
        class_idx = self.class_names.index(inst.text)
        contour_idx = self.contours.index(self.current_contour)
        item_class_color = self.dataset.meta_structure['classes'][class_idx][
            'color']
        item_class_name = self.dataset.meta_structure['classes'][class_idx][
            'name']

        proper_name = item_class_name
        if self.current_contour['name'] != '':
            if not self.current_contour['name'].isspace():
                proper_name = self.current_contour['name']

        self.contour_dropdown_items[contour_idx].setProperties(
            item_class_color, self.class_names.index(inst.text), proper_name)

        self.dropdown_activator.setProperties(
            item_class_color, self.class_names.index(inst.text), proper_name)

        self.parent.display.image_display.setContourColor(
            contour_idx, item_class_color)

    def _item_selected(self, inst):
        idx = self.contour_dropdown_items.index(inst)
        contour = self.contours[idx]

        self.setCurrentContour(contour)
コード例 #4
0
class GeneScreen(Screen):

    def __init__(self, **kwargs):
        super(GeneScreen, self).__init__(**kwargs)

        # Widget Container
        screen_container = BoxLayout(orientation='vertical',
                                     padding=[1])

        # *Logo----------------------------------------------------------------
        self.logo = HomeButton()
        screen_container.add_widget(self.logo)

        # *Gene Selection Title------------------------------------------------
        screen_container.add_widget(Label(text='Gene Selection',
                                          size_hint=(1, .1),
                                          color=(0, .1, .25, .75)))

        # *Drop Down Menu------------------------------------------------------
        self.dropdown = DropDown()
        self.dropdown.bind(on_select=self.set_gene)
        self.dd_btns = []  # A list of drop down buttons for easy deletion

        #       Populate when top button hit
        self.mainbutton = CustomButton(text='Select a gene',
                                       size_hint=(1, .2))
        self.mainbutton.bind(on_release=self.load_genes)  # Populate dropdown
        self.dropdown.bind(on_select=lambda instance, x:
                           setattr(self.mainbutton, 'text', x))
        #       Place on screen
        screen_container.add_widget(self.mainbutton)

        # *Gene Buttons--------------------------------------------------------
        #       Declarations
        self.button_holder = BoxLayout(orientation='horizontal')

        #       Edit Button
        self.edit_btn = CustomButton(text="Edit",
                                     size_hint=(.3, .3))
        self.edit_btn.bind(on_release=self.switch_screen)

        #       New Button
        self.new_btn = CustomButton(text="New",
                                    size_hint=(.3, .3))
        self.new_btn.bind(on_release=self.switch_screen)

        #       Delete Button
        self.delete_btn = CustomButton(text="Delete",
                                       size_hint=(.3, .3))
        self.delete_btn.bind(on_release=self.delete)

        #       Placement
        self.button_holder.add_widget(self.edit_btn)
        self.button_holder.add_widget(self.new_btn)
        self.button_holder.add_widget(self.delete_btn)
        screen_container.add_widget(self.button_holder)  # Place Container
        #       Pack all widgets
        self.add_widget(screen_container)

        # Reset drop down when screen is loaded
        self.bind(on_enter=self.reset_menu)

    def load_genes(self, *args):
        """Called when drop down is opened"""

        self.dropdown.clear_widgets()  # Clear any packaged buttons
        del self.dd_btns[:]  # Clear drop down button list

        # Grab relevant genes
        genes = global_data.groups[global_data.active_group]

        for gene in genes:
            btn = CustomButton(text=gene.name,
                               size_hint_y=None,
                               height=self.height/9)

            btn.bind(on_release=lambda button:
                     self.dropdown.select(button.text))
            self.dropdown.add_widget(btn)  # Add button to menu
            self.dd_btns.append(btn)  # Store button in delety-list

        self.dropdown.open(args[0])

    def set_gene(self, *args):
        # Storing which group is selected for use in gene screen
        global_data.active_gene = args[1]  # args[1] - Name of gene

    def delete(self, *args):

        def delete_gene():
            group = global_data.active_group  # Get active group
            gene = global_data.active_gene  # Get active gene

            # Iterate through genes because we need to check the name of each
            for index, _gene in enumerate(global_data.groups[group]):

                if _gene.name == gene:

                    # Delete the gene
                    del global_data.groups[group][index]
                    # Remove from drop down
                    self.dropdown.remove_widget(self.dd_btns[index])
                    log(f"Gene {gene} deleted.")
                    break

            group_mngr.save_groups(global_data.groups)  # Save the groups

            global_data.active_gene = ''  # No active gene
            self.dropdown.select('Select a gene')

            popup.dismiss()

        if global_data.active_gene != '':

            # *Deletion Confirmation-------------------------------------------
            content = BoxLayout(orientation='vertical')
            content.add_widget(Label(text=f"Delete "
                                     f"{global_data.active_gene}?"))

            # *Confirmation Buttons--------------------------------------------
            options = BoxLayout(orientation='horizontal',
                                spacing=2)

            confirm_btn = CustomButton(text="Delete",  # Confirm button
                                       size_hint=(.3, .3))

            cancel_btn = CustomButton(text="Cancel",  # Cancel button
                                      size_hint=(.3, .3))
            #       Add Widgets to container
            options.add_widget(confirm_btn)
            options.add_widget(cancel_btn)
            content.add_widget(options)

            # *Popup Settings--------------------------------------------------
            popup = Popup(title="Delete?",
                          content=content,
                          size_hint=(None, None),
                          size=(400, 400),
                          separator_color=[1., 1., 1., 1.])

            confirm_btn.bind(on_press=delete_gene)
            cancel_btn.bind(on_press=popup.dismiss)

            popup.open()

    def switch_screen(*args):

        if args[1].text == "New":
            sm.current = 'editgene'

        elif args[1].text == "Edit":
            if global_data.active_gene != '':
                sm.current = 'editgene'

    def reset_menu(self, *args):
        # Need to make sure the menu text is defaulted when screen is entered
        self.dropdown.select('Select a gene')
        global_data.active_gene = ''
コード例 #5
0
class GroupScreen(Screen):

    def __init__(self, **kwargs):
        super(GroupScreen, self).__init__(**kwargs)

        # Hold the widgets in a container
        screen_container = BoxLayout(orientation='vertical',
                                     padding=[1])

        # *Empowered Logo------------------------------------------------------
        self.logo = HomeButton()
        screen_container.add_widget(self.logo)

        # *Group Selection Title-----------------------------------------------
        screen_container.add_widget(Label(text='Group Selection',
                                          size_hint=(1, .1),
                                          color=(0, .1, .25, .75)))

        # *Dropdown Menu-------------------------------------------------------
        self.dropdown = DropDown()
        self.dropdown.bind(on_select=self.set_active_group)

        # On load, no group is active.
        global_data.active_group = ''
        # Store the drop down buttons for easy manipulation
        self.current_groups = {}

        #       Populate when top button hit
        self.mainbutton = CustomButton(text='Select a group',
                                       size_hint=(1, .2))

        # Populate drop down on select
        self.mainbutton.bind(on_release=self.load_groups)
        self.dropdown.bind(on_select=lambda instance, x:
                           setattr(self.mainbutton, 'text', x))
        # Place on screen
        screen_container.add_widget(self.mainbutton)

        # *Group Actions Title-------------------------------------------------
        # Declarations
        self.button_container = BoxLayout(orientation='horizontal')

        #       Edit Button
        self.edit_btn = CustomButton(text="Edit",
                                     size_hint=(.3, .3))
        self.edit_btn.bind(on_press=self.switch_screen)

        #       New Button
        self.new_btn = CustomButton(text="New",
                                    size_hint=(.3, .3))
        self.new_btn.bind(on_press=self.switch_screen)

        #       Delete Button
        self.delete_btn = CustomButton(text="Delete",
                                       size_hint=(.3, .3))
        self.delete_btn.bind(on_press=self.delete)

        # Put buttons in container
        self.button_container.add_widget(self.edit_btn)
        self.button_container.add_widget(self.new_btn)
        self.button_container.add_widget(self.delete_btn)

        # Add container to screen container
        screen_container.add_widget(self.button_container)
        # Package screen container
        self.add_widget(screen_container)
        # Make sure drop down menu gets reset
        self.bind(on_enter=self.reset_menu)

    def set_active_group(self, *args):
        # args = (<DropDown obj>, 'Methylation Pathway')
        # Storing which group is selected for use in gene screen and deletion
        global_data.active_group = args[1]

    def switch_screen(self, *args):
        # Switch screens
        if args[0].text == "Edit" and global_data.active_group != '':
            sm.current = 'gene'
        elif args[0].text == "New":
            sm.current = 'newgroup'

    def delete(self, *args):

        def delete_group(*args):

            # Get the selected group
            active_group = global_data.active_group

            # Delete it from the group dictionary
            del global_data.groups[active_group]

            log(f"Group {active_group} deleted.")

            # Overwrite the existing groups with the modified group dictionary
            group_mngr.save_groups(global_data.groups)

            # Clear the selected group
            global_data.active_group = ''
            # Remove it from the drop down menu
            self.dropdown.remove_widget(self.current_groups[active_group])
            # Set drop down menu to default
            self.dropdown.select('Select a group')

            popup.dismiss()

        # If a group is selected and delete button hit, confirm deletion
        if global_data.active_group != '':

            # *Confirmation Popup----------------------------------------------
            content = BoxLayout(orientation='vertical')
            content.add_widget(Label(text=
                                     f"Delete {global_data.active_group}?"))

            # *Popup buttons---------------------------------------------------
            options = BoxLayout(orientation='horizontal', spacing=2)

            confirm_btn = CustomButton(text="Delete",  # Confirm delete button
                                       size_hint=(.3, .3))

            cancel_btn = CustomButton(text="Cancel",  # Cancel delete button
                                      size_hint=(.3, .3))
            options.add_widget(confirm_btn)
            options.add_widget(cancel_btn)
            content.add_widget(options)

            # *Popup Attributes------------------------------------------------
            popup = Popup(title="Delete?", content=content,
                          size_hint=(None, None), size=(400, 400),
                          separator_color=[1., 1., 1., 1.])

            confirm_btn.bind(on_press=delete_group)
            cancel_btn.bind(on_press=popup.dismiss)

            popup.open()

    def load_groups(self, *args):

        self.dropdown.clear_widgets()  # Clear any packaged buttons
        self.current_groups = {}  # Clear drop down button list

        groups = global_data.groups

        for group in groups:  # Iterating through groups and adding a button
            btn = CustomButton(text=group,  # Create button
                               size_hint_y=None,
                               height=44)
            btn.bind(on_release=lambda button:
            self.dropdown.select(button.text))  # Bind drop down functionality
            self.current_groups[group] = btn
            self.dropdown.add_widget(btn)  # Put in drop down menu

        self.dropdown.open(args[0])  # Called on clicking the default button

    def reset_menu(self, *args):
        # Need to make sure the menu text is defaulted when screen is entered
        self.dropdown.select('Select a group')
        global_data.active_group = ''
        global_data.active_gene = ''
コード例 #6
0
ファイル: popup_classes.py プロジェクト: ykzzyk/Monopoly
class BuyHousesPop(Popup):

    def __init__(self, **kwargs):
        # Obtain root reference
        self.root = kwargs.pop('root')
        self.btns = {}
        self.entries = {}
        self.total_money = 0

        super().__init__(**kwargs)

        self.selected_square_properties = []
        self.ids.accept_btn.disabled = True

        Clock.schedule_once(self.create_dropdown, 0)

    def create_dropdown(self, *args):

        self.dropdown_list = DropDown()

        for player in self.root.players:
            player_name = player.name.upper()
            # button for dropdown list 1
            btn = Button(
                text=f'[b][color=#ffffff]{player_name}[/b][/color]', size_hint_y=None,
                height=self.width // 25,
                markup=True
            )

            # Storing the btn references into a list
            self.btns[player_name] = btn

            # Create the binding function
            btn.bind(on_release=lambda btn: self.dropdown_list.select(btn.text))

            # Add the widget to the dropdown window
            self.dropdown_list.add_widget(btn)

        # Bind the select name btns to opening the dropdown window
        self.ids.select_name_btn.bind(on_release=self.dropdown_list.open)

        # Binding the select name btns to also update their text values
        self.dropdown_list.bind(
            on_select=functools.partial(self.select_player, self.ids.select_name_btn)
        )

    def select_player(self, btn, instance, button_text):

        # Obtain the true value in the text
        previous_player_name = btn.text.split(']')[2].split('[')[0]
        player_name = button_text.split(']')[2].split('[')[0]

        # If the selection change from not the default value
        if previous_player_name != 'SELECT PLAYER NAME':
            self.dropdown_list.add_widget(self.btns[previous_player_name])

        # Removing the corresponding button from
        # right dropdown window
        self.dropdown_list.remove_widget(self.btns[player_name])

        # Update text to given x
        btn.text = button_text

        # Find the matching player given the player_name
        selected_player = None
        for player in self.root.players:
            if player.name.upper() == player_name:
                selected_player = player
                break

        # Storing the selected player
        self.player = selected_player

        # Update the player_current_money label
        self.ids.player_current_money.text = f"[b][color=#000000]Player Current Money: ${self.player.money}[/b][/color]"

        # Update the property container with the selected player
        self.update_property_container(selected_player)

        if selected_player is not None:
            self.ids.accept_btn.disabled = False

    def update_property_container(self, selected_player):

        # Clean property container
        self.ids.property_container.clear_widgets()

        # Fill the property container given the properties of the
        # selected player
        for square_property in selected_player.property_own:

            # If the property is not part of a full set, then ignore it
            if not isinstance(square_property, PropertySquare) or (square_property.full_set is False):
                continue


            # Create button for property
            entry = BuyHousesEntry(
                square_property=square_property,
                initial_houses=square_property.number_of_houses,
                total_houses=square_property.number_of_houses
            )

            # Add it to the entries of the popup
            if entry.square_property.property_set not in self.entries.keys():
                self.entries[entry.square_property.property_set] = [entry]
            else:
                self.entries[entry.square_property.property_set].append(entry)

            # Place property name
            entry.ids.property_name.text = f'[b][color=#000000]{entry.square_property.full_name}[/b][/color]'

            # Updateing the entry's text
            self.update_house_numbers(entry)

            # Update the button status
            self.update_button_status()

            # Bind the property button to function
            # entry.bind(on_release=functools.partial(self.property_button_press))
            entry.ids.buy_houses.bind(on_release=functools.partial(self.buy_houses, entry))
            entry.ids.sell_houses.bind(on_release=functools.partial(self.sell_houses, entry))

            # Add button to the property container
            self.ids.property_container.add_widget(entry)

        # Update the money values
        self.update_money_values()

    def update_button_status(self):

        for set_name in self.entries.keys():

            # Checking all the other entries within the same set
            number_of_total_houses = list(map(lambda x: x.total_houses, self.entries[set_name]))

            # Determine the min and max
            min_val, max_val = min(number_of_total_houses), max(number_of_total_houses)

            for entry in self.entries[set_name]:

                # Determine if the entry's specific buttons are enabled or disabled
                if min_val == max_val:
                    if min_val == 0:
                        entry.ids.buy_houses.disabled = False
                        entry.ids.sell_houses.disabled = True
                    elif max_val == 5:
                        entry.ids.buy_houses.disabled = True
                        entry.ids.sell_houses.disabled = False
                    else:
                        entry.ids.buy_houses.disabled = False
                        entry.ids.sell_houses.disabled = False

                elif entry.total_houses == min_val:
                    entry.ids.buy_houses.disabled = False
                    entry.ids.sell_houses.disabled = True
                elif entry.total_houses == max_val:
                    entry.ids.sell_houses.disabled = False
                    entry.ids.buy_houses.disabled = True

                # No matter what, if you have a mortgage property, you cannot buy/sell houses
                if entry.square_property.mortgage:
                    entry.ids.buy_houses.disabled = True
                    entry.ids.sell_houses.disabled = True

    def update_money_values(self):

        self.total_money = 0

        for set_name in self.entries.keys():

            # Determine the cost of the house for the set
            cost_of_house = self.entries[set_name][0].square_property.buy_house_cost

            # Determine the houses bought and the houses sold
            houses_bought = 0
            houses_sold = 0

            for entry in self.entries[set_name]:
                houses_diff = entry.total_houses - entry.initial_houses

                if houses_diff > 0:
                    houses_bought += houses_diff
                else:
                    houses_sold -= houses_diff

            # Calculate the total cost
            self.total_money += int(houses_sold * (cost_of_house / 2))
            self.total_money -= int(houses_bought * cost_of_house)

        # Update the buy_sell money and the player's total money
        if self.total_money >= 0:
            self.ids.buy_sell_money.text = f"[b][color=#000000]Property Money: ${self.total_money}[/b][/color]"
        else:
            self.ids.buy_sell_money.text = f"[b][color=#000000]Property Money: -${abs(self.total_money)}[/b][/color]"

        # Update the total money of the player after the transaciton
        self.total_money += self.player.money
        self.ids.total_money.text = f"[b][color=#000000]Total Money: ${self.total_money}[/b][/color]"

        # Disable buttons if the player does not have enough money to pay for the houses/hotel
        self.cannot_pay()

    def update_house_numbers(self, entry):

        # Updateing the entry's text
        if entry.total_houses == 5:
            entry.ids.houses_numbers.text = "[b][color=#000000]1[/b][/color]"
            entry.ids.house.color = [1, 0, 0, 1]
        else:
            entry.ids.houses_numbers.text = f"[b][color=#000000]{entry.total_houses}[/b][/color]"
            entry.ids.house.color = [0, 1, 0, 1]

    def cannot_pay(self):

        # Disable buttons based on not enough money
        for set_name in self.entries.keys():

            # Determine the cost of the house for the set
            cost_of_house = self.entries[set_name][0].square_property.buy_house_cost

            # If they don't have enough money to buy houses in this set
            if cost_of_house > self.total_money:
                for entry in self.entries[set_name]:
                    entry.ids.buy_houses.disabled = True

    def buy_houses(self, entry, btn_instance):

        # Increase the entry's total houses
        entry.total_houses += 1

        # Updateing the entry's text
        self.update_house_numbers(entry)

        # Place the houses/hotel number
        self.update_button_status()

        # Update money values
        self.update_money_values()

        if self.total_money != self.player.money:
            self.ids.select_name_btn.disabled = True
        else:
            self.ids.select_name_btn.disabled = False

    def sell_houses(self, entry, btn_instance):

        # Increase the entry's total houses
        entry.total_houses -= 1

        # Updateing the entry's text
        self.update_house_numbers(entry)

        # Update total houses number displayed
        self.update_button_status()

        # Update money values
        self.update_money_values()

        if self.total_money != self.player.money:
            self.ids.select_name_btn.disabled = True
        else:
            self.ids.select_name_btn.disabled = False

    def accept(self):

        # Update the houses visible after buying/selling houses/hotel
        for set_name in self.entries.keys():
            for entry in self.entries[set_name]:
                # Change the attributes of the property to the new number of houses
                entry.square_property.number_of_houses = entry.total_houses

                # Update the visibility of the house markers depending on the number
                # of houses.
                entry.square_property.update_house_markers()

        # Modify the player's money given the mortgage_unmortgage money
        self.player.money = self.total_money

        # Inform root to update property ownership and update player's money
        self.root.parent.parent.update_players_to_frame()

        # Log buy/sell houses
        bought_text = []
        sold_text = []
        for set_name in self.entries.keys():
            for entry in self.entries[set_name]:

                house_diff = entry.total_houses - entry.initial_houses
                if entry.total_houses != 5 and entry.initial_houses != 5:
                    if house_diff > 0:
                        bought_text.append(f"{house_diff} house(s) for {entry.square_property.full_name}")
                    elif house_diff < 0:
                        sold_text.append(f'{-house_diff} house(s) for {entry.square_property.full_name}')
                elif entry.total_houses == 5 and entry.initial_houses != 5:
                    bought_text.append(f"an hotel for {entry.square_property.full_name}")
                elif entry.initial_houses == 5 and entry.total_houses != 5:
                    sold_text.append(f"an hotel for {entry.square_property.full_name}")

        bought_text = ",".join(bought_text) if bought_text else "no houses/hotel"
        sold_text = ",".join(sold_text) if sold_text else "no houses/hotel"

        log_text = f"{self.player.name.upper()} bought {bought_text} and sold {sold_text}"
        self.root.parent.parent.add_history_log_entry(log_text)

        # Dismiss the popup
        self.dismiss()
コード例 #7
0
ファイル: popup_classes.py プロジェクト: ykzzyk/Monopoly
class MortgagePop(Popup):

    def __init__(self, **kwargs):
        # Obtain root reference
        self.root = kwargs.pop('root')
        self.btns = {}
        self.mortgage_unmortgage_money = 0
        self.total_money = 0

        if 'dismiss_binding_fn' in kwargs.keys():
            self.dismiss_binding_fn = kwargs.pop('dismiss_binding_fn')
        else:
            self.dismiss_binding_fn = None

        super().__init__(**kwargs)

        self.selected_square_properties = []
        self.ids.accept_btn.disabled = True

        Clock.schedule_once(self.create_dropdown, 0)

    def create_dropdown(self, *args):

        self.dropdown_list = DropDown()

        for player in self.root.players:
            player_name = player.name.upper()
            # button for dropdown list 1
            btn = Button(
                text=f'[b][color=#ffffff]{player_name}[/b][/color]', size_hint_y=None,
                height=self.width // 25,
                markup=True
            )

            # Storing the btn references into a list
            self.btns[player_name] = btn

            # Create the binding function
            btn.bind(on_release=lambda btn: self.dropdown_list.select(btn.text))

            # Add the widget to the dropdown window
            self.dropdown_list.add_widget(btn)

        # Bind the select name btns to opening the dropdown window
        self.ids.select_name_btn.bind(on_release=self.dropdown_list.open)

        # Binding the select name btns to also update their text values
        self.dropdown_list.bind(
            on_select=functools.partial(self.select_player, self.ids.select_name_btn)
        )

    def select_player(self, btn, instance, button_text):

        # Obtain the true value in the text
        previous_player_name = btn.text.split(']')[2].split('[')[0]
        player_name = button_text.split(']')[2].split('[')[0]

        # If the selection change from not the default value
        if previous_player_name != 'SELECT PLAYER NAME':
            self.dropdown_list.add_widget(self.btns[previous_player_name])

        # Removing the corresponding button from
        # right dropdown window
        self.dropdown_list.remove_widget(self.btns[player_name])

        # Update text to given x
        btn.text = button_text

        # Find the matching player given the player_name
        selected_player = None
        for player in self.root.players:
            if player.name.upper() == player_name:
                selected_player = player
                break

        # Storing the selected player
        self.player = selected_player

        # Update the player_current_money label
        self.ids.player_current_money.text = f"[b][color=#000000]Player Current Money: ${self.player.money}[/b][/color]"

        # Update the property container with the selected player
        self.update_property_container(selected_player)

        if selected_player is not None:
            self.ids.accept_btn.disabled = False

    def update_property_container(self, selected_player):

        # Clean property container
        self.ids.property_container.clear_widgets()

        # Fill the property container given the properties of the
        # selected player
        for square_property in selected_player.property_own:

            # If the property has houses, then it cannot be mortgaged
            if isinstance(square_property, PropertySquare) and (square_property.number_of_houses != 0):
                continue

            # Determine color of property
            property_color = "assets/buttons/red.png" if square_property.mortgage is False else "assets/buttons/light_grey.jpg"

            # Create button for property
            property_btn = PropertyButton(
                text=f'[b][color=#000000]{square_property.full_name}[/b][/color]',
                markup=True,
                background_normal=property_color,
                square_property=square_property
            )

            # Bind the property button to function
            property_btn.bind(on_release=functools.partial(self.property_button_press))

            # Add button to the property container
            self.ids.property_container.add_widget(property_btn)

    def property_button_press(self, btn_instance):

        # If the property is already selected, deselect it by:
        if btn_instance.square_property in self.selected_square_properties:

            # Remove from the list
            self.selected_square_properties.remove(btn_instance.square_property)

            # Change the color of the button back to white
            if btn_instance.square_property.mortgage is True:
                btn_instance.background_normal = "assets/buttons/light_grey.jpg"
                self.mortgage_unmortgage_money += btn_instance.square_property.unmortgage_value
            else:
                btn_instance.background_normal = "assets/buttons/red.png"
                self.mortgage_unmortgage_money -= btn_instance.square_property.mortgage_value

        else:

            # Append to the list
            self.selected_square_properties.append(btn_instance.square_property)

            # Change the color of the button to be highlighted
            if btn_instance.square_property.mortgage is True:
                btn_instance.background_normal = "assets/buttons/red.png"
                self.mortgage_unmortgage_money -= btn_instance.square_property.unmortgage_value
            else:
                btn_instance.background_normal = "assets/buttons/light_grey.jpg"
                self.mortgage_unmortgage_money += btn_instance.square_property.mortgage_value

        # Update the property_money
        if self.mortgage_unmortgage_money < 0:
            self.ids.mortgage_unmortgage_money.text = f"[b][color=#000000]Property Money: -${abs(self.mortgage_unmortgage_money)}[/b][/color]"
        else:
            self.ids.mortgage_unmortgage_money.text = f"[b][color=#000000]Property Money: ${abs(self.mortgage_unmortgage_money)}[/b][/color]"

        # Update the total_money
        self.total_money = self.player.money + self.mortgage_unmortgage_money
        self.ids.total_money.text = f"[b][color=#000000]Total Money: ${self.total_money}[/b][/color]"

        # if self.total_money != self.player.money:
        #     self.ids.select_name_btn.disabled = True
        # else:
        #     self.ids.select_name_btn.disabled = False
        if self.mortgage_unmortgage_money:
            self.ids.select_name_btn.disabled = True
        else:
            self.ids.select_name_btn.disabled = False

    def accept(self):

        # The properties that were selected must be mortgage/unmortgage
        for square_property in self.selected_square_properties:
            # Update the mortgage boolean
            square_property.mortgage = not square_property.mortgage

            # Call the gameboard to make the properties look mortgage or unmortgage
            square_property.update_player_icon()

        # Modify the player's money given the mortgage_unmortgage money
        self.player.money = self.total_money

        # Inform root to update property ownership and update player's money
        self.root.parent.parent.update_players_to_frame()

        # Log mortgage event
        mortgaged_property = ",".join(
            [square_property.full_name for square_property in self.selected_square_properties if
             square_property.mortgage is True])
        unmortgaged_property = ",".join(
            [square_property.full_name for square_property in self.selected_square_properties if
             square_property.mortgage is False])
        mortgaged_property = mortgaged_property if mortgaged_property else "no property"
        unmortgaged_property = unmortgaged_property if unmortgaged_property else "no property"

        log_text = f"{self.player.name.upper()} mortgaged {mortgaged_property} and unmortgage {unmortgaged_property}"
        self.root.parent.parent.add_history_log_entry(log_text)

        # Dismiss the popup
        self.dismiss()

    def dismiss(self):

        if self.dismiss_binding_fn:
            self.dismiss_binding_fn()

        super().dismiss()
コード例 #8
0
ファイル: popup_classes.py プロジェクト: ykzzyk/Monopoly
class TradePop(Popup):

    def __init__(self, **kwargs):
        # Obtain root reference
        self.root = kwargs.pop('root')

        super().__init__(**kwargs)

        # Btns list of players
        self.left_btns = {}
        self.right_btns = {}

        # Selected players
        self.left_player = None
        self.right_player = None

        # Properties selected containers
        self.left_square_properties = []
        self.right_square_properties = []

        # Disable the accept button
        self.ids.accept_btn.disabled = True

        Clock.schedule_once(self.create_dropdown, 0)

    def create_dropdown(self, *args):

        self.dropdown_list_left = DropDown()
        self.dropdown_list_right = DropDown()

        for player in self.root.players:
            player_name = player.name.upper()
            # button for dropdown list 1
            btn_left = Button(
                text=f'[b][color=#ffffff]{player_name}[/b][/color]', size_hint_y=None,
                height=self.width // 25,
                markup=True
            )

            # button for dropdown list 2
            btn_right = Button(
                text=f'[b][color=#ffffff]{player_name}[/b][/color]', size_hint_y=None,
                height=self.width // 25,
                markup=True
            )

            # Storing the btn references into a list
            self.left_btns[player_name] = btn_left
            self.right_btns[player_name] = btn_right

            # Create the binding function
            btn_left.bind(on_release=lambda btn_left: self.dropdown_list_left.select(btn_left.text))
            btn_right.bind(on_release=lambda btn_right: self.dropdown_list_right.select(btn_right.text))

            # Add the widget to the dropdown window
            self.dropdown_list_left.add_widget(btn_left)
            self.dropdown_list_right.add_widget(btn_right)

        # Bind the select name btns to opening the dropdown window
        self.ids.select_name_btn_left.bind(on_release=self.dropdown_list_left.open)
        self.ids.select_name_btn_right.bind(on_release=self.dropdown_list_right.open)

        # Binding the select name btns to also update their text values
        self.dropdown_list_left.bind(
            on_select=functools.partial(self.select_player, self.ids.select_name_btn_left, 'left')
        )
        self.dropdown_list_right.bind(
            on_select=functools.partial(self.select_player, self.ids.select_name_btn_right, 'right')
        )

    def select_player(self, btn, side, instance, button_text):

        # Obtain the true value in the text
        previous_player_name = btn.text.split(']')[2].split('[')[0]
        player_name = button_text.split(']')[2].split('[')[0]

        # If the selection change from not the default value
        if previous_player_name != 'SELECT PLAYER NAME':
            self.dropdown_list_right.add_widget(self.right_btns[previous_player_name])
            self.dropdown_list_left.add_widget(self.left_btns[previous_player_name])

        # Removing the corresponding button from
        # right dropdown window
        self.dropdown_list_left.remove_widget(self.left_btns[player_name])
        self.dropdown_list_right.remove_widget(self.right_btns[player_name])

        # Update text to given x
        btn.text = button_text

        # Find the matching player given the player_name
        selected_player = None
        for player in self.root.players:
            if player.name.upper() == player_name:
                selected_player = player
                break

        # Store the selected player
        if side == 'left':
            self.left_player = selected_player
            self.ids.left_slider.max = self.left_player.money
        elif side == 'right':
            self.right_player = selected_player
            self.ids.right_slider.max = self.right_player.money

        # Update the property container with the selected player
        self.update_property_container(selected_player, side)

        if (self.left_player is not None) and (self.right_player is not None):
            self.ids.accept_btn.disabled = False

    def update_property_container(self, selected_player, side):

        # Clean property container
        if side == 'left':
            self.ids.left_property_container.clear_widgets()
        elif side == 'right':
            self.ids.right_property_container.clear_widgets()

        # Fill the property container given the properties of the
        # selected player
        for square_property in selected_player.property_own:

            # Create button for property
            property_btn = PropertyButton(
                text=f'[b][color=#000000]{square_property.full_name}[/b][/color]',
                markup=True,
                background_normal="",
                square_property=square_property
            )

            # Bind the property button to function
            property_btn.bind(on_release=functools.partial(self.property_button_press, side))

            # Add button to the property container
            if side == 'left':
                self.ids.left_property_container.add_widget(property_btn)
            elif side == 'right':
                self.ids.right_property_container.add_widget(property_btn)

    def property_button_press(self, side, btn_instance):

        square_property_container = self.left_square_properties if side == 'left' else self.right_square_properties

        # If the property is already selected, deselect it by:
        if btn_instance.square_property in square_property_container:

            # Remove from the list
            square_property_container.remove(btn_instance.square_property)

            # Change the color of the button back to white
            btn_instance.background_normal = ""

        else:

            # Append to the list
            square_property_container.append(btn_instance.square_property)

            # Change the color of the button to be highlighted
            btn_instance.background_normal = "assets/buttons/red.png"

    def accept(self):
        # Exchange properties
        # Left player gets the right properties
        for traded_square_property in self.left_square_properties:
            # Remove left's ownership
            self.left_player.property_own.remove(traded_square_property)

            # Add right's ownership
            self.root.buy_property(self.right_player, traded_square_property, cost=0)

        # Right player gets the left properties
        for traded_square_property in self.right_square_properties:
            # Remove right's ownership
            self.right_player.property_own.remove(traded_square_property)

            # Add left's ownership
            self.root.buy_property(self.left_player, traded_square_property, cost=0)

        # Exchange money
        left_slider_value = int(self.ids.left_slider.value)
        right_slider_value = int(self.ids.right_slider.value)

        self.left_player.money -= left_slider_value
        self.right_player.money += left_slider_value

        self.left_player.money += right_slider_value
        self.right_player.money -= right_slider_value

        # Inform root to update property ownership and update player's money
        self.root.parent.parent.update_players_to_frame()

        # Trade event log
        left_property = ",".join([sq.full_name for sq in self.left_square_properties])
        right_property = ",".join([sq.full_name for sq in self.right_square_properties])

        left_property = left_property if left_property else "no property"
        right_property = right_property if right_property else "no property"

        log_text = f"{self.left_player.name.upper()} traded {left_property} and ${left_slider_value} for {self.right_player.name.upper()}'s {right_property} and ${right_slider_value}"
        self.root.parent.parent.add_history_log_entry(log_text)

        # Dismiss the popup
        self.dismiss()