Check gadget enable/disable status

Just starting out? Need help? Post your questions and find answers here.
User avatar
Shardik
Addict
Addict
Posts: 2058
Joined: Thu Apr 21, 2005 2:38 pm
Location: Germany

Re: Check gadget enable/disable status

Post by Shardik »

Cross-platform API-solution for Linux, MacOS and Windows:

Code: Select all

Procedure IsGadgetDisabled(GadgetNumber)
  CompilerSelect #PB_Compiler_OS
    CompilerCase #PB_OS_Linux
      Protected *Widget.GtkWidget = GadgetID(GadgetNumber)
      ProcedureReturn Bool(*Widget\state)
    CompilerCase #PB_OS_MacOS
      ProcedureReturn CocoaMessage(0, GadgetID(GadgetNumber), "isEnabled") ! 1
    CompilerCase #PB_OS_Windows
      ProcedureReturn IsWindowEnabled_(GadgetID(GadgetNumber)) ! 1
  CompilerEndSelect
EndProcedure

OpenWindow(0, 0, 0, 250, 105, "Disable/enable buttons...", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
ButtonGadget(0, 10, 15, 230, 30, "Disabled Button") : DisableGadget(0, 1)
ButtonGadget(1, 10, 60, 230, 30, "Enabled Button") : DisableGadget(1, 0)

Debug IsGadgetDisabled(0)
Debug IsGadgetDisabled(1)

Repeat
Until WaitWindowEvent() = #PB_Event_CloseWindow
Update: I extended the Windows API code with API code for Linux and MacOS to offer a true cross-platform solution without the disadvantages of the code examples of the following postings... :wink:

For those of you who don't need a cross-platform solution and don't want the additional source code lines for the other operating systems you only need to remove the unwanted source code lines. For Windows you simply change the procedure to

Code: Select all

Procedure IsGadgetDisabled(GadgetNumber)
  ProcedureReturn IsWindowEnabled_(GadgetID(GadgetNumber)) ! 1
EndProcedure
Last edited by Shardik on Wed Jul 31, 2013 5:21 pm, edited 4 times in total.
RASHAD
PureBasic Expert
PureBasic Expert
Posts: 4946
Joined: Sun Apr 12, 2009 6:27 am

Re: Check gadget enable/disable status

Post by RASHAD »

Cross platform

Code: Select all

Procedure IsGadgetDisabled(GadgetNumber)
  SetActiveGadget(GadgetNumber)
  If GetActiveGadget() < 0
     Debug "Gadget "+Str(GadgetNumber)+" Disabled"
  Else
     Debug "Gadget "+Str(GadgetNumber)+" Enabled"
  EndIf
EndProcedure

OpenWindow(0, 0, 0, 250, 105, "Disable/enable buttons...", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
ButtonGadget(0, 10, 15, 230, 30, "Disabled Button") : DisableGadget(0, 1)
ButtonGadget(1, 10, 60, 230, 30, "Enabled Button") : DisableGadget(1, 0)

IsGadgetDisabled(0)
IsGadgetDisabled(1)



Repeat
Until WaitWindowEvent() = #PB_Event_CloseWindow

Egypt my love
PB
PureBasic Expert
PureBasic Expert
Posts: 7581
Joined: Fri Apr 25, 2003 5:24 pm

Re: Check gadget enable/disable status

Post by PB »

> SetActiveGadget(GadgetNumber)

Eww, yuck! :) You shouldn't change the focus to test a state.
The gadget with the focus should stay that way at all times:

Code: Select all

Procedure IsGadgetDisabled(GadgetNumber)
  SetActiveGadget(GadgetNumber)
  If GetActiveGadget() < 0
     Debug "Gadget "+Str(GadgetNumber)+" Disabled"
  Else
     Debug "Gadget "+Str(GadgetNumber)+" Enabled"
  EndIf
EndProcedure

OpenWindow(0, 0, 0, 250, 150, "Disable/enable buttons...", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
ButtonGadget(0, 10, 15, 230, 30, "Disabled Button") : DisableGadget(0, 1)
ButtonGadget(1, 10, 60, 230, 30, "Enabled Button") : DisableGadget(1, 0)
StringGadget(2, 10, 110, 230, 30, "This is meant to have the focus!")
SetActiveGadget(2)

IsGadgetDisabled(0)
IsGadgetDisabled(1)

Repeat
Until WaitWindowEvent() = #PB_Event_CloseWindow
I compile using 5.31 (x86) on Win 7 Ultimate (64-bit).
"PureBasic won't be object oriented, period" - Fred.
User avatar
TI-994A
Addict
Addict
Posts: 2700
Joined: Sat Feb 19, 2011 3:47 am
Location: Singapore
Contact:

Re: Check gadget enable/disable status

Post by TI-994A »

SkyManager wrote:How can we check the gadget enable/disable status
something like getGadgetEnableStatus(#GadgetID)
Hi SkyManager. Here's a simple macro-based solution with no additional variables or arrays to maintain.

Code: Select all

Macro EnableGadget(gadgetNo)
  DisableGadget(gadgetNo, 0)
  SetGadgetData(gadgetNo, 0)
EndMacro

Macro DisableGadgetEx(gadgetNo)
  DisableGadget(gadgetNo, 1)
  SetGadgetData(gadgetNo, 1)
EndMacro

Procedure GadgetStatus(gadgetNo)
  ProcedureReturn -(GetGadgetData(gadgetNo) - 1)
EndProcedure

OpenWindow(0, 50, 50, 220, 75, "Gadget Enabled/Disabled")
ButtonGadget(0, 60, 15, 100, 20, "Click to toggle")
ButtonGadget(1, 60, 40, 100, 20, "TEST BUTTON")
DisableGadgetEx(1)

Repeat
  Select WaitWindowEvent()
    Case #PB_Event_CloseWindow
      appQuit = 1
    Case #PB_Event_Gadget
      Select EventGadget()
        Case 0
          If GadgetStatus(1)
            DisableGadgetEx(1)
          Else
            EnableGadget(1)
          EndIf
        Case 1
          DisableGadgetEx(1)
      EndSelect
  EndSelect
Until appQuit = 1
Simple and cross-platform. :)
Texas Instruments TI-99/4A Home Computer: the first home computer with a 16bit processor, crammed into an 8bit architecture. Great hardware - Poor design - Wonderful BASIC engine. And it could talk too! Please visit my YouTube Channel :D
RASHAD
PureBasic Expert
PureBasic Expert
Posts: 4946
Joined: Sun Apr 12, 2009 6:27 am

Re: Check gadget enable/disable status

Post by RASHAD »

OK PB how about that :)

Code: Select all

Procedure IsGadgetDisabled(GadgetNumber)
  Result = GetActiveGadget()
  If IsGadget(result) And Result <> GadgetNumber
     DisableGadget(Result,1)
  EndIf
  SetActiveGadget(GadgetNumber)
  If GetActiveGadget() < 0
     Debug "Gadget "+Str(GadgetNumber)+" Disabled"
  Else
     Debug "Gadget "+Str(GadgetNumber)+" Enabled"
  EndIf
  If IsGadget(result)
     DisableGadget(Result,0)
     SetActiveGadget(Result)
  EndIf
  
EndProcedure

OpenWindow(0, 0, 0, 250, 150, "Disable/enable buttons...", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
ButtonGadget(0, 10, 15, 230, 30, "Disabled Button") : DisableGadget(0, 1)
ButtonGadget(1, 10, 60, 230, 30, "Enabled Button") : DisableGadget(1, 0)
StringGadget(2, 10, 110, 230, 30, "This is meant to have the focus!")
SetActiveGadget(2)

IsGadgetDisabled(0)
IsGadgetDisabled(1)
Debug GetActiveGadget()

Repeat
Until WaitWindowEvent() = #PB_Event_CloseWindow
Egypt my love
BorisTheOld
Enthusiast
Enthusiast
Posts: 542
Joined: Tue Apr 24, 2012 5:08 pm
Location: Ontario, Canada

Re: Check gadget enable/disable status

Post by BorisTheOld »

@TI-994A -- This will only work if the gadget data is not already in use.

@RASHAD -- In an event driven system it's bad policy to change the program state in order to test the program state. All testing needs to be passive, otherwise the act of temporarily moving focus can cause big problems in the code.

In our own applications we assign a structure to each gadget to track it's status. The address of the structure is stored in the gadget data field. We do this because of the limitations in PB, such as the lack of many events and features that are standard in the native operating systems.

Each time we change the application state we modify the gadget status information. We also create custom events to simulate missing PB events, such as GotFocus and LostFocus for buttons.
For ten years Caesar ruled with an iron hand, then with a wooden foot, and finally with a piece of string.
~ Spike Milligan
RASHAD
PureBasic Expert
PureBasic Expert
Posts: 4946
Joined: Sun Apr 12, 2009 6:27 am

Re: Check gadget enable/disable status

Post by RASHAD »

Sorry BorisTheOld
I do not agree with you
Change the status of a an object (not the program) temporary then get the right status back at the same time will not cause any harm
sorry
Egypt my love
BorisTheOld
Enthusiast
Enthusiast
Posts: 542
Joined: Tue Apr 24, 2012 5:08 pm
Location: Ontario, Canada

Re: Check gadget enable/disable status

Post by BorisTheOld »

RASHAD wrote:Change the status of a an object (not the program) temporary then get the right status back at the same time will not cause any harm
When you change the state of a gadget, you're changing the state of the program. Events will be created that can have unexpected consequences. As TI-994A said, it's a bad idea.
For ten years Caesar ruled with an iron hand, then with a wooden foot, and finally with a piece of string.
~ Spike Milligan
User avatar
TI-994A
Addict
Addict
Posts: 2700
Joined: Sat Feb 19, 2011 3:47 am
Location: Singapore
Contact:

Re: Check gadget enable/disable status

Post by TI-994A »

BorisTheOld wrote:@TI-994A -- This will only work if the gadget data is not already in use.
Of course, but the gadget data is perfect for these types of flags. After all, not much can be done with this single numeric field.
BorisTheOld wrote:As TI-994A said, it's a bad idea.
I believe that's a misquote. :lol:

However, both points have merit. On the one hand, it may be alright to programmatically change focus, if such a change is associated with some user-initiated event. But, on the other hand, it may not be a good idea to automate such changes, as it can interfere with normal input and work flow. IMHO.
Last edited by TI-994A on Wed Jul 31, 2013 3:14 pm, edited 1 time in total.
Texas Instruments TI-99/4A Home Computer: the first home computer with a 16bit processor, crammed into an 8bit architecture. Great hardware - Poor design - Wonderful BASIC engine. And it could talk too! Please visit my YouTube Channel :D
RASHAD
PureBasic Expert
PureBasic Expert
Posts: 4946
Joined: Sun Apr 12, 2009 6:27 am

Re: Check gadget enable/disable status

Post by RASHAD »

I still do not agree with you
Shall we ask Fred to not support anymore HideGadget(),DisableGadget()
and MicroSoft as well ?
TI-994A did not say it's a bad idea
PB who said that
Egypt my love
BorisTheOld
Enthusiast
Enthusiast
Posts: 542
Joined: Tue Apr 24, 2012 5:08 pm
Location: Ontario, Canada

Re: Check gadget enable/disable status

Post by BorisTheOld »

RASHAD wrote:Shall we ask Fred to not support anymore HideGadget(),DisableGadget()
and MicroSoft as well ?
That's a specious argument.

I'm saying that if you temporarily move focus from one gadget to another, then move focus back to the original, you will create a series of LostFocus/GotFocus events that might cause problems in the code. Depending on the program logic, fields may get re-initialized out of sequence, or data may be written to files. It's just not a good idea.
RASHAD wrote:TI-994A did not say it's a bad idea
PB who said that
I misspelt PB's name. :)
For ten years Caesar ruled with an iron hand, then with a wooden foot, and finally with a piece of string.
~ Spike Milligan
PB
PureBasic Expert
PureBasic Expert
Posts: 7581
Joined: Fri Apr 25, 2003 5:24 pm

Re: Check gadget enable/disable status

Post by PB »

> you will create a series of LostFocus/GotFocus events

+1. Of course, you can code around it (set a flag when
you're doing focus change) but why should we need to?
A cross-platform PureBasic command is needed for this.
I compile using 5.31 (x86) on Win 7 Ultimate (64-bit).
"PureBasic won't be object oriented, period" - Fred.
User avatar
JHPJHP
Addict
Addict
Posts: 2251
Joined: Sat Oct 09, 2010 3:47 am

Re: Check gadget enable/disable status

Post by JHPJHP »

Not sure it makes a difference: PB 5.20 Beta 8 x86 (Windows 7 64bit)

Even though the documentation states there is no return value...
- and yes I realize that the state is being changed (but only half of the time) :)

*** I would use the Shardik solution posted above before my example ***

Code: Select all

Procedure.s IsGadgetEnabled(gNumber)
  Result.s = ""
  
  Select 8
    Case DisableGadget(gNumber, 0)
      DisableGadget(gNumber, 1)
      Result = "Disabled"
    Default
      Result = "Enabled"
  EndSelect
  ProcedureReturn Result
EndProcedure

If OpenWindow(0, 0, 0, 250, 105, "Disable/enable buttons...", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  ButtonGadget(0, 10, 15, 230, 30, "Disabled Button") : DisableGadget(0, 1)
  ButtonGadget(1, 10, 60, 230, 30, "Enabled Button") : DisableGadget(1, 0)
  Debug IsGadgetEnabled(0)
  Debug IsGadgetEnabled(1)
  Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow
EndIf

If you're not investing in yourself, you're falling behind.

My PureBasic StuffFREE STUFF, Scripts & Programs.
My PureBasic Forum ➤ Questions, Requests & Comments.
PB
PureBasic Expert
PureBasic Expert
Posts: 7581
Joined: Fri Apr 25, 2003 5:24 pm

Re: Check gadget enable/disable status

Post by PB »

> if you temporarily move focus from one gadget to another,
> then move focus back to the original

You will interrupt the user when they're typing or selecting text.
I compile using 5.31 (x86) on Win 7 Ultimate (64-bit).
"PureBasic won't be object oriented, period" - Fred.
User avatar
TI-994A
Addict
Addict
Posts: 2700
Joined: Sat Feb 19, 2011 3:47 am
Location: Singapore
Contact:

Re: Check gadget enable/disable status

Post by TI-994A »

Here's another cross-platform approach that handles the DisableGadget() and HideGadget() functions. Instead of making separate calls to enable/disable or show/hide the gadgets, only single calls are required to toggle their states. It makes use of the gadget-data integer on a bitwise level, allowing more than one flag to be set for each gadget:

Code: Select all

EnableExplicit
#bitShow = 0
#bitEnable = 1
Define gadgetData, wFlags, appQuit, vStat.s, eStat.s

Macro EnableGadget(gadgetNo)
  gadgetData = GetGadgetData(gadgetNo)
  gadgetData!(1<<#bitEnable)
  DisableGadget(gadgetNo,
  (gadgetData&(1<<#bitEnable))>>#bitEnable)
  SetGadgetData(gadgetNo, gadgetData)
EndMacro

Macro ShowGadget(gadgetNo)
  gadgetData = GetGadgetData(gadgetNo)
  gadgetData!(1<<#bitShow)
  HideGadget(gadgetNo,
  (gadgetData&(1<<#bitShow))>>#bitShow)
  SetGadgetData(gadgetNo, gadgetData)
EndMacro

Macro GadgetEnabled(gadgetNo)
  -(((GetGadgetData(gadgetNo)&(1<<#bitEnable))>>#bitEnable) - 1)
EndMacro

Macro GadgetVisible(gadgetNo)
  -(((GetGadgetData(gadgetNo)&(1<<#bitShow))>>#bitShow) - 1)
EndMacro

vStat = "Visible" : eStat = "Enabled"
wFlags = #PB_Window_SystemMenu | #PB_Window_ScreenCentered 
OpenWindow(0, 50, 50, 220, 100, "Gadget States", wFlags)
ButtonGadget(0, 15, 10, 120, 25, "ENABLE/DISABLE -->")
ButtonGadget(1, 15, 40, 120, 25, "SHOW/HIDE -->")
ButtonGadget(2, 150, 10, 50, 55, "TEST")
TextGadget(3, 15, 75, 200, 20, "Test Button Status: Visible && Enabled")

Repeat
  Select WaitWindowEvent()
    Case #PB_Event_CloseWindow
      appQuit = 1
    Case #PB_Event_Gadget
      If EventGadget() < 2
        Select EventGadget()
          Case 0
            EnableGadget(2)
            eStat = StringField("Disabled Enabled", 
                                GadgetEnabled(2) + 1, " ")
          Case 1
            ShowGadget(2)
            vStat = StringField("Hidden Visible", 
                                GadgetVisible(2) + 1, " ")
        EndSelect
        SetGadgetText(3, "Test Button Status: " +
                          vStat + " && " + eStat)
       EndIf
  EndSelect
Until appQuit = 1
It essentially expands the single gadget-data integer into its multiple bits. :wink:
Texas Instruments TI-99/4A Home Computer: the first home computer with a 16bit processor, crammed into an 8bit architecture. Great hardware - Poor design - Wonderful BASIC engine. And it could talk too! Please visit my YouTube Channel :D
Post Reply