Connect IQ/Monkey C: Getting from menu and submenu to main screen with user inputs

325 views Asked by At

I'm trying to learn Monkey C and create a really simple application, a timer where you can specify how long a period should be and how many periods (soccer game). I'm trying to do this in the most simple way to be able to launch on the oldest wearables (FR230/235 and onward). The main view then holds a countdown from the selected period duration and indicate what period it's in, e.g. 1 of 3.

On my main Menudelegate I have a MenuInputDelegate with the two items: periodLength and numPeriods. Each of these tranistion to another MenuInputDelegate, via WatchUi.pushView, where you can choose length and number from a preset number of alternatives.

class RefMenuDelegate extends WatchUi.MenuInputDelegate {
    var Storage = App.Storage;

    function initialize() {
        MenuInputDelegate.initialize();
    }

    function onMenuItem(item as Symbol) as Void {
        if (item == :item_1) {
            var menu = new WatchUi.Menu();
            menu.setTitle("Perioder");
            menu.addItem("1", :Periods1);
            menu.addItem("2", :Periods2);
            menu.addItem("3", :Periods3);
            menu.addItem("4", :Periods4);
            System.println("Perioder");
            WatchUi.pushView(menu, new ChangePeriodsDelegate(), WatchUi.SLIDE_UP);
        } else if (item == :item_2) {
            var length_menu = new WatchUi.Menu();
            length_menu.setTitle("Periodlängd");
            length_menu.addItem("15:00", :Timer1);
            length_menu.addItem("20:00", :Timer2);
            length_menu.addItem("45:00", :Timer3);
            System.println("periodlängd");
            WatchUi.pushView(length_menu, new ChangePeriodLengthDelegate(), WatchUi.SLIDE_UP);
        }
    }

}

When a period length or a numPeriod have been chosen in the sub-level menu, properties are set with the Application.Properties.setValue("key", value), and the WatchUi.popView brings me back to the main menu.

class ChangePeriodLengthDelegate extends WatchUi.MenuInputDelegate {
    var Storage = App.Storage;

    function initialize() {
        MenuInputDelegate.initialize();
    }

    function onMenuItem(item as Symbol) as Void {
        if (item == :Timer1) {
            System.println("15 min");
            App.Properties.setValue("period_duration", 10);
        } else if (item == :Timer2) {
            System.println("20 min");
            App.Properties.setValue("period_duration", 15);
        } else if (item == :Timer3) {
            System.println("45 min");
            App.Properties.setValue("period_duration", 20);
        }
        WatchUi.popView(WatchUi.SLIDE_UP);
    }

}

I must have misunderstood how it all works, and I need some kind of tutorial. What happens now when i click "back" on the main menu, is that the main screen is showing, but not with my selected values. Only the "layout values" are shown from layout.xml. And when I click start, the watch starts, but not with the selected values, but with som default values (45 min, 2 periods).

class RefDelegate extends WatchUi.BehaviorDelegate {

    private var _inProgress = false;
    private var _periodStarted = false;
    private var _gameEnded = false;
    private var _currentDuration = 0;
    private var _periodDuration = 0;
    private var _totalTime = 0;
    private var _stopTime = 0;
    private var _currentPeriod = 1;
    private var _numPeriods = 0;
    private var _timer = new Timer.Timer();
    private var _view = getView();

    function initialize() {
        BehaviorDelegate.initialize();
        _periodDuration = App.Properties.getValue("period_duration") == null ? 45 : App.Properties.getValue("period_duration");
        _numPeriods = App.Properties.getValue("num_periods") == null ? 2 : App.Properties.getValue("num_periods");
    }

    function onSelect() as Boolean {
        if (_periodStarted == false && _gameEnded == false) {
            _view.updatePeriodValue(_currentPeriod);
            startGame();
        }
        if (_inProgress == false) {
            _inProgress = true;
        }
        else {
            _inProgress = false;
        }
        return true;
    }

    function updateTimerValues() as Void {
        if (_currentDuration == 0) {
            stopCountDown();
            _view.setGameStateValue(GameState.Paused);
            _currentPeriod++;
            if (_currentPeriod > _numPeriods) {
                _gameEnded = true;
            }
            _totalTime = (_currentPeriod - 1) * _periodDuration;
            _currentDuration = _periodDuration;
            return;
        }

        _totalTime++;
        if (_inProgress) {
            _view.setGameStateValue(GameState.Running);
            _currentDuration--;
        } else {
            _view.setGameStateValue(GameState.Paused);
            _stopTime++;
        }
        _view.setTimerValues(_currentDuration, _totalTime, _stopTime);
    }

    function startGame() {
        _timer.start(method(:updateTimerValues), 1000, true);
    }

    function stopCountDown() {
        _timer.stop();
        _inProgress = false;
    }

    function onMenu() as Boolean {
        WatchUi.pushView(new Rez.Menus.MainMenu(), new RefMenuDelegate(), WatchUi.SLIDE_UP);
        return true;
    }

}

I was expecting the main screen to show in a paused mode, where the countdown timer should show my selected value, e.g. 20 min, and the total number of periods, e.g. 1 of 2, should show up.

How should I properly move between menus and main screen and update main screen with correct values? The documentation is sparse regarding this.

0

There are 0 answers