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.

Appreciating the View

Much of my project brainpower this week was spent examining the existing view hierarchy for Brainium Mahjong and thinking about where the Board Editor will fit in and what its own view hierarchy should look like.

At a very basic level, the Mahjong view hierarchy looks something like this:

Starting from the root node and working my way down the tree, I pretty quickly determined that the BoardEditorView should sit at the same functional level as the GameView and should be inserted into the overall view hierarchy at this point. The resulting view hierarchy would now look something like this:

With this decided, the next step was to figure out where in the existing application would be the best entry point for accessing the Board Editor. In certain project builds there are menus for debugging that are accessed in different ways, but that logic didn’t seem appropriate for the Board Editor. In my mind I saw the access point for the Board Editor being a button that would then transport the designer to a clean backdrop display with a simple GUI for adding and removing tiles to create a new board design. Tinkering within the Mahjong app and inspecting the Toolbar, the ideal access point became clear–adding another button to the bottom of the Game menu. 

Current Game menu in Mahjong without the Board Editor

Having successfully built the project in Xcode, it was time to tinker with the MainView to add a Board Editor button to the Game Menu. I began by skimming the MainView.cpp file for how it implemented the Achievements button and began adding code to create the Board Editor button. 

This might be time to mention one important aspect of the Board Editor project. Since this tool lives within the actual Mahjong project and will soon be merged with the main branch, anything related to the Board Editor implementation needs to be written within #if BOARD_EDITOR…#endif to ensure that the Board Editor can only be accessed from a specific Board Editor build or when the “BoardEditor” build configuration is selected in Xcode. Although this can be laborious and seems to dirty the code a bit in cases of numerous #if..#endif guards, the majority of the implementation will be in separate board editor files with a single #if..#endif at the top and bottom of the file.

With some mimicry of existing code and frequent visitation to the Xcode error messages when trying to build, eventually I got a working button added to the Game Menu that when clicked, for the time being, saves the game state and slides the Game Menu down.

Board Editor button in the Game Menu of BoardEditor builds

Next up I’ll be coding the BoardEditorView to open to the selected user Backdrop with no tiles displayed, a tile counter at the top of the screen, and two buttons for adding and removing tiles.

Worth celebrating:

  • Made a new branch “board_editor” and initial commits to the project
  • Successfully created the Board_Editor build configuration and got the project building in Xcode!
  • Began fleshing out the view hierarchy for the Board Editor (read this post)
  • Selected logical UI entry point within the Mahjong project for the Board Editor to be accessed (Toolbar -> Game Menu -> Board Editor)
  • Added BoardEditorView to the view hierarchy
  • Added the Board Editor as an app on App Center for builds to be accessed by internal teams