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.

  • To be fair, you probably want to show an example of the TextPickerDelegate too. Then it becomes to difficult to show your example code in isolation, since the TextPickerDelegate is a separate class, and your example code will just be free-floating without any context.

    For example:

    // Simple example code
    Ui.pushView(
        new Ui.TextPicker("foobarbaz"),
        new MyTextPickerDelegate(),
        Ui.SLIDE_UP
    );
    
    // But what if we want to explain TextPickerDelegate too?
    // Now the code for the class is fully contextualized and the example code above is not
    class MyTextPickerDelegate extends WatchUi.TextPickerDelegate {
        function initialize() {
            TextPickerDelegate.initialize();
        }
    
        // Handle successful text entry 
        // 
        // text (string): the current value of the picker
        // changed (boolean): true if the current value is different from the initial value, false otherwise
        function onTextEntered(text, changed) {
          //...
        }
    
        // Handle cancellation of text entry
        function onCancel() {
            //...
        }
    }

    I kinda get why the examples are the way they are, although I'm not thrilled about them either.

  • TextPicker is a good example of "Learning Curve",  Some devices (va and Venu) have never supported it and those where it is available, it can vary between device types..

    You want to took at using the generic picker

  • Why is this a learning curve? It is a simple view that needs to be pushed and it has a delegate, similar to a Menu/Menu2/View/Confirmation: pushView(new Rez.Menus.MyMenu(), new MyMenu2Delegate()). I really don't see the learning curve. Just because it is supported on some devices and not others: we have has for that. The biggest difference is you'll probably never extend it.

    I think the TextPicker requires indeed both the Delegate and the Picker code to be in the same example at both locations in the documentation. Without the surrounding code where suddenly you are in a inputDelegate. Although I could also go for just a link to the TextPickerDelegate docs. See there for more information.

    The same goes for the Confirmation class.

    Garmin should hire some technical documenation writers to get their docs up to date.

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

    I know it was Jim.

    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.

    I'm split, I think the API documentation AND the Samples in the SDK need more loving. I think these:

    https://developer.garmin.com/connect-iq/connect-iq-basics/, https://developer.garmin.com/connect-iq/monkey-c/, https://developer.garmin.com/connect-iq/core-topics/, https://developer.garmin.com/connect-iq/reference-guides/, and https://developer.garmin.com/connect-iq/sdk/ are good. They give you a good starting point on where to start and how to start and so on.

    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.)

    I don't know, but I don't have any complaints about my Garmin watches... Nor does my friend who has the Garmin Dive version of my Fenix6 (The Decent2?). The only jab they might have is that I can reply to whatsapp on my watch and they can't because of their iPhone and I have Android.

    Garmin has to compete with Apple, Samsung and the likes as with Suunto and those types of watches. I never developed for Apple or Android, but I think we may see different weird things, although, Android being FOSS. Bug might be fixed by ppl who want some of the stuff fixed. We are here looking at three developers at Garmin for CIQ? I dunno about Apple's development team size, but since their whole product line is iOS in some way, shape or form they have way more development resources than Garmin.

    Garmin does have a different niche. People who workout/play sports and get a watch and a smart watch at that. Apple watch users are... I dunno what kind of users they are. But still, it is competition.

  • Ask yourself why you have such an issue with the samples and the doc, where many, many others don't (except maybe for typos in the doc)

    This is NOT Apple.  Maybe you should develop for Apple and not Garmin

  • I really don't understand what you are trying to say here? I can't say that the docs need improvement? Or I can't say that the API docs need improvement? Or I can't say that anything needs improvement? Uhh,. what?

  • I agree that Garmin could use some decent technical writers. As a coder who's written documentation in the past, it isn't easy (and I'm not a writer by education or trade.)

    Garmin does have a different niche. People who workout/play sports and get a watch and a smart watch at that. Apple watch users are... I dunno what kind of users they are. But still, it is competition.

    DC Rainmaker has a recent article about how Apple is trying to improve triathlon functionality in Apple Watches....

    And I know decent runners who use Apple Watch. Most runners only care about posting their runs to Strava to be honest. Even those who use Garmin often don't use their watches to the "fullest" (imo). For example, when I do workouts (like 8 x 800m intervals), I prefer to let the timer run during my rest intervals and I press lap before and after every interval, because I want to see all my data, and I want it separated into work and rest intervals. Others just press pause when they're resting and/or allow the watch to use default 1 km autolaps, which means they lose information about their workouts that people like me would care about.

    As far as Apple vs Garmin goes, I've seen some people say that they like the features and usability of the Apple Watch Workoutdoors app a lot, compared to their experience with Garmin:

    http://www.workoutdoors.net/

    Interesting review:

    https://apps.apple.com/app/workoutdoors/id1241909999?ls=1

    Hands down the best running app I have used!

    WorkOutDoors is hands down the best watch running app that I have used! I have run using Garmin for over a decade and really like Garmin. When I purchased my first iPhone I decided to also get an Apple watch.

    ...

    And then ... I found WorkOutDoors. I have never had so much power on my wrist.

    Interesting how a $5 app from an indie dev on an Apple Watch is good enough for a user who ran with Garmin for over a decade...

    One coworker who also uses Garmin said the main reason people use Garmin is because it was there first.

    As far as I'm concerned, I wouldn't switch because:

    - I still like the Garmin "ecosystem" (such as it is)

    - you get all the sport-focused features out of the box

    - 5 physical buttons (this is probably the least important feature for casual runners. For me it's important because I want a lap button for interval workouts and I run in all kinds of weather and temperatures.)

    - Battery life (to a lesser extent)

    don't have any complaints about my Garmin watches

    Some bugs/issues that I've seen with my 945 LTE (which has been out for more than a year now):

    - Can't pan/zoom map while the timer is paused

    - Map gets stuck while you're panning or zooming

    (Like it's annoying to pay a premium for mapping, but you can barely use it.)

    - Adding certain CIQ data fields in a certain order causes the field to crash

    - GPS turns off when you return to the watch face during an activity

    - Can't launch a CIQ widget during an activity (step backwards from 935)

    - If the activity background is black, then you can't really edit data fields because the watch shows black text on a black background. Not the end of the world, but shows that they didn't test stuff

    Previously there was an issue where you couldn't use a black background for your activity otherwise it would break some or most CIQ data fields, because the firmware would report that the activity had a white background.

    When I previously bought a 935 at near release, I had issues with turn-by-turn navigation which made the feature next to useless. I had to spend some time recreating the issue and going back and forth with Garmin support. At least they eventually fixed it.

    There were also a weird issue with the activity list getting corrupted when you added or reordered activities, which were never really resolved. Also a few other annoying issues that I can't recall.

    Yeah none of that stuff is the end of the world, but it's very annoying to pay a lot of money for something and it has very noticeable problems (to me) out of the gate. To me it just reflects a lack of attention to detail and/or poor testing practices at Garmin. Most of the most annoying bugs I've seen aren't even related to CIQ, so we can't blame it on the small CIQ team size.

    As overpriced as Apple is, it's never the case that I buy a new phone or tablet and find myself corresponding with Apple because some basic/integral feature just does not work properly. I get they have a lot more resources than Garmin though.

    Looking at the boards for other devices, I see people having issues like turning on the Fenix 7's flashlight during the day causes the watch to crash (lol) or music is always played at max volume. I would be pretty upset if any of that stuff happened to me.

    To be fair, I'm fairly happy with my 945 LTE, although I feel bad about the price.

    This is NOT Apple.  Maybe you should develop for Apple and not Garmin

    This is a weird kind of reverse elitism considering the market for iOS apps and devices is so much bigger than Garmin's. Most of my friends and acquaintances who have a Garmin don't know or care about CIQ.

    Can anyone actually make money doing CIQ or is it limited to a fun hobby for retired devs? Is the fact that the CIQ has such a high learning curve (according to you) a good thing? Should the barrier of entry for an ecosystem be inversely proportional to the amount of money you can make or the number of users you can reach?

    If I actually wanted to make money or just reach lots of users, it would indeed be a much more rational choice to develop for Apple or even Android. If I actually had to try to live off of the proceeds of Garmin CIQ development, it would make more sense for me to work at Starbucks.

    If I were a noob who wanted to learn about embedded development and systems programming, especially in a way that would help my career, it would probably make more sense to develop for raspberry pi. Or even if I just wanted to do fun projects as a hobby.

    Think anyone can get hired anywhere if all they have is "Connect IQ Monkey C" on their resume?

    For me, CIQ development only made sense because I already owned a Garmin watch and bc I had some free time on my hands.

    Or I can't say that anything needs improvement?

    That's basically it, right here.

    Similar convos happen when certain feature requests are made (like support for docker, continuous integration, etc.)

    New dev: Gosh it would be swell if [modern feature X] was supported!

    Existing dev: I've been here for 700 years and nobody's asked for that

    Like maybe the reason nobody asks for stuff is because they're shot down or ignored every time they ask for stuff.

  • https://forums.garmin.com/apps-software/mobile-apps-web/f/garmin-connect-web/306966/time-for-some-modernization---common-garmin

    It's the users who are wrong tho.

    Yes, obviously people who have issues are much more vocal than people who are happy, but it's telling that the same kinds of complaints recur over time.

  • For example, when I do workouts (like 8 x 800m intervals), I prefer to let the timer run during my rest intervals and I press lap before and after every interval, because I want to see all my data, and I want it separated into work and rest intervals. Others just press pause when they're resting and/or allow the watch to use default 1 km autolaps, which means they lose information about their workouts that people like me would care about.

    That is where I use the workout for. I'm now in injury mode, so I put my physical therapists plan into Garmin Connect. But next to the other (custom) training plans I have, the lists becomes HUGE and I can't order them. ***** annoying.

    I'm not making the switch because all my data in in Garmin. Although I use https://github.com/cpfair/tapiriik to sync stuff between Garmin and Strava. So it might be that all my history is already at Strava.

    And truthfully, I don't really see a need to change - Garmin gives me hardware wise everything I need.

    Edditting workouts is a bit of a pain. You cant crop them on the web, only on the app and than you cannot select what you want or don't want and hit delete. No.. you need to crop things all manual. A pain.

    Free weights training is also a bit weird. You can only set the weight after your set, while you know before the set how much weight you've added to the bar. Right? And it doesn't show you the amount of sets you've done, until you start the set and it tells you at which set you are. Changing the automatic guess of the exercise.. a squat is a squat, unless you add weights, than it becomes a barbell squat. But you can't say what you did on your watch, it is all post workout on connect.

    That's basically it, right here.

    Similar convos happen when certain feature requests are made (like support for docker, continuous integration, etc.)

    New dev: Gosh it would be swell if [modern feature X] was supported!

    Existing dev: I've been here for 700 years and nobody's asked for that

    I know, sometimes I think we can only have 256 things in CIQ because that's all one person can handle.

  • I know, sometimes I think we can only have 256 things in CIQ because that's all one person can handle.

    "Understand that 256 is a limit because it's all that can fit into 8 bits. I have decades of experience as a coder, I know these things"