SlideShare une entreprise Scribd logo
1  sur  35
Télécharger pour lire hors ligne
werkkzeug3の
GUI実装
ぺりむ (@hi2p_perim)
werkkzeug3のGUIって




    Qt? Gtk? MFC?
werkkzeug3のGUIって




    Qt? Gtk? MFC?
werkkzeug3のGUIって




       独自実装
目的



 werkkzeug3で独自実装されているGUIが
     どのような仕組みで
      動いているのか
           を知る
アウトライン

 ・ 全体構成
 ・ インタラクション
 ・ 処理の流れ
 ・ まとめ
全体構成
全体構成(1) 基本となるクラス

sGuiManager
  GUI管理のメインクラス
  GUIに関する処理をすべて行う
全体構成(2) 基本となるクラス

sGuiWindow
  すべてのGUI要素の基底クラス
 ex. class WinPageList : public sGuiWindow




         分割された領域のひとつ
           cf. emacsのwindow
全体構成(3) 基本となるクラス

sGuiWindowは木構造をなす
class sGuiWindow : public sObject
{
public:
    ...
    sGuiWindow *Childs;
    sGuiWindow *Next;
    ...
};
全体構成(4) 基本となるクラス

windowのborder
  sGuiWindow::AddBorder()によって追加
  windowの境界、ツールバー、スクロールバー等
  ex. class sToolBorder : public sGuiWindow
全体構成(5) 基本となるクラス

sGuiWindowは次のような仮想関数を持つ
それぞれのwindowはこれらを実装する
 ・ OnCalcSize()
    XSize, YSizeを更新
 ・ OnSubBorder() (borderのみ)
    親windowからborderの大きさを引く
                                 レイアウト
 ・ OnLayout()
    childの位置を自身のborderを抜いたサイズに
    合わせて調整する
 ・ OnPaint(), OnPaint3d()
    windowを描画                    描画
全体構成(6) 基本となるクラス
 ・ OnKey()
    キー処理
 ・ OnShortcut()
    ショートカットキーを処理        入力
 ・ OnDrag()
    マウス処理(dragだけではない)
 ・ OnFrame()
    1フレームに1回呼ばれる関数
 ・ OnCommand()          更新
    コマンドを処理する(後述)
全体構成(7) windowの例 (frame)

sHSplitFrame
  windowの水平分割を行う。
  child windowが分割されて配置される。

 child 1



 child 2
全体構成(8) windowの例 (frame)

sSwitchFrame                void sDummyFrame::OnCalcSize()
                            {
  sSwitchFrame::Set()によって          if(Childs)
                                   {
  表示するwindowを選択できる。                        SizeX = Childs->SizeX;
                                           SizeY = Childs->SizeY;
                                   }
                            }

sDummyFrame                 void sDummyFrame::OnLayout()
                            {

  描画を行わない                          if(Childs)
                                   {
                                           Childs->Position = Client;
                                   }
                            }

                            void sDummyFrame::OnPaint()
                            {
                            }
全体構成(9) windowの例 (control)

sControl
  ボタン、テキストボックス等
  ex. ボタンとして初期化
  void sControl::Button(const sChar *label,sU32 cmd)
  {
       sCopyString(NumEditBuf,label,sizeof(NumEditBuf));
       Init(sCT_BUTTON,sCS_FATBORDER|sCS_BORDERSEL,
             NumEditBuf,cmd,0);
       Flags |= sGWF_SQUEEZE;
  }
全体構成(10) メインアプリ

class WerkkzeugApp : public sDummyFrame
   今まで説明してきたライブラリ(__gui.hpp)
   を用いて、werkkzeug3のメインアプリケーション
   クラスを構成している。
全体構成(11) メインアプリ

WerkkzeugApp::WerkkzeugApp()
 コンストラクタでwindowのツリーが作られる。
全体構成(12) メインアプリ

                             WerkkzeugApp




                              sHSplitFrame




              sVSplitFrame                    sVSplitFrame




sSwitchView           sSwitchFrame     sSwitchFrame          sSwitchFrame
インタラクション
インタラクション(1)

例えば…
 メニューバーの「File」を押すと何が起きる?
 borderのメニューを押すと何が起きる?




 これらはどのようにして
 実装されているのか?
インタラクション(2) command

commandを用いた通信を行なっている。

commandの発行・処理大枠
  1. あるwindowがcommand発行
  2. sGuiManager内のバッファに保存
     (コマンド、宛先windowのペアで保存)
  3. 次フレームで一気に処理を行う
     (次フレームのOnFrame()で処理される)
インタラクション(3) command

1. commandの発行
                                                        CMD_MENU_FILE
   sGuiWindow::Post()
void sControl::OnDrag(sDragData &dd)
{
      ...
      switch (dd.Mode)     マウスボタンを放したとき
      {
            case sDD_STOP:
                                               controlのtypeがボタン
                 DragMode = 0;
                 if((Type==sCT_BUTTON ||
                       Type==sCT_CHECKMARK) &&
                       (Flags&sGWF_HOVER))
                 {
                                                  commandをpost
                       Post(DoneCmd);             void sGuiWindow::Post(sU32 cmd)
                 }                                {
                 ...                                    if(cmd)                 宛先は親
      }                                                       sGui->Post(cmd, this ->Parent);
}                                                 }
                                                           sGUIManager
インタラクション(4) command

2. バッファに保存
   sGuiManager::Post()                              CMD_MENU_FILE


 void sGuiManager::Post(sU32 cmd,sGuiWindow *win)
 {
       if(cmd)
       {
             sVERIFY(PostIndex<256);
             PostBuffer[PostIndex] = cmd;
             PostBufferWin[PostIndex] = win;                 PostBuffer
             PostIndex++;
       }
 }
インタラクション(5) command

3. 次フレームで処理
   sGuiManager::OnFrame()                          CMD_MENU_FILE


void sGuiManager::OnFrame()
{
      ...
      for(i=0;i<PostIndex;i++)
      {
            sInt cmd = PostBuffer[i];
            PostBuffer[i] = 0;        バッファから取り出す
                                                        PostBuffer
            if(cmd)
                  Send(cmd,PostBufferWin[i]);
      }
      PostIndex = 0;
      ...
}
インタラクション(6) command

3. 次フレームで処理                                     OnCommand(CMD_MENU_FILE)
                                                is processed and returns sTRUE
   sGuiManager::Send()                                                             App


sBool sGuiManager::Send(sU32 cmd,sGuiWindow *win) OnCommand(CMD_MENU_FILE)
{                                                    returns sFALSE
     if(cmd==0) return sTRUE;
                                                                         ViewWin
     while(win)
     {                                    OnCommand(CMD_MENU_FILE)
           OnWindow = win;                returns sFALSE
           if(win->OnCommand(cmd))                                  ToolBorder
           {
                 OnWindow = 0;
                 return sTRUE;
           }
                                 宛先のwindowとその親すべてに対して
           win = win->Parent;
                                 OnCommandを成功するまで呼び出す
     }
     ...
}
インタラクション(7) command
cf. CMD_MENU_FILEはWerkkzeugAppで処理される
sBool WerkkzeugApp::OnCommand(sU32 cmd)
{
     ...
     switch(cmd)
     {
           ...
           case CMD_MENU_FILE:
                mf = new sMenuFrame;
                mf->SendTo = this ;
                mf->AddBorder( new sNiceBorder);
                mf->AddMenu( "New" ,CMD_FILE_NEW,0);
                mf->AddMenu( "Open" ,CMD_FILE_OPENAS,'o' |sKEYQ_CTRL);
                ...
     }
     ...
}
処理の流れ
処理の流れ(1) 初期化
WinMain() in _start.cpp
                                       メインループがある関数
→ sSystem_::InitX()

 void sSystem_::InitX()
 {
       ...
       sAppHandler(sAPPCODE_INIT,0);
       ...
       while (...)
       {
             ...
             Render();
             ...
       }
       ...
 }
処理の流れ(2) 初期化
sAppHandler() in wz3_main.cpp
→ InitGUI()
  void InitGui()
  {
        ...
        for(i=0;i<sGUI_MAXROOTS;i++)
        {
              if(sSystem->GetScreenInfo(i,si))
              {
                    ov = new sOverlappedFrame;
                    ...
                    sGui->SetRoot(ov,i);
              }
        }
        ...
                                             root nodeとappを作成して、
        win = new WerkkzeugApp;
                                             managerに追加
        sGui->AddApp(win);
        ...
  }
処理の流れ(3) メインループ
sSystem_::InitX()
→ Render()
→ sAppHandler(sAPPCODE_PAINT,0)

sBool sAppHandler(sInt code,sDInt value)
{
     switch(code)
     {
     case sAPPCODE_PAINT:
           {
                ...
                sGui->OnFrame();
                sGui->OnPaint();
                ...
           }
                                     sGuiManager::OnFrame(),
           break;                    sGuiManager::OnPaint()が毎フレーム呼ばれる
     }
}
処理の流れ(4) OnFrame
void sGuiManager::OnFrame()    void sGuiManager::FrameR(sGuiWindow *win)
{                              {
     (コマンドバッファの処理)                   ...
                                     if(win->Flags & sGWF_LAYOUT)
     (フォーカスの変更)                      {
     (マウス処理)                                CalcSizeR(win);
     (キー処理)                                 LayoutR(win);    レイアウト調整
     (子に対してOnFrameを呼び出す)             }
}
                                   (すべてのborderに対してFrameRを呼び出す)
                                   (すべてのchildに対してFrameRを呼び出す)
for(i=0;i<sGUI_MAXROOTS;i++)
                                   if(win->Client.Hit(MouseX,MouseY))
      if(Root[i])
                                          win->Flags |= sGWF_HOVER;
            FrameR(Root[i]);
                                   if(win == Focus)
               Recursion                  win->Flags |= sGWF_FOCUS
                                          |sGWF_CHILDFOCUS;
                                   ...
                                   win->OnFrame();            フォーカスの更新
                                   ...                        (フラグを変える)
                               }
処理の流れ(5) OnPaint
void sGuiManager::OnPaint()
{
     for each root
     {
          (ビューポートの設定)
          (画面のクリア)
          (子に対してOnPaintを呼び出す)
     }
}                           void sGuiManager::PaintR(sGuiWindow *win,
                                      sRect clip,sInt sx,sInt sy)
         PaintR(Root[i],r,0,0);
                                  {
                                      ...
                                      (クリッピングを設定して、OnPaintを呼び出す)
                                      (すべてのchildに対してPaintRを呼び出す)
                                      (すべてのborderに対してPaintRを呼び出す)
                                      ...
                                  }

                                       OnPaint, OnFrameを呼び出す位置に注意
まとめ
まとめ

 ・   werkkzeug3のGUIは独自実装である
 ・   木構造をなすwindowを構成する
 ・   仮想関数を実装して機能を実現する
 ・   window間の通信はcommandを用いる

Contenu connexe

Similaire à werkkzeug3のGUI実装

Node.js - JavaScript Thread Programming
Node.js - JavaScript Thread ProgrammingNode.js - JavaScript Thread Programming
Node.js - JavaScript Thread Programming
takesako
 
デジタルアートセミナー#2 openFrameworksで学ぶ、 クリエイティブ・コーディング Session 2: 構造をつくる
デジタルアートセミナー#2 openFrameworksで学ぶ、 クリエイティブ・コーディング Session 2: 構造をつくるデジタルアートセミナー#2 openFrameworksで学ぶ、 クリエイティブ・コーディング Session 2: 構造をつくる
デジタルアートセミナー#2 openFrameworksで学ぶ、 クリエイティブ・コーディング Session 2: 構造をつくる
Atsushi Tadokoro
 
Extending the Unity Editor Extended
Extending the Unity Editor ExtendedExtending the Unity Editor Extended
Extending the Unity Editor Extended
Masamitsu Ishikawa
 
メディア・アートII 第2回 openFrameworks基礎 配列、くりかえし、乱数 ベクトルを使用したアニメーション
メディア・アートII  第2回 openFrameworks基礎 配列、くりかえし、乱数 ベクトルを使用したアニメーションメディア・アートII  第2回 openFrameworks基礎 配列、くりかえし、乱数 ベクトルを使用したアニメーション
メディア・アートII 第2回 openFrameworks基礎 配列、くりかえし、乱数 ベクトルを使用したアニメーション
Atsushi Tadokoro
 
Media Art II 2013 第5回:openFrameworks Addonを使用する
Media Art II 2013 第5回:openFrameworks Addonを使用するMedia Art II 2013 第5回:openFrameworks Addonを使用する
Media Art II 2013 第5回:openFrameworks Addonを使用する
Atsushi Tadokoro
 
Shibuya Pm Tt08 Advanced Mogilefs
Shibuya Pm Tt08 Advanced MogilefsShibuya Pm Tt08 Advanced Mogilefs
Shibuya Pm Tt08 Advanced Mogilefs
guest172cfb
 

Similaire à werkkzeug3のGUI実装 (15)

Flashup 8
Flashup 8Flashup 8
Flashup 8
 
Node.js - JavaScript Thread Programming
Node.js - JavaScript Thread ProgrammingNode.js - JavaScript Thread Programming
Node.js - JavaScript Thread Programming
 
Android Lecture #03 @PRO&BSC Inc.
Android Lecture #03 @PRO&BSC Inc.Android Lecture #03 @PRO&BSC Inc.
Android Lecture #03 @PRO&BSC Inc.
 
デジタルアートセミナー#2 openFrameworksで学ぶ、 クリエイティブ・コーディング Session 2: 構造をつくる
デジタルアートセミナー#2 openFrameworksで学ぶ、 クリエイティブ・コーディング Session 2: 構造をつくるデジタルアートセミナー#2 openFrameworksで学ぶ、 クリエイティブ・コーディング Session 2: 構造をつくる
デジタルアートセミナー#2 openFrameworksで学ぶ、 クリエイティブ・コーディング Session 2: 構造をつくる
 
Extending the Unity Editor Extended
Extending the Unity Editor ExtendedExtending the Unity Editor Extended
Extending the Unity Editor Extended
 
C++でのゲームプログラミングをしたときのお話 札幌C++勉強会 #4 〜スタートゲームプログラミング〜
C++でのゲームプログラミングをしたときのお話 札幌C++勉強会 #4 〜スタートゲームプログラミング〜C++でのゲームプログラミングをしたときのお話 札幌C++勉強会 #4 〜スタートゲームプログラミング〜
C++でのゲームプログラミングをしたときのお話 札幌C++勉強会 #4 〜スタートゲームプログラミング〜
 
タイマー
タイマータイマー
タイマー
 
emc++ chapter32
emc++ chapter32emc++ chapter32
emc++ chapter32
 
Gocon2013
Gocon2013Gocon2013
Gocon2013
 
メディア・アートII 第2回 openFrameworks基礎 配列、くりかえし、乱数 ベクトルを使用したアニメーション
メディア・アートII  第2回 openFrameworks基礎 配列、くりかえし、乱数 ベクトルを使用したアニメーションメディア・アートII  第2回 openFrameworks基礎 配列、くりかえし、乱数 ベクトルを使用したアニメーション
メディア・アートII 第2回 openFrameworks基礎 配列、くりかえし、乱数 ベクトルを使用したアニメーション
 
Hello, Guava ! samples
Hello, Guava ! samplesHello, Guava ! samples
Hello, Guava ! samples
 
Media Art II 2013 第5回:openFrameworks Addonを使用する
Media Art II 2013 第5回:openFrameworks Addonを使用するMedia Art II 2013 第5回:openFrameworks Addonを使用する
Media Art II 2013 第5回:openFrameworks Addonを使用する
 
Shibuya Pm Tt08 Advanced Mogilefs
Shibuya Pm Tt08 Advanced MogilefsShibuya Pm Tt08 Advanced Mogilefs
Shibuya Pm Tt08 Advanced Mogilefs
 
Ogre3d 基礎
Ogre3d 基礎Ogre3d 基礎
Ogre3d 基礎
 
Sencha study
Sencha studySencha study
Sencha study
 

werkkzeug3のGUI実装