Matrix and User Defaults

This seems to be my week for questions. First, a little background on this project:

I am working on an app that works with NFL stats. I have a list of 32 records (1 record for each team in the league). Each record has 70 key/value pairs.

I have a window that is displayed as a sheet (thanks to help from Shane’s book). This window contains 2 matrices, each with 18 checkboxes of the stats I may wish to have displayed beneath each team. The first matrix will control what is displayed in the first text field for each team and the second matrix controls what is displayed in the second text field for each team.

In an earlier post http://macscripter.net/viewtopic.php?id=37604 I had help disabling cells in one matrix that have been selected in the other (thanks Ric).

Now I need to store the states and enabled status of the cells of each matrix to user defaults. Below is code I have written in a test app. This app contains 2 matrices, each with 2 rows and 3 columns. My question: is this the most efficient way to get the state and enabled status of each cell in the matrices? If so, cool! I’m on the right track. If not, what is a better approach?

property mat1 : missing value -- IBOutlet for the first matrix
property mat2 : missing value -- IBOutlet for the second matrix

on changeState_(sender) -- IBAction connected to both matrixes
-- this if/then/else code sets the enabled of a cell in 1 matrix 
-- based on the state of the corresponding cell in the other matrix
	if sender is mat1 then
		mat2's cellAtRow_column_(sender's selectedRow(), sender's selectedColumn())'s setEnabled_(1 - (sender's selectedCell()'s |state|()))
	else
		mat1's cellAtRow_column_(sender's selectedRow(), sender's selectedColumn())'s setEnabled_(1 - (sender's selectedCell()'s |state|()))
	end if
		
-- This code cycles through all of the cells in both matrices and gets their state and enabled status
-- and logs it to the console. The code will be modified to write a list of lists to user defaults
	repeat with x from 0 to 1
		repeat with y from 0 to 2
			set c1State to mat1's cellAtRow_column_(x, y)'s |state|()
			set c2State to mat2's cellAtRow_column_(x, y)'s |state|()
			set c1Enabled to mat1's cellAtRow_column_(x, y)'s isEnabled()
			set c2Enabled to mat2's cellAtRow_column_(x, y)'s isEnabled()
			log {"mat1: ", c1State, c1Enabled} as text
			log {"mat2: ", c2State, c2Enabled} as text
		end repeat
	end repeat
	log return -- used to separate output in the console
end changeState_

Thanks in advance,
Brad Bumgarner

Is there some reason you can’t use bindings?

Shane,

I tried using bindings to save the selection state of the matrix buttons. Without bindings, the code below works fine to do what Brad wants:

on changeState_(sender) -- IBAction connected to both matrixes
		if sender is mat1 then
            log sender's selectedRow()
            log sender's selectedColumn()
            log sender's selectedCell()
            log sender's selectedCell()'s state()
			mat2's cellAtRow_column_(sender's selectedRow(), sender's selectedColumn())'s setEnabled_(1 - sender's selectedCell()'s state())
		else
			mat1's cellAtRow_column_(sender's selectedRow(), sender's selectedColumn())'s setEnabled_(1 - sender's selectedCell()'s state())
		end if
	end changeState_

But if I bind the Matrix’s Selected Values to Shared User Defaults Controller.values.bankA, then it works unless I deselect the last box in the matrix. When I do that, I get -1,-1, null for the log, and an error message ( -[AppDelegate changeState:]: unrecognized function state.) which makes sense since the selectedCell is null. What I don’t get is why there is an interaction between what the user defaults controller is doing, and what happens in the changeState_ method.

Ric

My first attempts were using bindings. I didn’t have the Selected Indexes option and Selected Values didn’t work. I created the matrices by embedding a checkbox in a matrix so maybe that had something to do with it. As a test I placed a radio button matrix in the window and that worked as described.

The other reason for going to code route is any changes to the selections (there can be multiple selected checkboxes per matrix) will affect other areas of the interface, i.e., what the label headings are and what data is displayed.

I ended up using variations of the handlers from Shane’s book (saveDefaults, retrieveDefaults and revertDefaults) as well as creating 2 of my own (getMatrixStateAndEnabled and setMatrixStateAndEnabled). Both of these handlers run x and y loops to get/set the state and enabled of each cell in the matrices. “Get” places values into lists and “Set” sets the states and enabled based on the values of the lists.

It works but I’m not sure if it is the most efficient way of doing it but it works. :roll eyes:

Thanks,
Brad Bumgarner

Yes, when I think about it more, bindings aren’t going to fly. I don’t think there’s any shortcut.