Better TextArea drawable?

I'm imagining a better TextArea drawable implementation that 1) handles (semi-)rounded screens without clipping, 2) works for older SDK versions and devices. Does such a component exist in some monkey barrel somewhere? If not, would anyone agree it would be beneficial to build and share?

  • I've not seen any common code for this, and for barrels, not all devices support them.

    But doing your own isn't that complex.

    Say you have a string, and you know the font to use, and the width you want as a max, as well as the number of lines.

    You figure out how many characters will fit on a line using getTextWidthInPixels and the max width.

    Then in that sub string, look for the last space, and use that as a break.

    Display that and then move to the next line and repeat until the string is complete or you hit max lines.

    Her's an example (a fr230).

    The code I use here is a bit of spaghetti code, and maybe I'll do something a bit more generic and post it.

  • In case this helps anyone else, I've thrown together https://github.com/zmullett/connectiq-sonos/blob/master/source/BetterTextArea.mc. It's pretty scrappy, but its purpose is twofold; to render screen-centered text better on rounded screen geometries, and to provide support for < 3.0.1 devices. Furthermore, I was receiving reports that some users' devices (Fenix 6, Venu, Vivoactive 4S) weren't rendering the official textarea (black screen where the text ought to be).

  • Hi Jim, is this example code still around somewhere?

  • Here's a very basic version.  

    //Figure out how many lines can be displayed based on dc height, the height of the 
    //font used, with y being where to start on the screem
    			var maxLines=((height-y)/smallH).toNumber()-1; //I want an extra line at the end
    			var text=(the string you want to display);
    
    			if(text!=null) {
    	    		var lines=0;   	
    	    		while(lines<=maxLines && text.length()>maxChars) {
    		    		var thisOne=text.substring(0,maxChars);
    					var i,j,l;
    					l=thisOne.length();
    					
    					i=thisOne.find(" ");
    					j=i;
    					while(j!=null) {			
    						j=thisOne.substring(i+1,l).find(" ");
    						if(j!=null) {i=i+j+1;}					 
    					}
    					if(i!=null ) {
    						thisOne=thisOne.substring(0,i);
    					}
    		    		
    		    		dc.drawText(centerW,y,smallF,thisOne,Gfx.TEXT_JUSTIFY_CENTER);
    		    		y+=smallH;
    		    		lines++;		    	
    		    		text=text.substring(thisOne.length()+1,text.length());			
    				}
    	    		if(text.length()>0 && lines<=maxLines) {
    	    			dc.drawText(centerW,y,smallF,text,Gfx.TEXT_JUSTIFY_CENTER);
    	    			y+=smallH;
    	    		}
    			}

    for maxChars, here's what I do:

    var ch=dc.getTextWidthInPixels(". 2345AbcEi", smallF)/10;
    maxChars=((width-10)/ch).toNumber();

    You may want to use a different formula, based on where on the screen you are displaying the text.

    Here's how it looks on a 945 with a string of forecast data.  The extra line is sunrise/sunset.

    Same code on a venu SQ

    Same on a venu:

    They are all using FONT_SMALL, so the differences you see are based on that font on each device.