Beside exploring San Diego, I had done some coding intermittently only. My apology if I do not update X2 with fresh new examples often enough.
Having said that, here is one network-related example: a minor tweak to the previous example of Qt-based proxy server. Basically it adds a minimalistic URL filtering support, in the form of blacklisting certain URLs which start with some predefined strings. The code is available in the usual place, X2 repository, under the directory network/filterproxy.
While major browsers support some variants of content blocking, be it via an extension like AdBlock or as a feature built-in into the browser itself, this new filterproxy should work with any browser that supports proxy. Alas, I did not bother to implement an AdBlock-compatible rule system because it would complicate the code. Again, consider this is a proof of concept only. A challenging exercise would be to fully support the most known subscription filters.
It is unheard that content filtering can dramatically improve your browsing experience. Because it cuts the bandwidth usage, it does translate to lower cost for those who are not lucky enough to get unlimited data plan. But most importantly, throwing garbage out of the web pages definitely speeds up the page loading. For this filterproxy example, I did a very unscientific benchmark and test it with Detik.com news site (now you get the answer why the included blacklist.txt contains only some basic advertisement-laden sites). The screenshots below (click to enlarge) show the unfiltered version (left) and the filtered version (right). Notice also the whopping 40% of bandwith saving!
My promise was to post two variations from that simple proxy example. This counts as one of them, and when the time allows me to clean-up to the other, you'll know it. Stay tuned and happy proxying!
Just like Rich's trick with QNetworkAccessManager, I have done something similar which I call tracenet (around 150 lines of code). Though I have committed this example to X2 some time ago, only now I have the chance to blog about it.
The idea is to subclass QNetworkAccessManager and reimplement its createRequest method so that we can keep track all the network responses and replies. This is useful for your network-based application, or even for e.g. QtWebKit. As a matter of fact, the tracenet example captures the network traffic as you load a URL into a web page.
Now, the next step is how to visualize the result. While it's certainly possible to craft a Qt-based fancy GUI for this (maybe using Qt Quick?), let's think outside the box. Unless you live in a cave, I am sure you are aware that there is this nice tool called Speed Tracer, part of GWT, an extension for Google Chrome or Chromium. For this purpose, we won't use the live profiling feature of Speed Tracer, but rather its ability to visualize network requests and replies (with nice timeline and so on). All we have to do is to carefully spit some JSON-formatted data that match the Speed Tracer data dump format. And that is exactly what tracenet does!
The screenshot below gives an exemplary result from running tracenet on my Nokia N900 when it accesses New York Times front website, a notoriously complicated web page. All I did was to execute "tracenet > nytimes.htm", transfer back the HTML file to the laptop and then open it with Chromium on OpenSUSE, click on "Network (resources)" line, and voila! You can click on each entry to get detailed timing info, use zoom in/out, and many other features of Speed Tracer. Refer to some tutorials if you are new to Speed Tracer.
If you want some follow-up and challenging exercise, try to split Speed Tracer code so that the pure GWT-part can run on any browser. Then you can just package it with QtWebKit and use it to show the outcome of all your network sniffing. Have fun!
I guess a simple proxy server should have been an example in Qt Network module. What I mean of course a real proxy server based on Qt, not about using a proxy server via QNetworkProxy class. After all, there are other more complex examples like the torrent client and Google suggest (yeah, blame me for the latter). As a matter of fact, there are e.g. a gazillion proxy servers written in Python.
Look no more. I posted an example in the X2 repository, under the directory network/webproxy. The code is written for clarity and not for performance. In fact, fancy error handling is even omitted (minimalism rulez!). There is no support for pipelining, or in-memory cache, or per-connection thread, or even secure connection via https. I leave them as exercises for the curious readers.
If we focus on things which work, here they are: asynchronous socket handling, different request methods (GET/PUT/POST/HEAD), persistent connection aka keep alive, and even Flash and HTML 5 video streaming. Yes, you can still watch YouTube or Vimeo if you hook your browser into this little proxy. For a few hours of hacking and 92 lines of code (as reported by sloccount) and certain ways to abuse QObject, I could not be more happier.
There will be two other offspring examples based on this one. So stay tuned. Meanwhile let's just hope nobody would ask me for a colorful UML diagram for this snippet...
PS: Special thanks to Jan Erik for his feedback and review.
As I promised before, here is a fresh X2 example. Those who attended Bossa Conference 10 and followed my talk are lucky to have seen it for the first time there. In fact, this example is ridiculously simple that I am not surprised at all if somebody has done this ages ago.
Let's start with a screen capture, or two:
Basically the above shows an analog and digital clock running on my Nokia N900, hardly a shock. However, the fun part is when you switch the clock from analog to digital and vice versa. Check out this video, courtesy of Signor Portale from Nokia/Qt, showing the morphing on Nokia 5800:
The trick is simple. Actually it's not even generic enough, meaning that you can't morph from an arbitrary path to another arbitrary path. However, for this clock use-case, the gross approximation is good enough. First, we need to convert the path into a polygon, which is done easily via QPainterPath::toFillPolygon() function. Then any line segment in the polygon longer than a certain tolerance is further split into smaller segments. As I claimed above, the result is not perfect, i.e. it does not approximate the original path into line segments with equal length. But hey, it is good enough for this animation purpose (unless your user has ueberhuman eyes).
The target path needs to be sliced into segments as well. Since we have only two types, circle (for the analog clock frame) and solid block (for the hour and minute hands), it is easier to special-case both. The secret is to have the same number of segments as the source path. The following figure shows the digit '7' and a circle, each splitted to 28 line segments. Small dots indicate the start and end points of those segments. The animation is now a matter of doing tweening, or linear interpolation, between each segment.
The flaw of this trick is when the source path contains holes inside it, e.g. for digits like 0, 4, 6, 8, and 9. Again, we are cheating here for the sake of keeping the code simple, so I leave the code as it is. Doing a more advanced, better handling for those cases is left as a motivational exercise for the perfectionist readers. Another bonus puzzle: find out why 503 ms is the morphing time (hint: find the same number in Qt source tree).
For the sake of completeness, let me mentioned Dali Clock (even in Canvas and JavaScript version) from the famous Jamie Zawinski (jwz). It is similar, however Dali Clock just morphs the digits of the digital clock.
Also, if you just prefer a normal (but old-fashioned!) digital clock with the flipping effect, check the digiflip example I did back then. You already have it if you install Qt 4.6 for Symbian.
Last but not least, I'd like to mention my "special thanks to Delta Airlines for such a long (but safe) flight to Brazil so I had the chance to write this example while I was bored", but then I was told by the Trolls that this kind of intro line can't be funny anymore.
I got few proposed designs after I announced X2 project back then. It is tough to pick the winner cause they are all very good. In the end, the one from Elvis Stansvik becomes the new official logo of X2:
Thank you to everyone who has sent me the logo design!
Right now I am in Manaus, in the middle of the Amazon, Brazil. Good weather, beautiful nature. Fresh tropical rain, feels just like home.
Yes, I am here for the (legendary) Bossa Conference '10 from the awesome INdT folks. I had delivered my talk, Redefining Mobile Graphics Stack this morning. I used the chance to preview (and got feedback) some of upcoming graphics example for X2 from Ofi Labs (what's X2? read the explanation), even straight from my N900, so just watch its git repository in the next few weeks. BTW, Radeon HD 3200 of my new toy and TV output of N900 worked out-the-box with the projector.
It is also nice to meet few INdT guys I knew, and get to know new folks as well. Since a few Trolls are also here, I also catch up (and share more jokes) with them. Gosh, feels like ages since I left Oslo.
This is my first visit to Brazil. Looks like it won't be the last time!
There is a bunch of code out there (which can be copied and pasted) to grab the acceleration values from Nokia N900. Here I contribute one more, it's Qt-based and using the QtDBus module. The values in x, y, z will have the unit of G.
As usual, error checking is omitted (left as an exercise for the reader). Like Star Wars, there is also a reason I skip the first 3 QStrings. Debug it yourself to see what you would get. In addition, I found out that at most it would take 25 ms to grab all three values. It means, if you run your application at > 40 fps, then better put this function is a separate thread. Actually, consider that you don't want QDBusPendingReply::waitForFinished() to block your entire GUI, this is likely a good idea anyway.
For a full-version of an accelerometer tool, check out the X2 repository under the sub-directory sensor/accelview. Note that technically acceleration > 1 G is always possible, I clamp the values in this example to keep the UI simple.
Qt documentation mentions QPalette as the class that contains color groups, Active, Inactive, and Disabled, for each widget state. Knowing the color for many different color roles is important. For example, a style author might want to tweak the colors of each buttons depending on QPalette::Button, QPalette::ButtonText, QPalette::Highlight and likely play with the shades and the saturation. There are probably few different ways to get the RGB values of those colores, here I show one of them: using a small tool that display all the color roles for active, inactive and disabled states:
Like what every interface designer would tell you, you can't just reuse desktop user interface to your mobile version of the application and pray that the application will be useable. Here is an example. In a web browser designed for a mobile device armed with a touchscreen, the typical mapping the touch coordinate to the usual mouse event presents a problem because seems every screen has its own accuracy and precision problem. Sometimes it's hard trying to visit a link, merely because it is not possible to hit the link properly with your finger.
The solution seems to be quite (ridiculously) easy. Instead of trying to find what is exactly under your finger (point of contact with the screen), let's also probe the area in the nearby. If there is a link very close to it, then assume the user wants to go there, she just misses the link accidently by a few pixels. If there are multiple links, then pick the nearest one.
I have written a very short example, using Qt 4.6 (or later), based on QtWebKit, to demonstrate this workaround. Check the code in the X2 repository under the directory webkit/probelink. It might not work on web pages with multiple frames, but at least you got the basic idea. The chosen link is even highlighted before the browser loads it, just like in the screenshot above.
Next week, or the week after, let's see another simple example which implements something like Opera Fingertouch.
I know the number of Qt experts out there is growing (like crazy). Still, I believe we should do more to help people master this great framework. I am aware that I might bore you with few Qt code examples I did last year or even the year before, but somehow I feel that I won't do no harm if I keep sharing new stuff I learn every now and then (especially since now I got a new toy). And maybe it's not too bad if I change this blog tagline to "don't code today what you can't share tomorrow" :)
Since I am not with Nokia/Qt anymore, I also left the Graphics Dojo corner behind. I decide to publish my new and upcoming Qt examples under a new moniker: X2 from Ofi Labs. The two Xs there stand technically for eXperiments and eXamples, though X2 only sounds cool (even if that X-Men movie would not exist) and I prefer it that way. The name "Ofi Labs" will require a longer explanation, which I rather not elaborate right now.
The git repository for X2 is at gitorious.org/ofi-labs/X2. In the next few days, watch this space for the first few examples.
Meanwhile, enjoy the logo. If you are an artist, feel free to propose a new and better logo!