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 
00078     _verticalScroll->_numEntries = h;
00079     _verticalScroll->_currentPos = _scrolledY;
00080     _verticalScroll->_entriesPerPage = _limitH;
00081     _verticalScroll->_singleStep = kLineHeight;
00082     _verticalScroll->setPos(_w - scrollbarWidth, _scrolledY+1);
00083     _verticalScroll->setSize(scrollbarWidth, _limitH -2);
00084 }
00085 
00086 
00087 ScrollContainerWidget::~ScrollContainerWidget() {}
00088 
00089 int16 ScrollContainerWidget::getChildX() const {
00090     return getAbsX() - _scrolledX;
00091 }
00092 
00093 int16 ScrollContainerWidget::getChildY() const {
00094     return getAbsY() - _scrolledY;
00095 }
00096 
00097 uint16 ScrollContainerWidget::getWidth() const {
00098     return _w - (_verticalScroll->isVisible() ? _verticalScroll->getWidth() : 0);
00099 }
00100 
00101 uint16 ScrollContainerWidget::getHeight() const {
00102     return _limitH;
00103 }
00104 
00105 void ScrollContainerWidget::handleCommand(CommandSender *sender, uint32 cmd, uint32 data) {
00106     Widget::handleCommand(sender, cmd, data);
00107     switch (cmd) {
00108     case kSetPositionCmd:
00109         _scrolledY = _verticalScroll->_currentPos;
00110         reflowLayout();
00111         g_gui.scheduleTopDialogRedraw();
00112         break;
00113     }
00114 }
00115 
00116 void ScrollContainerWidget::reflowLayout() {
00117     Widget::reflowLayout();
00118 
00119     //reflow layout of inner widgets
00120     Widget *ptr = _firstWidget;
00121     while (ptr) {
00122         ptr->reflowLayout();
00123         ptr = ptr->next();
00124     }
00125 
00126     //hide and move widgets, if needed
00127     sendCommand(_reflowCmd, 0);
00128 
00129     //recalculate height
00130     recalc();
00131 
00132     //hide those widgets which are out of visible area
00133     ptr = _firstWidget;
00134     while (ptr) {
00135         int y = ptr->getAbsY() - getChildY();
00136         int h = ptr->getHeight();
00137         bool visible = ptr->isVisible();
00138         if (y + h - _scrolledY < 0) visible = false;
00139         if (y - _scrolledY > _limitH) visible = false;
00140         ptr->setVisible(visible);
00141         ptr = ptr->next();
00142     }
00143 
00144     _verticalScroll->setVisible(_verticalScroll->_numEntries > _limitH); //show when there is something to scroll
00145     _verticalScroll->recalc();
00146 }
00147 
00148 void ScrollContainerWidget::drawWidget() {
00149     g_gui.theme()->drawDialogBackground(Common::Rect(_x, _y, _x + _w, _y + getHeight() - 1), _backgroundType);
00150 }
00151 
00152 bool ScrollContainerWidget::containsWidget(Widget *w) const {
00153     if (w == _verticalScroll || _verticalScroll->containsWidget(w))
00154         return true;
00155     return containsWidgetInChain(_firstWidget, w);
00156 }
00157 
00158 Widget *ScrollContainerWidget::findWidget(int x, int y) {
00159     if (_verticalScroll->isVisible() && x >= _w - _verticalScroll->getWidth())
00160         return _verticalScroll;
00161     Widget *w = Widget::findWidgetInChain(_firstWidget, x + _scrolledX, y + _scrolledY);
00162     if (w)
00163         return w;
00164     return this;
00165 }
00166 
00167 Common::Rect ScrollContainerWidget::getClipRect() const {
00168     // Make sure the clipping rect contains the scrollbar so it is properly redrawn
00169     return Common::Rect(getAbsX(), getAbsY(), getAbsX() + _w, getAbsY() + getHeight());
00170 }
00171 
00172 void ScrollContainerWidget::setBackgroundType(ThemeEngine::DialogBackground backgroundType) {
00173     _backgroundType = backgroundType;
00174 }
00175 
00176 } // End of namespace GUI


Generated on Sat Mar 16 2019 05:01:53 for ResidualVM by doxygen 1.7.1
curved edge   curved edge