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

📄 guicanvas.cc

📁 五行MMORPG引擎系统V1.0
💻 CC
📖 第 1 页 / 共 3 页
字号:
      GuiControl *ctrl = static_cast<GuiControl *>(*i);
      ctrl->buildAcceleratorMap();

      if (ctrl->mProfile->mModal)
         break;
   }
#endif
   refreshMouseControl();
}

GuiControl *GuiCanvas::getContentControl()
{
   if(size() > 0)
      return (GuiControl *) first();
   return NULL;
}


void GuiCanvas::pushDialogControl(GuiControl *gui, S32 layer)
{
   //add the gui
   gui->mLayer = layer;

	//IME
	//保证输入法在reorder时永远在最顶上
	if(m_pIMEControl  && m_pIMEControl->mLayer <= layer)
	{
		m_pIMEControl->mLayer = layer + 1;
	}


   // GuiControl::addObject wakes the object
   bool wakedGui = !gui->isAwake();
   addObject(gui);

   //reorder it to the correct layer
   iterator i;
   for (i = begin(); i != end(); i++)
   {
      GuiControl *ctrl = static_cast<GuiControl*>(*i);
      if (ctrl->mLayer > gui->mLayer)
      {
         reOrder(gui, ctrl);
         break;
      }
   }

	//IME
   //需要在重排后调用
   UpdateTopControl();

   //call the dialog push method
   gui->onDialogPush();

   //find the top most dialog
   GuiControl *topCtrl = m_pTopControl ;//static_cast<GuiControl *>(last());  //IME

   //save the old
   GuiControl *oldResponder = mFirstResponder;

   //find the first responder
   mFirstResponder = gui->findFirstTabable();

   if (oldResponder && oldResponder != mFirstResponder)
      oldResponder->onLoseFirstResponder();

   // call the 'onWake' method?
   //if(wakedGui)
   //   Con::executef(gui, 1, "onWake");

   //refresh the entire gui
   resetUpdateRegions();

   //rebuild the accelerator map
#ifdef TGE_RPG
	addAccelMaps(gui);
#else
   mAcceleratorMap.clear();

   if (size() > 0)
   {
      GuiControl *ctrl = m_pTopControl ;//static_cast<GuiControl *>(last());  //IME
      ctrl->buildAcceleratorMap();
   }
#endif
   refreshMouseControl();
}

void GuiCanvas::popDialogControl(GuiControl *gui)
{
   if (size() < 1)
      return;

   //first, find the dialog, and call the "onDialogPop()" method
   GuiControl *ctrl = NULL;
   if (gui)
   {
      //make sure the gui really exists on the stack
      iterator i;
      bool found = false;
      for(i = begin(); i != end(); i++)
      {
         GuiControl *check = static_cast<GuiControl *>(*i);
         if (check == gui)
         {
            ctrl = check;
            found = true;
         }
      }
      if (! found)
         return;
   }
   else
      ctrl = m_pTopControl ;//static_cast<GuiControl *>(last());  //IME

   //call the "on pop" function
   ctrl->onDialogPop();

   // sleep the object
   bool didSleep = ctrl->isAwake();

   //now pop the last child (will sleep if awake)
   removeObject(ctrl);
   UpdateTopControl();//IME

   // Save the old responder:
   GuiControl *oldResponder = mFirstResponder;

   Sim::getGuiGroup()->addObject(ctrl);

   if (size() > 0)
   {
      GuiControl *ctrl = m_pTopControl ;//static_cast<GuiControl *>(last()); //IME
      mFirstResponder = ctrl->mFirstResponder;
   }
   else
   {
      mFirstResponder = NULL;
   }

   if (oldResponder && oldResponder != mFirstResponder)
      oldResponder->onLoseFirstResponder();

   //refresh the entire gui
   resetUpdateRegions();

#ifdef TGE_RPG
	removeAccelMap(gui);
#else

   //rebuild the accelerator map
   mAcceleratorMap.clear();
   if (size() > 0)
   {
      GuiControl *ctrl = m_pTopControl ;//static_cast<GuiControl *>(last()); //IME
      ctrl->buildAcceleratorMap();
   }
#endif
   refreshMouseControl();
}

void GuiCanvas::popDialogControl(S32 layer)
{
   if (size() < 1)
      return;

   GuiControl *ctrl = NULL;
   iterator i = end(); // find in z order (last to first)
   while (i != begin())
   {
      i--;
      ctrl = static_cast<GuiControl*>(*i);
      if (ctrl->mLayer == layer)
         break;
   }
   if (ctrl)
      popDialogControl(ctrl);
}

void GuiCanvas::mouseLock(GuiControl *lockingControl)
{
   if (bool(mMouseCapturedControl))
      return;
   mMouseCapturedControl = lockingControl;
   if(mMouseControl && mMouseControl != mMouseCapturedControl)
   {
      GuiEvent evt;
      evt.mousePoint.x = S32(cursorPt.x);
      evt.mousePoint.y = S32(cursorPt.y);

      mMouseControl->onMouseLeave(evt);
   }
}

void GuiCanvas::mouseUnlock(GuiControl *lockingControl)
{
   if (static_cast<GuiControl*>(mMouseCapturedControl) != lockingControl)
      return;

   GuiEvent evt;
   evt.mousePoint.x = S32(cursorPt.x);
   evt.mousePoint.y = S32(cursorPt.y);

   GuiControl * controlHit = findHitControl(evt.mousePoint);
   if(controlHit != mMouseCapturedControl)
   {
      mMouseControl = controlHit;
      mMouseControlClicked = false;
      if(bool(mMouseControl))
         mMouseControl->onMouseEnter(evt);
   }
   mMouseCapturedControl = NULL;
}

void GuiCanvas::paint()
{
   resetUpdateRegions();

   // inhibit explicit refreshes in the case we're swapped out
   if (gDGLRender)
      renderFrame(false);
}

void GuiCanvas::renderFrame(bool preRenderOnly, bool bufferSwap /* = true */)
{
   PROFILE_START(CanvasPreRender);
   if(mRenderFront)
      glDrawBuffer(GL_FRONT);
   else
      glDrawBuffer(GL_BACK);


   // Render all RTT Gui's HERE
   //DynamicTexture::updateGuiTextures();

   Point2I size = Platform::getWindowSize();

   if(size.x == 0 || size.y == 0)
      return;

   RectI screenRect(0, 0, size.x, size.y);
   mBounds = screenRect;

   //all bottom level controls should be the same dimensions as the canvas
   //this is necessary for passing mouse events accurately
   iterator i;
   for (i = begin(); i != end(); i++)
   {
      AssertFatal(static_cast<GuiControl*>((*i))->isAwake(), "GuiCanvas::renderFrame: ctrl is not awake");
      GuiControl *ctrl = static_cast<GuiControl*>(*i);
      Point2I ext = ctrl->getExtent();
      Point2I pos = ctrl->getPosition();

#ifdef TGE_RPG
		/*ctrl->m_bAutoSize*/
      if(ctrl->mProfile->mModal &&(  pos != screenRect.point || ext != screenRect.extent))
      {
         ctrl->resize(screenRect.point, screenRect.extent);
         resetUpdateRegions();
      }
#else
      if(pos != screenRect.point || ext != screenRect.extent)
      {
         ctrl->resize(screenRect.point, screenRect.extent);
         resetUpdateRegions();
      }
#endif
   }

   //preRender (recursive) all controls
   preRender();
   PROFILE_END();
   if(preRenderOnly)
      return;

   // for now, just always reset the update regions - this is a
   // fix for FSAA on ATI cards
   resetUpdateRegions();

   // finish the gl render so we don't get too far ahead of ourselves
#if defined(TORQUE_OS_WIN32)
   PROFILE_START(glFinish);
   glFinish();
   PROFILE_END();
#endif
   //draw the mouse, but not using tags...
   PROFILE_START(CanvasRenderControls);

   GuiCursor *mouseCursor = NULL;
   bool cursorVisible = true;

#ifdef TGE_RPG
	if(m_pDragCaret)
		mouseCursor = m_pDragCaret;
	else
#endif
   if(bool(mMouseCapturedControl))
      mMouseCapturedControl->getCursor(mouseCursor, cursorVisible, mLastEvent);
   else if(bool(mMouseControl))
      mMouseControl->getCursor(mouseCursor, cursorVisible, mLastEvent);

   Point2I cursorPos((S32)cursorPt.x, (S32)cursorPt.y);
   if(!mouseCursor)
      mouseCursor = defaultCursor;

   if(lastCursorON && lastCursor)
   {
      Point2I spot = lastCursor->getHotSpot();
      Point2I cext = lastCursor->getExtent();
      Point2I pos = lastCursorPt - spot;
      addUpdateRegion(pos - Point2I(2, 2), Point2I(cext.x + 4, cext.y + 4));
   }
   if(cursorVisible && mouseCursor)
   {
      Point2I spot = mouseCursor->getHotSpot();
      Point2I cext = mouseCursor->getExtent();
      Point2I pos = cursorPos - spot;

      addUpdateRegion(pos - Point2I(2, 2), Point2I(cext.x + 4, cext.y + 4));
   }

	lastCursorON = cursorVisible;
	lastCursor = mouseCursor;
	lastCursorPt = cursorPos;

   RectI updateUnion;
   buildUpdateUnion(&updateUnion);
   if (updateUnion.intersect(screenRect))
   {
      //fill in with black first
      //glClearColor(0, 0, 0, 0);
      //glClear(GL_COLOR_BUFFER_BIT);

      //render the dialogs
      iterator i;
      for(i = begin(); i != end(); i++)
      {
         GuiControl *contentCtrl = static_cast<GuiControl*>(*i);
         dglSetClipRect(updateUnion);
         glDisable( GL_CULL_FACE );
         contentCtrl->onRender(contentCtrl->getPosition(), updateUnion);
      }

	  // Tooltip resource
	  if(bool(mMouseControl))
	  {
         U32 curTime = Platform::getRealMilliseconds();
         if(hoverControl == mMouseControl)
		 {
            if(hoverPositionSet || (curTime - hoverControlStart) >= 1000 || (curTime - hoverLeftControlTime) <= 1000)
			{
               if(!hoverPositionSet)
			   {
                  hoverPosition = cursorPos;
			   }
               hoverPositionSet = mMouseControl->renderTooltip(hoverPosition);
			}

         } else
		 {
            if(hoverPositionSet)
			{
               hoverLeftControlTime = curTime;
			   hoverPositionSet = false;
			}
            hoverControl = mMouseControl;
			hoverControlStart = curTime;
		 }
	  }
	  //end tooltip

      dglSetClipRect(updateUnion);

      //temp draw the mouse
      if (cursorON && mShowCursor && !mouseCursor)
      {
         glColor4ub(255, 0, 0, 255);
         glRecti((S32)cursorPt.x, (S32)cursorPt.y, (S32)(cursorPt.x + 2), (S32)(cursorPt.y + 2));
      }

      //DEBUG
      //draw the help ctrl
      //if (helpCtrl)
      //{
      //   helpCtrl->render(srf);
      //}

      if (cursorON && mouseCursor && mShowCursor)
      {
         Point2I pos((S32)cursorPt.x, (S32)cursorPt.y);
         Point2I spot = mouseCursor->getHotSpot();

         pos -= spot;
         mouseCursor->render(pos);
      }
   }
   PROFILE_END();

   // Render all RTT end of frame updates HERE
   //DynamicTexture::updateScreenTextures();
   //DynamicTexture::updateEndOfFrameTextures();

   if( bufferSwap )
      swapBuffers();
}

void GuiCanvas::swapBuffers()
{
   PROFILE_START(SwapBuffers);
   //flip the surface
   if(!mRenderFront)
      Video::swapBuffers();
   PROFILE_END();
}

void GuiCanvas::buildUpdateUnion(RectI *updateUnion)
{
   *updateUnion = mOldUpdateRects[0];

   //the update region should encompass the oldUpdateRects, and the curUpdateRect
   Point2I upperL;
   Point2I lowerR;

   upperL.x = getMin(mOldUpdateRects[0].point.x, mOldUpdateRects[1].point.x);
   upperL.x = getMin(upperL.x, mCurUpdateRect.point.x);

   upperL.y = getMin(mOldUpdateRects[0].point.y, mOldUpdateRects[1].point.y);
   upperL.y = getMin(upperL.y, mCurUpdateRect.point.y);

   lowerR.x = getMax(mOldUpdateRects[0].point.x + mOldUpdateRects[0].extent.x, mOldUpdateRects[1].point.x + mOldUpdateRects[1].extent.x);
   lowerR.x = getMax(lowerR.x, mCurUpdateRect.point.x + mCurUpdateRect.extent.x);

   lowerR.y = getMax(mOldUpdateRects[0].point.y + mOldUpdateRects[0].extent.y, mOldUpdateRects[1].point.y + mOldUpdateRects[1].extent.y);
   lowerR.y = getMax(lowerR.y, mCurUpdateRect.point.y + mCurUpdateRect.extent.y);

   updateUnion->point = upperL;
   updateUnion->extent = lowerR - upperL;

   //shift the oldUpdateRects
   mOldUpdateRects[0] = mOldUpdateRects[1];
   mOldUpdateRects[1] = mCurUpdateRect;

   mCurUpdateRect.point.set(0,0);
   mCurUpdateRect.extent.set(0,0);
}

void GuiCanvas::addUpdateRegion(Point2I pos, Point2I ext)
{
   if(mCurUpdateRect.extent.x == 0)
   {
      mCurUpdateRect.point = pos;
      mCurUpdateRect.extent = ext;
   }
   else
   {
      Point2I upperL;
      upperL.x = getMin(mCurUpdateRect.point.x, pos.x);
      upperL.y = getMin(mCurUpdateRect.point.y, pos.y);
      Point2I lowerR;
      lowerR.x = getMax(mCurUpdateRect.point.x + mCurUpdateRect.extent.x, pos.x + ext.x);
      lowerR.y = getMax(mCurUpdateRect.point.y + mCurUpdateRect.extent.y, pos.y + ext.y);
      mCurUpdateRect.point = upperL;
      mCurUpdateRect.extent = lowerR - upperL;
   }
}

void GuiCanvas::resetUpdateRegions()
{
   //DEBUG - get surface width and height
   mOldUpdateRects[0].set(mBounds.point, mBounds.extent);
   mOldUpdateRects[1] = mOldUpdateRects[0];
   mCurUpdateRect = mOldUpdateRects[0];
}

void GuiCanvas::setFirstResponder( GuiControl* newResponder )
{
	GuiControl* oldResponder = mFirstResponder;
	Parent::setFirstResponder( newResponder );

	if ( oldResponder && ( oldResponder != mFirstResponder ) )
		oldResponder->onLoseFirstResponder();
}

#ifdef TGE_RPG


void GuiCanvas::addAccelMaps(GuiControl* pOwner)
{
	if(pOwner == NULL)
		return;

	m_arAccelMapOwners.increment();
	m_arAccelMapOwners.last().pOwner = pOwner;
	m_pAccelMap = &m_arAccelMapOwners.last().accelMap;
	constructInPlace(m_pAccelMap);

   for(iterator i = pOwner->end(); i != pOwner->begin() ; )
   {
      i--;
      GuiControl *ctrl = static_cast<GuiControl *>(*i);
      ctrl->buildAcceleratorMap();
#ifndef TGE_RPG
      if (ctrl->mProfile->mModal)
         break;
#endif
   }

	//Con::printf("   @@@ addAccelMaps %s" ,pOwner->getName());

}


void GuiCanvas::removeAllAccelMaps()
{
	//Con::printf("   @@@ removeAllAccelMaps");
	for(U32 n=0; n<m_arAccelMapOwners.size(); n++)
	{
		m_arAccelMapOwners[n].accelMap.clear();
		destructInPlace(&m_arAccelMapOwners[n].accelMap);
	}
	m_arAccelMapOwners.clear();
	m_pAccelMap = NULL;
}

void GuiCanvas::removeAccelMap(GuiControl* pOwner)
{
	for(S32 n=m_arAccelMapOwners.size()-1; n>= 0; n--)
	{
		if(m_arAccelMapOwners[n].pOwner == pOwner)
		{
			if(m_pAccelMap == &m_arAccelMapOwners[n].accelMap)
				m_pAccelMap = NULL;
			m_arAccelMapOwners[n].accelMap.clear();
			destructInPlace(&m_arAccelMapOwners[n].accelMap);
			m_arAccelMapOwners.erase(n);
			break;
		}
	}
	if(m_pAccelMap == NULL && m_arAccelMapOwners.size())
		m_pAccelMap = &m_arAccelMapOwners.last().accelMap;

	//if(pOwner)
		//Con::printf("   @@@ removeAccelMap %s" ,pOwner->getName());

}


bool GuiCanvas::processAccelKey(const InputEvent *event,U32 eventModifier, AccKeyTypes type)
{
	if(event == NULL)
		return false;

	U32 i;
	S32 n;
	Vector<AccKeyMap>*	pMap;

	for(n=m_arAccelMapOwners.size()-1; n>= 0; n--)
	{
		Vector<AccKeyMap>& accMap = m_arAccelMapOwners[n].accelMap;

		for(i = 0; i < accMap.size(); i++)
		{
			if ((U32)accMap[i].keyCode == (U32)event->objInst && (U32)accMap[i].modifier == eventModifier)
			{
				switch(type)
				{
				case AKT_PRESS:
					accMap[i].ctrl->acceleratorKeyPress(accMap[i].index);
					break;
				case AKT_RELEASE:
					accMap[i].ctrl->acceleratorKeyRelease(accMap[i].index);
					break;
				default:
					return false;
				}
				return true;
			}
		}//for
	}//for
	return false;
}

void GuiCanvas::initAccelMap()
{
	addAccelMaps(this);
}


#endif

⌨️ 快捷键说明

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