1
0
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:
Fay
2017-06-07 20:16:18 +02:00
parent f85632ea92
commit 02fa478bfb
8 changed files with 89 additions and 91 deletions

View File

@ -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>

View File

@ -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>

View File

@ -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

View File

@ -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);

View File

@ -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);
}
} }
} }

View File

@ -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);

View File

@ -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();
} }

View File

@ -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;
} }