Contenu connexe
Similaire à werkkzeug3のGUI実装 (15)
werkkzeug3のGUI実装
- 13. 全体構成(6) 基本となるクラス
・ OnKey()
キー処理
・ OnShortcut()
ショートカットキーを処理 入力
・ OnDrag()
マウス処理(dragだけではない)
・ OnFrame()
1フレームに1回呼ばれる関数
・ OnCommand() 更新
コマンドを処理する(後述)
- 15. 全体構成(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()
{
}
- 16. 全体構成(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;
}
- 19. 全体構成(12) メインアプリ
WerkkzeugApp
sHSplitFrame
sVSplitFrame sVSplitFrame
sSwitchView sSwitchFrame sSwitchFrame sSwitchFrame
- 23. インタラクション(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
- 24. インタラクション(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++;
}
}
- 25. インタラクション(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;
...
}
- 26. インタラクション(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を成功するまで呼び出す
}
...
}
- 27. インタラクション(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);
...
}
...
}
- 29. 処理の流れ(1) 初期化
WinMain() in _start.cpp
メインループがある関数
→ sSystem_::InitX()
void sSystem_::InitX()
{
...
sAppHandler(sAPPCODE_INIT,0);
...
while (...)
{
...
Render();
...
}
...
}
- 30. 処理の流れ(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);
...
}
- 31. 処理の流れ(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()が毎フレーム呼ばれる
}
}
- 32. 処理の流れ(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(); フォーカスの更新
... (フラグを変える)
}
- 33. 処理の流れ(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を呼び出す位置に注意
- 35. まとめ
・ werkkzeug3のGUIは独自実装である
・ 木構造をなすwindowを構成する
・ 仮想関数を実装して機能を実現する
・ window間の通信はcommandを用いる