Numeric sort in GLib

ファイル名の数値優先ソート C 言語版を書いてみた。

というより、手元に溜まっている古い覚書ファイルを整理している。
昔書いたのって posix と glib が混在で自分がゲンナリするもので。
とにかく今の知識で限界まで整理して Web に書き出す。

Python の覚書でディレクトリ内容列挙とソートを別々に書いているけど
どうせ同時に使うのだからまとめたほうがよさそう。
ということでこんなコードになった。

#include <glib.h>
#include <gio/gio.h>

/*
 * Numeric sort in GLib (like a Nautilus)
 * gcc nautilus_sort.c `pkg-config --cflags --libs gio-2.0`
**/

gint
compare_main_func(gchar** a, gchar** b) {

    gint n;

    gchar* aaa = g_utf8_collate_key_for_filename (*a, -1);
    gchar* bbb = g_utf8_collate_key_for_filename (*b, -1);
    n = g_strcmp0(aaa, bbb);
    g_free(aaa);
    g_free(bbb);
    return n;
}

gint
compare_data_func(gconstpointer a, gconstpointer b) {
    return compare_main_func((gchar**)a, (gchar**)b);
}

void 
print_data(gpointer data, gpointer user_data) {
    g_printf("%s\n", data);
}

int
main (int argc, char *argv[]) {

    gchar* dir;
    GFile* file;
    GFileEnumerator* file_enum;
    GFileInfo* info;
    GPtrArray* array;

    dir = g_get_current_dir();
    file = g_file_new_for_path(dir);
    g_free(dir);
    /* Get the directory contents */
    array = g_ptr_array_new();
    file_enum = g_file_enumerate_children(file,
                                          G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME,
                                          G_FILE_QUERY_INFO_NONE,
                                          NULL,
                                          NULL);
    for (;;) {
        info = g_file_enumerator_next_file(file_enum, NULL, NULL);
        if (info == NULL) break;
        g_ptr_array_add(array, g_strdup(g_file_info_get_display_name(info)));
        g_object_unref(info);
    }
    g_object_unref(file_enum);
    /* Sort */
    g_ptr_array_sort(array, compare_data_func);
    /* print */
    g_ptr_array_foreach(array, print_data, NULL);
    /* free */
    g_ptr_array_free(array, TRUE);
    return 0;
}

numeric_sort

pkg-config は gio ですのでお間違いなく。

Python では使わないので気が付かなかったけど
GCompareFunc の引数が gconstpointer になっている。
実際には const gchar** だ、コレにはまいった。

gchar* aaa = g_utf8_collate_key_for_filename (*((gchar**)a), -1);

とやれば一応関数に分離せずにビルドできる。
けど見た目が酷過ぎるので分離した、ドンだけキャストすればいいのよ。
ポインタが今一。。。な初心者がこんなの見たらブン投げるわ。

しかし GLib はループ用の int をまったく使わないで書けるんだな。
筆者はもう慣れたけどローカル変数も malloc も使わないって違和感スゲェ。
C より Python の経験があるほうが覚えるの早そう、破棄が必要なだけだし。

ついでに、今日電源を入れたら。

mouse

GNOME はこんなに親切だったのか、初めて見た。
いやマウスの LED がチカチカするから解るんですけど。

JavaScript Map to ComboBox

Javascript tips – 連想配列(ハッシュ)の要素取得

あれ、JavaScript の配列って普通に for in が使えたの?
Python 等と違ってキーが戻るってことなのね。

てっきりメソッド列挙しかできないと思いこんでいた。
ちと Gjs で試してみるか。

#!/usr/bin/env gjs

// Map
var map = {TOYOTA: "LEXUS", HONDA: "ACURA"};
map["NISSAN"] = "DATSUN";
for (var key in map) {
    print(key + " : " + map[key]);
}
print(" ");
// Array
var array = ["YAMAHA", "HONDA", "SUZUKI"];
array.push("KAWASAKI");
for (var key in array) {
    print(array[key]);
}
print(" ");
// Method
const Gtk = imports.gi.Gtk;
for (var s in Gtk.Window) {
    print(s);
}

gjs

うん Gjs でも問題無し、仕様のようだ。
forEach でも結果は同じだけどコッチのほうが違和感が少なくていい。

Array.forEach – JavaScript | MDN
Map.prototype.forEach() – JavaScript | MDN

ということで、JavaScript でコンボボックスを作る。
スマートフォンを考慮すると ListBox は使いたくない。

<form>
    <select>
        <option>KAWASAKI
        <option>SUZUKI
    </select>
</form>

実際の運用ではこういう HTML に直書きなんてほぼありえない。
データベースやファイルから読み込んで割り当てていくわけでして。
多分 Java か PHP で動的にタグを追加していくのが主流だと思う。

というか IE というゴミがさ。
それについては企業向けな人達にまかせてと。
IE をガン無視、スマートフォンはバッチリなサンプルコード。

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<!-- for Smart Phone -->
<meta name="viewport" content="
    width=device-width,
    initial-scale=1.0,
    minimum-scale=1.0,
    maximum-scale=1.0,
    user-scalable=no" />
<title>コンボボックスを使う</title>
<style>
body {
	font-family: sans-serif;
	/*margin: 0;*/
	-webkit-text-size-adjust: 100%; /* iPhone */
}
</style>
<script type="text/javascript"><!--

    const truck = {
        "大好きな 4t トラックを選んでください": "未選択",
        "ISUZU":  "フォワード",
        "FUSO":   "ファイター",
        "TOYOTA": "トヨエース",
        "HINO":   "レンジャー"
    };

    var init = function() {
        var combobox = document.getElementById("ID_COMBOBOX");
        combobox.onchange = function() {
            var item = combobox.options[combobox.selectedIndex].value;
            var text = document.getElementById("ID_TEXT");
            text.innerHTML = item + " です";
        };
        for (var key in truck) {
            combobox.appendChild(new Option(key, truck[key]));
        };
    }
    //-->
</script>
</head>

<body onLoad="init()">

<form>
<select id="ID_COMBOBOX">
</select>
</form>

<p id="ID_TEXT">未選択</p>

<p><a href=".">Back</a></p>

</body>
</html>

コンボボックスを使う

連想配列を利用して動的にコンボボックスに追加してみました。
こうしておくと追加や並べ替えをしたくなった時に便利。
珍しくパソコンブラウザでも動くよ、IE は知らない。

ところで iPhone でコンボボックスを使うとこうなります。

iphone_combobox

小さい画面でも使い易いように工夫してますね。
wonder なんとかは小さいボタンに耐えられず削除しました。

CSS3 table

glib ネタが尽きてきたので久々に HTML5 で。

モバイル Yahoo なんかで使われている等間隔テーブルが使いたい。
企業のモバイルサイトでよくヘッダに使われています。

つい FlexBox と思ってしまいますが素直にテーブルでいいようです。

display: table;
table-layout: fixed;

子要素は table-cell 指定で普通の table タグと同様に扱える。
むしろ table タグより簡単でした。

細かい解説は既に星の数ほど解説サイトがあるので省略。
今回はコチラを参考にしました。
横一列に並ぶ複数要素を均等幅で配置する | NAKAZI LAB.(ナカジラボ)

まあ相変わらずスマートフォンを考慮していない所が多いですが。
とにかく iPhone Safari 対策を入れて実験。

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<!-- for Smart Phone -->
<meta name="viewport" content="
    width=device-width,
    initial-scale=1.0,
    minimum-scale=1.0,
    maximum-scale=1.0,
    user-scalable=no" />
<title>等間隔ヘッダ</title>
<style>
body {
	font-family: sans-serif;
	margin: 0;
	-webkit-text-size-adjust: 100%; /* iPhone */
}
.header {
    display: table;
    table-layout: fixed;
    width: 100%;
	margin: 0;
}
.header > div {
    display: table-cell;
    margin: 0;
    background-color: #0066ff;
    border-right: 1px solid rgba(0, 255, 255, 0.5);
}
.header > div a {
    display: block;
    text-align: center;
    padding: 0.5em;
    text-decoration: none;
    
    color: #ffffff;
}
</style>
</head>

<body>

<div class="header">

<div><a href="1.html">Top</a></div>
<div><a href="2.html">Page2</a></div>
<div><a href="3.html">Page3</a></div>
<div><a href="4.html">a</a></div>
<div><a href="5.html">About</a></div>

</div>

<pre>
# 親要素
display: table;
table-layout: fixed;

# 子要素
display: table-cell;

を CSS で指定
</pre>
<p><a href=".">Back</a></p>

</body>
</html>

等間隔ヘッダ

display_table

狙ったとおりの等間隔配置になりました。
Chrome, Firefox ならブラウザをリサイズ、スマートフォンなら横向きにして。
リサイズしても等間隔が維持で幅いっぱいになるのが確認できると思う。

ぶっちゃけこのサイズが iPhone5S で普通にタップできる最小限です。

というのも、ウチ姫からいいかげん別ゲーに乗り換えようと。
wonder4world ってのが iPhone 版で出たばかりらしいので試すと。

close_button_small

閉じるボタンが全然タップできなくてイライラする!
この開発者達は本当に iPhone で操作性を確認したのか?
ゲーム自体も他にどこにでもある…

小さいボタンはマウスだったから成立していたんだよ。
メニューバーやツリービューも同様、タッチパネルで使えない。
だから Windows も GNOME も取っ払う方向に動いているわけで。

まさかスマホゲーでこんな小さなボタンを見るとは思わなかった。
とにかく皆様、もっとスマートフォンを考慮しましょう。

Nemiver

gcc で C/C++ プログラミングをする際のデバッガに gdb がある。
コマンドラインツールなので vi, emacs 愛用者は普通に使えると思う。
しかし筆者のような Gedit 愛用者には少々使い辛い。

何かないかと探すと Nemiver という GUI アプリケーションがあった。
ようするに gdb のフロントエンド。
GNOME Wiki! に登録されているし突然亡くなる心配はなさそう。

Apps/Nemiver – GNOME Wiki!

書くまでもなく日本語情報は無かった。
ということで自分で使ってみる。

sudo dnf install nemiber

で Fedora は導入できる、ubuntu は apt-get でいいはず。

設定の[デバッガ]タブにて gdb の位置を指定。
/usr/bin/gdb でいいはず、この設定は必要あるのかな?
レイアウト等はお好みで。

このアプリは起動時の引数に実行ファイルを渡すので終了させる。
ビルド時に gcc への引数 -g (デバッグ情報を含める)を追加。

gcc -g hoge.c
nemiver a.out

nemiver01

使い方は Visual Studio とだいたい同じですね。
F6 キーで次行へ進む、F7 キーで関数の内部へ入る。
F11 キーでカーソル行まで一気に進む、等々。

ブレークポイントは行番号横をクリック。
F5 を押していくと指定した位置で止まるのでその時の変数値なんかを。
下ペインのブレークポイントタブで通過数を確認等もできる。

下ペインのコンテキストタブで変数の現在値を確認できる。
日本語の文字列変数もそのまま確認できるけど静的配列だとダメです。

pchar

これ以外は各自で目的が違うと思うので勝手に調べてね。
Visual Studio を使っていた人ならなんとなく解ると思う。

っっって、つまり結局は毎回コマンドを打たなければいけないのか。
では意味がないので Gedit の外部ツールに登録してしまおう。

#!/bin/sh
gcc -g -o debug $GEDIT_CURRENT_DOCUMENT_PATH `pkg-config --cflags --libs glib-2.0`
if test $? -eq 0; then
    nemiver debug
fi

external_tools

筆者は GLib を使うのでこんな感じにしてみました。
デバッグの為だけに糞重い開発環境を使う必要はないです。

しかし Gedit は便利だ、コマンドが充実した Linux が便利なだけですが。
問題は外部ツールが増えすぎると指定したキーを忘れてしまうことだ。

我家公主最可愛

台湾版ウチ姫にはオリキャラがいるみたい、名前を見れば納得。
《我家公主最可愛》 台灣官方網站

というか他の姫様達って初期のまだ良かった頃のまんまや。
攻撃力二倍姫もいないしアビリティは固定、ボイスも無い?

この頃程度に戻してほしいな、今のウチ姫は面白くない。
かといって他のゲームはもっとツマランので乗り換えできねー。

uchihime

実は今迄に五千円しか課金していない。
アメーバコインが使えた頃に Android で買ったので星屑はゼロのままw
台湾の皆様、そんなほぼ無課金でも結構 SR は集まりますよ。
めぼしいのは数人しかいませんけど組み合わせを考えるのもまた一興。

いや遊ばせてもらっているのだしあと数万なら払ってもいいのですが…
最近のガチャにン万円使って当たり姫を引かないと参加しても無駄骨が確定なランキングクエスト連発で流石にその気が失せた。
ギルドとか競い合いの要素が無かったから気に入ったのに。
ピンボールは面白いんだよ、無益な競い合いに金なんて払いたくないの。

でもランキング上位陣を見ると当たり姫がワンサカ。
こういうイベントばかりになったのはコリャ当然だなと。

嘆いたり馬鹿にしたりしている人、そうじゃなくてプログラミングを始めよう。
こういう人達がジャブジャブ課金したくなる楽しいゲームを皆も作っていこう。
以上プログラミングの勧めでした。

どうでもいいけど、Fedora 21 の iPhone コネクトアイコン。

iphone

どうみても昔ながらのケータイです。
Fedora 20 は普通に iPhone と同じ見た目だったのに何故変えた?
iPhone mount in GNOME | PaePoi