MapInfo Pro

 View Only
  • 1.  Create ToggleButton

    Posted 11 days ago
    Edited by Peter Møller 11 days ago
    Hi,
     
    I'm trying to create a toggle button that when selected, it will open a WMS table and then change the icon on the button. When selected again it will close the table and change the button icon back to what it was before. Its not quite working as it should, I have to select the button twice for it to open the table, I'm not sure what i need to change to get the button working correctly? 
    Regards
    Andrew
    Define xProgram "Aerial OnOff"
    Define PATH_IMAGES ApplicationDirectory$() & "Images\"
     
    Global mbAerialHandlerEnabled As Logical
    Global nCtrlIdx As Integer
     
    Declare Sub Main
    Declare Sub AerialSwitchDisplay
    Declare Sub AerialOn
    Declare Sub AerialOff
    Declare Sub EndHandler
     
    Sub Main
     
    OnError GoTo ErrorOccured
     
    Dim sTabName, sGroupName As String
     
      Call PRGISetApplicationName(xProgram)
     
      If SystemInfo(SYS_INFO_MAPINFO_INTERFACE) = MIINTERFACE_RIBBON Then
         sTabName = TAB_MAP
        sGroupName = TAB_GROUP_MAP_OPTIONS
        nCtrlIdx = RBNGroupAddButton("btnAerial", "Imagery", "", sTabname, sGroupName)
        If nCtrlIdx > 0 Then
          Call RBNControlToggleIdx(nCtrlIdx, TRUE)
          Call RBNControlSetToolTipIdx(nCtrlIdx, PRGIGetApplicationName(),"Select to Turn Aerial Imagery On", "")
          Call RBNControlSetIconsIdx(nCtrlIdx, CONTROL_SIZE_LARGE, "", PATH_IMAGES + "AddImage_32x32.png")
          Call RBNControlSetCustomMBXHandlerIdx(nCtrlIdx, "AerialSwitchDisplay")
        End If
      End If
     
       Exit Sub
    ErrorOccured:
      Call ERRCreate(Err(), Error$(), "Main")
      Call ERRShow()
     
    End Sub
     
    Sub AerialSwitchDisplay
     
    OnError GoTo ErrorOccured
     
      mbAerialHandlerEnabled = (Not mbAerialHandlerEnabled)
      Call RBNControlSelectedIdx(nCtrlIdx, Not mbAerialHandlerEnabled)
    
      If mbAerialHandlerEnabled Then
        Call RBNControlSetToolTipIdx(nCtrlIdx, PRGIGetApplicationName(), "Select to Turn Aerial Imagery On.", "")
        Call RBNControlSetIconsIdx(nCtrlIdx, CONTROL_SIZE_LARGE, "", PATH_IMAGES + "AddImage_32x32.png")
        Call RBNControlSetCustomMBXHandlerIdx(nCtrlIdx, "AerialOn")
      Else
        Call RBNControlSetToolTipIdx(nCtrlIdx, PRGIGetApplicationName(), "Select to Turn Aerial Imagery Off.", "")
        Call RBNControlSetIconsIdx(nCtrlIdx, CONTROL_SIZE_LARGE, "", PATH_IMAGES + "RemoveImage_32x32.png")
        Call RBNControlSetCustomMBXHandlerIdx(nCtrlIdx, "AerialOFF")
      End If
     
      Exit Sub
    ErrorOccured:
      Call ERRCreate(Err(), Error$(), "Main")
      Call ERRShow()
     
    End Sub
     
    Sub AerialOn
     
      Open Table "G:\BaseData\Imagery\WMS_SISP\SISP_All_Users_Jpg.TAB" 
      Add Map Auto Layer SISP_All_Users_Jpg
      Call AerialSwitchDisplay
    
    End Sub AerialOn
     
    Sub AerialOff
     
      Close Table SISP_All_Users_Jpg
      Call AerialSwitchDisplay
     
    End Sub AerialOff  
     
    Sub EndHandler
     
    OnError GoTo ErrorOccured
     
      Call RBNEndHandler
      Exit Sub
    ErrorOccured:
      Call ERRCreate(Err(), Error$(), "EndHandler")
      Call ERRShow()
     
    End Sub


    ------------------------------
    Andrew Niebling
    Systems Administrator (GIS)
    Queensland Rail Ltd
    Brisbane QLD
    Australia
    ------------------------------



  • 2.  RE: Create ToggleButton

    Employee
    Posted 11 days ago

    You may only have to make one small change. The button should initially be created to call AerialOn, not AerialSwitchDisplay.

    Call RBNControlSetCustomMBXHandlerIdx(nCtrlIdx, "AerialOn")

    If that works, ignore the rest of my comments :-) I wrote these before I realized the issue.

    -----------------------------------------

    I would rewrite the handler called by the button to make it more clear.

    I would wait until the end to reset the logical variable which I would rename to relate to the state of the table.

    Sub AerialSwitchDisplay
     
    OnError GoTo ErrorOccured
    
      If mbAerialOpen Then
        'It is open, so let's close it, and change the button to allow opening it
        Call RBNControlSetToolTipIdx(nCtrlIdx, PRGIGetApplicationName(), "Select to Turn Aerial Imagery On.", "")
        Call RBNControlSetIconsIdx(nCtrlIdx, CONTROL_SIZE_LARGE, "", PATH_IMAGES + "AddImage_32x32.png")
        Call AerialClose
      Else
        'It is NOT open, so let's open it, and change the button to allow closing it
        Call RBNControlSetToolTipIdx(nCtrlIdx, PRGIGetApplicationName(), "Select to Turn Aerial Imagery Off.", "")
        Call RBNControlSetIconsIdx(nCtrlIdx, CONTROL_SIZE_LARGE, "", PATH_IMAGES + "RemoveImage_32x32.png")
        Call AerialOpen
      End If
    
      mbAerialOpen = (Not mbAerialOpen)
      Call RBNControlSelectedIdx(nCtrlIdx, mbAerialOpen)
     
      Exit Sub
    ErrorOccured:
      Call ERRCreate(Err(), Error$(), "Main")
      Call ERRShow()
     
    End Sub

    I would also rename the two functions for opening/closing the aerial to represent an action: AerialOpen/AerialClose. Again this is a personal preference.

    Note that I removed the interface change from these two procedures and kept the interface change at a single location.

    I would let the button continue to call the same procedure, AerialSwitchDisplay, and just handle what to do in that procedure. 

    Sub AerialOpen
     
      Open Table "G:\BaseData\Imagery\WMS_SISP\SISP_All_Users_Jpg.TAB" 
      Add Map Auto Layer SISP_All_Users_Jpg
    
    End Sub AerialOpen
     
    Sub AerialClose
     
      Close Table SISP_All_Users_Jpg
     
    End Sub AerialClose  


    ------------------------------
    Peter Horsbøll Møller
    Principal Presales Consultant | Distinguished Engineer
    Precisely | Trust in Data
    ------------------------------



  • 3.  RE: Create ToggleButton

    Posted 8 days ago
    Edited by Peter Møller 7 days ago
    Hi Peter,
     
    Thanks for the advice, making the changes as you suggested now makes the togglebutton work as it should, thankyou.
     
    I have now added another togglebutton to open a Open Street Map layer, but need to disable the button depending upon which one is selected.
     
    I need to use the below I think,
     
    Call RBNGroupEnableControls("", "", "btnSISPAerial", TRUE)
    Call RBNGroupEnableControls("", "", "btnSISPAerial", FALSE)
     
    Call RBNGroupEnableControls("", "", "btnOpenStreetMap", True)
    Call RBNGroupEnableControls("", "", "btnOpenStreetMap", False)
    but not sure where to place them, WinChangedHandler maybe? I tried placing them in the switchdisplays sub but that didnt work. How would you do it?
    Define xProgram "Aerial OnOff"
    
    Define PATH_IMAGES ApplicationDirectory$() & "Images\"
     
    Global mbAerialOpen As Logical
    Global mbOSMOpen As Logical
    Global nCtrlIdx As Integer
     
    Declare Sub Main
    Declare Sub AerialSwitchDisplay
    Declare Sub AerialOpen
    Declare Sub AerialClose
     
    Declare Sub OSMSwitchDisplay
    Declare Sub OSMOpen
    Declare Sub OSMClose
    Declare Sub EndHandler
     
    Sub Main
     
    OnError GoTo ErrorOccured
     
      Dim sTabName, sGroupName As String
     
      Call PRGISetApplicationName(xProgram)
     
      If SystemInfo(SYS_INFO_MAPINFO_INTERFACE) = MIINTERFACE_RIBBON Then
        sTabName = TAB_MAP
        sGroupName = TAB_GROUP_MAP_OPTIONS
     
        nCtrlIdx = RBNGroupAddButton("btnAerial", "QLD Imagery", "", sTabname, sGroupName)
        If nCtrlIdx > 0 Then
          Call RBNControlToggleIdx(nCtrlIdx, TRUE)
          Call RBNControlSetToolTipIdx(nCtrlIdx, PRGIGetApplicationName(),"Select to Turn QLD Imagery On", "")
          Call RBNControlSetIconsIdx(nCtrlIdx, CONTROL_SIZE_LARGE, "", PATH_IMAGES + "AddImage_32x32.png")
          Call RBNControlSetCustomMBXHandlerIdx(nCtrlIdx, "AerialSwitchDisplay")
        End If
    
        nCtrlIdx = RBNGroupAddButton("btnOpenStreetMap", "OpenStreetMap", "", sTabname, sGroupName)
        If nCtrlIdx > 0 Then
          Call RBNControlToggleIdx(nCtrlIdx, TRUE)
          Call RBNControlSetToolTipIdx(nCtrlIdx, PRGIGetApplicationName(),"Select to Turn OpenStreetMap On", "")
          Call RBNControlSetIconsIdx(nCtrlIdx, CONTROL_SIZE_LARGE, "", PATH_IMAGES + "AddOSM_32x32.png")
          Call RBNControlSetCustomMBXHandlerIdx(nCtrlIdx, "OSMSwitchDisplay")
        End If
      End If
    
      Exit Sub
    ErrorOccured:
      Call ERRCreate(Err(), Error$(), "Main")
      Call ERRShow()
    
    End Sub
     
    Sub AerialSwitchDisplay
     
    OnError GoTo ErrorOccured
    
      If mbAerialOpen Then
        Call RBNControlSetToolTipIdx(nCtrlIdx, PRGIGetApplicationName(), "Select to Turn QLD Imagery On.", "")
        Call RBNControlSetIconsIdx(nCtrlIdx, CONTROL_SIZE_LARGE, "", PATH_IMAGES + "AddImage_32x32.png")
        Call AerialClose
      Else
        Call RBNControlSetToolTipIdx(nCtrlIdx, PRGIGetApplicationName(), "Select to Turn QLD Imagery Off.", "")
        Call RBNControlSetIconsIdx(nCtrlIdx, CONTROL_SIZE_LARGE, "", PATH_IMAGES + "RemoveImage_32x32.png")
        Call AerialOpen
      End If
     
      mbAerialOpen = (Not mbAerialOpen)
      Call RBNControlSelectedIdx(nCtrlIdx, mbAerialOpen)
     
       Exit Sub
    ErrorOccured:
      Call ERRCreate(Err(), Error$(), "Main")
      Call ERRShow()
     
    End Sub
     
    Sub OSMSwitchDisplay
     
    OnError GoTo ErrorOccured
    
      If mbOSMOpen Then
        Call RBNControlSetToolTipIdx(nCtrlIdx, PRGIGetApplicationName(), "Select to Turn OpenStreetMap On.", "")
        Call RBNControlSetIconsIdx(nCtrlIdx, CONTROL_SIZE_LARGE, "", PATH_IMAGES + "AddOSM_32x32.png")
        Call OSMClose
      Else
        Call RBNControlSetToolTipIdx(nCtrlIdx, PRGIGetApplicationName(), "Select to Turn OpenStreetMap Off.", "")
        Call RBNControlSetIconsIdx(nCtrlIdx, CONTROL_SIZE_LARGE, "", PATH_IMAGES + "RemoveOSM_32x32.png")
        Call OSMOpen
      End If
     
      mbOSMOpen = (Not mbOSMOpen)
      Call RBNControlSelectedIdx(nCtrlIdx, mbOSMOpen)
     
      Exit Sub
    ErrorOccured:
      Call ERRCreate(Err(), Error$(), "Main")
      Call ERRShow()
     
    End Sub
     
    Sub AerialOpen
     
      Open Table "G:\BaseData\Imagery\WMS_SISP\SISP_All_Users_Jpg.TAB" 
      Add Map Auto Layer SISP_All_Users_Jpg
     
    End Sub
     
    Sub AerialClose
     
      Close Table SISP_All_Users_Jpg
     
    End Sub 
     
    Sub OSMOpen
     
      Open Table "G:\BaseData\Imagery\OpenStreetMap\OSM.TAB" 
      Add Map Auto Layer OSM
     
    End Sub
     
    Sub OSMClose
     
      Close Table OSM   
     
    End Sub 
     
    Sub EndHandler
     
    OnError GoTo ErrorOccured
     
      Call RBNEndHandler
      Exit Sub
    ErrorOccured:
      Call ERRCreate(Err(), Error$(), "EndHandler")
      Call ERRShow()
     
    End Sub



    ------------------------------
    Andrew Niebling
    Systems Administrator (GIS)
    Queensland Rail Ltd
    Brisbane QLD
    Australia
    ------------------------------



  • 4.  RE: Create ToggleButton

    Employee
    Posted 7 days ago

    Hi Andrew

    There are a few ways to do it, depending on how you want to have it work.

    I reckon these are base maps so you want the user to pick one or the other, right?

    If that's the case, I would add a check to each of the SwitchDisplay procedures to see if the other base map is open, and if it is call that SwitchDisplay procedure to get it closed before opening the other.

    Something along these lines:

    Sub AerialSwitchDisplay
     
    OnError GoTo ErrorOccured
    
      If mbOSMOpen Then
        '**OSM is open, let's close that layer before continuing
        Call OSMSwitchDisplay
      End 
    
      If mbAerialOpen Then
        Call RBNControlSetToolTipIdx(nCtrlIdx, PRGIGetApplicationName(), "Select to Turn QLD Imagery On.", "")
        Call RBNControlSetIconsIdx(nCtrlIdx, CONTROL_SIZE_LARGE, "", PATH_IMAGES + "AddImage_32x32.png")
        Call AerialClose
      Else
        Call RBNControlSetToolTipIdx(nCtrlIdx, PRGIGetApplicationName(), "Select to Turn QLD Imagery Off.", "")
        Call RBNControlSetIconsIdx(nCtrlIdx, CONTROL_SIZE_LARGE, "", PATH_IMAGES + "RemoveImage_32x32.png")
        Call AerialOpen
      End If
     
      mbAerialOpen = (Not mbAerialOpen)
      Call RBNControlSelectedIdx(nCtrlIdx, mbAerialOpen)
     
       Exit Sub
    ErrorOccured:
      Call ERRCreate(Err(), Error$(), "Main")
      Call ERRShow()
     
    End Sub

    In OSMSwitchDisplay, you would add this If statement:

      If mbAerialOpen Then
        '**Aerial is open, let's close that layer before continuing
        Call AerialSwitchDisplay
      End

    In this way, you don't have to disable the opposite control.

    Let me know how this works for you. Maybe I misunderstood your intention?



    ------------------------------
    Peter Horsbøll Møller
    Principal Presales Consultant | Distinguished Engineer
    Precisely | Trust in Data
    ------------------------------



  • 5.  RE: Create ToggleButton

    Posted 5 days ago

    Hi Peter,

    Yes, my intention was to not have both basemaps opened at the same time, so either open one base map and disable the other button until the user closed the first basemap then both buttons would be enabled again for selection.  

    Or the toggle button opens one base map and if the user selected the other button, then the first basemap would close and the second one would open and vice versa.

    I tried to implement both ways, but the button behaviour was very odd. I tried what you suggested but the buttons still wouldn't perform the actions correctly.

    I found that using nCtrlIdx as the control ID for both buttons is the problem, I don't know why that would be the case? (I am using Mapbasic v2023 by the way.) but 

    Changing all nCtrlIdx to nBtnAerial for the QLD Imagery button and 

    Changing all nCtrlIdx to nBtnOSM for the OSM button solved the problem, everything works perfectly now whether I disable the buttons upon selection or not.

    Thanks very much for your assistance with this :-)



    ------------------------------
    Andrew Niebling
    Systems Administrator (GIS)
    Queensland Rail Ltd
    Brisbane QLD
    Australia
    ------------------------------



  • 6.  RE: Create ToggleButton

    Employee
    Posted 4 days ago

    Hi Andrew

    Sorry, I missed that bit. Yeah, using nCtrlIdx for both buttons will cause issues as it can only refer to one of the controls, the last one.

    And you found the solution by using two separate variables for each button/control.

    I typically use the name nCtrlIdx when I create several buttons and don't care too much about the IDs for each. If I care about the IDs, I store them in a variable with a more specific name - just like you did now.

    If you start adding more and more base maps to your tool, you should consider using arrays for the base maps. Have a look at this #MapBasicMonday post. Maybe you have already seen it.

    Cheers

    Peter



    ------------------------------
    Peter Horsbøll Møller
    Principal Presales Consultant | Distinguished Engineer
    Precisely | Trust in Data
    ------------------------------