| 1 |
#include "stdafx.h" |
| 2 |
#include "CInterface.h" |
| 3 |
#include "CPopMenu.h" |
| 4 |
#include "CSkinPlugin.h" |
| 5 |
|
| 6 |
// 内部定数 |
| 7 |
const int MENU_RECT_MARGIN = 4; // 選択部余白 |
| 8 |
|
| 9 |
// static メンバ |
| 10 |
CPopMenu *CPopMenu::ms_ActiveMenu = NULL; |
| 11 |
|
| 12 |
/* |
| 13 |
* [static] |
| 14 |
* メニュー処理 |
| 15 |
*/ |
| 16 |
int CPopMenu::ScanInputAll(){ |
| 17 |
if(!ms_ActiveMenu) return 0; |
| 18 |
if(CInterface::ms_Focus){ |
| 19 |
ms_ActiveMenu = NULL; |
| 20 |
return 0; |
| 21 |
} |
| 22 |
int ret = ms_ActiveMenu->ScanInput(); |
| 23 |
if(ret>0 || !ret && (GetButton(DIM_LEFT)==S_PUSH |
| 24 |
|| GetButton(DIM_RIGHT)==S_PUSH)) ms_ActiveMenu = NULL; |
| 25 |
return ret; |
| 26 |
} |
| 27 |
|
| 28 |
/* |
| 29 |
* [static] |
| 30 |
* メニュー表示 |
| 31 |
*/ |
| 32 |
void CPopMenu::RenderAll(){ |
| 33 |
if(!ms_ActiveMenu) return; |
| 34 |
ms_ActiveMenu->Render(); |
| 35 |
} |
| 36 |
|
| 37 |
/* |
| 38 |
* コンストラクタ |
| 39 |
*/ |
| 40 |
CPopMenu::CPopMenu( |
| 41 |
char *str, // 文字列 |
| 42 |
CPopMenu *p // 親 |
| 43 |
){ |
| 44 |
m_ChildNum = 0; |
| 45 |
m_Width = TILE_UNIT*3/2; |
| 46 |
m_Height = TILE_UNIT; |
| 47 |
m_Enabled = true; |
| 48 |
m_String = str; |
| 49 |
m_Command = NULL; |
| 50 |
m_Parent = m_Brother = m_Child = NULL; |
| 51 |
if(p) p->InsertMenu(this); |
| 52 |
} |
| 53 |
|
| 54 |
/* |
| 55 |
* デストラクタ |
| 56 |
*/ |
| 57 |
CPopMenu::~CPopMenu(){ |
| 58 |
DELETE_V(m_Child); |
| 59 |
DELETE_V(m_Brother); |
| 60 |
ClearCommand(); |
| 61 |
} |
| 62 |
|
| 63 |
/* |
| 64 |
* 子メニュー挿入 |
| 65 |
*/ |
| 66 |
void CPopMenu::InsertMenu( |
| 67 |
CPopMenu *menu // メニュー |
| 68 |
){ |
| 69 |
CPopMenu **adr = &m_Child; |
| 70 |
while(*adr) adr = &(*adr)->m_Brother; |
| 71 |
*adr = menu; |
| 72 |
menu->m_Parent = this; |
| 73 |
m_ChildNum++; |
| 74 |
int tw = g_StrTex->DrawString(menu->m_String.c_str(), 0)->GetWidth(); |
| 75 |
if(m_Width<tw+TILE_UNIT*3/2) m_Width = tw+TILE_UNIT*3/2; |
| 76 |
m_Height += TILE_UNIT; |
| 77 |
} |
| 78 |
|
| 79 |
/* |
| 80 |
* 指定座標が範囲内か調べる |
| 81 |
*/ |
| 82 |
bool CPopMenu::IsInside( |
| 83 |
int x, int y // 座標 |
| 84 |
){ |
| 85 |
return m_PosX<=x && x<m_PosX+m_Width && m_PosY<=y && y<=m_PosY+m_Height; |
| 86 |
} |
| 87 |
|
| 88 |
/* |
| 89 |
* 指定座標に対応する番号を取得 |
| 90 |
*/ |
| 91 |
int CPopMenu::HitTest( |
| 92 |
int x, int y // 座標 |
| 93 |
){ |
| 94 |
if(x<m_PosX+MENU_RECT_MARGIN || m_PosX+m_Width-MENU_RECT_MARGIN<=x |
| 95 |
|| y<m_PosY+TILE_UNIT/2) return -1; |
| 96 |
int index = (y-m_PosY-TILE_UNIT/2)/TILE_UNIT; |
| 97 |
return m_ChildNum<=index ? -1 : index; |
| 98 |
} |
| 99 |
|
| 100 |
/* |
| 101 |
* 番号からメニュー取得 |
| 102 |
*/ |
| 103 |
CPopMenu *CPopMenu::GetMenu( |
| 104 |
int index // 番号 |
| 105 |
){ |
| 106 |
if(index<0 || m_ChildNum<=index) return NULL; |
| 107 |
CPopMenu *ptr = m_Child; |
| 108 |
while(index--) ptr = ptr->m_Brother; |
| 109 |
return ptr; |
| 110 |
} |
| 111 |
|
| 112 |
/* |
| 113 |
* メニューポップアップ |
| 114 |
*/ |
| 115 |
void CPopMenu::Popup( |
| 116 |
int x, int y, // 左上ポップアップ座標 |
| 117 |
int tw, int th, // 呼び出し元領域サイズ |
| 118 |
int dir // ポップアップ方向 (0: 左上, 1: 右上, 2: 左下, 3: 右下) |
| 119 |
){ |
| 120 |
CInterface::ms_Focus = NULL; |
| 121 |
m_Pointed = NULL; |
| 122 |
if(dir&1){ |
| 123 |
if(x+m_Width>=g_DispWidth) dir ^= 1; |
| 124 |
}else{ |
| 125 |
if(x-tw-m_Width<0) dir |= 1; |
| 126 |
} |
| 127 |
if(dir&2){ |
| 128 |
if(y+m_Height>=g_DispHeight) dir ^= 2; |
| 129 |
}else{ |
| 130 |
if(y+th-m_Height<0) dir |= 2; |
| 131 |
} |
| 132 |
if(!(dir&1)) x -= tw+m_Width; |
| 133 |
if(!(dir&2)) y -= m_Height-th; |
| 134 |
m_PosX = x; m_PosY = y; |
| 135 |
m_Expand = dir; |
| 136 |
if(!ms_ActiveMenu) ms_ActiveMenu = this; |
| 137 |
g_Skin->MouseDown(); |
| 138 |
CPopMenu *ptr = m_Child; |
| 139 |
while(ptr){ |
| 140 |
ptr->m_Expand = -1; |
| 141 |
ptr = ptr->m_Brother; |
| 142 |
} |
| 143 |
} |
| 144 |
|
| 145 |
/* |
| 146 |
* 入力チェック |
| 147 |
* |
| 148 |
* 戻り値: 0: none, >0: command, <0: inside |
| 149 |
*/ |
| 150 |
int CPopMenu::ScanInput(){ |
| 151 |
CPopMenu *ptr = m_Child; |
| 152 |
bool exp = false; |
| 153 |
while(ptr){ |
| 154 |
if(ptr->IsExpand()){ |
| 155 |
if(ptr!=m_Pointed){ |
| 156 |
ptr->m_Expand = -1; |
| 157 |
}else{ |
| 158 |
int tmp = ptr->ScanInput(); |
| 159 |
if(tmp) return tmp; |
| 160 |
exp = true; |
| 161 |
} |
| 162 |
} |
| 163 |
ptr = ptr->m_Brother; |
| 164 |
} |
| 165 |
POINT pos = g_Cursor.GetPos(); |
| 166 |
int index = HitTest(pos.x, pos.y); |
| 167 |
CPopMenu *pm = GetMenu(index); |
| 168 |
if(pm && (!pm->m_Enabled || pm->m_String=="-")) pm = NULL; |
| 169 |
if(!exp || pm && pm!=m_Pointed){ |
| 170 |
m_Pointed = pm; |
| 171 |
if(m_Pointed && m_Pointed->m_Child) m_Pointed->Popup( |
| 172 |
m_PosX+m_Width-MENU_RECT_MARGIN, m_PosY+TILE_UNIT/2+index*TILE_UNIT, |
| 173 |
m_Width-2*MENU_RECT_MARGIN, TILE_UNIT, m_Expand); |
| 174 |
} |
| 175 |
if(GetButton(DIM_LEFT)==S_PULL || GetButton(DIM_RIGHT)==S_PULL){ |
| 176 |
if(!pm) return 0; |
| 177 |
if(pm->m_Child) return -1; |
| 178 |
g_Skin->MouseUp(); |
| 179 |
if(pm->m_Command) pm->m_Command->Exec(); |
| 180 |
return 1; |
| 181 |
} |
| 182 |
return IsInside(pos.x, pos.y) ? -1 : 0; |
| 183 |
} |
| 184 |
|
| 185 |
/* |
| 186 |
* レンダリング |
| 187 |
*/ |
| 188 |
void CPopMenu::Render(){ |
| 189 |
g_Skin->SetInterfaceTexture(); |
| 190 |
SetUVMap(0.625f, 0.375f, 0.75f, 0.5f); |
| 191 |
TexMap2DRect(m_PosX, m_PosY, m_PosX+TILE_UNIT, m_PosY+TILE_UNIT, 0xffffffff); |
| 192 |
SetUVMap(0.75f, 0.375f, 0.875f, 0.5f); |
| 193 |
TexMap2DRect(m_PosX+TILE_UNIT, m_PosY, m_PosX+m_Width-TILE_UNIT, m_PosY+TILE_UNIT, 0xffffffff); |
| 194 |
SetUVMap(0.875f, 0.375f, 1.0f, 0.5f); |
| 195 |
TexMap2DRect(m_PosX+m_Width-TILE_UNIT, m_PosY, m_PosX+m_Width, m_PosY+TILE_UNIT, 0xffffffff); |
| 196 |
SetUVMap(0.625f, 0.5f, 0.75f, 0.625f); |
| 197 |
TexMap2DRect(m_PosX, m_PosY+TILE_UNIT, m_PosX+TILE_UNIT, m_PosY+m_Height-TILE_UNIT, 0xffffffff); |
| 198 |
SetUVMap(0.75f, 0.5f, 0.875f, 0.625f); |
| 199 |
TexMap2DRect(m_PosX+TILE_UNIT, m_PosY+TILE_UNIT, m_PosX+m_Width-TILE_UNIT, m_PosY+m_Height-TILE_UNIT, 0xffffffff); |
| 200 |
SetUVMap(0.875f, 0.5f, 1.0f, 0.625f); |
| 201 |
TexMap2DRect(m_PosX+m_Width-TILE_UNIT, m_PosY+TILE_UNIT, m_PosX+m_Width, m_PosY+m_Height-TILE_UNIT, 0xffffffff); |
| 202 |
SetUVMap(0.625f, 0.625f, 0.75f, 0.75f); |
| 203 |
TexMap2DRect(m_PosX, m_PosY+m_Height-TILE_UNIT, m_PosX+TILE_UNIT, m_PosY+m_Height, 0xffffffff); |
| 204 |
SetUVMap(0.75f, 0.625f, 0.875f, 0.75f); |
| 205 |
TexMap2DRect(m_PosX+TILE_UNIT, m_PosY+m_Height-TILE_UNIT, m_PosX+m_Width-TILE_UNIT, m_PosY+m_Height, 0xffffffff); |
| 206 |
SetUVMap(0.875f, 0.625f, 1.0f, 0.75f); |
| 207 |
TexMap2DRect(m_PosX+m_Width-TILE_UNIT, m_PosY+m_Height-TILE_UNIT, m_PosX+m_Width, m_PosY+m_Height, 0xffffffff); |
| 208 |
CPopMenu *ptr = m_Child; |
| 209 |
int ty = m_PosY+TILE_UNIT/2; |
| 210 |
while(ptr){ |
| 211 |
if(ptr->m_String=="-"){ |
| 212 |
devSetTexture(0, NULL); |
| 213 |
Draw2DLine(m_PosX+TILE_HALF, ty+TILE_HALF-1, |
| 214 |
m_PosX+m_Width-TILE_HALF, ty+TILE_HALF-1, |
| 215 |
g_Skin->m_PopupMenuData.m_DisabledFontColor); |
| 216 |
Draw2DLine(m_PosX+TILE_HALF, ty+TILE_HALF, |
| 217 |
m_PosX+m_Width-TILE_HALF, ty+TILE_HALF, |
| 218 |
g_Skin->m_PopupMenuData.m_DisabledShadowColor); |
| 219 |
}else{ |
| 220 |
D3DCOLOR fc, sdw = 0; |
| 221 |
if(ptr->m_Enabled){ |
| 222 |
if(ptr==m_Pointed){ |
| 223 |
devSetTexture(0, NULL); |
| 224 |
Grad2DRect(m_PosX+MENU_RECT_MARGIN, ty, |
| 225 |
m_PosX+m_Width-MENU_RECT_MARGIN, ty+TILE_UNIT, |
| 226 |
g_Skin->m_PopupMenuData.m_SelectedBaseColor); |
| 227 |
fc = g_Skin->m_PopupMenuData.m_SelectedFontColor; |
| 228 |
}else{ |
| 229 |
fc = g_Skin->m_PopupMenuData.m_DefaultFontColor; |
| 230 |
} |
| 231 |
}else{ |
| 232 |
fc = g_Skin->m_PopupMenuData.m_DisabledFontColor; |
| 233 |
sdw = g_Skin->m_PopupMenuData.m_DisabledShadowColor; |
| 234 |
} |
| 235 |
if(ptr->m_Child){ |
| 236 |
g_Skin->SetInterfaceTexture(); |
| 237 |
SetUVMap(0.5f, 0.875f, 0.625f, 1.0f); |
| 238 |
TexMap2DRect(m_PosX+m_Width-TILE_UNIT, ty, |
| 239 |
m_PosX+m_Width, ty+TILE_UNIT, fc); |
| 240 |
} |
| 241 |
if(sdw) g_StrTex->RenderLeft( |
| 242 |
m_PosX+TILE_UNIT/2+1, ty+FontY(TILE_UNIT)+1, sdw, 0, ptr->m_String.c_str()); |
| 243 |
g_StrTex->RenderLeft( |
| 244 |
m_PosX+TILE_UNIT/2, ty+FontY(TILE_UNIT), fc, 0, ptr->m_String.c_str()); |
| 245 |
} |
| 246 |
ty += TILE_UNIT; |
| 247 |
ptr = ptr->m_Brother; |
| 248 |
} |
| 249 |
if(m_Pointed && m_Pointed->IsExpand()) m_Pointed->Render(); |
| 250 |
} |