GLib stdin

時は 2015 年

@ サイト管理者やプログラマー
今後は更にスマートフォンの時代になる、タッチパネル向けに作らなければ!

@ 絵師
ソシャゲ用イラストの需要が凄い、ソッチ向けを考慮しなきゃ!!

@ 一般的な人
モンストと Line で忙しい、おっと便利なサイト発見etc…

@ ネクラでキモチワルイ人達
スマホで充分という人はパソコンでもたいしたこと(以下略)ドャァ!!!

こうなることは解っていたがスピードが速すぎな気がする。
実際の話、仕事に必要という理由以外でパソコンを買う人は減る一方なのは確実。
筆者は Fedora 愛用だが実は他人には Mac かタブレットを勧めている。
Linux なんてサイトを自力で作っている人以外にはメリットが無いので。

確実なのは Windows は既にデファクトスタンダードでは無いということ。
モバイルでの Web に関してはもはや Safari がスタンダードに近い。

大型バイク乗りのオッサン、もういいかげんにビクスクを認めろよ。
確かに大型バイクはカッチョイイけどそんなものオイラ達には不要なんですよ。
PCX150 がバカ売れしている時点で余程のバカでなければ気が付くはずなのだが。
その「余程のバカ」が多すぎる、スマホ普及率をガン無視するネラー共と同じく。

絵に関しては Mac 使いにまかせる、その理由で Mac にしたはずだし。
こんな時代にパソコンを使うならプログラミングは必須。
でないとネクラでキモチワルイ人達の一人だと思われてしまう。

そんなこんなで GLib Tips のページを作ろうと思ったわけですが。
GLib って scanf, fgets, fgetc という標準入力のラッパーが無いんですね。

scanf は色々アレなので fgets を今迄使っていたのだが。
コレも色々ある、バッファオーバーランに無力だしスタック領域が無駄だし。
何より改行コード付随というのが気に入らない。

#include <stdio.h>
#include <string.h>
 
int
main (int argc, char *argv[]) {
    char line[256];
    printf("Hi!\nPlease enter your name: ");
    fgets(line, sizeof(line), stdin);
    /* Remove '\n' */
    line[strlen(line)-1] = '\0';
    printf("Welcome, %s!\n", line);
    return 0;
}

ライブラリ関数で取得したものを自力で再加工なんて無駄にもほどがある。
ならば最初から自力で取得し加工したほうが無駄がない。

/* valac -C src.vala */
stdout.printf ("Hi!\nPlease enter your name: ");
var name = stdin.read_line ();
stdout.printf ("Welcome, %s!\n", name);

Vala には stdin.read_line() という便利な関数がある。
コレをどう C 言語にジェネレートしているか -C オプションで確認。
なんと自前で関数を作って適用するという恐るべし手段を使っていた。
相変わらず最適化依存のナニコレなコードを出力するが省略するとこういうこと。

#include <glib.h>
#include <stdio.h>

/* gcc src.c `pkg-config --cflags --libs glib-2.0` */

static gchar*
iostream_read_line (FILE* p) {

	GString* gstr;
	gchar* result;
    gint n;

	gstr = g_string_new("");
	while (TRUE) {
	    n = fgetc(p);
        if (n == ((gint)'\n') || n == EOF) {
			break;
		}
	    g_string_append_c(gstr, (gchar)n);
    }
    result = g_strdup(gstr->str);
    g_string_free(gstr, TRUE);
    return result;
}

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

    gchar* line;

    g_printf("Hi!\nPlease enter your name: ");
    line = iostream_read_line(stdin);
    g_printf("Welcome, %s!\n", line);
    g_free(line);

    return 0;
}

glib_iostream

fgetc で 1 byte ずつチェックしヒープ領域に積み立てて最後にポインタを戻す。
なるほど、これならスタック領域の無駄も最小限だしバッファオーバーランの心配も皆無。
日本語入力も半角スペースも何一つ問題なく処理できてしまう恐るべき関数であった。
Vala を作っている人達は想像以上に頭がいいようです。

ライブラリ関数に徹底的なほど拘るのも悪くないと思うんですけど。
強引に利用するより自分で関数を作ったほうが建設的だなと。
つか、ライブラリ関数に拘る人ってモレなく何もアプリを作っていない現実がね。

Fedora 21 2015.01.05

Fedora 21 を何の不具合もなく使っていたがアップデート通知がこない。
2015.01.05 の今日やっと掛かった、しかしその後アプリがインストールできない。

sudo dnf update

を一応やってみたら何だよコレ…

fedora_update

アップデート通知が無くてもこまめにコマンドを打ちましょう。
カーネルのアップデートがあるので再起動っと。

Wayland のアップデートもあったので変更してみる。
ドラッグアンドドロップ関連がダメダメだったのが修正されている。

しばらくコッチのまま使ってみようかと思えるくらいかな。
と思ったけどログアウトに失敗する、もう少し様子見。

そういえばと vala をインストールしようとしたら何故かまたエラー。
コマンドを打ち直したら正常修了、ダウンロード失敗だったのかな?
おかげで、今頃知ったのか?と思われそうだけど。

dnf_is_python

yum も dnf も Python2 製だったのね。
おいおい、Ubuntu の update-manager ですら Python3 だぞ。
つーか中の人達(死語)はドンダケ Python が好きなんだと。

おまけで、GNOME3 にてこんなことに気が付いた。

DnD_textfile

ブラウザから文字列選択のドロップだけでテキストファイルが作れる。
内容でファイル名が作られるけど私的には日付時刻だと嬉しいのだけど。
Gedit 等にドロップするとコピペになるのは誰でも知っているよね。
ブラウザのタブバーに url をドロップすると移動になるのも常識だよね。

しかし DnD 万能すぎる、何故いままで気が付かなかったのだ?
なのだが、時代は凄い勢いでタッチパネル化なんだよな。
役場の受付番号発券機がタッチパネルになっていて驚いた。
今後は業務用アプリまでもこんな感じになっていくのだろうな。

ということで。
あけましておめでとうございます。

localStorage

二年近く前のネタだけどこんなのを見つけた。

世界が熱狂する「100万のタマゴ」アプリ 日本の個人開発者のアプリが620万DLを達成 | 【EXドロイド(エックスドロイド)】

これならスマートフォン向け Web アプリで作れそう。
しかしパソコン対応なんかにしたらネクラでキモチワルイ奴がスクリプトでアッサリ百万突破してドヤッ!てやるのが目に見える…
まあそれは別の話として。

ゲーム再開用に行うタップ回数の保持は当然ローカルストレージとなるわけで。
スマートフォンのブラウザなら必ず実装しているので使わない手はない。
問題はそのストレージ内と変数値の同期をいつどう行うか。

ページを閉じた時を検知して変数の整数値を保存が一番確実なのだが
window.onbeforeunload – Web API インターフェイス | MDN
これ iPhone で使えなかった。

サイトの後処理にはonpagehideを使う – 読み書きプログラミング ブログ

onpagehide じゃ環境依存になってしまうようだ。
やはり値変更毎に localStorage へ保存するしか確実な手段は無さそう。
しかし[ピアノ打ち]とかされた場合にストレージへの同期は追い付くのかな?

iOSのlocalStorageは非同期でディスクに保存されるっぽい – Qiita

なんてページを発見。
自動的に非同期になるなら何も問題無さそう、コードを書いて実験だ。
毎度のようにスマートフォンかエミュレートでしか動きません。

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>タップした数を記憶する</title>
<!-- 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" />
<style>
body {
    -webkit-text-size-adjust: 100%;
}
</style>
<script type="text/javascript"><!--

    var count = 0;

    var writeText = function() {        
        var num = 1000000 - count;
        var out = String(num).replace( /(\d)(?=(\d\d\d)+(?!\d))/g, '$1,' );
        document.getElementById("ID_TEXT").innerHTML = out;
    }
    // Event Handler
    var onTouchEnd = function() {
        if (count < 1000000) {
            count += 1;
            localStorage.setItem("count", count);
            writeText();
        }
    }
    // Connect
    var init = function() {
        if (window.TouchEvent) {
            var tap = document.getElementById("ID_TAP");
            tap.addEventListener("touchend",onTouchEnd);
        }
        /* can not iPhone
        window.onbeforeunload = function(e) {
            localStorage.setItem("count", count);
            return null;
        );*/
        if (localStorage.getItem("count") != null) {
            count = Number(localStorage.getItem("count"));
        };
        writeText();
    }
    //-->
</script>

</head>
<body onLoad="init()">

<div id="ID_TEXT" style="font-size:48pt">1,000,000</div>
<div id="ID_TAP" style="font-size:96pt">Tap!</div>
<p><a href=".">Back</a></p>
</body>
</html>

タップした数を記憶する

IMG_0097

これだけだと本当につまらないアプリです。
卵がちょっぴりづつ割れていくみたいな演出があると先が気になるってことか。
メモしとこ。

CSS3 FlexBox

本サイトを iPhone 対応にしたしたのは随分前だがスカスカのまま放置。

site_old

Windows をまったく使っていないのでもう Windows アプリの公開をヤメる。
するともっとスカスカに、いいかげんに隙間を埋める感じにしたい。

スマートフォン(以下スマホ)を考慮するなら やはり CSS3 の FlexBox が一番だよな。
ユーザーエージェントで CSS を振り分けるほど豪華なコンテンツがあるならまだしも。

CSS flexible box の利用 – Web developer guide | MDN

tips 毎にブロックを作って横一列に並べ横幅いっぱいになったら改行。
そうすればスマホでハミ出さないし隙間も埋まる。

MDN のコードを参考に iPhone Safari 対策を入れてテスト。

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0,minimum-scale=1.0" />
<title>FlexBox Test</title>
<style>
body {
	font-family: sans-serif;
	margin: 0;
	-webkit-text-size-adjust: 100%; /* iPhone */
}
.flex {
    display: -webkit-flex;
    display: -moz-flex;
    display: -ms-flex;
    display: flex;
    flex-wrap: wrap;
    -webkit-flex-wrap: wrap;
	text-align: left;
	margin: 5px 0px;
}
.flex > div {
    -webkit-flex: 1 1 auto;
    flex: 1 1 auto;
    padding: 0.5em;
    margin:  0.5em;
    border: 1px solid #7c93b2;
    border-radius: 7pt;
    line-height: 1.7em;
}
</style>
</head>

<body>

<div class="flex">

<div>
aaaaaaaaaaaa<br />
bbbbbb<br />
cccccccc
</div>

<div>
d<br />
eeeeeeeeee<br />
</div>

<div>
fffffffffffffffffffffffffffffff<br />
gg<br />
</div>

<div>
hhhhhhhhhhhh
</div>

<div>
iiiiiiiiiiiiiiiiiiii<br />
jjjjjjjjjjjjj<br />
</div>

</div>

</body>
</html>

css3_frexbox

Firefox, Google Chrome, iPhone エミュレート問題無し。
実物の iPhone 5 Safari でも綺麗に横幅で埋まりました。
仕様はもうコレで固まっている、ということでいいのかな?

Google Chrome でイケるから現行 Android でも大丈夫だろう。
コッチは Blink だしエミュレートで確認すれば充分だと思う。

Internet Explorer では確認していない、ぶっちゃけどうでもいい。
せっかくデュアルブートにして残したミニノートの Windows7 なのだが…
もう半年以上起動すらしていない、残す必要なんて無かったな。

ということで本サイトにとっとと適用。
それとフォントサイズ指定を廃止したり行間を空けたりでタッチしやすく…
いやコンテンツを整理したり増やしたいのですけどね。

GtkFlowBox

開発者、システム管理者、ディストリビューター向けの新規事項

GTK+ 3.14 はマルチタッチをサポートしているのようです。
GtkGesture という名前か、マウスジェスチャはもう過去の遺物だな。

よし早速、ってタッチパネルのパソコンなんて持っていないよ。

後二年もすれば五万円台で ASER か ASUS が普通に出してくるのだろう。
コイツはそれからでいいや。

Gtk 3.12 のほうを見ると GtkActionBar, GtkPopover, GtkFlowBox
全部コンテナか、そんなに沢山の種類が必要なのかな?

GtkFlowBox はコンテナサイズで複数 Widget の位置を調節してくれる。
という解釈でいいのかな、GtkIconView とは違うのかな。
ちと試してみよう。

2015.03.05 修正

#!/usr/bin/env python3

from gi.repository import Gtk, Gio

class FBox(Gtk.Window):
    """
        Minimum width is standard ?
    """
    def __init__(self):
        Gtk.Window.__init__(self)
        # 
        self.flowbox = Gtk.FlowBox.new()
        button = Gtk.Button.new_with_label("Insert Label")
        button.connect("clicked", self.on_insert_button_clicked)
        # pack
        vbox = Gtk.Box.new(Gtk.Orientation.VERTICAL, 0)
        vbox.pack_start(button, False, False, 0)
        vbox.pack_start(self.flowbox, True, True, 0)
        # self
        self.index = 0
        self.add(vbox)
        self.connect("delete-event", Gtk.main_quit)
        self.resize(400, 1)
        self.show_all()

    def on_insert_button_clicked(self, widget):
        label = Gtk.Label("Label")
        label.show()
        self.flowbox.insert(label, self.index)
        self.index += 1

FBox()
Gtk.main()

gtkflowbox

3 クリック目から横に余裕があるのに縦に広がってしまう。
どうも横幅を最小値にした場合を常に計算しているようで。
ついでに、GtkListBox 同様に選択もできます。

どんな場面に便利か思いつかないのは筆者の想像力が足りないのだろう。
昨今の Web ページではよく見かけるのですけどね。