<div dir="ltr"><div>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.</div><div><br></div><div>  TTheme = class<br>  public<br>    { Calculate the actual theme color }<br>    function CalcColor(Widget: TWidget; Color: TThemeColor): LongWord; virtual; abstract;<br>    { Calculate the size of a widget }<br>    function CalcSize(Widget: TWidget; Part: TThemePart): TSizeF; virtual; abstract;<br>    { Render the widget }<br>    procedure Render(Widget: TWidget); virtual; abstract;<br>  end;<br></div><div><br></div><div>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:</div><div><br></div><div><a href="https://cache.getlazarus.org/images/desktop/both-acr-dark-and-chicago-theme-at-the-same-time.png">https://cache.getlazarus.org/images/desktop/both-acr-dark-and-chicago-theme-at-the-same-time.png</a><br></div><div><br></div><div>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.</div><div><br></div><div>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.</div><div><br></div><div>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:</div><div><br></div><div><a href="https://cache.getlazarus.org/images/desktop/icon-utility.png">https://cache.getlazarus.org/images/desktop/icon-utility.png</a><br></div><div><br></div><div>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:</div><div><br></div><div>procedure TMainWidget.MessageBox(const Message: string);<br>begin<br>  with Add<TWindow> do<br>  begin<br>    with This.Add<THBox> do<br>    begin<br>      Align := alignCenter;<br>      with This.Add<TGlyphImage> do<br>      begin<br>        Align := alignCenter;<br>        Text := '';<br>      end;<br>      with This.Add<TLabel> do<br>      begin<br>        Align := alignCenter;<br>        MaxWidth := 400;<br>        Text := Message;<br>      end;<br>    end;<br>    with This.Add<TButton> do<br>    begin<br>      Align := alignCenter;<br>      Text := 'OK';<br>      ModalResult := modalOk;<br>    end;<br>    Text := 'Message';<br>    Pack;<br>    X := (Self.Width - This.Width) / 2;<br>    Y := (Self.Height - This.Height) / 2;<br>    ShowModal(MessageBoxClose);<br>  end;<br>end; <br></div><div><br></div><div>And this is the result:</div><div><br></div><div><a href="https://cache.getlazarus.org/images/desktop/message-box.png">https://cache.getlazarus.org/images/desktop/message-box.png</a><br></div><div><br></div><div>And with the Chicago theme:</div><div><br></div><div><a href="https://cache.getlazarus.org/images/desktop/message-box-chicago.png">https://cache.getlazarus.org/images/desktop/message-box-chicago.png</a><br></div><div><br></div><div>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.</div></div>