4 Star 4 Fork 0

睿乐组织 TriMO/伶伦

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
LingLunStudio.py 49.15 KB
一键复制 编辑 原始数据 按行查看 历史
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467
# -*- coding: utf-8 -*-
"""
伶伦 WXGUI
Linglun Studio WxPython GUI
版权所有 © 2024 金羿ELS & 睿乐开发组
Copyright © 2024 EillesWan & TriM Org.
伶伦WXGUI版本(“本项目”)的协议颁发者为 金羿
The Licensor of _Linglun Studio WxPython GUI_("this project") is Eilles Wan.
本项目根据 第一版 汉钰律许可协议(“本协议”)授权。
任何人皆可从以下地址获得本协议副本:https://gitee.com/EillesWan/YulvLicenses。
若非因法律要求或经过了特殊准许,此作品在根据本协议“原样”提供的基础上,不予提供任何形式的担保、任何明示、任何暗示或类似承诺。也就是说,用户将自行承担因此作品的质量或性能问题而产生的全部风险。
详细的准许和限制条款请见原协议文本。
"""
# 伶伦 开发交流群 861684859
# Email TriM-Organization@hotmail.com
# 若需转载或借鉴 许可声明请查看仓库根目录下的 License.md
# BUG退散!BUG退散! BUG退散!BUG退散! BUG retreat! BUG retreat!
# 异常与错误作乱之时 異常、誤りが、困った時は Abnormalities and errors are causing chaos
# 二六字组!万国码合!二六字组!万国码合! グループ!コード#!グループ!コード#! Words combine! Unicode unite!
# 赶快呼叫 程序员!Let's Go! 直ぐに呼びましょプログラマ レッツゴー! Hurry to call the programmer! Let's Go!
# 下面为正文
# 音·创 为梦而创,为爱远航
from dataclasses import dataclass
import os
import random
import wx
# import wx.xrc
import wx.propgrid as pg
import Musicreater.experiment
from utils.io import logger, object_constants, log__init__, TrimLog
from utils.yanlun import yanlun_go, yanlun_fg_colour, yanlun_bg_colour
from utils.settings import WHITE, BLACK
from utils.packdata import enpack_lls_pack, unpack_lls_pack, load_msct_packed_data
import Musicreater
__appname__ = "伶伦"
__version__ = "WXGUI 0.0.0"
__zhver__ = "WX图形界面 预版"
osc = object_constants.ObjectStateConstant(
logging_project_name=__appname__,
logging_project_version=__version__,
logging_exit_exec=lambda sth: wx.MessageDialog(
None,
sth + "\n问题不大吧?有问题拜托请报给开发者!谢谢!",
"崩溃",
wx.YES_DEFAULT | wx.ICON_STOP,
).ShowModal(),
# is_this_a_release=True,
)
# print(osc.exit_execution)
osc.set_console(logger.console)
log__init__(osc, TrimLog.PipManage(True, True, 40), True)
logger.is_logging = True
logger.suffix = ".lls"
logger.is_tips = True
logger.printing = not osc.is_release
yanlun_length = len(yanlun_go)
logger.info("注册“量”并读取内容……")
on_exit_saving = True
MAX_LENGTH = 2200
# Define grid cell dimensions
GRID_WIDTH = 3
GRID_HEIGHT = 10
# Define snap and border thresholds
SNAP_THRESHOLD = 5
BORDER_THRESHOLD = 3
@dataclass
class Rectangle:
x_pos: int
y_pos: int
width_length: int
colour: wx.Colour
note: Musicreater.MineNote
def __init__(self, x, y, width, colour: tuple, note_: Musicreater.MineNote):
self.x_pos = x * GRID_WIDTH
self.y_pos = y * GRID_HEIGHT
self.width_length = width * GRID_WIDTH
self.colour = wx.Colour(colour)
self.note = note_
@classmethod
def from_note(cls, note: Musicreater.MineNote, colour: tuple):
return cls(note.start_tick, note.note_pitch, note.duration, colour, note)
@property
def x(self):
return round(self.x_pos / GRID_WIDTH)
@property
def y(self):
return round(self.y_pos / GRID_HEIGHT)
@property
def width(self):
return round(self.width_length / GRID_WIDTH)
@property
def pos(self):
return wx.Point(round(self.x_pos), round(self.y_pos))
def redefine_pos(self, pos: wx.Point):
self.x_pos = pos.x
self.y_pos = pos.y
# 创建应用程序类
class LinglunStudioApp(wx.App):
def OnInit(self):
# 创建主窗口
self.SetAppName(__appname__)
self.frame = LingLunMainFrame(
None,
)
self.SetTopWindow(self.frame)
self.frame.Show()
return True
logger.info("加载窗口布局……")
class LingLunMainFrame(wx.Frame):
def __init__(self, parent):
wx.Frame.__init__(
self,
parent,
id=wx.ID_ANY,
title=wx.EmptyString,
pos=wx.DefaultPosition,
size=wx.Size(1200, 720),
style=wx.DEFAULT_FRAME_STYLE | wx.TAB_TRAVERSAL,
)
self.SetSizeHints(wx.DefaultSize, wx.DefaultSize)
self.SetFont(
wx.Font(
wx.NORMAL_FONT.GetPointSize(),
wx.FONTFAMILY_DEFAULT,
wx.FONTSTYLE_NORMAL,
wx.FONTWEIGHT_NORMAL,
False,
"OPPOSans R",
)
)
self.SetForegroundColour(wx.SystemSettings.GetColour(wx.SYS_COLOUR_WINDOWTEXT))
self.SetBackgroundColour(wx.SystemSettings.GetColour(wx.SYS_COLOUR_WINDOW))
self.m_statusBar2 = self.CreateStatusBar(1, wx.STB_SIZEGRIP, wx.ID_ANY)
self.m_statusBar2.SetFont(
wx.Font(
wx.NORMAL_FONT.GetPointSize(),
wx.FONTFAMILY_DEFAULT,
wx.FONTSTYLE_NORMAL,
wx.FONTWEIGHT_NORMAL,
False,
"OPPOSans R",
)
)
self.m_menubar1 = wx.MenuBar(0)
self.m_menubar1.SetFont(
wx.Font(
wx.NORMAL_FONT.GetPointSize(),
wx.FONTFAMILY_DEFAULT,
wx.FONTSTYLE_NORMAL,
wx.FONTWEIGHT_NORMAL,
False,
"OPPOSans R",
)
)
self.FileMenu = wx.Menu()
self.m_SaveProj_menuItem9 = wx.MenuItem(
self.FileMenu, wx.ID_ANY, "保存", wx.EmptyString, wx.ITEM_NORMAL
)
self.FileMenu.Append(self.m_SaveProj_menuItem9)
self.FileMenu.AppendSeparator()
self.m_Import_submenu1 = wx.Menu()
self.m_ImportFromMidi_menuItem10 = wx.MenuItem(
self.m_Import_submenu1,
wx.ID_ANY,
"从Midi文件导入",
wx.EmptyString,
wx.ITEM_NORMAL,
)
self.m_Import_submenu1.Append(self.m_ImportFromMidi_menuItem10)
self.FileMenu.AppendSubMenu(self.m_Import_submenu1, "导入…")
self.FileMenu.AppendSeparator()
self.m_ClearSetting_menuItem2 = wx.MenuItem(
self.FileMenu,
wx.ID_ANY,
"重置设置",
"将全部数据设置重置为默认值(下次启动时生效)",
wx.ITEM_CHECK,
)
self.FileMenu.Append(self.m_ClearSetting_menuItem2)
self.m_Exit_menuItem1 = wx.MenuItem(
self.FileMenu, wx.ID_ANY, "退出", "这是退出按钮", wx.ITEM_NORMAL
)
self.FileMenu.Append(self.m_Exit_menuItem1)
self.m_menubar1.Append(self.FileMenu, "文件")
self.AdoptMenu = wx.Menu()
self.play_via_websocket = wx.MenuItem(
self.AdoptMenu,
wx.ID_ANY,
"启用WebSocket服务播放",
"在指定端口上开启WebSocket播放服务器",
wx.ITEM_NORMAL,
)
self.AdoptMenu.Append(self.play_via_websocket)
self.m_Export_menuItem11 = wx.MenuItem(
self.AdoptMenu, wx.ID_ANY, "导出…", wx.EmptyString, wx.ITEM_NORMAL
)
self.AdoptMenu.Append(self.m_Export_menuItem11)
self.m_menubar1.Append(self.AdoptMenu, "接出")
self.AboutMenu = wx.Menu()
self.m_author_info_menuItem4 = wx.MenuItem(
self.AboutMenu, wx.ID_ANY, "作者信息", "查看关于信息", wx.ITEM_NORMAL
)
self.AboutMenu.Append(self.m_author_info_menuItem4)
self.m_menubar1.Append(self.AboutMenu, "关于")
self.SetMenuBar(self.m_menubar1)
m_mainBoxSizer = wx.BoxSizer(wx.VERTICAL)
s_yanLunbarSizer = wx.StaticBoxSizer(
wx.StaticBox(self, wx.ID_ANY, "言·论"), wx.VERTICAL
)
self.yanlun_now = random.randrange(0, yanlun_length)
self.m_LinglunWords_staticText1 = wx.StaticText(
s_yanLunbarSizer.GetStaticBox(),
wx.ID_ANY,
"灵光焕发 深艺献心",
wx.DefaultPosition,
wx.DefaultSize,
wx.ALIGN_CENTER_HORIZONTAL | wx.ST_ELLIPSIZE_MIDDLE | wx.ST_NO_AUTORESIZE,
)
self.m_LinglunWords_staticText1.Wrap(-1)
self.m_LinglunWords_staticText1.SetFont(
wx.Font(
12,
wx.FONTFAMILY_DEFAULT,
wx.FONTSTYLE_NORMAL,
wx.FONTWEIGHT_NORMAL,
False,
"OPPOSans B",
)
)
self.m_LinglunWords_staticText1.SetForegroundColour(
wx.SystemSettings.GetColour(wx.SYS_COLOUR_HIGHLIGHTTEXT)
)
self.m_LinglunWords_staticText1.SetBackgroundColour(
wx.SystemSettings.GetColour(wx.SYS_COLOUR_WINDOWTEXT)
)
s_yanLunbarSizer.Add(self.m_LinglunWords_staticText1, 0, wx.EXPAND, 5)
m_mainBoxSizer.Add(
s_yanLunbarSizer,
0,
wx.ALL | wx.EXPAND | wx.RESERVE_SPACE_EVEN_IF_HIDDEN | wx.TOP,
2,
)
b_MainDCAreaSizer = wx.BoxSizer(wx.HORIZONTAL)
s_TrackSizer = wx.StaticBoxSizer(
wx.StaticBox(self, wx.ID_ANY, "乐器注轨"), wx.VERTICAL
)
b_MainDCAreaSizer.Add(s_TrackSizer, 5, wx.EXPAND, 5)
s_NotesSizer = wx.StaticBoxSizer(
wx.StaticBox(self, wx.ID_ANY, "编辑音符"), wx.VERTICAL
)
self.note_pannel = RectanglePanel(self, [])
s_NotesSizer.Add(self.note_pannel, 1, wx.EXPAND, 5)
b_MainDCAreaSizer.Add(s_NotesSizer, 40, wx.EXPAND, 5)
m_mainBoxSizer.Add(b_MainDCAreaSizer, 1, wx.EXPAND, 5)
self.SetSizer(m_mainBoxSizer)
self.Layout()
self.Centre(wx.BOTH)
# Connect Events
self.Bind(
wx.EVT_MENU,
self.onSaveProjButtonPressed,
id=self.m_SaveProj_menuItem9.GetId(),
)
self.Bind(
wx.EVT_MENU,
self.onImportFromMidiButtonPressed,
id=self.m_ImportFromMidi_menuItem10.GetId(),
)
self.Bind(
wx.EVT_MENU,
self.onResetSettingButtonSelection,
id=self.m_ClearSetting_menuItem2.GetId(),
)
self.Bind(
wx.EVT_MENU, self.onExitButtonPressed, id=self.m_Exit_menuItem1.GetId()
)
self.Bind(
wx.EVT_MENU,
self.onWebSocketPlayButtonPressed,
id=self.play_via_websocket.GetId(),
)
self.Bind(
wx.EVT_MENU, self.onExportButtonPressed, id=self.m_Export_menuItem11.GetId()
)
self.Bind(
wx.EVT_MENU,
self.on_author_button_pressed,
id=self.m_author_info_menuItem4.GetId(),
)
self.m_LinglunWords_staticText1.Bind(
wx.EVT_LEFT_DCLICK, self.onYanlunDoubleClicked
)
self.m_LinglunWords_staticText1.Bind(wx.EVT_MOUSEWHEEL, self.onYanlunWheeled)
def __del__(self):
pass
# Virtual event handlers, override them in your derived class
def onSaveProjButtonPressed(self, event):
event.Skip()
def onImportFromMidiButtonPressed(self, event):
self.OpenMidiFrame = CheckerFrame4OpenMidi(self)
self.OpenMidiFrame.Show()
self.OpenMidiFrame.Bind(wx.EVT_WINDOW_DESTROY, self.onOpenMidiFrameClosed)
event.Skip()
def onOpenMidiFrameClosed(self, event):
self.msq = self.OpenMidiFrame.MsSq
# print(self.msq)
self.colour_map = dict(
[
(
nns,
(
random.randint(0, 255),
random.randint(0, 255),
random.randint(0, 255),
),
)
for nns in self.msq.note_count_per_instrument.keys()
]
)
self.note_pannel.set_rectangles(
[
Rectangle.from_note(note, (self.colour_map[note.sound_name]))
for note in sorted(
[i for j in self.msq.channels.values() for i in j],
key=lambda note: note.start_tick,
)
]
)
# self.note_pannel.on_paint(None)
self.note_pannel.Refresh()
event.Skip()
def onResetSettingButtonSelection(self, event):
global on_exit_saving
if self.m_ClearSetting_menuItem2.IsChecked():
on_exit_saving = False
else:
on_exit_saving = True
def onExitButtonPressed(self, event):
self.Destroy()
def onWebSocketPlayButtonPressed(self, event):
event.Skip()
def onExportButtonPressed(self, event):
event.Skip()
def on_author_button_pressed(self, event):
pass
def onYanlunDoubleClicked(self, event):
self.yanlun_now = random.randrange(0, yanlun_length)
self.m_LinglunWords_staticText1.SetLabelText(
yanlun_go[self.yanlun_now] + "\r"
)
def onYanlunWheeled(self, event):
if event.GetWheelRotation() < 0:
self.yanlun_now += 1
else:
self.yanlun_now -= 1
self.yanlun_now += (
-yanlun_length
if self.yanlun_now >= yanlun_length
else (yanlun_length if self.yanlun_now < 0 else 0)
)
self.m_LinglunWords_staticText1.SetLabelText(
yanlun_go[self.yanlun_now] + "\r"
)
class RectanglePanel(wx.ScrolledWindow):
def __init__(self, parent, rectangles: list):
super().__init__(parent, size=(600, 600))
self.SetBackgroundStyle(wx.BG_STYLE_CUSTOM)
self.Bind(wx.EVT_PAINT, self.on_paint)
self.Bind(wx.EVT_LEFT_DOWN, self.on_left_down)
self.Bind(wx.EVT_LEFT_UP, self.on_left_up)
self.Bind(wx.EVT_MOTION, self.on_mouse_move)
self.Bind(wx.EVT_MOUSEWHEEL, self.on_mouse_wheel)
self.rect_height = GRID_HEIGHT
self.rectangles = rectangles
self.dragging = False
self.resizing = False
self.offset = wx.Point(0, 0)
self.selected_rectangle = None
self.zoom_factor = 1.0
self.SetScrollRate(GRID_WIDTH, GRID_HEIGHT)
self.SetVirtualSize((MAX_LENGTH * GRID_WIDTH, GRID_HEIGHT * 128))
def set_rectangles(self, rectangles: list):
self.rectangles = rectangles
def get_cursor_pos(self, event) -> tuple:
scrolled_x = self.GetScrollPos(wx.HORIZONTAL)
scrolled_y = self.GetScrollPos(wx.VERTICAL)
pos = event.GetPosition()
return (
pos.x / self.zoom_factor + scrolled_x * GRID_WIDTH,
pos.y / self.zoom_factor + scrolled_y * GRID_HEIGHT,
)
def on_paint(self, event):
dc = wx.AutoBufferedPaintDC(self)
self.PrepareDC(dc)
dc.Clear()
self.draw_grid(dc)
self.draw_line_numbers(dc)
self.draw_column_numbers(dc)
self.draw_rectangles(dc)
# scroll_x = self.GetScrollPos(wx.HORIZONTAL)
# scroll_y = self.GetScrollPos(wx.VERTICAL)
# print(f"Horizontal Scroll Position: {scroll_x}")
# print(f"Vertical Scroll Position: {scroll_y}")
def draw_grid(self, dc):
dc.SetPen(wx.Pen(wx.Colour(200, 200, 200), 1, wx.PENSTYLE_SOLID))
width, height = self.GetVirtualSize()
for x in range(0, round(width / self.zoom_factor + 0.5), GRID_WIDTH):
dc.DrawLine(int(x * self.zoom_factor), 0, int(x * self.zoom_factor), height)
for y in range(0, round(height / self.zoom_factor + 0.5), GRID_HEIGHT):
dc.DrawLine(0, int(y * self.zoom_factor), width, int(y * self.zoom_factor))
def draw_rectangles(self, dc):
for rect in self.rectangles:
dc.SetBrush(wx.Brush(rect.colour))
dc.SetPen(
wx.Pen(
rect.colour, width=round(self.zoom_factor), style=wx.PENSTYLE_SOLID
)
)
dc.DrawRectangle(
int(rect.x_pos * self.zoom_factor),
int(rect.y_pos * self.zoom_factor),
int(rect.width_length * self.zoom_factor),
int(self.rect_height * self.zoom_factor),
)
def draw_line_numbers(self, dc):
dc.SetFont(
wx.Font(
10, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL
)
)
dc.SetTextForeground(wx.Colour(0, 0, 0))
for i in range(
0, self.GetVirtualSize()[1] // int(GRID_HEIGHT * self.zoom_factor)
):
dc.DrawText(str(i), 5, round(i * GRID_HEIGHT * self.zoom_factor + 5))
def draw_column_numbers(self, dc):
dc.SetFont(
wx.Font(
10, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL
)
)
dc.SetTextForeground(wx.Colour(0, 0, 0))
for i in range(
0, self.GetVirtualSize()[0] // int(GRID_WIDTH * self.zoom_factor)
):
if i % 5 == 0:
dc.DrawText(str(i), round(i * GRID_WIDTH * self.zoom_factor + 5), 5)
def on_left_down(self, event):
pos = self.get_cursor_pos(event)
for rect in self.rectangles:
rect_right = rect.x_pos + rect.width_length
if (
rect.x_pos <= pos[0] <= rect_right
and rect.y_pos <= pos[1] <= rect.y_pos + self.rect_height
):
if abs(pos[0] - rect_right) <= BORDER_THRESHOLD:
self.resizing = True
else:
self.dragging = True
self.offset = wx.Point(
round(pos[0] - rect.pos.x),
round(pos[1] - rect.pos.y),
)
self.selected_rectangle = rect
break
def on_left_up(self, event):
if self.dragging or self.resizing:
self.dragging = False
self.resizing = False
self.snap_to_grid()
self.Refresh()
self.determin_note()
def on_mouse_move(self, event):
pos = self.get_cursor_pos(event)
if event.Dragging() and event.LeftIsDown():
if self.dragging and self.selected_rectangle:
self.selected_rectangle.x_pos = pos[0] - self.offset.x
self.selected_rectangle.y_pos = pos[1] - self.offset.y
self.apply_snap_effect()
self.Refresh()
elif self.resizing and self.selected_rectangle:
new_width = pos[0] - self.selected_rectangle.x_pos
if new_width >= GRID_WIDTH:
self.selected_rectangle.width_length = new_width
snap_w = round(self.selected_rectangle.width) * GRID_WIDTH
if (
abs(snap_w - self.selected_rectangle.width_length)
<= SNAP_THRESHOLD
):
self.selected_rectangle.width_length = snap_w
self.Refresh()
else:
cursor = wx.Cursor(wx.CURSOR_ARROW)
for rect in self.rectangles:
rect_right = rect.x_pos + rect.width_length
if (
rect.x_pos <= pos[0] <= rect_right
and rect.y_pos <= pos[1] <= rect.y_pos + self.rect_height
):
if abs(pos[0] - rect_right) <= BORDER_THRESHOLD:
cursor = wx.Cursor(wx.CURSOR_SIZEWE)
else:
cursor = wx.Cursor(wx.CURSOR_SIZING)
break
self.SetCursor(cursor)
def apply_snap_effect(self):
if not self.selected_rectangle:
raise ValueError("No rectangle selected")
snap_x = round(self.selected_rectangle.x * GRID_WIDTH)
snap_y = round(self.selected_rectangle.y * GRID_HEIGHT)
dist_x, dist_y = (
snap_x - self.selected_rectangle.x_pos,
snap_y - self.selected_rectangle.y_pos,
)
if abs(dist_x) <= SNAP_THRESHOLD:
self.selected_rectangle.x_pos = snap_x
if abs(dist_y) <= SNAP_THRESHOLD:
self.selected_rectangle.y_pos = snap_y
def snap_to_grid(self):
if not self.selected_rectangle:
raise ValueError("No rectangle selected")
snap_x = round(self.selected_rectangle.x) * GRID_WIDTH
snap_y = round(self.selected_rectangle.y) * GRID_HEIGHT
self.selected_rectangle.redefine_pos(wx.Point(snap_x, snap_y))
def determin_note(self):
if not self.selected_rectangle:
raise ValueError("No rectangle selected")
self.selected_rectangle.note.start_tick = self.selected_rectangle.x
self.selected_rectangle.note.note_pitch = self.selected_rectangle.y
self.selected_rectangle.note.duration = self.selected_rectangle.width
print(
"The rectangle is on pos ({},{}), with width of {}".format(
self.selected_rectangle.x,
self.selected_rectangle.y,
self.selected_rectangle.width,
)
)
def on_mouse_wheel(self, event):
if event.ControlDown():
delta = event.GetWheelRotation()
if delta > 0:
self.zoom_factor *= 1.1
elif delta < 0:
self.zoom_factor /= 1.1
self.SetScrollRate(
round(GRID_WIDTH * self.zoom_factor),
round(GRID_HEIGHT * self.zoom_factor),
)
self.SetVirtualSize(
(
round(MAX_LENGTH * GRID_WIDTH * self.zoom_factor + 0.5),
round(GRID_HEIGHT * 128 * self.zoom_factor + 0.5),
)
)
self.Refresh()
elif event.ShiftDown():
# Handle horizontal scrolling
scroll_x = self.GetScrollPos(wx.HORIZONTAL)
delta_x = (
event.GetWheelRotation() // event.GetWheelDelta()
) # * event.GetLinesPerAction()
self.Scroll(scroll_x - delta_x, -1)
else:
# Handle vertical scrolling
scroll_y = self.GetScrollPos(wx.VERTICAL)
delta_y = (
event.GetWheelRotation() // event.GetWheelDelta()
) # * event.GetLinesPerAction()
self.Scroll(-1, scroll_y - delta_y)
class LLMidiImportMainPanel(wx.Panel):
def __init__(
self,
parent,
id=wx.ID_ANY,
pos=wx.DefaultPosition,
size=wx.Size(714, 704),
style=wx.TAB_TRAVERSAL,
name=wx.EmptyString,
):
wx.Panel.__init__(
self, parent, id=id, pos=pos, size=size, style=style, name=name
)
self.convert_table_selection = {
"PITCHED": "“偷吃”的对照表",
"PERCUSSION": "“偷吃”的对照表",
}
self.convert_tables = {
"PITCHED": {
"“偷吃”的对照表": Musicreater.MM_TOUCH_PITCHED_INSTRUMENT_TABLE,
"“经典”对照表": Musicreater.MM_CLASSIC_PITCHED_INSTRUMENT_TABLE,
"“断联”的对照表": Musicreater.MM_DISLINK_PITCHED_INSTRUMENT_TABLE,
},
"PERCUSSION": {
"“偷吃”的对照表": Musicreater.MM_TOUCH_PERCUSSION_INSTRUMENT_TABLE,
"“经典”对照表": Musicreater.MM_CLASSIC_PERCUSSION_INSTRUMENT_TABLE,
"“断联”的对照表": Musicreater.MM_DISLINK_PERCUSSION_INSTRUMENT_TABLE,
},
}
main_page_sizer = wx.BoxSizer(wx.VERTICAL)
s_MidiBrowseSizer = wx.StaticBoxSizer(
wx.StaticBox(self, wx.ID_ANY, "选择需要导入的Midi文件"), wx.VERTICAL
)
self.m_MidiFilePicker1 = wx.FilePickerCtrl(
s_MidiBrowseSizer.GetStaticBox(),
wx.ID_ANY,
wx.EmptyString,
"选择需要导入的Midi文件",
"Midi数字乐谱 (*.mid;*.midi)|*.mid;*.midi",
wx.DefaultPosition,
wx.DefaultSize,
wx.FLP_FILE_MUST_EXIST | wx.FLP_OPEN | wx.FLP_USE_TEXTCTRL,
)
s_MidiBrowseSizer.Add(self.m_MidiFilePicker1, 0, wx.ALL | wx.EXPAND, 5)
main_page_sizer.Add(s_MidiBrowseSizer, 0, wx.EXPAND, 5)
s_promptSizer = wx.StaticBoxSizer(
wx.StaticBox(self, wx.ID_ANY, "基本参数"), wx.VERTICAL
)
ss_regularPromoptsEnteringSizer1 = wx.BoxSizer(wx.HORIZONTAL)
sss_VolumnPersentageEnteringSizer = wx.StaticBoxSizer(
wx.StaticBox(s_promptSizer.GetStaticBox(), wx.ID_ANY, "最小音量"),
wx.HORIZONTAL,
)
self.m_volumn_slider = wx.Slider(
sss_VolumnPersentageEnteringSizer.GetStaticBox(),
wx.ID_ANY,
1000,
0,
1000,
wx.DefaultPosition,
wx.DefaultSize,
wx.SL_HORIZONTAL,
)
sss_VolumnPersentageEnteringSizer.Add(self.m_volumn_slider, 0, 0, 5)
self.m_volumn_spinCtrlDouble1 = wx.SpinCtrlDouble(
sss_VolumnPersentageEnteringSizer.GetStaticBox(),
wx.ID_ANY,
"0.1",
wx.DefaultPosition,
wx.DefaultSize,
wx.ALIGN_CENTER_HORIZONTAL | wx.SP_ARROW_KEYS | wx.TE_PROCESS_ENTER,
0,
1,
0.100000,
0.001,
)
self.m_volumn_spinCtrlDouble1.SetDigits(3)
sss_VolumnPersentageEnteringSizer.Add(self.m_volumn_spinCtrlDouble1, 0, 0, 5)
ss_regularPromoptsEnteringSizer1.Add(
sss_VolumnPersentageEnteringSizer, 0, wx.EXPAND | wx.RIGHT, 5
)
sss_SpeedEnteringSizer = wx.StaticBoxSizer(
wx.StaticBox(s_promptSizer.GetStaticBox(), wx.ID_ANY, "播放倍速"),
wx.HORIZONTAL,
)
self.m_speed_slider = wx.Slider(
sss_SpeedEnteringSizer.GetStaticBox(),
wx.ID_ANY,
50,
0,
100,
wx.DefaultPosition,
wx.DefaultSize,
wx.SL_HORIZONTAL,
)
sss_SpeedEnteringSizer.Add(self.m_speed_slider, 0, 0, 5)
self.m_speed_spinCtrlDouble = wx.SpinCtrlDouble(
sss_SpeedEnteringSizer.GetStaticBox(),
wx.ID_ANY,
"1",
wx.DefaultPosition,
wx.DefaultSize,
wx.ALIGN_CENTER_HORIZONTAL | wx.SP_ARROW_KEYS | wx.TE_PROCESS_ENTER,
0.01,
10,
1,
0.1,
)
self.m_speed_spinCtrlDouble.SetDigits(2)
sss_SpeedEnteringSizer.Add(self.m_speed_spinCtrlDouble, 0, 0, 5)
ss_regularPromoptsEnteringSizer1.Add(
sss_SpeedEnteringSizer, 0, wx.EXPAND | wx.RIGHT | wx.LEFT, 5
)
sss_DeviationEnteringSizer1 = wx.StaticBoxSizer(
wx.StaticBox(s_promptSizer.GetStaticBox(), wx.ID_ANY, "音调偏移"),
wx.HORIZONTAL,
)
self.m_deviation_slider = wx.Slider(
sss_DeviationEnteringSizer1.GetStaticBox(),
wx.ID_ANY,
0,
-16000,
16000,
wx.DefaultPosition,
wx.DefaultSize,
wx.SL_HORIZONTAL,
)
sss_DeviationEnteringSizer1.Add(self.m_deviation_slider, 0, 0, 5)
self.m_deviation_spinCtrlDouble = wx.SpinCtrlDouble(
sss_DeviationEnteringSizer1.GetStaticBox(),
wx.ID_ANY,
"0.0",
wx.DefaultPosition,
wx.DefaultSize,
wx.ALIGN_CENTER_HORIZONTAL | wx.SP_ARROW_KEYS | wx.TE_PROCESS_ENTER,
-16,
16,
0,
0.001,
)
self.m_deviation_spinCtrlDouble.SetDigits(3)
sss_DeviationEnteringSizer1.Add(self.m_deviation_spinCtrlDouble, 0, 0, 5)
ss_regularPromoptsEnteringSizer1.Add(
sss_DeviationEnteringSizer1, 0, wx.EXPAND | wx.LEFT, 5
)
s_promptSizer.Add(ss_regularPromoptsEnteringSizer1, 0, wx.EXPAND, 5)
main_page_sizer.Add(s_promptSizer, 0, wx.SHAPED | wx.EXPAND, 5)
setting_page_sizer = wx.BoxSizer(wx.VERTICAL)
self.setting_notebook = wx.Notebook(
self,
wx.ID_ANY,
wx.DefaultPosition,
wx.DefaultSize,
wx.NB_FIXEDWIDTH | wx.NB_MULTILINE | wx.NB_RIGHT,
)
self.setting_notebook.SetFont(
wx.Font(
wx.NORMAL_FONT.GetPointSize(),
wx.FONTFAMILY_DEFAULT,
wx.FONTSTYLE_NORMAL,
wx.FONTWEIGHT_NORMAL,
False,
"@OPPOSans R",
)
)
self.setting_notebook.SetBackgroundColour(
wx.SystemSettings.GetColour(wx.SYS_COLOUR_WINDOW)
)
self.setting_page_pitched_inst = wx.Panel(
self.setting_notebook,
wx.ID_ANY,
wx.DefaultPosition,
wx.DefaultSize,
wx.TAB_TRAVERSAL,
)
self.setting_page_pitched_inst.SetFont(
wx.Font(
wx.NORMAL_FONT.GetPointSize(),
wx.FONTFAMILY_DEFAULT,
wx.FONTSTYLE_NORMAL,
wx.FONTWEIGHT_NORMAL,
False,
wx.EmptyString,
)
)
setting_page2_box_sizer = wx.BoxSizer(wx.VERTICAL)
self.m_pitched_instrument_table_choice = wx.Choice(
self.setting_page_pitched_inst,
wx.ID_ANY,
wx.DefaultPosition,
wx.DefaultSize,
list(self.convert_tables["PITCHED"].keys()),
0,
)
self.m_pitched_instrument_table_choice.SetSelection(
list(self.convert_tables["PITCHED"].keys()).index(
self.convert_table_selection["PITCHED"]
)
)
self.m_pitched_instrument_table_choice.SetFont(
wx.Font(
wx.NORMAL_FONT.GetPointSize(),
wx.FONTFAMILY_DEFAULT,
wx.FONTSTYLE_NORMAL,
wx.FONTWEIGHT_NORMAL,
False,
"OPPOSans R",
)
)
setting_page2_box_sizer.Add(
self.m_pitched_instrument_table_choice, 0, wx.ALL | wx.EXPAND, 5
)
self.m_pitched_notes_table_propertyGrid1 = pg.PropertyGrid(
self.setting_page_pitched_inst,
wx.ID_ANY,
wx.DefaultPosition,
wx.DefaultSize,
pg.PG_BOLD_MODIFIED | pg.PG_HIDE_MARGIN | pg.PG_SPLITTER_AUTO_CENTER,
)
self.m_pitched_notes_table_propertyGrid1.SetFont(
wx.Font(
wx.NORMAL_FONT.GetPointSize(),
wx.FONTFAMILY_DEFAULT,
wx.FONTSTYLE_NORMAL,
wx.FONTWEIGHT_NORMAL,
False,
"OPPOSans R",
)
)
for midi_inst, mc_inst_patern in self.convert_tables["PITCHED"][
self.convert_table_selection["PITCHED"]
].items():
self.m_pitched_notes_table_propertyGrid1.Append(
pg.StringProperty(
Musicreater.MIDI_PITCHED_NOTE_NAME_TABLE[midi_inst + 1][0],
"pitched_inst_{}".format(midi_inst),
mc_inst_patern,
)
)
setting_page2_box_sizer.Add(
self.m_pitched_notes_table_propertyGrid1, 1, wx.ALL | wx.EXPAND, 5
)
self.setting_page_pitched_inst.SetSizer(setting_page2_box_sizer)
self.setting_page_pitched_inst.Layout()
setting_page2_box_sizer.Fit(self.setting_page_pitched_inst)
self.setting_notebook.AddPage(
self.setting_page_pitched_inst, "乐音乐器对照表", True
)
self.setting_page_perc_inst = wx.Panel(
self.setting_notebook,
wx.ID_ANY,
wx.DefaultPosition,
wx.DefaultSize,
wx.TAB_TRAVERSAL,
)
setting_page3_box_sizer = wx.BoxSizer(wx.VERTICAL)
self.m_percussion_instrument_table_choice1 = wx.Choice(
self.setting_page_perc_inst,
wx.ID_ANY,
wx.DefaultPosition,
wx.DefaultSize,
list(self.convert_tables["PERCUSSION"].keys()),
0,
)
self.m_percussion_instrument_table_choice1.SetSelection(
list(self.convert_tables["PERCUSSION"].keys()).index(
self.convert_table_selection["PERCUSSION"]
)
)
self.m_percussion_instrument_table_choice1.SetFont(
wx.Font(
wx.NORMAL_FONT.GetPointSize(),
wx.FONTFAMILY_DEFAULT,
wx.FONTSTYLE_NORMAL,
wx.FONTWEIGHT_NORMAL,
False,
"OPPOSans R",
)
)
setting_page3_box_sizer.Add(
self.m_percussion_instrument_table_choice1, 0, wx.ALL | wx.EXPAND, 5
)
self.m_percussion_notes_table_propertyGrid11 = pg.PropertyGrid(
self.setting_page_perc_inst,
wx.ID_ANY,
wx.DefaultPosition,
wx.DefaultSize,
pg.PG_BOLD_MODIFIED | pg.PG_HIDE_MARGIN | pg.PG_SPLITTER_AUTO_CENTER,
)
self.m_percussion_notes_table_propertyGrid11.SetFont(
wx.Font(
wx.NORMAL_FONT.GetPointSize(),
wx.FONTFAMILY_DEFAULT,
wx.FONTSTYLE_NORMAL,
wx.FONTWEIGHT_NORMAL,
False,
"OPPOSans R",
)
)
for midi_inst, mc_inst_patern in self.convert_tables["PERCUSSION"][
self.convert_table_selection["PERCUSSION"]
].items():
self.m_percussion_notes_table_propertyGrid11.Append(
pg.StringProperty(
Musicreater.MIDI_PERCUSSION_NOTE_NAME_TABLE[midi_inst + 1][0],
"percussion_inst_{}".format(midi_inst),
mc_inst_patern,
)
)
setting_page3_box_sizer.Add(
self.m_percussion_notes_table_propertyGrid11, 1, wx.ALL | wx.EXPAND, 5
)
self.setting_page_perc_inst.SetSizer(setting_page3_box_sizer)
self.setting_page_perc_inst.Layout()
setting_page3_box_sizer.Fit(self.setting_page_perc_inst)
self.setting_notebook.AddPage(
self.setting_page_perc_inst, "打击乐器对照表", False
)
self.setting_page_advanced = wx.Panel(
self.setting_notebook,
wx.ID_ANY,
wx.DefaultPosition,
wx.DefaultSize,
wx.TAB_TRAVERSAL,
)
self.setting_page_advanced.SetFont(
wx.Font(
wx.NORMAL_FONT.GetPointSize(),
wx.FONTFAMILY_DEFAULT,
wx.FONTSTYLE_NORMAL,
wx.FONTWEIGHT_NORMAL,
False,
"OPPOSans R",
)
)
setting_page1_box_sizer = wx.BoxSizer(wx.VERTICAL)
ss_distancefuncChooseSizer = wx.StaticBoxSizer(
wx.StaticBox(self.setting_page_advanced, wx.ID_ANY, "选择音距处理曲线"),
wx.VERTICAL,
)
self.m_distancefuncChoice_choice_Choices = {
"自然拟合线": Musicreater.natural_curve,
"线性直线": Musicreater.straight_line,
}
self.m_distancefuncChoice_choice = wx.Choice(
ss_distancefuncChooseSizer.GetStaticBox(),
wx.ID_ANY,
wx.DefaultPosition,
wx.DefaultSize,
list(self.m_distancefuncChoice_choice_Choices.keys()),
0,
)
self.m_distancefuncChoice_choice.SetSelection(0)
ss_distancefuncChooseSizer.Add(
self.m_distancefuncChoice_choice, 0, wx.ALL | wx.EXPAND, 5
)
setting_page1_box_sizer.Add(
ss_distancefuncChooseSizer, 0, wx.ALL | wx.EXPAND, 5
)
setting_page1_experiment_style = wx.StaticBoxSizer(
wx.StaticBox(self.setting_page_advanced, wx.ID_ANY, "实验性转换功能"),
wx.HORIZONTAL,
)
self.m_enable_experiment_checkBox = wx.CheckBox(
setting_page1_experiment_style.GetStaticBox(),
wx.ID_ANY,
"启用实验性功能",
wx.DefaultPosition,
wx.DefaultSize,
0,
)
setting_page1_experiment_style.Add(
self.m_enable_experiment_checkBox, 1, wx.ALL | wx.EXPAND, 5
)
self.experiment_type_choiceChoices: Musicreater.Dict[str, Musicreater.MusicSequence] = { # type: ignore
"常规转换": Musicreater.MusicSequence,
"长音插值": Musicreater.experiment.FutureMidiConvertM4,
"同刻偏移": Musicreater.experiment.FutureMidiConvertM5,
}
self.experiment_type_choice = wx.Choice(
setting_page1_experiment_style.GetStaticBox(),
wx.ID_ANY,
wx.DefaultPosition,
wx.DefaultSize,
list(self.experiment_type_choiceChoices.keys()),
0,
)
self.experiment_type_choice.SetSelection(0)
setting_page1_experiment_style.Add(
self.experiment_type_choice, 2, wx.ALL | wx.EXPAND, 5
)
self.m_ignore_midi_error_checkBox = wx.CheckBox(
setting_page1_experiment_style.GetStaticBox(),
wx.ID_ANY,
"忽略MIDI错误",
wx.DefaultPosition,
wx.DefaultSize,
0,
)
self.m_ignore_midi_error_checkBox.SetValue(True)
setting_page1_experiment_style.Add(
self.m_ignore_midi_error_checkBox, 1, wx.ALL, 5
)
setting_page1_box_sizer.Add(
setting_page1_experiment_style, 0, wx.ALL | wx.EXPAND, 5
)
self.setting_page_advanced.SetSizer(setting_page1_box_sizer)
self.setting_page_advanced.Layout()
setting_page1_box_sizer.Fit(self.setting_page_advanced)
self.setting_notebook.AddPage(self.setting_page_advanced, "高级设置", False)
setting_page_sizer.Add(self.setting_notebook, 1, wx.EXPAND | wx.ALL, 5)
main_page_sizer.Add(setting_page_sizer, 8, wx.EXPAND, 5)
self.SetSizer(main_page_sizer)
self.Layout()
# Connect Events
self.m_volumn_slider.Bind(wx.EVT_SCROLL, self.onVolumeScrolling)
self.m_volumn_spinCtrlDouble1.Bind(
wx.EVT_SPINCTRLDOUBLE, self.onVolumeSpinChanged
)
self.m_speed_slider.Bind(wx.EVT_SCROLL, self.onSpeedScrolling)
self.m_speed_spinCtrlDouble.Bind(wx.EVT_SPINCTRLDOUBLE, self.onSpeedSpinChanged)
self.m_deviation_slider.Bind(wx.EVT_SCROLL, self.onDeviationScrolling)
self.m_deviation_spinCtrlDouble.Bind(
wx.EVT_SPINCTRLDOUBLE, self.onDeviationSpinChanged
)
self.m_pitched_instrument_table_choice.Bind(
wx.EVT_CHOICE, self.onPitchedInstListChanging
)
self.m_pitched_notes_table_propertyGrid1.Bind(
pg.EVT_PG_CHANGED, self.onPitchedInstTableChanged
)
self.m_pitched_notes_table_propertyGrid1.Bind(
pg.EVT_PG_CHANGING, self.onPitchedInstTableChanging
)
self.m_percussion_instrument_table_choice1.Bind(
wx.EVT_CHOICE, self.onPercussionInstListChanging
)
self.m_percussion_notes_table_propertyGrid11.Bind(
pg.EVT_PG_CHANGED, self.onPercussionInstTableChanged
)
self.m_percussion_notes_table_propertyGrid11.Bind(
pg.EVT_PG_CHANGING, self.onPercussionInstTableChanging
)
self.m_distancefuncChoice_choice.Bind(wx.EVT_CHOICE, self.onDistanceFuncChosen)
self.m_enable_experiment_checkBox.Bind(
wx.EVT_CHECKBOX, self.onExperimentEnableUpdating
)
self.experiment_type_choice.Bind(wx.EVT_CHOICE, self.onConvertMethodUpdating)
self.m_ignore_midi_error_checkBox.Bind(
wx.EVT_CHECKBOX, self.onMidiFaultIgnoranceChecking
)
def __del__(self):
pass
# Virtual event handlers, override them in your derived class
def onVolumeScrolling(self, event):
# prt(self.m_volumn_slider.Value)
self.m_volumn_spinCtrlDouble1.SetValue(self.m_volumn_slider.Value / 1000)
def onVolumeSpinChanged(self, event):
# prt(self.m_volumn_spinCtrlDouble1.Value)
self.m_volumn_slider.SetValue(int(self.m_volumn_spinCtrlDouble1.Value * 1000))
def onSpeedScrolling(self, event):
# prt(self.m_speed_slider.Value)
if self.m_speed_slider.Value > 50:
self.m_speed_spinCtrlDouble.SetValue(
(self.m_speed_slider.Value * 9 - 400) / 50
)
else:
self.m_speed_spinCtrlDouble.SetValue(
(self.m_speed_slider.Value * 99 + 50) / 5000
)
def onSpeedSpinChanged(self, event):
if self.m_speed_spinCtrlDouble.Value > 1:
self.m_speed_slider.SetValue(
int((self.m_speed_spinCtrlDouble.Value + 8) * 50 / 9)
)
else:
self.m_speed_slider.SetValue(
int((self.m_speed_spinCtrlDouble.Value - 0.01) * 5000 / 99)
)
def onDeviationScrolling(self, event):
self.m_deviation_spinCtrlDouble.SetValue(self.m_volumn_slider.Value / 1000)
def onDeviationSpinChanged(self, event):
self.m_deviation_slider.SetValue(
int(self.m_deviation_spinCtrlDouble.Value * 1000)
)
def onPitchedInstListChanging(self, event):
self.convert_table_selection["PITCHED"] = (
self.m_pitched_instrument_table_choice.GetStringSelection()
)
self.m_pitched_notes_table_propertyGrid1.SetPropertyValues(
dict(
[
("pitched_inst_{}".format(midi_inst), mc_inst_patern)
for midi_inst, mc_inst_patern in self.convert_tables["PITCHED"][
self.convert_table_selection["PITCHED"]
].items()
]
)
)
event.Skip()
def onPitchedInstTableChanged(self, event):
self.convert_tables["PITCHED"]["自定义对照表"] = dict(
[
(i, j)
for i, j in self.convert_tables["PITCHED"][
self.convert_table_selection["PITCHED"]
].items()
]
)
self.convert_table_selection["PITCHED"] = "自定义对照表"
to_change_id = int(event.GetProperty().GetName().split("_")[-1])
to_change_value = (
event.GetProperty().GetValue()
# Musicreater.MM_INSTRUMENT_DEVIATION_TABLE.get(
# event.GetProperty().GetValue(), -1
# ),
)
self.convert_tables["PITCHED"]["自定义对照表"][to_change_id] = to_change_value
logger.info(
"自定义乐音乐器对照表第 {} 项已更新为:{}".format(
to_change_id, to_change_value
)
)
if "自定义对照表" not in self.m_pitched_instrument_table_choice.Items:
self.m_pitched_instrument_table_choice.Append("自定义对照表")
self.m_pitched_instrument_table_choice.SetSelection(2)
event.Skip()
def onPitchedInstTableChanging(self, event):
event.Skip()
def onPercussionInstListChanging(self, event):
self.convert_table_selection["PERCUSSION"] = (
self.m_percussion_instrument_table_choice1.GetStringSelection()
)
self.m_percussion_notes_table_propertyGrid11.SetPropertyValues(
dict(
[
("percussion_inst_{}".format(midi_inst), mc_inst_patern)
for midi_inst, mc_inst_patern in self.convert_tables["PERCUSSION"][
self.convert_table_selection["PERCUSSION"]
].items()
]
)
)
event.Skip()
def onPercussionInstTableChanged(self, event):
self.convert_tables["PERCUSSION"]["自定义对照表"] = dict(
[
(i, j)
for i, j in self.convert_tables["PERCUSSION"][
self.convert_table_selection["PERCUSSION"]
].items()
]
)
self.convert_table_selection["PERCUSSION"] = "自定义对照表"
to_change_id = int(event.GetProperty().GetName().split("_")[-1])
to_change_value = (
event.GetProperty().GetValue()
# Musicreater.MM_INSTRUMENT_DEVIATION_TABLE.get(
# event.GetProperty().GetValue(), -1
# ),
)
self.convert_tables["PERCUSSION"]["自定义对照表"][
to_change_id
] = to_change_value
logger.info(
"自定义打击乐器对照表第 {} 项已更新为:{}".format(
to_change_id, to_change_value
)
)
if "自定义对照表" not in self.m_percussion_instrument_table_choice1.Items:
self.m_percussion_instrument_table_choice1.Append("自定义对照表")
self.m_percussion_instrument_table_choice1.SetSelection(2)
event.Skip()
def onPercussionInstTableChanging(self, event):
event.Skip()
def onDistanceFuncChosen(self, event):
event.Skip()
def onExperimentEnableUpdating(self, event):
if self.m_enable_experiment_checkBox.GetValue():
self.m_ignore_midi_error_checkBox.Enable(True)
self.experiment_type_choice.Enable(True)
else:
self.m_ignore_midi_error_checkBox.Enable(False)
self.experiment_type_choice.Enable(False)
event.Skip()
def onConvertMethodUpdating(self, event):
# 0 "常规转换", 1 "长音插值", 2 "同刻偏移"
# match self.experiment_type_choice.GetSelection():
event.Skip()
def onMidiFaultIgnoranceChecking(self, event):
event.Skip()
class CheckerFrame4OpenMidi(wx.Frame):
def __init__(self, parent):
wx.Frame.__init__(
self,
parent,
id=wx.ID_ANY,
title="确认",
pos=wx.DefaultPosition,
size=wx.Size(750, 860),
style=wx.CAPTION
| wx.CLOSE_BOX
| wx.MINIMIZE_BOX
| wx.SYSTEM_MENU
| wx.TAB_TRAVERSAL,
)
self.SetSizeHints(wx.DefaultSize, wx.DefaultSize)
mainSizer1 = wx.BoxSizer(wx.VERTICAL)
self.m_panel2 = LLMidiImportMainPanel(self)
mainSizer1.Add(self.m_panel2, 8, wx.EXPAND | wx.ALL, 5)
m_check_sdbSizer1 = wx.StdDialogButtonSizer()
self.m_check_sdbSizer1OK = wx.Button(self, wx.ID_OK)
m_check_sdbSizer1.AddButton(self.m_check_sdbSizer1OK)
self.m_check_sdbSizer1Cancel = wx.Button(self, wx.ID_CANCEL)
m_check_sdbSizer1.AddButton(self.m_check_sdbSizer1Cancel)
m_check_sdbSizer1.Realize()
mainSizer1.Add(m_check_sdbSizer1, 1, wx.EXPAND, 5)
self.SetSizer(mainSizer1)
self.Layout()
self.Centre(wx.BOTH)
# Connect Events
self.m_check_sdbSizer1Cancel.Bind(wx.EVT_BUTTON, self.onCancelPressed)
self.m_check_sdbSizer1OK.Bind(wx.EVT_BUTTON, self.onOKpressed)
def __del__(self):
pass
# Virtual event handlers, override them in your derived class
def onCancelPressed(self, event):
self.MsSq = Musicreater.MusicSequence(
"",
dict(),
)
self.Destroy()
event.Skip()
def onOKpressed(self, event):
# self.m_panel2.m_MidiFilePicker1.GetTextCtrl().GetValue()
self.MsSq = list(self.m_panel2.experiment_type_choiceChoices.values())[
self.m_panel2.experiment_type_choice.GetSelection()
].from_mido(
mido_file=Musicreater.mido.MidiFile(
self.m_panel2.m_MidiFilePicker1.GetTextCtrl().GetValue()
),
midi_music_name=os.path.splitext(
os.path.basename(
self.m_panel2.m_MidiFilePicker1.GetTextCtrl().GetValue()
)
)[0].replace(" ", "_"),
mismatch_error_ignorance=self.m_panel2.m_ignore_midi_error_checkBox.GetValue(),
speed_multiplier=self.m_panel2.m_speed_spinCtrlDouble.GetValue(),
pitched_note_referance_table=self.m_panel2.convert_tables["PITCHED"][
self.m_panel2.convert_table_selection["PITCHED"]
],
percussion_note_referance_table=self.m_panel2.convert_tables["PERCUSSION"][
self.m_panel2.convert_table_selection["PERCUSSION"]
],
minimum_vol=self.m_panel2.m_volumn_spinCtrlDouble1.GetValue(),
volume_processing_function=list(
self.m_panel2.m_distancefuncChoice_choice_Choices.values()
)[self.m_panel2.m_distancefuncChoice_choice.GetSelection()],
)
self.Destroy()
event.Skip()
logger.info("执行应用。")
# 启动应用程序
if __name__ == "__main__":
logger.info("开启窗口")
app = LinglunStudioApp()
app.MainLoop()
if on_exit_saving:
pass
else:
for path, dir_list, file_list in os.walk(r"./"):
for file_name in file_list:
if file_name.endswith(".lls.config"):
os.remove(
os.path.join(path, file_name),
)
# input("按下回车退出……")
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
Python
1
https://gitee.com/TriM-Organization/LinglunStudio.git
git@gitee.com:TriM-Organization/LinglunStudio.git
TriM-Organization
LinglunStudio
伶伦
master

搜索帮助