📄 guimenubar.cc
字号:
curX += walk->bounds.extent.x;
}
mouseOverMenu = NULL;
mouseDownMenu = NULL;
}
}
void GuiMenuBar::checkMenuMouseMove(const GuiEvent &event)
{
Menu *hit = findHitMenu(event.mousePoint);
if(hit && hit != mouseDownMenu)
{
// gotta close out the current menu...
mTextList->setSelectedCell(Point2I(-1, -1));
closeMenu();
mouseOverMenu = mouseDownMenu = hit;
setUpdate();
onAction();
}
}
void GuiMenuBar::onMouseMove(const GuiEvent &event)
{
Menu *hit = findHitMenu(event.mousePoint);
if(hit != mouseOverMenu)
{
mouseOverMenu = hit;
setUpdate();
}
}
void GuiMenuBar::onMouseLeave(const GuiEvent &event)
{
if(mouseOverMenu)
setUpdate();
mouseOverMenu = NULL;
}
void GuiMenuBar::onMouseDragged(const GuiEvent &event)
{
Menu *hit = findHitMenu(event.mousePoint);
if(hit != mouseOverMenu)
{
mouseOverMenu = hit;
mouseDownMenu = hit;
setUpdate();
onAction();
}
}
void GuiMenuBar::onMouseDown(const GuiEvent &event)
{
mouseDownMenu = mouseOverMenu = findHitMenu(event.mousePoint);
setUpdate();
onAction();
}
void GuiMenuBar::onMouseUp(const GuiEvent &event)
{
mouseDownMenu = NULL;
setUpdate();
}
void GuiMenuBar::onRender(Point2I offset, const RectI &updateRect)
{
//if opaque, fill the update rect with the fill color
if (mProfile->mOpaque)
dglDrawRectFill(RectI(offset, mBounds.extent), mProfile->mFillColor);
for(Menu *walk = menuList; walk; walk = walk->nextMenu)
{
if(!walk->visible)
continue;
ColorI fontColor = mProfile->mFontColor;
RectI bounds = walk->bounds;
bounds.point += offset;
Point2I start;
start.x = walk->bounds.point.x + 6;
start.y = walk->bounds.point.y + ( walk->bounds.extent.y - ( mProfile->mFont->getHeight() - 2 ) ) / 2;
#ifdef TGE_RPG_UI ///TGE_RPG_UI
if(walk == mouseDownMenu)
renderFilledBorder(bounds, mProfile->mBorderColorHL,mProfile->mFillColorHL);
else if(walk == mouseOverMenu && mouseDownMenu == NULL)
renderFilledBorder(bounds, mProfile->mBorderColor,mProfile->mFillColorHL);
#else
if(walk == mouseDownMenu)
renderSlightlyLoweredBox(bounds, mProfile);
else if(walk == mouseOverMenu && mouseDownMenu == NULL)
renderSlightlyRaisedBox(bounds, mProfile);
#endif
dglSetBitmapModulation( fontColor );
dglDrawText( mProfile->mFont, start + offset, walk->text, mProfile->mFontColors );
}
}
void GuiMenuBar::buildAcceleratorMap()
{
Parent::buildAcceleratorMap();
// ok, accelerator map is cleared...
// add all our keys:
mCurAcceleratorIndex = 1;
for(Menu *menu = menuList; menu; menu = menu->nextMenu)
{
for(MenuItem *item = menu->firstMenuItem; item; item = item->nextMenuItem)
{
if(!item->accelerator)
{
item->accelerator = 0;
continue;
}
EventDescriptor accelEvent;
ActionMap::createEventDescriptor(item->accelerator, &accelEvent);
//now we have a modifier, and a key, add them to the canvas
GuiCanvas *root = getRoot();
if (root)
root->addAcceleratorKey(this, mCurAcceleratorIndex, accelEvent.eventCode, accelEvent.flags);
item->acceleratorIndex = mCurAcceleratorIndex;
mCurAcceleratorIndex++;
}
}
}
void GuiMenuBar::acceleratorKeyPress(U32 index)
{
// loop through all the menus
// and find the item that corresponds to the accelerator index
for(Menu *menu = menuList; menu; menu = menu->nextMenu)
{
if(!menu->visible)
continue;
for(MenuItem *item = menu->firstMenuItem; item; item = item->nextMenuItem)
{
if(item->acceleratorIndex == index)
{
// first, call the script callback for menu selection:
Con::executef( this, 4, "onMenuSelect", Con::getIntArg(menu->id),
menu->text);
if(item->visible)
menuItemSelected(menu, item);
return;
}
}
}
}
//------------------------------------------------------------------------------
// Menu display class methods
//------------------------------------------------------------------------------
GuiMenuBackgroundCtrl::GuiMenuBackgroundCtrl(GuiMenuBar *ctrl, GuiMenuTextListCtrl *textList)
{
mMenuBarCtrl = ctrl;
mTextList = textList;
}
void GuiMenuBackgroundCtrl::onMouseDown(const GuiEvent &event)
{
mTextList->setSelectedCell(Point2I(-1,-1));
mMenuBarCtrl->closeMenu();
}
void GuiMenuBackgroundCtrl::onMouseMove(const GuiEvent &event)
{
GuiCanvas *root = getRoot();
GuiControl *ctrlHit = root->findHitControl(event.mousePoint, mLayer - 1);
if(ctrlHit == mMenuBarCtrl) // see if the current mouse over menu is right...
mMenuBarCtrl->checkMenuMouseMove(event);
}
void GuiMenuBackgroundCtrl::onMouseDragged(const GuiEvent &event)
{
GuiCanvas *root = getRoot();
GuiControl *ctrlHit = root->findHitControl(event.mousePoint, mLayer - 1);
if(ctrlHit == mMenuBarCtrl) // see if the current mouse over menu is right...
mMenuBarCtrl->checkMenuMouseMove(event);
}
GuiMenuTextListCtrl::GuiMenuTextListCtrl(GuiMenuBar *ctrl)
{
mMenuBarCtrl = ctrl;
}
void GuiMenuTextListCtrl::onRenderCell(Point2I offset, Point2I cell, bool selected, bool mouseOver)
{
if(dStrcmp(mList[cell.y].text + 2, "-\t"))
Parent::onRenderCell(offset, cell, selected, mouseOver);
else
{
S32 yp = offset.y + mCellSize.y / 2;
dglDrawLine(offset.x, yp, offset.x + mCellSize.x, yp, ColorI(128,128,128));
dglDrawLine(offset.x, yp+1, offset.x + mCellSize.x, yp+1, ColorI(255,255,255));
}
// now see if there's a bitmap...
U8 idx = mList[cell.y].text[0];
if(idx != 1)
{
// there's a bitmap...
U32 index = U32(idx - 2) * 3;
if(!mList[cell.y].active)
index += 2;
else if(selected || mouseOver)
index ++;
RectI rect = mProfile->mBitmapArrayRects[index];
#ifdef TGE_RPG_UI ///TGE_RPG_UI
Point2I off;
off.y = (mCellSize.y - rect.extent.y)/2;
off.x = 2;
if(selected || mouseOver)
off.y--;
#else
Point2I off = mMenuBarCtrl->maxBitmapSize - rect.extent;
off /= 2;
#endif
dglClearBitmapModulation();
dglDrawBitmapSR(mProfile->mTextureHandle, offset + off, rect);
}
}
bool GuiMenuTextListCtrl::onKeyDown(const GuiEvent &event)
{
//if the control is a dead end, don't process the input:
if ( !mVisible || !mActive || !mAwake )
return false;
//see if the key down is a <return> or not
if ( event.modifier == 0 )
{
if ( event.keyCode == KEY_RETURN )
{
mMenuBarCtrl->closeMenu();
return true;
}
else if ( event.keyCode == KEY_ESCAPE )
{
mSelectedCell.set( -1, -1 );
mMenuBarCtrl->closeMenu();
return true;
}
}
//otherwise, pass the event to it's parent
return Parent::onKeyDown(event);
}
void GuiMenuTextListCtrl::onMouseDown(const GuiEvent &event)
{
Parent::onMouseDown(event);
mMenuBarCtrl->closeMenu();
}
void GuiMenuTextListCtrl::onMouseUp(const GuiEvent &event)
{
// ok, this is kind of strange... but!
// here's the deal: if we get a mouse up in this control
// it means the mouse was dragged from the initial menu mouse click
// so: activate the menu result as though this event were,
// instead, a mouse down.
onMouseDown(event);
}
//------------------------------------------------------------------------------
void GuiMenuBar::menuItemSelected(GuiMenuBar::Menu *menu, GuiMenuBar::MenuItem *item)
{
if(item->enabled)
Con::executef( this, 6, "onMenuItemSelect", Con::getIntArg(menu->id),
menu->text, Con::getIntArg(item->id), item->text);
}
void GuiMenuBar::onSleep()
{
if(mBackground) // a menu is up?
{
mTextList->setSelectedCell(Point2I(-1, -1));
closeMenu();
}
Parent::onSleep();
}
void GuiMenuBar::closeMenu()
{
// Get the selection from the text list:
S32 selectionIndex = mTextList->getSelectedCell().y;
// Pop the background:
getRoot()->popDialogControl(mBackground);
// Kill the popup:
mBackground->deleteObject();
mBackground = NULL;
// Now perform the popup action:
if ( selectionIndex != -1 )
{
MenuItem *list = mouseDownMenu->firstMenuItem;
while(selectionIndex && list)
{
list = list->nextMenuItem;
selectionIndex--;
}
if(list)
menuItemSelected(mouseDownMenu, list);
}
mouseDownMenu = NULL;
}
//------------------------------------------------------------------------------
void GuiMenuBar::onAction()
{
if(!mouseDownMenu)
return;
// first, call the script callback for menu selection:
Con::executef( this, 4, "onMenuSelect", Con::getIntArg(mouseDownMenu->id),
mouseDownMenu->text);
MenuItem *visWalk = mouseDownMenu->firstMenuItem;
while(visWalk)
{
if(visWalk->visible)
break;
visWalk = visWalk->nextMenuItem;
}
if(!visWalk)
{
mouseDownMenu = NULL;
return;
}
mTextList = new GuiMenuTextListCtrl(this);
mTextList->mProfile = mProfile;
mBackground = new GuiMenuBackgroundCtrl(this, mTextList);
GuiCanvas *root = getRoot();
Point2I windowExt = root->mBounds.extent;
mBackground->mBounds.point.set(0,0);
mBackground->mBounds.extent = root->mBounds.extent;
S32 textWidth = 0, width = 0;
S32 acceleratorWidth = 0;
GFont *font = mProfile->mFont;
for(MenuItem *walk = mouseDownMenu->firstMenuItem; walk; walk = walk->nextMenuItem)
{
if(!walk->visible)
continue;
S32 iTextWidth = font->getStrWidth((const UTF8 *)walk->text);
S32 iAcceleratorWidth = walk->accelerator ? font->getStrWidth((const UTF8 *)walk->accelerator) : 0;
if(iTextWidth > textWidth)
textWidth = iTextWidth;
if(iAcceleratorWidth > acceleratorWidth)
acceleratorWidth = iAcceleratorWidth;
}
width = textWidth + acceleratorWidth + maxBitmapSize.x * 2 + 2 + 4;
#ifdef TGE_RPG ///TGE_RPG
mTextList->setCellSize(Point2I(width, font->getHeight()+6));
#else
mTextList->setCellSize(Point2I(width, font->getHeight()+3));
#endif
mTextList->clearColumnOffsets();
mTextList->addColumnOffset(-1); // add an empty column in for the bitmap index.
mTextList->addColumnOffset(maxBitmapSize.x + 1);
mTextList->addColumnOffset(maxBitmapSize.x + 1 + textWidth + 4);
U32 entryCount = 0;
#ifdef TGE_RPG_UI ///TGE_RPG_UI
char szAcc[64];
#endif
for(MenuItem *walk = mouseDownMenu->firstMenuItem; walk; walk = walk->nextMenuItem)
{
if(!walk->visible)
continue;
char buf[512];
char bitmapIndex = 1;
if(walk->bitmapIndex >= 0 && (walk->bitmapIndex * 3 <= mProfile->mBitmapArrayRects.size()))
bitmapIndex = walk->bitmapIndex + 2;
#ifdef TGE_RPG_UI ///TGE_RPG_UI
if(walk->accelerator)
{
dStrcpy(szAcc,walk->accelerator);
char* pSpace = dStrstr((const char*)szAcc," ");
if(pSpace)
pSpace[0] = '+';
}
else
szAcc[0] = 0;
dSprintf(buf, sizeof(buf), "%c\t%s\t%s", bitmapIndex, walk->text, szAcc);
#else
dSprintf(buf, sizeof(buf), "%c\t%s\t%s", bitmapIndex, walk->text, walk->accelerator ? walk->accelerator : "");
#endif
mTextList->addEntry(entryCount, buf);
if(!walk->enabled)
mTextList->setEntryActive(entryCount, false);
entryCount++;
}
Point2I menuPoint = localToGlobalCoord(mouseDownMenu->bounds.point);
menuPoint.y += mouseDownMenu->bounds.extent.y + 2;
GuiControl *ctrl = new GuiControl;
ctrl->mBounds.point = menuPoint;
ctrl->mBounds.extent = mTextList->mBounds.extent + Point2I(6, 6);
ctrl->mProfile = mProfile;
mTextList->mBounds.point += Point2I(3,3);
//mTextList->mBounds.point = Point2I(3,3);
mTextList->registerObject();
mBackground->registerObject();
ctrl->registerObject();
mBackground->addObject( ctrl );
ctrl->addObject( mTextList );
root->pushDialogControl(mBackground, mLayer + 1);
mTextList->setFirstResponder();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -