Need to store many checkboxes in integer/long

Just starting out? Need help? Post your questions and find answers here.
OgreVorbis
User
User
Posts: 79
Joined: Thu Jan 16, 2020 10:47 pm

Need to store many checkboxes in integer/long

Post 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.)
My blog/software site: http://dosaidsoft.com/
User avatar
mk-soft
Always Here
Always Here
Posts: 6286
Joined: Fri May 12, 2006 6:51 pm
Location: Germany

Re: Need to store many checkboxes in integer/long

Post 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.
My Projects ThreadToGUI / OOP-BaseClass / EventDesigner V3
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
OgreVorbis
User
User
Posts: 79
Joined: Thu Jan 16, 2020 10:47 pm

Re: Need to store many checkboxes in integer/long

Post 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
My blog/software site: http://dosaidsoft.com/
OgreVorbis
User
User
Posts: 79
Joined: Thu Jan 16, 2020 10:47 pm

Re: Need to store many checkboxes in integer/long

Post 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()
My blog/software site: http://dosaidsoft.com/
User avatar
HeX0R
Addict
Addict
Posts: 1209
Joined: Mon Sep 20, 2004 7:12 am
Location: Hell

Re: Need to store many checkboxes in integer/long

Post by HeX0R »

LOL, that's a pretty unconvential way, but I like it :D
User avatar
ChrisR
Addict
Addict
Posts: 1471
Joined: Sun Jan 08, 2017 10:27 pm
Location: France

Re: Need to store many checkboxes in integer/long

Post 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
infratec
Always Here
Always Here
Posts: 7658
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: Need to store many checkboxes in integer/long

Post 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
Jagermeister
Enthusiast
Enthusiast
Posts: 137
Joined: Thu Nov 15, 2012 11:38 pm
Location: Los Angeles

Re: Need to store many checkboxes in integer/long

Post 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
Post Reply