New themes are defined by this abstract class from which you would inherit and implement. Sliced up bitmaps could be used to create a theme for sure, but I have implemented the themes so far using vector drawing commands exclusively.
TTheme = class public { Calculate the actual theme color } function CalcColor(Widget: TWidget; Color: TThemeColor): LongWord; virtual; abstract; { Calculate the size of a widget } function CalcSize(Widget: TWidget; Part: TThemePart): TSizeF; virtual; abstract; { Render the widget } procedure Render(Widget: TWidget); virtual; abstract; end; There are two themes I have implemented so far. One theme based on the popular Arc Dark Linux theme, and the other based on Windows 95 or what I call the Chicago theme. See this screenshot: https://cache.getlazarus.org/images/desktop/both-acr-dark-and-chicago-theme-at-the-same-time.png After settling on how to implement my first theme Arc Dark, adding the Chicago theme was quite easy. I just changed some system colors and a few of the size / render options and I was done. One difference in the newer Chicago theme was that active window captions would be a different color, and I implemented the classic Windows 95 dotted focus rect for controls that can receive input focus. An interesting feature is that themes can be applied on a per widget level, or they can be inherited from the parent widget. Each widget has a computed property that reflects any property which can be inherited from the visual parent hierarchy. This includes computed opacity, enabled, visibility, boundaries, the theme being used, and so on. Another point of interest is how icons for message boxes, buttons, and other controls are handled. I reuse the text property and use a vector glyph font. You can change the glyph font to get different icons, but for now I am using the FOSS material design font and wrote a cross platform small utility to assist in picking out icons: https://cache.getlazarus.org/images/desktop/icon-utility.png Yesterday I completed modal windows support and added a few modal window message type functions to the main widget. As an example this is how MessageBox(const Message: string) implemented in TMainWidget: procedure TMainWidget.MessageBox(const Message: string); begin with Add<TWindow> do begin with This.Add<THBox> do begin Align := alignCenter; with This.Add<TGlyphImage> do begin Align := alignCenter; Text := ''; end; with This.Add<TLabel> do begin Align := alignCenter; MaxWidth := 400; Text := Message; end; end; with This.Add<TButton> do begin Align := alignCenter; Text := 'OK'; ModalResult := modalOk; end; Text := 'Message'; Pack; X := (Self.Width - This.Width) / 2; Y := (Self.Height - This.Height) / 2; ShowModal(MessageBoxClose); end; end; And this is the result: https://cache.getlazarus.org/images/desktop/message-box.png And with the Chicago theme: https://cache.getlazarus.org/images/desktop/message-box-chicago.png Mind you, this UI toolkit is only meant to be a minimal system for configuring or interfacing with a game, physics simulation, animation or demo program. It is not intended to be a general use cross platform UI framework.
_______________________________________________ fpc-pascal maillist - fpc-pascal@lists.freepascal.org https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal