mirror of
https://github.com/xfgryujk/blivechat.git
synced 2025-01-13 22:00:15 +08:00
GUI插件完成设置窗口
This commit is contained in:
parent
abbbbb1154
commit
c285ba20cc
@ -1,5 +1,137 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
import configparser
|
||||||
|
import logging
|
||||||
import os
|
import os
|
||||||
|
from typing import *
|
||||||
|
|
||||||
|
import pubsub.pub as pub
|
||||||
|
|
||||||
|
logger = logging.getLogger('native-ui.' + __name__)
|
||||||
|
|
||||||
BASE_PATH = os.path.realpath(os.getcwd())
|
BASE_PATH = os.path.realpath(os.getcwd())
|
||||||
LOG_PATH = os.path.join(BASE_PATH, 'log')
|
LOG_PATH = os.path.join(BASE_PATH, 'log')
|
||||||
|
DATA_PATH = os.path.join(BASE_PATH, 'data')
|
||||||
|
|
||||||
|
SAVE_CONFIG_PATH = os.path.join(DATA_PATH, 'config.ini')
|
||||||
|
CONFIG_PATH_LIST = [
|
||||||
|
SAVE_CONFIG_PATH,
|
||||||
|
os.path.join(DATA_PATH, 'config.example.ini')
|
||||||
|
]
|
||||||
|
|
||||||
|
_config: Optional['AppConfig'] = None
|
||||||
|
|
||||||
|
|
||||||
|
def init():
|
||||||
|
if reload():
|
||||||
|
return
|
||||||
|
logger.warning('Using default config')
|
||||||
|
set_config(AppConfig())
|
||||||
|
|
||||||
|
|
||||||
|
def reload():
|
||||||
|
config_path = ''
|
||||||
|
for path in CONFIG_PATH_LIST:
|
||||||
|
if os.path.exists(path):
|
||||||
|
config_path = path
|
||||||
|
break
|
||||||
|
if config_path == '':
|
||||||
|
return False
|
||||||
|
|
||||||
|
config = AppConfig()
|
||||||
|
if not config.load(config_path):
|
||||||
|
return False
|
||||||
|
|
||||||
|
set_config(config)
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
def get_config():
|
||||||
|
return _config
|
||||||
|
|
||||||
|
|
||||||
|
def set_config(new_config: 'AppConfig'):
|
||||||
|
global _config
|
||||||
|
old_config = _config
|
||||||
|
_config = new_config
|
||||||
|
|
||||||
|
if old_config is not None and new_config is not old_config:
|
||||||
|
pub.sendMessage('config_change', new_config=new_config, old_config=old_config)
|
||||||
|
|
||||||
|
|
||||||
|
class AppConfig:
|
||||||
|
def __init__(self):
|
||||||
|
self.room_opacity = 100
|
||||||
|
|
||||||
|
self.chat_url_params = self._get_default_url_params()
|
||||||
|
self.paid_url_params = self._get_default_url_params()
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _get_default_url_params():
|
||||||
|
return {
|
||||||
|
'minGiftPrice': '0',
|
||||||
|
'showGiftName': 'true',
|
||||||
|
'maxNumber': '200',
|
||||||
|
}
|
||||||
|
|
||||||
|
def is_url_params_changed(self, other: 'AppConfig'):
|
||||||
|
return self.chat_url_params != other.chat_url_params or self.paid_url_params != other.paid_url_params
|
||||||
|
|
||||||
|
def load(self, path):
|
||||||
|
try:
|
||||||
|
config = configparser.ConfigParser()
|
||||||
|
config.read(path, 'utf-8-sig')
|
||||||
|
|
||||||
|
self._load_ui_config(config)
|
||||||
|
self._load_url_params(config)
|
||||||
|
except Exception: # noqa
|
||||||
|
logger.exception('Failed to load config:')
|
||||||
|
return False
|
||||||
|
return True
|
||||||
|
|
||||||
|
def save(self, path):
|
||||||
|
try:
|
||||||
|
config = configparser.ConfigParser()
|
||||||
|
|
||||||
|
self._save_ui_config(config)
|
||||||
|
self._save_url_params(config)
|
||||||
|
|
||||||
|
tmp_path = path + '.tmp'
|
||||||
|
with open(tmp_path, 'w', encoding='utf-8-sig') as f:
|
||||||
|
config.write(f)
|
||||||
|
os.replace(tmp_path, path)
|
||||||
|
except Exception: # noqa
|
||||||
|
logger.exception('Failed to save config:')
|
||||||
|
return False
|
||||||
|
return True
|
||||||
|
|
||||||
|
def _load_ui_config(self, config: configparser.ConfigParser):
|
||||||
|
ui_section = config['ui']
|
||||||
|
self.room_opacity = ui_section.getint('room_opacity', self.room_opacity)
|
||||||
|
|
||||||
|
def _save_ui_config(self, config: configparser.ConfigParser):
|
||||||
|
config['ui'] = {
|
||||||
|
'room_opacity': str(self.room_opacity),
|
||||||
|
}
|
||||||
|
|
||||||
|
def _load_url_params(self, config: configparser.ConfigParser):
|
||||||
|
self.chat_url_params = self._section_to_url_params(config['chat_url_params'])
|
||||||
|
self.paid_url_params = self._section_to_url_params(config['paid_url_params'])
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _section_to_url_params(section: configparser.SectionProxy):
|
||||||
|
params = {}
|
||||||
|
for line in section.values():
|
||||||
|
key, _, value = line.partition('=')
|
||||||
|
params[key.strip()] = value.strip()
|
||||||
|
return params
|
||||||
|
|
||||||
|
def _save_url_params(self, config: configparser.ConfigParser):
|
||||||
|
config['chat_url_params'] = self._url_params_to_section(self.chat_url_params)
|
||||||
|
config['paid_url_params'] = self._url_params_to_section(self.paid_url_params)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _url_params_to_section(url_params: dict):
|
||||||
|
return {
|
||||||
|
str(index): f'{key} = {value}'
|
||||||
|
for index, (key, value) in enumerate(url_params.items(), 1)
|
||||||
|
}
|
||||||
|
47
plugins/native-ui/data/config.example.ini
Normal file
47
plugins/native-ui/data/config.example.ini
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
# 如果要修改配置,可以复制此文件并重命名为“config.ini”再修改
|
||||||
|
|
||||||
|
[ui]
|
||||||
|
# 房间窗口不透明度
|
||||||
|
room_opacity = 100
|
||||||
|
|
||||||
|
|
||||||
|
# 评论栏浏览器URL中的参数
|
||||||
|
[chat_url_params]
|
||||||
|
# --- 这些参数不可改变 ---
|
||||||
|
# 通过服务器转发消息
|
||||||
|
# 1 = relayMessagesByServer = true
|
||||||
|
|
||||||
|
# --- 这些参数可以在UI中设置 ---
|
||||||
|
# 自动翻译弹幕到日语
|
||||||
|
1 = autoTranslate = false
|
||||||
|
# 标注打赏用户名读音
|
||||||
|
2 = giftUsernamePronunciation =
|
||||||
|
# 最低显示打赏价格(元)
|
||||||
|
3 = minGiftPrice = 0
|
||||||
|
# 屏蔽礼物弹幕
|
||||||
|
4 = blockGiftDanmaku = true
|
||||||
|
|
||||||
|
# --- 其他的参数自己发挥 ---
|
||||||
|
# 显示礼物名
|
||||||
|
5 = showGiftName = true
|
||||||
|
# 最大弹幕数
|
||||||
|
6 = maxNumber = 200
|
||||||
|
|
||||||
|
|
||||||
|
# 付费消息浏览器URL中的参数
|
||||||
|
[paid_url_params]
|
||||||
|
# --- 这些参数不可改变 ---
|
||||||
|
# 通过服务器转发消息
|
||||||
|
# 1 = relayMessagesByServer = true
|
||||||
|
# 显示弹幕
|
||||||
|
# 2 = showDanmaku = false
|
||||||
|
|
||||||
|
# --- 这些参数可以在UI中设置 ---
|
||||||
|
1 = autoTranslate = false
|
||||||
|
2 = giftUsernamePronunciation =
|
||||||
|
3 = minGiftPrice = 0
|
||||||
|
4 = blockGiftDanmaku = true
|
||||||
|
|
||||||
|
# --- 其他的参数自己发挥 ---
|
||||||
|
5 = showGiftName = true
|
||||||
|
6 = maxNumber = 200
|
@ -443,7 +443,7 @@
|
|||||||
<object class="notebookpage" expanded="true">
|
<object class="notebookpage" expanded="true">
|
||||||
<property name="bitmap"></property>
|
<property name="bitmap"></property>
|
||||||
<property name="label">付费消息</property>
|
<property name="label">付费消息</property>
|
||||||
<property name="select">0</property>
|
<property name="select">1</property>
|
||||||
<object class="wxPanel" expanded="true">
|
<object class="wxPanel" expanded="true">
|
||||||
<property name="BottomDockable">1</property>
|
<property name="BottomDockable">1</property>
|
||||||
<property name="LeftDockable">1</property>
|
<property name="LeftDockable">1</property>
|
||||||
@ -824,7 +824,7 @@
|
|||||||
<object class="notebookpage" expanded="true">
|
<object class="notebookpage" expanded="true">
|
||||||
<property name="bitmap"></property>
|
<property name="bitmap"></property>
|
||||||
<property name="label">统计</property>
|
<property name="label">统计</property>
|
||||||
<property name="select">1</property>
|
<property name="select">0</property>
|
||||||
<object class="wxPanel" expanded="true">
|
<object class="wxPanel" expanded="true">
|
||||||
<property name="BottomDockable">1</property>
|
<property name="BottomDockable">1</property>
|
||||||
<property name="LeftDockable">1</property>
|
<property name="LeftDockable">1</property>
|
||||||
@ -1134,7 +1134,7 @@
|
|||||||
<property name="name">RoomConfigDialogBase</property>
|
<property name="name">RoomConfigDialogBase</property>
|
||||||
<property name="pos"></property>
|
<property name="pos"></property>
|
||||||
<property name="size">-1,-1</property>
|
<property name="size">-1,-1</property>
|
||||||
<property name="style">wxDEFAULT_DIALOG_STYLE</property>
|
<property name="style">wxDEFAULT_DIALOG_STYLE|wxDIALOG_NO_PARENT</property>
|
||||||
<property name="subclass">; ; forward_declare</property>
|
<property name="subclass">; ; forward_declare</property>
|
||||||
<property name="title">房间设置</property>
|
<property name="title">房间设置</property>
|
||||||
<property name="tooltip"></property>
|
<property name="tooltip"></property>
|
||||||
@ -1288,7 +1288,7 @@
|
|||||||
<property name="pos"></property>
|
<property name="pos"></property>
|
||||||
<property name="resize">Resizable</property>
|
<property name="resize">Resizable</property>
|
||||||
<property name="show">1</property>
|
<property name="show">1</property>
|
||||||
<property name="size">-1,-1</property>
|
<property name="size">200,-1</property>
|
||||||
<property name="style">wxSL_HORIZONTAL</property>
|
<property name="style">wxSL_HORIZONTAL</property>
|
||||||
<property name="subclass">; ; forward_declare</property>
|
<property name="subclass">; ; forward_declare</property>
|
||||||
<property name="toolbar_pane">0</property>
|
<property name="toolbar_pane">0</property>
|
||||||
@ -1301,6 +1301,7 @@
|
|||||||
<property name="window_extra_style"></property>
|
<property name="window_extra_style"></property>
|
||||||
<property name="window_name"></property>
|
<property name="window_name"></property>
|
||||||
<property name="window_style"></property>
|
<property name="window_style"></property>
|
||||||
|
<event name="OnSlider">_on_opacity_slider_change</event>
|
||||||
</object>
|
</object>
|
||||||
</object>
|
</object>
|
||||||
<object class="sizeritem" expanded="true">
|
<object class="sizeritem" expanded="true">
|
||||||
@ -1472,7 +1473,7 @@
|
|||||||
<property name="minimize_button">0</property>
|
<property name="minimize_button">0</property>
|
||||||
<property name="minimum_size"></property>
|
<property name="minimum_size"></property>
|
||||||
<property name="moveable">1</property>
|
<property name="moveable">1</property>
|
||||||
<property name="name">auto_translate_label1</property>
|
<property name="name">gift_pron_label</property>
|
||||||
<property name="pane_border">1</property>
|
<property name="pane_border">1</property>
|
||||||
<property name="pane_position"></property>
|
<property name="pane_position"></property>
|
||||||
<property name="pane_size"></property>
|
<property name="pane_size"></property>
|
||||||
@ -1503,9 +1504,9 @@
|
|||||||
<property name="permission">none</property>
|
<property name="permission">none</property>
|
||||||
<object class="sizeritem" expanded="true">
|
<object class="sizeritem" expanded="true">
|
||||||
<property name="border">5</property>
|
<property name="border">5</property>
|
||||||
<property name="flag">wxALL</property>
|
<property name="flag">wxALL|wxEXPAND</property>
|
||||||
<property name="proportion">0</property>
|
<property name="proportion">1</property>
|
||||||
<object class="wxRadioButton" expanded="true">
|
<object class="wxChoice" expanded="true">
|
||||||
<property name="BottomDockable">1</property>
|
<property name="BottomDockable">1</property>
|
||||||
<property name="LeftDockable">1</property>
|
<property name="LeftDockable">1</property>
|
||||||
<property name="RightDockable">1</property>
|
<property name="RightDockable">1</property>
|
||||||
@ -1519,6 +1520,7 @@
|
|||||||
<property name="caption"></property>
|
<property name="caption"></property>
|
||||||
<property name="caption_visible">1</property>
|
<property name="caption_visible">1</property>
|
||||||
<property name="center_pane">0</property>
|
<property name="center_pane">0</property>
|
||||||
|
<property name="choices">"不显示" "拼音" "日文假名"</property>
|
||||||
<property name="close_button">1</property>
|
<property name="close_button">1</property>
|
||||||
<property name="context_help"></property>
|
<property name="context_help"></property>
|
||||||
<property name="context_menu">1</property>
|
<property name="context_menu">1</property>
|
||||||
@ -1534,7 +1536,6 @@
|
|||||||
<property name="gripper">0</property>
|
<property name="gripper">0</property>
|
||||||
<property name="hidden">0</property>
|
<property name="hidden">0</property>
|
||||||
<property name="id">wxID_ANY</property>
|
<property name="id">wxID_ANY</property>
|
||||||
<property name="label">不显示</property>
|
|
||||||
<property name="max_size"></property>
|
<property name="max_size"></property>
|
||||||
<property name="maximize_button">0</property>
|
<property name="maximize_button">0</property>
|
||||||
<property name="maximum_size"></property>
|
<property name="maximum_size"></property>
|
||||||
@ -1542,72 +1543,7 @@
|
|||||||
<property name="minimize_button">0</property>
|
<property name="minimize_button">0</property>
|
||||||
<property name="minimum_size"></property>
|
<property name="minimum_size"></property>
|
||||||
<property name="moveable">1</property>
|
<property name="moveable">1</property>
|
||||||
<property name="name">gift_pron_none_radio</property>
|
<property name="name">gift_pron_choice</property>
|
||||||
<property name="pane_border">1</property>
|
|
||||||
<property name="pane_position"></property>
|
|
||||||
<property name="pane_size"></property>
|
|
||||||
<property name="permission">protected</property>
|
|
||||||
<property name="pin_button">1</property>
|
|
||||||
<property name="pos"></property>
|
|
||||||
<property name="resize">Resizable</property>
|
|
||||||
<property name="show">1</property>
|
|
||||||
<property name="size"></property>
|
|
||||||
<property name="style">wxRB_GROUP</property>
|
|
||||||
<property name="subclass">; ; forward_declare</property>
|
|
||||||
<property name="toolbar_pane">0</property>
|
|
||||||
<property name="tooltip"></property>
|
|
||||||
<property name="validator_data_type"></property>
|
|
||||||
<property name="validator_style">wxFILTER_NONE</property>
|
|
||||||
<property name="validator_type">wxDefaultValidator</property>
|
|
||||||
<property name="validator_variable"></property>
|
|
||||||
<property name="value">1</property>
|
|
||||||
<property name="window_extra_style"></property>
|
|
||||||
<property name="window_name"></property>
|
|
||||||
<property name="window_style"></property>
|
|
||||||
</object>
|
|
||||||
</object>
|
|
||||||
<object class="sizeritem" expanded="true">
|
|
||||||
<property name="border">5</property>
|
|
||||||
<property name="flag">wxALL</property>
|
|
||||||
<property name="proportion">0</property>
|
|
||||||
<object class="wxRadioButton" expanded="true">
|
|
||||||
<property name="BottomDockable">1</property>
|
|
||||||
<property name="LeftDockable">1</property>
|
|
||||||
<property name="RightDockable">1</property>
|
|
||||||
<property name="TopDockable">1</property>
|
|
||||||
<property name="aui_layer"></property>
|
|
||||||
<property name="aui_name"></property>
|
|
||||||
<property name="aui_position"></property>
|
|
||||||
<property name="aui_row"></property>
|
|
||||||
<property name="best_size"></property>
|
|
||||||
<property name="bg"></property>
|
|
||||||
<property name="caption"></property>
|
|
||||||
<property name="caption_visible">1</property>
|
|
||||||
<property name="center_pane">0</property>
|
|
||||||
<property name="close_button">1</property>
|
|
||||||
<property name="context_help"></property>
|
|
||||||
<property name="context_menu">1</property>
|
|
||||||
<property name="default_pane">0</property>
|
|
||||||
<property name="dock">Dock</property>
|
|
||||||
<property name="dock_fixed">0</property>
|
|
||||||
<property name="docking">Left</property>
|
|
||||||
<property name="drag_accept_files">0</property>
|
|
||||||
<property name="enabled">1</property>
|
|
||||||
<property name="fg"></property>
|
|
||||||
<property name="floatable">1</property>
|
|
||||||
<property name="font"></property>
|
|
||||||
<property name="gripper">0</property>
|
|
||||||
<property name="hidden">0</property>
|
|
||||||
<property name="id">wxID_ANY</property>
|
|
||||||
<property name="label">拼音</property>
|
|
||||||
<property name="max_size"></property>
|
|
||||||
<property name="maximize_button">0</property>
|
|
||||||
<property name="maximum_size"></property>
|
|
||||||
<property name="min_size"></property>
|
|
||||||
<property name="minimize_button">0</property>
|
|
||||||
<property name="minimum_size"></property>
|
|
||||||
<property name="moveable">1</property>
|
|
||||||
<property name="name">gift_pron_pinyin_radio</property>
|
|
||||||
<property name="pane_border">1</property>
|
<property name="pane_border">1</property>
|
||||||
<property name="pane_position"></property>
|
<property name="pane_position"></property>
|
||||||
<property name="pane_size"></property>
|
<property name="pane_size"></property>
|
||||||
@ -1615,6 +1551,7 @@
|
|||||||
<property name="pin_button">1</property>
|
<property name="pin_button">1</property>
|
||||||
<property name="pos"></property>
|
<property name="pos"></property>
|
||||||
<property name="resize">Resizable</property>
|
<property name="resize">Resizable</property>
|
||||||
|
<property name="selection">0</property>
|
||||||
<property name="show">1</property>
|
<property name="show">1</property>
|
||||||
<property name="size"></property>
|
<property name="size"></property>
|
||||||
<property name="style"></property>
|
<property name="style"></property>
|
||||||
@ -1625,72 +1562,6 @@
|
|||||||
<property name="validator_style">wxFILTER_NONE</property>
|
<property name="validator_style">wxFILTER_NONE</property>
|
||||||
<property name="validator_type">wxDefaultValidator</property>
|
<property name="validator_type">wxDefaultValidator</property>
|
||||||
<property name="validator_variable"></property>
|
<property name="validator_variable"></property>
|
||||||
<property name="value">0</property>
|
|
||||||
<property name="window_extra_style"></property>
|
|
||||||
<property name="window_name"></property>
|
|
||||||
<property name="window_style"></property>
|
|
||||||
</object>
|
|
||||||
</object>
|
|
||||||
<object class="sizeritem" expanded="true">
|
|
||||||
<property name="border">5</property>
|
|
||||||
<property name="flag">wxALL</property>
|
|
||||||
<property name="proportion">0</property>
|
|
||||||
<object class="wxRadioButton" expanded="true">
|
|
||||||
<property name="BottomDockable">1</property>
|
|
||||||
<property name="LeftDockable">1</property>
|
|
||||||
<property name="RightDockable">1</property>
|
|
||||||
<property name="TopDockable">1</property>
|
|
||||||
<property name="aui_layer"></property>
|
|
||||||
<property name="aui_name"></property>
|
|
||||||
<property name="aui_position"></property>
|
|
||||||
<property name="aui_row"></property>
|
|
||||||
<property name="best_size"></property>
|
|
||||||
<property name="bg"></property>
|
|
||||||
<property name="caption"></property>
|
|
||||||
<property name="caption_visible">1</property>
|
|
||||||
<property name="center_pane">0</property>
|
|
||||||
<property name="close_button">1</property>
|
|
||||||
<property name="context_help"></property>
|
|
||||||
<property name="context_menu">1</property>
|
|
||||||
<property name="default_pane">0</property>
|
|
||||||
<property name="dock">Dock</property>
|
|
||||||
<property name="dock_fixed">0</property>
|
|
||||||
<property name="docking">Left</property>
|
|
||||||
<property name="drag_accept_files">0</property>
|
|
||||||
<property name="enabled">1</property>
|
|
||||||
<property name="fg"></property>
|
|
||||||
<property name="floatable">1</property>
|
|
||||||
<property name="font"></property>
|
|
||||||
<property name="gripper">0</property>
|
|
||||||
<property name="hidden">0</property>
|
|
||||||
<property name="id">wxID_ANY</property>
|
|
||||||
<property name="label">日文假名</property>
|
|
||||||
<property name="max_size"></property>
|
|
||||||
<property name="maximize_button">0</property>
|
|
||||||
<property name="maximum_size"></property>
|
|
||||||
<property name="min_size"></property>
|
|
||||||
<property name="minimize_button">0</property>
|
|
||||||
<property name="minimum_size"></property>
|
|
||||||
<property name="moveable">1</property>
|
|
||||||
<property name="name">gift_pron_kana_radio</property>
|
|
||||||
<property name="pane_border">1</property>
|
|
||||||
<property name="pane_position"></property>
|
|
||||||
<property name="pane_size"></property>
|
|
||||||
<property name="permission">protected</property>
|
|
||||||
<property name="pin_button">1</property>
|
|
||||||
<property name="pos"></property>
|
|
||||||
<property name="resize">Resizable</property>
|
|
||||||
<property name="show">1</property>
|
|
||||||
<property name="size"></property>
|
|
||||||
<property name="style"></property>
|
|
||||||
<property name="subclass">; ; forward_declare</property>
|
|
||||||
<property name="toolbar_pane">0</property>
|
|
||||||
<property name="tooltip"></property>
|
|
||||||
<property name="validator_data_type"></property>
|
|
||||||
<property name="validator_style">wxFILTER_NONE</property>
|
|
||||||
<property name="validator_type">wxDefaultValidator</property>
|
|
||||||
<property name="validator_variable"></property>
|
|
||||||
<property name="value">0</property>
|
|
||||||
<property name="window_extra_style"></property>
|
<property name="window_extra_style"></property>
|
||||||
<property name="window_name"></property>
|
<property name="window_name"></property>
|
||||||
<property name="window_style"></property>
|
<property name="window_style"></property>
|
||||||
@ -2079,6 +1950,7 @@
|
|||||||
<property name="window_extra_style"></property>
|
<property name="window_extra_style"></property>
|
||||||
<property name="window_name"></property>
|
<property name="window_name"></property>
|
||||||
<property name="window_style"></property>
|
<property name="window_style"></property>
|
||||||
|
<event name="OnButtonClick">_on_ok</event>
|
||||||
</object>
|
</object>
|
||||||
</object>
|
</object>
|
||||||
<object class="sizeritem" expanded="true">
|
<object class="sizeritem" expanded="true">
|
||||||
@ -2153,6 +2025,7 @@
|
|||||||
<property name="window_extra_style"></property>
|
<property name="window_extra_style"></property>
|
||||||
<property name="window_name"></property>
|
<property name="window_name"></property>
|
||||||
<property name="window_style"></property>
|
<property name="window_style"></property>
|
||||||
|
<event name="OnButtonClick">_on_cancel</event>
|
||||||
</object>
|
</object>
|
||||||
</object>
|
</object>
|
||||||
</object>
|
</object>
|
||||||
|
@ -64,7 +64,7 @@ class RoomFrameBase ( wx.Frame ):
|
|||||||
self.paid_panel.SetSizer( bSizer4 )
|
self.paid_panel.SetSizer( bSizer4 )
|
||||||
self.paid_panel.Layout()
|
self.paid_panel.Layout()
|
||||||
bSizer4.Fit( self.paid_panel )
|
bSizer4.Fit( self.paid_panel )
|
||||||
self.console_notebook.AddPage( self.paid_panel, u"付费消息", False )
|
self.console_notebook.AddPage( self.paid_panel, u"付费消息", True )
|
||||||
self.super_chat_panel = wx.Panel( self.console_notebook, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.TAB_TRAVERSAL )
|
self.super_chat_panel = wx.Panel( self.console_notebook, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.TAB_TRAVERSAL )
|
||||||
bSizer5 = wx.BoxSizer( wx.VERTICAL )
|
bSizer5 = wx.BoxSizer( wx.VERTICAL )
|
||||||
|
|
||||||
@ -115,7 +115,7 @@ class RoomFrameBase ( wx.Frame ):
|
|||||||
self.statistics_panel.SetSizer( bSizer7 )
|
self.statistics_panel.SetSizer( bSizer7 )
|
||||||
self.statistics_panel.Layout()
|
self.statistics_panel.Layout()
|
||||||
bSizer7.Fit( self.statistics_panel )
|
bSizer7.Fit( self.statistics_panel )
|
||||||
self.console_notebook.AddPage( self.statistics_panel, u"统计", True )
|
self.console_notebook.AddPage( self.statistics_panel, u"统计", False )
|
||||||
|
|
||||||
bSizer1.Add( self.console_notebook, 1, wx.EXPAND, 5 )
|
bSizer1.Add( self.console_notebook, 1, wx.EXPAND, 5 )
|
||||||
|
|
||||||
@ -160,7 +160,7 @@ class RoomFrameBase ( wx.Frame ):
|
|||||||
class RoomConfigDialogBase ( wx.Dialog ):
|
class RoomConfigDialogBase ( wx.Dialog ):
|
||||||
|
|
||||||
def __init__( self, parent ):
|
def __init__( self, parent ):
|
||||||
wx.Dialog.__init__ ( self, parent, id = wx.ID_ANY, title = u"房间设置", pos = wx.DefaultPosition, size = wx.Size( -1,-1 ), style = wx.DEFAULT_DIALOG_STYLE )
|
wx.Dialog.__init__ ( self, parent, id = wx.ID_ANY, title = u"房间设置", pos = wx.DefaultPosition, size = wx.Size( -1,-1 ), style = wx.DEFAULT_DIALOG_STYLE|wx.DIALOG_NO_PARENT )
|
||||||
|
|
||||||
self.SetSizeHints( wx.DefaultSize, wx.DefaultSize )
|
self.SetSizeHints( wx.DefaultSize, wx.DefaultSize )
|
||||||
|
|
||||||
@ -177,7 +177,7 @@ class RoomConfigDialogBase ( wx.Dialog ):
|
|||||||
|
|
||||||
fgSizer1.Add( self.opacity_label, 0, wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT|wx.ALL, 5 )
|
fgSizer1.Add( self.opacity_label, 0, wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT|wx.ALL, 5 )
|
||||||
|
|
||||||
self.opacity_slider = wx.Slider( sbSizer1.GetStaticBox(), wx.ID_ANY, 100, 10, 100, wx.DefaultPosition, wx.Size( -1,-1 ), wx.SL_HORIZONTAL )
|
self.opacity_slider = wx.Slider( sbSizer1.GetStaticBox(), wx.ID_ANY, 100, 10, 100, wx.DefaultPosition, wx.Size( 200,-1 ), wx.SL_HORIZONTAL )
|
||||||
fgSizer1.Add( self.opacity_slider, 1, wx.ALL|wx.EXPAND, 5 )
|
fgSizer1.Add( self.opacity_slider, 1, wx.ALL|wx.EXPAND, 5 )
|
||||||
|
|
||||||
self.auto_translate_label = wx.StaticText( sbSizer1.GetStaticBox(), wx.ID_ANY, u"自动翻译弹幕到日语", wx.DefaultPosition, wx.DefaultSize, 0 )
|
self.auto_translate_label = wx.StaticText( sbSizer1.GetStaticBox(), wx.ID_ANY, u"自动翻译弹幕到日语", wx.DefaultPosition, wx.DefaultSize, 0 )
|
||||||
@ -188,22 +188,17 @@ class RoomConfigDialogBase ( wx.Dialog ):
|
|||||||
self.auto_translate_check = wx.CheckBox( sbSizer1.GetStaticBox(), wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.DefaultSize, 0 )
|
self.auto_translate_check = wx.CheckBox( sbSizer1.GetStaticBox(), wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.DefaultSize, 0 )
|
||||||
fgSizer1.Add( self.auto_translate_check, 1, wx.ALL|wx.EXPAND, 5 )
|
fgSizer1.Add( self.auto_translate_check, 1, wx.ALL|wx.EXPAND, 5 )
|
||||||
|
|
||||||
self.auto_translate_label1 = wx.StaticText( sbSizer1.GetStaticBox(), wx.ID_ANY, u"标注打赏用户名读音", wx.DefaultPosition, wx.DefaultSize, 0 )
|
self.gift_pron_label = wx.StaticText( sbSizer1.GetStaticBox(), wx.ID_ANY, u"标注打赏用户名读音", wx.DefaultPosition, wx.DefaultSize, 0 )
|
||||||
self.auto_translate_label1.Wrap( -1 )
|
self.gift_pron_label.Wrap( -1 )
|
||||||
|
|
||||||
fgSizer1.Add( self.auto_translate_label1, 0, wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT|wx.ALL, 5 )
|
fgSizer1.Add( self.gift_pron_label, 0, wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT|wx.ALL, 5 )
|
||||||
|
|
||||||
bSizer2 = wx.BoxSizer( wx.HORIZONTAL )
|
bSizer2 = wx.BoxSizer( wx.HORIZONTAL )
|
||||||
|
|
||||||
self.gift_pron_none_radio = wx.RadioButton( sbSizer1.GetStaticBox(), wx.ID_ANY, u"不显示", wx.DefaultPosition, wx.DefaultSize, wx.RB_GROUP )
|
gift_pron_choiceChoices = [ u"不显示", u"拼音", u"日文假名" ]
|
||||||
self.gift_pron_none_radio.SetValue( True )
|
self.gift_pron_choice = wx.Choice( sbSizer1.GetStaticBox(), wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, gift_pron_choiceChoices, 0 )
|
||||||
bSizer2.Add( self.gift_pron_none_radio, 0, wx.ALL, 5 )
|
self.gift_pron_choice.SetSelection( 0 )
|
||||||
|
bSizer2.Add( self.gift_pron_choice, 1, wx.ALL|wx.EXPAND, 5 )
|
||||||
self.gift_pron_pinyin_radio = wx.RadioButton( sbSizer1.GetStaticBox(), wx.ID_ANY, u"拼音", wx.DefaultPosition, wx.DefaultSize, 0 )
|
|
||||||
bSizer2.Add( self.gift_pron_pinyin_radio, 0, wx.ALL, 5 )
|
|
||||||
|
|
||||||
self.gift_pron_kana_radio = wx.RadioButton( sbSizer1.GetStaticBox(), wx.ID_ANY, u"日文假名", wx.DefaultPosition, wx.DefaultSize, 0 )
|
|
||||||
bSizer2.Add( self.gift_pron_kana_radio, 0, wx.ALL, 5 )
|
|
||||||
|
|
||||||
|
|
||||||
fgSizer1.Add( bSizer2, 1, wx.ALL|wx.EXPAND, 5 )
|
fgSizer1.Add( bSizer2, 1, wx.ALL|wx.EXPAND, 5 )
|
||||||
@ -250,12 +245,12 @@ class RoomConfigDialogBase ( wx.Dialog ):
|
|||||||
|
|
||||||
bSizer3.Add( ( 0, 0), 1, wx.EXPAND, 5 )
|
bSizer3.Add( ( 0, 0), 1, wx.EXPAND, 5 )
|
||||||
|
|
||||||
self.ok_button = wx.Button( self, wx.ID_ANY, u"确定", wx.DefaultPosition, wx.DefaultSize, 0 )
|
self.ok_button = wx.Button( self, wx.ID_OK, u"确定", wx.DefaultPosition, wx.DefaultSize, 0 )
|
||||||
|
|
||||||
self.ok_button.SetDefault()
|
self.ok_button.SetDefault()
|
||||||
bSizer3.Add( self.ok_button, 0, wx.ALL, 5 )
|
bSizer3.Add( self.ok_button, 0, wx.ALL, 5 )
|
||||||
|
|
||||||
self.cancel_button = wx.Button( self, wx.ID_ANY, u"取消", wx.DefaultPosition, wx.DefaultSize, 0 )
|
self.cancel_button = wx.Button( self, wx.ID_CANCEL, u"取消", wx.DefaultPosition, wx.DefaultSize, 0 )
|
||||||
bSizer3.Add( self.cancel_button, 0, wx.ALL, 5 )
|
bSizer3.Add( self.cancel_button, 0, wx.ALL, 5 )
|
||||||
|
|
||||||
|
|
||||||
@ -268,7 +263,23 @@ class RoomConfigDialogBase ( wx.Dialog ):
|
|||||||
|
|
||||||
self.Centre( wx.BOTH )
|
self.Centre( wx.BOTH )
|
||||||
|
|
||||||
|
# Connect Events
|
||||||
|
self.opacity_slider.Bind( wx.EVT_SLIDER, self._on_opacity_slider_change )
|
||||||
|
self.ok_button.Bind( wx.EVT_BUTTON, self._on_ok )
|
||||||
|
self.cancel_button.Bind( wx.EVT_BUTTON, self._on_cancel )
|
||||||
|
|
||||||
def __del__( self ):
|
def __del__( self ):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
# Virtual event handlers, override them in your derived class
|
||||||
|
def _on_opacity_slider_change( self, event ):
|
||||||
|
event.Skip()
|
||||||
|
|
||||||
|
def _on_ok( self, event ):
|
||||||
|
event.Skip()
|
||||||
|
|
||||||
|
def _on_cancel( self, event ):
|
||||||
|
event.Skip()
|
||||||
|
|
||||||
|
|
||||||
|
@ -29,6 +29,7 @@ async def init():
|
|||||||
init_signal_handlers()
|
init_signal_handlers()
|
||||||
|
|
||||||
init_logging()
|
init_logging()
|
||||||
|
config.init()
|
||||||
|
|
||||||
await blcsdk.init()
|
await blcsdk.init()
|
||||||
if not blcsdk.is_sdk_version_compatible():
|
if not blcsdk.is_sdk_version_compatible():
|
||||||
|
@ -7,6 +7,7 @@ import wxasync
|
|||||||
|
|
||||||
import blcsdk.models as sdk_models
|
import blcsdk.models as sdk_models
|
||||||
import listener
|
import listener
|
||||||
|
import ui.room_config_dialog
|
||||||
import ui.room_frame
|
import ui.room_frame
|
||||||
|
|
||||||
logger = logging.getLogger('native-ui.' + __name__)
|
logger = logging.getLogger('native-ui.' + __name__)
|
||||||
@ -25,12 +26,14 @@ class App(wxasync.WxAsyncApp):
|
|||||||
self.SetExitOnFrameDelete(False)
|
self.SetExitOnFrameDelete(False)
|
||||||
|
|
||||||
self._key_room_frame_dict: Dict[sdk_models.RoomKey, ui.room_frame.RoomFrame] = {}
|
self._key_room_frame_dict: Dict[sdk_models.RoomKey, ui.room_frame.RoomFrame] = {}
|
||||||
|
self._room_config_dialog: Optional[ui.room_config_dialog.RoomConfigDialog] = None
|
||||||
|
|
||||||
def OnInit(self):
|
def OnInit(self):
|
||||||
pub.subscribe(self._on_add_room, 'add_room')
|
pub.subscribe(self._on_add_room, 'add_room')
|
||||||
pub.subscribe(self._on_del_room, 'del_room')
|
pub.subscribe(self._on_del_room, 'del_room')
|
||||||
pub.subscribe(self._on_room_frame_close, 'room_frame_close')
|
pub.subscribe(self._on_room_frame_close, 'room_frame_close')
|
||||||
pub.subscribe(self._on_open_admin_ui, 'open_admin_ui')
|
pub.subscribe(self._on_open_admin_ui, 'open_admin_ui')
|
||||||
|
pub.subscribe(self._on_open_room_config_dialog, 'open_room_config_dialog')
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def _on_add_room(self, room_key: sdk_models.RoomKey):
|
def _on_add_room(self, room_key: sdk_models.RoomKey):
|
||||||
@ -51,3 +54,8 @@ class App(wxasync.WxAsyncApp):
|
|||||||
def _on_open_admin_ui(self):
|
def _on_open_admin_ui(self):
|
||||||
for room in listener.iter_rooms():
|
for room in listener.iter_rooms():
|
||||||
self._on_add_room(room.room_key)
|
self._on_add_room(room.room_key)
|
||||||
|
|
||||||
|
def _on_open_room_config_dialog(self):
|
||||||
|
if self._room_config_dialog is None or self._room_config_dialog.IsBeingDeleted():
|
||||||
|
self._room_config_dialog = ui.room_config_dialog.RoomConfigDialog(None)
|
||||||
|
self._room_config_dialog.Show()
|
||||||
|
96
plugins/native-ui/ui/room_config_dialog.py
Normal file
96
plugins/native-ui/ui/room_config_dialog.py
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
import copy
|
||||||
|
import logging
|
||||||
|
from typing import *
|
||||||
|
|
||||||
|
import pubsub.pub as pub
|
||||||
|
import wx
|
||||||
|
|
||||||
|
import config
|
||||||
|
import designer.ui_base
|
||||||
|
|
||||||
|
logger = logging.getLogger('native-ui.' + __name__)
|
||||||
|
|
||||||
|
|
||||||
|
class RoomConfigDialog(designer.ui_base.RoomConfigDialogBase):
|
||||||
|
_GIFT_PRON_CHOICES = ('', 'pinyin', 'kana')
|
||||||
|
|
||||||
|
def __init__(self, parent):
|
||||||
|
super().__init__(parent)
|
||||||
|
|
||||||
|
self._new_cfg_cache: Optional[config.AppConfig] = None
|
||||||
|
|
||||||
|
def TransferDataToWindow(self):
|
||||||
|
cfg = config.get_config()
|
||||||
|
url_params: dict = cfg.chat_url_params
|
||||||
|
|
||||||
|
self.opacity_slider.SetValue(cfg.room_opacity)
|
||||||
|
self.auto_translate_check.SetValue(self._to_bool(url_params.get('autoTranslate', 'false')))
|
||||||
|
try:
|
||||||
|
gift_pron_index = self._GIFT_PRON_CHOICES.index(url_params.get('giftUsernamePronunciation', ''))
|
||||||
|
except ValueError:
|
||||||
|
gift_pron_index = 0
|
||||||
|
self.gift_pron_choice.SetSelection(gift_pron_index)
|
||||||
|
self.min_gift_price_edit.SetValue(url_params.get('minGiftPrice', '0'))
|
||||||
|
self.block_gift_danmaku_check.SetValue(self._to_bool(url_params.get('blockGiftDanmaku', 'true')))
|
||||||
|
|
||||||
|
return super().TransferDataToWindow()
|
||||||
|
|
||||||
|
def _on_ok(self, event):
|
||||||
|
try:
|
||||||
|
self._new_cfg_cache = self._create_config_from_window()
|
||||||
|
except Exception as e:
|
||||||
|
logger.exception('_create_config_from_window failed:')
|
||||||
|
wx.MessageBox(str(e), '应用设置失败', wx.OK | wx.ICON_ERROR | wx.CENTRE, self)
|
||||||
|
return
|
||||||
|
|
||||||
|
if (
|
||||||
|
self._new_cfg_cache.is_url_params_changed(config.get_config())
|
||||||
|
and wx.MessageBox(
|
||||||
|
'修改部分设置需要刷新浏览器,是否继续?', '提示', wx.YES_NO | wx.CENTRE, self
|
||||||
|
) != wx.YES
|
||||||
|
):
|
||||||
|
return
|
||||||
|
super()._on_ok(event)
|
||||||
|
|
||||||
|
def _create_config_from_window(self):
|
||||||
|
cfg = copy.deepcopy(config.get_config())
|
||||||
|
|
||||||
|
cfg.room_opacity = self.opacity_slider.GetValue()
|
||||||
|
url_params = {
|
||||||
|
'autoTranslate': self._bool_to_str(self.auto_translate_check.GetValue()),
|
||||||
|
'giftUsernamePronunciation': self._GIFT_PRON_CHOICES[self.gift_pron_choice.GetSelection()],
|
||||||
|
'minGiftPrice': self.min_gift_price_edit.GetValue(),
|
||||||
|
'blockGiftDanmaku': self._bool_to_str(self.block_gift_danmaku_check.GetValue()),
|
||||||
|
}
|
||||||
|
cfg.chat_url_params.update(url_params)
|
||||||
|
cfg.paid_url_params.update(url_params)
|
||||||
|
|
||||||
|
return cfg
|
||||||
|
|
||||||
|
def TransferDataFromWindow(self):
|
||||||
|
if self._new_cfg_cache is None:
|
||||||
|
logger.warning('_new_cfg_cache is None')
|
||||||
|
return False
|
||||||
|
|
||||||
|
config.set_config(self._new_cfg_cache)
|
||||||
|
wx.CallAfter(self._new_cfg_cache.save, config.SAVE_CONFIG_PATH)
|
||||||
|
|
||||||
|
return super().TransferDataFromWindow()
|
||||||
|
|
||||||
|
def _on_cancel(self, event):
|
||||||
|
pub.sendMessage('room_config_dialog_cancel')
|
||||||
|
super()._on_cancel(event)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _to_bool(value):
|
||||||
|
if isinstance(value, str):
|
||||||
|
return value.lower() not in ('false', 'no', 'off', '0', '')
|
||||||
|
return bool(value)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _bool_to_str(value):
|
||||||
|
return 'true' if value else 'false'
|
||||||
|
|
||||||
|
def _on_opacity_slider_change(self, event):
|
||||||
|
pub.sendMessage('preview_room_opacity', room_opacity=self.opacity_slider.GetValue())
|
@ -10,6 +10,7 @@ import xlsxwriter.exceptions
|
|||||||
|
|
||||||
import blcsdk
|
import blcsdk
|
||||||
import blcsdk.models as sdk_models
|
import blcsdk.models as sdk_models
|
||||||
|
import config
|
||||||
import designer.ui_base
|
import designer.ui_base
|
||||||
import listener
|
import listener
|
||||||
|
|
||||||
@ -25,10 +26,7 @@ class RoomFrame(designer.ui_base.RoomFrameBase):
|
|||||||
room_str = str(room.room_id) if room is not None else str(self._room_key)
|
room_str = str(room.room_id) if room is not None else str(self._room_key)
|
||||||
self.SetTitle(f'blivechat - 房间 {room_str}')
|
self.SetTitle(f'blivechat - 房间 {room_str}')
|
||||||
|
|
||||||
room_params = {'minGiftPrice': 0, 'showGiftName': 'true'}
|
self._apply_config(True)
|
||||||
self.chat_web_view.LoadURL(self._get_room_url(room_params))
|
|
||||||
room_params['showDanmaku'] = 'false'
|
|
||||||
self.paid_web_view.LoadURL(self._get_room_url(room_params))
|
|
||||||
|
|
||||||
self.super_chat_list.AppendColumn('时间', width=50)
|
self.super_chat_list.AppendColumn('时间', width=50)
|
||||||
self.super_chat_list.AppendColumn('用户名', width=120)
|
self.super_chat_list.AppendColumn('用户名', width=120)
|
||||||
@ -53,6 +51,9 @@ class RoomFrame(designer.ui_base.RoomFrameBase):
|
|||||||
for index in room.uid_paid_user_dict:
|
for index in room.uid_paid_user_dict:
|
||||||
self._on_uid_paid_user_dict_change(room, room.uid_paid_user_dict, index, True)
|
self._on_uid_paid_user_dict_change(room, room.uid_paid_user_dict, index, True)
|
||||||
|
|
||||||
|
pub.subscribe(self._on_preview_room_opacity, 'preview_room_opacity')
|
||||||
|
pub.subscribe(self._on_room_config_dialog_cancel, 'room_config_dialog_cancel')
|
||||||
|
pub.subscribe(self._on_config_change, 'config_change')
|
||||||
pub.subscribe(self._on_super_chats_change, 'room_data_change.super_chats')
|
pub.subscribe(self._on_super_chats_change, 'room_data_change.super_chats')
|
||||||
pub.subscribe(self._on_gifts_change, 'room_data_change.gifts')
|
pub.subscribe(self._on_gifts_change, 'room_data_change.gifts')
|
||||||
pub.subscribe(self._on_uid_paid_user_dict_change, 'room_data_change.uid_paid_user_dict')
|
pub.subscribe(self._on_uid_paid_user_dict_change, 'room_data_change.uid_paid_user_dict')
|
||||||
@ -60,22 +61,8 @@ class RoomFrame(designer.ui_base.RoomFrameBase):
|
|||||||
pub.subscribe(self._on_simple_statistics_change, 'room_data_change.interact_uids')
|
pub.subscribe(self._on_simple_statistics_change, 'room_data_change.interact_uids')
|
||||||
pub.subscribe(self._on_simple_statistics_change, 'room_data_change.total_paid_price')
|
pub.subscribe(self._on_simple_statistics_change, 'room_data_change.total_paid_price')
|
||||||
|
|
||||||
def _get_room_url(self, params: dict):
|
|
||||||
params = params.copy()
|
|
||||||
params['roomKeyType'] = self._room_key.type.value
|
|
||||||
params['relayMessagesByServer'] = 'true'
|
|
||||||
|
|
||||||
query = '&'.join(
|
|
||||||
f'{urllib.parse.quote_plus(key)}={urllib.parse.quote_plus(str(value))}'
|
|
||||||
for key, value in params.items()
|
|
||||||
)
|
|
||||||
blc_port = blcsdk.get_blc_port()
|
|
||||||
encoded_room_key_value = urllib.parse.quote_plus(str(self._room_key.value))
|
|
||||||
url = f'http://localhost:{blc_port}/room/{encoded_room_key_value}?{query}'
|
|
||||||
return url
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# UI事件
|
# 本窗口UI事件
|
||||||
#
|
#
|
||||||
|
|
||||||
def _on_close(self, event):
|
def _on_close(self, event):
|
||||||
@ -83,9 +70,7 @@ class RoomFrame(designer.ui_base.RoomFrameBase):
|
|||||||
super()._on_close(event)
|
super()._on_close(event)
|
||||||
|
|
||||||
def _on_config_button_click(self, event):
|
def _on_config_button_click(self, event):
|
||||||
# TODO WIP
|
pub.sendMessage('open_room_config_dialog')
|
||||||
dialog = designer.ui_base.RoomConfigDialogBase(self)
|
|
||||||
dialog.Show()
|
|
||||||
|
|
||||||
def _on_stay_on_top_button_toggle(self, event: wx.CommandEvent):
|
def _on_stay_on_top_button_toggle(self, event: wx.CommandEvent):
|
||||||
style = self.GetWindowStyle()
|
style = self.GetWindowStyle()
|
||||||
@ -161,6 +146,51 @@ class RoomFrame(designer.ui_base.RoomFrameBase):
|
|||||||
for row in range(row_num):
|
for row in range(row_num):
|
||||||
yield [list_ctrl.GetItemText(row, col) for col in range(col_num)]
|
yield [list_ctrl.GetItemText(row, col) for col in range(col_num)]
|
||||||
|
|
||||||
|
#
|
||||||
|
# 配置事件
|
||||||
|
#
|
||||||
|
|
||||||
|
def _on_preview_room_opacity(self, room_opacity):
|
||||||
|
self._set_opacity(room_opacity)
|
||||||
|
|
||||||
|
def _set_opacity(self, opacity):
|
||||||
|
opacity = min(max(opacity, 10), 100)
|
||||||
|
alpha = round(opacity * wx.IMAGE_ALPHA_OPAQUE / 100)
|
||||||
|
return self.SetTransparent(alpha)
|
||||||
|
|
||||||
|
def _on_room_config_dialog_cancel(self):
|
||||||
|
cfg = config.get_config()
|
||||||
|
self._set_opacity(cfg.room_opacity)
|
||||||
|
|
||||||
|
def _on_config_change(self, new_config: config.AppConfig, old_config: config.AppConfig):
|
||||||
|
self._apply_config(new_config.is_url_params_changed(old_config))
|
||||||
|
|
||||||
|
def _apply_config(self, reload_web_views):
|
||||||
|
cfg = config.get_config()
|
||||||
|
self._set_opacity(cfg.room_opacity)
|
||||||
|
if reload_web_views:
|
||||||
|
self.chat_web_view.LoadURL(self._get_room_url(cfg.chat_url_params))
|
||||||
|
self.paid_web_view.LoadURL(self._get_room_url(cfg.paid_url_params, {'showDanmaku': 'false'}))
|
||||||
|
|
||||||
|
def _get_room_url(self, params: dict, override_params: Optional[dict] = None):
|
||||||
|
if override_params is None:
|
||||||
|
override_params = {}
|
||||||
|
params = {
|
||||||
|
**params,
|
||||||
|
'roomKeyType': self._room_key.type.value,
|
||||||
|
'relayMessagesByServer': 'true',
|
||||||
|
**override_params,
|
||||||
|
}
|
||||||
|
|
||||||
|
query = '&'.join(
|
||||||
|
f'{urllib.parse.quote_plus(key)}={urllib.parse.quote_plus(str(value))}'
|
||||||
|
for key, value in params.items()
|
||||||
|
)
|
||||||
|
blc_port = blcsdk.get_blc_port()
|
||||||
|
encoded_room_key_value = urllib.parse.quote_plus(str(self._room_key.value))
|
||||||
|
url = f'http://localhost:{blc_port}/room/{encoded_room_key_value}?{query}'
|
||||||
|
return url
|
||||||
|
|
||||||
#
|
#
|
||||||
# 模型事件
|
# 模型事件
|
||||||
#
|
#
|
||||||
|
Loading…
Reference in New Issue
Block a user