mirror of
https://github.com/xfgryujk/blivechat.git
synced 2024-12-26 12:50:33 +08:00
GUI插件完成托盘图标
This commit is contained in:
parent
c285ba20cc
commit
644e36b4eb
@ -1,5 +1,5 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
import os
|
||||
|
||||
BASE_PATH = os.path.realpath(os.getcwd())
|
||||
BASE_PATH = os.path.dirname(os.path.realpath(__file__))
|
||||
LOG_PATH = os.path.join(BASE_PATH, 'log')
|
||||
|
@ -8,7 +8,7 @@ import pubsub.pub as pub
|
||||
|
||||
logger = logging.getLogger('native-ui.' + __name__)
|
||||
|
||||
BASE_PATH = os.path.realpath(os.getcwd())
|
||||
BASE_PATH = os.path.dirname(os.path.realpath(__file__))
|
||||
LOG_PATH = os.path.join(BASE_PATH, 'log')
|
||||
DATA_PATH = os.path.join(BASE_PATH, 'data')
|
||||
|
||||
@ -18,6 +18,8 @@ CONFIG_PATH_LIST = [
|
||||
os.path.join(DATA_PATH, 'config.example.ini')
|
||||
]
|
||||
|
||||
BLC_ICON_PATH = os.path.join(DATA_PATH, 'blivechat.ico')
|
||||
|
||||
_config: Optional['AppConfig'] = None
|
||||
|
||||
|
||||
|
BIN
plugins/native-ui/data/blivechat.ico
Normal file
BIN
plugins/native-ui/data/blivechat.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 162 KiB |
@ -6,9 +6,9 @@ import pubsub.pub as pub
|
||||
import wxasync
|
||||
|
||||
import blcsdk.models as sdk_models
|
||||
import listener
|
||||
import ui.room_config_dialog
|
||||
import ui.room_frame
|
||||
import ui.task_bar_icon
|
||||
|
||||
logger = logging.getLogger('native-ui.' + __name__)
|
||||
|
||||
@ -22,6 +22,8 @@ def init():
|
||||
|
||||
class App(wxasync.WxAsyncApp):
|
||||
def __init__(self, *args, **kwargs):
|
||||
self._task_bar_icon: Optional[ui.task_bar_icon.TaskBarIcon] = None
|
||||
|
||||
super().__init__(*args, clearSigInt=False, **kwargs)
|
||||
self.SetExitOnFrameDelete(False)
|
||||
|
||||
@ -29,10 +31,12 @@ class App(wxasync.WxAsyncApp):
|
||||
self._room_config_dialog: Optional[ui.room_config_dialog.RoomConfigDialog] = None
|
||||
|
||||
def OnInit(self):
|
||||
self._task_bar_icon = ui.task_bar_icon.TaskBarIcon()
|
||||
|
||||
pub.subscribe(self._on_add_room, 'add_room')
|
||||
pub.subscribe(self._on_del_room, 'del_room')
|
||||
pub.subscribe(self._on_room_frame_close, 'room_frame_close')
|
||||
pub.subscribe(self._on_open_admin_ui, 'open_admin_ui')
|
||||
pub.subscribe(self._on_add_room, 'open_room')
|
||||
pub.subscribe(self._on_open_room_config_dialog, 'open_room_config_dialog')
|
||||
return True
|
||||
|
||||
@ -51,10 +55,6 @@ class App(wxasync.WxAsyncApp):
|
||||
def _on_room_frame_close(self, room_key: sdk_models.RoomKey):
|
||||
self._key_room_frame_dict.pop(room_key, None)
|
||||
|
||||
def _on_open_admin_ui(self):
|
||||
for room in listener.iter_rooms():
|
||||
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)
|
||||
|
@ -25,31 +25,35 @@ class RoomFrame(designer.ui_base.RoomFrameBase):
|
||||
room = listener.get_room(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._apply_config(True)
|
||||
self.SetIcon(wx.Icon(config.BLC_ICON_PATH, wx.BITMAP_TYPE_ICO))
|
||||
|
||||
self.super_chat_list.AppendColumn('时间', width=50)
|
||||
self.super_chat_list.AppendColumn('用户名', width=120)
|
||||
self.super_chat_list.AppendColumn('金额', width=50)
|
||||
self.super_chat_list.AppendColumn('内容', width=300)
|
||||
for index in range(len(room.super_chats)):
|
||||
self._on_super_chats_change(room, room.super_chats, index, True)
|
||||
|
||||
self.gift_list.AppendColumn('时间', width=50)
|
||||
self.gift_list.AppendColumn('用户名', width=120)
|
||||
self.gift_list.AppendColumn('礼物名', width=100)
|
||||
self.gift_list.AppendColumn('数量', width=50)
|
||||
self.gift_list.AppendColumn('总价', width=50)
|
||||
for index in range(len(room.gifts)):
|
||||
self._on_gifts_change(room, room.gifts, index, True)
|
||||
|
||||
# item_data只能存int,这里做个映射
|
||||
self._uid_to_paid_user_item_data: Dict[str, int] = {}
|
||||
self._next_paid_user_item_data = 1
|
||||
self.paid_user_list.AppendColumn('用户名', width=120)
|
||||
self.paid_user_list.AppendColumn('总付费', width=60)
|
||||
for index in room.uid_paid_user_dict:
|
||||
self._on_uid_paid_user_dict_change(room, room.uid_paid_user_dict, index, True)
|
||||
|
||||
self._apply_config(True)
|
||||
|
||||
if room is not None:
|
||||
for index in range(len(room.super_chats)):
|
||||
self._on_super_chats_change(room, room.super_chats, index, True)
|
||||
for index in range(len(room.gifts)):
|
||||
self._on_gifts_change(room, room.gifts, index, True)
|
||||
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_simple_statistics_change(room)
|
||||
|
||||
pub.subscribe(self._on_preview_room_opacity, 'preview_room_opacity')
|
||||
pub.subscribe(self._on_room_config_dialog_cancel, 'room_config_dialog_cancel')
|
||||
@ -195,7 +199,7 @@ class RoomFrame(designer.ui_base.RoomFrameBase):
|
||||
# 模型事件
|
||||
#
|
||||
|
||||
def _on_super_chats_change(self, room: listener.Room, value: List[listener.SuperChatRecord], index, is_new): # noqa
|
||||
def _on_super_chats_change(self, room: listener.Room, value: List[listener.SuperChatRecord], index, is_new):
|
||||
if room.room_key != self._room_key:
|
||||
return
|
||||
|
||||
@ -243,7 +247,7 @@ class RoomFrame(designer.ui_base.RoomFrameBase):
|
||||
if height_to_bottom < last_row_rect.GetHeight() * 3:
|
||||
list_ctrl.Focus(last_row_index)
|
||||
|
||||
def _on_gifts_change(self, room: listener.Room, value: List[listener.GiftRecord], index, is_new): # noqa
|
||||
def _on_gifts_change(self, room: listener.Room, value: List[listener.GiftRecord], index, is_new):
|
||||
if room.room_key != self._room_key:
|
||||
return
|
||||
|
||||
@ -260,7 +264,7 @@ class RoomFrame(designer.ui_base.RoomFrameBase):
|
||||
]
|
||||
|
||||
def _on_uid_paid_user_dict_change(
|
||||
self, room: listener.Room, value: Dict[str, listener.PaidUserRecord], index, is_new # noqa
|
||||
self, room: listener.Room, value: Dict[str, listener.PaidUserRecord], index, is_new
|
||||
):
|
||||
if room.room_key != self._room_key:
|
||||
return
|
||||
|
103
plugins/native-ui/ui/task_bar_icon.py
Normal file
103
plugins/native-ui/ui/task_bar_icon.py
Normal file
@ -0,0 +1,103 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
import logging
|
||||
import sys
|
||||
import webbrowser
|
||||
|
||||
import pubsub.pub as pub
|
||||
import wx.adv
|
||||
|
||||
import blcsdk
|
||||
import config
|
||||
import listener
|
||||
|
||||
if sys.platform == 'win32':
|
||||
IS_WIN = True
|
||||
# 懒得引入pywin32了
|
||||
import ctypes
|
||||
kernel32 = ctypes.windll.kernel32
|
||||
user32 = ctypes.windll.user32
|
||||
else:
|
||||
IS_WIN = False
|
||||
|
||||
|
||||
logger = logging.getLogger('native-ui.' + __name__)
|
||||
|
||||
|
||||
class TaskBarIcon(wx.adv.TaskBarIcon):
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
|
||||
self.SetIcon(wx.Icon(config.BLC_ICON_PATH, wx.BITMAP_TYPE_ICO), 'blivechat')
|
||||
|
||||
self._menu = wx.Menu()
|
||||
self._menu.Append(1, '打开所有房间窗口')
|
||||
self._menu.Append(2, '打开主页')
|
||||
if IS_WIN:
|
||||
self._menu.Append(3, '隐藏/显示控制台')
|
||||
self._menu.Append(wx.ID_SEPARATOR)
|
||||
self._menu.Append(wx.ID_EXIT, '退出')
|
||||
|
||||
self.Bind(wx.adv.EVT_TASKBAR_LEFT_UP, self._on_open_all_rooms_click)
|
||||
self.Bind(wx.EVT_MENU, self._on_open_all_rooms_click, id=1)
|
||||
self.Bind(wx.EVT_MENU, self._on_open_browser_click, id=2)
|
||||
self.Bind(wx.EVT_MENU, self._on_hide_console_click, id=3)
|
||||
self.Bind(wx.EVT_MENU, self._on_exit_click, id=wx.ID_EXIT)
|
||||
|
||||
pub.subscribe(self._on_open_admin_ui, 'open_admin_ui')
|
||||
|
||||
def _on_open_admin_ui(self):
|
||||
self.PopupMenu(self.GetPopupMenu())
|
||||
|
||||
def GetPopupMenu(self):
|
||||
return self._menu
|
||||
|
||||
@staticmethod
|
||||
def _on_open_browser_click(_event):
|
||||
blc_port = blcsdk.get_blc_port()
|
||||
url = 'http://localhost/' if blc_port == 80 else f'http://localhost:{blc_port}/'
|
||||
webbrowser.open(url)
|
||||
|
||||
@staticmethod
|
||||
def _on_open_all_rooms_click(_event):
|
||||
room_keys = [room.room_key for room in listener.iter_rooms()]
|
||||
if not room_keys:
|
||||
wx.MessageBox('没有任何已连接的房间', '提示')
|
||||
return
|
||||
|
||||
for room_key in room_keys:
|
||||
pub.sendMessage('open_room', room_key=room_key)
|
||||
|
||||
def _on_hide_console_click(self, _event):
|
||||
assert IS_WIN
|
||||
console_window_handle = self._find_console_window()
|
||||
if console_window_handle == 0:
|
||||
logger.warning('Console window not found')
|
||||
wx.MessageBox('找不到控制台窗口', '提示')
|
||||
return
|
||||
|
||||
is_visible = user32.IsWindowVisible(console_window_handle)
|
||||
show_param = 0 if is_visible else 5 # SW_HIDE SW_SHOW
|
||||
user32.ShowWindowAsync(console_window_handle, show_param)
|
||||
|
||||
@staticmethod
|
||||
def _find_console_window():
|
||||
assert IS_WIN
|
||||
console_window_handle: int = kernel32.GetConsoleWindow()
|
||||
if console_window_handle == 0:
|
||||
return 0
|
||||
# 兼容Windows Terminal,https://github.com/microsoft/terminal/issues/12464
|
||||
while True:
|
||||
parent_window_handle: int = user32.GetParent(console_window_handle)
|
||||
if parent_window_handle == 0:
|
||||
break
|
||||
console_window_handle = parent_window_handle
|
||||
return console_window_handle
|
||||
|
||||
def _on_exit_click(self, _event):
|
||||
assert IS_WIN
|
||||
# 先恢复控制台显示,防止退出后无法恢复
|
||||
console_window_handle = self._find_console_window()
|
||||
if console_window_handle != 0 and not user32.IsWindowVisible(console_window_handle):
|
||||
user32.ShowWindowAsync(console_window_handle, 5) # SW_SHOW
|
||||
|
||||
kernel32.GenerateConsoleCtrlEvent(0, 0) # CTRL_C_EVENT
|
@ -6,7 +6,7 @@ from typing import *
|
||||
|
||||
logger = logging.getLogger('text-to-speech.' + __name__)
|
||||
|
||||
BASE_PATH = os.path.realpath(os.getcwd())
|
||||
BASE_PATH = os.path.dirname(os.path.realpath(__file__))
|
||||
LOG_PATH = os.path.join(BASE_PATH, 'log')
|
||||
DATA_PATH = os.path.join(BASE_PATH, 'data')
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user