Merge pull request #11 from DeusEx010101/UI-fixes-new-themes

UI Update!
This commit is contained in:
C. Perreau 2020-07-01 15:39:31 +02:00 committed by GitHub
commit 4d4a640f34
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
95 changed files with 710 additions and 97 deletions

View File

@ -175,6 +175,7 @@ class Game:
else:
return event.name == self.player_name
# 1 = red, 2 = blue
def get_player_coalition_id(self):
if self.player_country in db.BLUEFOR_FACTIONS:
return 2
@ -187,6 +188,20 @@ class Game:
else:
return 1
def get_player_color(self):
if self.get_player_coalition_id() == 1:
return "red"
else:
return "blue"
def get_enemy_color(self):
if self.get_player_coalition_id() == 1:
return "blue"
else:
return "red"
def pass_turn(self, no_action=False, ignored_cps: typing.Collection[ControlPoint] = None):
logging.info("Pass turn")

1
liberation_theme.json Normal file
View File

@ -0,0 +1 @@
{"theme_index": 1}

View File

@ -1,7 +1,7 @@
from userdata import logging_config
# Logging setup
VERSION_STRING = "2.0RC7"
VERSION_STRING = "2.0RC9"
logging_config.init_logging(VERSION_STRING)
import logging
@ -17,19 +17,18 @@ from qt_ui import uiconstants
from qt_ui.windows.GameUpdateSignal import GameUpdateSignal
from qt_ui.windows.QLiberationWindow import QLiberationWindow
from qt_ui.windows.preferences.QLiberationFirstStartWindow import QLiberationFirstStartWindow
from userdata import liberation_install, persistency
from userdata import liberation_install, persistency, liberation_theme
if __name__ == "__main__":
app = QApplication(sys.argv)
# init the theme and load the stylesheet based on the theme index
liberation_theme.init();
css = ""
with open("./resources/stylesheets/style.css") as stylesheet:
with open("./resources/stylesheets/"+liberation_theme.get_theme_css_file()) as stylesheet:
app.setStyleSheet(stylesheet.read())
# Inject custom payload in pydcs framework
custom_payloads = os.path.join(os.path.dirname(os.path.realpath(__file__)), "..\\resources\\customized_payloads")
if os.path.exists(custom_payloads):

View File

@ -6,6 +6,7 @@ from PySide2.QtGui import QColor, QFont, QPixmap
from game.event import UnitsDeliveryEvent, FrontlineAttackEvent
from theater.theatergroundobject import CATEGORY_MAP
from userdata.liberation_theme import get_theme_icons
URLS : Dict[str, str] = {
"Manual": "https://github.com/khopa/dcs_liberation/wiki",
@ -19,26 +20,58 @@ URLS : Dict[str, str] = {
LABELS_OPTIONS = ["Full", "Abbreviated", "Dot Only", "Off"]
SKILL_OPTIONS = ["Average", "Good", "High", "Excellent"]
COLORS: Dict[str, QColor] = {
"dark_red": QColor(140, 20, 20),
"red": QColor(200, 80, 80),
"bright_red": QColor(150, 80, 80),
"super_red": QColor(200, 120, 120),
"blue": QColor(164, 164, 255),
"dark_blue": QColor(45, 62, 80),
"white": QColor(255, 255, 255),
"green": QColor(128, 186, 128),
"bright_green": QColor(64, 200, 64),
"black": QColor(0, 0, 0),
"black_transparent": QColor(0, 0, 0, 64),
"blue_transparent": QColor(164, 164, 255, 32),
"red_transparent": QColor(255, 125, 125, 32)
FONT_SIZE = 8
FONT_NAME = "Arial"
# FONT = QFont("Arial", 12, weight=5, italic=True)
FONT_PRIMARY = QFont(FONT_NAME, FONT_SIZE, weight=5, italic=False)
FONT_PRIMARY_I = QFont(FONT_NAME, FONT_SIZE, weight=5, italic=True)
FONT_PRIMARY_B = QFont(FONT_NAME, FONT_SIZE, weight=75, italic=False)
FONT_MAP = QFont(FONT_NAME, 10, weight=75, italic=False)
# new themes can be added here
THEMES: Dict[int, Dict[str, str]] = {
0: {'themeName': 'Vanilla',
'themeFile': 'windows-style.css',
'themeIcons': 'medium',
},
1: {'themeName': 'DCS World',
'themeFile': 'style-dcs.css',
'themeIcons': 'light',
},
}
COLORS: Dict[str, QColor] = {
"white": QColor(255, 255, 255),
"white_transparent": QColor(255, 255, 255, 35),
"grey_transparent": QColor(150, 150, 150, 30),
CP_SIZE = 25
FONT = QFont("Arial", 12, weight=5, italic=True)
"red": QColor(200, 80, 80),
"dark_red": QColor(140, 20, 20),
"red_transparent": QColor(227, 32, 0, 20),
"blue": QColor(0, 132, 255),
"dark_blue": QColor(45, 62, 80),
"blue_transparent": QColor(0, 132, 255, 20),
"bright_red": QColor(150, 80, 80),
"super_red": QColor(227, 32, 0),
"green": QColor(128, 186, 128),
"bright_green": QColor(64, 200, 64),
"black": QColor(0, 0, 0),
"black_transparent": QColor(0, 0, 0, 5),
"orange": QColor(254, 125, 10),
"night_overlay": QColor(12, 20, 69),
"dawn_dust_overlay": QColor(46, 38, 85),
}
CP_SIZE = 24
AIRCRAFT_ICONS: Dict[str, QPixmap] = {}
VEHICLES_ICONS: Dict[str, QPixmap] = {}
@ -46,9 +79,9 @@ ICONS: Dict[str, QPixmap] = {}
def load_icons():
ICONS["New"] = QPixmap("./resources/ui/misc/new.png")
ICONS["Open"] = QPixmap("./resources/ui/misc/open.png")
ICONS["Save"] = QPixmap("./resources/ui/misc/save.png")
ICONS["New"] = QPixmap("./resources/ui/misc/"+get_theme_icons()+"/new.png")
ICONS["Open"] = QPixmap("./resources/ui/misc/"+get_theme_icons()+"/open.png")
ICONS["Save"] = QPixmap("./resources/ui/misc/"+get_theme_icons()+"/save.png")
ICONS["Terrain_Caucasus"] = QPixmap("./resources/ui/terrain_caucasus.gif")
ICONS["Terrain_Persian_Gulf"] = QPixmap("./resources/ui/terrain_pg.gif")
@ -61,12 +94,12 @@ def load_icons():
ICONS["Dusk"] = QPixmap("./resources/ui/daytime/dusk.png")
ICONS["Night"] = QPixmap("./resources/ui/daytime/night.png")
ICONS["Money"] = QPixmap("./resources/ui/misc/money_icon.png")
ICONS["PassTurn"] = QPixmap("./resources/ui/misc/hourglass.png")
ICONS["Proceed"] = QPixmap("./resources/ui/misc/proceed.png")
ICONS["Settings"] = QPixmap("./resources/ui/misc/settings.png")
ICONS["Statistics"] = QPixmap("./resources/ui/misc/statistics.png")
ICONS["Ordnance"] = QPixmap("./resources/ui/misc/ordnance_icon.png")
ICONS["Money"] = QPixmap("./resources/ui/misc/"+get_theme_icons()+"/money_icon.png")
ICONS["PassTurn"] = QPixmap("./resources/ui/misc/"+get_theme_icons()+"/hourglass.png")
ICONS["Proceed"] = QPixmap("./resources/ui/misc/"+get_theme_icons()+"/proceed.png")
ICONS["Settings"] = QPixmap("./resources/ui/misc/"+get_theme_icons()+"/settings.png")
ICONS["Statistics"] = QPixmap("./resources/ui/misc/"+get_theme_icons()+"/statistics.png")
ICONS["Ordnance"] = QPixmap("./resources/ui/misc/"+get_theme_icons()+"/ordnance_icon.png")
ICONS["target"] = QPixmap("./resources/ui/ground_assets/target.png")
ICONS["cleared"] = QPixmap("./resources/ui/ground_assets/cleared.png")
@ -77,9 +110,9 @@ def load_icons():
ICONS["ship"] = QPixmap("./resources/ui/ground_assets/ship.png")
ICONS["ship_blue"] = QPixmap("./resources/ui/ground_assets/ship_blue.png")
ICONS["Generator"] = QPixmap("./resources/ui/misc/generator.png")
ICONS["Missile"] = QPixmap("./resources/ui/misc/missile.png")
ICONS["Cheat"] = QPixmap("./resources/ui/misc/cheat.png")
ICONS["Generator"] = QPixmap("./resources/ui/misc/"+get_theme_icons()+"/generator.png")
ICONS["Missile"] = QPixmap("./resources/ui/misc/"+get_theme_icons()+"/missile.png")
ICONS["Cheat"] = QPixmap("./resources/ui/misc/"+get_theme_icons()+"/cheat.png")
ICONS["TaskCAS"] = QPixmap("./resources/ui/tasks/cas.png")
ICONS["TaskCAP"] = QPixmap("./resources/ui/tasks/cap.png")

View File

@ -34,7 +34,7 @@ class QTopPanel(QFrame):
self.proceedButton = QPushButton("Mission Planning")
self.proceedButton.setIcon(CONST.ICONS["Proceed"])
self.proceedButton.setProperty("style", "btn-primary")
self.proceedButton.setProperty("style", "btn-success")
self.proceedButton.clicked.connect(self.proceed)
if self.game and self.game.turn == 0:
self.proceedButton.setEnabled(False)

View File

@ -113,6 +113,9 @@ class QLiberationMap(QGraphicsView):
scene = self.scene()
scene.clear()
playerColor = self.game.get_player_color()
enemyColor = self.game.get_enemy_color()
self.addBackground()
# Uncomment below to help set up theater reference points
@ -128,11 +131,11 @@ class QLiberationMap(QGraphicsView):
CONST.CP_SIZE, cp, self.game))
if cp.captured:
pen = QPen(brush=CONST.COLORS["blue"])
brush = CONST.COLORS["blue_transparent"]
pen = QPen(brush=CONST.COLORS[playerColor])
brush = CONST.COLORS[playerColor+"_transparent"]
else:
pen = QPen(brush=CONST.COLORS["red"])
brush = CONST.COLORS["red_transparent"]
pen = QPen(brush=CONST.COLORS[enemyColor])
brush = CONST.COLORS[enemyColor+"_transparent"]
added_objects = []
for ground_object in cp.ground_objects:
@ -157,34 +160,35 @@ class QLiberationMap(QGraphicsView):
if unit.threat_range > max_range:
max_range = unit.threat_range
if has_radar:
scene.addEllipse(go_pos[0] - max_range/300.0 + 8, go_pos[1] - max_range/300.0 + 8, max_range/150.0, max_range/150.0, pen, brush)
scene.addEllipse(go_pos[0] - max_range/300.0 + 8, go_pos[1] - max_range/300.0 + 8, max_range/150.0, max_range/150.0, CONST.COLORS["white_transparent"], CONST.COLORS["grey_transparent"])
added_objects.append(ground_object.obj_name)
for cp in self.game.theater.enemy_points():
if self.get_display_rule("lines"):
self.scene_create_lines_for_cp(cp)
self.scene_create_lines_for_cp(cp, playerColor, enemyColor)
for cp in self.game.theater.player_points():
if self.get_display_rule("lines"):
self.scene_create_lines_for_cp(cp)
self.scene_create_lines_for_cp(cp, playerColor, enemyColor)
for cp in self.game.theater.controlpoints:
if cp.captured:
pen = QPen(brush=CONST.COLORS["blue"])
brush = CONST.COLORS["blue_transparent"]
pen = QPen(brush=CONST.COLORS[playerColor])
brush = CONST.COLORS[playerColor+"_transparent"]
flight_path_pen = QPen(brush=CONST.COLORS[playerColor])
flight_path_pen.setColor(CONST.COLORS[playerColor])
flight_path_pen = QPen(brush=CONST.COLORS["blue"])
flight_path_pen.setColor(CONST.COLORS["blue"])
flight_path_pen.setWidth(1)
flight_path_pen.setStyle(Qt.DashDotLine)
else:
pen = QPen(brush=CONST.COLORS["red"])
brush = CONST.COLORS["red_transparent"]
pen = QPen(brush=CONST.COLORS[enemyColor])
brush = CONST.COLORS[enemyColor+"_transparent"]
flight_path_pen = QPen(brush=CONST.COLORS["bright_red"])
flight_path_pen.setColor(CONST.COLORS["bright_red"])
flight_path_pen.setWidth(1)
flight_path_pen.setStyle(Qt.DashDotLine)
flight_path_pen = QPen(brush=CONST.COLORS[enemyColor])
flight_path_pen.setColor(CONST.COLORS[enemyColor])
flight_path_pen.setWidth(1)
flight_path_pen.setStyle(Qt.DashDotLine)
pos = self._transform_point(cp.position)
if self.get_display_rule("flight_paths"):
@ -202,27 +206,27 @@ class QLiberationMap(QGraphicsView):
for cp in self.game.theater.controlpoints:
pos = self._transform_point(cp.position)
text = scene.addText(cp.name, font=QFont("Trebuchet MS", 10, weight=5, italic=False))
text = scene.addText(cp.name, font=CONST.FONT_MAP)
text.setPos(pos[0] + CONST.CP_SIZE, pos[1] - CONST.CP_SIZE / 2)
text = scene.addText(cp.name, font=QFont("Trebuchet MS", 10, weight=5, italic=False))
text = scene.addText(cp.name, font=CONST.FONT_MAP)
text.setDefaultTextColor(Qt.white)
text.setPos(pos[0] + CONST.CP_SIZE + 1, pos[1] - CONST.CP_SIZE / 2 + 1)
def scene_create_lines_for_cp(self, cp: ControlPoint):
def scene_create_lines_for_cp(self, cp: ControlPoint, playerColor, enemyColor):
scene = self.scene()
pos = self._transform_point(cp.position)
for connected_cp in cp.connected_points:
pos2 = self._transform_point(connected_cp.position)
if not cp.captured:
color = CONST.COLORS["red"]
color = CONST.COLORS["dark_"+enemyColor]
elif cp.captured:
color = CONST.COLORS["blue"]
color = CONST.COLORS["dark_"+playerColor]
else:
color = CONST.COLORS["red"]
color = CONST.COLORS["dark_"+enemyColor]
pen = QPen(brush=color)
pen.setColor(color)
pen.setWidth(16)
pen.setWidth(6)
if cp.captured and not connected_cp.captured and Conflict.has_frontline_between(cp, connected_cp):
if not cp.captured:
scene.addLine(pos[0], pos[1], pos2[0], pos2[1], pen=pen)
@ -234,8 +238,8 @@ class QLiberationMap(QGraphicsView):
p1 = point_from_heading(pos2[0], pos2[1], h+180, 25)
p2 = point_from_heading(pos2[0], pos2[1], h, 25)
frontline_pen = QPen(brush=CONST.COLORS["bright_red"])
frontline_pen.setColor(CONST.COLORS["bright_red"])
frontline_pen.setWidth(18)
frontline_pen.setColor(CONST.COLORS["orange"])
frontline_pen.setWidth(8)
scene.addLine(p1[0], p1[1], p2[0], p2[1], pen=frontline_pen)
else:
@ -318,14 +322,14 @@ class QLiberationMap(QGraphicsView):
pass
elif self.game.current_turn_daytime == "night":
ov = QPixmap(bg.width(), bg.height())
ov.fill(QColor(40, 40, 150))
ov.fill(CONST.COLORS["night_overlay"])
overlay = scene.addPixmap(ov)
effect = QGraphicsOpacityEffect()
effect.setOpacity(0.7)
overlay.setGraphicsEffect(effect)
else:
ov = QPixmap(bg.width(), bg.height())
ov.fill(QColor(165, 100, 100))
ov.fill(CONST.COLORS["dawn_dust_overlay"])
overlay = scene.addPixmap(ov)
effect = QGraphicsOpacityEffect()
effect.setOpacity(0.3)

View File

@ -1,7 +1,7 @@
from PySide2.QtGui import QFont
from PySide2.QtWidgets import QGraphicsScene
from qt_ui.uiconstants import COLORS
import qt_ui.uiconstants as CONST
class QLiberationScene(QGraphicsScene):
@ -9,5 +9,5 @@ class QLiberationScene(QGraphicsScene):
def __init__(self, parent):
super().__init__(parent)
item = self.addText("No save file found. Go to \"File/New Game\" to setup a new campaign.",
QFont("Arial", 14, weight=5))
item.setDefaultTextColor(COLORS["white"])
CONST.FONT_PRIMARY)
item.setDefaultTextColor(CONST.COLORS["white"])

View File

@ -96,10 +96,7 @@ class QMapControlPoint(QGraphicsRectItem):
@property
def pen_color(self) -> QColor:
if self.parent.game.player_country in db.BLUEFOR_FACTIONS:
return self.model.captured and CONST.COLORS["dark_blue"] or CONST.COLORS["bright_red"]
else:
return self.model.captured and CONST.COLORS["bright_red"] or CONST.COLORS["dark_blue"]
return self.model.captured and CONST.COLORS["white"] or CONST.COLORS["white"]
def openBaseMenu(self):
self.baseMenu = QBaseMenu2(self.window(), self.model, self.game)

View File

@ -17,17 +17,22 @@ class QMapEvent(QGraphicsRectItem):
self.setToolTip(str(self.gameEvent))
self.playable = not isinstance(self.gameEvent, UnitsDeliveryEvent)
def paint(self, painter, option, widget=None):
playerColor = self.game.get_player_color()
enemyColor = self.game.get_enemy_color()
if self.parent.get_display_rule("events"):
painter.save()
if self.gameEvent.is_player_attacking:
painter.setPen(QPen(brush=CONST.COLORS["blue"]))
painter.setBrush(CONST.COLORS["blue"])
painter.setPen(QPen(brush=CONST.COLORS[playerColor]))
painter.setBrush(CONST.COLORS[playerColor])
else:
painter.setPen(QPen(brush=CONST.COLORS["red"]))
painter.setBrush(CONST.COLORS["red"])
painter.setPen(QPen(brush=CONST.COLORS[enemyColor]))
painter.setBrush(CONST.COLORS[enemyColor])
if self.isUnderMouse() and self.playable:
painter.setBrush(CONST.COLORS["white"])

View File

@ -42,6 +42,13 @@ class QMapGroundObject(QGraphicsRectItem):
def paint(self, painter, option, widget=None):
#super(QMapControlPoint, self).paint(painter, option, widget)
if self.parent.game.player_country in db.BLUEFOR_FACTIONS:
playerIcons = "_blue"
enemyIcons = ""
else:
playerIcons = ""
enemyIcons = "_blue"
if self.parent.get_display_rule("go"):
painter.save()
@ -50,9 +57,9 @@ class QMapGroundObject(QGraphicsRectItem):
cat = "ship"
if not self.model.is_dead and not self.cp.captured:
painter.drawPixmap(option.rect, CONST.ICONS[cat])
painter.drawPixmap(option.rect, CONST.ICONS[cat + enemyIcons])
elif not self.model.is_dead:
painter.drawPixmap(option.rect, CONST.ICONS[cat + "_blue"])
painter.drawPixmap(option.rect, CONST.ICONS[cat + playerIcons])
else:
painter.drawPixmap(option.rect, CONST.ICONS["destroyed"])
painter.restore()

View File

@ -108,7 +108,7 @@ class NewGameWizard(QtWidgets.QWizard):
game.budget = int(game.budget * multiplier)
game.settings.multiplier = multiplier
game.settings.sams = True
game.settings.version = "2.0RC7"
game.settings.version = "2.0RC9"
if midgame:
game.budget = game.budget * 4 * len(list(conflicttheater.conflicts()))
@ -140,7 +140,7 @@ class FactionSelection(QtWidgets.QWizardPage):
self.setTitle("Faction selection")
self.setSubTitle("\nChoose the two opposing factions and select the player side.")
self.setPixmap(QtWidgets.QWizard.LogoPixmap,
QtGui.QPixmap('./resources/ui/wizard/logo1.png'))
QtGui.QPixmap('./resources/ui/misc/generator.png'))
self.setMinimumHeight(250)
@ -167,10 +167,10 @@ class FactionSelection(QtWidgets.QWizardPage):
# Unit Preview
self.blueSideRecap = QtWidgets.QLabel("")
self.blueSideRecap.setFont(QtGui.QFont("Arial", italic=True))
self.blueSideRecap.setFont(CONST.FONT_PRIMARY_I)
self.blueSideRecap.setWordWrap(True)
self.redSideRecap = QtWidgets.QLabel("")
self.redSideRecap.setFont(QtGui.QFont("Arial", italic=True))
self.redSideRecap.setFont(CONST.FONT_PRIMARY_I)
self.redSideRecap.setWordWrap(True)
# Link form fields

View File

@ -28,13 +28,13 @@ class QRecruitBehaviour:
existing_units = QLabel(str(existing_units))
existing_units.setSizePolicy(QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed))
amount_bought = QLabel("[{}]".format(str(scheduled_units)))
amount_bought = QLabel("{}".format(str(scheduled_units)))
amount_bought.setSizePolicy(QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed))
self.existing_units_labels[unit_type] = existing_units
self.bought_amount_labels[unit_type] = amount_bought
price = QLabel("{}m".format(db.PRICES[unit_type]))
price = QLabel("$ <b>{}</b> m".format(db.PRICES[unit_type]))
price.setSizePolicy(QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed))
buy = QPushButton("+")
@ -52,17 +52,18 @@ class QRecruitBehaviour:
layout.addWidget(unitName, row, 0)
layout.addItem(QSpacerItem(20, 0, QSizePolicy.Minimum, QSizePolicy.Minimum), row, 1)
layout.addWidget(existing_units, row, 2)
layout.addWidget(amount_bought, row, 3)
layout.addItem(QSpacerItem(20, 0, QSizePolicy.Minimum, QSizePolicy.Minimum), row, 3)
layout.addWidget(price, row, 4)
layout.addItem(QSpacerItem(20, 0, QSizePolicy.Minimum, QSizePolicy.Minimum), row, 5)
layout.addWidget(buy, row, 6)
layout.addWidget(sell, row, 7)
layout.addWidget(sell, row, 5)
layout.addWidget(amount_bought, row, 6)
layout.addWidget(buy, row, 7)
return row + 1
def _update_count_label(self, unit_type: UnitType):
self.bought_amount_labels[unit_type].setText("[{}]".format(
self.bought_amount_labels[unit_type].setText("{}".format(
unit_type in self.deliveryEvent.units and "{}".format(self.deliveryEvent.units[unit_type]) or "0"
))

View File

@ -22,7 +22,7 @@ class QInfoPanel(QGroupBox):
layout = QVBoxLayout()
layout.addWidget(self.informations_list)
layout.setSpacing(0)
layout.setContentsMargins(0, 0, 0, 0)
layout.setContentsMargins(0, 20, 0, 0)
self.setLayout(layout)

View File

@ -51,12 +51,13 @@ class QMissionPlanning(QDialog):
self.add_flight_button = QPushButton("Add Flight")
self.add_flight_button.clicked.connect(self.on_add_flight)
self.delete_flight_button = QPushButton("Delete Selected")
self.delete_flight_button.setProperty("style", "btn-danger")
self.delete_flight_button.clicked.connect(self.on_delete_flight)
self.button_layout = QHBoxLayout()
self.button_layout.addStretch()
self.button_layout.addWidget(self.add_flight_button)
self.button_layout.addWidget(self.delete_flight_button)
self.button_layout.addWidget(self.add_flight_button)
self.mission_start_button = QPushButton("Take Off")
self.mission_start_button.setProperty("style", "start-button")

View File

@ -1,11 +1,16 @@
import os
from PySide2 import QtWidgets
from PySide2.QtCore import QFile
from PySide2.QtGui import Qt
from PySide2.QtWidgets import QFrame, QLineEdit, QGridLayout, QVBoxLayout, QLabel, QPushButton, \
QFileDialog, QMessageBox, QDialog
QFileDialog, QMessageBox, QDialog, QComboBox, QApplication
import qt_ui.uiconstants as CONST
import sys
from userdata import liberation_install
import userdata
from userdata import liberation_install, liberation_theme
from userdata.liberation_theme import get_theme_index, set_theme_index
class QLiberationPreferences(QFrame):
@ -28,6 +33,8 @@ class QLiberationPreferences(QFrame):
self.browse_saved_game.clicked.connect(self.on_browse_saved_games)
self.browse_install_dir = QPushButton("Browse...")
self.browse_install_dir.clicked.connect(self.on_browse_installation_dir)
self.themeSelect = QComboBox()
[self.themeSelect.addItem(y['themeName']) for x, y in CONST.THEMES.items()]
self.initUi()
@ -40,6 +47,9 @@ class QLiberationPreferences(QFrame):
layout.addWidget(QLabel("<strong>DCS installation directory:</strong>"), 2, 0, alignment=Qt.AlignLeft)
layout.addWidget(self.edit_dcs_install_dir, 3, 0, alignment=Qt.AlignRight)
layout.addWidget(self.browse_install_dir, 3, 1, alignment=Qt.AlignRight)
layout.addWidget(QLabel("<strong>Theme (Requires Restart)</strong>"), 4, 0)
layout.addWidget(self.themeSelect, 4, 1, alignment=Qt.AlignRight)
self.themeSelect.setCurrentIndex(get_theme_index())
main_layout.addLayout(layout)
main_layout.addStretch()
@ -63,6 +73,7 @@ class QLiberationPreferences(QFrame):
print("Applying changes")
self.saved_game_dir = self.edit_saved_game_dir.text()
self.dcs_install_dir = self.edit_dcs_install_dir.text()
set_theme_index(self.themeSelect.currentIndex())
if not os.path.isdir(self.saved_game_dir):
error_dialog = QMessageBox.critical(self, "Wrong DCS Saved Games directory.",
@ -78,7 +89,8 @@ class QLiberationPreferences(QFrame):
error_dialog.exec_()
return False
if not os.path.isdir(os.path.join(self.dcs_install_dir, "Scripts")) and os.path.isfile(os.path.join(self.dcs_install_dir, "bin", "DCS.exe")):
if not os.path.isdir(os.path.join(self.dcs_install_dir, "Scripts")) and os.path.isfile(
os.path.join(self.dcs_install_dir, "bin", "DCS.exe")):
error_dialog = QMessageBox.critical(self, "Wrong DCS installation directory.",
self.dcs_install_dir + " is not a valid DCS installation directory",
QMessageBox.StandardButton.Ok)
@ -87,7 +99,5 @@ class QLiberationPreferences(QFrame):
liberation_install.setup(self.saved_game_dir, self.dcs_install_dir)
liberation_install.save_config()
liberation_theme.save_theme_config()
return True

Binary file not shown.

Before

Width:  |  Height:  |  Size: 800 KiB

After

Width:  |  Height:  |  Size: 1.9 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 467 KiB

After

Width:  |  Height:  |  Size: 697 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.4 MiB

After

Width:  |  Height:  |  Size: 3.6 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 496 KiB

After

Width:  |  Height:  |  Size: 936 KiB

View File

@ -0,0 +1,21 @@
--Initialization script for the Mission lua Environment (SSE)
dofile('Scripts/ScriptingSystem.lua')
--Sanitize Mission Scripting environment
--This makes unavailable some unsecure functions.
--Mission downloaded from server to client may contain potentialy harmful lua code that may use these functions.
--You can remove the code below and make availble these functions at your own risk.
local function sanitizeModule(name)
_G[name] = nil
package.loaded[name] = nil
end
do
sanitizeModule('os')
sanitizeModule('io')
sanitizeModule('lfs')
require = nil
loadlib = nil
end

Binary file not shown.

After

Width:  |  Height:  |  Size: 203 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 203 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 201 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 186 B

View File

@ -0,0 +1,442 @@
/*ui theme based on dcs*/
/*
colors
Backgrounds
blue ------------------------ #2D3E50
dark blue ------------------- #1D2731
med/grey/blue --------------- #435466
dark grey ------------------- #4E5760
button blue/grey gradient --- qlineargradient(x1:0, y1:0, x2:1, y2:1,stop:0 #A4B3B9, stop:1 #85989D);
button green gradient --- qlineargradient(x1:0, y1:0, x2:1, y2:1,stop:0 #82A466, stop:1 #5C863F);
Text
white text ------------------- #ffffff
blue text -------------------- #3592C4
grey text -------------------- #B7C0C6
*/
/*QMenuBar*/
QMenuBar {
spacing: 2px; /* spacing between menu bar items */
border-bottom:none;
}
QMenuBar::item {
padding: 4px 10px;
background: transparent;
border-radius: 2px;
margin: 4px 0;
}
QMenuBar::item:selected { /* when selected using mouse or keyboard */
background: #1D2731;
}
QMenuBar::item:pressed {
background: #1D2731;
}
QMenu::item:selected {
background: #435466;
}
QLabel{
font-weight:normal;
text-align:right;
}
/*QWidget*/
QWidget {
background-color: #2D3E50;
color:white;
}
/*QLiberationWindow*/
QLiberationWindow{
background-color: #2D3E50;
color:white;
}
/*QTopPanel*/
QTopPanel,
QTopPanel * {
background-color: #1D2731;
color: #B7C0C6;
font-size: 12px;
font-weight: bold;
}
/*QPushButton*/
QPushButton {
background: qlineargradient(x1:0, y1:0, x2:1, y2:1,stop:0 #A4B3B9, stop:1 #85989D);
border: 1px solid #97A9A9;
color:#fff;
padding: 6px 10px;
cursor: pointer;
border-radius:2px;
}
QPushButton:hover {
background: #6c7b7f;
cursor:pointer;
}
/*btn-primary*/
QPushButton[style="btn-primary"]{
background: qlineargradient(x1:0, y1:0, x2:1, y2:1,stop:0 #A4B3B9, stop:1 #85989D);
border: 1px solid #97A9A9;
color:#fff;
padding: 6px 20px;
border-radius:2px;
cursor: pointer;
font-weight:bold;
text-transform:uppercase;
}
QPushButton[style="btn-primary"]:hover{
background: #6c7b7f;
}
/*highlighted buttons*/
QPushButton[style="btn-success"] , QPushButton[style="start-button"]{
background-color:#82A466;
color: white;
cursor:pointer;
padding: 6px 20px;
border-radius:2px;
font-weight:bold;
text-transform:uppercase;
}
QPushButton[style="start-button"]{
padding: 8px 30px;
}
QPushButton[style="btn-success"]:hover , QPushButton[style="start-button"]:hover{
background:#5C863F;
}
QPushButton[style="btn-danger"]{
background-color:#9E3232;
color: white;
cursor:pointer;
padding: 6px;
border-radius:2px;
border: 1px solid #9E3232;
}
QPushButton[style="btn-danger"]:hover{
background-color:#D84545;
}
QPushButton:disabled{
background:#d6d6d6;
}
/*QLabel*/
QLabel{
border: none;
}
QLabel[style="base-title"]{
font-size: 24px;
font-color: #ccc;
}
QLabel[style="icon-plane"]{
background-color:#48719D;
min-height:24px;
max-width: 84px;
border: 1px solid black;
text-align:center;
color:white;
}
QLabel[style="BARCAP"]{
border: 1px solid black;
background-color: #445299;
color:white;
padding:2px 6px;
}
QLabel[style="TARCAP"]{
border: 1px solid black;
background-color: #445299;
color:white;
padding:2px 6px;
}
QLabel[style="CAP"]{
border: 1px solid black;
background-color: #445299;
color:white;
padding:2px 6px;
}
QLabel[style="INTERCEPTION"]{
border: 1px solid black;
background-color: #7752bc;
color:white;
padding:2px 6px;
}
QLabel[style="CAS"]{
border: 1px solid black;
background-color: #ab2244;
color:white;
padding:2px 6px;
}
QLabel[style="BAI"]{
border: 1px solid black;
background-color: #ab2244;
color:white;
padding:2px 6px;
}
QLabel[style="ANTISHIP"]{
border: 1px solid black;
background-color: #ab2244;
color:white;
padding:2px 6px;
}
QLabel[style="STRIKE"]{
border: 1px solid black;
background-color: #ab2244;
color:white;
padding:2px 6px;
}
QLabel[style="DEAD"]{
border: 1px solid black;
background-color: #cc8844;
color:white;
padding:2px 6px;
}
QLabel[style="SEAD"]{
border: 1px solid black;
background-color: #aa7744;
color:white;
padding:2px 6px;
}
/*QGroupBox these are the sections that look like fieldsets*/
QGroupBox {
margin-top: 1ex; /* leave space at the top for the title */
border:1px solid #435466;
padding:5px;
margin:5px;
}
QGroupBox::title {
subcontrol-origin: margin;
subcontrol-position: top left; /* position at the top left */
padding: 3px;
color: #B7C0C6;
font-weight: 800;
}
/*checkboxes*/
QGroupBox::indicator , QCheckBox::indicator {
width: 14px;
height: 14px;
border: 1px solid #435466;
}
QGroupBox::indicator:hover , QCheckBox::indicator:hover {
border-color: #fff;
image: url(resources/stylesheets/check-hover.png);
}
QGroupBox::indicator:unchecked , QCheckBox::indicator:unchecked {
}
QGroupBox::indicator:checked , QCheckBox::indicator:checked {
image: url(resources/stylesheets/check.png);
}
/*QDialog*/
QDialog{
}
QListView {
border: none;
}
/*QTabWidget*/
QTabWidget::pane { /* The tab widget frame */
border-top: 2px solid #1D2731;
}
QTabWidget::tab-bar {
}
QTabBar::tab {
color:#5B626B;
background: #202C3A;
border-right: 1px solid #14202B;
border-left: 1px solid #14202B;
min-width: 8ex;
padding: 6px 10px;
}
QTabBar::tab:hover {
background: #1D2731;
color:#fff;
}
QTabBar::tab:selected {
color:#3592C4;
background:#2C3E4C;
}
/*QComboBox*/
QComboBox {
border:1px solid #3B4656;
color: #fff;
padding: 4px 10px;
background: #1D2731;
}
QComboBox::editable {
border:4px solid red;
}
QComboBox:hover{
border-color: #3592C4;
}
QComboBox:disabled, QComboBox::drop-down:disabled{
color: #B7C0C6;
background: #435466;
}
QComboBox::drop-down {
subcontrol-origin: padding;
subcontrol-position: top right;
padding: 2px;
border:none;
color: #fff;
height: 20px;
}
QComboBox::down-arrow {
image: url(resources/stylesheets/chevron-down.png);
}
QComboBox QAbstractItemView {
padding: 4px;
border:1px solid #3B4656;
background: #465C74;
}
/*QSpinBox number input with up down arrows*/
QSpinBox{
border:1px solid #3B4656;
color: #fff;
padding: 4px 10px;
background: #1D2731;
min-width:40px;
}
QSpinBox:hover{
border-color: #3592C4;
}
QSpinBox::up-button , QSpinBox::down-button{
border:none;
}
QSpinBox::up-button{
image: url(resources/stylesheets/chevron-up.png);
}
QSpinBox::down-button{
image: url(resources/stylesheets/chevron-down.png);
}
QLineEdit{
padding: 4px 10px;
border:1px solid #3B4656;
background: #465C74;
color: #fff;
margin-bottom:10px;
}
/*table view*/
QHeaderView{
background: #4B5B74;
}
QHeaderView::section {
background: #4B5B74;
padding: 4px;
border-style: none;
border-bottom: 1px solid #1D2731;
}
QHeaderView::section:horizontal
{
border: none;
text-align:left;
background: #4B5B74;
}
QHeaderView::section:vertical
{
border: none;
text-align:left;
background: #4B5B74;
}
QTableWidget {
gridline-color: #1D2731;
background: #4B5B74;
}
/*helper modifiers*/
*[style="no-border"] {
border:none;
}
*[style="bordered"]{
border: 1px solid #1D2731;
}
/*
QBaseMenu{
background-color:#699245;
color:white;
}
QWidget[style="baseMenuHeader"]{
font-size: 24px;
font-weight: bold;
color:white;
}*/

View File

@ -0,0 +1,3 @@
/*
windows basis styles
*/

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 MiB

After

Width:  |  Height:  |  Size: 1.9 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 940 B

After

Width:  |  Height:  |  Size: 938 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 290 B

After

Width:  |  Height:  |  Size: 290 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 387 B

After

Width:  |  Height:  |  Size: 387 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 494 B

After

Width:  |  Height:  |  Size: 494 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 456 B

After

Width:  |  Height:  |  Size: 456 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 293 B

After

Width:  |  Height:  |  Size: 293 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 336 B

After

Width:  |  Height:  |  Size: 336 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 417 B

After

Width:  |  Height:  |  Size: 417 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 374 B

After

Width:  |  Height:  |  Size: 375 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 439 B

After

Width:  |  Height:  |  Size: 439 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 367 B

After

Width:  |  Height:  |  Size: 367 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 365 B

After

Width:  |  Height:  |  Size: 365 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 503 B

After

Width:  |  Height:  |  Size: 503 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 431 B

After

Width:  |  Height:  |  Size: 562 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 358 B

After

Width:  |  Height:  |  Size: 358 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 285 B

After

Width:  |  Height:  |  Size: 285 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 460 B

After

Width:  |  Height:  |  Size: 400 B

View File

Before

Width:  |  Height:  |  Size: 461 B

After

Width:  |  Height:  |  Size: 461 B

View File

Before

Width:  |  Height:  |  Size: 757 B

After

Width:  |  Height:  |  Size: 757 B

View File

Before

Width:  |  Height:  |  Size: 730 B

After

Width:  |  Height:  |  Size: 730 B

View File

Before

Width:  |  Height:  |  Size: 580 B

After

Width:  |  Height:  |  Size: 580 B

View File

Before

Width:  |  Height:  |  Size: 444 B

After

Width:  |  Height:  |  Size: 444 B

View File

Before

Width:  |  Height:  |  Size: 383 B

After

Width:  |  Height:  |  Size: 383 B

View File

Before

Width:  |  Height:  |  Size: 371 B

After

Width:  |  Height:  |  Size: 371 B

View File

Before

Width:  |  Height:  |  Size: 448 B

After

Width:  |  Height:  |  Size: 448 B

View File

Before

Width:  |  Height:  |  Size: 655 B

After

Width:  |  Height:  |  Size: 655 B

View File

Before

Width:  |  Height:  |  Size: 397 B

After

Width:  |  Height:  |  Size: 397 B

View File

Before

Width:  |  Height:  |  Size: 704 B

After

Width:  |  Height:  |  Size: 704 B

View File

Before

Width:  |  Height:  |  Size: 436 B

After

Width:  |  Height:  |  Size: 436 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 729 B

After

Width:  |  Height:  |  Size: 634 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 697 B

After

Width:  |  Height:  |  Size: 558 B

View File

Before

Width:  |  Height:  |  Size: 400 B

After

Width:  |  Height:  |  Size: 400 B

View File

Before

Width:  |  Height:  |  Size: 634 B

After

Width:  |  Height:  |  Size: 634 B

View File

Before

Width:  |  Height:  |  Size: 558 B

After

Width:  |  Height:  |  Size: 558 B

View File

Before

Width:  |  Height:  |  Size: 485 B

After

Width:  |  Height:  |  Size: 485 B

View File

Before

Width:  |  Height:  |  Size: 392 B

After

Width:  |  Height:  |  Size: 392 B

View File

Before

Width:  |  Height:  |  Size: 353 B

After

Width:  |  Height:  |  Size: 353 B

View File

Before

Width:  |  Height:  |  Size: 366 B

After

Width:  |  Height:  |  Size: 366 B

View File

Before

Width:  |  Height:  |  Size: 411 B

After

Width:  |  Height:  |  Size: 411 B

View File

Before

Width:  |  Height:  |  Size: 529 B

After

Width:  |  Height:  |  Size: 529 B

View File

Before

Width:  |  Height:  |  Size: 364 B

After

Width:  |  Height:  |  Size: 364 B

View File

Before

Width:  |  Height:  |  Size: 518 B

After

Width:  |  Height:  |  Size: 518 B

View File

Before

Width:  |  Height:  |  Size: 390 B

After

Width:  |  Height:  |  Size: 390 B

View File

Before

Width:  |  Height:  |  Size: 460 B

After

Width:  |  Height:  |  Size: 460 B

View File

Before

Width:  |  Height:  |  Size: 729 B

After

Width:  |  Height:  |  Size: 729 B

View File

Before

Width:  |  Height:  |  Size: 697 B

After

Width:  |  Height:  |  Size: 697 B

View File

Before

Width:  |  Height:  |  Size: 556 B

After

Width:  |  Height:  |  Size: 556 B

View File

Before

Width:  |  Height:  |  Size: 434 B

After

Width:  |  Height:  |  Size: 434 B

View File

Before

Width:  |  Height:  |  Size: 385 B

After

Width:  |  Height:  |  Size: 385 B

View File

Before

Width:  |  Height:  |  Size: 372 B

After

Width:  |  Height:  |  Size: 372 B

View File

Before

Width:  |  Height:  |  Size: 459 B

After

Width:  |  Height:  |  Size: 459 B

View File

Before

Width:  |  Height:  |  Size: 657 B

After

Width:  |  Height:  |  Size: 657 B

View File

Before

Width:  |  Height:  |  Size: 397 B

After

Width:  |  Height:  |  Size: 397 B

View File

Before

Width:  |  Height:  |  Size: 659 B

After

Width:  |  Height:  |  Size: 659 B

View File

Before

Width:  |  Height:  |  Size: 434 B

After

Width:  |  Height:  |  Size: 434 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 556 B

After

Width:  |  Height:  |  Size: 485 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 434 B

After

Width:  |  Height:  |  Size: 392 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 385 B

After

Width:  |  Height:  |  Size: 353 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 372 B

After

Width:  |  Height:  |  Size: 366 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 459 B

After

Width:  |  Height:  |  Size: 411 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 657 B

After

Width:  |  Height:  |  Size: 529 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 397 B

After

Width:  |  Height:  |  Size: 364 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 659 B

After

Width:  |  Height:  |  Size: 518 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 434 B

After

Width:  |  Height:  |  Size: 390 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 465 KiB

After

Width:  |  Height:  |  Size: 113 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 659 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@ -0,0 +1,74 @@
import json
import os
import qt_ui.uiconstants as CONST
global __theme_index
THEME_PREFERENCES_FILE_PATH = "liberation_theme.json"
DEFAULT_THEME_INDEX = 1
def init():
global __theme_index
__theme_index = DEFAULT_THEME_INDEX
print("init setting theme index to " + str(__theme_index))
if os.path.isfile(THEME_PREFERENCES_FILE_PATH):
try:
with(open(THEME_PREFERENCES_FILE_PATH)) as prefs:
pref_data = json.loads(prefs.read())
__theme_index = pref_data["theme_index"]
print(__theme_index)
set_theme_index(__theme_index)
save_theme_config()
print("file setting theme index to " + str(__theme_index))
except:
# is this necessary?
set_theme_index(DEFAULT_THEME_INDEX)
print("except setting theme index to " + str(__theme_index))
else:
# is this necessary?
set_theme_index(DEFAULT_THEME_INDEX)
print("else setting theme index to " + str(__theme_index))
# set theme index then use save_theme_config to save to file
def set_theme_index(x):
global __theme_index
__theme_index = x
# get theme index to reference other theme properties(themeName, themeFile, themeIcons)
def get_theme_index():
global __theme_index
return __theme_index
# get theme name based on current index
def get_theme_name():
theme_name = CONST.THEMES[get_theme_index()]['themeName']
return theme_name
# get theme icon sub-folder name based on current index
def get_theme_icons():
theme_icons = CONST.THEMES[get_theme_index()]['themeIcons']
return str(theme_icons)
# get theme stylesheet css based on current index
def get_theme_css_file():
theme_file = CONST.THEMES[get_theme_index()]['themeFile']
return str(theme_file)
# save current theme index to json file
def save_theme_config():
pref_data = {
"theme_index": get_theme_index()
}
with(open(THEME_PREFERENCES_FILE_PATH, "w")) as prefs:
prefs.write(json.dumps(pref_data))