mirror of
https://git.vladimir.cc/vladimir/ewsdr.git
synced 2026-08-25 19:45:09 +00:00
feat(slices): кастомные тематизированные popup-меню панов + фиксы позиционирования
Селекторы диапазона/samplerate панов N переведены с нативного TPopupMenu на своё меню в стиле приложения (одинаково на всех платформах, в цветовой теме). - FlatPopupMenu.pas (new): TFlatPopupMenu — owner-draw меню как ДОЧЕРНИЙ контрол формы (не top-level окно: Wayland центрирует свои top-level окна). Hover, галка текущего, клавиатура (↑↓/Enter/Esc), закрытие по клику-вне (MouseCapture) и потере фокуса. Позиционируется под лейблом-якорем в клиентских координатах. - PanDisplayPopup: поповер «◑» тоже переведён с top-level формы на дочерний контрол (центрировался на Wayland) — открывается под кнопкой, закрытие «×» или повторным «◑». - MainForm: band/rate-селекторы на FlatPopupMenu; свёртка повторяющегося выбора темы (9 инлайнов) в CurrentAppTheme. - PanafallPanel: курсор-«палец» кликабельных лейблов шапки переприменяется в конце Build (флаги *Clickable могли выставляться до создания лейблов — samplerate-лейбл не получал crHandPoint). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
+47
-30
@@ -8,7 +8,10 @@ unit PanDisplayPopup;
|
||||
зеркалит глобальные (для пана 0). Кнопки «Сброс к дефолту» / «Применить ко
|
||||
всем» — через OnResetDefault / OnApplyAll.
|
||||
|
||||
Форма без рамки, поверх всех, гаснет по потере фокуса (OnDeactivate).
|
||||
Реализован как ДОЧЕРНИЙ контрол верхнеуровневой формы (не отдельное окно):
|
||||
Wayland не даёт клиенту позиционировать свои top-level окна — они
|
||||
центрируются компоновщиком. Дочерний контрол позиционируется в клиентских
|
||||
координатах под кнопкой «◑». Закрытие — крестиком «×» или повторным «◑».
|
||||
Этап 3.6 плана мультислайсов (doc/SLICES_PLAN.md), per-pan дисплей.
|
||||
}
|
||||
|
||||
@@ -19,7 +22,7 @@ unit PanDisplayPopup;
|
||||
interface
|
||||
|
||||
uses
|
||||
Classes, SysUtils, Math, Controls, ExtCtrls, StdCtrls, Graphics, Forms,
|
||||
Classes, SysUtils, Math, Types, Controls, ExtCtrls, StdCtrls, Graphics, Forms,
|
||||
AppTheme, PanafallPanel,
|
||||
FlatButton, FlatComboBox, FlatCheckBox, FlatSpinEdit, FlatFloatSpinEdit;
|
||||
|
||||
@@ -28,7 +31,7 @@ type
|
||||
// FullRefresh=True ⇒ смена палитры/gamma/авто: чистим историю водопада.
|
||||
TPanDisplayApplyEvent = procedure(P: TPanafallPanel; FullRefresh: Boolean) of object;
|
||||
|
||||
TPanDisplayPopup = class(TForm)
|
||||
TPanDisplayPopup = class(TCustomControl)
|
||||
private
|
||||
FPan: TPanafallPanel; // пан, чьи настройки правим (не владеем)
|
||||
FLoading: Boolean; // подавляет OnApplied при программной заливке
|
||||
@@ -61,13 +64,14 @@ type
|
||||
procedure CloseClick(Sender: TObject);
|
||||
procedure ResetClick(Sender: TObject);
|
||||
procedure AllClick(Sender: TObject);
|
||||
procedure DoDeactivate(Sender: TObject);
|
||||
procedure UpdateWfRowEnable;
|
||||
protected
|
||||
procedure Paint; override;
|
||||
public
|
||||
constructor CreateNew(AOwner: TComponent; Num: Integer = 0); override;
|
||||
constructor Create(AOwner: TComponent); override;
|
||||
procedure LoadFrom(P: TPanafallPanel);
|
||||
// Показать под кнопкой (экранные координаты левого-нижнего угла кнопки).
|
||||
procedure ShowFor(P: TPanafallPanel; ScreenX, ScreenY: Integer);
|
||||
// Показать под контролом-якорем (кнопкой «◑») как дочерний контрол формы.
|
||||
procedure PopupBelow(P: TPanafallPanel; Anchor: TControl);
|
||||
property OnApplied: TPanDisplayApplyEvent read FOnApplied write FOnApplied;
|
||||
property OnResetDefault: TPanDisplayEvent read FOnResetDefault write FOnResetDefault;
|
||||
property OnApplyAll: TPanDisplayEvent read FOnApplyAll write FOnApplyAll;
|
||||
@@ -97,7 +101,7 @@ const
|
||||
|
||||
WF_PALETTE_NAMES: array[0..2] of string = ('Classic', 'Inferno', 'Turbo');
|
||||
|
||||
constructor TPanDisplayPopup.CreateNew(AOwner: TComponent; Num: Integer);
|
||||
constructor TPanDisplayPopup.Create(AOwner: TComponent);
|
||||
var
|
||||
Y: Integer;
|
||||
|
||||
@@ -123,14 +127,13 @@ var
|
||||
end;
|
||||
|
||||
begin
|
||||
inherited CreateNew(AOwner, Num);
|
||||
BorderStyle := bsNone;
|
||||
FormStyle := fsStayOnTop;
|
||||
inherited Create(AOwner);
|
||||
ControlStyle := ControlStyle + [csOpaque];
|
||||
Visible := False;
|
||||
Color := CLR_BG;
|
||||
Font.Name := UI_FONT;
|
||||
Font.Size := 9;
|
||||
Font.Color := CLR_TEXT;
|
||||
OnDeactivate := DoDeactivate;
|
||||
FLoading := False;
|
||||
|
||||
FBg := TPanel.Create(Self);
|
||||
@@ -235,9 +238,18 @@ begin
|
||||
FBtnAll.ClrTextAct := CLR_ACCENT;
|
||||
Inc(Y, ROWH + PAD);
|
||||
|
||||
FBg.Height := Y - 1;
|
||||
ClientWidth := POP_W;
|
||||
ClientHeight := Y + 1;
|
||||
FBg.Height := Y - 1;
|
||||
Width := POP_W;
|
||||
Height := Y + 1;
|
||||
end;
|
||||
|
||||
procedure TPanDisplayPopup.Paint;
|
||||
begin
|
||||
// 1px рамка вокруг FBg (FBg = CLR_PANEL перекрывает нутро).
|
||||
Canvas.Brush.Style := bsSolid;
|
||||
Canvas.Brush.Color := CLR_BG;
|
||||
Canvas.Pen.Style := psClear;
|
||||
Canvas.FillRect(0, 0, Width, Height);
|
||||
end;
|
||||
|
||||
function TPanDisplayPopup.MakeLbl(const Cap: string; ALeft, ATop, AW: Integer): TLabel;
|
||||
@@ -334,24 +346,29 @@ begin
|
||||
FOnApplyAll(FPan);
|
||||
end;
|
||||
|
||||
procedure TPanDisplayPopup.DoDeactivate(Sender: TObject);
|
||||
begin
|
||||
Hide;
|
||||
end;
|
||||
|
||||
procedure TPanDisplayPopup.ShowFor(P: TPanafallPanel; ScreenX, ScreenY: Integer);
|
||||
var L, T: Integer;
|
||||
procedure TPanDisplayPopup.PopupBelow(P: TPanafallPanel; Anchor: TControl);
|
||||
var
|
||||
Root: TCustomForm;
|
||||
L, T: Integer;
|
||||
Cl: TPoint;
|
||||
begin
|
||||
if Anchor = nil then Exit;
|
||||
Root := GetParentForm(Anchor);
|
||||
if Root = nil then Exit;
|
||||
LoadFrom(P);
|
||||
L := ScreenX;
|
||||
T := ScreenY;
|
||||
// Кламп в экран.
|
||||
if L + Width > Screen.Width then L := Screen.Width - Width - 4;
|
||||
if L < 0 then L := 4;
|
||||
if T + Height > Screen.Height then T := ScreenY - Height - 4; // раскрыть вверх
|
||||
if T < 0 then T := 4;
|
||||
// Позиция под якорем в КЛИЕНТСКИХ координатах формы (не top-level окно!).
|
||||
Cl := Root.ScreenToClient(Anchor.ClientToScreen(Point(0, Anchor.Height + 2)));
|
||||
L := Cl.X;
|
||||
T := Cl.Y;
|
||||
if L + Width > Root.ClientWidth then L := Root.ClientWidth - Width;
|
||||
if L < 0 then L := 0;
|
||||
if T + Height > Root.ClientHeight then
|
||||
T := Root.ScreenToClient(Anchor.ClientToScreen(Point(0, 0))).Y - Height; // вверх
|
||||
if T < 0 then T := 0;
|
||||
Parent := Root;
|
||||
SetBounds(L, T, Width, Height);
|
||||
Show;
|
||||
Visible := True;
|
||||
BringToFront;
|
||||
end;
|
||||
|
||||
end.
|
||||
|
||||
Reference in New Issue
Block a user