Menu2 a lot of questions.

Hello!

I'm a beginner in garmin developing APP.. I have a Fenix 5x plus and I want to make a Windsurf APP.

the ideia is have an app with all my information about windsurf equipment.

when going windsurf, I will run the app, choose what sail I will use, what board and what fin, then it will only track me and record how many jibes, jumps and shows live time and speed.

I already search on this forum about my doubts but I still have ones.

To create a Menu 2, what I'm doing wrong?

what is the best way to create a menu like:

the menu is pre defined by me, will be like.

Sails
- 11 m2
- 9.4 m2
- 7.8 m2
- 7.1 m2
- 6 m2 
etc...

Boards
- Formula 161l
- Isonic 127l
- Simmer 116l
etc...

Fins
- 70 boss
- 70 Zfins
- 44 Vmax
-39 SMAX
etc...

I know it will be very hard to make this kind of app, but lets give a try... 

maybe 10 years a go on my free times I used to be "web developer", using javascript, php, Ajax, ASP, mySQL, HTML :D

Thanks!!!

menu.xml

<menu id="mainMenu_Windsurf">
    <menu-item id="item_sail" label="@Strings.menu_sail" />
    <menu-item id="item_board" label="@Strings.menu_board" />
</menu>

strings.xml

<strings>
    <string id="AppName">teste4</string>
    <string id="prompt">Windsurf APP</string>
    <string id="menu_sail">Sail</string>
    <string id="menu_board">Board</string>
</strings>

teste4App.mc

import Toybox.Application;
import Toybox.Lang;
import Toybox.WatchUi;

class teste4App extends Application.AppBase {

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

    // onStart() is called on application start up
    function onStart(state as Dictionary?) as Void {
    }

    // onStop() is called when your application is exiting
    function onStop(state as Dictionary?) as Void {
    }

    // Return the initial view of your application here
    function getInitialView() as Array<Views or InputDelegates>? {
        return [ new teste4View(), new teste4Delegate() ] as Array<Views or InputDelegates>;
    }

}

function getApp() as teste4App {
    return Application.getApp() as teste4App;
}

teste4Delegate.mc

import Toybox.Lang;
import Toybox.WatchUi;

class teste4Delegate extends WatchUi.BehaviorDelegate {

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


    function onMenu() as Boolean {

        var menu = new WatchUi.Menu2({:title=>"Wind Surf"});

            menu.addItem(new WatchUi.MenuItem("Sails",null,"item_sail",{}));
            menu.addItem(new WatchUi.MenuItem("Boards", null,"item_board", null));

            WatchUi.pushView(menu, new teste4MenuDelegate(), WatchUi.SLIDE_IMMEDIATE);

        return true;
    }
    

}

teste4MenuDelegate.mc

import Toybox.Lang;
import Toybox.System;
import Toybox.WatchUi;

class teste4MenuDelegate extends WatchUi.MenuInputDelegate {

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

    


    function onMenuItem(item as Symbol) as Void {

        // quando carrega no bortao "vermelho"
        if (item == :item_sail) {

            System.println("VELAS");

            //CREATE SUB MENU
            var menu_sub = new WatchUi.Menu2({:title=>"Sails Size"});

            menu_sub.addItem(new WatchUi.MenuItem("7.8",null,"sail1",null));
            menu_sub.addItem(new WatchUi.MenuItem("7.1", null,"sail2", null));
            menu_sub.addItem(new WatchUi.MenuItem("6", null,"sail3", null));

            WatchUi.pushView(menu_sub, new teste4MenuDelegate(), WatchUi.SLIDE_IMMEDIATE);

        } 
        else if (item == :sail1) { System.println("you chose sail 7.8"); }
        else if (item == :sail2) { System.println("you chose sail 7.1"); }
        else if (item == :item_board) { System.println("PRANCHAS"); }
    }

}

teste4View.mc

import Toybox.Graphics;
import Toybox.WatchUi;

class teste4View extends WatchUi.View {

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

    // Load your resources here
    function onLayout(dc as Dc) as Void {
        setLayout(Rez.Layouts.MainLayout(dc));
    }

    // Called when this View is brought to the foreground. Restore
    // the state of this View and prepare it to be shown. This includes
    // loading resources into memory.
    function onShow() as Void {
    }

    // Update the view
    function onUpdate(dc as Dc) as Void {
        // Call the parent onUpdate function to redraw the layout
        View.onUpdate(dc);
    }

    // Called when this View is removed from the screen. Save the
    // state of this View here. This includes freeing resources from
    // memory.
    function onHide() as Void {
    }

}

so... the only error is when I push the select button on "Sails", instead of open a new menu with new options (sail sizes), it doesn't do nothing...

Error: Symbol Not Found Error
Details: Failed invoking <symbol>
Stack: 

Encountered app crash.

  • Personally I have looked at the sample but they are riddled with incomprehensible logic.

    Understand those are writen by the Garmin CIQ folks that are the experts at how things should be written.  Maybe you need to spend a bit more time learning the code.

  • No. They need to simplify the stuff and bring it down to the core in an example. That is how you write documentation. It should be copy paste and run. 

    When I put their convoluted example into my app i was able to bring the example down to the bare bones and make it work. 

    The essence is this: gitlab.com/.../ConfirmMenu.mc delegate to deal with the change of text. 

    Essentially it was what I was expecting but the example made it like it was rocket science.

    Their example is to bring in a view. With a default text, than load the textpicker with a different default text and some other stuff. Why they dont open the initial view as a textpicker and on the entered text show it in some manner is beyond me.

    If you want me to lose you quickly add random code in examples. Because you start to wonder about: why are they doing this and should I be doing this? This is the sample.. so I should. Examples should be to the point, consise, short and clear.

    Thw link is gitlab.com/.../ConfirmMenu.mc L105

  • They need to simplify the stuff and bring it down to the core in an example. That is how you write documentation. It should be copy paste and run. 

    To be fair there are attempts to do this in the documentation, with simple examples that should be runnable.

    Unfortunately:

    - some examples are incorrect, because they don't compile

    - other examples are just wrong because the documentation is wrong (they'll run but they don't work exactly as described)

    The reason I complain is because I actually like Garmin products and I wish they were better. I don't want Apple to crush Garmin because Garmin has a fairly unique product in this niche. (I'm not counting Polar, Suunto, Coros, etc., although I've seen some runners switch to Coros.)

    I'm very realistic and I realize that Garmin won't stay afloat by fixing bugs, improving customer-facing UI/UX or massively improving Connect IQ. They obviously make money by releasing 12 new watches every year, each of which has a ton of new features that most people don't want or need. (But the key is there's a new feature for almost everyone.)

    Speaking of which, another anecdotal experience I've had is where people on [last year's flagship model]'s forum complain about all the bugs and issues in that model, but as soon as this year's model is announced, they're all "well, I'm beyond frustrated with [last year's model], so I guess I have no choice but to buy [this year's model] and hope for the best."

    Customers like that (I'm one of them) are how Garmin makes money. I don't buy a new Garmin every year, but I've bought more than I should.

    But take a look at the first page of the Fenix 7 forum. Tons of bugs, as usual.

    EDIT another example of software issues:

    https://forums.garmin.com/sports-fitness/running-multisport/f/forerunner-955-series/296142/garmin-strap-power-stryd-power-doubled-power-values-in-activity

    Basically the problem is that with the introduction of native power, Garmin users who run with the HRM-RUN chest strap and a Stryd are getting both native power and CIQ power in their fit files, but some services are are using native power instead of CIQ power, which is not what users want. You could argue those services are doing the wrong thing, but you could also argue that Garmin just made a major change without considering the downstream impact on the users and 3rd party services. (i.e. they gave users no way to opt out of native power)

    I complain because this is the kind of thing that happens over and over with Garmin. It seems to be part of the culture.

  • Hello everyone!

    Its true, I didnt know about the SDK examples... but thanks! now I know!! and will learn about with them.

    another thing.. I can't open the site https://developer.garmin.com/connect-iq/connect-iq-basics/

    actually I can't open any site about developer.garmin.com, only the forum... I'm on Mac M1 macOS Monterey 12.3.1 using the opera browser....

    as a newbie in developing garmin, I think garmin documentation has not so many examples.. you can see like a php.net manual, each "command" has a pratique example.

    I can tell you guys, before I do a POST in this forum, I do my search...

    thanks everyone!

  • The CIQ doc is also in the SDK,  With VS Code, from the command palette, Monkey C: View Documentation.  The API doc is better than what you see on the Web as it includes supported devices for things.

  • I can understand a whole lot but when you say I need to.. spend more time understanding the code for a simple thing you are ignoring easy to understand documentation.

    We have developers here who have trouble following a page with SDK/vscode install instructions.

    To reply to your points:

    I am probably an ignorant user or I dont use my watch to the fullest potential but I havent had (many/any) bugs with my forerunner 610, fenix3 or current fenix6. I do have problems with Linux support. I hated it that I could never use Connect's predecessor Express. I always needed a vm with Windows to fully use my watch. With the Android app I can finally use Connect propperly. But Linux support on CIQ fills the hate gap. At least I can dev on Linix now.

    I dislike the training (build) tools that they give you. You cant order them into folders. They sorta force you to use their training plans. Eventhough I want to use my own. Gimma a better UI! I've submitted several ideas and feedback to garmin: 0 response. 

    CIQ I dont have hateful feeling against, perhaps too naieve and relatively new developer in the MonkeyC world. It is fun, its different from my day job. But things do feel bolted on without propper (after) thought, mainly looking at you barrels and the typing system. It works, until you actually start using it and it breaks. 

    Barrels with annotations and tests: can only work when using all annotations, which goes against only import what you need. Multiple annotations: break. Devices: if you supply one it limits on which type of device a barrel runs. Supply none: works on all. I like it, means I dont need every device in the list and installed, but weird API. If you dont list permissions it doesnt mean you get all permissions. 

    What I do hate is the bug reporting and feature requesting method on these forums without a way to propperly track stuff. I also have no clue what the release notes of each SDK are and what the beta entails. Also the EULA should be booted ASAP. The 1990 called, they want their EULA back.

  • I can understand a whole lot but when you say I need to.. spend more time understanding the code for a simple thing you are ignoring easy to understand documentation.

    To be clear I never said that, that was Jim. What I said was some of the documentation is broken or out of date.

    We have developers here who have trouble following a page with SDK/vscode install instructions.

    TBH I'm not sure whether you're implying the documentation is good and people aren't reading it closely, or the documentation is bad and needs to be improved, although I'm leaning towards the former.

    CIQ I dont have hateful feeling against,

    CIQ was fun for me at first too. I ran into so many bugs, design issues and limitations that it isn't fun for me anymore, but maybe that's a me thing.

    It is nice to be able to make little apps, some of which I use on a day-to-day basis, some of which have little niche audiences.

    I don't hate CIQ or Garmin, I'm just a little jaded after being in the ecosystem for awhile. (My first watch was a FR210, so I've used Garmin running watches about as long as you have)

    But things do feel bolted on without propper (after) thought

    Yeah, to me it's not the bugs per se (everyone has bugs), it's the design issues, the bugs that recur over the years (e.g. Fenix and halved cadence, app settings and invalid characters), and the bugs that exist on a new product's release.

    I think some of this stuff is down to lack of resources.

    Honestly I've felt the same way at my old day job. I could literally predict some bugs years in advance, due to poor design choices....

    Gimma a better UI! I've submitted several ideas and feedback to garmin: 0 response. 

    When it comes to UI/UX, this is where I get the feeling Garmin just does not care, or it's not their area of expertise. I'm not allowed to complain about anything tho, and if I point to others who complain on these forums or elsewhere, they're just clueless. I do think a lot of people who use Garmin watches use them because not because they "like" Garmin but because they're used to Garmin and it's what their friends use. I don't hear the same enthusiasm from runners about their Garmin as I do when some of them talk about their new Apple Watch. Then again, largely different markets (although it's clear Garmin is trying to keep with music, an Apple Watch-like form factor, touch and OLED.)

    On a personal note, I feel like I use a Garmin watch in spite of its flaws, not because it's something I'm excited to use. I am happy that Garmin has improved a lot of things over the years. I never ran with music until I got a music-enabled watch, and the speed of the UI has improved a lot. The buttons of newer forerunners are way better than the older mushy blister-like buttons which were painful to press.

    As far as UI/UX goes, again I will say that the choice of this forum platform perfectly reflects Garmin's attitude towards UX. It's "good enough" and any obvious flaws are either no big deal and/or will never be fixed. Like sometimes I'm randomly unable to paste images inline and I have to upload them to an image host as an intermediate step. Then if I want to enlarge the tiny inline thumbnail, I have to edit the resolution manually. It's also funny how the migration from old to new forums broke inbound and outbound links, including links from Garmin's own blogs to here.

  • If you can't understand the samples in the SDK, you do need to spend time to understand why things are done this way with Monkey C.  This isn't like writing a app for a phone.  There is a learning curve to CIQ.  It's not something you can pick up in a few days.  It's become even a longer learning curve over the last 7 years as more things and more devices are added.

    I'd been professional programing for decades when I started with CIQ, and yes, I had a learning curve, and two biggies are that devices can be really different  and native fonts.

  • We clearly have different opinions. An example should be useable not a long read. The fun thing was, I read the docs and got confused.

    developer.garmin.com/.../TextPicker.html

    https://developer.garmin.com/connect-iq/api-docs/Toybox/WatchUi/TextPickerDelegate.html

    Look at the examples. Screenmessage has something there. But there is no view. You go to the sample dir. That has several views, none of it makes sense. The example can be made as simple as

    Ui.pushView(
            new Ui.TextPicker("foobarbaz"),
            new MyTextPickerDelegate(),
    Ui.SLIDE_TYPE
    );

    Why you are telling me I need a masters degree in English lit to understand the docs and examples is something I dont get.