ドリコムの俺を支えるUIツールキット

これは ドリコム Advent Calendar 2014 - Adventar の8日目です。

7日目は おーはら (@ohrdev) | Twitter さんによる 写経 - 般若心経F*ck、コピペで徳を高める話 - Qiita です。

f:id:sazae657:20141207134418p:plain

自己紹介

@sazae657

配線工や商業作曲家等を経て、現在はドリコムにてクロスプラットフォーム開発向けのミドルウエアやデータプロテクション等の研究開発をしています。

ドリコム釣り部CFO(Chief Fishing Officer)

本日の話

クライアント/サーバー両用、クロスプラットフォームのライブラリを作っているので、データ生成ツールや逆アセンブラーなどの個人的に使うツールをたくさん作ります。

そのツール類の爆速開発を支える Motif についてゆる〜くお話しします。

背景

ライブラリをC/C++たまにアセンブラで作ります。
この時にデータ生成等のツールを作るのですが、コレがどんどん複雑化していきコマンドラインオプションが MagaCLI 並に大変な事になるようなゆゆ式事態が発生。
という事でGUIでマルチスレッドでポインティングデバイスでポチポチ出来る素敵ツールを作ろうと思ったのですが、iOSを扱うので開発端末はMacMacといえばXQuartz、X11といえばMotifという事でMotif を選択しました。

Motif って何よ

最近はGTKやQtは知ってるのに、Motifを聞いた事すら無いという人が増えてきて寂しい限りですが、X Window System 上で動く信頼と伝統のUIツールキットです。
超絶格好いいクールなLook&Feel とシンプルで洗練されたAPIが特徴です。

昔、布教しようと頑張りましたが・・・無理でした

以前はライセンスを買う必要があったので、Lesstif のような互換ライブラリを使いましたが、現在は 非商用に限りOpenMotif として本家の Motif が使えます。ライブラリのビルドは簡単なので割愛します。

ちょっとアラートダイアログを出してみました。

f:id:sazae657:20141207153905p:plain

かっけえ!!!!

Windows Phone に端を発し、Nimdaも顔負けの大流行中っぷりを見せるフラットデザインとは真逆を行くエッジの立ったボタン、フォーカスの当たっているボタンは周りが大きく陥没し、これでもかと言うほどの存在感を放っています。
ビットマップフォントも美しいですね、やっぱ -misc-fixed-medium-r-normal--14- はいつ見ても美しいです。 シャープでエッジの効いた Motif にはアンチエイリアスボケボケフォントより -misc-fixed-medium-r-normal--14- ですね。

もう一個

f:id:sazae657:20141207161629p:plain

プルダウンメニューです。
とにかく立体的です。選択項目がボコボコと膨らむので非常にわかりやすい上に格好いいです。実際に触った全人類の90%はこの格好良さと独特のフィーリングの前に論議など無意味と知る事になるでしょう。


ツールといえばダイアログ、ダイアログの華といえばグループボックスに収まったラジオボタンチェックボックスですよね!

f:id:sazae657:20141207163640p:plain

Motifのソレはこれまた超絶格好いいのです。
ダイヤ型のラジオボタン、四角いチェックボックス
そう、シンセサイザーなんかのトグルスイッチがそうですね。UIのパーツ表現として非常非常ひじょーーーーー優秀です。

ボタンと同じようにフォーカスが当たっているウイジェットには黒い枠線が引かれ、キーボードでのフォーカス切り替え時の視認性は抜群です。細かい所まで気が利いてます。

GTKで実装されたGnomeやQtで実装されたKDEのようにMotifで実装されたデスクトップ環境のCDEという物もあります。
自宅で使っているSun Ultra45ワークステーションはずっとCDEです。メチャクチャ格好いいです。やる気がみなぎってきます。
現在はオープンソースになっているので是非、お試しください(超絶格好いいです)

The Common Desktop Environment

その昔、大枚叩いて買ったLinux向けのDeXtop CDEという物もありました。

以外とモダンだぜ Motif

古くさいように見えますが、結構モダンな造りなのが Motifの良い所
XmPushButton (超格好いいプッシュボタン)の定義はこんな感じになっています。

f:id:sazae657:20141207171638p:plain

そう、継承関係があるんですよ!!

Button は・・・
TextView を継承してるから setText が出来る
TextView は View を継承しているからsetXが出来る

どこぞの AWT のような感じというか同じです。モダンでしょ?

コレの定義がある Xm/PushB.h を見てみると・・・

/*
 * HISTORY
*/
/*   $XConsortium: PushB.h /main/12 1995/07/13 17:43:06 drk $ */
/*
*  (c) Copyright 1989, DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASS. */
/*
*  (c) Copyright 1987, 1988, 1989, 1990, 1991, 1992 HEWLETT-PACKARD COMPANY */
/*
*  (c) Copyright 1988 MASSACHUSETTS INSTITUTE OF TECHNOLOGY  */
/*
*  (c) Copyright 1988 MICROSOFT CORPORATION */
/***********************************************************************
 *
 * PushButton Widget
 *
 ***********************************************************************/

Testing

古!!!!

カルチャー・クラブがアーハでテイク~オン~ミーな時代です

私は小学生になった直後くらいです

でも良いのです、良い物は古くても良いのです(みんな大好きCocoaだってNeXTSTEPからほとんど変わってません)

以外と簡単だぜ Motif

冒頭の方で出たダイアログのテキストラベルの部分の全ソースです
文字列をハードコードするのはダメですが、ここではハードコードしてしまいます
(リソースの外出しについては XToolkit intrinsics が面倒を見てくれます。Xtサイコー)

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <Xm/XmAll.h>

static char *fallback_resource[] = {
    "*fontList:  -misc-fixed-medium-r-normal--14-*-*-*-*-*-*-*:",
    "*title:   svchost",
    NULL
};


int
main(argc, argv)
    int argc;
    char **argv;
{
    XtAppContext app_context;
    Widget app, panel, label;
    Arg al[20];
    int ac;


    XtSetLanguageProc( NULL, NULL, NULL);

    ac = 0;
    app = XtAppInitialize(&app_context, "test", NULL, 0,
            &argc, argv, fallback_resource , al, ac);
    ac = 0;
    panel = XmCreateRowColumn(app, "panel", al, ac);
    XtManageChild(panel);

    ac = 0;
    XtSetArg(al[ac], XmNlabelString,
                XmStringCreateLtoR("右隣の部屋にはテレビが2台\n"
                                    "左隣の部屋にはスライスたくあんが1kgあるとする\n"
                                    "顧問がPCを1台着服したと仮定して、現在の情報処理部のPC台数を求めよ",
                XmSTRING_DEFAULT_CHARSET)); ac++;

    label = XmCreateLabel(panel,"label", al, ac);
    XtManageChild(label);

    XtRealizeWidget(app);
    XtAppMainLoop(app_context);
    return 0;
}

これだけです!

ボタンやメニューを置いてコールバックを付けても、隣の席の人がXcodeでテンプレートを生成してIBActionを線で結んでる間にコーディングが終わります。
さすがに爆速っぷりでは WindowsForms には勝てませんが、C/C++で書いたライブラリールーチンをそのまま呼べるので、変なラッパーを噛まさなくても実際にゲーム開発開発で使われているor使われる予定のルーチンを使ったデータ生成や読み込みが出来るのが非常に強いです。
変なライブラリをリンクしない&エンディアンに気をつければSolarisだろうがHP-UXだろうがソース互換です
あと、自動的に格好良くなります。

まとめ

Motif はかっこいい
Motif はモダン
Motif 最高

第9回は ひらしー (@y05_net) | Twitter さんです。