Menu

DevelDoc-DesignNotes

Luis Garrido

Design notes

Qt Reference Documentation

Design guidelines

It's all about choices. IIAAC.

FLAM is for both Gary Garish and Clint Succinct.

Allow as much wiggle room as possible while keeping things in a manageable level of complexity (yeah, right!)

Bonus effect of a MIDI in/out: poor man's parameter automation.

Qt Look & Feel

QStyle

QWidgets are rendered in the paintEvent() event. Most factory QWidgets defer the look and part of the feel (like the dimensions of the handle of a slider) to their QStyle. If they don't have a QStyle they defer to that of the qApp.

QStyle takes into account some properties of the QWidget to perform the drawing, like its QFont, QPalette, etc. These attributes are inheritable.

From Qt documentation:

http://doc.trolltech.com/4.5/qapplication.html#setStyle

QApplication::setStyle(new QWindowsStyle); When switching application styles, the color palette is set back to the initial colors or the system defaults. This is necessary since certain styles have to adapt the color palette to be fully style-guide compliant.

Setting the style before a palette has been se, i.e., before creating QApplication, will cause the application to use QStyle::standardPalette() for the palette.

What about the widgets that are not overriden? FLAM styles could be based on one of the Qt standard styles, like Windows or Motif, but it would be nice if we could preserve the user's default style of choice.

See qapplication_x11.cpp. qtconfig-qt4 stores a default style choice in:

QSettings settings(QSettings::UserScope, QLatin1String("Trolltech"));
settings.beginGroup(QLatin1String("Qt"));QString stylename = settings.value(QLatin1String("style")).toString();

See also how a default style is chosen if this setting is empty at QApplicationPrivate::x11_desktop_style()

A FLAM piggyback style could on creation read qApp->style() and create a private copy for itself (we shouldn't store that reference because it will be destroyed.) It seems not trivial to find out what kind of style it was. There is also the risk of triggering a cascade of piggybacking style constructors. What if the qtconfig style is a FLAM style?

Meh, sounds more trouble that it is worth. After all, non-FLAM widgets should be very few. Just pick one of the standard ones as a base and get done with it.

QPalette

Family of related colors to achieve a pleasant balance and a coherent style. A palette is inherited from parent to children. Like other heavyweight objects in Qt, it is passed around via a clever copy-on-write mechanism called implicit sharing.

Qt Stylesheets

More look than feel. No need to code a QStyle plugin. Supersede styles. It is the only way of setting up background images from Qt Designer.

Interesting fact: since Qt 4.3 style sheets can be used to set properties:

QPushButton { qproperty-iconSize: 20px 20px; }

Palettes vs Style sheets

Palettes are an intrinsic part of QStyle architecture. Style sheets override the GUI coherence forced by styles. Style sheets are not accessible by custom styles at the moment, although they will be in the future.

Style sheets are easily stored in human-readable files. Palettes can be serialized to an ASCII stream of binary data via the QSettings mechanism.

Style sheets allow setting pixmaps as backgrounds and borders from within Qt Designer. Palettes can have pixmap brushes, but cannot.

Palettes are inherited by QWidget parentage. Style sheets offer a pretty powerful CSS-like selector mechanism.

Skins

The purpose of skins is to futher customize styles that use media files to render the widgets. For instance, a style based on bitmap animations (QMovie) could have different substyles of sliders, dials, etc.

The problem is at what level does this configuration belong and whether or not propagate it through the QWidget inheritance tree.

In the end a UI is a combination of:

  • Layout (coming from the UI file and the style.)
  • Visual variations: color, font... I think skin belongs in this level. This is style sheet stuff. A style sheet can be general or tailor made for the UI (for instance, grouping functionally related controls in QGroupBoxen of different colors.) I think it makes sense if there is a general style sheet selectable by the end user and a particular one embedded in the UI. Advice the designer to keep this one minimal and try to devise a general one making clever use of selectors.
  • Connectivity settings for the controls that need them. For convenience these can be piggybacked as Qt properties editable in Qt Designer and thus will end up in the UI.

Let the end user change the general skin (i.e. the one not overridden by the UI). This means I have to implement some sort of global skin mechanism.

One possibility is to travel upwards in the QObject hierarchy until I find a skin property:

QVariant QObject::property ( const char * name ) const

There should be a default value, or if there is no default skin, the style could pass the operation to its parent.

The skin can be implemented as a styleVariation property, settable manually at Qt Designer or via a style sheet. This property will be a string of the form "stylename(parameters)" and its semantics are defined by the style to what it is addressed. It is conceivable that two very similar styles could share the semantics (i.e. a movie based style and a SVG one: a designer could make parallel themes/skins for both engines.)

Distribution

Directory structure

Base directories

http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html

Environment variable
Default

$XDG_DATA_HOME
$HOME/.local/share

$XDG_DATA_DIRS
/usr/local/share/:/usr/share/

$XDG_CONFIG_HOME
$HOME/.config

$XDG_CONFIG_DIRS
/etc/xdg

$XDG_CACHE_HOME
$HOME/.cache

FLAM directories

Sort of FLAM_PREFIX:

$XDG_DATA_{HOME,DIRS}/flam

UIs:

$FLAM_PREFIX/uis/{dssi,ladspa}/<soname>/<pluginid>/<name>.ui

Qt Designer allows to insert into UIs relative references to qrc files.

Packaging alternatives

Custom widgets and styles

Perhaps it is better form if we don't pollute $QTDIR with the plugin libraries that contain styles and widgets. This is no problem for FLAM's own executables that can use QCoreApplication::addLibraryPath. For making Qt Designer aware of FLAM stuff we must use then the environment variable QT_PLUGIN_PATH.

FLAM widgets

FLAMDialog

Add properties:

  • Remove decoration.
  • Translucent background.
  • Copyright.
  • Draggable.
  • preferredStyle.
  • preferredTheme.
  • preferredStylesheet.

FLAMAbstractSlider

Value display

Regular QStyle's QSliders and QDials are not too strong at conveying at a glance their value, except Cleanlooks, which colours the lower part of the slide bar. You can always tie a QProgressBar to them, but this is suboptimal and kludgy to solve for the QDial. Besides, range hints are important too, see below.

Range hints

For audio widgets it is desirable a visual indication of whether they are unipolar or bipolar.

We may let the ui designer choose a different skin for those particular widgets that need it, but what of non-skinnable ones? I think it is cleaner add some kind of rangeHint property: unipolar, bipolar. A hint of Cyclic would also be possible, but only for dials and it is taken care of via QDial::wrapping.

Stylesheet

Transparent Windows

http://doc.trolltech.com/4.5/qwidget.html#creating-translucent-windows

// Remove window manager decoration (not all WM support it).

Qt::WindowFlags flags = windowFlags();
setWindowFlags(flags | Qt::FramelessWindowHint);

// Allow translucent window (not all WM support it, must have composition enabled)

setStyleSheet("background-image: url(something-transparent.png)");
setAttribute(Qt::WA_TranslucentBackground);

Dragging a window

http://lists.trolltech.com/qt-interest/2002-01/msg00228.html

Ideas

MIDI learn

Other protocols

dbus?

Other widgets

XY, envelope.

Arbitrary OSC messaging

A widget is configured with an OSC address, type tag and a pattern string where each value can have a literal value, a reference to one of the widget properties or a "keep the last received or sent value" indicator. Ex.:

  • Address: /speaker
  • Type tag: isfff (number of speaker, speaker ID, 3D coordinates.)
  • Value: 1,-,$1,$2,$3 (send speaker 1, keep the previous name, set the coordinates to three values given by the widget state.) A companion text line widget could have the value 1,$1,-,-,-

Extend ladspa ontology to include program and bank number in preset

In the n3 file add the following triples:

presetEntity http://dssi.sourceforge.net/ontology#hasProgram nn presetEntity http://dssi.sourceforge.net/ontology#hasBank nn

Extend lrdf:

Add a similar function to lrdf_add_preset(): lrdf_add_dssi_preset(), adding bank and program like the label is added. Add similar functions to lrdf_get_label(): lrdf_get_program() and lrdf_get_bank()

FLAM rack

All the GUIs under one window? Mmm, make that a multitab window, one tab per OSC server URL? If a family of rackable UIs is used plus some position snapping it could make for a very compact and slick view.

How to publish the service, QSharedMemory perhaps? A well-known osc.udp port? The infamous dbus?

Use QDockWidget for snapping? Perhaps too limited. Just a QHBox (full tab) containing QVBoxes (rack columns) containing QHBoxes (rack rows) containing the UIs.

19" rack units use 1.75" as U height, that's a 10.8571 aspect ratio. I guess if a UI designer is targetting rackability power-of-2 modules make good choices: 16x16 px, etc.

http://en.wikipedia.org/wiki/19-inch_rack

http://en.wikipedia.org/wiki/Display_resolution

Frameless or framed? I'd say at least title bars should be necessary. They eat up some space but provide separation and allow to display the "user friendly" identifier supplied by DSSI.

Is necessary to provide a mechanism to save a session file with this arrangement? Preloaded UIs ready to be connected (connection indicator in the title bar)?

Miscellanea

Creating a multipixmap with ImageMagick

The options are case-sensitive:

montage -mode Concatenate -background None -tile x1 button0*.png button.png

Qt parenting issues :-)

Some reparenting methods worth remembering:

  • QMainWindow::setCentralWidget()
  • QLayout::addWidget()
  • QLayout::addLayout()
  • QLayout::QLayout(QWidget *parent)
  • QWidget::setLayout()
  • QTableWidget::setCellWidget()

... et al. Search for the word "ownership" or "reparent" in Qt Assistant.


Related

Wiki: DevelDoc

Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.