SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

DeveloperZine(デベロッパージン)- エンジニアの意思決定を支える技術情報メディア ProductZine

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

特集記事

GTK+プログラミング:プレゼンテーション支援ツールの開発

アンチョコ付きプレゼンテーションツール「Prompter」

Prompterプログラムの解説(2/3)

GUIの設定

 次にGUIの設定の中味を見てみましょう。pmpt_gui_config()は「gui.c」で定義されています。

GUIの設定
void
pmpt_gui_config (PmptGUI* gui)
{
  /* 1. note window setting */
  pmpt_gui_note_window_config (gui);

  /* 2. slide window setting */
  if (pmpt_opt_is_fullscreen (gui->ctrl->opt))
    {
      pmpt_gui_slide_window_config (gui);
    }

  /* 3. current slide window setting */
  if (pmpt_opt_is_currentslide (gui->ctrl->opt))
    {
      pmpt_gui_current_window_config (gui);
    }

  /* 4. next slide window setting */
  if (pmpt_opt_is_nextslide (gui->ctrl->opt))
    {
      pmpt_gui_next_window_config (gui);
    }
}

 順番に、ノート表示のウィンドウ設定、外部ディスプレイに出力するスライド表示の設定、発表者画面に出す現在のスライドのウィンドウ設定、同じく次のスライドのウィンドウ設定の順番で設定用の関数を呼んでいます。ノート表示以外は、表示するかしないかをオプションで選べるため、if文で選択的に呼び出すようになっています。

ノート表示ウィンドウの設定

 少し長いのですが、ノート表示用のウィンドウを設定する関数を次に示します。大まかに説明すると、トップレベルのウィンドウ(GtkWindow)の中にスクロール用のウィンドウ(GtkScrolledWindow)を配置し、さらにその中にテキスト表示用のウィジット(GtkTextView)を入れ込んでいます。なおGtkTextViewに関連付けられたテキストバッファGtkTextBufferは後から内容を変更できるように、PmptGUI型のデータから参照できるようにしています。

ノート表示ウィンドウの設定
static
void
pmpt_gui_note_window_config (PmptGUI* gui)
{
  GtkWidget* window;
  GtkWidget* scroll_window;
  GtkWidget* text;
  GtkTextBuffer* text_buffer;
  gchar* str = pmpt_data_get_current_page (gui->ctrl->data) ->note;

  /* get the note text of the first page */
  text_buffer = gtk_text_buffer_new (gtk_text_tag_table_new ());
  gtk_text_buffer_set_text (text_buffer, str, -1);
  text = gtk_text_view_new_with_buffer (text_buffer);

  /* GtkTextView settings */
  gtk_text_view_set_editable (GTK_TEXT_VIEW (text), false);
  gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (text), GTK_WRAP_CHAR);

  /* GtkWindow settings */
  window = gtk_window_new (GTK_WINDOW_TOPLEVEL);

  scroll_window = gtk_scrolled_window_new (NULL, NULL);
  gtk_container_add (GTK_CONTAINER (window), scroll_window);
  gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (scroll_window),
                                         text);
  gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll_window),
                                  GTK_POLICY_NEVER, GTK_POLICY_ALWAYS);

  gtk_window_set_title (GTK_WINDOW (window), "Prompt");
  gtk_window_resize (GTK_WINDOW (window),
                     gui->textarea_width, gui->textarea_height);

  gtk_widget_show_all (window);

  /* signal bindings (& key press handling) */
  gtk_signal_connect (GTK_OBJECT (window), "destroy",
                      GTK_SIGNAL_FUNC (pmpt_gui_quit), NULL);

  gtk_key_snooper_install (pmpt_gui_key_press_handler, gui);

  gui->text_buffer = text_buffer;
}

 この関数で、gtk_widget_show_all()の呼び出しまでが、GUIと関連するテキストバッファの設定です。すべてのウィジットの関連を構築した後で、gtk_widget_show_all()を呼び出すことによってGUIが画面に表示されます。

 次にgtk_signal_connect()関数で、ユーザーの操作などで生じたイベント(GTK+ではシグナルと呼びます)と呼び出される関数の設定を行います。ウィンドウマネージャなどによってウィンドウの破棄が行われると、「destroy」シグナルが発生します。ここではそのシグナルに対してpmpt_gui_quit()が呼ばれるように設定しています。

 またその次の関数gtk_key_snooper_install()では、イベントループが回っている間に、キーボードから何か押されたときに呼び出されるべき関数を設定しています。この設定により、キーボードから入力があるとpmpt_gui_key_press_handler()が呼び出されるようになります。

スライド表示の設定

 スライド表示はウィンドウを全画面サイズに拡げて表示させることで実現しています。構造は比較的簡単で、トップレベルのウィンドウ(GtkWindow)の中にイメージ表示用のウィジット(GtkImage)を貼り込んでいるだけです。

プロジェクタで投影するスライド表示の設定
static
void
pmpt_gui_slide_window_config (PmptGUI* gui)
{
  GtkWidget* window;
  GtkWidget* image_widget;
  PmptPage* page = pmpt_data_get_current_page (gui->ctrl->data);
  PmptOpt* opt = gui->ctrl->opt;
  gchar* image_filename = page->image_filename;
  int width, height;

  /* get the display name which shows slides */
  gchar* slide_display_name = pmpt_opt_get_slide_display (opt);
  GdkDisplay* display = gdk_display_open (slide_display_name);
  GdkScreen* screen;

  if (display == NULL)
    {
      g_warning ("cannot open display: %s", slide_display_name);
      exit (-1);
    }
  screen = gdk_display_get_default_screen (display);

  /* GtkWindow settings */
  window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
  gtk_window_set_screen (GTK_WINDOW (window), screen);

  image_widget = gtk_image_new ();
  gtk_container_add (GTK_CONTAINER (window), image_widget);
  gtk_window_set_title (GTK_WINDOW (window), "Slide Show");

  /* set fullscreen mode */
  width  = gdk_screen_get_width (screen);
  height = gdk_screen_get_height (screen);
  gtk_window_fullscreen (GTK_WINDOW (window));

  gtk_widget_show_all (window);

  /* signal bindings (& key press handling) */
  gtk_signal_connect (GTK_OBJECT (window), "destroy",
                      GTK_SIGNAL_FUNC (pmpt_gui_quit), NULL);

  gui->slide_window = image_widget;
  gui->slide_width  = width;
  gui->slide_height = height;

  /* set the first slide image */
  pmpt_gui_update_slide (gui, image_filename);
}

 ここでのポイントは次の部分です。GTK+の低レベル描画レイヤを提供するGDK(Graphics Drawing Kit)のAPIを利用して、スライドを表示するディスプレイを選択します。ここでリモートPCのXサーバが提供するディスプレイを指定すれば、スライドはネットワークで接続された投影用PCに表示されるという仕掛けです。

別のスクリーンに表示する設定
GdkDisplay* display = gdk_display_open (slide_display_name);
GdkScreen* screen;

if (display == NULL)
  {
    g_warning ("cannot open display: %s", slide_display_name);
    exit (-1);
  }
screen = gdk_display_get_default_screen (display);

/* GtkWindow settings */
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_window_set_screen (GTK_WINDOW (window), screen);

 なおここでも、設定終了後にウィジットを表示させ、シグナルを結びつけています。キーボード入力のピックアップは既に設定済みなので必要ありません。また最後にpmpt_gui_update_slide()を呼び出して1枚めのスライドを表示するようにしています。

発表者画面に表示するウィンドウの設定

 発表者画面に出す現在のスライドのウィンドウと、次のスライドのウィンドウの設定も同様です。やはりトップレベルのウィンドウ(GtkWindow)の中にイメージ表示用のウィジット(GtkImage)を配置した構造になっています。それぞれの関数の記述はほとんど同じなので、ここでの解説は割愛します。別のディスプレイへの表示や全画面表示のための設定がないぶん、より単純な定義になっています。

次のページ
Prompterプログラムの解説(3/3)

この記事は参考になりましたか?

特集記事連載記事一覧

もっと読む

この記事の著者

飯尾 淳(イイオ ジュン)

1970年生まれ。株式会社三菱総合研究所 情報通信技術研究本部 情報技術研究グループ 主任研究員。専門は、画像処理とユーザインタフェース……のはずが、なぜか最近はOSS普及振興の手伝いで多忙な毎日を過ごしている。著書に「Linuxによる画像処理プログラミング」、「リブレソフトウェアの利用と開発~I...

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

CodeZine(コードジン)
https://codezine.jp/article/detail/389 2006/05/24 00:00

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー