550 lines
12 KiB
C++
550 lines
12 KiB
C++
/* ScummVM - Graphic Adventure Engine
|
|
*
|
|
* ScummVM is the legal property of its developers, whose names
|
|
* are too numerous to list here. Please refer to the COPYRIGHT
|
|
* file distributed with this source distribution.
|
|
*
|
|
* This program is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*
|
|
*/
|
|
|
|
#include "titanic/pet_control/pet_glyphs.h"
|
|
#include "titanic/pet_control/pet_section.h"
|
|
#include "titanic/pet_control/pet_control.h"
|
|
|
|
namespace Titanic {
|
|
|
|
bool CPetGlyph::setup(CPetControl *petControl, CPetGlyphs *owner) {
|
|
_element.setBounds(Rect(0, 0, 52, 50));
|
|
_owner = owner;
|
|
return true;
|
|
}
|
|
|
|
void CPetGlyph::drawAt(CScreenManager *screenManager, const Point &pt, bool isHighlighted_) {
|
|
_element.translate(pt.x, pt.y);
|
|
_element.draw(screenManager);
|
|
_element.translate(-pt.x, -pt.y);
|
|
}
|
|
|
|
void CPetGlyph::updateTooltip() {
|
|
CTextControl *petText = getPetSection()->getText();
|
|
if (petText) {
|
|
petText->setColor(getPetSection()->getColor(0));
|
|
getTooltip(petText);
|
|
|
|
if (_owner)
|
|
getPetSection()->stopTextTimer();
|
|
}
|
|
}
|
|
|
|
bool CPetGlyph::contains(const Point &delta, const Point &pt) {
|
|
translate(delta);
|
|
bool result = _element.contains2(pt);
|
|
translateBack(delta);
|
|
|
|
return result;
|
|
}
|
|
|
|
CPetSection *CPetGlyph::getPetSection() const {
|
|
return _owner ? _owner->getOwner() : nullptr;
|
|
}
|
|
|
|
CPetControl *CPetGlyph::getPetControl() const {
|
|
return _owner ? _owner->getPetControl() : nullptr;
|
|
}
|
|
|
|
void CPetGlyph::setName(const CString &name, CPetControl *petControl) {
|
|
Rect r(0, 0, 52, 52);
|
|
_element.setBounds(r);
|
|
_element.reset(name, petControl, MODE_UNSELECTED);
|
|
}
|
|
|
|
bool CPetGlyph::isHighlighted() const {
|
|
return _owner->isGlyphHighlighted(this);
|
|
}
|
|
|
|
/*------------------------------------------------------------------------*/
|
|
|
|
CPetGlyphs::CPetGlyphs() : _firstVisibleIndex(0), _numVisibleGlyphs(TOTAL_GLYPHS),
|
|
_highlightIndex(-1), _field1C(-1), _flags(0),
|
|
_dragGlyph(nullptr), _owner(nullptr) {
|
|
}
|
|
|
|
void CPetGlyphs::setNumVisible(int total) {
|
|
if (total > 0)
|
|
_numVisibleGlyphs = total;
|
|
}
|
|
|
|
void CPetGlyphs::clear() {
|
|
changeHighlight(-1);
|
|
destroyContents();
|
|
_firstVisibleIndex = 0;
|
|
}
|
|
|
|
void CPetGlyphs::setup(int numVisible, CPetSection *owner) {
|
|
setNumVisible(numVisible);
|
|
_owner = owner;
|
|
_selection.setBounds(Rect(0, 0, 76, 76));
|
|
|
|
int buttonsLeft = numVisible * 70 + 21;
|
|
|
|
_scrollLeft.setBounds(Rect(0, 0, 31, 15));
|
|
_scrollLeft.translate(buttonsLeft + 7, 373);
|
|
_scrollRight.setBounds(Rect(0, 0, 31, 15));
|
|
_scrollRight.translate(buttonsLeft + 7, 413);
|
|
}
|
|
|
|
void CPetGlyphs::reset() {
|
|
if (_owner && _owner->_petControl) {
|
|
CPetControl *pet = _owner->_petControl;
|
|
|
|
_scrollLeft.reset("PetScrollLeft", pet, MODE_UNSELECTED);
|
|
_scrollRight.reset("PetScrollRight", pet, MODE_UNSELECTED);
|
|
_selection.reset("PetSelection", pet, MODE_UNSELECTED);
|
|
|
|
for (iterator i = begin(); i != end(); ++i) {
|
|
(*i)->reset();
|
|
}
|
|
}
|
|
}
|
|
|
|
void CPetGlyphs::enter() {
|
|
if (_highlightIndex != -1) {
|
|
CPetGlyph *glyph = getGlyph(_highlightIndex);
|
|
if (glyph)
|
|
glyph->enter();
|
|
}
|
|
}
|
|
|
|
void CPetGlyphs::leave() {
|
|
if (_highlightIndex != -1) {
|
|
CPetGlyph *glyph = getGlyph(_highlightIndex);
|
|
if (glyph)
|
|
glyph->leave();
|
|
}
|
|
}
|
|
|
|
void CPetGlyphs::draw(CScreenManager *screenManager) {
|
|
if (_highlightIndex != -1) {
|
|
int index = getHighlightedIndex(_highlightIndex);
|
|
if (index != -1) {
|
|
Point pt = getPosition(index);
|
|
pt -= Point(12, 13);
|
|
_selection.translate(pt.x, pt.y);
|
|
_selection.draw(screenManager);
|
|
_selection.translate(-pt.x, -pt.y);
|
|
}
|
|
}
|
|
|
|
// Iterate through displaying glyphs on the screen
|
|
int listSize = size();
|
|
for (int index = 0; index < _numVisibleGlyphs; ++index) {
|
|
int itemIndex = getItemIndex(index);
|
|
|
|
if (itemIndex >= 0 && itemIndex < listSize) {
|
|
Point pt = getPosition(index);
|
|
CPetGlyph *glyph = getGlyph(itemIndex);
|
|
|
|
if (glyph)
|
|
glyph->drawAt(screenManager, pt, itemIndex == _highlightIndex);
|
|
}
|
|
}
|
|
|
|
// Draw scrolling arrows if more than a screen's worth of items are showing
|
|
if (listSize > _numVisibleGlyphs || (_flags & GFLAG_16)) {
|
|
_scrollLeft.draw(screenManager);
|
|
_scrollRight.draw(screenManager);
|
|
}
|
|
|
|
// Handle secondary highlight
|
|
if (_highlightIndex != -1) {
|
|
CPetGlyph *glyph = getGlyph(_highlightIndex);
|
|
if (glyph)
|
|
glyph->draw2(screenManager);
|
|
}
|
|
}
|
|
|
|
Point CPetGlyphs::getPosition(int index) const {
|
|
Point tempPoint(37 + index * 70, 375);
|
|
return tempPoint;
|
|
}
|
|
|
|
Rect CPetGlyphs::getRect(int index) const {
|
|
Point pt = getPosition(index);
|
|
return Rect(pt.x, pt.y, pt.x + 52, pt.y + 52);
|
|
}
|
|
|
|
void CPetGlyphs::changeHighlight(int index) {
|
|
if (index == _highlightIndex)
|
|
return;
|
|
|
|
if (_highlightIndex >= 0 && (_flags & GFLAG_4)) {
|
|
CPetGlyph *glyph = getGlyph(_highlightIndex);
|
|
if (glyph)
|
|
glyph->unhighlightCurrent();
|
|
}
|
|
|
|
_highlightIndex = index;
|
|
if (index >= 0) {
|
|
CPetGlyph *glyph = getGlyph(_highlightIndex);
|
|
|
|
if (glyph) {
|
|
if (_flags & GFLAG_4) {
|
|
Point pt;
|
|
int idx = getHighlightedIndex(_highlightIndex);
|
|
if (idx >= 0)
|
|
pt = getPosition(idx);
|
|
|
|
glyph->highlightCurrent(pt);
|
|
}
|
|
|
|
glyph->updateTooltip();
|
|
}
|
|
} else if (_owner) {
|
|
_owner->removeText();
|
|
}
|
|
}
|
|
|
|
void CPetGlyphs::highlight(int index) {
|
|
if (index >= 0) {
|
|
setSelectedIndex(index);
|
|
changeHighlight(index);
|
|
makePetDirty();
|
|
}
|
|
}
|
|
|
|
void CPetGlyphs::highlight(const CPetGlyph *glyph) {
|
|
highlight(indexOf(glyph));
|
|
}
|
|
|
|
int CPetGlyphs::getHighlightedIndex(int index) const {
|
|
int idx = index - _firstVisibleIndex;
|
|
return (idx >= 0 && idx < _numVisibleGlyphs) ? idx : -1;
|
|
}
|
|
|
|
int CPetGlyphs::getItemIndex(int index) const {
|
|
return _firstVisibleIndex + index;
|
|
}
|
|
|
|
void CPetGlyphs::setSelectedIndex(int index) {
|
|
if (index >= 0 && index < (int)size() && getHighlightedIndex(index) == -1) {
|
|
if (_firstVisibleIndex <= index)
|
|
index -= _numVisibleGlyphs - 1;
|
|
|
|
setFirstVisible(index);
|
|
}
|
|
}
|
|
|
|
CPetGlyph *CPetGlyphs::getGlyph(int index) const {
|
|
for (const_iterator i = begin(); i != end(); ++i) {
|
|
if (index-- == 0)
|
|
return *i;
|
|
}
|
|
|
|
return nullptr;
|
|
}
|
|
|
|
CPetControl *CPetGlyphs::getPetControl() const {
|
|
return _owner ? _owner->getPetControl() : nullptr;
|
|
}
|
|
|
|
void CPetGlyphs::setFirstVisible(int index) {
|
|
if (index != _firstVisibleIndex) {
|
|
_firstVisibleIndex = index;
|
|
|
|
if ((_flags & GFLAG_8) && _highlightIndex != -1) {
|
|
CPetGlyph *glyph = getGlyph(_highlightIndex);
|
|
|
|
if (glyph) {
|
|
int idx = getHighlightedIndex(_highlightIndex);
|
|
if (idx != -1) {
|
|
Point tempPt = getPosition(idx);
|
|
glyph->glyphFocused(tempPt, true);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void CPetGlyphs::scrollLeft() {
|
|
if (_firstVisibleIndex > 0) {
|
|
setFirstVisible(_firstVisibleIndex - 1);
|
|
if (_highlightIndex != -1) {
|
|
int index = getHighlightedIndex(_highlightIndex);
|
|
if (index == -1)
|
|
changeHighlight(_highlightIndex - 1);
|
|
}
|
|
|
|
makePetDirty();
|
|
}
|
|
}
|
|
|
|
void CPetGlyphs::scrollRight() {
|
|
int count = size();
|
|
int right = count - _numVisibleGlyphs;
|
|
|
|
if (_firstVisibleIndex < right) {
|
|
setFirstVisible(_firstVisibleIndex + 1);
|
|
if (_highlightIndex != -1) {
|
|
int index = getHighlightedIndex(_highlightIndex);
|
|
if (index == -1)
|
|
changeHighlight(_highlightIndex + 1);
|
|
}
|
|
|
|
makePetDirty();
|
|
}
|
|
}
|
|
|
|
void CPetGlyphs::makePetDirty() {
|
|
if (_owner && _owner->_petControl)
|
|
_owner->_petControl->makeDirty();
|
|
}
|
|
|
|
bool CPetGlyphs::MouseButtonDownMsg(const Point &pt) {
|
|
if (_scrollLeft.contains2(pt)) {
|
|
scrollLeft();
|
|
return true;
|
|
}
|
|
|
|
if (_scrollRight.contains2(pt)) {
|
|
scrollRight();
|
|
return true;
|
|
}
|
|
|
|
for (int idx = 0; idx < _numVisibleGlyphs; ++idx) {
|
|
Rect glyphRect = getRect(idx);
|
|
if (glyphRect.contains(pt)) {
|
|
int index = getItemIndex(idx);
|
|
CPetGlyph *glyph = getGlyph(index);
|
|
if (glyph) {
|
|
if (_highlightIndex == index) {
|
|
glyph->selectGlyph(glyphRect, pt);
|
|
glyph->updateTooltip();
|
|
} else {
|
|
changeHighlight(index);
|
|
makePetDirty();
|
|
}
|
|
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (_highlightIndex != -1) {
|
|
CPetGlyph *glyph = getGlyph(_highlightIndex);
|
|
|
|
if (glyph) {
|
|
if (glyph->MouseButtonDownMsg(pt))
|
|
return true;
|
|
|
|
if (!(_flags & GFLAG_2)) {
|
|
changeHighlight(-1);
|
|
makePetDirty();
|
|
}
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
bool CPetGlyphs::MouseButtonUpMsg(const Point &pt) {
|
|
if (_highlightIndex >= 0) {
|
|
CPetGlyph *glyph = getGlyph(_highlightIndex);
|
|
if (glyph) {
|
|
if (glyph->MouseButtonUpMsg(pt))
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
bool CPetGlyphs::MouseDragStartMsg(CMouseDragStartMsg *msg) {
|
|
if (!(_flags & GFLAG_1) && _highlightIndex >= 0) {
|
|
CPetGlyph *glyph = getGlyph(_highlightIndex);
|
|
int index = getHighlightedIndex(_highlightIndex);
|
|
Rect glyphRect = getRect(index);
|
|
|
|
if (glyphRect.contains(msg->_mousePos))
|
|
return glyph->dragGlyph(glyphRect, msg);
|
|
else
|
|
return glyph->MouseDragStartMsg(msg);
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
bool CPetGlyphs::MouseDragMoveMsg(CMouseDragMoveMsg *msg) {
|
|
if (_dragGlyph) {
|
|
return _dragGlyph->MouseDragMoveMsg(msg);
|
|
} else {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
bool CPetGlyphs::MouseDragEndMsg(CMouseDragEndMsg *msg) {
|
|
if (_dragGlyph) {
|
|
return _dragGlyph->MouseDragEndMsg(msg);
|
|
} else {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
bool CPetGlyphs::KeyCharMsg(int key) {
|
|
if (_highlightIndex >= 0) {
|
|
CPetGlyph *glyph = getGlyph(_highlightIndex);
|
|
|
|
if (glyph && glyph->KeyCharMsg(key))
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
bool CPetGlyphs::ActionMsg(CActionMsg *msg) {
|
|
if (_highlightIndex >= 0) {
|
|
CPetGlyph *glyph = getGlyph(_highlightIndex);
|
|
if (glyph && glyph->ActionMsg(msg))
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
bool CPetGlyphs::enterHighlighted() {
|
|
if (_highlightIndex >= 0)
|
|
return getGlyph(_highlightIndex)->enterHighlighted();
|
|
else
|
|
return false;
|
|
}
|
|
|
|
void CPetGlyphs::leaveHighlighted() {
|
|
if (_highlightIndex >= 0)
|
|
getGlyph(_highlightIndex)->leaveHighlighted();
|
|
}
|
|
|
|
void CPetGlyphs::startDragging(CPetGlyph *glyph, CMouseDragStartMsg *msg) {
|
|
if (glyph) {
|
|
_dragGlyph = glyph;
|
|
msg->_dragItem = getPetControl();
|
|
}
|
|
}
|
|
|
|
void CPetGlyphs::endDragging() {
|
|
_dragGlyph = nullptr;
|
|
}
|
|
|
|
bool CPetGlyphs::highlighted14() {
|
|
if (_highlightIndex != -1) {
|
|
CPetGlyph *pet = getGlyph(_highlightIndex);
|
|
if (pet) {
|
|
pet->updateTooltip();
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
int CPetGlyphs::indexOf(const CPetGlyph *glyph) const {
|
|
int index = 0;
|
|
for (const_iterator i = begin(); i != end(); ++i, ++index) {
|
|
if (*i == glyph)
|
|
return index;
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
|
|
void CPetGlyphs::incSelection() {
|
|
if (_highlightIndex >= 0 && _highlightIndex < ((int)size() - 1)) {
|
|
if (getHighlightedIndex(_highlightIndex) >= (_numVisibleGlyphs - 1))
|
|
scrollRight();
|
|
|
|
changeHighlight(_highlightIndex + 1);
|
|
makePetDirty();
|
|
}
|
|
}
|
|
|
|
void CPetGlyphs::decSelection() {
|
|
if (_highlightIndex > 0) {
|
|
if (getHighlightedIndex(_highlightIndex) == 0)
|
|
scrollLeft();
|
|
|
|
changeHighlight(_highlightIndex - 1);
|
|
makePetDirty();
|
|
}
|
|
}
|
|
|
|
CGameObject *CPetGlyphs::getObjectAt(const Point &pt) const {
|
|
for (int idx = 0; idx < _numVisibleGlyphs; ++idx) {
|
|
Rect glyphRect = getRect(idx);
|
|
if (glyphRect.contains(pt)) {
|
|
CPetGlyph *glyph = getGlyph(getItemIndex(idx));
|
|
if (glyph)
|
|
return glyph->getObjectAt();
|
|
}
|
|
}
|
|
|
|
return nullptr;
|
|
}
|
|
|
|
bool CPetGlyphs::isGlyphHighlighted(const CPetGlyph *glyph) const {
|
|
if (_highlightIndex == -1)
|
|
return false;
|
|
|
|
return indexOf(glyph) == _highlightIndex;
|
|
}
|
|
|
|
Point CPetGlyphs::getHighlightedGlyphPos() const {
|
|
if (_highlightIndex != -1) {
|
|
int idx = getHighlightedIndex(_highlightIndex);
|
|
if (idx >= 0)
|
|
return getPosition(idx);
|
|
}
|
|
|
|
return Point(0, 0);
|
|
}
|
|
|
|
bool CPetGlyphs::areItemsValid() const {
|
|
for (const_iterator i = begin(); i != end(); ++i) {
|
|
if (!(*i)->isValid())
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
void CPetGlyphs::removeInvalid() {
|
|
if (!areItemsValid()) {
|
|
changeHighlight(-1);
|
|
|
|
for (iterator i = begin(); i != end(); ) {
|
|
CPetGlyph *glyph = *i;
|
|
|
|
if (!glyph->isValid()) {
|
|
i = erase(i);
|
|
delete glyph;
|
|
} else {
|
|
++i;
|
|
}
|
|
}
|
|
|
|
int max = MAX((int)size() - _numVisibleGlyphs, 0);
|
|
_firstVisibleIndex = CLIP(_firstVisibleIndex, 0, max);
|
|
}
|
|
}
|
|
|
|
} // End of namespace Titanic
|