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

📄 guicanvas.cc

📁 五行MMORPG引擎系统V1.0
💻 CC
📖 第 1 页 / 共 3 页
字号:
//-----------------------------------------------------------------------------
// Torque Game Engine
// Copyright (C) GarageGames.com, Inc.
//-----------------------------------------------------------------------------

#include "console/console.h"
#include "platform/profiler.h"
#include "dgl/dgl.h"
#include "platform/event.h"
#include "platform/platform.h"
#include "platform/platformVideo.h"
#include "gui/core/guiTypes.h"
#include "gui/core/guiControl.h"
#include "gui/core/guiCanvas.h"
#include "dgl/gDynamicTexture.h"
#include "gui/controls/guiCellButtonCtrl.h"

extern bool gDGLRender;

#ifdef TGE_RPG
#define	MOUSE_DRAG_DIFF 5*5
#endif

// We formerly kept all the GUI related IMPLEMENT_CONOBJECT macros here.
// Now they belong with their implementations. -- BJG

IMPLEMENT_CONOBJECT(GuiCanvas);

GuiCanvas *Canvas = NULL;

ConsoleMethod( GuiCanvas, getContent, S32, 2, 2, "Get the GuiControl which is being used as the content.")
{
   GuiControl *ctrl = object->getContentControl();
   if(ctrl)
      return ctrl->getId();
   return -1;
}

#ifdef TGE_RPG
ConsoleMethod( GuiCanvas, pushPanel, bool, 3, 3, "pushPanel(ctrl) 把控件当作面板追加到当前content子集中")
{
	object;
	argc;

   GuiControl *ctrl = object->getContentControl();
   if(ctrl)
	{
		GuiControl *gui = NULL;
		if(argv[2][0])
		{
			if (Sim::findObject(argv[2], gui))
			{
				ctrl->addObject(gui);
				return true;
			}
		}
	}
   return false;
}

ConsoleMethod( GuiCanvas, popPanel, bool, 3, 3, "pushPanel(ctrl) 把控件当作面板从当前content子集中去掉")
{
	object;
	argc;

   GuiControl *ctrl = object->getContentControl();
   if(ctrl)
	{

		GuiControl *gui = NULL;
		if(argv[2][0])
		{
			if (Sim::findObject(argv[2], gui))
			{
				ctrl->removeObject(gui);
				return true;
			}
		}
	}
   return false;
}

#endif


ConsoleMethod( GuiCanvas, setContent, void, 3, 3, "(GuiControl ctrl)"
              "Set the content of the canvas.")
{
   object;
   argc;

   GuiControl *gui = NULL;
   if(argv[2][0])
   {
      if (!Sim::findObject(argv[2], gui))
      {
         Con::printf("%s(): Invalid control: %s", argv[0], argv[2]);
         return;
      }
   }

   //set the new content control
   Canvas->setContentControl(gui);
}

ConsoleMethod( GuiCanvas, pushDialog, void, 3, 4, "(GuiControl ctrl, int layer)")
{
   object;

   GuiControl *gui;

   if (!	Sim::findObject(argv[2], gui))
   {
      Con::printf("%s(): Invalid control: %s", argv[0], argv[2]);
      return;
   }

   //find the layer
   S32 layer = 0;
   if (argc == 4)
      layer = dAtoi(argv[3]);

   //set the new content control
   Canvas->pushDialogControl(gui, layer);
}

ConsoleMethod( GuiCanvas, popDialog, void, 2, 3, "(GuiControl ctrl=NULL)")
{
   object;

   GuiControl *gui;
   if (argc == 3)
   {
      if (!Sim::findObject(argv[2], gui))
      {
         Con::printf("%s(): Invalid control: %s", argv[0], argv[2]);
         return;
      }
   }

   if (gui)
      Canvas->popDialogControl(gui);
   else
      Canvas->popDialogControl();
}

ConsoleMethod( GuiCanvas, popLayer, void, 2, 3, "(int layer)")
{
   object;

   S32 layer = 0;
   if (argc == 3)
      layer = dAtoi(argv[2]);

   Canvas->popDialogControl(layer);
}

ConsoleMethod(GuiCanvas, cursorOn, void, 2, 2, "")
{
   object;
   argc;
   argv;
   Canvas->setCursorON(true);
}

ConsoleMethod(GuiCanvas, cursorOff, void, 2, 2, "")
{
   object;
   argc;
   argv;
   Canvas->setCursorON(false);
}

ConsoleMethod( GuiCanvas, setCursor, void, 3, 3, "(bool visible)")
{
   object;
   argc;

   GuiCursor *curs = NULL;
   if(argv[2][0])
   {
      if(!Sim::findObject(argv[2], curs))
      {
         Con::printf("%s is not a valid cursor.", argv[2]);
         return;
      }
   }
   Canvas->setCursor(curs);
}

ConsoleMethod( GuiCanvas, renderFront, void, 3, 3, "(bool enable)")
{
   Canvas->setRenderFront(dAtob(argv[2]));
}

ConsoleMethod( GuiCanvas, showCursor, void, 2, 2, "")
{
   Canvas->showCursor(true);
}

ConsoleMethod( GuiCanvas, hideCursor, void, 2, 2, "")
{
   Canvas->showCursor(false);
}

ConsoleMethod( GuiCanvas, isCursorOn, bool, 2, 2, "")
{
   return Canvas->isCursorON();
}

ConsoleMethod( GuiCanvas, repaint, void, 2, 2, "Force canvas to redraw.")
{
   Canvas->paint();
}

ConsoleMethod( GuiCanvas, reset, void, 2, 2, "Reset the update regions for the canvas.")
{
   Canvas->resetUpdateRegions();
}

ConsoleMethod( GuiCanvas, getCursorPos, const char*, 2, 2, "Get the current position of the cursor.")
{
   Point2I pos = Canvas->getCursorPos();
   char * ret = Con::getReturnBuffer(32);
   dSprintf(ret, 32, "%d %d", pos.x, pos.y);
   return(ret);
}

ConsoleMethod( GuiCanvas, setCursorPos, void, 3, 4, "(Point2I pos)")
{
   Point2I pos(0,0);

   if(argc == 4)
      pos.set(dAtoi(argv[2]), dAtoi(argv[3]));
   else
      dSscanf(argv[2], "%d %d", &pos.x, &pos.y);

   Canvas->setCursorPos(pos);
}

ConsoleFunction( createCanvas, bool, 2, 2, "(string windowTitle)"
                "Create the game window/canvas, with the specified window title.")
{
   AssertISV(!Canvas, "CreateCanvas: canvas has already been instantiated");

#if !defined(TORQUE_OS_MAC) // macs can only run one instance in general.
#if !defined(TORQUE_DEBUG) && !defined(INTERNAL_RELEASE)
   if(!Platform::excludeOtherInstances("TorqueTest"))
      return false;
#endif
#endif
   Platform::initWindow(Point2I(800, 600), argv[1]);

   // create the canvas, and add it to the manager
   Canvas = new GuiCanvas();
   Canvas->registerObject("Canvas"); // automatically adds to GuiGroup

#ifdef TGE_RPG
	Canvas->initAccelMap();
#endif
   return true;
}

GuiCanvas::GuiCanvas()
{
#ifdef TGE_RPG
   mBounds.set(0, 0, 800, 600);
#else
   mBounds.set(0, 0, 640, 480);
#endif
   mAwake = true;
   mPixelsPerMickey = 1.0f;
   lastCursorON = false;
   cursorON    = true;
   mShowCursor = true;
   rLastFrameTime = 0.0f;

   mMouseCapturedControl = NULL;
   mMouseControl = NULL;
   mMouseControlClicked = false;
   mMouseButtonDown = false;
   mMouseRightButtonDown = false;
   mMouseMiddleButtonDown = false;
#ifdef TGE_RPG
	mMouseButtonDrag = false;
   mPointDragStart.set(0,0);
#endif

   lastCursor = NULL;
   lastCursorPt.set(0,0);
   cursorPt.set(0,0);

	mLastMouseClickCount = 0;
	mLastMouseDownTime = 0;
	mPrevMouseTime = 0;
	defaultCursor = NULL;

   mRenderFront = false;

   hoverControlStart = Platform::getRealMilliseconds();
   hoverControl = NULL;
   hoverPosition = getCursorPos();
   hoverPositionSet = false;
   hoverLeftControlTime = 0;

	m_pIMEControl = NULL;
	m_pTopControl = NULL;

#ifdef TGE_RPG
   m_dblClkCursorPt.set(0.,0.);
	m_pDragCaret	= NULL;

	m_pAccelMap		= NULL;

	SimObject::setModStaticFields(true);
	SimObject::setModDynamicFields(true);
#endif

}

GuiCanvas::~GuiCanvas()
{
   if(Canvas == this)
      Canvas = 0;
}

//------------------------------------------------------------------------------
void GuiCanvas::setCursor(GuiCursor *curs)
{
   defaultCursor = curs;
}

void GuiCanvas::setCursorON(bool onOff)
{
   cursorON = onOff;
   if(!cursorON)
      mMouseControl = NULL;
}


#ifdef TGE_RPG
GuiCursor	*GuiCanvas::createDragCursor(GuiCellButtonCtrl	*pDragCell)
{
	static GuiCursor sDragCursor;
	sDragCursor.setDragCell(pDragCell);

	m_pDragCaret = &sDragCursor;
	return m_pDragCaret;
}

void GuiCanvas::clearDragCursor()
{
	if(m_pDragCaret)
		m_pDragCaret->setDragCell(0);
	m_pDragCaret = NULL;
}

#endif

void GuiCanvas::addAcceleratorKey(GuiControl *ctrl, U32 index, U32 keyCode, U32 modifier)
{
   if (keyCode > 0 && ctrl)
   {
      AccKeyMap newMap;
      newMap.ctrl = ctrl;
      newMap.index = index;
      newMap.keyCode = keyCode;
      newMap.modifier = modifier;

#ifdef TGE_RPG
		AssertFatal(m_pAccelMap,"需要先创建AccelMap实例");
		if(m_pAccelMap)
			m_pAccelMap->push_back(newMap);
#else
      mAcceleratorMap.push_back(newMap);
#endif
   }
}

void GuiCanvas::tabNext(void)
{
   GuiControl *ctrl = m_pTopControl;//static_cast<GuiControl *>(last()); //IME
   if (ctrl)
   {
      //save the old
      GuiControl *oldResponder = mFirstResponder;

		GuiControl* newResponder = ctrl->findNextTabable(mFirstResponder);
      if ( !newResponder )
         newResponder = ctrl->findFirstTabable();

		if ( newResponder && newResponder != oldResponder )
		{
			newResponder->setFirstResponder();

      	if ( oldResponder )
         	oldResponder->onLoseFirstResponder();
		}
   }
}

void GuiCanvas::tabPrev(void)
{
   GuiControl *ctrl = m_pTopControl ;//static_cast<GuiControl *>(last()); //IME
   if (ctrl)
   {
      //save the old
      GuiControl *oldResponder = mFirstResponder;

		GuiControl* newResponder = ctrl->findPrevTabable(mFirstResponder);
		if ( !newResponder )
         newResponder = ctrl->findLastTabable();

		if ( newResponder && newResponder != oldResponder )
		{
			newResponder->setFirstResponder();
	
	      if ( oldResponder )
	         oldResponder->onLoseFirstResponder();
		}
   }
}


void GuiCanvas::processMouseMoveEvent(const MouseMoveEvent *event)
{
   if( cursorON )
   {
		//copy the modifier into the new event
		mLastEvent.modifier = event->modifier;

		Point2F pt(cursorPt.x, cursorPt.y);

		pt.x += ( F32(event->xPos - cursorPt.x) * mPixelsPerMickey);
		cursorPt.x = getMax(0, getMin((S32)pt.x, mBounds.extent.x - 1));

		pt.y += ( F32(event->yPos - cursorPt.y) * mPixelsPerMickey);
		cursorPt.y = getMax(0, getMin((S32)pt.y, mBounds.extent.y - 1));

		mLastEvent.mousePoint.x = S32(cursorPt.x);
		mLastEvent.mousePoint.y = S32(cursorPt.y);

#ifdef TGE_RPG
		if (mMouseButtonDrag)
		{
			if (mMouseButtonDown)
				rootMouseDragged(mLastEvent);
			else if (mMouseRightButtonDown)
				rootRightMouseDragged(mLastEvent);
			else if(mMouseMiddleButtonDown)
				rootMiddleMouseDragged(mLastEvent);
			else
				rootMouseMove(mLastEvent);
		}
		else
		{
			rootMouseMove(mLastEvent);
		}
#else
		if (mMouseButtonDown)
			rootMouseDragged(mLastEvent);
		else if (mMouseRightButtonDown)
			rootRightMouseDragged(mLastEvent);
		else if(mMouseMiddleButtonDown)
			rootMiddleMouseDragged(mLastEvent);
		else
			rootMouseMove(mLastEvent);
#endif
	}
}

bool GuiCanvas::processInputEvent(const InputEvent *event)
{
#ifdef TGE_RPG
		AssertFatal(m_pAccelMap,"需要先创建AccelMap实例");
#endif
	// First call the general input handler (on the extremely off-chance that it will be handled):
	if ( mFirstResponder )
   {
      if ( mFirstResponder->onInputEvent( *event ) )
		   return( true );
   }

   if(event->deviceType == KeyboardDeviceType)
   {
      mLastEvent.ascii = event->ascii;
      mLastEvent.modifier = event->modifier;
      mLastEvent.keyCode = event->objInst;

      U32 eventModifier = event->modifier;
      if(eventModifier & SI_SHIFT)
         eventModifier |= SI_SHIFT;
      if(eventModifier & SI_CTRL)
         eventModifier |= SI_CTRL;
      if(eventModifier & SI_ALT)
         eventModifier |= SI_ALT;

      if (event->action == SI_MAKE)
      {
         //see if we should tab next/prev

         //see if we should now pass the event to the first responder
         if (mFirstResponder)
         {
            if(mFirstResponder->onKeyDown(mLastEvent))
               return true;
         }

         if ( isCursorON() && ( event->objInst == KEY_TAB ) )
         {
            if (size() > 0)
            {
               if (event->modifier & SI_SHIFT)
               {
                  tabPrev();
                  return true;
               }
               else if (event->modifier == 0)
               {
                  tabNext();
                  return true;
               }
            }
         }

         //if not handled, search for an accelerator
#ifdef TGE_RPG
			if(processAccelKey(event,eventModifier,AKT_PRESS))
				return true;
#else
         for (U32 i = 0; i < mAcceleratorMap.size(); i++)
         {
            if ((U32)mAcceleratorMap[i].keyCode == (U32)event->objInst && (U32)mAcceleratorMap[i].modifier == eventModifier)
            {
               mAcceleratorMap[i].ctrl->acceleratorKeyPress(mAcceleratorMap[i].index);
               return true;
            }
         }
#endif
      }
      else if(event->action == SI_BREAK)
      {
         if(mFirstResponder)
            if(mFirstResponder->onKeyUp(mLastEvent))
               return true;

         //see if there's an accelerator
#ifdef TGE_RPG
			if(processAccelKey(event,eventModifier,AKT_RELEASE))
				return true;
#else
         for (U32 i = 0; i < mAcceleratorMap.size(); i++)
         {
            if ((U32)mAcceleratorMap[i].keyCode == (U32)event->objInst && (U32)mAcceleratorMap[i].modifier == eventModifier)
            {
               mAcceleratorMap[i].ctrl->acceleratorKeyRelease(mAcceleratorMap[i].index);
               return true;
            }
         }
#endif
      }
      else if(event->action == SI_REPEAT)
      {

         //if not handled, search for an accelerator
#ifdef TGE_RPG
			if(processAccelKey(event,eventModifier,AKT_PRESS))
				return true;
#else
         for (U32 i = 0; i < mAcceleratorMap.size(); i++)
         {
            if ((U32)mAcceleratorMap[i].keyCode == (U32)event->objInst && (U32)mAcceleratorMap[i].modifier == eventModifier)
            {
               mAcceleratorMap[i].ctrl->acceleratorKeyPress(mAcceleratorMap[i].index);
               return true;
            }
         }
#endif
         if(mFirstResponder)
            mFirstResponder->onKeyRepeat(mLastEvent);
         return true;
      }
   }
   else if(event->deviceType == MouseDeviceType && cursorON)
   {
      //copy the modifier into the new event
      mLastEvent.modifier = event->modifier;

      if(event->objType == SI_XAXIS || event->objType == SI_YAXIS)
      {
         bool moved = false;
         Point2I oldpt((S32)cursorPt.x, (S32)cursorPt.y);

⌨️ 快捷键说明

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