From 41ea1b80de03f4c98157d6c29dd817859ea1e94a Mon Sep 17 00:00:00 2001 From: 4aiman Date: Sat, 22 Aug 2026 01:40:43 +0300 Subject: [PATCH] =?UTF-8?q?=D0=9E=D0=B4=D0=B8=D0=BD=20=D1=89=D0=B5=D0=BB?= =?UTF-8?q?=D1=87=D0=BE=D0=BA=20=E2=80=94=20=D0=BE=D0=B4=D0=BD=D0=BE=20?= =?UTF-8?q?=D0=B4=D0=B5=D0=B9=D1=81=D1=82=D0=B2=D0=B8=D0=B5;=20=D0=BA?= =?UTF-8?q?=D0=BD=D0=BE=D0=BF=D0=BA=D0=B8=20=D0=B2=D0=BD=D0=B8=D0=B7=D1=83?= =?UTF-8?q?=20=D0=BF=D1=80=D0=B8=D0=B2=D0=B5=D0=B4=D0=B5=D0=BD=D1=8B=20?= =?UTF-8?q?=D0=B2=20=D0=BF=D0=BE=D1=80=D1=8F=D0=B4=D0=BE=D0=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Главное. Каждый щелчок по нашей кнопке срабатывал дважды. Click вызывает сама LCL при отпускании внутри кнопки — TControl.WMLButtonUp, с той же проверкой «внутри», какую я написал руками в MouseUp. Мой вызов оказывался вторым. На кнопке-переключателе это значит «ничего не произошло»: первое срабатывание меняло состояние, второе возвращало обратно. Свой вызов убран. Найдено на невидимом экране: на один щелчок мышью в журнал легли две записи об одном обработчике, тогда как то же действие с клавиатуры давало одну. После правки три щелчка дают три переключения, а магнит послушно меняет цвет туда и обратно. Второе. Журнал, спрятанный до первого показа окна, не получал своего виджета вовсе, и вернуть его было нечем: свойство переключалось, а на экране ничего не менялось. Теперь состояние применяется на показе окна, когда дескриптор уже есть. Третье. Правка файла формы не сработала молча — строка не совпала, а я это не проверил. Кнопка прилипания осталась широкой, с надписью, и наехала на соседние. Исправлено. Заодно выяснилось, что файл формы пересобирается только вместе со своим модулем: правки одного лишь lfm в двоичный файл не попадают. Значок прилипания переделан в подкову магнита: линия со стрелками смысла не передавала. Переключение журнала добавлено в меню «Вид» и на Ctrl+L. --- icons/snap.svg | 18 ++++++------------ src/uMainForm.lfm | 7 +++++-- src/uMainForm.pas | 25 ++++++++++++++++++++++++- src/uTheme.pas | 39 ++++++++++++++++++++++++--------------- 4 files changed, 59 insertions(+), 30 deletions(-) diff --git a/icons/snap.svg b/icons/snap.svg index 51604bc..1bec0db 100644 --- a/icons/snap.svg +++ b/icons/snap.svg @@ -1,14 +1,8 @@ - - - - - - - - - - + + + + diff --git a/src/uMainForm.lfm b/src/uMainForm.lfm index 2f29898..102cc70 100644 --- a/src/uMainForm.lfm +++ b/src/uMainForm.lfm @@ -49,11 +49,12 @@ object MainForm: TMainForm Left = 290 Height = 28 Top = 6 - Width = 170 + Width = 28 Down = True - Caption = 'Прилипание: вкл' + Icon = tiSnap OnClick = btnSnapClick ShowHint = True + TabStop = False end object btnRipple: TThemedButton Left = 326 @@ -63,6 +64,7 @@ object MainForm: TMainForm Icon = tiRipple OnClick = btnRippleClick ShowHint = True + TabStop = False end object btnRippleMenu: TThemedButton Left = 356 @@ -71,6 +73,7 @@ object MainForm: TMainForm Width = 22 Arrow = True OnClick = btnRippleMenuClick + TabStop = False end object lblStatus: TLabel Left = 428 diff --git a/src/uMainForm.pas b/src/uMainForm.pas index 9aa2e99..834d8d7 100644 --- a/src/uMainForm.pas +++ b/src/uMainForm.pas @@ -211,6 +211,7 @@ type procedure JobTimerTick(Sender: TObject); procedure AdvanceJobBar; procedure LogButtonClick(Sender: TObject); + procedure MenuToggleLog(Sender: TObject); procedure ApplyLogVisible(AVisible: Boolean); procedure BuildTimeline; procedure StartPlayer; @@ -461,7 +462,6 @@ begin pnlVideo.Height := FSettings.VideoPanelHeight; FTimeline.TrackHeight := FSettings.TrackHeight; FTimeline.WaveGain := FSettings.WaveGain; - ApplyLogVisible(FSettings.LogVisible); { Режим схлопывания и его состояние переживают перезапуск. } if FSettings.RippleAllTracks then @@ -626,6 +626,8 @@ begin AddItem(MView, 'Вписать весь проект', @MenuZoomFit, ShortCut(VK_0, [ssCtrl])); AddItem(MView, 'Приблизить', @MenuZoomIn, ShortCut(VK_ADD, [ssCtrl])); AddItem(MView, 'Отдалить', @MenuZoomOut, ShortCut(VK_SUBTRACT, [ssCtrl])); + AddSep(MView); + AddItem(MView, 'Журнал сообщений', @MenuToggleLog, ShortCut(VK_L, [ssCtrl])); MProject := AddTop('Проект'); AddItem(MProject, 'Сведения о проекте...', @MenuProjectInfo); @@ -686,6 +688,9 @@ begin один набор, а не как случайно разбросанные значки. } FLogButton.SetBounds(LogButtonLeft, 6, LogButtonWidth, 28); FLogButton.Icon := tiLog; + { Фокус переключателям не нужен: по ним щёлкают, а обходить их клавишей + Tab при работе с монтажом только мешает. } + FLogButton.TabStop := False; FLogButton.Down := True; FLogButton.OnClick := @LogButtonClick; FLogButton.ShowHint := True; @@ -719,6 +724,11 @@ begin ApplyLogVisible(not memoLog.Visible); end; +procedure TMainForm.MenuToggleLog(Sender: TObject); +begin + ApplyLogVisible(not memoLog.Visible); +end; + procedure TMainForm.ApplyLogVisible(AVisible: Boolean); begin memoLog.Visible := AVisible; @@ -874,6 +884,19 @@ begin Exit; FStarted := True; + { Журнал прячется здесь, а не при чтении настроек. + + Спрятанный до первого показа окна, он не получает своего виджета + вовсе, и вернуть его потом уже нечем: свойство переключается, + а на экране ничего не меняется. Проверено на невидимом экране: + щелчок по кнопке журнала не менял ни пикселя, при том что запись в + журнале показывала Visible=True, высоту 135 и верх 743. + + HandleNeeded — на случай, если до этого места дескриптор всё же не + создан: прятать можно только то, что уже существует. } + memoLog.HandleNeeded; + ApplyLogVisible(FSettings.LogVisible); + { Подложка полосы меню задаётся здесь, а не при создании формы. Она задаётся через SetMenuInfo по дескриптору меню, а тот появляется diff --git a/src/uTheme.pas b/src/uTheme.pas index e68a12e..23af205 100644 --- a/src/uTheme.pas +++ b/src/uTheme.pas @@ -441,13 +441,18 @@ begin case FIcon of tiSnap: begin - { Средняя линия — граница, к которой прилипает край; по бокам - края, притягивающиеся к ней. } - Line(12, 2, 12, 22); - Line(2, 6, 2, 18); - Line(22, 6, 22, 18); - Tri(9, 5, 12, 4); - Tri(15, 19, 12, 4); + { Подкова магнита: дуга сверху, две ноги вниз, полюса закрашены. + Без закрашенных полюсов подкова читается как перевёрнутая + буква U и смысла не передаёт. } + Canvas.Pen.Width := Max(2, Side div 6); + Canvas.Brush.Style := bsClear; + { Дуга по верхней половине окружности с центром в (12,13). } + Canvas.Arc(PX(5), PY(6), PX(19), PY(20), 0, 180 * 16); + Line(5, 13, 5, 19); + Line(19, 13, 19, 19); + Canvas.Pen.Width := 1; + Box(3, 18, 8, 23, True); + Box(16, 18, 21, 23, True); end; tiRipple: begin @@ -651,18 +656,22 @@ end; procedure TThemedButton.MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); -var - WasPressed: Boolean; begin - WasPressed := FPressed; FPressed := False; Invalidate; inherited MouseUp(Button, Shift, X, Y); - { Щелчком считается только отпускание внутри кнопки: увёл курсор в - сторону — значит передумал. } - if WasPressed and (Button = mbLeft) and - PtInRect(ClientRect, Point(X, Y)) then - Click; + + { Click отсюда не вызывается. + + Его вызывает сама LCL при отпускании внутри кнопки — TControl. + WMLButtonUp, с той же проверкой «внутри», какая напрашивается здесь. + Написанный руками вызов оказывался вторым, и каждый щелчок срабатывал + дважды. На кнопке-переключателе это значит «ничего не произошло»: + первое срабатывание меняло состояние, второе возвращало обратно. + + Найдено на невидимом экране: в журнал легли две записи «обработчик + кнопки журнала вызван» на один щелчок мышью, тогда как то же действие + с клавиатуры давало одну. } end; procedure TThemedButton.KeyDown(var Key: Word; Shift: TShiftState);