This semester I am taking the “Topics in Open Source Development” course at Seneca and will be blogging periodically about it as part of our requirements.. our first tasks given to us are to read the EULA of two pieces of software.. one open.. and one closed source.. and discuss any surprises / reactions.
For this task I read the EULA of Skype (closed), and BSD (open).
Obvious quick observations are that EULAs for close software tend to me a lot larger.. and written in a lot more legalese full of many caveats and loop holes for the companies. While legally the onus is always on the service provider to clarify any ambiguity in contracts (so they can get long and wordy) I can’t help but feel this is also an act to discourage users actually reading the terms they agree to. Lets be realistic, no one actually reads them. Personally I question how legal they truly are since you cannot prove which user agreed to the terms and the system has no real enforcement.
Skype’s EULA is full of some interesting tidbits.. Skype had some form of currency you can pay into and they can void any credits after 180 days of inactivity. Also, they have written in their contract that any time they add changes to their EULA you automatically retroactively agree to them, and the onus is on the user to periodically check their EULA page to be aware of these changes. I personally doubt that would be legal or hold up in court.. a contract that can freely change and grow without notifying the user it effects or having them agree to the changes knowingly.
They also apparently can delete user accounts that aren’t used for 1 year? I still remember my ICQ # personally.. and I seem to be able to log into it still! I don’t see a point in removing a user’s account / their friend list if you ever want them to come back to your service. With how small a data foot print a user account would be this part seems kinda silly…
Anywho.. as for BSD.. tiny.. brief.. essentially says provided as is and no liability is on them. Seems fair to me.
Wow ok so I have not blogged about BerrySync for 2 months! Lets recap what has been accomplished since then:
- I drew the logo / branding
- I drew the ui
- Implemented our ui with: collapsible folders, hierarchy icon (can tell whats inside of what), sorting, etc.
- We linked in the fetcher to have live data
- Setup the settings page with some customizable options
- Greatly improved the login screen
- Setup a loading screen
- TONS of ui code improvements to speed up things, hide processing, improve the user experience.
- The main navigation scrolling screen uses momentum now which feels much more natural for users.
and..
BerrySync v1.0 is complete!
More news to follow once the application is on the Blackberry store .
There are plans to open source the navigation scrolling code, I first wish modify the code to better emulate the usage of normal Blackberry field Managers. Also add support for vertical movement.
Lets talk about how we got the zooming into BerrySync. The previous entry I wrote discussed the changes that were made to process bitmaps in a background thread. This keeps the UI fast and usable. This was initially done so thumbnails can be generated of the various screens quickly during load in the background.. and rotated ones generated when the device is rotated.. plus updated pics as data on them change on demand.
Another feature we knew we wanted was to have pages zoom in to full screen instead of just snapping into view. A zoom can be thought of as an animation with X number of frames. For the moment I used 3 frames, + the initial starting image and the final screen filling the screen. This means the animation will feel like 5 frames.
Here’s a video of how it looks: (sorry for loud audio.. had to do a audio swap on the video to remove background voices and YouTube doesn’t let you choose a volume level O.o bad YouTube, BAD!)
I layered another class on top of the CaptureAndApppendScreen class I described last time. The capture class is a task for the BitmapManipulationHandler that allows a screenshot to be taken of a screen, and drawn into the supplied graphic in the #of locations specified in dimensions specified… all on a background thread without interrupting the main thread. For the previous work it simply is being used to captured the screen into a bitmap, resized the bitmap smaller, and draw on the thumbnail to the master Bitmap provided (which is wrapped inside a Graphics object).
My new class, named ScreenZoom, extends CaptureAndAppendScreen. This class is used to buffer the animation frames in advance. This will allow us to have the animations ready to use when a person click on a thumbnail so it instantly zooms in without delay.
GENERATING THE BUFFERED ANIMATION FRAMES
When ScreenZoom is run() by the BitmapManipulationHandler in the back thread instead of drawing onto the master image with the thumbnails it: generates enough separate bitmaps for all the animation frames, and then uses the methods inherited from CaptureAndAppendScreen to process in advance our animation of the desired screen centered and growing from small to big.
wrapped the desired bitmap inside a graphics object locally..
set that graphic as the current destination,
create a drawLocation object specifying the size and position within the Bitmap to place the screen,
and then call the run() method of the original CaptureAndAppendScreen object. (note the screen is captured in internal method named getScreenBitmap(), and CaptureAndAppendScreen will only capture an image of the screen once and store it unless a flag is set requesting it to recapture / update the image. This means we don’t waste time capturing the screen for each animation frame)
Repeat this for all the images and the animation frames are ready.
protectedvoid run(){if(!ready){
moveToStart();//we want all processing in the ScreenCaptureAndAppend to end up in a image the dimensions of a screen for us to work with
screenAnimationFrames =new Bitmap[maxSteps];do{//bitmapif(screenAnimationFrames[step]==null){
screenAnimationFrames[step]=new Bitmap(BerrySyncApp.getWidth(), BerrySyncApp.getHeight());//make it transparent
screenAnimationFrames[step].setARGB(newint[screenAnimationFrames[step].getWidth()* screenAnimationFrames[step].getHeight()], 0, screenAnimationFrames[step].getWidth(), 0, 0, screenAnimationFrames[step].getWidth(), screenAnimationFrames[step].getHeight());}if(!screenAnimationFramesFinished[step]){//set up the graphic...
screenGraphic =Graphics.create(screenAnimationFrames[step]);//set the location to draw to the result...super.setDrawDestination(screenGraphic);//setup desired dimensions
clearDrawingLocations();
addDrawingLocation(
srcX, srcY, srcWidth, srcHeight,
(int)(dstStartX + deltaX *((float)step)),
(int)(dstStartY + deltaY *((float)step)),
(int)(dstStartWidth + deltaWidth *((float)step)),
(int)(dstStartHeight + deltaHeight *((float)step)));//this will capture and scale the screen into screenSpacesuper.run();
screenAnimationFramesFinished[step]=true;}}while(nextStep());//return to the same step it started at when this method ran
moveToStart();
ready =true;}}
Animation frames are played through in steps. You advance to the next step, draw the frame, advance again.. until you hit the end. The animation can be played in forwards or backwards.. and at whatever speed is desired depending on how fast you draw them / advance to the next speed.
To keep the animation fast and smooth I knew I had to draw the bitmaps from this task straight to the graphics object from device. This means outputting them in the Paint() method.
WHEN WE WANT TO ANIMATE, WE MUST..
When the frames are all generated the method inside it named isReady() will return true.
When we want to zoom (such as on a click event) a timer will keep checking until the zoom task for the selected screen isReady() (all these tasks should have been tossed into the background thread earlier and have all the frames ready for use by now but this is just to be safe).
Next we set the ScreenZoom task into a variable like current_screen_zoom and run the method in it of goToStart() (to ensure we are at the first step of our ‘zooming in’ animation).
Run Invalidate() on our screen to request a repaint.
if(current_screen_zoom ==null|| current_screen_zoom .getScreenID()!= selectableScreens[currentScreen]){
current_screen_zoom = screen_zoom_tasks[current_orientation][currentScreen];
current_screen_zoom .moveToStart();
bitmapManipulator.addTask(current_screen_zoom );//just incase it's not buffered yet... this will do nothing if it is!}
DRAWING THE ANIMATION FRAMES WE PROCESSED EARLIER ONTO THE SCREEN
If paint() sees that current_screen_zoom is not null.. and it isReady().. we pass into it the Graphics object. For simplicity the ScreenZoom task has a paint(Graphics) method emulating this paint method which we pass into.
Earlier I mentioned that getScreenBitmap() is used to get a capture of the desired screen inside ScreenCaptureAndAppend. ScreenZoom actually overloads this method, and will instead return the current animation frames (based on current step) if the task isReady().
This way we are able to use the inherited run() command from ScreenCaptureAndAppend to both output the finished animation frames to the device screen as well as generate the buffered animation frames earlier into local Bitmaps.
With that method overloaded, our current animation frame will properly be drawn into the Graphics object we set (which is the device screen Graphics object from paint())
ADVANCING THROUGH FRAMES AND KNOWING WHEN ZOOMING IN IS COMPLETED
A timer watches for when the ScreenZoom tasks returns hasPainted() as true.. tries to do NextStep().
If NextStep() returns false the animation is completed, the real screen is placed on the top of display stack, and we set current_screen_zoom back to null again.
If NextStep() returns true, HasPainted() will have been set to false again internally automatically.. and we run Invalidate() requesting the screen to repaint.. once it has been painted again we repeat until NextStep() returns false meaning we have finished the animation.
privatevoid zoomInOnCurrentScreen(){//yay zooming ! ^_^if(UiApplication.getUiApplication().getActiveScreen().equals(this))if(currentTouchXOffset != targetTouchXOffset){//we arn't centered.. make sure timer is on so it becomes centered...
startScreenSlidingTimer();}elseif(!fingerIsDown){//time to zoom in...boolean isReady =false, isPainted =false, isFinished =false;if(screen_zoom_task !=null){
isReady = screen_zoom_task.isReady();
isPainted = screen_zoom_task.hasPainted();if(isReady && isPainted)
isFinished =!screen_zoom_task.nextStep();}if(screen_zoom_task ==null|| screen_zoom_task.getScreenID()!= selectableScreens[currentScreen]){
screen_zoom_task = screen_zoom_tasks[current_orientation][currentScreen];
screen_zoom_task.moveToStart();
bitmapManipulator.addTask(screen_zoom_task);}//this will queue up the next stepelseif(isFinished){
screen_zoom_task =null;//toss the screen on top
UiApplication.getUiApplication().pushScreen(ScreensFactory.getInstance().getScreen(selectableScreens[currentScreen]));}}}
Okay! Let’s talk about device rotations and blackberry.
Rotating, that seems simple enough right? The device is rotated.. blackberry already auto rotates the screen contents and any controls you have set. None of my existing content will remain sideways… it just won’t be in the right dimensions after. BerrySync already generates the bitmaps to fill the screen to current orientation on app load.. so I know it can display in both vertical and horizontal screen modes just fine. Simply need to tell the screen to adjust the bitmaps after a device rotation while the app is running.
Simple enough then… I just need to regenerate my bitmaps to the new dimensions so everything looks proper. The device -should- throw some sort of rotated event when it rotates since that just makes sense, right? So just recalculate the new dimensions, offsets, etc.. and then draw the bitmap adjusting to new dimensions. Since this is all coded already to be flexible to the device dimensions when generated it should just work. I assumed this would be simple enough but……..
Lets look at the first issues we gotta approach:
Problem 1 – that nasty screen shot bug I mentioned way back yonder, we need to figure out why we can’t just use paint properly to draw into a bitmap that’s packed in a graphics object to get screen captures! Using the screenshot command / causing flickering is not an option. Problem 2 – A lot of code is packed into the constructor so we need to move it elsewhere. Problem 3 – User input cannot be gathered while doing stuff like generating a bunch of bitmaps. This makes the device feel slow and unresponsive to a user Problem 4 – Generating bitmaps is slow to do, lot of wait time
* * *
Problem 1 (nasty screenshot bug) was fixed easily enough.. turns out my method I first tried WORKED! I just couldn’t tell since there is some other bugs (“working as intended” likely) in how blackberry was painting it that prevented me from noticing. Let me explain:
Bitmap b =new Bitmap(width, height);Graphics g =Graphics.create(b);
Screen s =new MyAwesomeScreen();
s.paint(g);
This code had the screen paint into the bitmap without painting to the screen. When it finishes running b contains an image of MyAwesomeScreen. The bug is that unless a screen is on the display stack blackberry will not render any of the fields / controls you’ve placed into the field. There is some automated stuff happening in the background that only runs on paint if it’s on the stack. When I tested adding into the paint method within MyAwesomeScreen any manual drawing, (in my case drawing a rectangle via Graphics.filledrect()) I could see this appear it in the Bitmap b after. The problem was the controls / fields…
So how to fix this and make everything render properly when we call paint?
Bitmap b =new Bitmap(width, height);Graphics g =Graphics.create(b);
Screen s =new MyAwesomeScreen();
UiApplication.getUiApplication().push(s);/* ADDED TO MAKE FIELDS RENDER */
s.paint(g);
UiApplication.getUiApplication().pop(s);/* ADDED TO MAKE FIELDS RENDER */
If you push the screen onto the display stack and THEN call paint on it (also popping it off after when done) the controls and fields will appear in the result and but this never renders to the device screen! Progress!
* * *
Problem 2 (too much in constructor) was simple enough to fix and just a result of rushing, laziness, and poor planning. Methods were added that represented various actions so everything was split up and easier to maintain. Now we can call GenerateBitmaps() anytime we wanna regenerate everything.
* * *
Problem 3 (User input being blocked by Bitmaps being processed) was a real problem at first. My early tests had the phone lock up for a few seconds when the PageScrollingScreen wasn’t even currently visible (the rotate event fired since it’s on bottom of display stack). During this time you could not do anything on the page displayed on the device.
My first try to fix this: I added an if statement to prevent anything not on the top of display stack from handling rotations.. then called the rotate on page scroller from the current page that’s on top of the stack using the InvokeLater command on UiApplication which time shares on the current main thread:
This did shave off some time since the current full screen would rotate nearly instantly but when you tried to access the page scroller while the rotate was being handled still the device was still locked up until done. As soon as the current screen finished handling it’s rotate PageScroller still ran on the same thread to handle it’s rotate.. it simply waited to go second now. This completely dominated all processing time on the application once again. That’s stupidly sloppy and it wasn’t good enough. Any user would not understand why sliding their finger to the side wasn’t working and be mad at the locking up.
My second try to fix this:
I removed the garbage of my first try since pages should self manage their rotations when it happens.. I don’t want pages cross communicating telling when the others should rotate. Lets try to maintain the abstraction of this design.
The problem was entirely the Bitmaps. This brings me to…
* * *
Problem 4 (Bitmap processing is slow). I decided I needed to move the Bitmap processing into another thread and update the visible area the user sees as they are completed so a user can see screens pop into view as they become available. Since the processing is off the main thread all user input continues working just fine and remains fast and responsive. The bonus of this is if any data changes while in this view we can fluidly update the thumbnails now during.
I setup a structure where I can queue up the tasks of bitmap manipulation, pass them to a handler to run on a background thread, and have the results shown as it finishes. This greatly sped up the applications responsiveness and allowed the code to become a lot cleaner too. I knew I wanted to use a similar task for processing zooming later so tried to be mindful of that while I was figuring out how to keep everything fairly abstract and flexible.
Capturing the screens into bitmap via the paint() method needed to be slightly tweaked to work with the thread setup now…
We sync with the UiApplication using UiApplication.getEventLock() so that we can safely stick screens into it without threading problems.
The reason UiApplication.suspendPainting() was required this time around was due to that since all of this code is running on a separate thread the main thread was not waiting to redraw. As soon as you popped any screens onto the display stack the device was instantly updated to show it. To prevent any flickering of screens being drawn simply suspend paint, push, paint, pop, unsuspend.. and done!
The code in PageScroller for updating Bitmaps was nice and simple now. I setup all my tasks in the constructor so they are ready to use when desired. Now I simply pass them into the handler!
privatevoid generateBitmaps(){Graphics g =null;int orientation = getOrientation();if(orientation != current_orientation){
current_orientation = orientation;
g =Graphics.create(scaledCombinedScreensImage[current_orientation]);}synchronized(this){//abort any current tasks just to be safe...
bitmapManipulator.abortCurrentTasks();if(g !=null)
bitmapManipulator.setDrawDestination(g);//*********//needs to also check which screens have visually changed by some flag //and make an array of update commands for only screens that have really //updated and need to be displayed here...//*********//prioritize the order.. lets have stuff in the center of the user's focus be first //add on the update tasks.. sorting to the front the updates for center screen, previous screen and next screen
bitmapManipulator.addTasks(screen_update_tasks[current_orientation], newint[]{currentScreen, previousScreen, nextScreen});}}
With scrolling between screens working smoothly as seen in my previous post I next set out to get screens appearing fullscreen on the device after both either a short pause or clicking / tapping on the screen. I knew I wanted them to zoom in (and maybe out) but for now my goal was to simply go full screen and to be able to gesture to the side to return to page select mode.
As I mentioned last time the blackberry has a stack for screens to be placed on. The top most screen is the one currently visible to the user, removing the top screen reveals any that are below it on the stack. (see diagram to the right). Using this concept the flow for pages would be simple.. keep the page scroller on the bottom of the display stack always.. when we open a specific section (such as bookmarks) simple place it on top and tadaaa.. fullscreen. We simply toss it on top after a set period of time or when a user triggers it early via clicking or tapping on the screen. The tricky part is how do you return back to the page scrolling page smoothly and fluidly? I originally thought that would be simpler then I expected…
The most basic concept is to return.. we pop off the top screen. Any screen can pop itself off the display stack, such as:
//within the desired screen at some point call...
UiApplication.getUiApplication().popScreen(this);
My first inclination was to capture my desired event (such as gesturing to the right with a finger), and pop off the screen revealing the page selector below. I assumed.. (never assume!) that the touch move event would continue firing off into the new ‘active’ top screen while I moved my finger on the screen. A quick test revealed that… no. When the top screen was popped off the device entirely forgot my finger was on the screen and no further events were being captured until I lifted it off.. and pressed it onto the screen a second time. This would make for a horribly clunky interface…
So.. original plans had the 2 screens entirely separated and they would be activated by some basic events in blackberry that notify when they are the topmost screen on the display stack, such as:
Now knowing that popping off the top screen makes the events disappear.. the only way I could keep the interface as fluid as I aimed to would be to have the screens communicating a bit between each other.
I would need to forward all the input events from the top screen into the bottom screen until a good opportunity arises to actually pop it off (such as when the user lifts their finger for a moment).. and remotely use the paint method of the bottom screen *even though it is in the bottom of the display stack and not on top at the moment* and bypass drawing the top screen effectively making it transparent and nonexistent. As soon as the user lifts their finger and I don’t need the touch input I officially pop it off without the user being aware it even happened.
I really wanted to keep things fairly abstract and didn’t want the objects to have to know a lot of specifics (or any) about each other so many changes were made to the class diagram. The new structure involved a base class that standardized the event methods (since the ones available are a disjointed mess all implemented differently) while adding a few new events I wanted. There was another class that extended it which handled all the necessary work for a screen to be useable on the page select screen.. it knows what to do when put on the display stack.. how to gesture to the side to display the page select screen again.. and how to pop itself off the display. This way the real content screens, such as bookmarks, don’t have to see -any- of this implementation and contain only content relevant to showing their page’s information.
With these changes we had working gestures to slide to the side to fluidly exit fullscreen and display page select without the events being lost in the process (as seen in the video at the top of this post!).
Recently I set out to code the screen scrolling transitions for BerrySync which involves letting a user gesture side to side to scroll through screens both via touchscreen and the touchpad. My early research showed that BlackBerry in their ‘kindness’ added in some basic screen transitions for people, but not until OS5 O.o (or was it 6 I forget right now..). How they never added these in before then perplexes me. More, these transitions are quite basic covering stuff like fade in, slide in, etc… between screens that completely fill the current display
My research into how people do more involved effects (such as for us, showing multiple screens zoomed out while scrolling) lead to info on the developer forums how the best approach is to take screenshots of the screens, do the transitions with the bitmaps, and swap the real screen on top when done with the user unaware it was ever a screenshot.
How the blackberry display works is that there is a display stack of objects of type screen (or the supplied more advance types.. FullScreen, MainScreen, etc). Whichever screen is on top of the stack is displayed on the device. If someone opened some content that they need to close in reverse order the stack is handy since the content will persist in those screens, and you will access them in reverse order as you pop the stack.
OUR PLAN:
For our screen approach we want to scroll around viewing many screens at once (via the image approach).. likely 3 at a time.. find the one we want.. and then have it seamlessly swap to the top of the stack without the user knowing we traded the image for the real thing. The controls must be highly responsive and it must look very smooth and professional. Sluggish makes users unhappy and Kait sad .
Here are some videos of my recent work at establishing our screen scrolling transition! I explained some of the approach at the bottom.
GETTING THE SCREENSHOTS:
Getting the screenshots of the screens has been… tricky. Info on the forums suggests you should be able to set the paint method public, make an instance of a graphics object using a empty Bitmap.. and tell the screen to paint into the graphic.. and thus paint into the bitmap. Unfortunately this seems a bit temperamental and I don’t have this working properly -yet-.
Bitmap b =new Bitmap(width, height);Graphics g =Graphics.create(b);
Screen s =new MyAwesomeScreen();
s.paint(g);//yay I should have it now ! but I don't :(
The other less elegant way, which I am currently using so I could continue getting some work done as a proof of concept, is to toss the screen onto the display stack and then take a screenshot. The major issue here is the screen draws on the device so the user will see flickering. That is not ideal at all.
Bitmap b =new Bitmap(Display.getWidth(), Display.getHeight());
Screen s =new MyAwesomeScreen();
UiApplication.getUiApplication().pushScreen(s);
UiApplication.getUiApplication().getActiveScreen().doPaint();
Display.screenshot(b);
UiApplication.getUiApplication().popScreen(s);//I have a screenshot but I saw a ugly flicker of the screen being drawn
For now I moved on since I had screenshots but I need to resolve this problem later and figure out why the first way doesn’t work…
With the screenshots in hand I put them all beside each other inside the same image so we can start scrolling through.
MAKING IT SCROLL:
A)
I started working on this on the touch phone interface. My first through was to use the touch gesture event which would tell us which direction the swipe was.. the angle of it.. and the magnitude. I converted the angle into a vector.. applied the magnitude.. and extracted only the X position from it to applied to the screen. This worked great! Except… the event only fires when you gesture about 100 pixels.. at a certain speed. Move too slow and it doesn’t happen. Move fast but not far enough and nopes.. nadda. This wasn’t going to work.
B)
My next approach was to use the Move event. It was actually better suited for my needs… a queue of x and y positions constantly fills up with recent movement positions. Grab the offset position from your previous check to the latest position and apply these to the image and you have real time movement. Now as you gesture side to side the image moves in tune with it. There was a problem however!
This event seems to only fire like every 20 pixels making the movement jagged and not remotely smooth. This makes everything feel jagged…
SMOOTHING THINGS OUT:
Instead of just having an offset variable that matched touch input (and caused things to move around jaggedly) I broke things apart…
I setup a variable for screen offset. This is the current screen closest to center of the device visible area (screens are #0-3 for 4 screens) * the screenWidth. The resulting value is used to know the offset for centering the current focused screen in the center of the device.
User’s input is tracked as “touch offset” and added on top of screen offset to visually show it slide back and forth with touch movements. When a user moves far enough to the side I “cycle the screens” over by adjusting my current screen #, which causes the screen offset to shrink or grow by 1 screen width and centering the new screen.
Touch was broken to 2 parts.. the current offset being used to display.. and the desired offset (or target offset as I wrote in my code) based on recent input.
I next added a timer running at 30 FPS which smooths out movements between target offset and current offset always bring them aligned but instead of instantly snapping to position it would gradually do it in a few frames making everything smooth and comfortable. My first approach used a constant value added which was fine when a user moved slow but faster movements made things feel laggy.
The smarter solution was to get the difference between current and target and add a percentage of the difference as the offset. This way it keeps pace with the speed of the movements. Greater distances are leaped faster, smaller ones are eased slowly.
When a finger comes ‘up’ from the device simply set the desired offset to 0, this causes the screen to snap back to center.
USING THE TOUCH PAD:
The touchpad was put in simply by using the work established for the touch screen.
When a user gestures to the right on the touchpad we set a desired offset one screen width to the left and enable the timer. Presto! The screen slides over.
MAKING THINGS MORE COMFY:
My initial approach had the screens cycle over one when the current touch offset was half a screens width in either direction. After some testing I found this didn’t feel as responsive as necessary. Instead I setup a screen cycle threshold. If the movement is within this threshold it will cycle based on the recent direction of their movements. Fir our application it is 2/3 of the screen width in the middle. If the current touch offset is beyond half of the remaining 1/3 of space (half for 1 side of the device) then the screens cycle. If a user slides into the threshold zone but moves back in the previous direction it will cycle them back again. The user doesn’t even know this is happening but the end result controls whcih screen it will snap to the center of upon release. The presumption is a user will move in the direction they desire to go before releasing. The 1/3 of safe zone prevents accidentally changing screens while scrolling vertically.
LOOKING AHEAD:
What needs to happen now is for the selected screen to be zoomed in on when either clicked on or a long enough delay occurs. Once the bitmap fills the device screen the real screen object will be played on the top of the stack.
After that I will be working on establishing the actual screens of our applications and the controls within them…
(this is a bit old but I forgot I left this post saved as a draft / never posted it)
For the UI of BerrySync we’ve been looking to many sources.. such as the BlackBerry’s design principals.. Google’s I.O. conference’s presentation on U.I. design for android… iPhone’s design ideology and design docs.. examples of good blackberry applications from misc websites.. etc…
We are basing this largely on the existing firefox home app available for iPhone but we must consider how it would work on a blackberry device and what must be different too.
Ideally we want to design an app that a frequent blackberry user can easily understand how to use… but we also want to develop something that feels modern and is useful. As a platform a lot of the applications available on blackberry do feel somewhat dated. There is a lot of inconsistency in interfaces as well since BlackBerry provided so few premade controls or transitions for people to employ. Everyone comes up with their own implementations that have slightly different timings. A stark contrast to the iPhone where apple provided a lot of well thought out visually appealing controls for developers to use.
Developing our app will take some balancing of these needs to appease users with what they understand and a desire to make something different and up to our standards.
Also we need to make our ap work on OS5 and up.. and both screen sizes. This also brings on it’s own considerations. Do we develop one UI that works for both, or should we customize the UI different for widescreen vs not? Being OS5 means we cannot use all the modern improvements blackberry has made to their API unfortunately too, tho it is only a small annoyance as best since anything should be possible with some effort still.
————
Firefox Home’s design works great for any touch screen device that is a wide screen but it can be problematic with the traditional blackberry screen size and using the touchpad. Even the button placement is problematic: Blackberry suggests buttons should be at the top not the bottom so a user doesn’t have to scroll through all the content to access them when using the touchpad. Makes a lot of sense really..
Personally I want to minimize the use of buttons to maximize our screen space as there is so little screen space to start with.
We can use numerous adjacent pages and swipe side to side between them keeping the screen space free of useless buttons and showing more content to the user.
———
The problem with the swipe to pages plan is the user will spend more time finding their desired pages since they can only see one page at a time. Many tricks can be used to encourage the user in the direction (a good ones is showing the names of adjacent pages on the top corners). After some consideration we also decided that zooming out while scrolling is ideal as the user can see 3 pages as the same time this way. Though seeing more pages at once they will more rapidly find their content.
//zoomed in.. not a lot to see
//zoomed out.. can see a lot more!
——–
Some simple concepts were done in pencil for how this could look. In this example a fisheye effect is applied but that may not happen in the final application.
With the transition in mobile computing in our society over the past decade from clunky and not overly convenient to something you could finally call truly *mobile* (pocket sized) and powerful enough to be worthy of being called *computing* it is no surprise how widely used data phones have become. I only got my first data phone, an iPhone 4, this last October and I cannot believe how much it has changed many aspects of my life. Largely it has replaced my need for a laptop and music player (previously used for portable email, internet, chatting, music, etc.. plus it’s a phone!). I’ve also found having the internet in your pocket makes information infinity more accessible then before. (Side note- too bad the only thing the iPhone does poorly is -be a phone-, shameful apple :/. The ear piece is so ineffective that without using the headphones it is almost impossible to hear anything through the phone’s speaker.)
*Ahem*, so back on topic.. with this greater reliance on these devices some disparity has grown with inconsistent user data between the workstations in use and their mobile devices. Many companies have put in considerable effects to curb this problem such as the iPhone syncing through iTunes (another side note- why must a phone that does 100 things besides music do all it’s syncing in a MUSIC PROGRAM? Once again apple, you are making no sense), or with blackberry they have their propriety messaging system and the ability to push calendars and emails from an outlook server to the phone. One more recent push has been in the area of browsers with Mozilla’s offering of Firefox Sync, and Firefox Home. Using Firefox Sync one can store to a server (all automated, is in the browser as an addon) the bookmarks, history, and recent or last open tabs from their Firefox browser to be stored on the Mozilla servers for retrieval. Firefox home allows read only access to all that information on an iPhone.
My last post said I would give some project details so here they are: For my work term this summer at CDOT our goal is to bring that same functionality to Blackberry devices that Mozilla has added to iPhone (to start we are focusing on BB OS 5 and 6, both screen sizes, keyboard and touch interfaces… but not tablets). We have called the project BerrySync for now and we are looking through the established FF Home and FF Sync work. (our wiki of project info may be found here: http://zenit.senecac.on.ca/wiki/index.php/BerrySync!) We are still mapping out a lot of features but our current plan is this:
Make sure we can do the same cryto that Mozilla is using
Try to connect with their servers successfully / authenticate with them… and retrieve the Firefox sync data for one user
Work at producing an interface to use that data in a meaningful way
This is obviously a simplification and there is a lot we need to account for. Currently we are busy planning out what we would like to see the application do while researching a lot on the technologies we need to interact with.
Excited to see how this project progresses in the coming weeks.
This is my newly re-appropriated up till now ignored blog space that will be used for discussing my development work at the Center for Development in Open Technologies ( or if you would rather, CDOT ). CDOT is situated in Seneca College in Toronto, Ontario and I am excited to be a part of it for the summer! A lot of great open source development work is carried out in that space with a lot of highly talented people (with 22 new staff just brought in). There are numerous projects being developed and a lot of info is already available on the wiki here if curious: http://zenit.senecac.on.ca/wiki
The project I’m developing on involves blackberry devices (so working with java)… and my personal focus area will be as the interface developer. I’m working on this project with Mao Hua Li, Carl Desautels, plus Mike Hoye who is the project supervisor.
I will discuss our progress here on a regular basis so be sure to check back!
More detailed project info to follow in a future post…