From 86e8c31d35a15c93a6d71e1c1448f983f2d9be7b Mon Sep 17 00:00:00 2001 From: bigeagle Date: Sat, 8 Nov 2014 22:46:02 +0800 Subject: [PATCH] settings --- danmaQ/app.py | 44 +++++++++++++++++---- danmaQ/config_dialog.py | 86 +++++++++++++++++++++++++++++++++++++++++ danmaQ/danmaq_ui.py | 49 +++++++++++++---------- danmaQ/settings.py | 46 ++++++++++++++++++++++ danmaQ/tray_icon.py | 1 + 5 files changed, 197 insertions(+), 29 deletions(-) create mode 100644 danmaQ/config_dialog.py create mode 100644 danmaQ/settings.py diff --git a/danmaQ/app.py b/danmaQ/app.py index 407a9be..67d8a8a 100644 --- a/danmaQ/app.py +++ b/danmaQ/app.py @@ -7,6 +7,8 @@ from PyQt5.QtCore import pyqtSignal from .danmaq_ui import Danmaku from .tray_icon import DanmaQTrayIcon, ICON_ENABLED +from .settings import load_config, save_config +from .config_dialog import ConfigDialog class SubscribeThread(QtCore.QThread): @@ -54,34 +56,50 @@ def __init__(self, parent=None): self.trayIcon = DanmaQTrayIcon(self) self.trayIcon.show() + self.config_dialog = ConfigDialog(self) + self._options = load_config() layout = QtWidgets.QVBoxLayout() hbox = QtWidgets.QHBoxLayout() - hbox.addWidget(QtWidgets.QLabel("Server: ")) - self._server = QtWidgets.QLineEdit("http://dm.tuna.moe/") + hbox.addWidget(QtWidgets.QLabel("Server: ", self)) + self._server = QtWidgets.QLineEdit( + self._options['http_stream_server'], self) hbox.addWidget(self._server) layout.addLayout(hbox) hbox = QtWidgets.QHBoxLayout() - hbox.addWidget(QtWidgets.QLabel("Channel: ")) - self._chan = QtWidgets.QLineEdit("demo") + hbox.addWidget(QtWidgets.QLabel("Save As Default Server: ", self)) + self._save_server = QtWidgets.QCheckBox(self) + hbox.addWidget(self._save_server) + layout.addLayout(hbox) + + hbox = QtWidgets.QHBoxLayout() + hbox.addWidget(QtWidgets.QLabel("Channel: ", self)) + self._chan = QtWidgets.QLineEdit("demo", self) hbox.addWidget(self._chan) layout.addLayout(hbox) hbox = QtWidgets.QHBoxLayout() - hbox.addWidget(QtWidgets.QLabel("Password: ")) - self._passwd = QtWidgets.QLineEdit("") + hbox.addWidget(QtWidgets.QLabel("Password: ", self)) + self._passwd = QtWidgets.QLineEdit("", self) hbox.addWidget(self._passwd) layout.addLayout(hbox) - self.main_button = QtWidgets.QPushButton("Subscribe") - layout.addWidget(self.main_button) + hbox = QtWidgets.QHBoxLayout() + self.hide_button = QtWidgets.QPushButton("Hide", self) + self.main_button = QtWidgets.QPushButton("Subscribe", self) + hbox.addWidget(self.hide_button) + hbox.addWidget(self.main_button) + layout.addLayout(hbox) self.setLayout(layout) + self.hide_button.released.connect(self.hide) self.main_button.released.connect(self.subscribe_danmaku) + self.config_dialog.preferenceChanged.connect(self.apply_new_preference) self.trayIcon.toggleAction.triggered.connect(self.subscribe_danmaku) self.trayIcon.exitAction.triggered.connect(self.close) self.trayIcon.showAction.triggered.connect(self.show) + self.trayIcon.configAction.triggered.connect(self.config_dialog.show) self.workThread = None self.dms = {} @@ -114,6 +132,11 @@ def delete_danmaku(self, _id): dm.close() def on_subscription_started(self): + if self._save_server.isChecked(): + opts = load_config() + opts['http_stream_server'] = self._server.text() + save_config(opts) + self.main_button.setText("Unsubscribe") self.trayIcon.set_icon_running() self.trayIcon.showMessage( @@ -130,6 +153,11 @@ def on_subscription_finished(self): self.main_button.setText("Subscribe") self.trayIcon.showMessage("DanmaQ", "Subscription Finished") + def apply_new_preference(self): + pref = self.config_dialog.preferences() + # print(pref) + Danmaku.set_options(pref) + def main(): import signal diff --git a/danmaQ/config_dialog.py b/danmaQ/config_dialog.py new file mode 100644 index 0000000..98c838a --- /dev/null +++ b/danmaQ/config_dialog.py @@ -0,0 +1,86 @@ +#!/usr/bin/env python2 +# -*- coding:utf-8 -*- +from PyQt5 import QtWidgets, QtCore, QtGui +from PyQt5.QtCore import pyqtSignal +from .tray_icon import ICON_ENABLED +from .settings import load_config, save_config + + +class ConfigDialog(QtWidgets.QDialog): + preferenceChanged = pyqtSignal(name="preferenceChanged") + + def __init__(self, parent=None): + super(ConfigDialog, self).__init__(parent) + self.setWindowTitle("Danmaku") + self.setWindowIcon(QtGui.QIcon(ICON_ENABLED)) + + self._dft = load_config() + + layout = QtWidgets.QVBoxLayout() + + hbox = QtWidgets.QHBoxLayout() + hbox.addWidget(QtWidgets.QLabel("Font Family: ")) + self._font_family = QtWidgets.QFontComboBox(self) + self._font_family.setCurrentFont(QtGui.QFont(self._dft['font_family'])) + hbox.addWidget(self._font_family) + layout.addLayout(hbox) + + hbox = QtWidgets.QHBoxLayout() + hbox.addWidget(QtWidgets.QLabel("Font Size: ")) + self._font_size = QtWidgets.QSpinBox(self) + self._font_size.setValue(self._dft['font_size']) + hbox.addWidget(self._font_size) + layout.addLayout(hbox) + + hbox = QtWidgets.QHBoxLayout() + hbox.addWidget(QtWidgets.QLabel("Speed Scale: ")) + self._speed = QtWidgets.QSlider(QtCore.Qt.Horizontal, self) + self._speed.setTickInterval(1) + self._speed.setMaximum(21) + self._speed.setMinimum(4) + self._speed.setValue(10) + self._speed_indicator = QtWidgets.QLabel("1.0", self) + self._speed.sliderMoved.connect(self.update_speed_indicator) + hbox.addWidget(self._speed) + hbox.addWidget(self._speed_indicator) + layout.addLayout(hbox) + + hbox = QtWidgets.QHBoxLayout() + self._save = QtWidgets.QPushButton("&Save && Apply", self) + self._apply = QtWidgets.QPushButton("&Apply", self) + self._cancel = QtWidgets.QPushButton("&Cancel", self) + self._save.released.connect(self.save_preferences) + self._apply.released.connect(self.emit_new_preferences) + self._cancel.released.connect(self.hide) + hbox.addWidget(self._save) + hbox.addWidget(self._apply) + hbox.addWidget(self._cancel) + layout.addLayout(hbox) + + self.setLayout(layout) + + def update_speed_indicator(self): + val = self._speed.value() + self._speed_indicator.setText("{:.1f}".format(val/10.0)) + + def preferences(self): + return { + 'font_family': self._font_family.currentText(), + 'font_size': self._font_size.value(), + 'speed_scale': self._speed.value() / 10.0, + } + + def save_preferences(self): + opts = load_config() + new_opts = self.preferences() + opts['font_family'] = new_opts['font_family'] + opts['font_size'] = new_opts['font_size'] + opts['speed_scale'] = new_opts['speed_scale'] + save_config(opts) + self.emit_new_preferences() + + def emit_new_preferences(self): + self.preferenceChanged.emit() + self.hide() + +# vim: ts=4 sw=4 sts=4 expandtab diff --git a/danmaQ/danmaq_ui.py b/danmaQ/danmaq_ui.py index f143732..557f6dc 100644 --- a/danmaQ/danmaq_ui.py +++ b/danmaQ/danmaq_ui.py @@ -7,6 +7,8 @@ from PyQt5 import QtWidgets, QtCore, QtGui from PyQt5.QtCore import pyqtSignal +from .settings import load_config + color_styles = { "white": ('rgb(255, 255, 255)', QtGui.QColor("black"), ), "black": ('rgb(0, 0, 0)', QtGui.QColor("white"), ), @@ -18,19 +20,31 @@ "purple": ('rgb(128, 0, 128)', QtGui.QColor("white"), ), } +OPTIONS = load_config() + -class Danmaku(QtWidgets.QWidget): +class Danmaku(QtWidgets.QLabel): _lock = Lock() vertical_slots = None - _speed_scale = 1 - _font_size = 28 + _font_family = OPTIONS['font_family'] + _speed_scale = OPTIONS['speed_scale'] + _font_size = OPTIONS['font_size'] _interval = 10 + _style_tmpl = "font-size: {font_size}pt;" \ + + "font-family: {font_family};" \ + + "color: {color}; font-weight: bold;" exited = pyqtSignal(str, name="exited") + @classmethod + def set_options(cls, opts): + cls._font_family = opts['font_family'] + cls._font_size = opts['font_size'] + cls._speed_scale = opts['speed_scale'] + def __init__(self, text="text", style='white', position='fly', parent=None): - super(Danmaku, self).__init__(parent) + super(Danmaku, self).__init__(text, parent) self._text = text self._style = style @@ -41,13 +55,13 @@ def __init__(self, text="text", style='white', position='fly', parent=None): self.setAttribute(QtCore.Qt.WA_TranslucentBackground, True) self.setAttribute(QtCore.Qt.WA_DeleteOnClose, True) - self.setWindowFlags(QtCore.Qt.ToolTip - |QtCore.Qt.FramelessWindowHint) + self.setWindowFlags( + QtCore.Qt.ToolTip + | QtCore.Qt.FramelessWindowHint + ) self.init_text(text, style) - # QtCore.QTimer.singleShot(20, self.fly) - self._width = self.frameSize().width() self._height = self.frameSize().height() self.screenGeo = QtWidgets.QDesktopWidget().screenGeometry() @@ -62,8 +76,6 @@ def __init__(self, text="text", style='white', position='fly', parent=None): self.init_position() def init_text(self, text, style): - - self.label = QtWidgets.QLabel(text, parent=self) tcolor, bcolor = color_styles.get(style, color_styles['white']) effect = QtWidgets.QGraphicsDropShadowEffect(self) @@ -71,22 +83,18 @@ def init_text(self, text, style): effect.setColor(bcolor) effect.setOffset(0, 0) - self.label.setStyleSheet( - "font-size: {font_size}pt; color: {color}; font-weight: bold; ".format( + self.setStyleSheet( + self._style_tmpl.format( font_size=self._font_size, + font_family=self._font_family, color=tcolor, ) ) - self.label.setGraphicsEffect(effect) + self.setGraphicsEffect(effect) - layout = QtWidgets.QVBoxLayout() - layout.addWidget(self.label) - self.setLayout(layout) - self.setContentsMargins(0, 0, 0, 0) - self.layout().setContentsMargins(0, 0, 0, 0) _msize = self.minimumSizeHint() - _msize.setHeight(_msize.height() - 10) + _msize.setHeight(_msize.height()) self.resize(_msize) def init_position(self): @@ -129,7 +137,7 @@ def init_position(self): QtCore.QTimer.singleShot(1000, self.init_position) return - self.y = self._height * self.vslot + 10 + self.y = self._height * self.vslot QtCore.QTimer.singleShot(5000, self.clean_close) self.move(self.x, self.y) @@ -190,7 +198,6 @@ def delete_danmaku(self, _id): dm = self.dms.pop(_id) dm.close() - if __name__ == "__main__": import signal signal.signal(signal.SIGINT, signal.SIG_DFL) diff --git a/danmaQ/settings.py b/danmaQ/settings.py new file mode 100644 index 0000000..68e9400 --- /dev/null +++ b/danmaQ/settings.py @@ -0,0 +1,46 @@ +#!/usr/bin/env python3 +# -*- coding:utf-8 -*- +import os +import json + +DEFAULT_OPTIONS = { + 'http_stream_server': "http://dm.tuna.moe", + 'http_stream_uri': "/api/v1/channels/{cname}/danmaku", + 'font_family': "WenQuanYi Micro Hei", + 'font_size': 28, + 'speed_scale': 1.0, +} + +_xdg_cfg_dir = os.environ.get( + "XDG_CONFIG_HOME", os.path.join(os.path.expanduser("~"), ".config")) + +_cfg_file = os.path.join(_xdg_cfg_dir, "danmaQ", "config.json") + + +def load_config(): + options = dict(DEFAULT_OPTIONS.items()) + + if os.path.exists(_cfg_file): + try: + with open(_cfg_file, 'r') as f: + opts = json.load(f) + options['font_family'] = opts['font_family'] + options['font_size'] = opts['font_size'] + options['speed_scale'] = opts['speed_scale'] + options['http_stream_server'] = opts['http_stream_server'] + except: + options = dict(DEFAULT_OPTIONS.items()) + save_config(options) + else: + if not os.path.exists(os.path.dirname(_cfg_file)): + os.makedirs(os.path.dirname(_cfg_file)) + save_config(options) + + return options + + +def save_config(options): + with open(_cfg_file, 'wb') as f: + json.dump(options, f, indent=4) + +# vim: ts=4 sw=4 sts=4 expandtab diff --git a/danmaQ/tray_icon.py b/danmaQ/tray_icon.py index 0036775..c1ee620 100644 --- a/danmaQ/tray_icon.py +++ b/danmaQ/tray_icon.py @@ -22,6 +22,7 @@ def __init__(self, parent=None): menu = QtWidgets.QMenu(parent) self.toggleAction = menu.addAction("Toggle Subscription") self.showAction = menu.addAction("Show Main Window") + self.configAction = menu.addAction("Preferences") self.exitAction = menu.addAction("Exit") self.setContextMenu(menu) self.activated.connect(self.on_activate)