GTK+ によるコンソールもどき

2010年2月21日

はじめに

Gtk+ を使ってコンソールっぽいものを作ってみようという企画。

開発環境

Gtk+ 2.1.2.11, MinGW 5.1.4

ファイル

console.tar.gz

使い方

コンパイルして起動すると、コマンドが打てる。コマンドを打つと、入力がそのまま出力される。コマンド履歴機能付き。

キー操作

  • ←, Ctrl+B: カーソルを左へ移動
  • →, Ctrl+F: カーソルを右へ移動
  • ↑, Ctrl+P: コマンド履歴を前へたどる
  • ↓, Ctrl+N: コマンド履歴を後へたどる
  • Ctrl+A: コマンドラインの先頭へ移動
  • Ctrl+E: コマンドラインの最後へ移動
  • Ctrl+U: カーソルからコマンドラインの先頭までの文字を削除
  • Ctrl+K: カーソルからコマンドラインの最後までの文字を削除
  • Ctrl+L: コンソールをクリア
  • Delete, Ctrl+D: カーソル位置の文字、あるいは選択した文字列を削除
  • BackSpace, Ctrl+H: カーソル位置の前の文字、あるいは選択した文字列を削除
  • Enter, Ctrl+J: コマンドを実行

内容

構成

  • main (main.c): console を使う人。ウインドウの準備などを行う。
  • console (console.c, console.h): コンソールモジュール。

console モジュールのインタフェース

  • console_new: Console オブジェクトの作成
  • console_delete: Console オブジェクトの削除
  • console_start: コンソールの開始
  • console_set_prompt: プロンプト文字列の設定
  • console_set_callback: コマンド実行時に呼ばれるコールバック関数の設定
  • console_set_font: フォントの設定
  • console_write: コンソールへ文字列を書く

console の Gtk+ ウィジットは CONSOLE_WIDGET(console) で参照できる。

main() は次のようになる。

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

	gtk_set_locale();

	gtk_init(&argc, &argv);

	window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
	gtk_window_set_title(GTK_WINDOW(window), TITLE);
	gtk_window_resize(GTK_WINDOW(window), WIDTH, HEIGHT);
	gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
	g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL);

	console = console_new();
	gtk_container_add(GTK_CONTAINER(window), CONSOLE_WIDGET(console));

	console_set_callback(console, callback);

	console_write(console, "console start\n");
	console_start(console);

	gtk_widget_show_all(window);

	gtk_main();

	return 0;
}

コマンド処理用コールバック関数は、渡されるコマンドをそのまま表示させているだけである。

static void callback(Console *console, const char *command)
{
	console_write(console, command);
	console_write(console, "\n");
}

console は GtkTextView をベースにしている。key-press-event のコールバック関数でキー入力をつかまえて、GtkTextBuffer, GtkTextIter の関数を駆使してなんとかしている。

「使い方」以外の細かい仕様として、コマンドライン以外の編集不可領域の動作がある。編集不可領域においては、カーソル移動や選択、Ctrl+C によるコピー以外の操作は受け付けない。編集不可領域にカーソルがある状態でコマンドライン入力に関するキー入力が行われた場合は、カーソルをコマンドライン末尾に移動し、コマンドライン位置に画面をスクロールし、入力を受け付ける。それ以外のキー入力に対してはなにもしない。