mirror of
https://github.com/vcmi/vcmi.git
synced 2025-06-15 00:05:02 +02:00
Refactor: unified logic for notyfing CIntObjs about left/right mouse click events;
Added support for middle-click;
This commit is contained in:
@ -292,6 +292,4 @@
|
|||||||
</ProjectReference>
|
</ProjectReference>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||||
<ImportGroup Label="ExtensionTargets">
|
|
||||||
</ImportGroup>
|
|
||||||
</Project>
|
</Project>
|
@ -109,17 +109,10 @@
|
|||||||
<Filter>gui</Filter>
|
<Filter>gui</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="..\CCallback.cpp" />
|
<ClCompile Include="..\CCallback.cpp" />
|
||||||
</ItemGroup>
|
<ClCompile Include="SDLRWwrapper.cpp" />
|
||||||
<ItemGroup>
|
|
||||||
<ClCompile Include="CQuestLog.cpp">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ResourceCompile Include="VCMI_client.rc" />
|
<ResourceCompile Include="VCMI_client.rc" />
|
||||||
<ClInclude Include="CQuestLog.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Include="vcmi.ico" />
|
<None Include="vcmi.ico" />
|
||||||
@ -254,5 +247,6 @@
|
|||||||
<Filter>gui</Filter>
|
<Filter>gui</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="..\CCallback.h" />
|
<ClInclude Include="..\CCallback.h" />
|
||||||
|
<ClInclude Include="SDLRWwrapper.h" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
@ -60,6 +60,7 @@ void CGuiHandler::processLists(const ui16 activityFlag, std::function<void (std:
|
|||||||
{
|
{
|
||||||
processList(CIntObject::LCLICK,activityFlag,&lclickable,cb);
|
processList(CIntObject::LCLICK,activityFlag,&lclickable,cb);
|
||||||
processList(CIntObject::RCLICK,activityFlag,&rclickable,cb);
|
processList(CIntObject::RCLICK,activityFlag,&rclickable,cb);
|
||||||
|
processList(CIntObject::MCLICK,activityFlag,&mclickable,cb);
|
||||||
processList(CIntObject::HOVER,activityFlag,&hoverable,cb);
|
processList(CIntObject::HOVER,activityFlag,&hoverable,cb);
|
||||||
processList(CIntObject::MOVE,activityFlag,&motioninterested,cb);
|
processList(CIntObject::MOVE,activityFlag,&motioninterested,cb);
|
||||||
processList(CIntObject::KEYBOARD,activityFlag,&keyinterested,cb);
|
processList(CIntObject::KEYBOARD,activityFlag,&keyinterested,cb);
|
||||||
@ -260,18 +261,18 @@ void CGuiHandler::handleEvent(SDL_Event *sEvent)
|
|||||||
CCS->curh->cursorMove(sEvent->motion.x, sEvent->motion.y);
|
CCS->curh->cursorMove(sEvent->motion.x, sEvent->motion.y);
|
||||||
handleMouseMotion(sEvent);
|
handleMouseMotion(sEvent);
|
||||||
}
|
}
|
||||||
else if (sEvent->type==SDL_MOUSEBUTTONDOWN)
|
else if(sEvent->type == SDL_MOUSEBUTTONDOWN)
|
||||||
{
|
{
|
||||||
if(sEvent->button.button == SDL_BUTTON_LEFT)
|
switch(sEvent->button.button)
|
||||||
{
|
{
|
||||||
|
case SDL_BUTTON_LEFT:
|
||||||
if(lastClick == sEvent->motion && (SDL_GetTicks() - lastClickTime) < 300)
|
if(lastClick == sEvent->motion && (SDL_GetTicks() - lastClickTime) < 300)
|
||||||
{
|
{
|
||||||
std::list<CIntObject*> hlp = doubleClickInterested;
|
std::list<CIntObject*> hlp = doubleClickInterested;
|
||||||
for(auto i=hlp.begin(); i != hlp.end() && current; i++)
|
for(auto i = hlp.begin(); i != hlp.end() && current; i++)
|
||||||
{
|
{
|
||||||
if(!vstd::contains(doubleClickInterested,*i)) continue;
|
if(!vstd::contains(doubleClickInterested, *i)) continue;
|
||||||
if (isItIn(&(*i)->pos,sEvent->motion.x,sEvent->motion.y))
|
if(isItIn(&(*i)->pos, sEvent->motion.x, sEvent->motion.y))
|
||||||
{
|
{
|
||||||
(*i)->onDoubleClick();
|
(*i)->onDoubleClick();
|
||||||
}
|
}
|
||||||
@ -282,31 +283,16 @@ void CGuiHandler::handleEvent(SDL_Event *sEvent)
|
|||||||
lastClick = sEvent->motion;
|
lastClick = sEvent->motion;
|
||||||
lastClickTime = SDL_GetTicks();
|
lastClickTime = SDL_GetTicks();
|
||||||
|
|
||||||
std::list<CIntObject*> hlp = lclickable;
|
handleMouseButtonClick(lclickable, EIntObjMouseBtnType::LEFT, true);
|
||||||
for(auto i=hlp.begin(); i != hlp.end() && current; i++)
|
break;
|
||||||
{
|
case SDL_BUTTON_RIGHT:
|
||||||
if(!vstd::contains(lclickable,*i)) continue;
|
handleMouseButtonClick(rclickable, EIntObjMouseBtnType::RIGHT, true);
|
||||||
if (isItIn(&(*i)->pos,sEvent->motion.x,sEvent->motion.y))
|
break;
|
||||||
{
|
case SDL_BUTTON_MIDDLE:
|
||||||
prev = (*i)->pressedL;
|
handleMouseButtonClick(mclickable, EIntObjMouseBtnType::MIDDLE, true);
|
||||||
(*i)->pressedL = true;
|
break;
|
||||||
(*i)->clickLeft(true, prev);
|
default:
|
||||||
}
|
break;
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (sEvent->button.button == SDL_BUTTON_RIGHT)
|
|
||||||
{
|
|
||||||
std::list<CIntObject*> hlp = rclickable;
|
|
||||||
for(auto i=hlp.begin(); i != hlp.end() && current; i++)
|
|
||||||
{
|
|
||||||
if(!vstd::contains(rclickable,*i)) continue;
|
|
||||||
if (isItIn(&(*i)->pos,sEvent->motion.x,sEvent->motion.y))
|
|
||||||
{
|
|
||||||
prev = (*i)->pressedR;
|
|
||||||
(*i)->pressedR = true;
|
|
||||||
(*i)->clickRight(true, prev);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (sEvent->type == SDL_MOUSEWHEEL)
|
else if (sEvent->type == SDL_MOUSEWHEEL)
|
||||||
@ -336,41 +322,45 @@ void CGuiHandler::handleEvent(SDL_Event *sEvent)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
//todo: muiltitouch
|
//todo: muiltitouch
|
||||||
else if ((sEvent->type==SDL_MOUSEBUTTONUP) && (sEvent->button.button == SDL_BUTTON_LEFT))
|
else if(sEvent->type == SDL_MOUSEBUTTONUP)
|
||||||
{
|
{
|
||||||
std::list<CIntObject*> hlp = lclickable;
|
switch(sEvent->button.button)
|
||||||
for(auto i=hlp.begin(); i != hlp.end() && current; i++)
|
|
||||||
{
|
{
|
||||||
if(!vstd::contains(lclickable,*i)) continue;
|
case SDL_BUTTON_LEFT:
|
||||||
prev = (*i)->pressedL;
|
handleMouseButtonClick(lclickable, EIntObjMouseBtnType::LEFT, false);
|
||||||
(*i)->pressedL = false;
|
break;
|
||||||
if (isItIn(&(*i)->pos,sEvent->motion.x,sEvent->motion.y))
|
case SDL_BUTTON_RIGHT:
|
||||||
{
|
handleMouseButtonClick(rclickable, EIntObjMouseBtnType::RIGHT, false);
|
||||||
(*i)->clickLeft(false, prev);
|
break;
|
||||||
}
|
case SDL_BUTTON_MIDDLE:
|
||||||
else
|
handleMouseButtonClick(mclickable, EIntObjMouseBtnType::MIDDLE, false);
|
||||||
(*i)->clickLeft(boost::logic::indeterminate, prev);
|
break;
|
||||||
}
|
|
||||||
}
|
|
||||||
else if ((sEvent->type==SDL_MOUSEBUTTONUP) && (sEvent->button.button == SDL_BUTTON_RIGHT))
|
|
||||||
{
|
|
||||||
std::list<CIntObject*> hlp = rclickable;
|
|
||||||
for(auto i=hlp.begin(); i != hlp.end() && current; i++)
|
|
||||||
{
|
|
||||||
if(!vstd::contains(rclickable,*i)) continue;
|
|
||||||
prev = (*i)->pressedR;
|
|
||||||
(*i)->pressedR = false;
|
|
||||||
if (isItIn(&(*i)->pos,sEvent->motion.x,sEvent->motion.y))
|
|
||||||
{
|
|
||||||
(*i)->clickRight(false, prev);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
(*i)->clickRight(boost::logic::indeterminate, prev);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
current = nullptr;
|
current = nullptr;
|
||||||
} //event end
|
} //event end
|
||||||
|
|
||||||
|
void CGuiHandler::handleMouseButtonClick(CIntObjectList & interestedObjs, EIntObjMouseBtnType btn, bool isPressed)
|
||||||
|
{
|
||||||
|
auto hlp = interestedObjs;
|
||||||
|
for(auto i = hlp.begin(); i != hlp.end() && current; i++)
|
||||||
|
{
|
||||||
|
if(!vstd::contains(interestedObjs, *i)) continue;
|
||||||
|
|
||||||
|
auto prev = (*i)->mouseState(btn);
|
||||||
|
if(!isPressed)
|
||||||
|
(*i)->updateMouseState(btn, isPressed);
|
||||||
|
if(isItIn(&(*i)->pos, current->motion.x, current->motion.y))
|
||||||
|
{
|
||||||
|
if(isPressed)
|
||||||
|
(*i)->updateMouseState(btn, isPressed);
|
||||||
|
(*i)->click(btn, isPressed, prev);
|
||||||
|
}
|
||||||
|
else if(!isPressed)
|
||||||
|
(*i)->click(btn, boost::logic::indeterminate, prev);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void CGuiHandler::handleMouseMotion(SDL_Event *sEvent)
|
void CGuiHandler::handleMouseMotion(SDL_Event *sEvent)
|
||||||
{
|
{
|
||||||
//sending active, hovered hoverable objects hover() call
|
//sending active, hovered hoverable objects hover() call
|
||||||
|
@ -10,6 +10,7 @@ class CIntObject;
|
|||||||
class IUpdateable;
|
class IUpdateable;
|
||||||
class IShowActivatable;
|
class IShowActivatable;
|
||||||
class IShowable;
|
class IShowable;
|
||||||
|
enum class EIntObjMouseBtnType;
|
||||||
template <typename T> struct CondSh;
|
template <typename T> struct CondSh;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -53,6 +54,7 @@ private:
|
|||||||
//active GUI elements (listening for events
|
//active GUI elements (listening for events
|
||||||
CIntObjectList lclickable,
|
CIntObjectList lclickable,
|
||||||
rclickable,
|
rclickable,
|
||||||
|
mclickable,
|
||||||
hoverable,
|
hoverable,
|
||||||
keyinterested,
|
keyinterested,
|
||||||
motioninterested,
|
motioninterested,
|
||||||
@ -62,6 +64,7 @@ private:
|
|||||||
textInterested;
|
textInterested;
|
||||||
|
|
||||||
|
|
||||||
|
void handleMouseButtonClick(CIntObjectList &interestedObjs, EIntObjMouseBtnType btn, bool isPressed);
|
||||||
void processLists(const ui16 activityFlag, std::function<void (std::list<CIntObject*> *)> cb);
|
void processLists(const ui16 activityFlag, std::function<void (std::list<CIntObject*> *)> cb);
|
||||||
public:
|
public:
|
||||||
void handleElementActivate(CIntObject * elem, ui16 activityFlag);
|
void handleElementActivate(CIntObject * elem, ui16 activityFlag);
|
||||||
|
@ -16,7 +16,7 @@ CIntObject::CIntObject(int used_, Point pos_):
|
|||||||
parent(parent_m),
|
parent(parent_m),
|
||||||
active(active_m)
|
active(active_m)
|
||||||
{
|
{
|
||||||
pressedL = pressedR = hovered = captureAllKeys = strongInterest = false;
|
hovered = captureAllKeys = strongInterest = false;
|
||||||
toNextTick = timerDelay = 0;
|
toNextTick = timerDelay = 0;
|
||||||
used = used_;
|
used = used_;
|
||||||
|
|
||||||
@ -134,6 +134,23 @@ CIntObject::~CIntObject()
|
|||||||
parent_m->removeChild(this);
|
parent_m->removeChild(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CIntObject::click(EIntObjMouseBtnType btn, tribool down, bool previousState)
|
||||||
|
{
|
||||||
|
switch(btn)
|
||||||
|
{
|
||||||
|
default:
|
||||||
|
case EIntObjMouseBtnType::LEFT:
|
||||||
|
clickLeft(down, previousState);
|
||||||
|
break;
|
||||||
|
case EIntObjMouseBtnType::MIDDLE:
|
||||||
|
clickMiddle(down, previousState);
|
||||||
|
break;
|
||||||
|
case EIntObjMouseBtnType::RIGHT:
|
||||||
|
clickRight(down, previousState);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void CIntObject::printAtLoc( const std::string & text, int x, int y, EFonts font, SDL_Color kolor/*=Colors::WHITE*/, SDL_Surface * dst/*=screen*/ )
|
void CIntObject::printAtLoc( const std::string & text, int x, int y, EFonts font, SDL_Color kolor/*=Colors::WHITE*/, SDL_Surface * dst/*=screen*/ )
|
||||||
{
|
{
|
||||||
graphics->fonts[font]->renderTextLeft(dst, text, kolor, Point(pos.x + x, pos.y + y));
|
graphics->fonts[font]->renderTextLeft(dst, text, kolor, Point(pos.x + x, pos.y + y));
|
||||||
@ -340,16 +357,9 @@ void CKeyShortcut::keyPressed(const SDL_KeyboardEvent & key)
|
|||||||
if(vstd::contains(assignedKeys,key.keysym.sym)
|
if(vstd::contains(assignedKeys,key.keysym.sym)
|
||||||
|| vstd::contains(assignedKeys, CGuiHandler::numToDigit(key.keysym.sym)))
|
|| vstd::contains(assignedKeys, CGuiHandler::numToDigit(key.keysym.sym)))
|
||||||
{
|
{
|
||||||
bool prev = pressedL;
|
bool prev = mouseState(EIntObjMouseBtnType::LEFT);
|
||||||
if(key.state == SDL_PRESSED)
|
updateMouseState(EIntObjMouseBtnType::LEFT, key.state == SDL_PRESSED);
|
||||||
{
|
clickLeft(key.state == SDL_PRESSED, prev);
|
||||||
pressedL = true;
|
|
||||||
clickLeft(true, prev);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
pressedL = false;
|
|
||||||
clickLeft(false, prev);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -61,6 +61,7 @@ public:
|
|||||||
virtual ~IShowActivatable(){}; //d-tor
|
virtual ~IShowActivatable(){}; //d-tor
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum class EIntObjMouseBtnType { LEFT, MIDDLE, RIGHT };
|
||||||
//typedef ui16 ActivityFlag;
|
//typedef ui16 ActivityFlag;
|
||||||
|
|
||||||
// Base UI element
|
// Base UI element
|
||||||
@ -73,6 +74,8 @@ class CIntObject : public IShowActivatable //interface object
|
|||||||
int toNextTick;
|
int toNextTick;
|
||||||
int timerDelay;
|
int timerDelay;
|
||||||
|
|
||||||
|
std::map<EIntObjMouseBtnType, bool> currentMouseState;
|
||||||
|
|
||||||
void onTimer(int timePassed);
|
void onTimer(int timePassed);
|
||||||
|
|
||||||
//non-const versions of fields to allow changing them in CIntObject
|
//non-const versions of fields to allow changing them in CIntObject
|
||||||
@ -104,13 +107,13 @@ public:
|
|||||||
CIntObject(int used=0, Point offset=Point());
|
CIntObject(int used=0, Point offset=Point());
|
||||||
virtual ~CIntObject(); //d-tor
|
virtual ~CIntObject(); //d-tor
|
||||||
|
|
||||||
//l-clicks handling
|
void updateMouseState(EIntObjMouseBtnType btn, bool state) { currentMouseState[btn] = state; }
|
||||||
/*const*/ bool pressedL; //for determining if object is L-pressed
|
bool mouseState(EIntObjMouseBtnType btn) const { return currentMouseState.count(btn) ? currentMouseState.at(btn) : false; }
|
||||||
virtual void clickLeft(tribool down, bool previousState){}
|
|
||||||
|
|
||||||
//r-clicks handling
|
virtual void click(EIntObjMouseBtnType btn, tribool down, bool previousState);
|
||||||
/*const*/ bool pressedR; //for determining if object is R-pressed
|
virtual void clickLeft(tribool down, bool previousState) {}
|
||||||
virtual void clickRight(tribool down, bool previousState){}
|
virtual void clickRight(tribool down, bool previousState) {}
|
||||||
|
virtual void clickMiddle(tribool down, bool previousState) {}
|
||||||
|
|
||||||
//hover handling
|
//hover handling
|
||||||
/*const*/ bool hovered; //for determining if object is hovered
|
/*const*/ bool hovered; //for determining if object is hovered
|
||||||
@ -138,7 +141,7 @@ public:
|
|||||||
//double click
|
//double click
|
||||||
virtual void onDoubleClick(){}
|
virtual void onDoubleClick(){}
|
||||||
|
|
||||||
enum {LCLICK=1, RCLICK=2, HOVER=4, MOVE=8, KEYBOARD=16, TIME=32, GENERAL=64, WHEEL=128, DOUBLECLICK=256, TEXTINPUT=512, ALL=0xffff};
|
enum {LCLICK=1, RCLICK=2, HOVER=4, MOVE=8, KEYBOARD=16, TIME=32, GENERAL=64, WHEEL=128, DOUBLECLICK=256, TEXTINPUT=512, MCLICK=1024, ALL=0xffff};
|
||||||
const ui16 & active;
|
const ui16 & active;
|
||||||
void addUsedEvents(ui16 newActions);
|
void addUsedEvents(ui16 newActions);
|
||||||
void removeUsedEvents(ui16 newActions);
|
void removeUsedEvents(ui16 newActions);
|
||||||
|
@ -587,7 +587,7 @@ void CMinimap::hover(bool on)
|
|||||||
|
|
||||||
void CMinimap::mouseMoved(const SDL_MouseMotionEvent & sEvent)
|
void CMinimap::mouseMoved(const SDL_MouseMotionEvent & sEvent)
|
||||||
{
|
{
|
||||||
if (pressedL)
|
if (mouseState(EIntObjMouseBtnType::LEFT))
|
||||||
moveAdvMapSelection();
|
moveAdvMapSelection();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -623,7 +623,7 @@ void CSlider::clickLeft(tribool down, bool previousState)
|
|||||||
return;
|
return;
|
||||||
// if (rw>1) return;
|
// if (rw>1) return;
|
||||||
// if (rw<0) return;
|
// if (rw<0) return;
|
||||||
slider->clickLeft(true, slider->pressedL);
|
slider->clickLeft(true, slider->mouseState(EIntObjMouseBtnType::LEFT));
|
||||||
moveTo(rw * positions + 0.5);
|
moveTo(rw * positions + 0.5);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user