Hello, I am Mohammed Nafees. I have been introduced to the KDE development platform during Google Code-in 2012 and as I become one of the many KDE developers, here is my first blogpost on the new Navigation FloatItem that I have implemented.
The former look of the Navigation Float Item
I re-designed the Navigation Float Item of Marble in a series of GCI tasks which ended today. We now have a modern-looking navigation float item which works miraculously.
The first thing to implement was the arrow disc. I made a new class - ArrowDiscWidget - for it which inherits QWidget. The float item paints different pixmaps for different events - namely, enterEvent, leaveEvent, mousePressEvent and mouseReleaseEvent. The idea behind these events is that there are separate pixmaps which get painted when the mouse is hovered over the arrow disc, when the mouse is pressed and the normal state with no event being trigerred, that is, the default look. Implementing this arrow disc was one of the most challenging parts. There is one image and there are four different actions to be handled, that is, the four directions. So, the first part was to divide the image into four equal quadrants. For this, Dennis, my mentor, advised that we use Polar Coordinates. This worked quite well where we determined the correct arrow ( direction ) with the angle where the mouse is currently pointed to. We also excluded a small circle from the center so that when the mouse is hovered over the center of the arrow disc, no repaint gets trigerred.
(Left) The default look of the Navigation Float Item.
(Right) The current position button replaces the home button when required.
Next part to implement were the zoom buttons. So, I created a new class - NavigationButton - which inherits QAbstractButton. The pixmap handling for these buttons are just the same as that of the arrow disc widget. Next came the home button which is another NavigationButton.
The slider was yet another tricky part and I needed a lot of help from my mentors - Dennis and Torsten. For the slider, I made a new class - NavigationSlider - which inherits QAbstractSlider. The range of the slider is always the same as that of the current map’s zoom range and this is what is the tricky part. The original height of the slider is 160px and we have to convert the zoom range ( usually between 900-2100 ) to fit into this range. Dennis provided this calculation which worked wonders:
qreal const fraction = ( value() - minimum() ) / qreal( maximum() - minimum() );
int const y = ( height() - handleImageHeight ) * ( 1 - fraction );
where ‘value()’ is the current value of the slider, ‘maximum()’ and ‘minimum()’ are extreme values that can be set or to be more precise, the range of the slider. ‘height()’ is the height of the float item( 160px ) and handleImageHeight is the height of the handle image( 32px ).’y’ is where the slider’s handle is placed on the slider. And similar to this we had a formula for the conversion of the current position of the handle to the normalized slider range or zoom level. And with this the slider was complete. But there was still something missing. Thanks to Torsten, he made a new backdrop for the float item which made the navigation float item complete.
I recently extended the home button. The user can now switch between the home button - which when clicked, navigates the user to his saved home location - and the current position button - which when clicked, navigates the user to the current GPS position of his selected track. This change of buttons is handled by the float item’s context menu.
The current position button navigates the user to the current GPS position
The whole “Marble” experience was very enriching. I would like to thank all my mentors at Marble - Dennis, Torsten and Rene - for giving me just the right inputs and criticizing my work whenever the need arose.
The current look of the Navigation Float Item
Working for KDE during GCI ‘11 and GCI ‘12 has been a major milestone in my life. And now this connection has become even stronger as I step into the KDE world as a young developer who wants to contribute every bit of his creativity to this exceptionally unique community.