In the RSS Reader project in → Chapter 18.12.5 it is shown how to create an RSS feed form in the Gambas IDE in addition to the (main) form (→ class FeedItem.Class) and how to insert several controls (2 TextAreas and a PictureBox) into the RSS feed form:
Figure 126.96.36.199: RSS feed form (IDE)
Then RSS feed forms are created in the (main) form according to the number of current news items in the selected RSS data stream and immediately inserted and displayed in a ListContainer. From an application point of view, you can consider these RSS feed forms inserted into the (main) form as their own self-developed controls - as a compound control element or 'Compound Control'. The container for the RSS feed forms is the ListContainer control, which is now considered obsolete and for which there is currently a sufficiently equivalent replacement in the form of the ScrollView control element.
Figure 188.8.131.52: Two RSS feed forms in a ListContainer
It is interesting to note that many control elements from gb.form - which most users may think of as “built-in” - have been created as specially designed form classes; much like the FeedItem class from the project above.
The RSS Reader project consistently implements the strategy already mentioned in chapter 12.2.7:
Private hFSelfmadeControl As FSelfmadeControl ' » Compound Control Public Sub Form_Open() ... hFSelfmadeControl = New FSelfmadeControl(Container) As "hFSelfmadeControl" ... End
Implementing the above strategy is a great way to easily develop your own controls because you can design forms and write class source code for them using the form editor in the IDE. This design process in the Gambas IDE even takes care of organising projects into classes as an implementation of the principle of encapsulation in object-oriented programming (OOP).
In one project it was necessary to realise a colour selection that should fulfil the following requirements:
Before you reinvent the wheel in such a case, it is worth taking a look at the collection of control elements in the Gambas IDE. The relevant control elements ColorChooser and ColorPalette did not fulfil all the requirements in a suitable way. The colour selection via an additional dialogue, as shown in the following two illustrations, spoke against the ColorButton:
Figure 184.108.40.206.1: ColorButton dialogue (right)
So it was clear: The control element FMinimalColorChooser will be developed according to strategy 1 in the IDE of Gambas itself! The control element has these two properties:
|NumberOfColors||Integer||Sets the number of colours [1..12] in the colour palette or returns the number of colours.|
|ValueOfColor||Integer||Returns the colour value selected in the colour palette.|
Table 220.127.116.11.1 : Properties of the class FMCChooser
The control element FMinimalColorChooser has only the event Change. It is triggered when a colour in the colour palette has been selected with a mouse click - it has been changed:
Figure 18.104.22.168.2: MiniColorChooser in action
To test the self-developed control element, a (main) form was designed so that the selected colour in the control element FMinimalColorChooser is used as the foreground colour for a text in a TextArea. In addition, the number of colours in the colour palette is displayed in a SpinBox, which can also be used to change their number in the specified interval [1|12]. The currently selected colour value is displayed in a TextBox (hexadecimal).
 ' Gambas class file   Private hMCChooser As FMinimalColorChooser ' ➘ Compound Control   Public Sub Form_Open()   FMain.Resizable = False  panMCC.Arrangement = Arrange.Fill  ' panMCC.Border = Border.Plain ' Option: Border around the embedded window  sboxNumberOfColors.MinValue = 1  sboxNumberOfColors.MaxValue = 12  txbColorHex.ReadOnly = True   hMCChooser = New FMinimalColorChooser(panMCC, 5) As "hMCChooser"   ' Set selected properties of the embedded window of FMinimalColorChooser.  hMCChooser.Arrangement = Arrange.Vertical  hMCChooser.Spacing = True  ' Set selected properties of control elements on FMinimalColorChooser,  ' whose Public property was set to True at development time.  hMCChooser.dwgColors.Expand = True  hMCChooser.dwgColors.Border = Border.Solid  hMCChooser.panShowColor.Border = Border.Solid   hMCChooser_Change()   End   Public Sub hMCChooser_Change()  SetTAColor(hMCChooser.ValueOfColor)  txbColorHex.Text = "#" & Hex$(hMCChooser.ValueOfColor, 6)  sboxNumberOfColors.Value = hMCChooser.NumberOfColors  End   Public Sub sboxNumberOfColors_Change()  hMCChooser.NumberOfColors = sboxNumberOfColors.Value  End   Private Sub SetTAColor(FGColor As Integer)  TextArea1.Foreground = FGColor  txbColorHex.SetFocus()  End
The form for the control element looks less spectacular:
Figure 22.214.171.124.3: Form with DrawingArea and Panel (IDE and runtime).
The source code for the FMinimalColorChooser class is given in full:
 ' Gambas class file   Property NumberOfColors As Integer '' Number of colours, interval \[1..12\] (read + write)  Property Read ValueOfColor As Integer '' Colour Value (Read Only)   Private $iNumberOfColors As Integer  Private $iValueOfColor As Integer   Event Change   Public Sub _new(Optional NumberOfColors As Integer = 6)  If Not IsMissing(NumberOfColors) Then $iNumberOfColors = NumberOfColors  ' $iValueOfColor = GetColor(0) ' Option: Set start colour  End   Public Sub dwgColors_Draw()   Dim iY As Integer   Paint.LineWidth = dwgColors.H / $iNumberOfColors ' Relative width - related to DrawingArea  Paint.Translate(0, Paint.LineWidth / 2)  For iY = 0 To $iNumberOfColors - 1  Paint.Background = GetColor(iY)  Paint.MoveTo(0, iY * Paint.LineWidth)  Paint.LineTo(dwgColors.W, iY * Paint.LineWidth) ' Relative height - related to DrawingArea  Paint.Stroke()  Next   $iValueOfColor = GetColor(0)  UpdatePreviewColor()   End   Private Function GetColor(Ind As Integer) As Integer ' Generate colour palette   Dim fR, fG, fB As Float  Dim fFreq As Float = Pi(2) / $iNumberOfColors   fR = Sin(fFreq * Ind) * 127 + 128  fG = Sin(fFreq * Ind + Pi(1 / 3)) * 127 + 128  fB = Sin(fFreq * Ind + Pi) * 127 + 128   Return Color.RGB(fR, fG, fB)   End   Private Sub UpdatePreviewColor()  panShowColor.Background = $iValueOfColor  End   Public Sub dwgColors_MouseMove()  dwgColors_MouseUp()  End   Public Sub dwgColors_MouseUp()  $iValueOfColor = GetColor(Mouse.Y * $iNumberOfColors / dwgColors.H)  UpdatePreviewColor()  Raise Change ' The Change event is triggered  End   Private Function NumberOfColors_Read() As Integer  Return $iNumberOfColors  End   Private Sub NumberOfColors_Write(Colors As Integer)  If Colors < 1 Or colors > 12 Then Error.Raise(Subst$(("Invalid number: &1"), Colors))  $iNumberOfColors = Colors  dwgColors.Refresh() ' Colour palette is redrawn  End   Private Function ValueOfColor_Read() As Integer  Return $iValueOfColor  End
Things get really interesting when you put the class FMinimalColorChooser in a control element that can also be integrated into the collection of control elements (tool collection) with its own symbol:
Figure 126.96.36.199.1: Tool collection (Chooser)
It is not until Chapter 30 that components, classes, modules and control elements are described in more detail under the aspect of object-oriented programming. To give you an insight into the strategy for developing and implementing self-developed control elements for the tool collection in the Gambas IDE, a suitable project by Tobias Boege is presented in the download area.
Please note: To integrate the control element MinimalColorChooser into the tool collection, the directory MinimalColorChooser has to be copied into the project directory which shall use the control element MinimalColorChooser.
The source code for the crucial MinimalColorChooser class looks like this:
' Gambas class file Inherits UserControl Export Event Change Public Const _Properties As String = "*,NumberOfColors=8" Public Const _Group As String = "Chooser" Public Const _Similar As String = "ColorChooser" Public Const _DefaultEvent As String = "Change" Property NumberOfColors As Integer Property Read ValueOfColor As Integer Private $hMCChooser As FMinimalColorChooser Public Sub _new() $hMCChooser = New FMinimalColorChooser(Me, 6) End Public Sub Raise_ColorChange() Raise Change ' To be called from the FMinimalColorChooser End Private Function NumberOfColors_Read() As Integer Return $hMCChooser.NumberOfColors End Private Sub NumberOfColors_Write(Value As Integer) $hMCChooser.NumberOfColors = Value End Private Function ValueOfColor_Read() As Integer Return $hMCChooser.ValueOfColor End