Create BevelButton Control Set that Acts Like a RadioButton Set

I have a control set of several bevelbuttons. I want to use these buttons in a similar way to radiobuttons so that only one button is pressed down at one time in the set.

By default, BevelButton does not have a sticky “pressed” condition. This means you will have to create your own.

You may want to subclass the BevelButton, and add a Selected boolean computed property which when true makes the backcolor of the button slightly darker, like when it is clicked.

Then to make sure only one is selected at a time, loop through all of the members and make sure only the one pressed is selected.

Here is an example : StickyBevelButton.xojo_binary_project

Thanks for your time. I tried the download and it did not work quite correctly - a single button would not stay down (10.9.5 OS X).

After further searching I combined information from several similar unsolved posts about the problem and added a bit of “luck” and have found a solution (cross fingers):

I have a bevelbutton control set of several buttons which is named TS2. The first button of index 0 is set to pressed state upon start (not required). This code is put in the action event of the control set. It does appear to make a difference how the buttons are set (bevel, toggle, sticky) as the code works. The result is that only one button can be pressed down at one time in the set.

I am using the caption of a button that is in the down state as a setting for another method. I wanted to use this option as opposed to radiobuttons (they take up more room) or a popupmenu (slower - user has to carefully manipulate it as opposed to just pressing a button in the set).

This code works withtout any problem and with no delay, but can it technically be written any more effeciently?

  Dim IN2 as integer
  
  For IN2 = 0 to Self.ControlCount - 1
    If Control(IN2) IsA TS2 then
      If IN2 <> Index then
        TS2(Control(IN2)).Value = False
      End if
    End if
  Next
  
  TS2(Index).Value = True

It could be made more efficient by collecting the controls into an array, say in Window.Open, and using that array directly, instead of looping through all the controls on the window. I’m not sure the improvement would be worth the added complexity, however, especially given that this code will only run in response to user interaction and will be quite unnoticeable either way.

Sounds like you want a segmented control set to have only one section pressed at a time

[quote=199783:@Edmundo Tata]Thanks for your time. I tried the download and it did not work quite correctly - a single button would not stay down (10.9.5 OS X).

After further searching I combined information from several similar unsolved posts about the problem and added a bit of “luck” and have found a solution (cross fingers):

I have a bevelbutton control set of several buttons which is named TS2. The first button of index 0 is set to pressed state upon start (not required). This code is put in the action event of the control set. It does appear to make a difference how the buttons are set (bevel, toggle, sticky) as the code works. The result is that only one button can be pressed down at one time in the set.

I am using the caption of a button that is in the down state as a setting for another method. I wanted to use this option as opposed to radiobuttons (they take up more room) or a popupmenu (slower - user has to carefully manipulate it as opposed to just pressing a button in the set).

This code works withtout any problem and with no delay, but can it technically be written any more effeciently?

  Dim IN2 as integer
  
  For IN2 = 0 to Self.ControlCount - 1
    If Control(IN2) IsA TS2 then
      If IN2 <> Index then
        TS2(Control(IN2)).Value = False
      End if
    End if
  Next
  
  TS2(Index).Value = True
[/code][/quote]

If you make sure your control set does not have hole (all members are consecutive), you do not need to go through all the controls on the window.

Why don't you simply loop only through TS2 members like this :

 [code]Dim IN2 as integer
  
  For IN2 = 0 to 9 // Up to the highest member index
        If IN2 <> Index then
          TS2(IN2).Value = False
        else
          TS2(IN2).Value = True
      End if
  Next

Yes, this suggestion is less code to run. I believe I may have had a gap in the indexes before.

Dim IN2 as integer
  
  For IN2 = 0 to 9 // Up to the highest member index
        If IN2 <> Index then
          TS2(IN2).Value = False
        else
          TS2(IN2).Value = True
      End if
  Next

I’ve modified it slightly so I need not have to hard code the total number of buttons into the code in case I add to delete buttons:

  Dim IN2 as integer = 0
  While TS2(IN2) <> Nil
    If IN2 <> Index then
      TS2(IN2).Value = False
    else
      TS2(IN2).Value = True
    End if
    IN2 = IN2 + 1
  Wend

Yes, that is similar to what I want. Its is 5 x 4 grid of buttons. I am trying to maintain a vertical strip of controls along the left edge of the main window while the right is used to display graphics. I thought the horizontal segmented control would eventually get in the way of the graphics area so I essentially opted for something that is visually similar to four stacked segmented controls.

Thanks for information. I think I will stay with the current option at this point mainly due to the added complexity.

I don’t know if its of interest, but I have used a list box for this in the past.
It already has a selected property, - I set it so that only one row can be selected at a time.
And I have full control over whats drawn in each cell.
If you add extra 'button’s , it scrolls for you too…