How to format and display long text?

I'm trying to display a message which may be longer than screen width. What's the best way to format the message to display it as multiline?

Note, that the message comes from server, so it's not a hardcoded resource string.

I cannot see any tools for that, and neither Toybox::WatchUi::Text drawable nor Dc.drawText seem to have support for paragraph formatting.

Dc.getTextDimensions allows to determine width and height of text, so this is potentially helpful, but native apps (e.g. message notifier) do display properly formatted paragraphs, so I have an impression I'm missing something.

Thanks,
  • You have to do it yourself. This means breaking the text into lines that will be visible on the screen and then building functionality to scroll through those lines.

    Travis
  • Thank you Travis.
    That's what I was hoping to avoid as it's a very generic functionality :/

    Also, smooth scrolling doesn't seem to be possible for now using the SDK (I suppose touch screen devices in the SDK are relatively new addition), even though some system screens do use this functionality (together with nice bounce at the end of screen).

    Not showstoppers for my use cases, but makes development that little bit more complex.
  • Ui.animate() is the easier bit, but what's lacking is drag events. Currently only swipe and tap events are passed, so you cannot implement fluid scrolling as in Vivoactive app selection screen. SwipeEvent passes only direction, but no distance http://developer.garmin.com/downloads/connect-iq/monkey-c/doc/Toybox/WatchUi/SwipeEvent.html.
  • Certainly. When you get a swipe, you scroll a screen full of data, just like the built-in stuff.

    Travis
  • At least some of the built-in stuff (e.g. app selection screen on Vivoactive HR) tracks your finger nicely with pixel resolution rather than screen resolution. I guess this may be coming to the SDK at some point.
  • The native things don't use CIQ and can do things differently than CIQ things can. In CIQ, once you get the formatting/line splits worked out, can you do something where a swipe or up/down button just cycles though the text, by advancing/backing up a line or a page at a time?

    I have an app where I get a large amount of text back from a website, but found that at most it was 6 lines of data, and was able to display that on a single page. Here's how I start out my "Pretty Print" for the data BTW:

    var oneCharWidth=dc.getTextWidthInPixels("AbCdEfGhIj",Gfx.FONT_SMALL)/10;
    var charPerLine=width/oneCharWidth;

    I use a 10 char sting to get a estimate of how wide an "average" character is (I found that 10 was enough), and use that to figure out how many chars at most will fit on a line. Then I grab that many chars off the full string, and back up to a space, and use that as the display line. Then advance the full string to account for what's displayed, and repeat. (width=dc.getWidth(); )
  • Something else. When you see the swipe, do you do a Ui.requestUpdate() when it occurs? That way onUpdate() is called right away and you don't have to wait for calls to onUpdate().
  • Something else. When you see the swipe, do you do a Ui.requestUpdate() when it occurs? That way onUpdate() is called right away and you don't have to wait for calls to onUpdate().


    Thank you. Very interesting insight! I started working on similar heuristics as well. To save space and time I'm also preprocessing data on the server to shorted text to what will be visible.
    Yes, I do force updates whenever necessary.

    I'm now trying to figure out another conundrum - signing API calls from the watch. As far as I can tell there's no cryptography library within CIQ, but that's a story for a different thread...
  • The native things don't use CIQ and can do things differently than CIQ things can. In CIQ, once you get the formatting/line splits worked out, can you do something where a swipe or up/down button just cycles though the text, by advancing/backing up a line or a page at a time?

    I have an app where I get a large amount of text back from a website, but found that at most it was 6 lines of data, and was able to display that on a single page. Here's how I start out my "Pretty Print" for the data BTW:

    var oneCharWidth=dc.getTextWidthInPixels("AbCdEfGhIj",Gfx.FONT_SMALL)/10;
    var charPerLine=width/oneCharWidth;

    I use a 10 char sting to get a estimate of how wide an "average" character is (I found that 10 was enough), and use that to figure out how many chars at most will fit on a line. Then I grab that many chars off the full string, and back up to a space, and use that as the display line. Then advance the full string to account for what's displayed, and repeat. (width=dc.getWidth(); )


    Actually, according to wikipedia letter frequency page for english, and these calculations https://docs.google.com/spreadsheets/d/1jHo9NrHV4aZd5H7FOQREGJZ_W7EJkKDWJsFnoqu2w98/edit?usp=sharing
    better sample string for english would be 10 letter "EtaoiNshrd", or 20 letter "EeeTtaAooiNshRdlcumw", but it doesn't matter much if yours is working fine!