Results 1 to 14 of 14
Like Tree12Likes
  • 2 Post By jonwise80
  • 1 Post By jonwise80
  • 2 Post By jonwise80
  • 2 Post By jonwise80
  • 1 Post By Grabber5.0
  • 1 Post By Misj'
  • 2 Post By jonwise80
  • 1 Post By jonwise80
  1.    #1  
    Although the documentation is better preserved than some other "dead" platforms I've tinkered with, there's still a lot of gaps to leap between in trying to figure out how to get started. I figured I'd start a thread of my own foibles, in case it benefits anyone else who wants to try.

    A couple resources I've found so far:
    • The Wayback Machine SDK Archive is in decent shape.
    • At least 172 pages of the original O'Reilly Press "Palm webOS: The Insider's Guide" can be found on Google Books. I also ordered a paperback copy from Amazon. Its pretty good at filling in the gaps.
    • This tutsplus Introduction to webOS SDK tutorial has some good stuff.

    Some none-obvious things that probably should be obvious:
    - Mojo means webOS 2.x and earlier
    - Enyo means webOS 3.x and seems to only ever have come to the TouchPad.

    I decided to start with Mojo, and try to figure out how to make my apps scale well onto the TouchPad. Not sure if that's possible, but it seems like others have managed to target both big and little screens with a single .ipk, so there must be a way to do it without writing the code twice.

    Goals
    Other than adding to the community, there are a couple things I want my Pre to do that I can't find nice solutions for. Once I get through a "Hello World" I want to start with these two apps:
    • Stopwatch: This should be a simple starting point. I use my iPhone stop-watch daily for exercises, and other than a sample from HP, I haven't found one for my Pre. I'm going to "take inspiration" from the iOS one, and try to make it beautiful and simple, while adapting to the webOS widgets and design language.
    • Philips Hue Light Control: Obviously a little harder than a stop watch, but the Hue Bridge has a nice and easy-to-understand REST API. I've written sample apps for it in a dozen languages, and it requires no service-side access, so i can do it all in client-side Javascript -- which should work well on the Pre. I've got 4 light zones, and almost a dozen bulbs in my house, so it'll be worth the effort for me.

    Neither of these will exercise NodeJS for back-end services on the phone. But I'll get to that later. I use Node every day at work, so I'm hoping that'll be an easy next step.

    Observations (So Far)
    Palm went really hard-to-the-hoop with their MVC implementation, and its a bit of a pain in the bum. Fortunately, the phone won't complain too much if you just start hacking with a simple webpage with some embedded script. But I want to learn their intent, and in general, I agree with the MVC pattern, so I'm slogging through. Newbie things I had to learn the hard way:

    • The SDK documentation goes on ad-naseum about their app model, but all you really need to know is that your app's card is called a Stage. Apps that spawn multiple cards (like e-mail) have multiples Stages. Think of the Stage like a browser tab. Just like a browser, you can move between pages within a tab, in webOS those pages are called Scenes. You navigate between Scenes by putting them on-and-off the stack, much like the back-stack in a browser. Most simple apps need only one stage, but only the simplest will have a single scene.
    • The index.html that the SDK generates for you is a stub. Its used for setup of the Stage, but you won't have content in there. Instead, your content goes into your Scenes, which are other .html files that are fragments. These get loaded into your Stage when the Scene is pushed forward.
    • The Scene .html is used for layout only. Their pattern is not to put content in there -- you can, but that's not what the tutorials want. Instead, the SDK generates a supporting javascript file, called the Assistant. The scene HTML and Assistant have the same file name, but a different extension -- that's how the SDK knows they're related.
    • The Stage has an Assistant too, so far I've only seen it used for pushing the default Scene on start-up.
    • Inside the Assistants, you have to "setup" your widgets that you've previously laid out in HTML. This is a side-effect of their strict MVC separation and is a pain. In normal web development, putting something in the mark-up also instantiates it in the DOM. In Mojo, you have to do this manually. (The analogy that works for me is that its like the "code-behind" in ASP.NET -- only in that, VisualStudio does these things for you!)
    • Once set-up, you also use the Assistant to bind your handlers to your widgets. You might have done this manually in Javascript, but here again, in simple HTML this would have been...simpler. Obviously you have to define your handlers as functions in the Assistant too -- before they can be bound.


    Dev Environment
    You can set-up as much or as little environment as you want. At a minimum, you need the SDK itself. This gives you the command line utilities to generate app and scene structures, to build your app, and to deploy it to an emulator or Developer Mode phone.

    Once installed, the SDK comes with a bunch of sample apps and source code. The most useful one so far, for me, has been the UIWidgets one -- which helps learn what's possible within the UI.

    I haven't tried the Eclipse plug-in, mostly because it requires a really old version of Eclipse that I haven't been able to hunt down yet. It doesn't seem like it adds a lot of value -- I like VisualStudio Code for web development, and this is pretty close. The command-line tools are simple enough to use too.

    The emulator is strictly a nice-to-have -- you can get away with just having a phone. The emulator requires VirtualBox 4.0 or 4.1 -- but even within those versions, specific builds just refuse to start the VM. I finally went back to VirtualBox builds near 2011 (when the SDK was last updated) and got 4.1.0 r73009 to work, on Windows 7 32-bit, as long as VirtualBox was started "As Administrator."

    Obviously Windows 7 32-bit is not an ideal environment in 2018, but I suspect if I decide to abandon the emulator and just develop against my phone, I'll have much more platform flexibility.

    Hello World
    With these learnings behind me, I was finally able to lay out a Scene that did something when a button was pressed. It says Hello World, of course, but its a start. Important note, you must do your widget setups before you do your bindings. Here's the scene Assistant code:

    Code:
    WatchViewAssistant.prototype.btnOkHandler = function()
    {
    	Mojo.Log.info("The OK button was pressed");
    	this.controller.get("watchViewSummary").innerHTML = "Hello world!";
    }
    
    WatchViewAssistant.prototype.setup = function() {
    	/* this function is for setup tasks that have to happen when the scene is first created */	
    	/* use Mojo.View.render to render view templates and add them to the scene, if needed */
    	
    	/* setup widgets here */
    	var watchViewTitleElement = this.controller.get("watchViewTitle");
    	var watchViewSummaryElement = this.controller.get("watchViewSummary");
    	watchViewTitleElement.innerHTML = "Jon is cool!";
    	watchViewSummaryElement.innerHTML = "This is my first app!";
    	Mojo.Log.info("Scene started!"); 
    	
    	this.controller.setupWidget('btnOk', this.attributes={}, this.model={label:"OK", disabled: false});
    	this.btnOkHandler = this.btnOkHandler.bind(this);
    };
    HelloWorld.PNG

    Next, I'll work on laying out my Stop Watch UI.
    Last edited by jonwise80; 10/06/2018 at 09:29 PM.
    Nafetz and mazzinia like this.
  2.    #2  
    Today's fun with trial-and-error was about trying to disable a button once its been clicked. You can set buttons to disabled during setup in the Assistant, or during declaration in the HTML, but changing it on an event... well, in pretty much any other environment, this would involve setting the button's enabled value to false, or disabled value to true. In fact, I was teaching some high school kids Scratch last week, and they were doing just this in only the third lesson!

    Palm, in their wisdom, decided not to make it quite so simple. You have two choices -- one is to use a button class that has a mojo attribute that allows it to stay stuck down:
    Code:
    x-mojo-tap-highlight="persistent"
    Your other choice is to change the button's setup -- which requires setting it up again! Unless you had your button's setup stored as a global variable (and why would you), you need to fetch it from the button, change it and put it back. I can't find a way to do this with less than 4 or 5 lines of code. Since I was constantly toggling buttons, I made a helper method, that I can call like this:
    Code:
    this.SetWidgetDisablement("btnStart", true);
    With some logging, so I could see what was going on, the helper looks like this. (Note: JSON.stringify is a beautiful thing!)

    Code:
    WatchViewAssistant.prototype.SetWidgetDisablement = function(widgetName, newvalue)
    {
    	var thisWidgetSetup = this.controller.getWidgetSetup(widgetName);
    	Mojo.Log.info("was: " + JSON.stringify(thisWidgetSetup));
    
    	var thisWidgetModel = thisWidgetSetup.model;
    	thisWidgetModel.disabled = newvalue;
    
    	Mojo.Log.info("set to: " + JSON.stringify(thisWidgetModel));
    
    	this.controller.setWidgetModel(widgetName, thisWidgetModel);
    	//This might not be necessary. Nothing seems to care, but this site said to do it: https://semisignal.com/changing-the-model-of-activity-buttons-on-webos/
    	this.controller.modelChanged(this.controller.get(widgetName));
    	Mojo.Log.info("is now: " + JSON.stringify(thisWidgetSetup));
    }
    Addendum: Technically, you have a third choice. You can use an HTML button, instead of the Palm button widget. But then you lose other features.
    StopWatchLayout.PNG
    Now my buttons toggle, and interact with the stopwatch area of the UI. Next up is the timer logic...and the icon. Maybe I'll do the icon first, to take a break from Mojo!
    Nafetz likes this.
  3. #3  
    Quote Originally Posted by jonwise80 View Post
    Some none-obvious things that probably should be obvious:
    - Mojo means webOS 2.x and earlier
    - Enyo means webOS 3.x and seems to only ever have come to the TouchPad.

    I decided to start with Mojo, and try to figure out how to make my apps scale well onto the TouchPad. Not sure if that's possible, but it seems like others have managed to target both big and little screens with a single .ipk, so there must be a way to do it without writing the code twice
    Preware is an example of a mojo app that scales. Http://github.com/webos-internals/preware

    The Phones (2.2.4) support Enyo 1. You probably know that phone (sized) mojo apps will display in an emulator on the TouchPad, which also supports Enyo 2.
    mojo is closed source. Enyo is open-source. Enyo apps will work on LuneOS (though mojo could probably be installed if required).

    With different resources (Moonstone vs Onyx) Enyo was used to create LG webOS TV apps. The latest TV app framework is called Enact and is based on React. LG released a new open source version of webOS called webOS OSE to encourage application beyond TVs. This also supports Enact.

    Fears about Facebook's licensing of React caused webOS Ports to diverge from LG and choose Polymer as their framework of choice for LuneOS (though at this point, I'm unclear if any apps have actually been written). As much of the UI is Qt, QML is also an option for apps.

    I hope I got all that right. It's become complex, but hopefully you can see the options depending on what versions of webOS you are interested in developing for.

    There are a number of stopwatch apps already available for webOS, but I assume you are doing yours as a learning exercise. Your posts so far are an interesting read!

    Some developer resources are listed in the status report linked below.
    Last edited by Preemptive; 10/06/2018 at 07:24 PM.
  4.    #4  
    Quote Originally Posted by Preemptive View Post
    I hope I got all that right. It's become complex, but hopefully you can see the options depending on what versions of webOS you are interested in developing for.
    Wow, that is complex! I wonder if they managed to hang on to any developers through that evolution, or if they had to evangelize new support with each iteration.
    Mostly, I just want to not use an iPhone, so I want to learn to build things that are useful to me on my Pre. But its also interesting history and tech. There are real moments of brilliance in this platform (and a few head scratchers!) It would have been nice if so many people hadn't tried to hard to put a bullet it in...

    Thanks for the links! I read a lot of this site before I started tinkering. I picked up a spare Pre 1st gen with a dead digitizer, so I guess I'll be doing some hardware tinkering soon too!
  5. #6  
    Some things here might also be useful: www.banneret.nl/webos/documentation

    good luck on your endeavor.

    Personally I can offer more help on Enyo (and general Javascript) than Mojo. And in my opinion Enyo works quite well on phones as well...until you want to scroll; then you have to do some trickery to make it usable (and still it won't be as good as a Mojo app for some reason). Also, for Enyo I mostly debug in my desktop browser (technically that's also possible with Mojo up to a certain degree, but you will have to set up your desktop/windows quite well, strip all framework requirements from the doctor, etc...and I haven't done that since my harddrive broke down).
    Last edited by Misj'; 10/07/2018 at 03:43 PM.
  6. #7  
    Hi,

    I started developing Mojo a few months before the shutdown of the HP servers and my programming skills seem to be lower than yours ("just-for-fun-programmer"). So your posts are very interesting for me.

    Quote Originally Posted by jonwise80 View Post
    Technically, you have a third choice. You can use an HTML button, instead of the Palm button widget. But then you lose other features.
    You might have the addinional option to hide your buttons if you don't need them temporarily:
    scene.html
    Code:
    <div id="main_btnStart" x-mojo-element="Button"></div>
    assistant_js
    Code:
    $("main_btnStart").hide();
    $("main_btnStart").show();
  7.    #8  
    Quote Originally Posted by Nafetz View Post
    You might have the addinional option to hide your buttons if you don't need them temporarily:
    Excellent! I'm sure I'll need that some day soon! Glad to hear someone else is tinkering along with me.

    Today I got through all the logic (counting and displaying) of the stopwatch. No major complaints -- save for with my own brain having trouble calculating 10ths of a second from milliseconds. It was pretty vanilla Javascript. I also managed to move to Windows 10. I couldn't deploy the VMs there, but I could copy them from my Windows 7 partition and start them that way. If anyone else needs the Windows 10 64-bit Novacom driver here it is.

    At this point, I'm done the main stopwatch -- it has most of the features of the iOS stopwatch, save for coloring "best and worst" times. It has a pretty icon, and makes good use of Mojo UI widgets. If I stop here, I'll have gotten as far as most of the other stopwatch apps in Preware -- so I'll have to keep going. However, I think I'll declare this my 0.5 and make it available.
    Edit: Added lap coloring, bumped version number to 0.6

    The project (with full source) is here:
    https://github.com/codepoet80/webos-stopwatch

    The bin folder has the latest built .ipk, which you can also directly download here:
    https://github.com/codepoet80/webos-..._0.0.6_all.ipk

    Let me know if you have any feedback. Next up is to add a Timer mode (count down, instead of up), on its own Scene, and maybe an "About" Scene as well.

    StopWatchWorking.PNG
    Last edited by jonwise80; 10/08/2018 at 02:23 PM.
    Preemptive and Nafetz like this.
  8.    #9  
    Menus are widgets that you don't position or place with HTML. They can only be programmatically created -- which means that in order to position a menu, you have to know what kind of menu to create.

    AppMenus - these allow you to add to the system menu in the top left corner of the screen.
    ViewMenus - these are button-based menus that appear horizontally at the top of your app's Stage (or Scene). You can also create cascading vertical text-based menus out of them.
    CommandMenus - these are button-based menus that appear horizontally at the bottom of your app's Stage (or Scene).

    Menus are placed automatically -- you have limited control over their positioning, unless you want to fully implement your own CSS class for them. To position a horizontal menu in the middle of the screen, you have to have menus to the right or left of them. If you don't want menus there, just create empty one. You can group menu items, by creating an item group within the menu item group.

    As a final note, menus that are consistently throughout your app (regardless of scene) can be defined during Stage setup, then setup on each scene. Menus that are scene-specific are defined and setup in the Scene setup.

    Here's a menu that is specific to a Scene.
    Note the empty items that force the command menu into the center, and the item group within the item group, which keeps the buttons together -- the toggleCommand defines the default selection.

    Scene Assistant
    Code:
    this.cmdMenuModel = {
       visible: true,
       items: [
             {},
             {
                items: [
    		{iconPath: 'images/count-up.png', command:'countUp'},
    		{iconPath: 'images/count-down.png', command:'countDown'}
    		], toggleCmd:'countUp', 
             },
             {}
          ]
    };
    this.controller.setupWidget(Mojo.Menu.commandMenu, this.cmdMenuAttributes, this.cmdMenuModel);
    Here's a menu that is used in all Scenes being defined on the Stage, then being used in a Scene.

    Stage Assistant
    Code:
    StageController = Mojo.Controller.stageController;
    StageController.appMenuModel = {
          items: [{label: "About Stopwatch", command: 'do-myAbout'}]
    };
    Scene Assistant
    Code:
    this.controller.setupWidget(Mojo.Menu.appMenu, {}, Mojo.Controller.stageController.appMenuModel);
    I'm just beginning to learn how to use them to navigate scenes. More details, including how to handle menu clicks are in the SDK Reference Section -- but not in the Widget section. Look in: Mojo App Framework APIs > Classes and Namespaces > Mojo.Menu

    AppMenu.PNG CommandMenu.PNG
    Grabber5.0 and Nafetz like this.
  9. #10  
    I didn't catch if you mentioned how long you've been working at this, but it appears that you're doing a great job coming up to speed and gaining a good understanding of Palm's strategy for Mojo.

    To that I'll add, they really dropped the ball in the Mojo to Enyo transition. They both are able to work on both phones and tablets, but both have problems that prevent them from working fully on both platforms. In some cases, their strategy essentially forced you to drop support for your Mojo apps and create new Enyo apps for the Touchpad. They all but said that in their Enyo dev sessions.
    jonwise80 likes this.
  10. #11  
    Also, should you need the Palm:// services...this is a good repository: https://kylemaas.github.io/luna-sysmgr/

    It quite nicely describes the different services, their input, and their output. Also it indicates whether these services are public or private (private services can only be used by apps defines as com.palm.appname...or in other words: app that have Palm as a vendor). There's even a public ambient-light function which could be fun for your next app.


    ps. as for NodeJS on webos...they are really old versions. If I remember correctly it's 0.24 on 2nd gen+ phones, and 0.4 on the touchpad...but I haven't checked lately. So there's a lot you're probably used to that simply didn't exist when NodeJS started. It's a pity, but alas...
    jonwise80 likes this.
  11.    #12  
    Quote Originally Posted by Misj' View Post
    Also, should you need the Palm:// services...this is a good repository: https://kylemaas.github.io/luna-sysmgr/
    Awesome, this was a hole in the documentation I had found so far. This will come in very handy!

    Quote Originally Posted by Grabber5.0 View Post
    In some cases, their strategy essentially forced you to drop support for your Mojo apps and create new Enyo apps for the Touchpad.
    That was obviously an expensive mistake, but I can see how they sort of painted themselves into a corner with Mojo. Even from what little I've learned so far, it's clear that it wasn't going to work well on a bigger screen.

    I really just started working on this when I first posted in this thread -- so 3 days ago. I actually took a vacation day on Monday so I could really dive in. I'll have to park it for a bit, because I have some travel coming up, but I'll try to read up on some of that documentation so I can pick it back up again soon.
    Last edited by jonwise80; 10/09/2018 at 05:51 PM.
    Grabber5.0 and Nafetz like this.
  12.    #13  
    Checked-in a little prep work for my second scene, the count-down Timer. I've got the command menu working, and loading to the right default on each scene. And reading through the documentation, I've decided the right approach is to swapScene -- since there's only 2 scenes, and I don't want to create an infinitely growing scene stack.

    However, I ran into a problem identifying which scene is active. You can get the active scene object from the stage controller by calling activeScene, but the object doesn't have a member you can use to compare with. I tried activeScene().name, activeScene().Name and activeScene().id -- those don't exist. So then I tried adding them to the Scene controller, both globally in the Javascript, and appending to the prototype... but I couldn't access them from the Stage.

    Then I tried JSON.stringify on the activeScene object, but its circular, so it wouldn't work. Solutions I found for filtering circular references either require a later version of ECMAScript, or that you know what members you want to strip out.

    I finally just gave up, and put a variable in the StageController. Any time I swap the scene, I update that variable. Then I can do things like:

    Code:
    if (this.currentSceneName != "stopwatch")
    {
         this.currentSceneName = "stopwatch";
         StageController.swapScene(this.currentSceneName);
    }
    So I don't try to load a scene that's already active. This probably won't work if I allow pushing scenes in-and-out, so I'd love it if someone has better advice.

    Update: Added UI revision, so that it now scales properly on TouchPad. Thanks to @Preemptive for the tip!
    Last edited by jonwise80; 10/13/2018 at 10:12 AM.
    Preemptive likes this.
  13.    #14  
    Quote Originally Posted by jonwise80 View Post
    This probably won't work if I allow pushing scenes in-and-out, so I'd love it if someone has better advice
    So the answer is:
    Mojo.Controller.stageController.activeScene().sceneName

    The way I found it might be useful for finding other undocumented members, when JSON.stringify won't work:

    Code:
    enumerateObject = function(yourObject)
    {
    	for (var key in yourObject) {
    		Mojo.Log.info("=== prop:" + key + ": " + yourObject[key]);
    		if (yourObject.hasOwnProperty(key)) {
    		   var obj = yourObject[key];
    		   for (var prop in obj) {
    			  if (obj.hasOwnProperty(prop)) {
    				 Mojo.Log.info("...... sub: " + prop + " = " + obj[prop])
    			  }
    		   }
    		}
    	 }
    }
    Last edited by jonwise80; 10/15/2018 at 10:29 AM.

Similar Threads

  1. webOS Collection for sale!
    By Aeatherion in forum Marketplace
    Replies: 2
    Last Post: 10/14/2018, 09:51 PM
  2. LG WebOS 4.0 is rolling out for 2018 models.
    By akitayo in forum LG webOS TV
    Replies: 2
    Last Post: 10/14/2018, 02:35 AM
  3. My Pre 3's days are numbered
    By elvispre in forum HP Pre 3
    Replies: 13
    Last Post: 10/01/2018, 03:24 PM
  4. WebOS 3.5 to WebOS 4 OLED55B7V
    By DroYze in forum LG webOS TV
    Replies: 0
    Last Post: 09/12/2018, 07:48 AM
  5. WebOS Ports Down?
    By Firepower in forum LuneOS
    Replies: 1
    Last Post: 09/03/2018, 05:40 AM

Tags for this Thread

Posting Permissions