⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 guipopupctrl.cc

📁 五行MMORPG引擎系统V1.0
💻 CC
📖 第 1 页 / 共 2 页
字号:

         // Now perform the popup action:
         char idval[24];
         dSprintf( idval, sizeof(idval), "%d", mEntries[mSelIndex].id );
         Con::executef( this, 3, "onSelect", idval, mEntries[mSelIndex].buf );
         return;
      }

   setText("");
   mSelIndex = -1;

   Con::executef( this, 1, "onCancel" );

   // Execute the popup console command:
   if ( mConsoleCommand[0] )
      Con::evaluate( mConsoleCommand, false );
}

//------------------------------------------------------------------------------
const char *GuiPopUpMenuCtrl::getScriptValue()
{
   return getText();
}

//------------------------------------------------------------------------------
void GuiPopUpMenuCtrl::onRender(Point2I offset, const RectI &updateRect)
{
   updateRect;
   Point2I localStart;

   if(mScrollDir != GuiScrollCtrl::None)
      autoScroll();

   RectI r(offset, mBounds.extent);
   RectI buttonRect( ( r.point.x + r.extent.x ) - 18, r.point.y + 2, 16, r.extent.y - 4);
   if( mProfile->mBorder && mProfile->mOpaque)
   {
      if(mInAction)
      {
         renderFilledBorder(r, mProfile->mBorderColorHL, mProfile->mFillColor);
         renderFilledBorder( buttonRect, mProfile->mBorderColorHL, mProfile->mFillColorNA);
      }
      else
      {
         renderFilledBorder(r, mProfile->mBorderColorHL, mProfile->mFillColor);
         renderFilledBorder( buttonRect, mProfile->mBorderColorHL, mProfile->mFillColorNA);
      }
   }

   
   

   S32 txt_w = mFont->getStrWidth((const UTF8 *)mText);
   localStart.x = 0;
   localStart.y = (mBounds.extent.y - (mFont->getHeight())) / 2;

   // align the horizontal
   switch (mProfile->mAlignment)
   {
      case GuiControlProfile::RightJustify:
         localStart.x = mBounds.extent.x - txt_w;
         break;
      case GuiControlProfile::CenterJustify:
         localStart.x = (mBounds.extent.x - txt_w) / 2;
         break;
      default: // GuiControlProfile::LeftJustify
         localStart.x = 4;
         break;
   }
   Point2I globalStart = localToGlobalCoord(localStart);
   dglSetBitmapModulation(mProfile->mFontColor);
   dglDrawText(mFont, globalStart, mText, mProfile->mFontColors);
}

//------------------------------------------------------------------------------
void GuiPopUpMenuCtrl::closePopUp()
{
   if ( !mInAction )
      return;

   // Get the selection from the text list:
   mSelIndex = mTl->getSelectedCell().y;
   mSelIndex = (mRevNum >= mSelIndex && mSelIndex != -1) ? mRevNum - mSelIndex : mSelIndex;
   if ( mSelIndex != -1 )
   {
      if(mReplaceText)
         setText( mEntries[mSelIndex].buf );
      setIntVariable( mEntries[mSelIndex].id );
   }

   // Release the mouse:
   mInAction = false;
   mTl->mouseUnlock();

   // Pop the background:
   getRoot()->popDialogControl(mBackground);

   // Kill the popup:
   mBackground->removeObject( mSc );
   mTl->deleteObject();
   mSc->deleteObject();
   mBackground->deleteObject();

   // Set this as the first responder:
   setFirstResponder();

   // Now perform the popup action:
   if ( mSelIndex != -1 )
   {
      char idval[24];
      dSprintf( idval, sizeof(idval), "%d", mEntries[mSelIndex].id );
      Con::executef( this, 3, "onSelect", idval, mEntries[mSelIndex].buf );
   }
   else
      Con::executef( this, 1, "onCancel" );

   // Execute the popup console command:
   if ( mConsoleCommand[0] )
      Con::evaluate( mConsoleCommand, false );
}

//------------------------------------------------------------------------------
bool GuiPopUpMenuCtrl::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.keyCode == KEY_RETURN && event.modifier == 0 )
   {
      onAction();
      return true;
   }

   S32 selected = mSelIndex;
   switch( event.keyCode )
   {
   case KEY_RIGHT:
   case KEY_DOWN:
      if( ( selected + 1 ) < mEntries.size() )
         setSelected( mEntries[selected + 1].id );
      break;
   case KEY_UP:
   case KEY_LEFT:
      if( ( selected - 1 ) > 0 )
         setSelected( mEntries[selected - 1].id );

      break;   
   }

   //otherwise, pass the event to its parent
   return Parent::onKeyDown( event );
}

//------------------------------------------------------------------------------
void GuiPopUpMenuCtrl::onAction()
{
   GuiControl *canCtrl = getParent();

   addChildren();

   GuiCanvas *root = getRoot();
   Point2I windowExt = root->mBounds.extent;

   mBackground->mBounds.point.set(0,0);
   mBackground->mBounds.extent = root->mBounds.extent;

   S32 textWidth = 0, width = mBounds.extent.x;
   const S32 menuSpace = 5;
   const S32 textSpace = 2;
   bool setScroll = false;

   for(U32 i=0; i<mEntries.size(); ++i)
      if(S32(mFont->getStrWidth((const UTF8 *)mEntries[i].buf)) > textWidth)
         textWidth = mFont->getStrWidth((const UTF8 *)mEntries[i].buf);

   if(textWidth > mBounds.extent.x)
   {
      textWidth +=10;
      width = textWidth;
   }

   mTl->setCellSize(Point2I(width, mFont->getHeight()+3));

   for(U32 j=0; j<mEntries.size(); ++j)
      mTl->addEntry(mEntries[j].id, mEntries[j].buf);

   Point2I pointInGC = canCtrl->localToGlobalCoord(mBounds.point);
   Point2I scrollPoint(pointInGC.x, pointInGC.y + mBounds.extent.y);

   //Calc max Y distance, so Scroll Ctrl will fit on window
   S32 maxYdis = windowExt.y - pointInGC.y - mBounds.extent.y - menuSpace;

   //If scroll bars need to be added
   if(maxYdis < mTl->mBounds.extent.y + textSpace)
   {
      //Should we pop menu list above the button
      if(maxYdis < pointInGC.y - menuSpace)
      {
         reverseTextList();
         maxYdis = pointInGC.y - menuSpace;
         //Does the menu need a scroll bar
         if(maxYdis < mTl->mBounds.extent.y + textSpace)
         {
            //Calc for the width of the scroll bar
            if(textWidth >=  width)
               width += 20;
            mTl->setCellSize(Point2I(width,mFont->getHeight() + textSpace));
            //Pop menu list above the button
            scrollPoint.set(pointInGC.x, menuSpace - 1);
            setScroll = true;
         }
         //No scroll bar needed
         else
         {
            maxYdis = mTl->mBounds.extent.y + textSpace;
            scrollPoint.set(pointInGC.x, pointInGC.y - maxYdis -1);
         }
      }
      //Scroll bar needed but Don't pop above button
      else
      {
         mRevNum = 0;
         //Calc for the width of the scroll bar
         if(textWidth >=  width)
            width += 20;
         mTl->setCellSize(Point2I(width,mFont->getHeight() + textSpace));
         setScroll = true;
      }
   }
   //No scroll bar needed
   else
      maxYdis = mTl->mBounds.extent.y + textSpace;

   //offset it from the background so it lines up properly
   mSc->mBounds.point = mBackground->globalToLocalCoord(scrollPoint);

   if(mSc->mBounds.point.x + width > mBackground->mBounds.extent.x)
      if(width - mBounds.extent.x > 0)
         mSc->mBounds.point.x -= width - mBounds.extent.x;

   mSc->mBounds.extent.set(width-1, maxYdis);

   mSc->registerObject();
   mTl->registerObject();
   mBackground->registerObject();

   mSc->addObject( mTl );
   mBackground->addObject( mSc );

   // JDD - push the popup dialog to the topmost layer, so it's never under anything
   root->pushDialogControl(mBackground,99);

   if ( setScroll )
   {
      if ( mSelIndex )
         mTl->scrollCellVisible( Point2I(0, mSelIndex));
      else
         mTl->scrollCellVisible( Point2I( 0, 0 ) );
   }

   mTl->setFirstResponder();

   mInAction = true;
}

//------------------------------------------------------------------------------
void GuiPopUpMenuCtrl::addChildren()
{
   mTl = new GuiPopUpTextListCtrl(this);
   AssertFatal(mTl, "Failed to create the GuiPopUpTextListCtrl for the PopUpMenu");
   mTl->mProfile = mProfile;
   mTl->setField("noDuplicates", "false");

   mSc = new GuiScrollCtrl;
   AssertFatal(mSc, "Failed to create the GuiScrollCtrl for the PopUpMenu");
   mSc->mProfile = mProfile;
   mSc->setField("hScrollBar","AlwaysOff");
   mSc->setField("vScrollBar","dynamic");

   mBackground = new GuiPopUpBackgroundCtrl(this, mTl);
   AssertFatal(mBackground, "Failed to create the GuiBackgroundCtrl for the PopUpMenu");
}

//------------------------------------------------------------------------------
void GuiPopUpMenuCtrl::repositionPopup()
{
   if ( !mInAction || !mSc || !mTl )
      return;

   // I'm not concerned with this right now...
}

//------------------------------------------------------------------------------
void GuiPopUpMenuCtrl::reverseTextList()
{
   mTl->clear();
   for(S32 i=mEntries.size()-1; i >= 0; --i)
      mTl->addEntry(mEntries[i].id, mEntries[i].buf);

   // Don't lose the selected cell:
   if ( mSelIndex >= 0 )
      mTl->setSelectedCell( Point2I( 0, mEntries.size() - mSelIndex - 1 ) );

   mRevNum = mEntries.size() - 1;
}

//------------------------------------------------------------------------------
bool GuiPopUpMenuCtrl::getFontColor( ColorI &fontColor, S32 id, bool selected, bool mouseOver )
{
   U32 i;
   Entry* entry = NULL;
   for ( i = 0; i < mEntries.size(); i++ )
   {
      if ( mEntries[i].id == id )
      {
         entry = &mEntries[i];
         break;
      }
   }

   if ( !entry )
      return( false );

   if ( entry->scheme != 0 )
   {
      // Find the entry's color scheme:
      for ( i = 0; i < mSchemes.size(); i++ )
      {
         if ( mSchemes[i].id == entry->scheme )
         {
            fontColor = selected ? mSchemes[i].fontColorSEL : mouseOver ? mSchemes[i].fontColorHL : mSchemes[i].fontColor;
            return( true );
         }
      }
   }

   // Default color scheme...
   fontColor = selected ? mProfile->mFontColorSEL : mouseOver ? mProfile->mFontColorHL : mProfile->mFontColor;

   return( true );
}

//------------------------------------------------------------------------------
void GuiPopUpMenuCtrl::onMouseDown(const GuiEvent &event)
{
   event;
   onAction();
}

//------------------------------------------------------------------------------
void GuiPopUpMenuCtrl::onMouseUp(const GuiEvent &event)
{
   event;
}

//------------------------------------------------------------------------------
void GuiPopUpMenuCtrl::setupAutoScroll(const GuiEvent &event)
{
   GuiControl *parent = getParent();
   if (! parent) return;

   Point2I mousePt = mSc->globalToLocalCoord(event.mousePoint);

   mEventSave = event;

   if(mLastYvalue != mousePt.y)
   {
      mScrollDir = GuiScrollCtrl::None;
      if(mousePt.y > mSc->mBounds.extent.y || mousePt.y < 0)
      {
         S32 topOrBottom = (mousePt.y > mSc->mBounds.extent.y) ? 1 : 0;
         mSc->scrollTo(0, topOrBottom);
         return;
      }

      F32 percent = (F32)mousePt.y / (F32)mSc->mBounds.extent.y;
      if(percent > 0.7f && mousePt.y > mLastYvalue)
      {
         mIncValue = percent - 0.5f;
         mScrollDir = GuiScrollCtrl::DownArrow;
      }
      else if(percent < 0.3f && mousePt.y < mLastYvalue)
      {
         mIncValue = 0.5f - percent;
         mScrollDir = GuiScrollCtrl::UpArrow;
      }
      mLastYvalue = mousePt.y;
   }
}

//------------------------------------------------------------------------------
void GuiPopUpMenuCtrl::autoScroll()
{
   mScrollCount += mIncValue;

   while(mScrollCount > 1)
   {
      mSc->autoScroll(mScrollDir);
      mScrollCount -= 1;
   }
   mTl->onMouseMove(mEventSave);
}

//------------------------------------------------------------------------------
void GuiPopUpMenuCtrl::replaceText(S32 boolVal)
{
   mReplaceText = boolVal;
}
// EOF //

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -