Inhaltsverzeichnis
Arhitektura kontrola
Arhitektura i obrasci za WvdS UI Controls.
Pregled
Sve WvdS Controls prate Properties/ViewInfo/Control Pattern (WPF-inspiriran):
TWvdSDependencyObject
└── TWvdSFrameworkElement
└── TWvdSControl
└── TWvdS{ControlName}
Hijerarhija klasa
TWvdSDependencyObject
Baza za sve objekte s Dependency Properties.
TWvdSDependencyObject = class private FPropertyValues: TDictionary<string, TValue>; public function GetValue(AProperty: TWvdSDependencyProperty): TValue; procedure SetValue(AProperty: TWvdSDependencyProperty; AValue: TValue); procedure ClearValue(AProperty: TWvdSDependencyProperty); end;
TWvdSFrameworkElement
Proširuje s layoutom i vizualnim svojstvima.
TWvdSFrameworkElement = class(TWvdSDependencyObject) private FWidth, FHeight: Double; FMinWidth, FMinHeight: Double; FMaxWidth, FMaxHeight: Double; FMargin, FPadding: TWvdSThickness; FHorizontalAlignment: TWvdSHorizontalAlignment; FVerticalAlignment: TWvdSVerticalAlignment; public function MeasureOverride(AAvailableSize: TWvdSSize): TWvdSSize; virtual; function ArrangeOverride(AFinalSize: TWvdSSize): TWvdSSize; virtual; procedure Render(ASurface: TWvdSRenderSurface); virtual; abstract; end;
TWvdSControl
Baza za sve interaktivne kontrole.
TWvdSControl = class(TWvdSFrameworkElement) private FIsEnabled: Boolean; FIsFocused: Boolean; FTabIndex: Integer; FTemplate: TWvdSControlTemplate; FViewInfo: TWvdSViewInfo; public property IsEnabled: Boolean read FIsEnabled write SetIsEnabled; property IsFocused: Boolean read FIsFocused; property TabIndex: Integer read FTabIndex write FTabIndex; property Template: TWvdSControlTemplate read FTemplate write FTemplate; property ViewInfo: TWvdSViewInfo read FViewInfo; procedure OnGotFocus; virtual; procedure OnLostFocus; virtual; procedure OnKeyDown(AEvent: TWvdSKeyEventArgs); virtual; procedure OnMouseDown(AEvent: TWvdSMouseEventArgs); virtual; end;
Properties/ViewInfo/Control Pattern
Troslojna arhitektura
┌─────────────────────────────────────────────────┐ │ Properties Layer │ │ - Javni API (Properties, Events) │ │ - Dependency Properties │ │ - Bindable, PXAML-kompatibilno │ ├─────────────────────────────────────────────────┤ │ ViewInfo Layer │ │ - Izračunate vizualne informacije │ │ - Cache za rendering │ │ - Bounds, Rects, izračunate vrijednosti │ ├─────────────────────────────────────────────────┤ │ Control Layer │ │ - Rendering-logika │ │ - Input-Handling │ │ - Target-specifično (TUI/GUI/Web) │ └─────────────────────────────────────────────────┘
Primjer: TWvdSButton
(* Properties Layer *) TWvdSButtonProperties = class(TWvdSControlProperties) published property Caption: string; property ImageSource: TWvdSImageSource; property IsDefault: Boolean; property IsCancel: Boolean; property Command: IWvdSCommand; end; (* ViewInfo Layer *) TWvdSButtonViewInfo = class(TWvdSViewInfo) private FCaptionBounds: TRect; FImageBounds: TRect; FContentBounds: TRect; public procedure Calculate(AAvailableRect: TRect); override; property CaptionBounds: TRect read FCaptionBounds; property ImageBounds: TRect read FImageBounds; end; (* Control Layer *) TWvdSButton = class(TWvdSControl) private FProperties: TWvdSButtonProperties; FViewInfo: TWvdSButtonViewInfo; public constructor Create; procedure Render(ASurface: TWvdSRenderSurface); override; procedure OnClick; virtual; published property Caption: string read GetCaption write SetCaption; property OnClick: TNotifyEvent read FOnClick write FOnClick; end;
Target-Renderer
Svaka kontrola ima specijalizirani renderer po targetu.
Renderer-Interface
IWvdSControlRenderer = interface function Measure(AControl: TWvdSControl; AAvailable: TWvdSSize): TWvdSSize; procedure Arrange(AControl: TWvdSControl; ARect: TRect); procedure Paint(AControl: TWvdSControl; ASurface: TWvdSRenderSurface); function HandleInput(AControl: TWvdSControl; AEvent: TWvdSInputEvent): Boolean; end;
Target-specifične implementacije
sources/common/ui/targets/
├── tui/
│ ├── WvdS.UI.TUI.ButtonRenderer.pas
│ ├── WvdS.UI.TUI.TextEditRenderer.pas
│ └── ...
├── gui/
│ ├── WvdS.UI.GUI.ButtonRenderer.pas
│ └── ...
└── web/
├── WvdS.UI.Web.ButtonRenderer.pas
└── ...
TUI Renderer Primjer
TWvdSButtonTUIRenderer = class(TInterfacedObject, IWvdSControlRenderer) public function Measure(AControl: TWvdSControl; AAvailable: TWvdSSize): TWvdSSize; procedure Arrange(AControl: TWvdSControl; ARect: TRect); procedure Paint(AControl: TWvdSControl; ASurface: TWvdSRenderSurface); function HandleInput(AControl: TWvdSControl; AEvent: TWvdSInputEvent): Boolean; end; procedure TWvdSButtonTUIRenderer.Paint(AControl: TWvdSControl; ASurface: TWvdSRenderSurface); var Btn: TWvdSButton; Style: TWvdSStyle; begin Btn := TWvdSButton(AControl); (* Odabir stila na temelju stanja *) if not Btn.IsEnabled then Style := Theme.ButtonDisabled else if Btn.IsFocused then Style := Theme.ButtonFocused else Style := Theme.ButtonDefault; (* Crtanje obruba *) ASurface.DrawBorder(Btn.Bounds, bsSingle, Style); (* Centrirano crtanje Caption *) ASurface.DrawTextCentered(Btn.ViewInfo.ContentBounds, Btn.Caption, Style); end;
Dependency Properties
Definicija
class var CaptionProperty: TWvdSDependencyProperty; class constructor TWvdSButton.Create; begin CaptionProperty := TWvdSDependencyProperty.Register( 'Caption', (* Naziv *) TypeInfo(string), (* Tip *) TWvdSButton, (* Owner *) '', (* Default *) @OnCaptionChanged (* Callback *) ); end;
pas2js-kompatibilnost:
class var ne radi u pas2js. Koristi Unit-Level varijable umjesto toga.
pas2js-kompatibilna alternativa
var GButtonCaptionProperty: TWvdSDependencyProperty = nil; function ButtonCaptionProperty: TWvdSDependencyProperty; begin if GButtonCaptionProperty = nil then GButtonCaptionProperty := TWvdSDependencyProperty.Register(...); Result := GButtonCaptionProperty; end;
Visual States
Obvezna stanja: ├─ Normal (* Zadano stanje *) ├─ Focused (* Ima tipkovnički fokus *) ├─ Disabled (* IsEnabled = False *) └─ Invalid (* Validacijska greška *) Opcionalna stanja: ├─ MouseOver (* Miš iznad *) ├─ Pressed (* Aktivno pritisnuto *) └─ Selected (* Odabrano *)
Input-Handling
Redoslijed događaja
1. PreviewKeyDown (Tunneling) 2. KeyDown (Bubbling) 3. Kontrola-specifična obrada 4. Izvršavanje Command (ako je povezan)
Focus-Management
TWvdSFocusManager = class public class function GetFocusedElement: TWvdSFrameworkElement; class procedure SetFocus(AElement: TWvdSFrameworkElement); class procedure MoveFocus(ADirection: TWvdSFocusNavigationDirection); end; TWvdSFocusNavigationDirection = ( fndNext, (* Tab *) fndPrevious, (* Shift+Tab *) fndUp, fndDown, fndLeft, fndRight );
Data Binding
Binding-sintaksa u PXAML
<TextEdit Text="{Binding CustomerName, Mode=TwoWay}" /> <Button Caption="{Binding SaveCommand.Caption}" Command="{Binding SaveCommand}" />
Binding-Modes
| Mode | Opis |
| OneTime | Jednom kod inicijalizacije |
|---|---|
| OneWay | Source → Target |
| TwoWay | Source ↔ Target |
| OneWayToSource | Target → Source |
Životni ciklus kontrole
1. Konstruktor └─ Inicijalizacija svojstava 2. Primjena predloška └─ Učitavanje i primjena ControlTemplate 3. Measure └─ Izračun željene veličine 4. Arrange └─ Finalna pozicija i veličina 5. Render └─ Crtanje u RenderSurface 6. Input-Events └─ Tipkovnica, miš, dodir 7. Destruktor └─ Oslobađanje resursa
Struktura datoteka
sources/common/ui/
├── framework/ # Bazni Framework (42 Unit-a)
│ ├── WvdS.UI.DependencyObject.pas
│ ├── WvdS.UI.FrameworkElement.pas
│ ├── WvdS.UI.Control.pas
│ ├── WvdS.UI.ViewInfo.pas
│ └── ...
│
├── controls/ # Implementacije kontrola
│ ├── basic/
│ │ ├── WvdS.UI.Controls.Button.pas
│ │ ├── WvdS.UI.Controls.Label.pas
│ │ └── ...
│ ├── editors/
│ ├── data/
│ └── ...
│
├── targets/ # Target-specifični Rendereri
│ ├── tui/
│ ├── gui/
│ └── web/
│
└── themes/ # Definicije tema
├── WvdS.UI.Themes.Default.pas
└── WvdS.UI.Themes.Dark.pas
Vidi također
Zuletzt geändert: 29.01.2026. u 22:33