Filter: code, computer science, software, tech, life, robotics

Qt Manual/Fixed Layout Manager ("QManualLayout")

I still question whether I missed something very obvious, but it seems difficult to manually layout widgets in the Qt Framework, and there isn't any provided QManualLayout layout manager. Below you will find my implementation of one. And yes, there are plenty of special cases where you might need one. Using my layout manager you can place widgets anywhere on the layout using the common widget methods such as move(), resize(), and setGeometry().

/*******************************************************************
**
** Qt Manual/Fixed Layout Manager ("QManualLayout")
** ManualLayout.h
** v1.0
**
** This layout manager lets you easily programmatically place
** widgets in a fixed/manual method. Widgets can be placed
** in a fixed method and dynamically moved on the layout manager's
** widget resizeEvent(QResizeEvent*) event.
**
** Usage:
**
** this->setLayout(new ManualLayout());
** QWidget *widget = new QWidget(this);
** widget->setGeometry(10,10,200,100);
**
** Copyright 2012 Dan Krusi, Nerves Design & Engineering
** dan.krusi@nerves.ch | www.dankrusi.com | www.nerves.ch
**
*******************************************************************/

#ifndef MANUALLAYOUT_H
#define MANUALLAYOUT_H

#include <QtGui>
#include <QList>

class ManualLayout : public QLayout {

private:
QList<QLayoutItem*> list;

public:
ManualLayout(QWidget *parent): QLayout(parent) {}
ManualLayout(): QLayout() {}
~ManualLayout();

public:
int count() const;
void addItem(QLayoutItem *item);
QSize sizeHint() const;
QSize minimumSize() const;
QLayoutItem *itemAt(int) const;
QLayoutItem *takeAt(int);
void setGeometry(const QRect &rect);
};

#endif // MANUALLAYOUT_H

/*******************************************************************
**
** Qt Manual/Fixed Layout Manager ("QManualLayout")
** ManualLayout.cpp
** v1.0
**
** This layout manager lets you easily programmatically place
** widgets in a fixed/manual method. Widgets can be placed
** in a fixed method and dynamically moved on the layout manager's
** widget resizeEvent(QResizeEvent*) event.
**
** Usage:
**
** this->setLayout(new ManualLayout());
** QWidget *widget = new QWidget(this);
** widget->setGeometry(10,10,200,100);
**
** Copyright 2012 Dan Krusi, Nerves Design & Engineering
** dan.krusi@nerves.ch | www.dankrusi.com | www.nerves.ch
**
*******************************************************************/

#include "ManualLayout.h"

int ManualLayout::count() const {
return list.size();
}

QLayoutItem *ManualLayout::itemAt(int idx) const {
return list.value(idx);
}

QLayoutItem *ManualLayout::takeAt(int idx) {
return idx >= 0 && idx < list.size() ? list.takeAt(idx) : 0;
}

void ManualLayout::addItem(QLayoutItem *item) {
list.append(item);
}

ManualLayout::~ManualLayout() {
QLayoutItem *item;
while ((item = takeAt(0))) delete item;
}

void ManualLayout::setGeometry(const QRect &r) {
QLayout::setGeometry(r);
}

QSize ManualLayout::sizeHint() const {
QSize s(0,0);
int n = list.count();
int i = 0;
while (i < n) {
s = s.expandedTo(list.at(i)->sizeHint());
i++;
}
return s;
}

QSize ManualLayout::minimumSize() const {
QSize s(0,0);
int n = list.count();
int i = 0;
while (i < n) {
s = s.expandedTo(list.at(i)->minimumSize());
i++;
}
return s;
}

You can download a demo project including the source here:

Source Download: ManualLayout_src.zip

Tags: code

SVN Global Ignore

Are you annoyed by setting svn:prop on all your repositories and subdirectories with the same redundant ignore lists? There is actually a handy configuration setting called global-ignores which will let you ignore specific files client-side in a global fashion. All you have to do is edit your SVN client config file at ~/.subversion/config with something like the following:

global-ignores = *.o *.lo *.la *.al .*

Tags: computer science

64 Bits

64-bit processors and operating systems have been available to general consumers for just about ten years now. It's astonishing how hard it has been for software developers and vendors to fully make the transition to 32-bit architectures. Even when we install a 64-bit version of OS X or Windows, if we look closely there is still a lot of software running in 32-bit mode. Most rude are some of Adobes Create Suit products, such as In-Design CS5, which still runs in 32-bit on OS X.

I finally made the complete transition to 64-bit on my Linux machines. I don't have a single bit of code in 32-bit running anymore. Everything is compiled for my 64-bit wide registers and to take advantages of the 64-bit architecture.

The upside: Theoretically some software might run faster, but basically it's just progressive and cool.

The downside: Some software might be harder to find (and not available). Thank God I use Linux and open source software.

Tags: computer science

Clipboard Sharer

I use two computers running Linux and OS X for various frustrating reasons, and something that has bugged me for a long time is the wall between clipboards. It's an obvious problem: when I copy something on one machine I want to be able to paste it also on the other machine. So I finally sat down one evening and wrote myself a cross-platform clipboard sharer. Clipboard Sharer lets you share a common logical clipboard between two machines on Linux, OS X, and Windows.

Clipboard Sharer sits quietly in your system tray.

You can access it's settings by right-clicking it.

Simple and straight-forward.

I plan on adding new features as I need them. Currently it only supports text, but files will surely come soon. Also, if someone requests it, I'll change the 1-1 relationship to 1-N (meaning you can connect any number of machines). A history tool will also be added soon, allowing you to fetch older clipboard elements.

Binary: Clipboard Sharer 0.1 Linux

Binary: Clipboard Sharer 0.1 OS X

Source: Clipboard Sharer 0.1

Note: The binaries will require the Qt Runtime which can be found at http://qt.nokia.com/downloads.

Tags: software

iPhone Tracker

Alasdair Allan and Pete Warden have put together a great piece of software which nicely displays where your iPhone has been over it's lifetime. Below you will find some impressions of my coverage...

Switzerland

Zurich

Zurich Detail

I love the fact that Apple has this tracker built in to all it's iPhones. Yes, I know the privacy implications, but look how interesting this is! The way Apple implemented it is also very smart: they use triangulation from cell towers (thus the low resolution), which doesn't impact the battery consumption. One question remains: how do they know where the cell towers are?

If you are curious where this secret file from Apple is, search for consolidated.db on you jailbroken iPhone.

Tags: tech

Web Developer Extension Mod

If you've ever coded up any HTML/CSS, you'll probably have come across the excellent Firefox/Chrome extension Web Developer by Chris Pederick.

I mostly use the tools ability to outline all the block level DOM elements which helps when constructing complex structures. In addition, the tool also can spit out the DOM path (and all it's classes) for any element you hover over ("Outline Current Element"). However, the output of the path is quickly clipped by the size of the browser when displaying highly nested structures.

So here is my modded version of Web Developer which solves this problem:

Binary: web_developer-1.1.9x-fx+sm.xpi

How to find this: Web Developer "Outline Current Element" information box as a multiline text box.

Tags: software

ConvertX for ImageMagick

I use ImageMagick to convert images on a daily basis. It's rarely failed me with missing features or problems, but one thing that really bothers me is the way convert handles batch conversion of *.ext files on Unix. Other than no being able to easily change/append/prepend filenames, the greatest problem is that all images are done in one process. That means if I convert 200 images, they are all done in one convert process. That's why I wrote ConvertX, which simplifies this process for me and splits up batch jobs into separate commands.

Once installed, the command convertx works just like convert, except there are added arguments and variables that can be used.

Example:

Let's say I have three PNG images (A.png, B.png and C.png) and want to convert them to low quality JPG images with an appended "low" to the filename. With convertx I can do this easily:

convertx "*.png" -quality 80 "%f_low.jpg"

The command is then split up into the following convert commands:

convert A.png -quality 80 "A_low.jpg"
convert B.png -quality 80 "B_low.jpg"
convert C.png -quality 80 "C_low.jpg"

Here is the full source code:

#!/bin/sh

# Grab files to convert...
FILES=$1
shift
echo $@
ARGUMENTS=$@

# Loop files
for FILE in $FILES
do

# Extract filename
FILENAME=`echo $FILE | sed 's/\(.*\)\..*/\1/'`

# Replace filename variable...
ARGUMENTS_PROCESSED=`echo $@ | sed 's/\%f/'$FILENAME'/'`

# Do conversion
echo "convert $FILE $ARGUMENTS_PROCESSED"
convert $FILE $ARGUMENTS_PROCESSED

done

You can also download a ZIP file with the script and accompanying setup/install script:

Source Code: ConvetX.zip

Tags: code

Pixelation

I recently came across photographing some close-ups of several iPhone/iPad Apps we developed at Nerves. Fore some reason, I had forgotten how wonderful our back-lit LED displays are. Isn't it amazing that these screens work for countless hours with hardly any visible error.

Below are some impressions of our photo-shoot.

Pixels at Large 1

Pixels at Large 2

Pixels at Large 3

Tags: life, tech

Welcome to the Digital Age

I was recently interviewed for a documentary film about life in the digital age. Below are some excerpts which might be of interest.

What aspects fascinate you in the digital worlds in which you live in? Which opportunities do they offer?

Since I was a young child I was completely fascinated by electronics. My parents were always afraid to leave a calculator or such lying around, because they knew that if I found it I would surely take it apart, inspecting all the insides thoroughly. When I finally got my first computer at age 10, I discovered the internet, which instantly became my new passion. I was absolutely captivated by the idea that I could publish something online which would be instantaneously reachable from all corners of the globe! Today we take it for granted, but 15 years ago this was groundbreaking in the way we communicate with each other as well as with whom we communicate to. The digital world has progressed, where now I am always connected in some manner to multiple services spread across the globe which provide information in a constant stream. To me, the digital world is an (almost) unlimited resource, where information is easily obtainable. If I want to know who ruled England during the 18th century, I only need to grab my phone and type “18th century king england” into Google. Before the digital revolution, gaining this knowledge was considerably harder. This is what fascinates me: the wealth of obtainable knowledge. That's why I co-founded NERVES, where we develop digital services and applications and constantly try to redefine how we communicate digitally.

Could you say that the digitalization of technology has changed your life? How?

Yes, definitely. Probably the most astounding change is the way I interact with people. I'm sure I spend more time interacting with most people through a digital service, such as E-Mail, SMS, Networking, et cetera, than actually talking with them in person. This has both positive and negative effects and my daily life. In some senses I feel more productive (it's faster to Twitter a birthday party than call everyone), but at the same time I also feel much more disconnected from many people, especially in the professional world. I grew up in Africa, Asia, Middle East, Europe, and America, so I have many friends spread out all over the globe. Since the widespread use of the internet and social networks, I now have daily contact with all these friends again. So there are definitely positive benefits from the obsessive digital revolution.

How does your social circle react to your active digital life?

My curiosity makes me a typical early adopter. Most people react well to that, showing a similar interest in much of my digital life, just at a different (lower) level. My family have all slowly joined in on the digital world. We now commonly communicate with Skype and SMS. Even my mother has a Facebook profile now, and tries to promote her art on the internet. My deeper passion with computer science is not understood well by the people around me, neither are they interested. I mostly keep that to myself and a handful of fellow nerds.

Tags: life, tech

Stretching the Timeline in Flash

One of the greatest lacking features in Adobe Flash is the ability to stretch the timeline. I find this an unbelievable missing feature. I assume the reason it is missing is because of the technical questions that arise when stretching the timeline: mainly that which has to do with rounding errors. Because flash is keyframe oriented, rounding errors can become sorely visible when performing stretch operations. A difficult problem to solve universally. However, in many cases these errors can be ignored. Below is my JSFL script which will stretch the selected frames on the timeline by any given factor.

//
// Stretch Timeline Flash Extension Command
// v2
//
// This extension will automatically stretch the selected frames
// to the given factor of the currently selected timeline.
//
// Compatible with Adobe Flash CS3/CS4.
//
// Based on Reineir Feijen's Flash Extensions. Contributions by Nitin Malik.
//
// Copyright 2011 Dan Krusi, Nerves
// dan.krusi@nerves.ch | www.nerves.ch
//

// Init
var valid = true;
var factor = 1.0;

// Sanity check and factor input
if (fl.getDocumentDOM() == null || fl.getDocumentDOM().getTimeline() == null) {
alert("No timeline is selected!");
} else {
var ret = prompt("Stretch Timeline by a factor. For example, 0.8 would speed up the timeline while 1.4 would slow it down...\n ");
if(ret != null) {
factor = parseFloat(ret);
if (isNaN(factor)) {
alert("The factor '"+ret+"' is not valid!");
} else {
// Rock n Roll!
stretchTimeline(fl.getDocumentDOM().getTimeline(),factor);
}
}
}

// Strech the timeline
function stretchTimeline(timeline_obj, factor) {
// Init
var tl = timeline_obj;
//cleanSelection(tl)
var sel = tl.getSelectedFrames().concat([]);

// Loop selection
for (var i=0;i<sel.length;i+=3) {
var splices = [];
var changed = 0;
var frameCount = tl.layers[ sel[i] ].frameCount;

// Nitin Malik: If startFrame is on empty frame
// Based on fact empty frames can only come after all frames on the layer
if( sel[i+1] > frameCount ) {
sel[i+1] = frameCount;
}

// Nitin Malik: If endFrame is on empty frame
if( sel[i+2] > frameCount ) {
sel[i+2] = frameCount;
}

tl.setSelectedFrames([sel[i],sel[i+1],sel[i+2]]);

// Calculate splices
for (var j=sel[i+1];j<sel[i+2]+1;j++) {
if (j==sel[i+2] || (tl.layers[sel[i]].frames[j] && j==tl.layers[sel[i]].frames[j].startFrame)) {//only keyframes and last frame
var goal = sel[i+1]+Math.round((j-sel[i+1])*factor);
if (factor>=1) {
var df = goal-(j+changed);
var at = j-1+changed;
} else {
var df = (j-changed)-goal;
var at = j-changed;
}
if(df>0) {
splices.push([at, df]);
changed += df;
}
}
}

// Insert/remove necessary frames
if (factor>=1) {
for (var j=0;j<splices.length;j++) {
tl.insertFrames(splices[j][1], false, splices[j][0]);
}
} else {
for (var j=0;j<splices.length;j++) {
tl.removeFrames(splices[j][0]-splices[j][1], splices[j][0]);
}
}
}
}

Download: StretchTimeline_v2.jsfl

Select the Frames to Stretch on the Timeline

Select 'Run Command...' from the Menu

Open the StretchTimeline_v1 Script

Enter the Desired Stretch Factor

Verify the Results

Update: Thanks to Nitin Malik (blog.nitinmalik.com) for contributing some changes to handling empty frames.

Tags: code

Page 1 of 9 Next »