Page 1 of 1

Need to store many checkboxes in integer/long

Posted: Thu Mar 24, 2022 6:00 pm
by OgreVorbis
I have a program that has a window where there are checkbox gadgets for each day of the week. I want to save and load the sate of those checkboxes. I figure I could just somehow binary AND them or something like that. I don't want to store them as individual integers - that's junky. Could you provide an example? Actually, I could just use a byte and then have one extra bit for if the function is enabled.
One issue is that these checkboxes are created with the form designer and use #PB_Any for their numbers. The names are like: Checkbox_Mon, Checkbox_Tue. If I reference the first checkbox, can I just loop and add to a counter to get the latter ones or will they be all out of order? (Cause otherwise I'll have to mess with the form to make them indexed or just write code that assigns them all to an array.)

Re: Need to store many checkboxes in integer/long

Posted: Thu Mar 24, 2022 7:38 pm
by mk-soft
Just keep counting, because with PB_Any the numbers are unique.
Perhaps work in the FormDesigner without PB_Any in general.
Makes things much easier.

Re: Need to store many checkboxes in integer/long

Posted: Thu Mar 24, 2022 8:23 pm
by OgreVorbis
mk-soft wrote: Thu Mar 24, 2022 7:38 pm Just keep counting, because with PB_Any the numbers are unique.
I just made an array. That statement is contradictory because like you said I just checked and they are completely random. But no problem there...
I checked up the code to do bit manipulation and it's not clean. I could just copy it, but I don't understand it.
Can't I just somehow AND or OR with a specific number for each day? I don't have much experience dealing directly with bits.

Ex:

Code: Select all

Procedure.i SaveDays()
	ValueToStore.i = 0
	Dim WeekDay(6)
	WeekDay(0) = Checkbox_Mon : WeekDay(1) = Checkbox_Tue : WeekDay(2) = Checkbox_Wed : WeekDay(3) = Checkbox_Thu : WeekDay(4) = Checkbox_Fri : WeekDay(5) = Checkbox_Sat : WeekDay(6) = Checkbox_Sun
	For i = 0 To 6
		ValueToStore ?????????????????? GetGadgetState(WeekDay(i))
	Next
	ProcedureReturn ValueToStore
EndProcedure

Re: Need to store many checkboxes in integer/long

Posted: Thu Mar 24, 2022 8:54 pm
by OgreVorbis
I discovered I could do it this way cause it's super simple:

Code: Select all

Procedure.i SaveDays()
	BinBuilder.s = "%"
	Dim WeekDay(6)
	WeekDay(0) = Checkbox_Mon : WeekDay(1) = Checkbox_Tue : WeekDay(2) = Checkbox_Wed : WeekDay(3) = Checkbox_Thu : WeekDay(4) = Checkbox_Fri
	WeekDay(5) = Checkbox_Sat : WeekDay(6) = Checkbox_Sun
	For i = 0 To 6
		BinBuilder + Str(GetGadgetState(WeekDay(i)))
	Next
	ProcedureReturn Val(BinBuilder)
EndProcedure
For loading, seems like I can use Bin()

Re: Need to store many checkboxes in integer/long

Posted: Thu Mar 24, 2022 10:00 pm
by HeX0R
LOL, that's a pretty unconvential way, but I like it :D

Re: Need to store many checkboxes in integer/long

Posted: Thu Mar 24, 2022 11:08 pm
by ChrisR
You can try this idea, stored in 1 byte (WeekDay.b)

Code: Select all

EnableExplicit

Enumeration Window
  #MainWindow
EndEnumeration

Enumeration Gadgets
  #Check_Monday    = 1
  #Check_Tuesday   = 2
  #Check_Wednesday = 4
  #Check_Thursday  = 8
  #Check_Friday    = 16
  #Check_Saturday  = 32
  #Check_Sunday    = 64
EndEnumeration

Declare Open_Window(X = 0, Y = 0, Width = 160, Height = 220)

Macro SetWeekOfDay(WeekOfDay)
  SetGadgetState(WeekOfDay, Bool((WeekDay & WeekOfDay) = WeekOfDay))
EndMacro
  
Procedure Open_Window(X = 0, Y = 0, Width = 160, Height = 220)
  If OpenWindow(#MainWindow, X, Y, Width, Height, "WeekDay", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
    CheckBoxGadget(#Check_Monday,    20,  10, 120, 22, "Monday")
    CheckBoxGadget(#Check_Tuesday,   20,  40, 120, 22, "Tuesday")
    CheckBoxGadget(#Check_Wednesday, 20,  70, 120, 22, "Wednesday")
    CheckBoxGadget(#Check_Thursday,  20, 100, 120, 22, "Thursday")
    CheckBoxGadget(#Check_Friday,    20, 130, 120, 22, "Friday")
    CheckBoxGadget(#Check_Saturday,  20, 160, 120, 22, "Saturday")
    CheckBoxGadget(#Check_Sunday,    20, 190, 120, 22, "Sunday")
  EndIf
EndProcedure

Define WeekDay.b = 67   ; 67 = 1 + 2 + 64 (#Check_Monday + #Check_Tuesday + #Check_Sunday)

Open_Window()

SetWeekOfDay(#Check_Monday)
SetWeekOfDay(#Check_Tuesday)
SetWeekOfDay(#Check_Wednesday)
SetWeekOfDay(#Check_Thursday)
SetWeekOfDay(#Check_Friday)
SetWeekOfDay(#Check_Saturday)
SetWeekOfDay(#Check_Sunday)

Repeat
  Select WaitWindowEvent()
    Case #PB_Event_CloseWindow
      Break
    Case #PB_Event_Gadget
      If GetGadgetState(EventGadget())
        WeekDay = WeekDay | EventGadget()
      Else
        WeekDay = WeekDay &~ EventGadget()
      EndIf
      Debug WeekDay
  EndSelect
ForEver

Re: Need to store many checkboxes in integer/long

Posted: Fri Mar 25, 2022 8:02 am
by infratec
Btw., you can use this:

Code: Select all

EnumerationBinary
  #Check_Monday
  #Check_Tuesday
  #Check_Wednesday
  #Check_Thursday
  #Check_Friday
  #Check_Saturday
  #Check_Sunday
EndEnumeration

Re: Need to store many checkboxes in integer/long

Posted: Fri Mar 25, 2022 9:07 pm
by Jagermeister
By the title, a dev like Infratec would assume you want summed flag values - a true integer. By your own discovery, it looks like you maybe want a visual representation of boolean values - a boolean array (which would be concatenated into a string).

A database-centric dev like myself would find it easier with the visual route as that's easier to decode -by humans- across database fields.
[Note: Infratec is self-aware AI recording all human weaknesses for fun and profit.]

Code: Select all

;ENUMERATION

Enumeration gadgets
  #checkbox_1
  #checkbox_2
  #checkbox_3
EndEnumeration

;LISTS

Structure struc_checks
  gadget.i
  state.b
EndStructure

Global NewList list_checks.struc_checks()

;PROCEDURES

Procedure set_state()
  
  gadget = EventGadget()
  state = GetGadgetState(gadget)
  
  Debug "gadget: " + Str(gadget) + " , state: " + Str(state)
  
  ForEach list_checks()
    Select list_checks()\gadget
      Case GadgetID(gadget)
        list_checks()\state = state
        Break
    EndSelect
  Next
  
  ForEach list_checks()
    string$ + Str(list_checks()\state)
  Next
  
  Debug string$
  
EndProcedure

;START

pad = 8

winW = 200
winH = 200
title$ = "Checkbox Flags"
flags = #PB_Window_ScreenCentered |
        #PB_Window_SystemMenu

OpenWindow(#PB_Any , 0 , 0 , winW , winH , title$ , flags)

; Create an element along with each checkbox...

AddElement(list_checks()) : list_checks()\gadget = CheckBoxGadget(#checkbox_1 , pad , pad , 104 , 24 , "Checkbox 1")
AddElement(list_checks()) : list_checks()\gadget = CheckBoxGadget(#checkbox_2 , pad , GadgetY(#checkbox_1) + GadgetHeight(#checkbox_1) + pad , 104 , 24 , "Checkbox 2")
AddElement(list_checks()) : list_checks()\gadget = CheckBoxGadget(#checkbox_3 , pad , GadgetY(#checkbox_2) + GadgetHeight(#checkbox_2) + pad , 104 , 24 , "Checkbox 3")

BindEvent(#PB_Event_Gadget , @set_state())

;LOOP

Repeat
  event = WaitWindowEvent()
  
  Select event
    Case #PB_Event_CloseWindow
      shutdown = #True
  EndSelect
  
Until shutdown = #True

End
Around form designer generated code...

Code: Select all

;LISTS

Structure struc_checks
  gadget.i
  state.b
EndStructure

Global NewList list_checks.struc_checks()

;GLOBALS

Global Window_0

Global Checkbox_Mon, Checkbox_Tue, Checkbox_Wed

;PROCEDURES

Procedure set_state()
  
  gadget = EventGadget()
  state = GetGadgetState(gadget)
  
  Debug "gadget: " + Str(gadget) + " , state: " + Str(state)
  
  ForEach list_checks()
    Select list_checks()\gadget
      Case gadget
        list_checks()\state = state
        Break
    EndSelect
  Next
  
  ForEach list_checks()
    string$ + Str(list_checks()\state)
  Next
  
  Debug string$
  
EndProcedure

Procedure OpenWindow_0(x = 0, y = 0, width = 112, height = 88)
  Window_0 = OpenWindow(#PB_Any, x, y, width, height, "", #PB_Window_SystemMenu)
  Checkbox_Mon = CheckBoxGadget(#PB_Any, 8, 8, 100, 25, "Monday") : AddElement(list_checks()) : list_checks()\gadget = Checkbox_Mon
  Checkbox_Tue = CheckBoxGadget(#PB_Any, 8, 32, 100, 25, "Tuesday") : AddElement(list_checks()) : list_checks()\gadget = Checkbox_Tue
  Checkbox_Wed = CheckBoxGadget(#PB_Any, 8, 56, 100, 25, "Wednesday") : AddElement(list_checks()) : list_checks()\gadget = Checkbox_Wed
  
  BindEvent(#PB_Event_Gadget , @set_state())
EndProcedure

;LOOP

OpenWindow_0()

Repeat
  event = WaitWindowEvent()
  
  Select event
    Case #PB_Event_CloseWindow
      shutdown = #True
  EndSelect
  
Until shutdown = #True

End