Buttons, You Really Push My Buttons

I kid you not, I have more to say about buttons.

Previously I experienced success with creating a grid of buttons that would display on the screen, but they didn’t do anything yet. Ultimately, I wanted to have users be able to press a ghost tile button and for the tile to register being touched by turning on like a light switch going from quarter opacity to full opacity. 

I began by utilizing a member function that allows the opacity of buttons to be set, which seemed like a surefire way to get the opacity of the buttons to change on press, but when running the Board Editor on a device I saw no inkling of an opacity change. When running the debugger I was able to confirm that the opacity function was indeed being entered and called on the button pressed. Yet again, a mystery was afoot!

Turns out, instead of setting the opacity of the ghost tiles when they were created, I was setting the lower opacity in the function that renders the view, which on the device at first looks just fine, but is very problematic since the rendering function gets called any time there is a change to the board, or any time it is “made dirty”. So, when a tile button was pressed, the opacity changed to full opacity, a change to the board occurred, and the render function got called, changing the button back to ghost state. The remedy was simple, once figured out, and voila, buttons were able to be pressed and turned on.

A few other things would also need to happen when a ghost tile would be touched, such as the counter incrementing and that tile actually being added to the board. Although I really should’ve focused on adding the tile to the board and working on the model side of things, I kept tinkering with the view and added the increment counter (and decrement counter) functions to the handler for the buttons so that the counter would increase/decrease accordingly.

This led me to discover a bug, which truly was more of a result of poor planning on my part. The accuracy of the counter in its current state requires that the designer use the board editor in a very specific way. They start in add mode by default and can immediately tap on ghost tile buttons to get them to appear at full opacity and the counter to increment. To remove a tile and have the counter remain accurate, a designer must press the remove button and then click the tile they want removed. However, currently, a tile that is at full opacity will go back to quarter opacity when tapped, regardless of the current mode. 

Various discussions with engineers illuminated for me how and why the counter should be tied to the current/latest board in the boards vector instead of being tied to the number of touches on the screen. This makes a whole lot of sense when you think about it–who knows how many tiles there are at any given time? The current board! In practice though, it took me a while to absorb this and rather than letting the counter be something implemented later, I impatiently wanted it “to work” now. My way of doing it works in theory, but not well in practice.

For now, the buggy counter will live on and I’ll ignore it while I get to work on what should’ve come first, the model.

Let’s Talk About Buttons

Last week with the delivery of the Project Plan, I had developed a strong sense of what I wanted the Board Editor UI to look like and generated a few prototypes to lean on as visual guides. 

The first key to getting into the Board Editor involved doing away with the Game View, so that the designer was presented with a clean, empty backdrop rather than the view of a Mahjong game to be played. By making a call to an existing MakeDirtyRecursively() function and setting up some logic for when to display the Game View or Board Editor View, I was able to get the Board Editor button in the Main Menu to result in an empty backdrop. 

With this small victory, I began going full tilt on getting the UI elements in my prototype to display in the Board Editor with the intention of fleshing out the actual implementations of those elements (i.e. export button when pressed fires the actions necessary to export the text file of the board design) later. 

The bulk of my time in this pursuit was spent examining other implementations of buttons in our game. I began with reviewing the Toolbar files and the way each button was created and added to the view hierarchy. Essentially I needed to determine if the app was in the Board Editor configuration and if so, if the user was in the Board Editor. If the user was in the Board Editor then a Save button  and Export button needed to be pushed onto the view, otherwise push the Hint button and Undo button onto the view.

As with each button element of the toolbar, the Save and Export buttons needed to have a texture/icon, a handler that would do whatever actions needed when pressed, and text for the button label, and pass these params to the ToolbarButton constructor. For now I left the handlers empty as I would write the actual functionality for these buttons later. For the textures, I opted to use pre-existing textures in our codebase for now and will add the exact textures I want for those buttons later on if time allows. Finally, for the text I simply passed the following strings: “SAVE” and “EXPORT”. In the end, this generated a Toolbar that closely matches the intended UI:

Toolbar from inside the Board Editor

Next up, I focused on getting an ADD button to the screen, which will eventually be the component to signal that the Board Editor is in add mode and taps to the screen should run the necessary functions for adding a tile in the touched location. To get this button added to the screen, I started reviewing implementations of PillButtons in other classes like MainView and EndOfGameScreen. There were a few functions I knew I needed to write based on reviewing these other classes. For starters I would need a function for getting the button rect (its positioning on the screen), one for getting the size of the button, and one for getting all of the button params to pass to the PillButton constructor.

After getting these functions written out and the code to successfully build, I was expecting to open the Board Editor and see a large blue button with a plus sign texture and the label “ADD”, but alas there was nothing displaying on the screen. Reviewing my code and comparing it to other buttons that were generated in other views, I grew increasingly frustrated and confused: where is the addTilesButton? I solicited the assistance of one of our software engineers who gave me an incredibly useful walk-through of the debug tools in Xcode, which allowed me to set breakpoints and ensure my functions were actually getting run by the program, and sure enough they were. This engineer was also now confused and curious–we had to crack the case of the missing pill button!

Both of us were thinking that either I needed to include a render function in my BoardEditorView (wrong!) or that the button was actually being rendered, we just weren’t seeing it because it was out of view (nope) or somehow hidden (much warmer).

At lunch I checked in with my mentor to see if they could take a look at what I’d implemented and see if they had any idea what steps to take next. We immediately set breakpoints and they confirmed that all of my functions were being properly called and that a button should be in the upper left corner of the screen. He then suggested removing the backdrop entirely and re-running the code. Sure enough, with the background texture removed, there was the missing addTilesButton in the top left corner, right where I placed it.

Apparently the BoardEditorView needed to be assigned to a DepthGroup in our game that set it at the same level as the GameView and by simply adding this to the BoardEditorView constructor, the addTilesButton displayed exactly where I told it to:

Stage 1 of creating the addTilesButton

Having implemented the addTilesButton, getting the removeTilesButton to the screen was quick work and with some tinkering of button params and adjustments to the button rect, I was able to get both buttons to the screen in a position that allows for the status bar to be displayed:

addTilesButton and removeTilesButton displaying in the Board Editor

I’m still working on getting a counter label to display and to have the add and remove buttons to update their color when selected/deselected, but for now I’ve at least started to hack away at getting some UI elements to display and that feels really good.