Fox GUIのメモ

(ここにある内容は無保証です、自己責任でどうぞ,以下の参考URLを参考にさせていただいています)

  1. Fox GUI のインストール(ubuntu-ja)
  2. Windowだけを表示する
  3. ボタンをおいてみる
  4. ボタンを押すと終了するようにする
  5. ボタンを押すとダイアログを表示させる
  6. 日本語を表示する(fox-1.6.0rc1)

    参考URL集


Fox GUI のインストール(ubuntu-ja)

fox guiのソースをとってくる
$ mkdir temp
$ cd temp
$ wget http://www.fox-toolkit.org/ftp/fox-1.4.26.tar.gz
$ tar zxvf fox-1.4.26.tar.gz
$ cd fox-1.4.26
$ ./configure --enable-release
このときtiff, gif, jpeg, png等の必要があれば、あらかじめライブラリを入れておくこと
$ make -j3
でMake -j3を入れておくと、SMPまたは、Hyper Threadなマシンでは早くコンパイルできる
$ sudo make install
デフォルトでは/usr/localに入るので、/etc/ld.so.confに/usr/local/binを入れておき
$ sudo /etc/ldconfig -v


Windowだけを表示する

表示するWindowのClassを作らないといけません。もちろんFOXのMainWindowに関するクラス
を継承すればいいです。Classの名前をMainWindowとして、sampleを見ながら作ると、ヘッダ、
ソースは以下の感じで良いみたい。

MainWindow.h
class MainWindow: public FXMainWindow
{
 public:
  FXDECLARE(MainWindow)
 public:
  MainWindow(FXApp* app);
  virtual void create();
  virtual ~MainWindow();
 protected:
  MainWindow(){}
};

MainWindow.cpp
#include <fx.h>
#include "MainWindow.h"

FXDEFMAP(MainWindow) MainWindowMap[]=
{
};

FXIMPLEMENT(MainWindow,FXMainWindow, MainWindowMap,ARRAYNUMBER(MainWindowMap))

//250x250のメインウインドウの大きさ
MainWindow::MainWindow(FXApp* app):FXMainWindow(app, "MainWindow", NULL, NULL, DECOR_ALL, 0,0,250, 250)
{

}

void MainWindow::create()
{
  FXMainWindow::create();
  show(PLACEMENT_SCREEN);//PLACEMENT_SCREENで画面中央に表示
}

MainWindow::~MainWindow()
{
}

main関数は、どれも同じ感じで使い回せます

main.h
int main(int argc, char* argv[]);

main.cpp
#include <fx.h>
#include "main.h"
#include "MainWindow.h"

int main(int argc, char* argv[])
{
  FXApp application("MainWindow","MainWindow");
  application.init(argc, argv);
  new MainWindow(&application);
  application.create();
  return application.run();
}

Makefile
NAME    = Skelton
OBJS    = main.o MainWindow.o

CXX     = g++
CXXFLAGS        = -Wall -O2
INCLUDES        = -I/usr/local/include/fox-1.4
LIBS    = -lFOX-1.4 -lGL -lGLU -lX11
LDFLAGS =

$(NAME):$(OBJS)
        $(CXX) -o $@ $(OBJS) $(LDFLAGS) $(LIBS)

.cpp.o:
        $(CXX) -c $(CXXFLAGS) $(INCLUDES) $?

clean:
        $(RM) -f *.o *~ $(NAME)

実行すると、こんな感じ
$ make
$ ./Skelton




ボタンをおいてみる

いじるところは、MainWindow class にボタン(FXButton)を宣言する。
MainWindow.h
class MainWindow: public FXMainWindow
{
 public:
  FXDECLARE(MainWindow)
 public:
  MainWindow(FXApp* app);
  virtual void create();
  virtual ~MainWindow();
 protected:
  MainWindow(){}
 protected:
  FXButton *Button1;
};

そして、ボタンを配置
MainWindow.cpp
#include <fx.h>
#include "MainWindow.h"

FXDEFMAP(MainWindow) MainWindowMap[]=
{
};

FXIMPLEMENT(MainWindow,FXMainWindow, MainWindowMap,ARRAYNUMBER(MainWindowMap))

MainWindow::MainWindow(FXApp* app):FXMainWindow(app, "MainWindow", NULL, NULL, DECOR_ALL, 0,0,250, 250)
{
  Button1 = new FXButton(this, "Hello", NULL);
}

void MainWindow::create()
{
  FXMainWindow::create();
  show(PLACEMENT_SCREEN);
}

MainWindow::~MainWindow()
{
}

そして
$ make clean
$ make
$ ./Skelton



ボ タンを押すと終了するようにする

ボタンをクリック→FXDEFMAPを探す(該当するIDとイベント)→該当するルーチンを呼び出す
というようになっているようなので、
1.どのボタンが押されたのかを識別するためのIDを振る
2.押されたときにどの関数を呼び出すのかを決める
3.押された際の動作を定義する。

これらを定義すると、MainWindow.h, MainWindow.cppは次のようになる
MainWindow.h
class MainWindow: public FXMainWindow
{
 public:
  FXDECLARE(MainWindow)
 public:
  MainWindow(FXApp* app);
  virtual void create();
  virtual ~MainWindow();
 protected:
  MainWindow(){}

 protected:
  FXButton *Button1;
 public:
  long onBtnClick(FXObject*,FXSelector,void*);//ボタンが押されたときに呼び出す関数
 public:
enum
  {
    ID_QuitBtn = FXMainWindow::ID_LAST,
  };//IDを列挙する。ちなみにはじめのIDにはFXMainWindow::ID_LASTを入れること

};

MainWindow.cpp
#include <fx.h>
#include "MainWindow.h"

FXDEFMAP(MainWindow) MainWindowMap[]=
{
  //ボタンが押された 際のIDと呼び出す関数の対応づけ
  FXMAPFUNC(SEL_COMMAND, MainWindow::ID_QuitBtn, MainWindow::onBtnClick)
};

FXIMPLEMENT(MainWindow,FXMainWindow, MainWindowMap,ARRAYNUMBER(MainWindowMap))

MainWindow::MainWindow(FXApp* app):FXMainWindow(app, "MainWindow", NULL, NULL, DECOR_ALL, 0,0,250, 250)
{
  //ボタンに対してIDを振った、その前のNULL, thisはとりあえず気にしないこと
  //気になるようだったらReferenceを見ること
  Button1 = new FXButton(this, "Hello", NULL, this, ID_QuitBtn);
}

void MainWindow::create()
{
  FXMainWindow::create();
  show(PLACEMENT_SCREEN);
}

MainWindow::~MainWindow()
{
}

//ボタンが呼ばれたときに呼び出 される関数
long MainWindow::onBtnClick(FXObject*,FXSelector,void*)
{
  getApp()->exit(0);
  return 1;
};

$ make clean
$ make
$ ./Skelton
とした後、Helloのボタンを押すと終了する。
ちなみに、終了させるだけなら
Button1 = new FXButton(this, "Hello", NULL, this, FXApp::ID_QUIT);
とするだけで、ほかの関数とかを書かなくても終了させることはできる。


ボタンを押すとダイアログを表示させる
終了のボタンは作成したので、もう一つ別なボタンを配置してダイアログを表示してみたいと
思います。
IDをID_Dialogとして、呼び出す関数をonCmdDialogaとして実装します。
Dialog自体は簡単に呼び出すことができて、
FXMessageBox::information(this, MBOX_OK,"タイトルの文字列","ダイアログの中の文字列")
として呼び出せば可能です。
できたソースは、下のようになります。
MainWindow.h
class MainWindow: public FXMainWindow
{
 public:
  FXDECLARE(MainWindow)
 public:
  MainWindow(FXApp* app);
  virtual void create();
  virtual ~MainWindow();
 protected:
  MainWindow(){}

 protected:
  FXButton *Button1, *Button2;
 public:
  long onBtnClick(FXObject*,FXSelector,void*);
  long onCmdDialog(FXObject*,FXSelector,void*);//ID_Dialogから呼び出される関数
 public:
enum
  {
    ID_QuitBtn = FXMainWindow::ID_LAST,
    ID_Dialog,//ボタンのIDを振る
  };

};

MainWindow.cpp
#include <fx.h>
#include "MainWindow.h"

FXDEFMAP(MainWindow) MainWindowMap[]=
{
  FXMAPFUNC(SEL_COMMAND, MainWindow::ID_QuitBtn, MainWindow::onBtnClick),
  FXMAPFUNC(SEL_COMMAND, MainWindow::ID_Dialog, MainWindow::onCmdDialog)
};

FXIMPLEMENT(MainWindow,FXMainWindow, MainWindowMap,ARRAYNUMBER(MainWindowMap))

MainWindow::MainWindow(FXApp* app):FXMainWindow(app, "MainWindow", NULL, NULL, DECOR_ALL, 0,0,250, 250)
{
  Button1 = new FXButton(this, "Hello", NULL, this, ID_QuitBtn);
  Button2 = new FXButton(this, "Dialog", NULL, this, ID_Dialog);//ボタンを配置
}

void MainWindow::create()
{
  FXMainWindow::create();
  show(PLACEMENT_SCREEN);
}

MainWindow::~MainWindow()
{
}

long MainWindow::onBtnClick(FXObject*,FXSelector,void*)
{
  getApp()->exit(0);
  return 1;
};

//タイトルをTitleで文章をThis is Skelton Appで表示、MBOX_OKはOKボタンを配置する
long MainWindow::onCmdDialog(FXObject*,FXSelector,void*)
{
  FXMessageBox::information(this, MBOX_OK,"Title","This is Skelton App");
  return 1;
}

できるとこんな感じ


日本語を表示する(fox- 1.6.0rc1)
日本語を表示させるためには、fox-1.6.0rc1が必要となってきます。
$ ./configure --enable-release  --enable-threadsafe --with-xft
筆者は上のオプションでコンパイルしたものを使用しています。
日本語はソース埋め込みでそのまま使えるようです。
変換はfromAscii("はろ〜")で、FXString型で返してくれます。
そして、デフォルトのままではうまくFontの処理ができないので
FXFontのインスタンスをつくり、設定しておきます。できあがるとソースは次のようになります。
MainWindow.h
class MainWindow: public FXMainWindow
{
 public:
  FXDECLARE(MainWindow)
 public:
  MainWindow(FXApp* app);
  virtual void create();
  virtual ~MainWindow();
 protected:
  MainWindow(){}

 protected:
  FXButton *Button1;
  FXFont *Font1;// 使用するためのFont定義を追加
 public:
  long onBtnClick(FXObject*,FXSelector,void*);
 public:
enum
  {
    ID_QuitBtn = FXMainWindow::ID_LAST,
  };

};

MainWindow.cpp
#include <fx.h>
#include "MainWindow.h"

FXDEFMAP(MainWindow) MainWindowMap[]=
{
  FXMAPFUNC(SEL_COMMAND, MainWindow::ID_QuitBtn, MainWindow::onBtnClick)
};

FXIMPLEMENT(MainWindow,FXMainWindow, MainWindowMap,ARRAYNUMBER(MainWindowMap))

MainWindow::MainWindow(FXApp* app):FXMainWindow(app, "MainWindow", NULL, NULL, DECOR_ALL, 0,0,250, 250)
{
 //Fontの定義・作成
  Font1 = new FXFont(getApp(),"IPAMonaPGothic [unknown],90,normal,regular,,iso10646-1");
  Font1->create();
  //”はろ〜”を入れる
  Button1 = new FXButton(this, fromAscii("はろ〜"), NULL, this, ID_QuitBtn);
  Button1->setFont(Font1);
}

void MainWindow::create()
{
  FXMainWindow::create();
  show(PLACEMENT_SCREEN);
}

MainWindow::~MainWindow()
{
}

long MainWindow::onBtnClick(FXObject*,FXSelector,void*)
{
  getApp()->exit(0);
  return 1;
};

Makefile
NAME    = Skelton
OBJS    = main.o MainWindow.o

CXX     = g++
CXXFLAGS        = -Wall -g3
INCLUDES        = -I/usr/local/include/fox-1.6
LIBS    = -lFOX-1.6 -lGL -lGLU -lX11
LDFLAGS =

$(NAME):$(OBJS)
        $(CXX) -o $@ $(OBJS) $(LDFLAGS) $(LIBS)

.cpp.o:
        $(CXX) -c $(CXXFLAGS) $(INCLUDES) $?

clean:
        $(RM) -f *.o *~ $(NAME)

できるとこんな感じ



参考URL集
    FOX-GUI
    FOX-GUI Community
    日 本語FOX GUI情報
    日 本語でのチュートリアル(大変参考にさせていただきました)