Understanding DirectX Styles in Visual LANSA Applications
|Date:||11 April 2013|
|Product/Release:||Visual LANSA V13|
|Abstract:||Understanding how to use styles in DirectX - Visual LANSA V13|
|Submitted By:||LANSA Technical Support|
Application user interfaces have changed greatly in recent years, and the revolution is showing no sign of slowing. Web page designs, mobile phone apps., large monitors, and the continued rise of the touch screen all mean that we need to rethink how we make functionality available to the user and how an application should appear. Transparency, rounded corners, gradient brushes and flatter designs are now the norm, meaning that 3D borders and preformatted controls like push button and group box have given way to simple images and labels.
Visual Styles and Styles
Historically, Visual Styles and latterly Themes provided a simple, if somewhat restrictive, approach to application styling. The runtime played games with a gray background to ensure that themes and other features worked well together and for the most part, applications looked fine. However, anything outside of a typical set of requirements made it difficult to get the right appearance.
As part of the adoption of the DirectX rendering engine in version 13, and in particular the introduction of gradient colors and transparency, it was necessary to take another look at how Visual LANSA managed application appearance. The old Visual Style and Theme rules could no longer be applied, and a new type of style became necessary.
Styles can be defined as simple static features of a Visual Style and can be thought of as much the same as cascading style sheet, with multiple styles defined in one place.
This example shows a few basic styles.
Begin_Com Role(*Extends #Prim_Vs) Define_Com Class(#Prim_vs.Style) Name(#ApplicationStyle) Textcolor(40:40:40) Define_Com Class(#prim_vs.Style) Name(#Edit) Cornerbottomleft(3) Cornerbottomright(3) Cornertopleft(3) Cornertopright(3) Define_Com Class(#Prim_vs.Style) Name(#Heading1) Bold(True) Fontsize(16) Textcolor(48:48:48) Define_Com Class(#Prim_vs.Style) Name(#Heading2) Fontsize(14) Textcolor(48:48:48) Define_Com Class(#prim_vs.style) Name(#Emphasis) Bold(True) Textcolor(48:48:48) Define_Com Class(#Prim_vs.Style) Name(#Error) Textcolor(189:0:0) Define_Com Class(#Prim_vs.Style) Name(#Warning) Textcolor(1:156:0) * Linear Horizontal Background White to Grey, Top to Bottom Define_Com Class(#PRIM_VS.Style) Name(#Background) Backgroundbrush(#BackgroundBrush) Define_Com Class(#PRIM_VS.LinearBrush) Name(#BackgroundBrush) Colors(#BackgroundColors) Define_Com Class(#PRIM_VS.BrushColors) Name(#BackgroundColors) Define_Com Class(#PRIM_VS.BrushColor) Name(#BackgroundColor1) Color(255:255:255) Parent(#BackgroundColors) Define_Com Class(#PRIM_VS.BrushColor) Name(#BackgroundColor2) At(100) Color(181:181:181) Parent(#BackgroundColors) End_Com
Unlike Visual Styles, which simply replaced the incumbent settings with their own, Styles have a very light touch, only affecting the features specifically referenced in their definition.
Styles are made up of background and foreground features. Only the foreground features, TextColor, Font and ForegroundBrush are adopted by child controls. The reason for this is that it is most unlikely that borders and a background brush applied to a panel would be required on each and every child control. Instead, panels and labels are transparent by default, allowing a base background to be visible. Of course, should you want the background and border to repeat on each control, you can still explicitly apply the Style.
Style and Styles Properties
All controls have Style and Styles properties. The simplest application of a style is as below.
Define_Com Class(#Prim_labl) name(#Heading) Caption(‘Details’) Style(#MyStyles<Heading1>)
Previously, all of the combinations of styles that were required needed to be created individually. However, it is now possible to assign multiple styles to a single control at runtime by using the Styles property.
In this example, a label already has a style, but as a value changes, an “error” style is added or removed as required.
Define_Com Class(#Prim_labl) name(#ValueCaption) Caption(‘Details’) Style(#MyStyles<Emphasis>) Evtroutine Handling(#Value.Changed) If (#Value > #AllowedLimit) #ValueCaption.Styles.Add(#MyStyles<Error>) Else #ValueCaption.Styles.Remove(#MyStyles<Error>) Endif Endroutine
Styles can also be applied at a global level, for example, when the application first starts. This will be adopted by all forms and reusable parts. This same concept also applies to individual controls. Below, the application is given a style, and an additional style is applied to all edit boxes to ensure that they all have rounded corners when first created.
Evtroutine Handling(#Com_owner.CreateInstance) #sys_appln.Style <= #MyStyles<ApplicationStyle> #sys_appln.Appearance.Edit <= #MyStyles<Edit> Endroutine
MouseOverStyle and MouseOverStyles Properties
Modern applications often change the appearance of controls as the mouse enters. To simplify this process, all controls have a further pair of properties – MouseOverStyle and MouseOverStyles.
As before with Style and Styles, the control can be defined as having an individual MouseOverStyle, or multiple MouseOverStyles can be applied at runtime.
Define_Com Class(#Prim_labl) name(#ValueCaption) Caption(‘Details’) MouseOverStyle(#MyStyles<Emphasis>)
The VL runtime will automatically add the style when the mouse enters the control and will remove it again as soon as the mouse leaves. This saves the need for the user to clutter the code with multiple MouseEnter and MouseLeave routines just to apply a simple style.
PrivateStyle and PrivateStyles Properties
Composite controls, such as tab folder and group box often need their own style for their captions, but don’t want to pass that style to their child controls. To facilitate this, composite controls can have their own private styles. These are styles that are applied to the visible features of the control, typically text, but will not be adopted by the child controls.
For most scenarios, predefined styles stored in the repository will cover application requirements. However, there are situations where dynamic styles are required e.g. Font or color selection. In these situations, Styles can be defined and instances created just like any other component, meaning their properties can be set at runtime.
The following shows a color picker dialog when the form is clicked. The selected color is applied to the style and thus to the background of the form.
Function Options(*DIRECT) Begin_Com Role(*EXTENDS #PRIM_Form) Clientheight(284) Clientwidth(464) Height(322) Left(126) Style(#Style) Top(223) Width(480) Define_Com Class(#prim_vs.Style) Name(#Style) Normbackcolor(White) Define_Com Class(#Prim_appl.ICommonDialogColor) Name(#ColorPicker) Reference(*dynamic) Evtroutine Handling(#Com_owner.CreateInstance) #Com_owner.Cursor <= #sys_appln.Cursors<Hand> Endroutine Evtroutine Handling(#Com_owner.Click) Define_Com Class(#prim_boln) Name(#OK) If (#ColorPicker *Is *null) #ColorPicker <= #sys_appln.CreateColorDialog #ColorPicker.FullyOpen := true Endif #ColorPicker.ChosenColor := #Style.NormBackColor #OK := #ColorPicker.Show If (#OK) #Style.NormBackColor := #ColorPicker.ChosenColor Endif Endroutine End_Com