Finally in the store!

November 10, 2011 at 9:07 am | Posted in Uncategorized | Leave a comment

The Morse Player has finally gone into the store after several attempts. The biggest problem stopping the application from being accepted was the “equally functional in portrait and landscape mode” requirement.

Originally, this was solved, but then I put in a Morse Code table as an QML splash screen and as a menu item. This had rotation problems, performance problems, and then rendering problems. And this was an eye candy feature – mainly the version/web page information plus additional information for learning morse.

The rotation problem was due to the method to present the morse code table, it was 3 columns that went off the screen in landscape, so this had to be changed – leading a performance problem. This issue came from my use of loaders to change the morse code table between portrait and landscape (I just wanted to try them out really). Creating both the portrait and landscape tables, making them invisible/visible depending on the screen orientation solved the performance, leaving only the rendering issue.

The rendering issue came from the use of a completely black background in the morse table in a application with a white background. When static this did not cause any problems, but when rotating the display white lines flickered at the top of the display. I presume this comes from the application background getting rendered first. After some hacking, the solution I chose was to invert the application when showing the morse table and rotating. This solved the issue, maybe not the cleanest solution, but it worked.

This simple morse code table feature also forced me to play with showing the status bar when in landscape mode. Removing the status bar gives more screen, and in the landscape mode height is a value resource.
Again, this caused me to dig some more to get a reliable way of working out when the application is in landscape mode. The first approach was to use the QML PageStackWindow inPortrait property, but when the virtual keyboard is shown this becomes undefined. This makes sense because when the keyboard is shown the application is in neither landscape or portrait modes. The solution is to use the Screen object’s orientation policy, as described in the developer.nokia.com wiki. This is pretty reliable and works whether the virtual keyboard is active or not, at it is very easy:

main.qml:

...
onOrientationChangeFinished: {
  appWindow.showStatusBar = 
    ( ( screen.currentOrientation == Screen.Portrait ) || 
      ( screen.currentOrientation == Screen.PortraitInverted ) );
}
...

The source code of the accepted application is here.

http://www.developer.nokia.com/Community/Wiki/File:Morseplayer_0_0_7.tar.gz

If you want to check out the application just search on the Nokia Store for morse.

Now all I need is some more real features……

Bugs, bugs, and then some features…

October 13, 2011 at 8:34 am | Posted in Uncategorized | Leave a comment

Well, needless to say the quick submission to Ovi Store did not work. There were bugs that needed to be corrected:

1. The Qt SDK overwrote the qmlapplicationviewer.cpp code at the last build so the application did not show any QML.
2. The playing of morse code disabled the UI, creating a warning message.
3. When rotating the device while inputing text the playbutton took over the entire screen.
4. (This one I found myself), there is need for about information so this needed to be added.

So back to the SDK to clean things up.

The first bug is easy to fix as I just started using code version control – a quick revert and we’re done.

The second bug is much more tricky. My first idea was to use a WorkerScript inside my existing QML code to run the morse playback. This was a mistake, as it seems there is no way to access a QML object from within a WorkerScript (especially a C++ object). So the way forward was to insert the threading into the MorsePlayer C++ object. As a side-effect I was able to include a stop functionality, so a user can stop morse playback.

morseplayer.cpp:

...
class MorseThread : public QThread {

public:
    MorseThread ( MorsePlayer* player ) : 
          m_player( player ), m_text( "" ), 
          m_stop(false), m_mutex() {}

    void setText( const QString& text ) { m_text = text; }

    void run() {
        m_stop = false;
        QString morseString( m_text.toUpper() );
        m_player->setSending( true );
        for ( int i = 0; i playLetter( morseString.at( i ) );
            QMutexLocker locker(&m_mutex);
            if ( m_stop ) {
                break;
            }
        }
        m_player->setSending( false );
    }
public slots:
    void stopFlag( bool stopFlagValue ) {
        QMutexLocker locker(&m_mutex);
        m_stop = stopFlagValue;
    }

public:
    MorsePlayer* m_player;
    QString m_text;
    bool m_stop;
    QMutex m_mutex;
};
...

The third bug was also tricky. After trying to detect rotation using the Window orientationChangeFinished signal, and noticing that the virtual keyboard interferes with the result, the method I chose was to remove the button when the TextArea was active – this improves the usability as it is unlikely a user will want to input and playback at the same time. This also gave me a chance to play around with QML animations, and states.

MainPage.qml:

...
   Behavior on height { PropertyAnimation { duration: 500 } }
   Behavior on font.pixelSize { PropertyAnimation { duration: 500 } }
   states: [
     State {
       name: "active"
       when: morseText.activeFocus
       PropertyChanges {
         target: playButton
         height: 0
       }
       PropertyChanges {
         target: playButton
         font.pixelSize: 1
       }
     },
     State {
       name: "inactive"
       when: !morseText.activeFocus
       PropertyChanges {
         target: playButton
         height: ( parent.height*0.2 )
       }
       PropertyChanges {
         target: playButton
         font.pixelSize: ( parent.height*0.1 )
       }
    }
  ]
...

The last bug was interesting too. Just for the fun of it I decided to make a QML splash screen and to reuse it inside the application. This meant I had to play around with the application’s page stack.

main.qml:

...
  initialPage: SplashScreen {
    id: splashPage
    Timer {
      id: timer
      interval: 300
      running: true
      onTriggered: {
        var component = 
          Qt.createQmlObject( 'import QtQuick 1.1; MainPage { }', 
          appWindow );
        appWindow.pageStack.push( component );
      }
    }
  }
...

To activate the about screen from within the application I added a toolbar, and got hit by a gotcha. The final code:

main.qml:

...
  ToolBarLayout {
    id: commonTools
    visible: false
    ToolIcon {
      platformIconId: "toolbar-view-menu"
      anchors.right: (parent === undefined) ? undefined : parent.right
      onClicked: {
        var component = 
          Qt.createQmlObject( 
          'import QtQuick 1.1; SplashScreen { tools: backgroundTools }',
                   appWindow );
        appWindow.pageStack.push( component )
      }
   }
  }

  ToolBarLayout {
    id: backgroundTools
    visible: false
    ToolIcon {
      platformIconId: "toolbar-back"
      anchors.left: (parent === undefined) ? undefined : parent.left
      onClicked: {
        appWindow.pageStack.pop();
       }
    }
  }
...

The gotcha is to make the toolbars invisible in the PageStackWindow, and only to enable them in the Page code using tools property.

I also heard that it is possible to create another splash screen using the Nokia N9 program (see “Enabling a splash screen for an application”). This requires images 854×480, so out with the GIMP program and following the Drive application approach I created two images with the MP logo. The next step is to hack the _harmattan.desktop file:

...
Exec=/usr/bin/invoker --type=d --splash=/opt/morseplayer/morseplayer_portraitSplash.png 
                     --splash-landscape=/opt/morseplayer/morseplayer_landscapeSplash.png 
                     -s /opt/morseplayer/bin/morseplayer
...

Now it is time to re-submit.
(The updated source code is here.)

Simple Morse Player for the N950, now for the N9 and submitted to Store.

October 4, 2011 at 3:27 pm | Posted in Uncategorized | Leave a comment

Store Submission done!

Well, I thought I would share my code with the world by putting the application on the Nokia Store. This was pretty easy once I had cleaned up the code a bit.

The big thing for me was placing the qml files inside the binary. The files where put inside a resource file, and the QmlApplicationViewer setMainQmlFile function hacked to remove the adjustPath function call, and to use a QUrl instead of a local file.

void QmlApplicationViewer::setMainQmlFile(const QString &file)
{
    d->mainQmlFile = file;
    d->view->setSource(QUrl(d->mainQmlFile));
}

Then the main.cpp needed to be changed to point to the resource file;

...
    viewer->setOrientation(QmlApplicationViewer::ScreenOrientationAuto);
    viewer->setMainQmlFile("qrc:/qml/qml/morseplayer/main.qml");
    viewer->showExpanded();
...

Additionally, I created a configuration file for linking the application to the resource management framework:

[classify media]
/opt/morseplayer/bin/morseplayer

And altered the .pro file to install this file into the right location on the device:

...
contains(MEEGO_EDITION,harmattan) {
    desktopfile.files = $${TARGET}.desktop
    desktopfile.path = /usr/share/applications
    rsrc_config.files = morseplayer.conf
    rsrc_config.path = /usr/share/policy/etc/syspart.conf.d
    INSTALLS += desktopfile rsrc_config
}
...

To make things proper I also did some editing to the debian packaging tools, see the source code for more information.

Once the software was ready, it was time to put it in the Store. So after quickly running through the quality criteria, I started the publish process.

For those of you who will do this later, you will need a screenshot in two formats square, and in the N9 resolution. I created the screenshot using the screenshot tool, and then made it square using GIMP. The Store also wants a 256×256 icon, this I created using GIMP and scaling up the application icon.

The rest of the information is pretty straightforward:
1. A web site (this blog)
2. A maintainer email (my own)

And then it is there.
Here is the source code.

Now all I have to do is wait for Store QA to get back to me.

Qt SDK Updates, now with better Qt Component support

September 30, 2011 at 12:03 pm | Posted in Information, Software Development | Leave a comment
Tags:

For those of you in the know, the Qt SDK has just been released on developer.nokia.com. However, as itt might not have grasped your attention, there is also an online update that adds better support for MeeGo 1.2 Harmattan to the SDK.

One very useful thing that has been added is support for the Harmattan Qt Components in the Qt Simulator, so now you can do more without the need to access a device. Here is a screenshot of the template Qt Quick component application running on a Windows 7 environment.

Qt Components running inside the Qt Simulator

Qt Components running inside the Qt Simulator

I have been reliably informed that the Qt Components now also work on the desktop. So what are you waiting for? Start updating your Qt SDK now.

Simple morse player for the N950

September 26, 2011 at 9:56 am | Posted in Software Development, Uncategorized | Leave a comment

Remember the old fashioned movies with spies and sailors going dit-dit-dah to each other. Well now you can relive that nostalgia with the “Morse Code Player (source code available below).

This application was supposed to be a quickie that just does a few simple things, but in the end it turned out to be a headache due to my limited understanding of the threading behaviour of QML and Qt C++. The core of the application consists of two C++ classes the MorsePlayer that converts text to morse, and the ToneEngine that creates a audio tone.

The MorsePlayer class is relatively straightforward QML binding class that has a bit of logic for converting text to morse, and then for call the ToneEngine to play the necessary tone. The ToneEngine class is a bit more complicated; it copies logic from the AudioOutput example for generating a simple tone. The tricky bit (that took several half days to solve) was working out that the audio handling code (ToneGenerator, QAudioOutput) needs to run in its own thread, with its own event handler othwerwise the audio output blocks. Additionally. MorsePlayer needs to send signals to the ToneEnginer otherwise the audio blocks. Another tricky bit is the use of resume and suspend to start/stop the audio output, this is simply because QAudioOutput start/stop takes too long to create the initial buffers etc.

The current code is not perfect, it still occasionally has buffer underflows (any help here would be appreciated). As an application, it needs some extra features like a way to set the morse code rate, and tone frequency. Additionally, it could do with more features like haptic feedback and other clever ideas. I could also clean up the code more (add more comments, play with the design, make it a QML plugin) so I am just releasing it “as-is” as a simple example of tone generation from QML.

A simple wiki page with historical source code.

A direct link to the source tarball.

Enjoy!

MeeGo on an N900

August 23, 2010 at 11:10 am | Posted in Information, Software Development | Leave a comment

For those of you who have not been following the MeeGo on the N900, MeeGo has been ported to the device.  Being a cynic, I waited until I got it to work before posting about this activity.  It is not that difficult to get the MeeGo Handset UX on the device, but it may take some additional massaging (in my case I needed to flash the kernel twice).  Here is a screenshot in glorious technicolor:

There are good instructions here.  I took the easy approach and just downloaded the proprietary ready-made images from tablets-dev, used the windows 32 diskimager to write to the MicroSD card, and a linux laptop to flash the kernel.  I am sure there is an easier approach, but this one worked for me.

Ari Jaaksi’s key note at the Linux Collaboration Summit

April 14, 2010 at 9:39 pm | Posted in Information, Software Development | 1 Comment
Tags:

Hi all,

Ari just delivered a key-note “MeeGo: A Free & Standard Linux OS for the Mobile Industry” and he pushed two major themes: user experience and openness.  The other thing made very clear was that the Meego platform will be more attractive to application developers, with better tools etc. to make their lives easier.

Another interesting tit-bit is his Meego to-do list:

  1. Develop in the open: This really means release code earlier than products.  This means that if you connect the dots, you can reverse architect the product characteristics, and can make your own decisions and change if you want it.
  2. Product quality and focus: For a phone there is a surprising amount of effort goes into finalization, it is a lot of work.  We need to focus on quality, it is getting easier as more people join the project.
  3. Keep governance simple: This should be based on contribution, and not a political committee.  We need it to be simple.
  4. Help others to join Meego: We have not been so good so far, this is changing with more people onboard.
  5. Move fast: Push code out earlier than we feel comfortable.

Other issues were mentioned regarding governance, etc. Basically the issue is that we are starting now and are heavily reliant on Intel/Nokia at the moment, but this will change over time as more companies will join (and a lot just did  see here).

Questions?

Some things change, some stay the same, how painful does it have to be?

March 26, 2010 at 9:37 am | Posted in Uncategorized | Leave a comment

On Thursday Maemo Devices became Meego Devices, without any change but the name, rather surreal actually.

Not all change is progress, but progress is impossible without change.  One thing that is certain in any community change has a human and time cost, as the community adapts to the new circumstances.

So it will be with the Meego change, it will cost and benefit the people already involved in the Moblin and Maemo communities.  They will have to adjust to a new platform with a new set of technologies.  The tools they use will be different, the community management will be different, and the people they work with will be different.  All this will take some time to get used to, although the rewards are potentially huge.

Anybody who has been through a few organization changes knows the forming, storming, norming, and performing model of how a community/team adjusts to change.  The theory is that each stage is inevitable, so the issue is how to make the migration to Meego go smoothly, quickly, and with the least amount of pain, especially inside an open community?

Hello community!

February 26, 2010 at 12:09 pm | Posted in Information | 1 Comment
Tags: ,

Well hello, today is the first day in a public coporate role, it also the first day of spring so I am quite optimistic.  I have now become Nokia’s Maemo Developer Advocate.

I have been watching the growth of Maemo for many years, from its first early days as a small project in Nokia to the release of the first handset.  Unfortunately, my work has steered me away until recent, so until last year I never really knew just now much fun Maemo development actually is.

I have just come from Maemo software development, where I have been brushing up on my C++ skills and getting into scratchbox/Qt/QtCreator coding.  I am a long-time Nokian, and I have spent many years in applied research, and in product development.  By background contains elements of audio engineering, multimodal multimedia, CORBA, distributed systems, embedded component based software and medical software.

As a developer advocate my role is to support the developer ecosystem and help guide Nokia’s contribution, for the benefit of both.  So, my goal is to listen, and to understand the issues, pain points, good things, etc. and investigate how Nokia can help.

Any suggestions on how to do this are welcome.

Create a free website or blog at WordPress.com. | The Pool Theme.
Entries and comments feeds.

Follow

Get every new post delivered to your Inbox.