13.6 Context menu - TrayIcon

The component gb. gui. trayicon with the two classes TrayIcon and TrayIcons is described in chapter 19.2. This chapter deals with assigning a context menu to a tray icon, which can be called up with the right mouse button in the task bar above the tray icon. If you want to run a Gambas program in the background, you can use the class TrayIcon to access the program via an icon in the task bar. This has the advantage that you always have access to the program interface, or alternatively you can call up selected subprograms in a context menu assigned to the tray icon. The menu is declared in a module in the presented project. You can also create it with the menu editor, whose description can be found in Chapter 13.2 Menu Editor.

Since not every reader has a USB interface for temperature measurement and the class TrayIcon is especially interesting for programs that work hidden for a long time and signal their presence only by an icon in the taskbar, a simulation project is presented to you. The temperature values are generated and displayed randomly in a specified temperature range. The temperature values are also logged in a log file:

MEASUREMENT PROTOCOL
DATE: 14. February 2018
----------------------------
>  09:47:56  |  T = 22,3 °C
>  09:47:57  |  T = 22,1 °C
>  09:47:58  |  T = 21,8 °C
>  09:47:59  |  T = 21,0 °C
>  09:48:00  |  T = 21,5 °C
>  09:48:01  |  T = 20,3 °C
>  09:48:02  |  T = 19,9 °C

The program section dedicated to the tray icon context menu has been saved in a module. In this module, the

The source code for the module MTI (module TrayIcon) does not come as a surprise:

[1] ' Gambas module file
[2]
[3] Public M10MainMenu As Menu
[4] Public M11ProgramHideShow As Menu
[5] Public M12ShowData As Menu
[6] Public M13CloseExperiment As Menu
[7]
[8] Public Sub CreateMenu()
[9]
[10] ' True -> The menu is NOT displayed in the main program!
[11]   M10MainMenu = New Menu(FMain, True) As "Menu"
[12]   M10MainMenu.Text = ("Caption")
[13]
[14] ' This property is required for the assignment as pop-up menu of the tray icon!
[15]   M10MainMenu.Name = "M10MainMenu"
[16]
[17]   M11ProgramHideShow = New Menu(M10MainMenu) As "M11ProgramHideShowShow"
[18]   M11ProgramHideShow.Text = ("Hide program")
[19]   M11ProgramHideShow.Picture = Picture["icon:/16/down"]
[20]
[21]   M12ShowData = New Menu(M10MainMenu) As "M12ViewData"
[22]   M12ShowData.Text = ("Display data")
[23]   M12ShowData.Picture = Picture["icon:/16/view-icon"]
[24]
[25]   M13CloseExperiment = New Menu(M10MainMenu) As "M13CloseExperiment"
[26]   M13CloseExperiment.Text = ("Close experiment")
[27]   M13CloseExperiment.Picture = Picture["icon:/16/quit"]
[28]
[29] End
[30]
[31] Public Sub M11ProgramHideShowShow_Click()
[32]   If M11ProgramHideShow.Text = ("Hide program") Then
[33]      FMain.Visible = False
[34]      M11ProgramHideShow.Text = ("Show program")
[35]      M11ProgramHideShow.Picture = Picture["icon:/16/up"]
[36]   Else
[37]      FMain.Visible = True
[38]      M11ProgramHideShow.Text = ("Hide program")
[39]      M11ProgramHideShow.Picture = Picture["icon:/16/down"]
[40]   Endif
[41] End
[42]
[43] Public Sub M12ViewData_Click()
[44]   Message.Info(("Measurement data are displayed ..."))
[45] End ' M12ViewData
[46]
[47] Public Sub M13CloseExperiment_Click()
[48]      FMain.Close()
[49] End

The complete project for the simulation of a long-term temperature measurement can be found in the long. time. experiment. tar. gz repository in the download area. The source code for the main program can also be found at the end of the chapter.

B1
Figure 13.6.1: GUI of the simulation project

Hints:

B2
Figure 13.6.2: Contents of the context menu for the tray icon

In the following source code, important sections are highlighted in color:

' Gambas class file
 
Public timerDataLog As Timer
Public timerReadData As Timer
Public timerSimulation As Timer
Public fTemperature As Float
 
Public hTrayIcon As TrayIcon
 
Public Sub Form_Open()
 
  FMain.Resizable = False
  FMain.Height = 160
  expRX_TX.Hidden = True
  expRX_TX.Animated = True
 
  SetRS232Parameters()
 
  timerSimulation = New Timer As "timerSimulation"
' Generate a random temperature value from the specified interval every 100 ms
  timerSimulation.Delay = 100
 
  timerReadData = New Timer As "timerReadData"
' The current temperature value is read out every 1000 ms
  timerReadData.Delay = 1000
 
  timerDataLog = New Timer As "timerDataLog"
' Time interval of data storage in a log file
  timerDataLog.Delay = 3000 * 1
 
  SetLEDColor(picStatus, "red")
  btnExperimentStop.Enabled = False
 
  hTrayIcon = New TrayIcon As "hTrayIcon"
  hTrayIcon.Icon = Picture["Symbols/experiment.png"]
  hTrayIcon.Tooltip = ("Long time experiment")
  hTrayIcon.Visible = False
  MTI.CreateMenu()
' The menu declared in the module MTI.module is assigned to the tray icon as a context menu.
  hTrayIcon.PopupMenu = MTI.M10MainMenu.Name
 
End
 
Public Sub btnExperimentStart_Click()
 
  GetRS232Parameters()
 
  If Exist(Application.Path &/ "rs232.log") Then
     If Message.Question(("Should the last measurement log be deleted?"), ("Yes"), ("No")) = 1 Then
        Try Kill Application.Path &/ "rs232.log"
        AddTextToFile(("Log of measurement data") & gb.NewLine)
        AddTextToFile(("Date") & ":  " & Format(Now, "dd. mmmm yyyy"))
        AddTextToFile("------------------------------")
     Endif
  Else
     AddTextToFile(("Log of measurement data"))
     AddTextToFile(("Date") & ":  " & Format(Now, "dd. mmmm yyyy"))
     AddTextToFile("-------------------------------")
  Endif
 
  btnExperimentStart.Enabled = False
  btnExperimentStop.Enabled = True
  SetLEDColor(picStatus, "green")
  lblTemperaturAnzeige.Text = "--- °C"
 
  timerSimulation.Start()
  timerSimulation.Trigger()
  timerReadData.Start()
  timerReadData.Trigger()
  timerDataLog.Start()
  timerDataLog.Trigger()
 
  expRX_TX.Hidden = True
 
  MTI.M11ProgramHideShow.Text = ("Show measuring program")
  MTI.M11ProgramHideShow.Picture = Picture["icon:/16/up"]
 
  FMain.Hide()
  hTrayIcon.Show()
 
End
 
Public Sub btnExperimentStop_Click()
 
  timerSimulation.Stop()
  timerReadData.Stop()
  timerDataLog.Stop()
  btnExperimentStart.Enabled = True
  btnExperimentStop.Enabled = False
  SetLEDColor(picStatus, "red")
  lblTemperaturAnzeige.Text = "--- °C"
 
End
 
Public Sub TimerSimulation_Timer()
 
  Dim aRange As Float[] = [19.0, 22.0]
 
  Randomize
  fTemperature = Round(Rnd(aRange[0], aRange[1]), -1)
 
End
 
Public Sub timerReadData_Timer()
  lblTemperaturAnzeige.Text = Str(fTemperature) & " °C"
End
 
Public Sub timerDataLog_Timer()
  AddTextToFile(">  " & Format(Now, "hh:nn:ss") & "  |  " & "T = " & Str(fTemperature) & " °C")
End
 
Public Sub expRX_TX_Hide()
  FMain.Height = 160
  expRX_TX.Hidden = True
End
 
Public Sub expRX_TX_Show()
  FMain.Height = 430
  expRX_TX.Hidden = False
End
 
Public Sub AddTextToFile(Text As String)
 
  Dim hFile As File
  Dim FilePath As String
 
  FilePath = Application.Path &/ "rs232.log"
 
  Try hFile = Open FilePath For Append
  If Error Then
     Message.Error(("File error"))
     Return
  Endif
  Print #hFile, Text
  Close #hFile
End
 
Public Sub hTrayIcon_Click()
  Message.Info(("I am the little program help..."))
End
 
Public Sub hTrayIcon_MiddleClick()
  FMain.Close()
End
 
Public Sub hTrayIcon_Scroll(Delta As Float, Orientation As Integer)
  If Orientation = TrayIcon.Vertical Then Print "VERTICAL"
  Print Delta
End
 
Private Sub SetRS232Parameters()
 
  Dim aDataFlow As New String[]
 
  aDataFlow.Add("None")
  aDataFlow.Add("XON/XOFF")
  aDataFlow.Add("RFR/CTS")
  aDataFlow.Add("RFR/CTS + XON/XOFF")
  cmbFlow.List = aDataFlow
 
  cmbRS232Port.List = [("/dev/ttyUSB0.virtual")]
  cmbSpeed.List = ["4800", "9600", "2400"]
  cmbParity.Add("None")
  cmbParity.Add("Even")
  cmbParity.Add("Odd")
  cmbDataBits.List = ["8", "7", "6", "5"]
  cmbStopBits.List = ["1", "2"]
 
End
 
Private Sub GetRS232Parameters()
 
  RS232.PortName = cmbRS232Port.Text
' Setting the transmission parameters
  RS232.Speed = cmbSpeed.Text
  RS232.Parity = cmbParity.Index
  RS232.DataBits = cmbDataBits.Text
  RS232.StopBits = cmbStopBits.Text
  RS232.FlowControl = cmbFlow.Index
 
End
 
Private Sub SetLEDColor(picBox As PictureBox, sLEDColor As String)
  picBox.Picture = Picture["LED/led_" & sLEDColor & ".svg"]
End
 
Public Sub Form_Close()
 
  If Message.Question(("Finish this experiment?"), ("Yes"), ("No")) = 1 Then
     hTrayIcon.Hide()
     FMain.Close()
  Endif
 
End

Download