ResidualVM logo ResidualVM website - Forums - Contact us BuildBot - Doxygen - Wiki curved edge

scrollcontainer.cpp

Go to the documentation of this file.
00001 /* ScummVM - Graphic Adventure Engine
00002  *
00003  * ScummVM is the legal property of its developers, whose names
00004  * are too numerous to list here. Please refer to the COPYRIGHT
00005  * file distributed with this source distribution.
00006  *
00007  * This program is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU General Public License
00009  * as published by the Free Software Foundation; either version 2
00010  * of the License, or (at your option) any later version.
00011  *
00012  * This program is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  * GNU General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU General Public License
00018  * along with this program; if not, write to the Free Software
00019  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00020  *
00021  */
00022 
00023 #include "common/util.h"
00024 #include "gui/widgets/scrollcontainer.h"
00025 #include "gui/gui-manager.h"
00026 
00027 #include "gui/ThemeEval.h"
00028 
00029 namespace GUI {
00030 
00031 ScrollContainerWidget::ScrollContainerWidget(GuiObject *boss, int x, int y, int w, int h, uint32 reflowCmd)
00032     : Widget(boss, x, y, w, h), CommandSender(nullptr), _reflowCmd(reflowCmd) {
00033     init();
00034 }
00035 
00036 ScrollContainerWidget::ScrollContainerWidget(GuiObject *boss, const Common::String &name, uint32 reflowCmd)
00037     : Widget(boss, name), CommandSender(nullptr), _reflowCmd(reflowCmd) {
00038     init();
00039 }
00040 
00041 void ScrollContainerWidget::init() {
00042     setFlags(WIDGET_ENABLED);
00043     _type = kScrollContainerWidget;
00044     _backgroundType = ThemeEngine::kDialogBackgroundDefault;
00045     _verticalScroll = new ScrollBarWidget(this, _w-16, 0, 16, _h);
00046     _verticalScroll->setTarget(this);
00047     _scrolledX = 0;
00048     _scrolledY = 0;
00049     _limitH = 140;
00050     recalc();
00051 }
00052 
00053 void ScrollContainerWidget::handleMouseWheel(int x, int y, int direction) {
00054     _verticalScroll->handleMouseWheel(x, y, direction);
00055 }
00056 
00057 void ScrollContainerWidget::recalc() {
00058     int scrollbarWidth = g_gui.xmlEval()->getVar("Globals.Scrollbar.Width", 0);
00059     _limitH = _h;
00060 
00061     //calculate virtual height
00062     const int spacing = g_gui.xmlEval()->getVar("Global.Font.Height", 16); //on the bottom
00063     int h = 0;
00064     int min = spacing, max = 0;
00065     Widget *ptr = _firstWidget;
00066     while (ptr) {
00067         if (ptr != _verticalScroll && ptr->isVisible()) {
00068             int y = ptr->getAbsY() - getChildY();
00069             min = MIN(min, y - spacing);
00070             max = MAX(max, y + ptr->getHeight() + spacing);
00071         }
00072         ptr = ptr->next();
00073     }
00074     h = max - min;
00075 
00076     if (h <= _limitH) _scrolledY = 0;
00077     if (_scrolledY > h - _limitH) _scrolledY = 0;
00078 
00079     _verticalScroll->_numEntries = h;
00080     _verticalScroll->_currentPos = _scrolledY;
00081     _verticalScroll->_entriesPerPage = _limitH;
00082     _verticalScroll->_singleStep = kLineHeight;
00083     _verticalScroll->setPos(_w - scrollbarWidth, _scrolledY);
00084     _verticalScroll->setSize(scrollbarWidth, _limitH-1);
00085 }
00086 
00087 
00088 ScrollContainerWidget::~ScrollContainerWidget() {}
00089 
00090 int16 ScrollContainerWidget::getChildX() const {
00091     return getAbsX() - _scrolledX;
00092 }
00093 
00094 int16 ScrollContainerWidget::getChildY() const {
00095     return getAbsY() - _scrolledY;
00096 }
00097 
00098 uint16 ScrollContainerWidget::getWidth() const {
00099     return _w - (_verticalScroll->isVisible() ? _verticalScroll->getWidth() : 0);
00100 }
00101 
00102 uint16 ScrollContainerWidget::getHeight() const {
00103     return _limitH;
00104 }
00105 
00106 void ScrollContainerWidget::handleCommand(CommandSender *sender, uint32 cmd, uint32 data) {
00107     Widget::handleCommand(sender, cmd, data);
00108     switch (cmd) {
00109     case kSetPositionCmd:
00110         _scrolledY = _verticalScroll->_currentPos;
00111         reflowLayout();
00112         g_gui.scheduleTopDialogRedraw();
00113         break;
00114     }
00115 }
00116 
00117 void ScrollContainerWidget::reflowLayout() {
00118     Widget::reflowLayout();
00119 
00120     //reflow layout of inner widgets
00121     Widget *ptr = _firstWidget;
00122     while (ptr) {
00123         ptr->reflowLayout();
00124         ptr = ptr->next();
00125     }
00126 
00127     //hide and move widgets, if needed
00128     sendCommand(_reflowCmd, 0);
00129 
00130     //recalculate height
00131     recalc();
00132 
00133     //hide those widgets which are out of visible area
00134     ptr = _firstWidget;
00135     while (ptr) {
00136         int y = ptr->getAbsY() - getChildY();
00137         int h = ptr->getHeight();
00138         bool visible = ptr->isVisible();
00139         if (y + h - _scrolledY < 0) visible = false;
00140         if (y - _scrolledY > _limitH) visible = false;
00141         ptr->setVisible(visible);
00142         ptr = ptr->next();
00143     }
00144 
00145     _verticalScroll->setVisible(_verticalScroll->_numEntries > _limitH); //show when there is something to scroll
00146     _verticalScroll->recalc();
00147 }
00148 
00149 void ScrollContainerWidget::drawWidget() {
00150     g_gui.theme()->drawDialogBackground(Common::Rect(_x, _y, _x + _w, _y + getHeight()), _backgroundType);
00151 }
00152 
00153 bool ScrollContainerWidget::containsWidget(Widget *w) const {
00154     if (w == _verticalScroll || _verticalScroll->containsWidget(w))
00155         return true;
00156     return containsWidgetInChain(_firstWidget, w);
00157 }
00158 
00159 Widget *ScrollContainerWidget::findWidget(int x, int y) {
00160     if (_verticalScroll->isVisible() && x >= _w - _verticalScroll->getWidth())
00161         return _verticalScroll;
00162     Widget *w = Widget::findWidgetInChain(_firstWidget, x + _scrolledX, y + _scrolledY);
00163     if (w)
00164         return w;
00165     return this;
00166 }
00167 
00168 Common::Rect ScrollContainerWidget::getClipRect() const {
00169     // Make sure the clipping rect contains the scrollbar so it is properly redrawn
00170     return Common::Rect(getAbsX(), getAbsY(), getAbsX() + _w, getAbsY() + getHeight() - 1); // this -1 is because of container border, which might not be present actually
00171 }
00172 
00173 void ScrollContainerWidget::setBackgroundType(ThemeEngine::DialogBackground backgroundType) {
00174     _backgroundType = backgroundType;
00175 }
00176 
00177 } // End of namespace GUI


Generated on Sat Apr 4 2020 05:00:37 for ResidualVM by doxygen 1.7.1
curved edge   curved edge