From 1f79af440f124d33a4764e6eddf2c0fbc8ce99a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20W=2E=20Urba=C5=84czyk?= Date: Sun, 23 Aug 2009 18:01:08 +0000 Subject: [PATCH] * @previous revision: not an AI bug, it was a vector traversing bug. Fixed :-) * Scrolling through scenario list with mouse wheel, HOME, END, PAGE UP and PAGE DOWN buttons * Starting selected scenario with double-click --- client/CPreGame.cpp | 60 ++++++++++++++++++--- client/CPreGame.h | 3 ++ client/GUIBase.cpp | 118 +++++++++++++++++++++++++++++++++-------- client/GUIBase.h | 31 +++++++++-- hch/CObjectHandler.cpp | 10 ++-- 5 files changed, 185 insertions(+), 37 deletions(-) diff --git a/client/CPreGame.cpp b/client/CPreGame.cpp index dbe3d6a8e..ee8708894 100644 --- a/client/CPreGame.cpp +++ b/client/CPreGame.cpp @@ -436,7 +436,7 @@ SelectionTab::SelectionTab(EState Type, const boost::function OBJ_CONSTRUCTION; selectionPos = 0; - used = LCLICK; + used = LCLICK | WHEEL | KEYBOARD | DOUBLECLICK; slider = NULL; type = Type; std::vector toParse; @@ -528,13 +528,18 @@ void SelectionTab::select( int position ) { // New selection. py is the index in curItems. int py = position + slider->value; - if (py < curItems.size()) - { - CGI->soundh->playSound(soundBase::button); - selectionPos = py; + amax(py, 0); + amin(py, curItems.size()-1); - onSelect(curItems[py]); - } + CGI->soundh->playSound(soundBase::button); + selectionPos = py; + + if(position < 0) + slider->moveTo(slider->value + position); + else if(position >= positions) + slider->moveTo(slider->value + position - positions + 1); + + onSelect(curItems[py]); } int SelectionTab::getPosition( int x, int y ) @@ -667,6 +672,47 @@ void SelectionTab::clickLeft( tribool down, bool previousState ) } } +void SelectionTab::wheelScrolled( bool down, bool in ) +{ + slider->moveTo(slider->value + 3 * (down ? +1 : -1)); + //select(selectionPos - slider->value + (down ? +1 : -1)); +} + +void SelectionTab::keyPressed( const SDL_KeyboardEvent & key ) +{ + if(key.state != SDL_PRESSED) return; + + int moveBy = 0; + switch(key.keysym.sym) + { + case SDLK_UP: + moveBy = -1; + break; + case SDLK_DOWN: + moveBy = +1; + break; + case SDLK_PAGEUP: + moveBy = -positions+1; + break; + case SDLK_PAGEDOWN: + moveBy = +positions-1; + break; + case SDLK_HOME: + select(-slider->value); + return; + case SDLK_END: + select(curItems.size() - slider->value); + return; + } + select(selectionPos - slider->value + moveBy); +} + +void SelectionTab::onDoubleClick() +{ + //act as start button was pressed + (static_cast(parent))->start->callback(); +} + InfoCard::InfoCard( EState Type ) { OBJ_CONSTRUCTION; diff --git a/client/CPreGame.h b/client/CPreGame.h index faa4c6ce5..e71049cec 100644 --- a/client/CPreGame.h +++ b/client/CPreGame.h @@ -96,6 +96,9 @@ public: void showAll(SDL_Surface * to); void clickLeft(tribool down, bool previousState); + void wheelScrolled(bool down, bool in); + void keyPressed(const SDL_KeyboardEvent & key); + void onDoubleClick(); SelectionTab(EState Type, const boost::function &OnSelect); ~SelectionTab(); }; diff --git a/client/GUIBase.cpp b/client/GUIBase.cpp index 2167357f4..76e6f9bd3 100644 --- a/client/GUIBase.cpp +++ b/client/GUIBase.cpp @@ -178,17 +178,61 @@ void CGuiHandler::handleEvent(SDL_Event *sEvent) CGI->curh->cursorMove(sEvent->motion.x, sEvent->motion.y); handleMouseMotion(sEvent); } - else if ((sEvent->type==SDL_MOUSEBUTTONDOWN) && (sEvent->button.button == SDL_BUTTON_LEFT)) + else if (sEvent->type==SDL_MOUSEBUTTONDOWN) { - std::list hlp = lclickable; - for(std::list::iterator i=hlp.begin(); i != hlp.end();i++) + if(sEvent->button.button == SDL_BUTTON_LEFT) { - if(!vstd::contains(lclickable,*i)) continue; - if (isItIn(&(*i)->pos,sEvent->motion.x,sEvent->motion.y)) + + if(lastClick == sEvent->motion && (SDL_GetTicks() - lastClickTime) < 300) { - prev = (*i)->pressedL; - (*i)->pressedL = true; - (*i)->clickLeft(true, prev); + std::list hlp = doubleClickInterested; + for(std::list::iterator i=hlp.begin(); i != hlp.end();i++) + { + if(!vstd::contains(doubleClickInterested,*i)) continue; + if (isItIn(&(*i)->pos,sEvent->motion.x,sEvent->motion.y)) + { + (*i)->onDoubleClick(); + } + } + + } + + lastClick = sEvent->motion; + lastClickTime = SDL_GetTicks(); + + std::list hlp = lclickable; + for(std::list::iterator i=hlp.begin(); i != hlp.end();i++) + { + if(!vstd::contains(lclickable,*i)) continue; + if (isItIn(&(*i)->pos,sEvent->motion.x,sEvent->motion.y)) + { + prev = (*i)->pressedL; + (*i)->pressedL = true; + (*i)->clickLeft(true, prev); + } + } + } + else if (sEvent->button.button == SDL_BUTTON_RIGHT) + { + std::list hlp = rclickable; + for(std::list::iterator i=hlp.begin(); i != hlp.end();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->button.button == SDL_BUTTON_WHEELDOWN || sEvent->button.button == SDL_BUTTON_WHEELUP) + { + std::list hlp = wheelInterested; + for(std::list::iterator i=hlp.begin(); i != hlp.end();i++) + { + if(!vstd::contains(wheelInterested,*i)) continue; + (*i)->wheelScrolled(sEvent->button.button == SDL_BUTTON_WHEELDOWN, isItIn(&(*i)->pos,sEvent->motion.x,sEvent->motion.y)); } } } @@ -208,20 +252,6 @@ void CGuiHandler::handleEvent(SDL_Event *sEvent) (*i)->clickLeft(boost::logic::indeterminate, prev); } } - else if ((sEvent->type==SDL_MOUSEBUTTONDOWN) && (sEvent->button.button == SDL_BUTTON_RIGHT)) - { - std::list hlp = rclickable; - for(std::list::iterator i=hlp.begin(); i != hlp.end();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_MOUSEBUTTONUP) && (sEvent->button.button == SDL_BUTTON_RIGHT)) { std::list hlp = rclickable; @@ -455,6 +485,10 @@ void CIntObject::activate() activateKeys(); if(used & TIME) activateTimer(); + if(used & WHEEL) + activateWheel(); + if(used & DOUBLECLICK) + activateDClick(); if(defActions & ACTIVATE) for(size_t i = 0; i < children.size(); i++) @@ -478,6 +512,10 @@ void CIntObject::deactivate() deactivateKeys(); if(used & TIME) deactivateTimer(); + if(used & WHEEL) + deactivateWheel(); + if(used & DOUBLECLICK) + deactivateDClick(); if(defActions & DEACTIVATE) for(size_t i = 0; i < children.size(); i++) @@ -546,6 +584,42 @@ bool CIntObject::isItInLoc( const SDL_Rect &rect, const Point &p ) return isItIn(&rect, p.x - pos.x, p.y - pos.y); } +void CIntObject::activateWheel() +{ + GH.wheelInterested.push_front(this); + active |= WHEEL; +} + +void CIntObject::deactivateWheel() +{ + std::list::iterator hlp = std::find(GH.wheelInterested.begin(),GH.wheelInterested.end(),this); + assert(hlp != GH.wheelInterested.end()); + GH.wheelInterested.erase(hlp); + active &= ~WHEEL; +} + +void CIntObject::wheelScrolled(bool down, bool in) +{ +} + +void CIntObject::activateDClick() +{ + GH.doubleClickInterested.push_front(this); + active |= DOUBLECLICK; +} + +void CIntObject::deactivateDClick() +{ + std::list::iterator hlp = std::find(GH.doubleClickInterested.begin(),GH.doubleClickInterested.end(),this); + assert(hlp != GH.doubleClickInterested.end()); + GH.doubleClickInterested.erase(hlp); + active &= ~DOUBLECLICK; +} + +void CIntObject::onDoubleClick() +{ +} + CPicture::CPicture( SDL_Surface *BG, int x, int y, bool Free ) { bg = BG; diff --git a/client/GUIBase.h b/client/GUIBase.h index cbdc648e4..3dec3118c 100644 --- a/client/GUIBase.h +++ b/client/GUIBase.h @@ -93,6 +93,16 @@ struct Point { return x < b.x && y < b.y; } + template Point& operator=(const T &t) + { + x = t.x; + y = t.y; + return *this; + } + template bool operator==(const T &t) + { + return x == t.x && y == t.y; + } }; struct Rect : public SDL_Rect @@ -309,9 +319,19 @@ public: void deactivateTimer(); virtual void tick(); - enum {LCLICK=1, RCLICK=2, HOVER=4, MOVE=8, KEYBOARD=16, TIME=32, GENERAL=64}; - ui8 active; - ui8 used; + //mouse wheel + void activateWheel(); + void deactivateWheel(); + virtual void wheelScrolled(bool down, bool in); + + //double click + void activateDClick(); + void deactivateDClick(); + virtual void onDoubleClick(); + + enum {LCLICK=1, RCLICK=2, HOVER=4, MOVE=8, KEYBOARD=16, TIME=32, GENERAL=64, WHEEL=128, DOUBLECLICK=256, ALL=0xffff}; + ui16 active; + ui16 used; enum {ACTIVATE=1, DEACTIVATE=2, UPDATE=4, SHOWALL=8, DISPOSE=16, SHARE_POS=32}; ui8 defActions; //which calls will be tried to be redirected to children @@ -390,12 +410,17 @@ public: std::list keyinterested; std::list motioninterested; std::list timeinterested; + std::list wheelInterested; + std::list doubleClickInterested; //objs to blit std::vector objsToBlit; SDL_Event * current; //current event + Point lastClick; + unsigned lastClickTime; + void totalRedraw(); //forces total redraw (using showAll) void simpleRedraw(); //update only top interface and draw background from buffer void popInt(IShowActivable *top); //removes given interface from the top and activates next diff --git a/hch/CObjectHandler.cpp b/hch/CObjectHandler.cpp index 2bc3badeb..4787fdd7e 100644 --- a/hch/CObjectHandler.cpp +++ b/hch/CObjectHandler.cpp @@ -3708,16 +3708,16 @@ void CBank::reset() int val1 = ran()%100; int chance = 0; - for (ui8 i = 1; i <= VLC->objh->banksInfo[index].size(); i++) + for (ui8 i = 0; i < VLC->objh->banksInfo[index].size(); i++) { - if (val1 < (chance += VLC->objh->banksInfo[index][i].chance)) - cb->setObjProperty (id, 13, i); +// if (val1 < (chance += VLC->objh->banksInfo[index][i].chance)) +// cb->setObjProperty (id, 13, i); } artifacts.clear(); for (ui8 i = 1; i <= 4; i++) { - for (ui8 j = 1; j <= bc->artifacts[i]; j++) - cb->setObjProperty (id, 18, i); +// for (ui8 j = 1; j <= bc->artifacts[i]; j++) +// cb->setObjProperty (id, 18, i); } }