From 80f2b7a1dbcea44b2fc5e10d3a9dfaa3f4f5183c Mon Sep 17 00:00:00 2001 From: Dan Albert Date: Sun, 13 Sep 2020 22:51:41 -0700 Subject: [PATCH] Cleanups in map object UI. * Fix the context menu * Remove unnecessary overrides * Clean up formatting/naming * Factor out base class for shared behavior --- qt_ui/widgets/map/QMapControlPoint.py | 101 ++++++++++---------------- qt_ui/widgets/map/QMapGroundObject.py | 84 ++++++++++----------- qt_ui/widgets/map/QMapObject.py | 28 +++++++ 3 files changed, 107 insertions(+), 106 deletions(-) create mode 100644 qt_ui/widgets/map/QMapObject.py diff --git a/qt_ui/widgets/map/QMapControlPoint.py b/qt_ui/widgets/map/QMapControlPoint.py index 09061e16..a006cb5a 100644 --- a/qt_ui/widgets/map/QMapControlPoint.py +++ b/qt_ui/widgets/map/QMapControlPoint.py @@ -1,29 +1,32 @@ -from PySide2.QtCore import QRect, Qt -from PySide2.QtGui import QColor, QPainter -from PySide2.QtWidgets import QGraphicsRectItem, QGraphicsSceneHoverEvent, QGraphicsSceneContextMenuEvent, QMenu, \ - QAction, QGraphicsSceneMouseEvent +from typing import Optional -import qt_ui.uiconstants as CONST +from PySide2.QtGui import QColor, QPainter +from PySide2.QtWidgets import ( + QAction, + QGraphicsSceneContextMenuEvent, + QMenu, +) + +import qt_ui.uiconstants as const from game import Game from qt_ui.windows.basemenu.QBaseMenu2 import QBaseMenu2 -from theater import ControlPoint, db +from theater import ControlPoint +from .QMapObject import QMapObject -class QMapControlPoint(QGraphicsRectItem): +class QMapControlPoint(QMapObject): - def __init__(self, parent, x: float, y: float, w: float, h: float, model: ControlPoint, game: Game): - super(QMapControlPoint, self).__init__(x, y, w, h) + def __init__(self, parent, x: float, y: float, w: float, h: float, + model: ControlPoint, game: Game) -> None: + super().__init__(x, y, w, h) self.model = model self.game = game self.parent = parent - self.setAcceptHoverEvents(True) self.setZValue(1) self.setToolTip(self.model.name) + self.base_details_dialog: Optional[QBaseMenu2] = None - - def paint(self, painter, option, widget=None): - #super(QMapControlPoint, self).paint(painter, option, widget) - + def paint(self, painter, option, widget=None) -> None: if self.parent.get_display_rule("cp"): painter.save() painter.setRenderHint(QPainter.Antialiasing) @@ -32,69 +35,43 @@ class QMapControlPoint(QGraphicsRectItem): if self.model.has_runway(): if self.isUnderMouse(): - painter.setBrush(CONST.COLORS["white"]) + painter.setBrush(const.COLORS["white"]) painter.setPen(self.pen_color) r = option.rect painter.drawEllipse(r.x(), r.y(), r.width(), r.height()) - - #gauge = QRect(r.x(), - # r.y()+CONST.CP_SIZE/2 + 2, - # r.width(), - # CONST.CP_SIZE / 4) - - #painter.setBrush(CONST.COLORS["bright_red"]) - #painter.setPen(CONST.COLORS["black"]) - #painter.drawRect(gauge) - - #gauge2 = QRect(r.x(), - # r.y() + CONST.CP_SIZE / 2 + 2, - # r.width()*self.model.base.strength, - # CONST.CP_SIZE / 4) - - #painter.setBrush(CONST.COLORS["green"]) - #painter.drawRect(gauge2) - else: - # TODO : not drawing sunk carriers. Can be improved to display sunk carrier. - pass + # TODO: Draw sunk carriers differently. + # Either don't draw them at all, or perhaps use a sunk ship icon. painter.restore() - def hoverEnterEvent(self, event: QGraphicsSceneHoverEvent): - self.update() - self.setCursor(Qt.PointingHandCursor) - - def mouseMoveEvent(self, event:QGraphicsSceneMouseEvent): - self.update() - - def hoverLeaveEvent(self, event: QGraphicsSceneHoverEvent): - self.update() - - def mousePressEvent(self, event:QGraphicsSceneMouseEvent): - self.openBaseMenu() - #self.contextMenuEvent(event) - - def contextMenuEvent(self, event: QGraphicsSceneContextMenuEvent): - + def contextMenuEvent(self, event: QGraphicsSceneContextMenuEvent) -> None: if self.model.captured: - openBaseMenu = QAction("Open base menu") + text = "Open base menu" else: - openBaseMenu = QAction("Open intel menu") + text = "Open intel menu" - openBaseMenu.triggered.connect(self.openBaseMenu) + open_menu = QAction(text) + open_menu.triggered.connect(self.on_click) menu = QMenu("Menu", self.parent) - menu.addAction(openBaseMenu) + menu.addAction(open_menu) menu.exec_(event.screenPos()) - @property - def brush_color(self)->QColor: - return self.model.captured and CONST.COLORS["blue"] or CONST.COLORS["super_red"] + def brush_color(self) -> QColor: + if self.model.captured: + return const.COLORS["blue"] + else: + return const.COLORS["super_red"] @property def pen_color(self) -> QColor: - return self.model.captured and CONST.COLORS["white"] or CONST.COLORS["white"] + return const.COLORS["white"] - def openBaseMenu(self): - self.baseMenu = QBaseMenu2(self.window(), self.model, self.game) - self.baseMenu.show() \ No newline at end of file + def on_click(self) -> None: + self.base_details_dialog = QBaseMenu2( + self.window(), + self.model, + self.game + ) + self.base_details_dialog.show() diff --git a/qt_ui/widgets/map/QMapGroundObject.py b/qt_ui/widgets/map/QMapGroundObject.py index a79ce1ab..89d1bf07 100644 --- a/qt_ui/widgets/map/QMapGroundObject.py +++ b/qt_ui/widgets/map/QMapGroundObject.py @@ -1,33 +1,37 @@ -from PySide2.QtCore import QPoint, QRect, QPointF, Qt -from PySide2.QtGui import QPainter, QBrush -from PySide2.QtWidgets import QGraphicsRectItem, QGraphicsItem, QGraphicsSceneHoverEvent, QGraphicsSceneMouseEvent +from typing import List, Optional -import qt_ui.uiconstants as CONST -from game import db, Game +from PySide2.QtCore import QRect +from PySide2.QtGui import QBrush +from PySide2.QtWidgets import QGraphicsItem + +import qt_ui.uiconstants as const +from game import Game from game.data.building_data import FORTIFICATION_BUILDINGS from qt_ui.windows.groundobject.QGroundObjectMenu import QGroundObjectMenu from theater import TheaterGroundObject, ControlPoint +from .QMapObject import QMapObject -class QMapGroundObject(QGraphicsRectItem): - - def __init__(self, parent, x: float, y: float, w: float, h: float, cp: ControlPoint, model: TheaterGroundObject, game:Game, buildings=[]): - super(QMapGroundObject, self).__init__(x, y, w, h) +class QMapGroundObject(QMapObject): + def __init__(self, parent, x: float, y: float, w: float, h: float, + cp: ControlPoint, model: TheaterGroundObject, game: Game, + buildings: Optional[List[TheaterGroundObject]] = None) -> None: + super().__init__(x, y, w, h) self.model = model self.cp = cp self.parent = parent self.game = game - self.setAcceptHoverEvents(True) self.setZValue(2) - self.buildings = buildings + self.buildings = buildings if buildings is not None else [] self.setFlag(QGraphicsItem.ItemIgnoresTransformations, False) + self.ground_object_dialog: Optional[QGroundObjectMenu] = None if len(self.model.groups) > 0: units = {} for g in self.model.groups: print(g) for u in g.units: - if u.type in units.keys(): + if u.type in units: units[u.type] = units[u.type]+1 else: units[u.type] = 1 @@ -42,14 +46,9 @@ class QMapGroundObject(QGraphicsRectItem): tooltip = tooltip + str(building.dcs_identifier) + "\n" self.setToolTip(tooltip[:-1]) - def mousePressEvent(self, event:QGraphicsSceneMouseEvent): - self.openEditionMenu() - - def paint(self, painter, option, widget=None): - #super(QMapControlPoint, self).paint(painter, option, widget) - - playerIcons = "_blue" - enemyIcons = "" + def paint(self, painter, option, widget=None) -> None: + player_icons = "_blue" + enemy_icons = "" if self.parent.get_display_rule("go"): painter.save() @@ -58,7 +57,8 @@ class QMapGroundObject(QGraphicsRectItem): if cat == "aa" and self.model.sea_object: cat = "ship" - rect = QRect(option.rect.x()+2,option.rect.y(),option.rect.width()-2,option.rect.height()) + rect = QRect(option.rect.x() + 2, option.rect.y(), + option.rect.width() - 2, option.rect.height()) is_dead = self.model.is_dead for building in self.buildings: @@ -67,16 +67,16 @@ class QMapGroundObject(QGraphicsRectItem): break if not is_dead and not self.cp.captured: - painter.drawPixmap(rect, CONST.ICONS[cat + enemyIcons]) + painter.drawPixmap(rect, const.ICONS[cat + enemy_icons]) elif not is_dead: - painter.drawPixmap(rect, CONST.ICONS[cat + playerIcons]) + painter.drawPixmap(rect, const.ICONS[cat + player_icons]) else: - painter.drawPixmap(rect, CONST.ICONS["destroyed"]) + painter.drawPixmap(rect, const.ICONS["destroyed"]) - self.drawHealthGauge(painter, option) + self.draw_health_gauge(painter, option) painter.restore() - def drawHealthGauge(self, painter, option): + def draw_health_gauge(self, painter, option) -> None: units_alive = 0 units_dead = 0 @@ -97,22 +97,18 @@ class QMapGroundObject(QGraphicsRectItem): if units_dead + units_alive > 0: ratio = float(units_alive)/(float(units_dead) + float(units_alive)) bar_height = ratio * option.rect.height() - painter.fillRect(option.rect.x(), option.rect.y(), 2, option.rect.height(), QBrush(CONST.COLORS["dark_red"])) - painter.fillRect(option.rect.x(), option.rect.y(), 2, bar_height, QBrush(CONST.COLORS["green"])) - - - def hoverEnterEvent(self, event: QGraphicsSceneHoverEvent): - self.update() - self.setCursor(Qt.PointingHandCursor) - - def mouseMoveEvent(self, event:QGraphicsSceneMouseEvent): - self.update() - self.setCursor(Qt.PointingHandCursor) - - def hoverLeaveEvent(self, event: QGraphicsSceneHoverEvent): - self.update() - - def openEditionMenu(self): - self.editionMenu = QGroundObjectMenu(self.window(), self.model, self.buildings, self.cp, self.game) - self.editionMenu.show() + painter.fillRect(option.rect.x(), option.rect.y(), 2, + option.rect.height(), + QBrush(const.COLORS["dark_red"])) + painter.fillRect(option.rect.x(), option.rect.y(), 2, bar_height, + QBrush(const.COLORS["green"])) + def on_click(self) -> None: + self.ground_object_dialog = QGroundObjectMenu( + self.window(), + self.model, + self.buildings, + self.cp, + self.game + ) + self.ground_object_dialog.show() diff --git a/qt_ui/widgets/map/QMapObject.py b/qt_ui/widgets/map/QMapObject.py new file mode 100644 index 00000000..1e29c7dd --- /dev/null +++ b/qt_ui/widgets/map/QMapObject.py @@ -0,0 +1,28 @@ +"""Common base for objects drawn on the game map.""" +from PySide2.QtCore import Qt +from PySide2.QtWidgets import ( + QGraphicsRectItem, + QGraphicsSceneHoverEvent, + QGraphicsSceneMouseEvent, +) + + +class QMapObject(QGraphicsRectItem): + """Base class for objects drawn on the game map. + + Game map objects have an on_click behavior that triggers on left click, and + change the mouse cursor on hover. + """ + def __init__(self, x: float, y: float, w: float, h: float): + super().__init__(x, y, w, h) + self.setAcceptHoverEvents(True) + + def hoverEnterEvent(self, event: QGraphicsSceneHoverEvent): + self.setCursor(Qt.PointingHandCursor) + + def mousePressEvent(self, event: QGraphicsSceneMouseEvent): + if event.button() == Qt.LeftButton: + self.on_click() + + def on_click(self) -> None: + raise NotImplementedError