def __init__(self, cp: ControlPoint, game_model: GameModel):
        super().__init__(self)
        self.cp = cp
        self.game_model = game_model

        self.bought_amount_labels = {}
        self.existing_units_labels = {}

        main_layout = QVBoxLayout()
        self.setLayout(main_layout)

        scroll_content = QWidget()
        task_box_layout = QGridLayout()
        scroll_content.setLayout(task_box_layout)

        units_column = sorted(cp.base.armor, key=lambda u: u.name)

        count = 0
        for count, unit_type in enumerate(units_column):
            self.add_purchase_row(unit_type, task_box_layout, count)
        stretch = QVBoxLayout()
        stretch.addStretch()
        task_box_layout.addLayout(stretch, count, 0)

        scroll_content.setLayout(task_box_layout)
        scroll = QScrollArea()
        scroll.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        scroll.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOn)
        scroll.setWidgetResizable(True)
        scroll.setWidget(scroll_content)
        main_layout.addWidget(scroll)
Example #2
0
    def init_ui(self):
        self.mainLayout = QVBoxLayout()

        scroll_content = QWidget()
        task_box_layout = QGridLayout()
        scroll_content.setLayout(task_box_layout)

        for g in self.cp.ground_objects:
            # Airbase groups are the objects that are hidden on the map because
            # they're shown in the base menu.
            if not g.airbase_group:
                continue

            # Of these, we need to ignore the FOB structure itself since that's
            # not supposed to be targetable.
            if isinstance(self.cp, Fob) and isinstance(g, BuildingGroundObject):
                continue

            group_info = QBaseDefenseGroupInfo(self.cp, g, self.game)
            task_box_layout.addWidget(group_info)

        scroll_content.setLayout(task_box_layout)
        scroll = QScrollArea()
        scroll.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        scroll.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOn)
        scroll.setWidgetResizable(True)
        scroll.setWidget(scroll_content)

        self.mainLayout.addWidget(scroll)

        self.setLayout(self.mainLayout)
    def init_ui(self):
        main_layout = QVBoxLayout()

        units = {
            CAP: db.find_unittype(CAP, self.game.player_name),
            CAS: db.find_unittype(CAS, self.game.player_name),
        }

        scroll_content = QWidget()
        task_box_layout = QGridLayout()
        row = 0

        for task_type in units.keys():
            units_column = list(set(units[task_type]))
            if len(units_column) == 0: continue
            units_column.sort(key=lambda x: db.PRICES[x])
            for unit_type in units_column:
                if self.cp.is_carrier and not unit_type in db.CARRIER_CAPABLE:
                    continue
                if self.cp.is_lha and not unit_type in db.LHA_CAPABLE:
                    continue
                row = self.add_purchase_row(unit_type, task_box_layout, row)
            stretch = QVBoxLayout()
            stretch.addStretch()
            task_box_layout.addLayout(stretch, row, 0)

        scroll_content.setLayout(task_box_layout)
        scroll = QScrollArea()
        scroll.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        scroll.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOn)
        scroll.setWidgetResizable(True)
        scroll.setWidget(scroll_content)
        main_layout.addWidget(scroll)
        self.setLayout(main_layout)
    class __Tab(QWidget):
        """ This code is for showing device specific items. This is just a scrollable display area. """
        def __init__(self):
            self.logger = logging.getLogger(__name__)
            self.logger.debug("Initializing")
            super().__init__()
            self.setLayout(QVBoxLayout())
            self.__scroll_area = QScrollArea(self)
            size_policy = QSizePolicy(QSizePolicy.Minimum, QSizePolicy.Minimum)
            size_policy.setHorizontalStretch(0)
            size_policy.setVerticalStretch(0)
            size_policy.setHeightForWidth(
                self.__scroll_area.hasHeightForWidth())
            self.__scroll_area.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded)
            self.__scroll_area.setHorizontalScrollBarPolicy(
                Qt.ScrollBarAsNeeded)
            self.__scroll_area.setSizeAdjustPolicy(
                QAbstractScrollArea.AdjustToContents)
            self.__scroll_area.setSizePolicy(size_policy)
            self.__scroll_area.setWidgetResizable(True)
            self.layout().addWidget(self.__scroll_area)
            self.logger.debug("Initialized")

        def add_contents(self, contents):
            self.logger.debug("running")
            self.__scroll_area.setWidget(contents)
            self.logger.debug("done")
Example #5
0
class PlayersWidget(QWidget):
    def __init__(self):
        factory = ApiRequestFactory.get_instance()
        QWidget.__init__(self)

        page_list = factory.get_players_from_page(1)

        self.layout = QVBoxLayout()

        label_widget = QWidget()
        label_widget.layout = QVBoxLayout()
        for page_obj in page_list[0]:
            for pl in page_obj[1]:
                lb_text = pl.first_name + ' ' + pl.last_name

                if pl.position is not None and (pl.position is not ''
                                                or pl.position is not ' '):
                    lb_text = lb_text + ': ' + pl.position

                player_lb = QLabel(text=lb_text)
                label_widget.layout.addWidget(player_lb)

        label_widget.setLayout(label_widget.layout)

        self.scroll_widget = QScrollArea()
        self.scroll_widget.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded)
        self.scroll_widget.setBackgroundRole(QPalette.Light)
        self.scroll_widget.setWidgetResizable(True)

        self.scroll_widget.setWidget(label_widget)
        self.layout.addWidget(self.scroll_widget)

        self.setLayout(self.layout)
    def __init__(self, cp: ControlPoint, game_model: GameModel) -> None:
        super().__init__()
        self.cp = cp
        self.game_model = game_model
        self.transfers: Dict[Type[UnitType, int]] = defaultdict(int)

        main_layout = QVBoxLayout()

        scroll_content = QWidget()
        task_box_layout = QGridLayout()

        unit_types = set(
            self.game_model.game.faction_for(player=True).ground_units)
        sorted_units = sorted(
            {u
             for u in unit_types if self.cp.base.total_units_of_type(u)},
            key=lambda u: u.name,
        )
        for row, unit_type in enumerate(sorted_units):
            self.add_unit_row(unit_type, task_box_layout, row)
        stretch = QVBoxLayout()
        stretch.addStretch()
        task_box_layout.addLayout(stretch, task_box_layout.count(), 0)

        scroll_content.setLayout(task_box_layout)
        scroll = QScrollArea()
        scroll.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        scroll.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOn)
        scroll.setWidgetResizable(True)
        scroll.setWidget(scroll_content)
        main_layout.addWidget(scroll)
        self.setLayout(main_layout)
Example #7
0
    def init_ui(self):
        main_layout = QVBoxLayout()

        units = {
            PinpointStrike:
            db.find_unittype(PinpointStrike, self.game.player_name),
        }

        scroll_content = QWidget()
        task_box_layout = QGridLayout()
        scroll_content.setLayout(task_box_layout)
        row = 0

        for task_type in units.keys():
            units_column = list(set(units[task_type]))
            if len(units_column) == 0: continue
            units_column.sort(key=lambda x: db.PRICES[x])
            for unit_type in units_column:
                row = self.add_purchase_row(unit_type, task_box_layout, row)
            stretch = QVBoxLayout()
            stretch.addStretch()
            task_box_layout.addLayout(stretch, row, 0)

        scroll_content.setLayout(task_box_layout)
        scroll = QScrollArea()
        scroll.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        scroll.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOn)
        scroll.setWidgetResizable(True)
        scroll.setWidget(scroll_content)
        main_layout.addWidget(scroll)
        self.setLayout(main_layout)
Example #8
0
    def _init_widgets(self):
        if self._state.am_none():
            return

        layout = QVBoxLayout()
        area = QScrollArea()
        area.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded)
        area.setHorizontalScrollBarPolicy(Qt.ScrollBarAsNeeded)
        area.setWidgetResizable(True)

        table = QTableWidget(0, 0)
        table.setColumnCount(len(self.COLUMNS))
        table.setHorizontalHeaderLabels(self.COLUMNS)

        self.table = table
        layout.addWidget(table)

        # common ones
        layout.setSpacing(0)
        layout.addStretch(0)
        layout.setContentsMargins(2, 2, 2, 2)

        # the container
        container = QFrame()
        container.setAutoFillBackground(True)
        palette = container.palette()
        palette.setColor(container.backgroundRole(), Qt.white)
        container.setPalette(palette)
        container.setLayout(layout)

        area.setWidget(container)

        base_layout = QVBoxLayout()
        base_layout.addWidget(area)
        self.setLayout(base_layout)
    def __init__(self, cp: ControlPoint, game_model: GameModel):
        super().__init__()
        self.cp = cp
        self.setMinimumWidth(500)

        layout = QVBoxLayout()
        self.setLayout(layout)

        scroll_content = QWidget()
        task_box_layout = QGridLayout()
        scroll_content.setLayout(task_box_layout)

        for convoy in game_model.game.coalition_for(
                cp.captured).transfers.convoys.departing_from(cp):
            group_info = DepartingConvoyInfo(convoy)
            task_box_layout.addWidget(group_info)

        for cargo_ship in game_model.game.coalition_for(
                cp.captured).transfers.cargo_ships.departing_from(cp):
            group_info = DepartingConvoyInfo(cargo_ship)
            task_box_layout.addWidget(group_info)

        scroll_content.setLayout(task_box_layout)
        scroll = QScrollArea()
        scroll.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        scroll.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOn)
        scroll.setWidgetResizable(True)
        scroll.setWidget(scroll_content)
        layout.addWidget(scroll)
Example #10
0
    def _init_widgets(self):
        layout = QVBoxLayout()

        # address

        lbl_addr = QLabel()
        lbl_addr.setText("Address")

        txt_addr = QLineEdit()
        txt_addr.returnPressed.connect(self._on_address_entered)
        self._txt_addr = txt_addr

        top_layout = QHBoxLayout()
        top_layout.addWidget(lbl_addr)
        top_layout.addWidget(txt_addr)

        self._view = QMemoryView(self.state, self.workspace)

        area = QScrollArea()
        self._scrollarea = area
        area.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded)
        area.setHorizontalScrollBarPolicy(Qt.ScrollBarAsNeeded)
        area.setWidgetResizable(True)

        area.setWidget(self._view)

        layout.addLayout(top_layout)
        layout.addWidget(area)
        layout.setContentsMargins(0, 0, 0, 0)

        self.setLayout(layout)
    def init_ui(self):
        main_layout = QVBoxLayout()

        scroll_content = QWidget()
        task_box_layout = QGridLayout()
        scroll_content.setLayout(task_box_layout)
        row = 0

        unit_types = list(
            set(self.game_model.game.faction_for(player=True).ground_units))
        unit_types.sort(key=lambda u: u.name)
        for row, unit_type in enumerate(unit_types):
            self.add_purchase_row(unit_type, task_box_layout, row)
        stretch = QVBoxLayout()
        stretch.addStretch()
        task_box_layout.addLayout(stretch, row, 0)

        scroll_content.setLayout(task_box_layout)
        scroll = QScrollArea()
        scroll.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        scroll.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOn)
        scroll.setWidgetResizable(True)
        scroll.setWidget(scroll_content)
        main_layout.addWidget(scroll)
        self.setLayout(main_layout)
Example #12
0
class PageAllegroMonitored(QWidget):
    def __init__(self, parent=None, shared_dict=None):
        QWidget.__init__(self)
        parent.addWidget(self)
        self.shared_dict = shared_dict
        self.parent = parent
        self.setLayoutDirection(Qt.LeftToRight)

        self.gridLayout = QGridLayout(self)
        self.gridLayout.setContentsMargins(0, 0, 0, 0)

        self.scrollArea = QScrollArea(self)
        self.scrollArea.setStyleSheet("""QScrollArea{border: none;}""")
        self.scrollArea.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded)
        self.scrollArea.setSizeAdjustPolicy(QAbstractScrollArea.AdjustIgnored)
        self.scrollArea.setWidgetResizable(True)
        self.gridLayout.addWidget(self.scrollArea, 0, 0, 1, 1)

        self.scrollAreaWidgetContents = QWidget()
        self.scrollAreaWidgetContents.setGeometry(QRect(0, 0, 654, 479))
        self.scrollArea.setWidget(self.scrollAreaWidgetContents)

        self.gridLayout_scroll_area = QGridLayout(
            self.scrollAreaWidgetContents)
        self.gridLayout_scroll_area.setSpacing(0)
        self.gridLayout_scroll_area.setContentsMargins(40, 0, 40, -1)

        self.label_title = QLabel("List of your monitored objects",
                                  self.scrollAreaWidgetContents)
        self.label_title.setStyleSheet(styles.label_title)
        self.label_title.setAlignment(Qt.AlignCenter)
        self.gridLayout_scroll_area.addWidget(self.label_title)

        self.spacer = QSpacerItem(20, 40, QSizePolicy.Minimum,
                                  QSizePolicy.Expanding)

        self.load_list()

    def load_list(self):
        elements = data.read_monitored_elements()
        for element in elements:
            e = ElementAllegroMonitored(element['name'], element['link'],
                                        element['is_done'], element['price'],
                                        element['xpath'], element['time'],
                                        element['is_monitoring'],
                                        self.scrollAreaWidgetContents,
                                        self.shared_dict)
            self.gridLayout_scroll_area.addWidget(e)

        self.gridLayout_scroll_area.addItem(self.spacer)

    def add_to_list(self, name, link, is_done, price, xpath, time,
                    is_monitoring):
        self.gridLayout_scroll_area.removeItem(self.spacer)
        e = ElementAllegroMonitored(name, link, is_done, price, xpath, time,
                                    is_monitoring)
        self.gridLayout_scroll_area.addWidget(e)
        self.gridLayout_scroll_area.addItem(self.spacer)
Example #13
0
    def _askForFieldsDialog(self, options, fields_type="inputs"):
        #Display a dialog to ask the user to choose what inputs/outputs they want
        dialog = QDialog(self)

        dialog.setWindowTitle(f"Select the model {fields_type.upper()}")
        dialogButtons = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel)
        dialogButtons.button(QDialogButtonBox.Ok).setDisabled(0)
        dialogButtons.accepted.connect(dialog.accept)
        dialogButtons.rejected.connect(dialog.reject)
        
        mainLayout = QVBoxLayout(dialog)
        scroll = QScrollArea(dialog)
        scroll.setWidgetResizable(True)
        layoutWidget = QWidget()
        layout = QVBoxLayout(layoutWidget)
        scroll.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded)
        scroll.setWidget(layoutWidget)

        chosenFields=[]
        checkboxes=[]

        def handleCheckboxClicked():
            dialogButtons.button(QDialogButtonBox.Ok).setDisabled(1)
            count = 0
            for checkbox in checkboxes:
                if checkbox.isChecked():
                    count += 1
            if fields_type.lower() == "output":
                setDisabled = True if count > 1 else False
            else:
                setDisabled = True if count == 0 else False
            dialogButtons.button(QDialogButtonBox.Ok).setDisabled(setDisabled)

        for input in options:
            checkbox = QCheckBox(text=input)
            checkbox.clicked.connect(handleCheckboxClicked)
            checkbox.setChecked(True)
            checkboxes.append(checkbox)
            layout.addWidget(checkbox)

        mainLayout.addWidget(QLabel(text=f"Please select the {fields_type.lower()} from the following:"))
        mainLayout.addWidget(scroll)
        mainLayout.addWidget(dialogButtons)
        dialog.setLayout(mainLayout)

        handleCheckboxClicked()

        if dialog.exec_() == QDialog.Accepted:
            for checkbox in checkboxes:
                if checkbox.isChecked():
                    chosenFields.append(checkbox.text())
            self.logger.log(f"The chosen {fields_type.lower()} are: "+ ', '.join(chosenFields), type ="INFO")
            return chosenFields
        else:
            return []
    def _init_widgets(self):
        if self._state.am_none():
            return

        if self._state.arch.name not in self.ARCH_REGISTERS:
            l.error(
                "Architecture %s is not listed in QRegisterViewer.ARCH_REGISTERS.",
                self._state.arch.name)
            return

        layout = QVBoxLayout()
        area = QScrollArea()
        area.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded)
        area.setHorizontalScrollBarPolicy(Qt.ScrollBarAsNeeded)
        area.setWidgetResizable(True)

        regs = self.ARCH_REGISTERS[self._state.arch.name]

        # common ones
        common_regs = regs['common']

        for reg_name in common_regs:
            sublayout = QHBoxLayout()

            lbl_reg_name = QLabel(self)
            lbl_reg_name.setProperty('class', 'reg_viewer_label')
            lbl_reg_name.setText(reg_name)
            lbl_reg_name.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
            sublayout.addWidget(lbl_reg_name)

            sublayout.addSpacing(10)
            reg_value = QASTViewer(None, parent=self, workspace=self.workspace)
            self._registers[reg_name] = reg_value
            sublayout.addWidget(reg_value)

            layout.addLayout(sublayout)

        layout.setSpacing(0)
        layout.addStretch(0)
        layout.setContentsMargins(2, 2, 2, 2)

        # the container
        container = QFrame()
        container.setAutoFillBackground(True)
        palette = container.palette()
        palette.setColor(container.backgroundRole(), Qt.white)
        container.setPalette(palette)
        container.setLayout(layout)

        area.setWidget(container)

        base_layout = QVBoxLayout()
        base_layout.addWidget(area)
        self.setLayout(base_layout)
Example #15
0
    def _init_widgets(self):

        area = QScrollArea()
        area.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded)
        area.setHorizontalScrollBarPolicy(Qt.ScrollBarAsNeeded)
        area.setWidgetResizable(True)

        self._area = area

        base_layout = QVBoxLayout()
        base_layout.addWidget(area)
        self.setLayout(base_layout)
    def __init__(self, cp: ControlPoint, game_model: GameModel) -> None:
        QFrame.__init__(self)
        self.cp = cp
        self.game_model = game_model
        self.purchase_groups = {}
        self.bought_amount_labels = {}
        self.existing_units_labels = {}

        # Determine maximum number of aircrafts that can be bought
        self.set_maximum_units(self.cp.total_aircraft_parking)

        self.bought_amount_labels = {}
        self.existing_units_labels = {}

        self.hangar_status = QHangarStatus(game_model, self.cp)

        main_layout = QVBoxLayout()

        scroll_content = QWidget()
        task_box_layout = QGridLayout()
        row = 0

        unit_types: Set[AircraftType] = set()
        for unit_type in self.game_model.game.player_faction.aircrafts:
            if self.cp.is_carrier and not unit_type.carrier_capable:
                continue
            if self.cp.is_lha and not unit_type.lha_capable:
                continue
            if (self.cp.cptype
                    in [ControlPointType.FOB, ControlPointType.FARP]
                    and unit_type not in helicopter_map.values()):
                continue
            unit_types.add(unit_type)

        sorted_units = sorted(
            unit_types,
            key=lambda u: u.name,
        )
        for row, unit_type in enumerate(sorted_units):
            self.add_purchase_row(unit_type, task_box_layout, row)
        stretch = QVBoxLayout()
        stretch.addStretch()
        task_box_layout.addLayout(stretch, row, 0)

        scroll_content.setLayout(task_box_layout)
        scroll = QScrollArea()
        scroll.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        scroll.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOn)
        scroll.setWidgetResizable(True)
        scroll.setWidget(scroll_content)
        main_layout.addLayout(self.hangar_status)
        main_layout.addWidget(scroll)
        self.setLayout(main_layout)
Example #17
0
    def init_ui(self):
        layout = QVBoxLayout()
        scroll_content = QWidget()
        intelLayout = QVBoxLayout()

        units = {
            CAP: db.find_unittype(CAP, self.game.enemy_name),
            Embarking: db.find_unittype(Embarking, self.game.enemy_name),
            CAS: db.find_unittype(CAS, self.game.enemy_name),
            PinpointStrike: db.find_unittype(PinpointStrike, self.game.enemy_name),
        }

        for task_type in units.keys():
            units_column = list(set(units[task_type]))

            if sum([self.cp.base.total_units_of_type(u) for u in units_column]) > 0:

                group = QGroupBox(db.task_name(task_type))
                groupLayout = QGridLayout()
                group.setLayout(groupLayout)

                row = 0
                for unit_type in units_column:
                    existing_units = self.cp.base.total_units_of_type(unit_type)
                    if existing_units == 0:
                        continue
                    groupLayout.addWidget(
                        QLabel(
                            "<b>"
                            + db.unit_get_expanded_info(
                                self.game.enemy_country, unit_type, "name"
                            )
                            + "</b>"
                        ),
                        row,
                        0,
                    )
                    groupLayout.addWidget(QLabel(str(existing_units)), row, 1)
                    row += 1

                intelLayout.addWidget(group)

        scroll_content.setLayout(intelLayout)
        scroll = QScrollArea()
        scroll.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        scroll.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOn)
        scroll.setWidgetResizable(True)
        scroll.setWidget(scroll_content)

        layout.addWidget(scroll)

        self.setLayout(layout)
Example #18
0
    def init_ui(self):
        main_layout = QVBoxLayout()

        tasks = [CAP, CAS, AWACS]

        scroll_content = QWidget()
        task_box_layout = QGridLayout()
        row = 0

        unit_types: Set[Type[FlyingType]] = set()
        for task in tasks:
            units = db.find_unittype(task, self.game_model.game.player_name)
            if not units:
                continue
            for unit in units:
                if not issubclass(unit, FlyingType):
                    continue
                if self.cp.is_carrier and unit not in db.CARRIER_CAPABLE:
                    continue
                if self.cp.is_lha and unit not in db.LHA_CAPABLE:
                    continue
                if (self.cp.cptype
                        in [ControlPointType.FOB, ControlPointType.FARP]
                        and unit not in helicopter_map.values()):
                    continue
                unit_types.add(unit)

        sorted_units = sorted(
            unit_types,
            key=lambda u: db.unit_get_expanded_info(
                self.game_model.game.player_country, u, "name"),
        )
        for unit_type in sorted_units:
            row = self.add_purchase_row(
                unit_type,
                task_box_layout,
                row,
                disabled=not self.cp.can_operate(unit_type),
            )
            stretch = QVBoxLayout()
            stretch.addStretch()
            task_box_layout.addLayout(stretch, row, 0)

        scroll_content.setLayout(task_box_layout)
        scroll = QScrollArea()
        scroll.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        scroll.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOn)
        scroll.setWidgetResizable(True)
        scroll.setWidget(scroll_content)
        main_layout.addLayout(self.hangar_status)
        main_layout.addWidget(scroll)
        self.setLayout(main_layout)
Example #19
0
class SearchRouteList(QWidget):
    def __init__(self, routes):
        super().__init__()

        self.route_list = RouteList(routes)
        self.scroll_area = QScrollArea()
        self.scroll_area.setWidget(self.route_list)
        self.scroll_area.setWidgetResizable(False)
        self.scroll_area.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        self.scroll_area.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded)

        self.search_line = QLineEdit()
        self.search_line.setPlaceholderText('Search')
        self.search_line.textChanged.connect(self.search)
        self.search_line.returnPressed.connect(self.select_first_visible)

        layout = QVBoxLayout()
        layout.addWidget(self.search_line)
        layout.addWidget(self.scroll_area)

        self.setLayout(layout)

    def search(self):
        text_elements = self.search_line.text().lower().split(' ')

        for button in self.route_list.buttons:
            visible = all(text_element in button.text().lower()
                          for text_element in text_elements)
            button.setVisible(visible)

    def select_first_visible(self):
        for button in self.route_list.buttons:
            if button.isVisible():
                button.animateClick()
                return

    def select_route_with_name(self, name):
        for route, button in self.route_list.route_per_button.items():
            if route.name == name:
                button.animateClick()
                return

    def set_search(self, text):
        self.search_line.setText(text)

    def current_search(self):
        return self.search_line.text()

    def focus(self):
        self.search_line.setFocus()
        self.search_line.selectAll()
Example #20
0
    def __init__(self, cp: ControlPoint):
        super(QIntelInfo, self).__init__()
        self.cp = cp

        layout = QVBoxLayout()
        scroll_content = QWidget()
        intel_layout = QVBoxLayout()

        units_by_task: dict[str,
                            dict[str,
                                 int]] = defaultdict(lambda: defaultdict(int))
        for unit_type, count in self.cp.allocated_aircraft().present.items():
            if count:
                task_type = unit_type.dcs_unit_type.task_default.name
                units_by_task[task_type][unit_type.name] += count

        units_by_task = {
            task: units_by_task[task]
            for task in sorted(units_by_task.keys())
        }

        front_line_units = defaultdict(int)
        for unit_type, count in self.cp.base.armor.items():
            if count:
                front_line_units[unit_type.name] += count

        units_by_task["Front line units"] = front_line_units
        for task, unit_types in units_by_task.items():
            task_group = QGroupBox(task)
            task_layout = QGridLayout()
            task_group.setLayout(task_layout)

            for row, (name, count) in enumerate(unit_types.items()):
                task_layout.addWidget(QLabel(f"<b>{name}</b>"), row, 0)
                task_layout.addWidget(QLabel(str(count)), row, 1)

            intel_layout.addWidget(task_group)

        scroll_content.setLayout(intel_layout)
        scroll = QScrollArea()
        scroll.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        scroll.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOn)
        scroll.setWidgetResizable(True)
        scroll.setWidget(scroll_content)

        layout.addWidget(scroll)

        self.setLayout(layout)
    def __init__(self, squadrons: list[Squadron],
                 theater: ConflictTheater) -> None:
        super().__init__()
        layout = QVBoxLayout()
        self.setLayout(layout)

        self.squadrons_config = SquadronConfigurationLayout(squadrons, theater)
        self.squadrons_config.config_changed.connect(
            self.on_squadron_config_changed)

        scrolling_widget = QWidget()
        scrolling_widget.setLayout(self.squadrons_config)

        scrolling_area = QScrollArea()
        scrolling_area.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        scrolling_area.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOn)
        scrolling_area.setWidgetResizable(True)
        scrolling_area.setWidget(scrolling_widget)

        layout.addWidget(scrolling_area)
Example #22
0
    def init_ui(self):
        self.mainLayout = QVBoxLayout()

        scroll_content = QWidget()
        task_box_layout = QGridLayout()
        scroll_content.setLayout(task_box_layout)

        for g in self.cp.ground_objects:
            if g.airbase_group:
                group_info = QBaseDefenseGroupInfo(self.cp, g, self.game)
                task_box_layout.addWidget(group_info)

        scroll_content.setLayout(task_box_layout)
        scroll = QScrollArea()
        scroll.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        scroll.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOn)
        scroll.setWidgetResizable(True)
        scroll.setWidget(scroll_content)

        self.mainLayout.addWidget(scroll)

        self.setLayout(self.mainLayout)
Example #23
0
    def build_ui(self):
        layout = QGridLayout(self)
        layout.setContentsMargins(5, 5, 5, 5)
        self.setLayout(layout)

        self.name_edt = QLineEdit()
        self.name_edt.setPlaceholderText('Create New')
        self.name_edt.setSizePolicy(QSizePolicy.Preferred,
                                    QSizePolicy.Preferred)
        layout.addWidget(self.name_edt, 0, 0, 1, 1)

        self.add_btn = QPushButton()
        self.add_btn.setIcon(QIcon(QPixmap(':/teAdditive.png')))
        self.add_btn.setSizePolicy(QSizePolicy.Maximum, QSizePolicy.Preferred)
        layout.addWidget(self.add_btn, 0, 1, 1, 1)

        self.refresh_btn = QPushButton()
        self.refresh_btn.setIcon(QIcon(QPixmap(':/teKeyRefresh.png')))
        self.refresh_btn.setSizePolicy(QSizePolicy.Maximum,
                                       QSizePolicy.Preferred)
        layout.addWidget(self.refresh_btn, 0, 2, 1, 1)

        scroll_wdg = QWidget(self)
        scroll_area = QScrollArea()
        scroll_area.setWidgetResizable(True)
        scroll_area.setStyleSheet(
            "QScrollArea { background-color: rgb(57,57,57);}")
        scroll_area.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOn)
        scroll_area.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        scroll_area.setWidget(scroll_wdg)

        self.spore_layout = QVBoxLayout()
        self.spore_layout.setContentsMargins(1, 1, 3, 1)
        self.spore_layout.setSpacing(0)
        self.spore_layout.addStretch()
        scroll_wdg.setLayout(self.spore_layout)
        layout.addWidget(scroll_area, 1, 0, 1, 3)
Example #24
0
    def __init__(self, cp: ControlPoint, game_model: GameModel):
        super().__init__(
            game_model,
            GroundUnitPurchaseAdapter(
                cp, game_model.game.coalition_for(cp.captured),
                game_model.game),
        )
        self.cp = cp
        self.game_model = game_model
        self.purchase_groups = {}
        self.bought_amount_labels = {}
        self.existing_units_labels = {}

        main_layout = QVBoxLayout()

        scroll_content = QWidget()
        task_box_layout = QGridLayout()
        scroll_content.setLayout(task_box_layout)
        row = 0

        unit_types = list(
            set(self.game_model.game.faction_for(player=True).ground_units))
        unit_types.sort(key=lambda u: u.name)
        for row, unit_type in enumerate(unit_types):
            self.add_purchase_row(unit_type, task_box_layout, row)
        stretch = QVBoxLayout()
        stretch.addStretch()
        task_box_layout.addLayout(stretch, row, 0)

        scroll_content.setLayout(task_box_layout)
        scroll = QScrollArea()
        scroll.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        scroll.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOn)
        scroll.setWidgetResizable(True)
        scroll.setWidget(scroll_content)
        main_layout.addWidget(scroll)
        self.setLayout(main_layout)
    def init_ui(self):
        main_layout = QVBoxLayout()

        tasks = [CAP, CAS]

        scroll_content = QWidget()
        task_box_layout = QGridLayout()
        row = 0

        unit_types: Set[UnitType] = set()
        for task in tasks:
            units = db.find_unittype(task, self.game_model.game.player_name)
            if not units:
                continue
            for unit in units:
                if self.cp.is_carrier and unit not in db.CARRIER_CAPABLE:
                    continue
                if self.cp.is_lha and unit not in db.LHA_CAPABLE:
                    continue
                unit_types.add(unit)

        sorted_units = sorted(unit_types, key=lambda u: db.unit_type_name_2(u))
        for unit_type in sorted_units:
            row = self.add_purchase_row(unit_type, task_box_layout, row)
            stretch = QVBoxLayout()
            stretch.addStretch()
            task_box_layout.addLayout(stretch, row, 0)

        scroll_content.setLayout(task_box_layout)
        scroll = QScrollArea()
        scroll.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        scroll.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOn)
        scroll.setWidgetResizable(True)
        scroll.setWidget(scroll_content)
        main_layout.addLayout(self.hangar_status)
        main_layout.addWidget(scroll)
        self.setLayout(main_layout)
Example #26
0
class NodeChoiceWidget(QWidget):
    def __init__(self, flow, nodes):
        super(NodeChoiceWidget, self).__init__()

        self.flow = flow

        self.all_nodes = sort_nodes(nodes)  # copy, no ref

        self.nodes = []

        # 'current_nodes' are the currently selectable ones, they get recreated every time update_view() is called
        self.current_nodes = []
        self.all_current_node_widgets = []
        self.active_node_widget_index = -1
        self.active_node_widget = None

        self.reset_list()

        self.node_widget_index_counter = 0

        self.setMinimumWidth(260)
        self.setFixedHeight(450)

        self.main_layout = QVBoxLayout(self)
        self.main_layout.setAlignment(Qt.AlignTop)
        self.setLayout(self.main_layout)

        # adding all stuff to the layout
        self.search_line_edit = QLineEdit(self)
        self.search_line_edit.setPlaceholderText('search for node...')
        self.search_line_edit.textChanged.connect(self.update_view)
        self.layout().addWidget(self.search_line_edit)

        self.list_scroll_area = QScrollArea(self)
        self.list_scroll_area.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded)
        self.list_scroll_area.setHorizontalScrollBarPolicy(
            Qt.ScrollBarAsNeeded)
        self.list_scroll_area.setWidgetResizable(True)

        self.list_scroll_area_widget = QWidget()
        self.list_scroll_area.setWidget(self.list_scroll_area_widget)

        self.list_layout = QVBoxLayout()
        self.list_layout.setAlignment(Qt.AlignTop)
        self.list_scroll_area_widget.setLayout(self.list_layout)

        self.layout().addWidget(self.list_scroll_area)

        self.setFixedHeight(400)

        self.update_view('')

        try:
            f = open('resources/stylesheets/dark_node_choice_widget.txt')
            self.setStyleSheet(f.read())
            f.close()
        except FileNotFoundError:
            pass

        self.search_line_edit.setFocus()

    def mousePressEvent(self, event):
        QWidget.mousePressEvent(self, event)
        event.accept()

    def keyPressEvent(self, event):
        if event.key() == Qt.Key_Escape:
            self.flow.hide_node_choice_widget()

        if event.key() == Qt.Key_Down:
            index = self.active_node_widget_index+1 if \
                self.active_node_widget_index+1 < len(self.all_current_node_widgets) else 0
            self.set_active_node_widget_index(index)
        if event.key() == Qt.Key_Up:
            index = self.active_node_widget_index-1 if \
                self.active_node_widget_index-1 > -1 else len(self.all_current_node_widgets)-1
            self.set_active_node_widget_index(index)

        if event.key() == Qt.Key_Return:
            if len(self.all_current_node_widgets) > 0:
                self.place_node(self.active_node_widget_index)

    def wheelEvent(self, event):
        QWidget.wheelEvent(self, event)
        event.accept()

    def refocus(self):
        self.search_line_edit.setFocus()
        self.search_line_edit.selectAll()

    def update_list(self, nodes):
        self.nodes = sort_nodes(nodes)

    def reset_list(self):
        self.nodes = self.all_nodes

    def update_view(self, text=''):
        text = text.lower()
        for i in reversed(range(self.list_layout.count())):
            self.list_layout.itemAt(i).widget().setParent(None)

        self.current_nodes.clear()
        self.all_current_node_widgets.clear()

        self.node_widget_index_counter = 0

        # select valid elements from text
        # nodes
        nodes_names_dict = {}
        for n in self.nodes:
            nodes_names_dict[n] = n.title.lower()
        sorted_indices = self.get_sorted_dict_matching_search(
            nodes_names_dict, text)
        for n, index in sorted_indices.items():
            self.current_nodes.append(n)

        # nodes
        if len(self.current_nodes) > 0:
            nodes_label = QLabel('Hover for description')
            nodes_label_font = QFont('Poppins')
            nodes_label_font.setPixelSize(15)
            nodes_label.setStyleSheet('color: #9bbf9dff; border: none;')
            nodes_label.setFont(nodes_label_font)
            self.list_layout.addWidget(nodes_label)

            for n in self.current_nodes:
                node_widget = self.create_list_item_widget(n)
                self.list_layout.addWidget(node_widget)
                self.all_current_node_widgets.append(node_widget)

        if len(self.all_current_node_widgets) > 0:
            self.set_active_node_widget_index(0)

        # self.setFixedWidth(self.minimumWidth())
        # print(self.list_scroll_area_widget.width())

    def get_sorted_dict_matching_search(self, items_dict, text):
        indices_dict = {}
        for item, name in items_dict.items(
        ):  # the strings are already lowered here
            Debugger.debug(item, name, text)
            if name.__contains__(text):
                index = name.index(text)
                indices_dict[item] = index
        return {
            k: v
            for k, v in sorted(indices_dict.items(), key=lambda i: i[1])
        }

    def create_list_item_widget(self, node):
        node_widget = NodeWidget(self, node)  # , self.node_images[node])
        node_widget.custom_focused_from_inside.connect(
            self.node_widget_focused_from_inside)
        node_widget.setObjectName('node_widget_' +
                                  str(self.node_widget_index_counter))
        self.node_widget_index_counter += 1
        node_widget.chosen.connect(self.node_widget_chosen)

        return node_widget

    def node_widget_focused_from_inside(self):
        self.set_active_node_widget_index(
            self.all_current_node_widgets.index(self.sender()))

    def set_active_node_widget_index(self, index):
        self.active_node_widget_index = index
        node_widget = self.all_current_node_widgets[index]

        if self.active_node_widget:
            self.active_node_widget.set_custom_focus(False)

        node_widget.set_custom_focus(True)
        self.active_node_widget = node_widget
        self.list_scroll_area.ensureWidgetVisible(self.active_node_widget)

    def node_widget_chosen(
        self
    ):  # gets called when the user clicks on a node widget with the mouse
        self.flow.ignore_mouse_event = True  # otherwise, it will receive a mouse press event

        index = int(
            self.sender().objectName()[self.sender().objectName().rindex('_') +
                                       1:])
        self.place_node(index)

    def place_node(self, index):
        node_index = index
        node = self.current_nodes[node_index]
        self.flow.place_node__cmd(node)

        self.flow.hide_node_choice_widget()
Example #27
0
    def __init__(self, filenames: list, *args, **kwargs):
        super(ImportParamDialog, self).__init__(*args, **kwargs)

        self.import_widgets = []

        self.setWindowTitle("Video Import Options")

        self.import_types = [
            {
                "video_type":
                "hdf5",
                "match":
                "h5,hdf5",
                "video_class":
                Video.from_hdf5,
                "params": [
                    {
                        "name": "dataset",
                        "type": "function_menu",
                        "options": "_get_h5_dataset_options",
                        "required": True,
                    },
                    {
                        "name": "input_format",
                        "type": "radio",
                        "options": "channels_first,channels_last",
                        "required": True,  # we can't currently auto-detect
                    },
                ],
            },
            {
                "video_type": "mp4",
                "match": "mp4,avi",
                "video_class": Video.from_media,
                "params": [{
                    "name": "grayscale",
                    "type": "check"
                }],
            },
            {
                "video_type": "imgstore",
                "match": "json",
                "video_class": Video.from_filename,
                "params": [],
            },
        ]

        outer_layout = QVBoxLayout()

        scroll_widget = QScrollArea()
        # scroll_widget.setWidgetResizable(False)
        scroll_widget.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOn)
        scroll_widget.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)

        scroll_items_widget = QWidget()
        scroll_layout = QVBoxLayout()
        for file_name in filenames:
            if file_name:
                this_type = None
                for import_type in self.import_types:
                    if import_type.get("match", None) is not None:
                        if file_name.lower().endswith(
                                tuple(import_type["match"].split(","))):
                            this_type = import_type
                            break
                if this_type is not None:
                    import_item_widget = ImportItemWidget(file_name, this_type)
                    self.import_widgets.append(import_item_widget)
                    scroll_layout.addWidget(import_item_widget)
                else:
                    raise Exception("No match found for file type.")
        scroll_items_widget.setLayout(scroll_layout)
        scroll_widget.setWidget(scroll_items_widget)
        outer_layout.addWidget(scroll_widget)

        button_layout = QHBoxLayout()
        cancel_button = QPushButton("Cancel")
        import_button = QPushButton("Import")
        import_button.setDefault(True)
        button_layout.addStretch()
        button_layout.addWidget(cancel_button)
        button_layout.addWidget(import_button)

        outer_layout.addLayout(button_layout)

        self.setLayout(outer_layout)

        import_button.clicked.connect(self.accept)
        cancel_button.clicked.connect(self.reject)
Example #28
0
    def _startButtonClicked(self):
        self.logger.log("Attempting to start the processing", type="INFO")
        if not self.b_serialConnected:
            self.logger.log(
                "Serial is not connected, Please connect serial first",
                type="ERROR")
            return
        if self.inputLineEdit.text()[-4:].lower() != ".csv":
            self.logger.log("Please select a valid input csv file",
                            type="ERROR")
            return
        if self.outputFolderLineEdit.text() == "":
            self.logger.log("Please select an output directory", type="ERROR")
            return
        self.executer = Executer(serialObj=self.port, loggerObj=self.logger)

        if self.modelLineEdit.text() != "":
            modelPath = self.modelLineEdit.text()
        else:
            modelPath = None
            if self._modelRPiPath:
                self.logger.log(
                    "Please select a valid model that is already available in the folder saved_models on the RPi",
                    type="ERROR")
                return

        #Read the Input File
        try:
            inputDataFrame = pd.read_csv(self.inputLineEdit.text())
        except:
            self.logger.log("CSV File Reading Failed, select a valid csv file",
                            type="ERROR")

        possibleInputs = list(inputDataFrame.columns)

        #Display a dialog to ask the user to choose what inputs they want
        dialog = QDialog(self)

        dialog.setWindowTitle("Select the Input Fields")
        dialogButtons = QDialogButtonBox(QDialogButtonBox.Ok
                                         | QDialogButtonBox.Cancel)
        dialogButtons.button(QDialogButtonBox.Ok).setDisabled(0)
        dialogButtons.accepted.connect(dialog.accept)
        dialogButtons.rejected.connect(dialog.reject)

        mainLayout = QVBoxLayout(dialog)
        scroll = QScrollArea(dialog)
        scroll.setWidgetResizable(True)
        layoutWidget = QWidget()
        layout = QVBoxLayout(layoutWidget)
        scroll.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded)
        scroll.setWidget(layoutWidget)

        chosenInputs = []
        checkboxes = []

        def handleCheckboxClicked():
            dialogButtons.button(QDialogButtonBox.Ok).setDisabled(1)
            for checkbox in checkboxes:
                if checkbox.isChecked():
                    dialogButtons.button(QDialogButtonBox.Ok).setDisabled(0)

        for input in possibleInputs:
            checkbox = QCheckBox(text=input)
            checkbox.clicked.connect(handleCheckboxClicked)
            checkbox.setChecked(True)
            checkboxes.append(checkbox)
            layout.addWidget(checkbox)

        mainLayout.addWidget(
            QLabel(text="Please select the input fields from the following:"))
        mainLayout.addWidget(scroll)
        mainLayout.addWidget(dialogButtons)
        dialog.setLayout(mainLayout)
        # dialog.setFixedHeight(400)
        if dialog.exec_() == QDialog.Accepted:
            for checkbox in checkboxes:
                if checkbox.isChecked():
                    chosenInputs.append(checkbox.text())
            self.logger.log("The chosen input fields are: " +
                            ', '.join(chosenInputs),
                            type="INFO")
        else:
            return

        self.startStopButton.setText("Stop Processing")
        self.b_processRunning = True
        executionResult = self.executer.execute(self.labNameComboBox.currentText().split(":")[0], inputDataFrame, \
                                self.outputFolderLineEdit.text(), inputFields=chosenInputs, progressBar=self.progressBar, \
                                    model=modelPath if not self._modelRPiPath else "RPI:"+modelPath)
        if executionResult == ExecutionResult.COMPLETED:
            self._stopButtonClicked(finishedProcessing=True)
        elif executionResult == ExecutionResult.INTERRUPTED or executionResult == ExecutionResult.FAILED:
            self._stopButtonClicked()
            if self.executer.reset() == ExecutionResult.FAILED:
                self.logger.log(
                    "Resetting the serial state of RPi Failed, please power cycle the RPi",
                    type="ERROR")
            else:
                self.logger.log("The serial state of RPi has been reset",
                                type="INFO")
Example #29
0
class QImageFlowWidget(_ViewModelWidgetBase, Generic[TImageFlowView,
                                                     TImageFlowModel]):
    def __init__(self, parent):
        # type: (QObject) -> NoReturn
        super(QImageFlowWidget, self).__init__(parent, QImageFlowView,
                                               QImageFlowModel)
        self.__scrollArea = QScrollArea()
        self.__scrollArea.setWidgetResizable(True)
        self.__scrollArea.setWidget(self._view)

        mainLayout = QHBoxLayout()
        mainLayout.setContentsMargins(0, 0, 0, 0)
        mainLayout.addWidget(self.__scrollArea)
        self.setLayout(mainLayout)

        self.__flowDirection = self.setFlowDirection(
            QFlowDirection.LeftToRight)

    def setFlowDirection(self, direction):
        # type: (str) -> str
        if direction == QFlowDirection.LeftToRight:
            self.view().setFlow(QListView.LeftToRight)
            self.__scrollArea.setHorizontalScrollBarPolicy(
                Qt.ScrollBarAlwaysOff)
            self.__scrollArea.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded)
            return direction

        if direction == QFlowDirection.TopToBottom:
            self.view().setFlow(QListView.TopToBottom)
            self.__scrollArea.setHorizontalScrollBarPolicy(
                Qt.ScrollBarAsNeeded)
            self.__scrollArea.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
            return direction

    def flowDirection(self):
        # type: () -> str
        return self.__flowDirection

    def setProxyModel(self, proxy):
        # type: (QAbstractProxyModel) -> NoReturn
        model = self.model()
        if isinstance(model, QAbstractProxyModel):
            proxy.setSourceModel(model.sourceModel())
            model.deleteLater()
        else:
            proxy.setSourceModel(model)
        self.view().setModel(proxy)

    def appendItem(self, item):
        # type: (TImageFlowItem) -> TImageFlowItem
        model = self.model()
        if isinstance(model, QAbstractProxyModel):
            model = model.sourceModel()
        model.append(item)
        return item

    def appendImage(self, image):
        # type: (QImage) -> TImageFlowItem
        item = QImageFlowItem()
        item.setImage(image)
        return self.appendItem(item)

    def appendFile(self, filePath):
        # type: (str) -> TImageFlowItem
        image = QImage(filePath)
        return self.appendImage(image)
Example #30
0
class SlideShow(QObject):
    current_index_changed = Signal(int)
    clicked = Signal()
    key_pressed = Signal(QEvent)

    def __init__(self, parent, base_widget, is_animated=True):
        QObject.__init__(self, parent)
        self._base_widget = base_widget  # has to be stacked widget
        self._is_animated = is_animated
        self._slides_count = self._base_widget.count()

        self._scroll_area = QScrollArea(parent)
        self._scroll_area.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        self._scroll_area.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        self._scroll_area.setFrameShape(QFrame.NoFrame)
        self._scroll_area.mouseReleaseEvent = self._on_mouse_release_event
        self._scroll_area.keyPressEvent = self._on_key_pressed

        self._slide_width = None
        self._current_index = 0
        self._is_moving = False
        self._orig_resize_event = self._base_widget.resizeEvent
        self._base_widget.resizeEvent = self._resizeEvent

        self._animation_time = 300
        self._animation_steps = 50

    def _construct_ribbon(self):
        self._ribbon = QWidget()

        self._layout = QHBoxLayout()
        self._ribbon.setLayout(self._layout)

        x = 0
        for i in range(self._slides_count):
            self._base_widget.setCurrentIndex(i)
            widget = self._base_widget.currentWidget()
            if widget:
                new_widget = self._grab(widget)
                self._layout.addWidget(new_widget)
                x += self._slide_width

    def _grab(self, widget):
        new_widget = QLabel()
        pixmap = widget.grab()
        new_widget.setPixmap(pixmap)
        return new_widget

    def _resizeEvent(self, *args, **kwargs):
        self._orig_resize_event(*args, **kwargs)
        if not self._slide_width:
            self._scroll_area.setGeometry(self._base_widget.geometry())
            self._slide_width = self._base_widget.widget(0).width()
            QTimer.singleShot(50, self._show)

    def _show(self):
        self._construct_ribbon()
        self._scroll_area.setWidget(self._ribbon)
        self._scroll_area.setAlignment(Qt.AlignCenter)
        self._scroll_area.show()
        self._scroll_area.setFocus()

    def _on_mouse_release_event(self, ev):
        self.clicked.emit()

    def _on_key_pressed(self, ev):
        self.key_pressed.emit(ev)

    def setAnimated(self,
                    is_animated,
                    animation_time=None,
                    animation_steps=None):
        self._is_animated = is_animated
        if animation_time:
            self._animation_time = animation_time
        if animation_steps:
            self._animation_steps = animation_steps

    def is_moving(self):
        return self._is_moving

    def setCurrentIndex(self, new_index):
        new_index = max(new_index, 0)
        new_index = min(new_index, self._slides_count - 1)

        if new_index == self._current_index or self._is_moving:
            return

        is_animated = self._is_animated and \
                      abs(self._current_index - new_index) == 1
        self._move(new_index, is_animated)

    def _move(self, new_index, is_animated):
        self._is_moving = True
        source_x = self._current_index * self._slide_width
        target_x = new_index * self._slide_width

        if not is_animated:
            dx = target_x - source_x
            self._ribbon.scroll(-dx, 0)
            self._finish_moving(new_index)
        else:
            animation_interval = self._animation_time // self._animation_steps
            dx = (target_x - source_x) // self._animation_steps
            self._move_animated(source_x, target_x, dx, animation_interval,
                                new_index)

    def _move_animated(self, source_x, target_x, dx, animation_interval,
                       new_index):
        if target_x == source_x:
            self._finish_moving(new_index)
            return

        if target_x > source_x:
            dx = min(dx, target_x - source_x)
        else:
            dx = -min(-dx, source_x - target_x)
        self._ribbon.scroll(-dx, 0)
        source_x += dx
        QTimer.singleShot(
            animation_interval, lambda: self._move_animated(
                source_x, target_x, dx, animation_interval, new_index))

    def _finish_moving(self, new_index):
        self._current_index = new_index
        self.current_index_changed.emit(self._current_index)
        self._is_moving = False

    def widget(self):
        return self._scroll_area