Guichan library and few examples, by Lubomyr
This commit is contained in:
284
project/jni/guichan/src/widgets/button.cpp
Normal file
284
project/jni/guichan/src/widgets/button.cpp
Normal file
@@ -0,0 +1,284 @@
|
||||
/* _______ __ __ __ ______ __ __ _______ __ __
|
||||
* / _____/\ / /\ / /\ / /\ / ____/\ / /\ / /\ / ___ /\ / |\/ /\
|
||||
* / /\____\// / // / // / // /\___\// /_// / // /\_/ / // , |/ / /
|
||||
* / / /__ / / // / // / // / / / ___ / // ___ / // /| ' / /
|
||||
* / /_// /\ / /_// / // / // /_/_ / / // / // /\_/ / // / | / /
|
||||
* /______/ //______/ //_/ //_____/\ /_/ //_/ //_/ //_/ //_/ /|_/ /
|
||||
* \______\/ \______\/ \_\/ \_____\/ \_\/ \_\/ \_\/ \_\/ \_\/ \_\/
|
||||
*
|
||||
* Copyright (c) 2004 - 2008 Olof Naessén and Per Larsson
|
||||
*
|
||||
*
|
||||
* Per Larsson a.k.a finalman
|
||||
* Olof Naessén a.k.a jansem/yakslem
|
||||
*
|
||||
* Visit: http://guichan.sourceforge.net
|
||||
*
|
||||
* License: (BSD)
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* 3. Neither the name of Guichan nor the names of its contributors may
|
||||
* be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
|
||||
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* For comments regarding functions please see the header file.
|
||||
*/
|
||||
|
||||
#include "guichan/widgets/button.hpp"
|
||||
|
||||
#include "guichan/exception.hpp"
|
||||
#include "guichan/font.hpp"
|
||||
#include "guichan/graphics.hpp"
|
||||
#include "guichan/key.hpp"
|
||||
#include "guichan/mouseevent.hpp"
|
||||
#include "guichan/mouseinput.hpp"
|
||||
|
||||
namespace gcn
|
||||
{
|
||||
Button::Button()
|
||||
: mHasMouse(false),
|
||||
mKeyPressed(false),
|
||||
mMousePressed(false),
|
||||
mAlignment(Graphics::CENTER),
|
||||
mSpacing(4)
|
||||
{
|
||||
setFocusable(true);
|
||||
adjustSize();
|
||||
setFrameSize(1);
|
||||
|
||||
addMouseListener(this);
|
||||
addKeyListener(this);
|
||||
addFocusListener(this);
|
||||
}
|
||||
|
||||
Button::Button(const std::string& caption)
|
||||
: mCaption(caption),
|
||||
mHasMouse(false),
|
||||
mKeyPressed(false),
|
||||
mMousePressed(false),
|
||||
mAlignment(Graphics::CENTER),
|
||||
mSpacing(4)
|
||||
{
|
||||
setFocusable(true);
|
||||
adjustSize();
|
||||
setFrameSize(1);
|
||||
|
||||
addMouseListener(this);
|
||||
addKeyListener(this);
|
||||
addFocusListener(this);
|
||||
}
|
||||
|
||||
void Button::setCaption(const std::string& caption)
|
||||
{
|
||||
mCaption = caption;
|
||||
}
|
||||
|
||||
const std::string& Button::getCaption() const
|
||||
{
|
||||
return mCaption;
|
||||
}
|
||||
|
||||
void Button::setAlignment(Graphics::Alignment alignment)
|
||||
{
|
||||
mAlignment = alignment;
|
||||
}
|
||||
|
||||
Graphics::Alignment Button::getAlignment() const
|
||||
{
|
||||
return mAlignment;
|
||||
}
|
||||
|
||||
void Button::setSpacing(unsigned int spacing)
|
||||
{
|
||||
mSpacing = spacing;
|
||||
}
|
||||
|
||||
unsigned int Button::getSpacing() const
|
||||
{
|
||||
return mSpacing;
|
||||
}
|
||||
|
||||
void Button::draw(Graphics* graphics)
|
||||
{
|
||||
Color faceColor = getBaseColor();
|
||||
Color highlightColor, shadowColor;
|
||||
int alpha = getBaseColor().a;
|
||||
|
||||
if (isPressed())
|
||||
{
|
||||
faceColor = faceColor - 0x303030;
|
||||
faceColor.a = alpha;
|
||||
highlightColor = faceColor - 0x303030;
|
||||
highlightColor.a = alpha;
|
||||
shadowColor = faceColor + 0x303030;
|
||||
shadowColor.a = alpha;
|
||||
}
|
||||
else
|
||||
{
|
||||
highlightColor = faceColor + 0x303030;
|
||||
highlightColor.a = alpha;
|
||||
shadowColor = faceColor - 0x303030;
|
||||
shadowColor.a = alpha;
|
||||
}
|
||||
|
||||
graphics->setColor(faceColor);
|
||||
graphics->fillRectangle(Rectangle(1, 1, getDimension().width-1, getHeight() - 1));
|
||||
|
||||
graphics->setColor(highlightColor);
|
||||
graphics->drawLine(0, 0, getWidth() - 1, 0);
|
||||
graphics->drawLine(0, 1, 0, getHeight() - 1);
|
||||
|
||||
graphics->setColor(shadowColor);
|
||||
graphics->drawLine(getWidth() - 1, 1, getWidth() - 1, getHeight() - 1);
|
||||
graphics->drawLine(1, getHeight() - 1, getWidth() - 1, getHeight() - 1);
|
||||
|
||||
graphics->setColor(getForegroundColor());
|
||||
|
||||
int textX;
|
||||
int textY = getHeight() / 2 - getFont()->getHeight() / 2;
|
||||
|
||||
switch (getAlignment())
|
||||
{
|
||||
case Graphics::LEFT:
|
||||
textX = mSpacing;
|
||||
break;
|
||||
case Graphics::CENTER:
|
||||
textX = getWidth() / 2;
|
||||
break;
|
||||
case Graphics::RIGHT:
|
||||
textX = getWidth() - mSpacing;
|
||||
break;
|
||||
default:
|
||||
throw GCN_EXCEPTION("Unknown alignment.");
|
||||
}
|
||||
|
||||
graphics->setFont(getFont());
|
||||
|
||||
if (isPressed())
|
||||
{
|
||||
graphics->drawText(getCaption(), textX + 1, textY + 1, getAlignment());
|
||||
}
|
||||
else
|
||||
{
|
||||
graphics->drawText(getCaption(), textX, textY, getAlignment());
|
||||
|
||||
if (isFocused())
|
||||
{
|
||||
graphics->drawRectangle(Rectangle(2, 2, getWidth() - 4,
|
||||
getHeight() - 4));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Button::adjustSize()
|
||||
{
|
||||
setWidth(getFont()->getWidth(mCaption) + 2*mSpacing);
|
||||
setHeight(getFont()->getHeight() + 2*mSpacing);
|
||||
}
|
||||
|
||||
bool Button::isPressed() const
|
||||
{
|
||||
if (mMousePressed)
|
||||
{
|
||||
return mHasMouse;
|
||||
}
|
||||
else
|
||||
{
|
||||
return mKeyPressed;
|
||||
}
|
||||
}
|
||||
|
||||
void Button::mousePressed(MouseEvent& mouseEvent)
|
||||
{
|
||||
if (mouseEvent.getButton() == MouseEvent::LEFT)
|
||||
{
|
||||
mMousePressed = true;
|
||||
mouseEvent.consume();
|
||||
}
|
||||
}
|
||||
|
||||
void Button::mouseExited(MouseEvent& mouseEvent)
|
||||
{
|
||||
mHasMouse = false;
|
||||
}
|
||||
|
||||
void Button::mouseEntered(MouseEvent& mouseEvent)
|
||||
{
|
||||
mHasMouse = true;
|
||||
}
|
||||
|
||||
void Button::mouseReleased(MouseEvent& mouseEvent)
|
||||
{
|
||||
if (mouseEvent.getButton() == MouseEvent::LEFT
|
||||
&& mMousePressed
|
||||
&& mHasMouse)
|
||||
{
|
||||
mMousePressed = false;
|
||||
distributeActionEvent();
|
||||
mouseEvent.consume();
|
||||
}
|
||||
else if (mouseEvent.getButton() == MouseEvent::LEFT)
|
||||
{
|
||||
mMousePressed = false;
|
||||
mouseEvent.consume();
|
||||
}
|
||||
}
|
||||
|
||||
void Button::mouseDragged(MouseEvent& mouseEvent)
|
||||
{
|
||||
mouseEvent.consume();
|
||||
}
|
||||
|
||||
void Button::keyPressed(KeyEvent& keyEvent)
|
||||
{
|
||||
Key key = keyEvent.getKey();
|
||||
|
||||
if (key.getValue() == Key::ENTER
|
||||
|| key.getValue() == Key::SPACE)
|
||||
{
|
||||
mKeyPressed = true;
|
||||
keyEvent.consume();
|
||||
}
|
||||
}
|
||||
|
||||
void Button::keyReleased(KeyEvent& keyEvent)
|
||||
{
|
||||
Key key = keyEvent.getKey();
|
||||
|
||||
if ((key.getValue() == Key::ENTER
|
||||
|| key.getValue() == Key::SPACE)
|
||||
&& mKeyPressed)
|
||||
{
|
||||
mKeyPressed = false;
|
||||
distributeActionEvent();
|
||||
keyEvent.consume();
|
||||
}
|
||||
}
|
||||
|
||||
void Button::focusLost(const Event& event)
|
||||
{
|
||||
mMousePressed = false;
|
||||
mKeyPressed = false;
|
||||
}
|
||||
}
|
||||
189
project/jni/guichan/src/widgets/checkbox.cpp
Normal file
189
project/jni/guichan/src/widgets/checkbox.cpp
Normal file
@@ -0,0 +1,189 @@
|
||||
/* _______ __ __ __ ______ __ __ _______ __ __
|
||||
* / _____/\ / /\ / /\ / /\ / ____/\ / /\ / /\ / ___ /\ / |\/ /\
|
||||
* / /\____\// / // / // / // /\___\// /_// / // /\_/ / // , |/ / /
|
||||
* / / /__ / / // / // / // / / / ___ / // ___ / // /| ' / /
|
||||
* / /_// /\ / /_// / // / // /_/_ / / // / // /\_/ / // / | / /
|
||||
* /______/ //______/ //_/ //_____/\ /_/ //_/ //_/ //_/ //_/ /|_/ /
|
||||
* \______\/ \______\/ \_\/ \_____\/ \_\/ \_\/ \_\/ \_\/ \_\/ \_\/
|
||||
*
|
||||
* Copyright (c) 2004 - 2008 Olof Naessén and Per Larsson
|
||||
*
|
||||
*
|
||||
* Per Larsson a.k.a finalman
|
||||
* Olof Naessén a.k.a jansem/yakslem
|
||||
*
|
||||
* Visit: http://guichan.sourceforge.net
|
||||
*
|
||||
* License: (BSD)
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* 3. Neither the name of Guichan nor the names of its contributors may
|
||||
* be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
|
||||
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* For comments regarding functions please see the header file.
|
||||
*/
|
||||
|
||||
#include "guichan/widgets/checkbox.hpp"
|
||||
|
||||
#include "guichan/font.hpp"
|
||||
#include "guichan/graphics.hpp"
|
||||
#include "guichan/key.hpp"
|
||||
#include "guichan/mouseinput.hpp"
|
||||
|
||||
namespace gcn
|
||||
{
|
||||
|
||||
CheckBox::CheckBox()
|
||||
{
|
||||
setSelected(false);
|
||||
|
||||
setFocusable(true);
|
||||
addMouseListener(this);
|
||||
addKeyListener(this);
|
||||
}
|
||||
|
||||
CheckBox::CheckBox(const std::string &caption, bool selected)
|
||||
{
|
||||
setCaption(caption);
|
||||
setSelected(selected);
|
||||
|
||||
setFocusable(true);
|
||||
addMouseListener(this);
|
||||
addKeyListener(this);
|
||||
|
||||
adjustSize();
|
||||
}
|
||||
|
||||
void CheckBox::draw(Graphics* graphics)
|
||||
{
|
||||
drawBox(graphics);
|
||||
|
||||
graphics->setFont(getFont());
|
||||
graphics->setColor(getForegroundColor());
|
||||
|
||||
const int h = getHeight() + getHeight() / 2;
|
||||
|
||||
graphics->drawText(getCaption(), h - 2, 0);
|
||||
}
|
||||
|
||||
void CheckBox::drawBox(Graphics *graphics)
|
||||
{
|
||||
const int h = getHeight() - 2;
|
||||
const int alpha = getBaseColor().a;
|
||||
Color faceColor = getBaseColor();
|
||||
faceColor.a = alpha;
|
||||
Color highlightColor = faceColor + 0x303030;
|
||||
highlightColor.a = alpha;
|
||||
Color shadowColor = faceColor - 0x303030;
|
||||
shadowColor.a = alpha;
|
||||
|
||||
graphics->setColor(shadowColor);
|
||||
graphics->drawLine(1, 1, h, 1);
|
||||
graphics->drawLine(1, 1, 1, h);
|
||||
|
||||
graphics->setColor(highlightColor);
|
||||
graphics->drawLine(h, 1, h, h);
|
||||
graphics->drawLine(1, h, h - 1, h);
|
||||
|
||||
graphics->setColor(getBackgroundColor());
|
||||
graphics->fillRectangle(Rectangle(2, 2, h - 2, h - 2));
|
||||
|
||||
graphics->setColor(getForegroundColor());
|
||||
|
||||
if (isFocused())
|
||||
{
|
||||
graphics->drawRectangle(Rectangle(0, 0, h + 2, h + 2));
|
||||
}
|
||||
|
||||
if (mSelected)
|
||||
{
|
||||
graphics->drawLine(3, 5, 3, h - 2);
|
||||
graphics->drawLine(4, 5, 4, h - 2);
|
||||
|
||||
graphics->drawLine(5, h - 3, h - 2, 4);
|
||||
graphics->drawLine(5, h - 4, h - 4, 5);
|
||||
}
|
||||
}
|
||||
|
||||
bool CheckBox::isSelected() const
|
||||
{
|
||||
return mSelected;
|
||||
}
|
||||
|
||||
void CheckBox::setSelected(bool selected)
|
||||
{
|
||||
mSelected = selected;
|
||||
}
|
||||
|
||||
const std::string &CheckBox::getCaption() const
|
||||
{
|
||||
return mCaption;
|
||||
}
|
||||
|
||||
void CheckBox::setCaption(const std::string& caption)
|
||||
{
|
||||
mCaption = caption;
|
||||
}
|
||||
|
||||
void CheckBox::keyPressed(KeyEvent& keyEvent)
|
||||
{
|
||||
Key key = keyEvent.getKey();
|
||||
|
||||
if (key.getValue() == Key::ENTER ||
|
||||
key.getValue() == Key::SPACE)
|
||||
{
|
||||
toggleSelected();
|
||||
keyEvent.consume();
|
||||
}
|
||||
}
|
||||
|
||||
void CheckBox::mouseClicked(MouseEvent& mouseEvent)
|
||||
{
|
||||
if (mouseEvent.getButton() == MouseEvent::LEFT)
|
||||
{
|
||||
toggleSelected();
|
||||
}
|
||||
}
|
||||
|
||||
void CheckBox::mouseDragged(MouseEvent& mouseEvent)
|
||||
{
|
||||
mouseEvent.consume();
|
||||
}
|
||||
|
||||
void CheckBox::adjustSize()
|
||||
{
|
||||
int height = getFont()->getHeight();
|
||||
|
||||
setHeight(height);
|
||||
setWidth(getFont()->getWidth(mCaption) + height + height / 2);
|
||||
}
|
||||
|
||||
void CheckBox::toggleSelected()
|
||||
{
|
||||
mSelected = !mSelected;
|
||||
distributeActionEvent();
|
||||
}
|
||||
}
|
||||
|
||||
112
project/jni/guichan/src/widgets/container.cpp
Normal file
112
project/jni/guichan/src/widgets/container.cpp
Normal file
@@ -0,0 +1,112 @@
|
||||
/* _______ __ __ __ ______ __ __ _______ __ __
|
||||
* / _____/\ / /\ / /\ / /\ / ____/\ / /\ / /\ / ___ /\ / |\/ /\
|
||||
* / /\____\// / // / // / // /\___\// /_// / // /\_/ / // , |/ / /
|
||||
* / / /__ / / // / // / // / / / ___ / // ___ / // /| ' / /
|
||||
* / /_// /\ / /_// / // / // /_/_ / / // / // /\_/ / // / | / /
|
||||
* /______/ //______/ //_/ //_____/\ /_/ //_/ //_/ //_/ //_/ /|_/ /
|
||||
* \______\/ \______\/ \_\/ \_____\/ \_\/ \_\/ \_\/ \_\/ \_\/ \_\/
|
||||
*
|
||||
* Copyright (c) 2004 - 2008 Olof Naessén and Per Larsson
|
||||
*
|
||||
*
|
||||
* Per Larsson a.k.a finalman
|
||||
* Olof Naessén a.k.a jansem/yakslem
|
||||
*
|
||||
* Visit: http://guichan.sourceforge.net
|
||||
*
|
||||
* License: (BSD)
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* 3. Neither the name of Guichan nor the names of its contributors may
|
||||
* be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
|
||||
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* For comments regarding functions please see the header file.
|
||||
*/
|
||||
|
||||
#include "guichan/widgets/container.hpp"
|
||||
|
||||
#include "guichan/exception.hpp"
|
||||
#include "guichan/graphics.hpp"
|
||||
|
||||
namespace gcn
|
||||
{
|
||||
|
||||
Container::Container()
|
||||
{
|
||||
mOpaque = true;
|
||||
}
|
||||
|
||||
Container::~Container()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void Container::draw(Graphics* graphics)
|
||||
{
|
||||
if (isOpaque())
|
||||
{
|
||||
graphics->setColor(getBaseColor());
|
||||
graphics->fillRectangle(Rectangle(0, 0, getWidth(), getHeight()));
|
||||
}
|
||||
|
||||
drawChildren(graphics);
|
||||
}
|
||||
|
||||
void Container::setOpaque(bool opaque)
|
||||
{
|
||||
mOpaque = opaque;
|
||||
}
|
||||
|
||||
bool Container::isOpaque() const
|
||||
{
|
||||
return mOpaque;
|
||||
}
|
||||
|
||||
void Container::add(Widget* widget)
|
||||
{
|
||||
BasicContainer::add(widget);
|
||||
}
|
||||
|
||||
void Container::add(Widget* widget, int x, int y)
|
||||
{
|
||||
widget->setPosition(x, y);
|
||||
BasicContainer::add(widget);
|
||||
}
|
||||
|
||||
void Container::remove(Widget* widget)
|
||||
{
|
||||
BasicContainer::remove(widget);
|
||||
}
|
||||
|
||||
void Container::clear()
|
||||
{
|
||||
BasicContainer::clear();
|
||||
}
|
||||
|
||||
Widget* Container::findWidgetById(const std::string &id)
|
||||
{
|
||||
return BasicContainer::findWidgetById(id);
|
||||
}
|
||||
}
|
||||
635
project/jni/guichan/src/widgets/dropdown.cpp
Normal file
635
project/jni/guichan/src/widgets/dropdown.cpp
Normal file
@@ -0,0 +1,635 @@
|
||||
/* _______ __ __ __ ______ __ __ _______ __ __
|
||||
* / _____/\ / /\ / /\ / /\ / ____/\ / /\ / /\ / ___ /\ / |\/ /\
|
||||
* / /\____\// / // / // / // /\___\// /_// / // /\_/ / // , |/ / /
|
||||
* / / /__ / / // / // / // / / / ___ / // ___ / // /| ' / /
|
||||
* / /_// /\ / /_// / // / // /_/_ / / // / // /\_/ / // / | / /
|
||||
* /______/ //______/ //_/ //_____/\ /_/ //_/ //_/ //_/ //_/ /|_/ /
|
||||
* \______\/ \______\/ \_\/ \_____\/ \_\/ \_\/ \_\/ \_\/ \_\/ \_\/
|
||||
*
|
||||
* Copyright (c) 2004 - 2008 Olof Naessén and Per Larsson
|
||||
*
|
||||
*
|
||||
* Per Larsson a.k.a finalman
|
||||
* Olof Naessén a.k.a jansem/yakslem
|
||||
*
|
||||
* Visit: http://guichan.sourceforge.net
|
||||
*
|
||||
* License: (BSD)
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* 3. Neither the name of Guichan nor the names of its contributors may
|
||||
* be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
|
||||
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "guichan/widgets/dropdown.hpp"
|
||||
|
||||
#include "guichan/exception.hpp"
|
||||
#include "guichan/font.hpp"
|
||||
#include "guichan/graphics.hpp"
|
||||
#include "guichan/key.hpp"
|
||||
#include "guichan/listmodel.hpp"
|
||||
#include "guichan/mouseinput.hpp"
|
||||
#include "guichan/widgets/listbox.hpp"
|
||||
#include "guichan/widgets/scrollarea.hpp"
|
||||
|
||||
namespace gcn
|
||||
{
|
||||
DropDown::DropDown(ListModel *listModel,
|
||||
ScrollArea *scrollArea,
|
||||
ListBox *listBox)
|
||||
{
|
||||
setWidth(100);
|
||||
setFocusable(true);
|
||||
mDroppedDown = false;
|
||||
mPushed = false;
|
||||
mIsDragged = false;
|
||||
|
||||
setInternalFocusHandler(&mInternalFocusHandler);
|
||||
|
||||
mInternalScrollArea = (scrollArea == NULL);
|
||||
mInternalListBox = (listBox == NULL);
|
||||
|
||||
if (mInternalScrollArea)
|
||||
{
|
||||
mScrollArea = new ScrollArea();
|
||||
}
|
||||
else
|
||||
{
|
||||
mScrollArea = scrollArea;
|
||||
}
|
||||
|
||||
if (mInternalListBox)
|
||||
{
|
||||
mListBox = new ListBox();
|
||||
}
|
||||
else
|
||||
{
|
||||
mListBox = listBox;
|
||||
}
|
||||
|
||||
mScrollArea->setContent(mListBox);
|
||||
add(mScrollArea);
|
||||
|
||||
mListBox->addActionListener(this);
|
||||
mListBox->addSelectionListener(this);
|
||||
|
||||
setListModel(listModel);
|
||||
|
||||
if (mListBox->getSelected() < 0)
|
||||
{
|
||||
mListBox->setSelected(0);
|
||||
}
|
||||
|
||||
addMouseListener(this);
|
||||
addKeyListener(this);
|
||||
addFocusListener(this);
|
||||
|
||||
adjustHeight();
|
||||
}
|
||||
|
||||
DropDown::~DropDown()
|
||||
{
|
||||
if (widgetExists(mListBox))
|
||||
{
|
||||
mListBox->removeActionListener(this);
|
||||
mListBox->removeSelectionListener(this);
|
||||
}
|
||||
|
||||
if (mInternalScrollArea)
|
||||
{
|
||||
delete mScrollArea;
|
||||
}
|
||||
|
||||
if (mInternalListBox)
|
||||
{
|
||||
delete mListBox;
|
||||
}
|
||||
|
||||
setInternalFocusHandler(NULL);
|
||||
}
|
||||
|
||||
void DropDown::draw(Graphics* graphics)
|
||||
{
|
||||
int h;
|
||||
|
||||
if (mDroppedDown)
|
||||
{
|
||||
h = mFoldedUpHeight;
|
||||
}
|
||||
else
|
||||
{
|
||||
h = getHeight();
|
||||
}
|
||||
|
||||
Color faceColor = getBaseColor();
|
||||
Color highlightColor, shadowColor;
|
||||
int alpha = getBaseColor().a;
|
||||
highlightColor = faceColor + 0x303030;
|
||||
highlightColor.a = alpha;
|
||||
shadowColor = faceColor - 0x303030;
|
||||
shadowColor.a = alpha;
|
||||
|
||||
// Draw a border.
|
||||
graphics->setColor(shadowColor);
|
||||
graphics->drawLine(0, 0, getWidth() - 1, 0);
|
||||
graphics->drawLine(0, 1, 0, h - 2);
|
||||
graphics->setColor(highlightColor);
|
||||
graphics->drawLine(getWidth() - 1, 1, getWidth() - 1, h - 1);
|
||||
graphics->drawLine(0, h - 1, getWidth() - 1, h - 1);
|
||||
|
||||
// Push a clip area so the other drawings don't need to worry
|
||||
// about the border.
|
||||
graphics->pushClipArea(Rectangle(1, 1, getWidth() - 2, h - 2));
|
||||
const Rectangle currentClipArea = graphics->getCurrentClipArea();
|
||||
|
||||
graphics->setColor(getBackgroundColor());
|
||||
graphics->fillRectangle(Rectangle(0, 0, currentClipArea.width, currentClipArea.height));
|
||||
|
||||
if (isFocused())
|
||||
{
|
||||
graphics->setColor(getSelectionColor());
|
||||
graphics->fillRectangle(Rectangle(0,
|
||||
0,
|
||||
currentClipArea.width - currentClipArea.height,
|
||||
currentClipArea.height));
|
||||
graphics->setColor(getForegroundColor());
|
||||
}
|
||||
|
||||
if (mListBox->getListModel()
|
||||
&& mListBox->getSelected() >= 0)
|
||||
{
|
||||
graphics->setColor(getForegroundColor());
|
||||
graphics->setFont(getFont());
|
||||
|
||||
graphics->drawText(mListBox->getListModel()->getElementAt(mListBox->getSelected()), 1, 0);
|
||||
}
|
||||
|
||||
// Push a clip area before drawing the button.
|
||||
graphics->pushClipArea(Rectangle(currentClipArea.width - currentClipArea.height,
|
||||
0,
|
||||
currentClipArea.height,
|
||||
currentClipArea.height));
|
||||
drawButton(graphics);
|
||||
graphics->popClipArea();
|
||||
graphics->popClipArea();
|
||||
|
||||
if (mDroppedDown)
|
||||
{
|
||||
// Draw a border around the children.
|
||||
graphics->setColor(shadowColor);
|
||||
graphics->drawRectangle(Rectangle(0,
|
||||
mFoldedUpHeight,
|
||||
getWidth(),
|
||||
getHeight() - mFoldedUpHeight));
|
||||
drawChildren(graphics);
|
||||
}
|
||||
}
|
||||
|
||||
void DropDown::drawButton(Graphics *graphics)
|
||||
{
|
||||
Color faceColor, highlightColor, shadowColor;
|
||||
int offset;
|
||||
int alpha = getBaseColor().a;
|
||||
|
||||
if (mPushed)
|
||||
{
|
||||
faceColor = getBaseColor() - 0x303030;
|
||||
faceColor.a = alpha;
|
||||
highlightColor = faceColor - 0x303030;
|
||||
highlightColor.a = alpha;
|
||||
shadowColor = faceColor + 0x303030;
|
||||
shadowColor.a = alpha;
|
||||
offset = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
faceColor = getBaseColor();
|
||||
faceColor.a = alpha;
|
||||
highlightColor = faceColor + 0x303030;
|
||||
highlightColor.a = alpha;
|
||||
shadowColor = faceColor - 0x303030;
|
||||
shadowColor.a = alpha;
|
||||
offset = 0;
|
||||
}
|
||||
|
||||
const Rectangle currentClipArea = graphics->getCurrentClipArea();
|
||||
graphics->setColor(highlightColor);
|
||||
graphics->drawLine(0,
|
||||
0,
|
||||
currentClipArea.width - 1,
|
||||
0);
|
||||
graphics->drawLine(0,
|
||||
1,
|
||||
0,
|
||||
currentClipArea.height - 1);
|
||||
graphics->setColor(shadowColor);
|
||||
graphics->drawLine(currentClipArea.width - 1,
|
||||
1,
|
||||
currentClipArea.width - 1,
|
||||
currentClipArea.height - 1);
|
||||
graphics->drawLine(1,
|
||||
currentClipArea.height - 1,
|
||||
currentClipArea.width - 2,
|
||||
currentClipArea.height - 1);
|
||||
|
||||
graphics->setColor(faceColor);
|
||||
graphics->fillRectangle(Rectangle(1,
|
||||
1,
|
||||
currentClipArea.width - 2,
|
||||
currentClipArea.height - 2));
|
||||
|
||||
graphics->setColor(getForegroundColor());
|
||||
|
||||
int i;
|
||||
int n = currentClipArea.height / 3;
|
||||
int dx = currentClipArea.height / 2;
|
||||
int dy = (currentClipArea.height * 2) / 3;
|
||||
for (i = 0; i < n; i++)
|
||||
{
|
||||
graphics->drawLine(dx - i + offset,
|
||||
dy - i + offset,
|
||||
dx + i + offset,
|
||||
dy - i + offset);
|
||||
}
|
||||
}
|
||||
|
||||
int DropDown::getSelected() const
|
||||
{
|
||||
return mListBox->getSelected();
|
||||
}
|
||||
|
||||
void DropDown::setSelected(int selected)
|
||||
{
|
||||
if (selected >= 0)
|
||||
{
|
||||
mListBox->setSelected(selected);
|
||||
}
|
||||
}
|
||||
|
||||
void DropDown::keyPressed(KeyEvent& keyEvent)
|
||||
{
|
||||
if (keyEvent.isConsumed())
|
||||
return;
|
||||
|
||||
Key key = keyEvent.getKey();
|
||||
|
||||
if ((key.getValue() == Key::ENTER || key.getValue() == Key::SPACE)
|
||||
&& !mDroppedDown)
|
||||
{
|
||||
dropDown();
|
||||
keyEvent.consume();
|
||||
}
|
||||
else if (key.getValue() == Key::UP)
|
||||
{
|
||||
setSelected(getSelected() - 1);
|
||||
keyEvent.consume();
|
||||
}
|
||||
else if (key.getValue() == Key::DOWN)
|
||||
{
|
||||
setSelected(getSelected() + 1);
|
||||
keyEvent.consume();
|
||||
}
|
||||
}
|
||||
|
||||
void DropDown::mousePressed(MouseEvent& mouseEvent)
|
||||
{
|
||||
// If we have a mouse press on the widget.
|
||||
if (0 <= mouseEvent.getY()
|
||||
&& mouseEvent.getY() < getHeight()
|
||||
&& mouseEvent.getX() >= 0
|
||||
&& mouseEvent.getX() < getWidth()
|
||||
&& mouseEvent.getButton() == MouseEvent::LEFT
|
||||
&& !mDroppedDown
|
||||
&& mouseEvent.getSource() == this)
|
||||
{
|
||||
mPushed = true;
|
||||
dropDown();
|
||||
requestModalMouseInputFocus();
|
||||
}
|
||||
// Fold up the listbox if the upper part is clicked after fold down
|
||||
else if (0 <= mouseEvent.getY()
|
||||
&& mouseEvent.getY() < mFoldedUpHeight
|
||||
&& mouseEvent.getX() >= 0
|
||||
&& mouseEvent.getX() < getWidth()
|
||||
&& mouseEvent.getButton() == MouseEvent::LEFT
|
||||
&& mDroppedDown
|
||||
&& mouseEvent.getSource() == this)
|
||||
{
|
||||
mPushed = false;
|
||||
foldUp();
|
||||
releaseModalMouseInputFocus();
|
||||
}
|
||||
// If we have a mouse press outside the widget
|
||||
else if (0 > mouseEvent.getY()
|
||||
|| mouseEvent.getY() >= getHeight()
|
||||
|| mouseEvent.getX() < 0
|
||||
|| mouseEvent.getX() >= getWidth())
|
||||
{
|
||||
mPushed = false;
|
||||
foldUp();
|
||||
}
|
||||
}
|
||||
|
||||
void DropDown::mouseReleased(MouseEvent& mouseEvent)
|
||||
{
|
||||
if (mIsDragged)
|
||||
{
|
||||
mPushed = false;
|
||||
}
|
||||
|
||||
// Released outside of widget. Can happen when we have modal input focus.
|
||||
if ((0 > mouseEvent.getY()
|
||||
|| mouseEvent.getY() >= getHeight()
|
||||
|| mouseEvent.getX() < 0
|
||||
|| mouseEvent.getX() >= getWidth())
|
||||
&& mouseEvent.getButton() == MouseEvent::LEFT
|
||||
&& isModalMouseInputFocused())
|
||||
{
|
||||
releaseModalMouseInputFocus();
|
||||
|
||||
if (mIsDragged)
|
||||
{
|
||||
foldUp();
|
||||
}
|
||||
}
|
||||
else if (mouseEvent.getButton() == MouseEvent::LEFT)
|
||||
{
|
||||
mPushed = false;
|
||||
}
|
||||
|
||||
mIsDragged = false;
|
||||
}
|
||||
|
||||
void DropDown::mouseDragged(MouseEvent& mouseEvent)
|
||||
{
|
||||
mIsDragged = true;
|
||||
|
||||
mouseEvent.consume();
|
||||
}
|
||||
|
||||
void DropDown::setListModel(ListModel *listModel)
|
||||
{
|
||||
mListBox->setListModel(listModel);
|
||||
|
||||
if (mListBox->getSelected() < 0)
|
||||
{
|
||||
mListBox->setSelected(0);
|
||||
}
|
||||
|
||||
adjustHeight();
|
||||
}
|
||||
|
||||
ListModel *DropDown::getListModel()
|
||||
{
|
||||
return mListBox->getListModel();
|
||||
}
|
||||
|
||||
void DropDown::adjustHeight()
|
||||
{
|
||||
if (mScrollArea == NULL)
|
||||
{
|
||||
throw GCN_EXCEPTION("Scroll area has been deleted.");
|
||||
}
|
||||
|
||||
if (mListBox == NULL)
|
||||
{
|
||||
throw GCN_EXCEPTION("List box has been deleted.");
|
||||
}
|
||||
|
||||
int listBoxHeight = mListBox->getHeight();
|
||||
|
||||
// We add 2 for the border
|
||||
int h2 = getFont()->getHeight() + 2;
|
||||
|
||||
setHeight(h2);
|
||||
|
||||
// The addition/subtraction of 2 compensates for the seperation lines
|
||||
// seperating the selected element view and the scroll area.
|
||||
|
||||
if (mDroppedDown && getParent())
|
||||
{
|
||||
int h = getParent()->getChildrenArea().height - getY();
|
||||
|
||||
if (listBoxHeight > h - h2 - 2)
|
||||
{
|
||||
mScrollArea->setHeight(h - h2 - 2);
|
||||
setHeight(h);
|
||||
}
|
||||
else
|
||||
{
|
||||
setHeight(listBoxHeight + h2 + 2);
|
||||
mScrollArea->setHeight(listBoxHeight);
|
||||
}
|
||||
}
|
||||
|
||||
mScrollArea->setWidth(getWidth());
|
||||
// Resize the ListBox to exactly fit the ScrollArea.
|
||||
mListBox->setWidth(mScrollArea->getChildrenArea().width);
|
||||
mScrollArea->setPosition(0, 0);
|
||||
}
|
||||
|
||||
void DropDown::dropDown()
|
||||
{
|
||||
if (!mDroppedDown)
|
||||
{
|
||||
mDroppedDown = true;
|
||||
mFoldedUpHeight = getHeight();
|
||||
adjustHeight();
|
||||
|
||||
if (getParent())
|
||||
{
|
||||
getParent()->moveToTop(this);
|
||||
}
|
||||
}
|
||||
|
||||
mListBox->requestFocus();
|
||||
}
|
||||
|
||||
void DropDown::foldUp()
|
||||
{
|
||||
if (mDroppedDown)
|
||||
{
|
||||
mDroppedDown = false;
|
||||
adjustHeight();
|
||||
mInternalFocusHandler.focusNone();
|
||||
}
|
||||
}
|
||||
|
||||
void DropDown::focusLost(const Event& event)
|
||||
{
|
||||
foldUp();
|
||||
mInternalFocusHandler.focusNone();
|
||||
}
|
||||
|
||||
|
||||
void DropDown::death(const Event& event)
|
||||
{
|
||||
if (event.getSource() == mScrollArea)
|
||||
{
|
||||
mScrollArea = NULL;
|
||||
}
|
||||
|
||||
BasicContainer::death(event);
|
||||
}
|
||||
|
||||
void DropDown::action(const ActionEvent& actionEvent)
|
||||
{
|
||||
foldUp();
|
||||
releaseModalMouseInputFocus();
|
||||
distributeActionEvent();
|
||||
}
|
||||
|
||||
Rectangle DropDown::getChildrenArea()
|
||||
{
|
||||
if (mDroppedDown)
|
||||
{
|
||||
// Calculate the children area (with the one pixel border in mind)
|
||||
return Rectangle(1,
|
||||
mFoldedUpHeight + 1,
|
||||
getWidth() - 2,
|
||||
getHeight() - mFoldedUpHeight - 2);
|
||||
}
|
||||
|
||||
return Rectangle();
|
||||
}
|
||||
|
||||
void DropDown::setBaseColor(const Color& color)
|
||||
{
|
||||
if (mInternalScrollArea)
|
||||
{
|
||||
mScrollArea->setBaseColor(color);
|
||||
}
|
||||
|
||||
if (mInternalListBox)
|
||||
{
|
||||
mListBox->setBaseColor(color);
|
||||
}
|
||||
|
||||
Widget::setBaseColor(color);
|
||||
}
|
||||
|
||||
void DropDown::setBackgroundColor(const Color& color)
|
||||
{
|
||||
if (mInternalScrollArea)
|
||||
{
|
||||
mScrollArea->setBackgroundColor(color);
|
||||
}
|
||||
|
||||
if (mInternalListBox)
|
||||
{
|
||||
mListBox->setBackgroundColor(color);
|
||||
}
|
||||
|
||||
Widget::setBackgroundColor(color);
|
||||
}
|
||||
|
||||
void DropDown::setForegroundColor(const Color& color)
|
||||
{
|
||||
if (mInternalScrollArea)
|
||||
{
|
||||
mScrollArea->setForegroundColor(color);
|
||||
}
|
||||
|
||||
if (mInternalListBox)
|
||||
{
|
||||
mListBox->setForegroundColor(color);
|
||||
}
|
||||
|
||||
Widget::setForegroundColor(color);
|
||||
}
|
||||
|
||||
void DropDown::setFont(Font *font)
|
||||
{
|
||||
if (mInternalScrollArea)
|
||||
{
|
||||
mScrollArea->setFont(font);
|
||||
}
|
||||
|
||||
if (mInternalListBox)
|
||||
{
|
||||
mListBox->setFont(font);
|
||||
}
|
||||
|
||||
Widget::setFont(font);
|
||||
}
|
||||
|
||||
void DropDown::mouseWheelMovedUp(MouseEvent& mouseEvent)
|
||||
{
|
||||
if (isFocused() && mouseEvent.getSource() == this)
|
||||
{
|
||||
mouseEvent.consume();
|
||||
|
||||
if (mListBox->getSelected() > 0)
|
||||
{
|
||||
mListBox->setSelected(mListBox->getSelected() - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DropDown::mouseWheelMovedDown(MouseEvent& mouseEvent)
|
||||
{
|
||||
if (isFocused() && mouseEvent.getSource() == this)
|
||||
{
|
||||
mouseEvent.consume();
|
||||
|
||||
mListBox->setSelected(mListBox->getSelected() + 1);
|
||||
}
|
||||
}
|
||||
|
||||
void DropDown::setSelectionColor(const Color& color)
|
||||
{
|
||||
Widget::setSelectionColor(color);
|
||||
|
||||
if (mInternalListBox)
|
||||
{
|
||||
mListBox->setSelectionColor(color);
|
||||
}
|
||||
}
|
||||
|
||||
void DropDown::valueChanged(const SelectionEvent& event)
|
||||
{
|
||||
distributeValueChangedEvent();
|
||||
}
|
||||
|
||||
void DropDown::addSelectionListener(SelectionListener* selectionListener)
|
||||
{
|
||||
mSelectionListeners.push_back(selectionListener);
|
||||
}
|
||||
|
||||
void DropDown::removeSelectionListener(SelectionListener* selectionListener)
|
||||
{
|
||||
mSelectionListeners.remove(selectionListener);
|
||||
}
|
||||
|
||||
void DropDown::distributeValueChangedEvent()
|
||||
{
|
||||
SelectionListenerIterator iter;
|
||||
|
||||
for (iter = mSelectionListeners.begin(); iter != mSelectionListeners.end(); ++iter)
|
||||
{
|
||||
SelectionEvent event(this);
|
||||
(*iter)->valueChanged(event);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
116
project/jni/guichan/src/widgets/icon.cpp
Normal file
116
project/jni/guichan/src/widgets/icon.cpp
Normal file
@@ -0,0 +1,116 @@
|
||||
/* _______ __ __ __ ______ __ __ _______ __ __
|
||||
* / _____/\ / /\ / /\ / /\ / ____/\ / /\ / /\ / ___ /\ / |\/ /\
|
||||
* / /\____\// / // / // / // /\___\// /_// / // /\_/ / // , |/ / /
|
||||
* / / /__ / / // / // / // / / / ___ / // ___ / // /| ' / /
|
||||
* / /_// /\ / /_// / // / // /_/_ / / // / // /\_/ / // / | / /
|
||||
* /______/ //______/ //_/ //_____/\ /_/ //_/ //_/ //_/ //_/ /|_/ /
|
||||
* \______\/ \______\/ \_\/ \_____\/ \_\/ \_\/ \_\/ \_\/ \_\/ \_\/
|
||||
*
|
||||
* Copyright (c) 2004 - 2008 Olof Naessén and Per Larsson
|
||||
*
|
||||
*
|
||||
* Per Larsson a.k.a finalman
|
||||
* Olof Naessén a.k.a jansem/yakslem
|
||||
*
|
||||
* Visit: http://guichan.sourceforge.net
|
||||
*
|
||||
* License: (BSD)
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* 3. Neither the name of Guichan nor the names of its contributors may
|
||||
* be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
|
||||
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* For comments regarding functions please see the header file.
|
||||
*/
|
||||
|
||||
#include "guichan/widgets/icon.hpp"
|
||||
|
||||
#include "guichan/graphics.hpp"
|
||||
#include "guichan/image.hpp"
|
||||
#include "guichan/rectangle.hpp"
|
||||
|
||||
namespace gcn
|
||||
{
|
||||
Icon::Icon()
|
||||
: mImage(0)
|
||||
, mInternalImage(false)
|
||||
{
|
||||
setSize(0, 0);
|
||||
}
|
||||
|
||||
Icon::Icon(const std::string& filename)
|
||||
: mImage(0),
|
||||
mInternalImage(false)
|
||||
{
|
||||
mImage = Image::load(filename);
|
||||
mInternalImage = true;
|
||||
setSize(mImage->getWidth(),
|
||||
mImage->getHeight());
|
||||
}
|
||||
|
||||
Icon::Icon(const Image* image)
|
||||
: mImage(image),
|
||||
mInternalImage(false)
|
||||
{
|
||||
setSize(mImage->getWidth(),
|
||||
mImage->getHeight());
|
||||
}
|
||||
|
||||
Icon::~Icon()
|
||||
{
|
||||
if (mInternalImage)
|
||||
{
|
||||
delete mImage;
|
||||
}
|
||||
}
|
||||
|
||||
void Icon::setImage(const Image* image)
|
||||
{
|
||||
if (mInternalImage)
|
||||
{
|
||||
delete mImage;
|
||||
}
|
||||
|
||||
mImage = image;
|
||||
mInternalImage = false;
|
||||
setSize(mImage->getWidth(),
|
||||
mImage->getHeight());
|
||||
}
|
||||
|
||||
const Image* Icon::getImage() const
|
||||
{
|
||||
return mImage;
|
||||
}
|
||||
|
||||
void Icon::draw(Graphics* graphics)
|
||||
{
|
||||
if (mImage != NULL)
|
||||
{
|
||||
const int x = (getWidth() - mImage->getWidth()) / 2;
|
||||
const int y = (getHeight() - mImage->getHeight()) / 2;
|
||||
graphics->drawImage(mImage, x, y);
|
||||
}
|
||||
}
|
||||
}
|
||||
166
project/jni/guichan/src/widgets/imagebutton.cpp
Normal file
166
project/jni/guichan/src/widgets/imagebutton.cpp
Normal file
@@ -0,0 +1,166 @@
|
||||
/* _______ __ __ __ ______ __ __ _______ __ __
|
||||
* / _____/\ / /\ / /\ / /\ / ____/\ / /\ / /\ / ___ /\ / |\/ /\
|
||||
* / /\____\// / // / // / // /\___\// /_// / // /\_/ / // , |/ / /
|
||||
* / / /__ / / // / // / // / / / ___ / // ___ / // /| ' / /
|
||||
* / /_// /\ / /_// / // / // /_/_ / / // / // /\_/ / // / | / /
|
||||
* /______/ //______/ //_/ //_____/\ /_/ //_/ //_/ //_/ //_/ /|_/ /
|
||||
* \______\/ \______\/ \_\/ \_____\/ \_\/ \_\/ \_\/ \_\/ \_\/ \_\/
|
||||
*
|
||||
* Copyright (c) 2004 - 2008 Olof Naessén and Per Larsson
|
||||
*
|
||||
*
|
||||
* Per Larsson a.k.a finalman
|
||||
* Olof Naessén a.k.a jansem/yakslem
|
||||
*
|
||||
* Visit: http://guichan.sourceforge.net
|
||||
*
|
||||
* License: (BSD)
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* 3. Neither the name of Guichan nor the names of its contributors may
|
||||
* be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
|
||||
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* For comments regarding functions please see the header file.
|
||||
*/
|
||||
|
||||
#include "guichan/widgets/imagebutton.hpp"
|
||||
|
||||
#include "guichan/graphics.hpp"
|
||||
#include "guichan/image.hpp"
|
||||
|
||||
namespace gcn
|
||||
{
|
||||
ImageButton::ImageButton()
|
||||
: mImage(0),
|
||||
mInternalImage(false)
|
||||
{
|
||||
setWidth(0);
|
||||
setHeight(0);
|
||||
}
|
||||
|
||||
ImageButton::ImageButton(const std::string& filename)
|
||||
: mImage(0),
|
||||
mInternalImage(false)
|
||||
{
|
||||
mImage = Image::load(filename);
|
||||
mInternalImage = true;
|
||||
setWidth(mImage->getWidth() + mImage->getWidth() / 2);
|
||||
setHeight(mImage->getHeight() + mImage->getHeight() / 2);
|
||||
}
|
||||
|
||||
ImageButton::ImageButton(const Image* image)
|
||||
: mImage(image),
|
||||
mInternalImage(false)
|
||||
{
|
||||
setWidth(mImage->getWidth() + mImage->getWidth() / 2);
|
||||
setHeight(mImage->getHeight() + mImage->getHeight() / 2);
|
||||
}
|
||||
|
||||
ImageButton::~ImageButton()
|
||||
{
|
||||
if (mInternalImage)
|
||||
{
|
||||
delete mImage;
|
||||
}
|
||||
}
|
||||
|
||||
void ImageButton::setImage(const Image* image)
|
||||
{
|
||||
if (mInternalImage)
|
||||
{
|
||||
delete mImage;
|
||||
}
|
||||
|
||||
mImage = image;
|
||||
mInternalImage = false;
|
||||
}
|
||||
|
||||
const Image* ImageButton::getImage() const
|
||||
{
|
||||
return mImage;
|
||||
}
|
||||
|
||||
void ImageButton::draw(Graphics* graphics)
|
||||
{
|
||||
gcn::Color faceColor = getBaseColor();
|
||||
gcn::Color highlightColor, shadowColor;
|
||||
int alpha = getBaseColor().a;
|
||||
|
||||
if (isPressed())
|
||||
{
|
||||
faceColor = faceColor - 0x303030;
|
||||
faceColor.a = alpha;
|
||||
highlightColor = faceColor - 0x303030;
|
||||
highlightColor.a = alpha;
|
||||
shadowColor = faceColor + 0x303030;
|
||||
shadowColor.a = alpha;
|
||||
}
|
||||
else
|
||||
{
|
||||
highlightColor = faceColor + 0x303030;
|
||||
highlightColor.a = alpha;
|
||||
shadowColor = faceColor - 0x303030;
|
||||
shadowColor.a = alpha;
|
||||
}
|
||||
|
||||
graphics->setColor(faceColor);
|
||||
graphics->fillRectangle(Rectangle(1,
|
||||
1,
|
||||
getDimension().width - 1,
|
||||
getHeight() - 1));
|
||||
|
||||
graphics->setColor(highlightColor);
|
||||
graphics->drawLine(0, 0, getWidth() - 1, 0);
|
||||
graphics->drawLine(0, 1, 0, getHeight() - 1);
|
||||
|
||||
graphics->setColor(shadowColor);
|
||||
graphics->drawLine(getWidth() - 1, 1, getWidth() - 1, getHeight() - 1);
|
||||
graphics->drawLine(1, getHeight() - 1, getWidth() - 1, getHeight() - 1);
|
||||
|
||||
graphics->setColor(getForegroundColor());
|
||||
|
||||
const int textX = (getWidth() - (mImage ? mImage->getWidth() : 0) ) / 2;
|
||||
const int textY = (getHeight() - (mImage ? mImage->getHeight() : 0) ) / 2;
|
||||
|
||||
if (isPressed())
|
||||
{
|
||||
if(mImage)
|
||||
graphics->drawImage(mImage, textX + 1, textY + 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(mImage)
|
||||
graphics->drawImage(mImage, textX, textY);
|
||||
|
||||
if (isFocused())
|
||||
{
|
||||
graphics->drawRectangle(Rectangle(2,
|
||||
2,
|
||||
getWidth() - 4,
|
||||
getHeight() - 4));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
120
project/jni/guichan/src/widgets/label.cpp
Normal file
120
project/jni/guichan/src/widgets/label.cpp
Normal file
@@ -0,0 +1,120 @@
|
||||
/* _______ __ __ __ ______ __ __ _______ __ __
|
||||
* / _____/\ / /\ / /\ / /\ / ____/\ / /\ / /\ / ___ /\ / |\/ /\
|
||||
* / /\____\// / // / // / // /\___\// /_// / // /\_/ / // , |/ / /
|
||||
* / / /__ / / // / // / // / / / ___ / // ___ / // /| ' / /
|
||||
* / /_// /\ / /_// / // / // /_/_ / / // / // /\_/ / // / | / /
|
||||
* /______/ //______/ //_/ //_____/\ /_/ //_/ //_/ //_/ //_/ /|_/ /
|
||||
* \______\/ \______\/ \_\/ \_____\/ \_\/ \_\/ \_\/ \_\/ \_\/ \_\/
|
||||
*
|
||||
* Copyright (c) 2004 - 2008 Olof Naessén and Per Larsson
|
||||
*
|
||||
*
|
||||
* Per Larsson a.k.a finalman
|
||||
* Olof Naessén a.k.a jansem/yakslem
|
||||
*
|
||||
* Visit: http://guichan.sourceforge.net
|
||||
*
|
||||
* License: (BSD)
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* 3. Neither the name of Guichan nor the names of its contributors may
|
||||
* be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
|
||||
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* For comments regarding functions please see the header file.
|
||||
*/
|
||||
|
||||
#include "guichan/widgets/label.hpp"
|
||||
|
||||
#include "guichan/exception.hpp"
|
||||
#include "guichan/font.hpp"
|
||||
#include "guichan/graphics.hpp"
|
||||
|
||||
namespace gcn
|
||||
{
|
||||
Label::Label()
|
||||
{
|
||||
mAlignment = Graphics::LEFT;
|
||||
}
|
||||
|
||||
Label::Label(const std::string& caption)
|
||||
{
|
||||
mCaption = caption;
|
||||
mAlignment = Graphics::LEFT;
|
||||
|
||||
setWidth(getFont()->getWidth(caption));
|
||||
setHeight(getFont()->getHeight());
|
||||
}
|
||||
|
||||
const std::string &Label::getCaption() const
|
||||
{
|
||||
return mCaption;
|
||||
}
|
||||
|
||||
void Label::setCaption(const std::string& caption)
|
||||
{
|
||||
mCaption = caption;
|
||||
}
|
||||
|
||||
void Label::setAlignment(Graphics::Alignment alignment)
|
||||
{
|
||||
mAlignment = alignment;
|
||||
}
|
||||
|
||||
Graphics::Alignment Label::getAlignment() const
|
||||
{
|
||||
return mAlignment;
|
||||
}
|
||||
|
||||
void Label::draw(Graphics* graphics)
|
||||
{
|
||||
int textX;
|
||||
int textY = getHeight() / 2 - getFont()->getHeight() / 2;
|
||||
|
||||
switch (getAlignment())
|
||||
{
|
||||
case Graphics::LEFT:
|
||||
textX = 0;
|
||||
break;
|
||||
case Graphics::CENTER:
|
||||
textX = getWidth() / 2;
|
||||
break;
|
||||
case Graphics::RIGHT:
|
||||
textX = getWidth();
|
||||
break;
|
||||
default:
|
||||
throw GCN_EXCEPTION("Unknown alignment.");
|
||||
}
|
||||
|
||||
graphics->setFont(getFont());
|
||||
graphics->setColor(getForegroundColor());
|
||||
graphics->drawText(getCaption(), textX, textY, getAlignment());
|
||||
}
|
||||
|
||||
void Label::adjustSize()
|
||||
{
|
||||
setWidth(getFont()->getWidth(getCaption()));
|
||||
setHeight(getFont()->getHeight());
|
||||
}
|
||||
}
|
||||
350
project/jni/guichan/src/widgets/listbox.cpp
Normal file
350
project/jni/guichan/src/widgets/listbox.cpp
Normal file
@@ -0,0 +1,350 @@
|
||||
/* _______ __ __ __ ______ __ __ _______ __ __
|
||||
* / _____/\ / /\ / /\ / /\ / ____/\ / /\ / /\ / ___ /\ / |\/ /\
|
||||
* / /\____\// / // / // / // /\___\// /_// / // /\_/ / // , |/ / /
|
||||
* / / /__ / / // / // / // / / / ___ / // ___ / // /| ' / /
|
||||
* / /_// /\ / /_// / // / // /_/_ / / // / // /\_/ / // / | / /
|
||||
* /______/ //______/ //_/ //_____/\ /_/ //_/ //_/ //_/ //_/ /|_/ /
|
||||
* \______\/ \______\/ \_\/ \_____\/ \_\/ \_\/ \_\/ \_\/ \_\/ \_\/
|
||||
*
|
||||
* Copyright (c) 2004 - 2008 Olof Naessén and Per Larsson
|
||||
*
|
||||
*
|
||||
* Per Larsson a.k.a finalman
|
||||
* Olof Naessén a.k.a jansem/yakslem
|
||||
*
|
||||
* Visit: http://guichan.sourceforge.net
|
||||
*
|
||||
* License: (BSD)
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* 3. Neither the name of Guichan nor the names of its contributors may
|
||||
* be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
|
||||
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* For comments regarding functions please see the header file.
|
||||
*/
|
||||
|
||||
#include "guichan/widgets/listbox.hpp"
|
||||
|
||||
#include "guichan/basiccontainer.hpp"
|
||||
#include "guichan/font.hpp"
|
||||
#include "guichan/graphics.hpp"
|
||||
#include "guichan/key.hpp"
|
||||
#include "guichan/listmodel.hpp"
|
||||
#include "guichan/mouseinput.hpp"
|
||||
#include "guichan/selectionlistener.hpp"
|
||||
|
||||
namespace gcn
|
||||
{
|
||||
ListBox::ListBox()
|
||||
: mSelected(-1),
|
||||
mListModel(NULL),
|
||||
mWrappingEnabled(false)
|
||||
{
|
||||
setWidth(100);
|
||||
setFocusable(true);
|
||||
|
||||
addMouseListener(this);
|
||||
addKeyListener(this);
|
||||
}
|
||||
|
||||
ListBox::ListBox(ListModel *listModel)
|
||||
: mSelected(-1),
|
||||
mWrappingEnabled(false)
|
||||
{
|
||||
setWidth(100);
|
||||
setListModel(listModel);
|
||||
setFocusable(true);
|
||||
|
||||
addMouseListener(this);
|
||||
addKeyListener(this);
|
||||
}
|
||||
|
||||
void ListBox::draw(Graphics* graphics)
|
||||
{
|
||||
graphics->setColor(getBackgroundColor());
|
||||
graphics->fillRectangle(Rectangle(0, 0, getWidth(), getHeight()));
|
||||
|
||||
if (mListModel == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
graphics->setColor(getForegroundColor());
|
||||
graphics->setFont(getFont());
|
||||
|
||||
// Check the current clip area so we don't draw unnecessary items
|
||||
// that are not visible.
|
||||
const ClipRectangle currentClipArea = graphics->getCurrentClipArea();
|
||||
int rowHeight = getRowHeight();
|
||||
|
||||
// Calculate the number of rows to draw by checking the clip area.
|
||||
// The addition of two makes covers a partial visible row at the top
|
||||
// and a partial visible row at the bottom.
|
||||
int numberOfRows = currentClipArea.height / rowHeight + 2;
|
||||
|
||||
if (numberOfRows > mListModel->getNumberOfElements())
|
||||
{
|
||||
numberOfRows = mListModel->getNumberOfElements();
|
||||
}
|
||||
|
||||
// Calculate which row to start drawing. If the list box
|
||||
// has a negative y coordinate value we should check if
|
||||
// we should drop rows in the begining of the list as
|
||||
// they might not be visible. A negative y value is very
|
||||
// common if the list box for instance resides in a scroll
|
||||
// area and the user has scrolled the list box downwards.
|
||||
int startRow;
|
||||
if (getY() < 0)
|
||||
{
|
||||
startRow = -1 * (getY() / rowHeight);
|
||||
}
|
||||
else
|
||||
{
|
||||
startRow = 0;
|
||||
}
|
||||
|
||||
int i;
|
||||
// The y coordinate where we start to draw the text is
|
||||
// simply the y coordinate multiplied with the font height.
|
||||
int y = rowHeight * startRow;
|
||||
for (i = startRow; i < startRow + numberOfRows; ++i)
|
||||
{
|
||||
if (i == mSelected)
|
||||
{
|
||||
graphics->setColor(getSelectionColor());
|
||||
graphics->fillRectangle(Rectangle(0, y, getWidth(), rowHeight));
|
||||
graphics->setColor(getForegroundColor());
|
||||
}
|
||||
|
||||
// If the row height is greater than the font height we
|
||||
// draw the text with a center vertical alignment.
|
||||
if (rowHeight > getFont()->getHeight())
|
||||
{
|
||||
graphics->drawText(mListModel->getElementAt(i), 1, y + rowHeight / 2 - getFont()->getHeight() / 2);
|
||||
}
|
||||
else
|
||||
{
|
||||
graphics->drawText(mListModel->getElementAt(i), 1, y);
|
||||
}
|
||||
|
||||
y += rowHeight;
|
||||
}
|
||||
}
|
||||
|
||||
void ListBox::logic()
|
||||
{
|
||||
adjustSize();
|
||||
}
|
||||
|
||||
int ListBox::getSelected() const
|
||||
{
|
||||
return mSelected;
|
||||
}
|
||||
|
||||
void ListBox::setSelected(int selected)
|
||||
{
|
||||
if (mListModel == NULL)
|
||||
{
|
||||
mSelected = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (selected < 0)
|
||||
{
|
||||
mSelected = -1;
|
||||
}
|
||||
else if (selected >= mListModel->getNumberOfElements())
|
||||
{
|
||||
mSelected = mListModel->getNumberOfElements() - 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
mSelected = selected;
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle scroll;
|
||||
|
||||
if (mSelected < 0)
|
||||
{
|
||||
scroll.y = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
scroll.y = getRowHeight() * mSelected;
|
||||
}
|
||||
|
||||
scroll.height = getRowHeight();
|
||||
showPart(scroll);
|
||||
|
||||
distributeValueChangedEvent();
|
||||
}
|
||||
|
||||
void ListBox::keyPressed(KeyEvent& keyEvent)
|
||||
{
|
||||
Key key = keyEvent.getKey();
|
||||
|
||||
if (key.getValue() == Key::ENTER || key.getValue() == Key::SPACE)
|
||||
{
|
||||
distributeActionEvent();
|
||||
keyEvent.consume();
|
||||
}
|
||||
else if (key.getValue() == Key::UP)
|
||||
{
|
||||
setSelected(mSelected - 1);
|
||||
|
||||
if (mSelected == -1)
|
||||
{
|
||||
if (mWrappingEnabled)
|
||||
{
|
||||
setSelected(getListModel()->getNumberOfElements() - 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
setSelected(0);
|
||||
}
|
||||
}
|
||||
|
||||
keyEvent.consume();
|
||||
}
|
||||
else if (key.getValue() == Key::DOWN)
|
||||
{
|
||||
if (mWrappingEnabled
|
||||
&& getSelected() == getListModel()->getNumberOfElements() - 1)
|
||||
{
|
||||
setSelected(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
setSelected(getSelected() + 1);
|
||||
}
|
||||
|
||||
keyEvent.consume();
|
||||
}
|
||||
else if (key.getValue() == Key::HOME)
|
||||
{
|
||||
setSelected(0);
|
||||
keyEvent.consume();
|
||||
}
|
||||
else if (key.getValue() == Key::END)
|
||||
{
|
||||
setSelected(getListModel()->getNumberOfElements() - 1);
|
||||
keyEvent.consume();
|
||||
}
|
||||
}
|
||||
|
||||
void ListBox::mousePressed(MouseEvent& mouseEvent)
|
||||
{
|
||||
if (mouseEvent.getButton() == MouseEvent::LEFT)
|
||||
{
|
||||
setSelected(mouseEvent.getY() / getRowHeight());
|
||||
distributeActionEvent();
|
||||
}
|
||||
}
|
||||
|
||||
void ListBox::mouseWheelMovedUp(MouseEvent& mouseEvent)
|
||||
{
|
||||
if (isFocused())
|
||||
{
|
||||
if (getSelected() > 0 )
|
||||
{
|
||||
setSelected(getSelected() - 1);
|
||||
}
|
||||
|
||||
mouseEvent.consume();
|
||||
}
|
||||
}
|
||||
|
||||
void ListBox::mouseWheelMovedDown(MouseEvent& mouseEvent)
|
||||
{
|
||||
if (isFocused())
|
||||
{
|
||||
setSelected(getSelected() + 1);
|
||||
|
||||
mouseEvent.consume();
|
||||
}
|
||||
}
|
||||
|
||||
void ListBox::mouseDragged(MouseEvent& mouseEvent)
|
||||
{
|
||||
mouseEvent.consume();
|
||||
}
|
||||
|
||||
void ListBox::setListModel(ListModel *listModel)
|
||||
{
|
||||
mSelected = -1;
|
||||
mListModel = listModel;
|
||||
adjustSize();
|
||||
}
|
||||
|
||||
ListModel* ListBox::getListModel()
|
||||
{
|
||||
return mListModel;
|
||||
}
|
||||
|
||||
void ListBox::adjustSize()
|
||||
{
|
||||
if (mListModel != NULL)
|
||||
{
|
||||
setHeight(getRowHeight() * mListModel->getNumberOfElements());
|
||||
}
|
||||
}
|
||||
|
||||
bool ListBox::isWrappingEnabled() const
|
||||
{
|
||||
return mWrappingEnabled;
|
||||
}
|
||||
|
||||
void ListBox::setWrappingEnabled(bool wrappingEnabled)
|
||||
{
|
||||
mWrappingEnabled = wrappingEnabled;
|
||||
}
|
||||
|
||||
void ListBox::addSelectionListener(SelectionListener* selectionListener)
|
||||
{
|
||||
mSelectionListeners.push_back(selectionListener);
|
||||
}
|
||||
|
||||
void ListBox::removeSelectionListener(SelectionListener* selectionListener)
|
||||
{
|
||||
mSelectionListeners.remove(selectionListener);
|
||||
}
|
||||
|
||||
void ListBox::distributeValueChangedEvent()
|
||||
{
|
||||
SelectionListenerIterator iter;
|
||||
|
||||
for (iter = mSelectionListeners.begin(); iter != mSelectionListeners.end(); ++iter)
|
||||
{
|
||||
SelectionEvent event(this);
|
||||
(*iter)->valueChanged(event);
|
||||
}
|
||||
}
|
||||
|
||||
unsigned int ListBox::getRowHeight() const
|
||||
{
|
||||
return getFont()->getHeight();
|
||||
}
|
||||
}
|
||||
298
project/jni/guichan/src/widgets/radiobutton.cpp
Normal file
298
project/jni/guichan/src/widgets/radiobutton.cpp
Normal file
@@ -0,0 +1,298 @@
|
||||
/* _______ __ __ __ ______ __ __ _______ __ __
|
||||
* / _____/\ / /\ / /\ / /\ / ____/\ / /\ / /\ / ___ /\ / |\/ /\
|
||||
* / /\____\// / // / // / // /\___\// /_// / // /\_/ / // , |/ / /
|
||||
* / / /__ / / // / // / // / / / ___ / // ___ / // /| ' / /
|
||||
* / /_// /\ / /_// / // / // /_/_ / / // / // /\_/ / // / | / /
|
||||
* /______/ //______/ //_/ //_____/\ /_/ //_/ //_/ //_/ //_/ /|_/ /
|
||||
* \______\/ \______\/ \_\/ \_____\/ \_\/ \_\/ \_\/ \_\/ \_\/ \_\/
|
||||
*
|
||||
* Copyright (c) 2004 - 2008 Olof Naessén and Per Larsson
|
||||
*
|
||||
*
|
||||
* Per Larsson a.k.a finalman
|
||||
* Olof Naessén a.k.a jansem/yakslem
|
||||
*
|
||||
* Visit: http://guichan.sourceforge.net
|
||||
*
|
||||
* License: (BSD)
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* 3. Neither the name of Guichan nor the names of its contributors may
|
||||
* be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
|
||||
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* For comments regarding functions please see the header file.
|
||||
*/
|
||||
|
||||
#include "guichan/widgets/radiobutton.hpp"
|
||||
|
||||
#include "guichan/font.hpp"
|
||||
#include "guichan/graphics.hpp"
|
||||
#include "guichan/key.hpp"
|
||||
#include "guichan/mouseinput.hpp"
|
||||
|
||||
namespace gcn
|
||||
{
|
||||
RadioButton::GroupMap RadioButton::mGroupMap;
|
||||
|
||||
RadioButton::RadioButton()
|
||||
{
|
||||
setSelected(false);
|
||||
|
||||
setFocusable(true);
|
||||
addMouseListener(this);
|
||||
addKeyListener(this);
|
||||
}
|
||||
|
||||
RadioButton::RadioButton(const std::string &caption,
|
||||
const std::string &group,
|
||||
bool selected)
|
||||
{
|
||||
setCaption(caption);
|
||||
setGroup(group);
|
||||
setSelected(selected);
|
||||
|
||||
setFocusable(true);
|
||||
addMouseListener(this);
|
||||
addKeyListener(this);
|
||||
|
||||
adjustSize();
|
||||
}
|
||||
|
||||
RadioButton::~RadioButton()
|
||||
{
|
||||
// Remove us from the group list
|
||||
setGroup("");
|
||||
}
|
||||
|
||||
void RadioButton::draw(Graphics* graphics)
|
||||
{
|
||||
graphics->pushClipArea(Rectangle(1,
|
||||
1,
|
||||
getWidth() - 1,
|
||||
getHeight() - 1));
|
||||
drawBox(graphics);
|
||||
graphics->popClipArea();
|
||||
|
||||
|
||||
graphics->setFont(getFont());
|
||||
graphics->setColor(getForegroundColor());
|
||||
|
||||
if (isFocused())
|
||||
{
|
||||
int fh;
|
||||
|
||||
if (getHeight()%2 == 0)
|
||||
{
|
||||
fh = getHeight() - 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
fh = getHeight() - 3;
|
||||
}
|
||||
|
||||
int hh = (fh + 1) / 2;
|
||||
|
||||
graphics->drawLine(0, hh + 1, hh + 1, 0);
|
||||
graphics->drawLine(hh + 2, 1, fh + 2, hh + 1);
|
||||
graphics->drawLine(fh + 1, hh + 2, hh + 1, fh + 2);
|
||||
graphics->drawLine(hh + 1, fh + 2, 1, hh + 2);
|
||||
}
|
||||
|
||||
int h = getHeight() + getHeight() / 2;
|
||||
|
||||
graphics->drawText(getCaption(), h - 2, 0);
|
||||
}
|
||||
|
||||
void RadioButton::drawBox(Graphics *graphics)
|
||||
{
|
||||
int h;
|
||||
|
||||
if (getHeight()%2 == 0)
|
||||
{
|
||||
h = getHeight() - 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
h = getHeight() - 3;
|
||||
}
|
||||
|
||||
int alpha = getBaseColor().a;
|
||||
Color faceColor = getBaseColor();
|
||||
faceColor.a = alpha;
|
||||
Color highlightColor = faceColor + 0x303030;
|
||||
highlightColor.a = alpha;
|
||||
Color shadowColor = faceColor - 0x303030;
|
||||
shadowColor.a = alpha;
|
||||
|
||||
graphics->setColor(getBackgroundColor());
|
||||
|
||||
int i;
|
||||
int hh = (h + 1) / 2;
|
||||
|
||||
for (i = 1; i <= hh; ++i)
|
||||
{
|
||||
graphics->drawLine(hh - i + 1,
|
||||
i,
|
||||
hh + i - 1,
|
||||
i);
|
||||
}
|
||||
|
||||
for (i = 1; i < hh; ++i)
|
||||
{
|
||||
graphics->drawLine(hh - i + 1,
|
||||
h - i,
|
||||
hh + i - 1,
|
||||
h - i);
|
||||
}
|
||||
|
||||
graphics->setColor(shadowColor);
|
||||
graphics->drawLine(hh, 0, 0, hh);
|
||||
graphics->drawLine(hh + 1, 1, h - 1, hh - 1);
|
||||
|
||||
graphics->setColor(highlightColor);
|
||||
graphics->drawLine(1, hh + 1, hh, h);
|
||||
graphics->drawLine(hh + 1, h - 1, h, hh);
|
||||
|
||||
graphics->setColor(getForegroundColor());
|
||||
|
||||
int hhh = hh - 3;
|
||||
if (mSelected)
|
||||
{
|
||||
for (i = 0; i < hhh; ++i)
|
||||
{
|
||||
graphics->drawLine(hh - i, 4 + i, hh + i, 4 + i);
|
||||
}
|
||||
for (i = 0; i < hhh; ++i)
|
||||
{
|
||||
graphics->drawLine(hh - i, h - 4 - i, hh + i, h - 4 - i);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
bool RadioButton::isSelected() const
|
||||
{
|
||||
return mSelected;
|
||||
}
|
||||
|
||||
void RadioButton::setSelected(bool selected)
|
||||
{
|
||||
if (selected && mGroup != "")
|
||||
{
|
||||
GroupIterator iter, iterEnd;
|
||||
iterEnd = mGroupMap.upper_bound(mGroup);
|
||||
|
||||
for (iter = mGroupMap.lower_bound(mGroup);
|
||||
iter != iterEnd;
|
||||
iter++)
|
||||
{
|
||||
if (iter->second->isSelected())
|
||||
{
|
||||
iter->second->setSelected(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mSelected = selected;
|
||||
}
|
||||
|
||||
const std::string &RadioButton::getCaption() const
|
||||
{
|
||||
return mCaption;
|
||||
}
|
||||
|
||||
void RadioButton::setCaption(const std::string caption)
|
||||
{
|
||||
mCaption = caption;
|
||||
}
|
||||
|
||||
void RadioButton::keyPressed(KeyEvent& keyEvent)
|
||||
{
|
||||
Key key = keyEvent.getKey();
|
||||
|
||||
if (key.getValue() == Key::ENTER ||
|
||||
key.getValue() == Key::SPACE)
|
||||
{
|
||||
setSelected(true);
|
||||
distributeActionEvent();
|
||||
keyEvent.consume();
|
||||
}
|
||||
}
|
||||
|
||||
void RadioButton::mouseClicked(MouseEvent& mouseEvent)
|
||||
{
|
||||
if (mouseEvent.getButton() == MouseEvent::LEFT)
|
||||
{
|
||||
setSelected(true);
|
||||
distributeActionEvent();
|
||||
}
|
||||
}
|
||||
|
||||
void RadioButton::mouseDragged(MouseEvent& mouseEvent)
|
||||
{
|
||||
mouseEvent.consume();
|
||||
}
|
||||
|
||||
void RadioButton::setGroup(const std::string &group)
|
||||
{
|
||||
if (mGroup != "")
|
||||
{
|
||||
GroupIterator iter, iterEnd;
|
||||
iterEnd = mGroupMap.upper_bound(mGroup);
|
||||
|
||||
for (iter = mGroupMap.lower_bound(mGroup);
|
||||
iter != iterEnd;
|
||||
iter++)
|
||||
{
|
||||
if (iter->second == this)
|
||||
{
|
||||
mGroupMap.erase(iter);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (group != "")
|
||||
{
|
||||
mGroupMap.insert(
|
||||
std::pair<std::string, RadioButton *>(group, this));
|
||||
}
|
||||
|
||||
mGroup = group;
|
||||
}
|
||||
|
||||
const std::string &RadioButton::getGroup() const
|
||||
{
|
||||
return mGroup;
|
||||
}
|
||||
|
||||
void RadioButton::adjustSize()
|
||||
{
|
||||
int height = getFont()->getHeight();
|
||||
|
||||
setHeight(height);
|
||||
setWidth(getFont()->getWidth(getCaption()) + height + height/2);
|
||||
}
|
||||
}
|
||||
1246
project/jni/guichan/src/widgets/scrollarea.cpp
Normal file
1246
project/jni/guichan/src/widgets/scrollarea.cpp
Normal file
File diff suppressed because it is too large
Load Diff
369
project/jni/guichan/src/widgets/slider.cpp
Normal file
369
project/jni/guichan/src/widgets/slider.cpp
Normal file
@@ -0,0 +1,369 @@
|
||||
/* _______ __ __ __ ______ __ __ _______ __ __
|
||||
* / _____/\ / /\ / /\ / /\ / ____/\ / /\ / /\ / ___ /\ / |\/ /\
|
||||
* / /\____\// / // / // / // /\___\// /_// / // /\_/ / // , |/ / /
|
||||
* / / /__ / / // / // / // / / / ___ / // ___ / // /| ' / /
|
||||
* / /_// /\ / /_// / // / // /_/_ / / // / // /\_/ / // / | / /
|
||||
* /______/ //______/ //_/ //_____/\ /_/ //_/ //_/ //_/ //_/ /|_/ /
|
||||
* \______\/ \______\/ \_\/ \_____\/ \_\/ \_\/ \_\/ \_\/ \_\/ \_\/
|
||||
*
|
||||
* Copyright (c) 2004 - 2008 Olof Naessén and Per Larsson
|
||||
*
|
||||
*
|
||||
* Per Larsson a.k.a finalman
|
||||
* Olof Naessén a.k.a jansem/yakslem
|
||||
*
|
||||
* Visit: http://guichan.sourceforge.net
|
||||
*
|
||||
* License: (BSD)
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* 3. Neither the name of Guichan nor the names of its contributors may
|
||||
* be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
|
||||
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* For comments regarding functions please see the header file.
|
||||
*/
|
||||
|
||||
#include "guichan/widgets/slider.hpp"
|
||||
|
||||
#include "guichan/graphics.hpp"
|
||||
#include "guichan/key.hpp"
|
||||
#include "guichan/mouseinput.hpp"
|
||||
|
||||
namespace gcn
|
||||
{
|
||||
Slider::Slider(double scaleEnd)
|
||||
{
|
||||
mDragged = false;
|
||||
|
||||
mScaleStart = 0;
|
||||
mScaleEnd = scaleEnd;
|
||||
|
||||
setFocusable(true);
|
||||
setFrameSize(1);
|
||||
setOrientation(HORIZONTAL);
|
||||
setValue(0);
|
||||
setStepLength(scaleEnd / 10);
|
||||
setMarkerLength(10);
|
||||
|
||||
addMouseListener(this);
|
||||
addKeyListener(this);
|
||||
}
|
||||
|
||||
Slider::Slider(double scaleStart, double scaleEnd)
|
||||
{
|
||||
mDragged = false;
|
||||
|
||||
mScaleStart = scaleStart;
|
||||
mScaleEnd = scaleEnd;
|
||||
|
||||
setFocusable(true);
|
||||
setFrameSize(1);
|
||||
setOrientation(HORIZONTAL);
|
||||
setValue(scaleStart);
|
||||
setStepLength((scaleEnd - scaleStart)/ 10);
|
||||
setMarkerLength(10);
|
||||
|
||||
addMouseListener(this);
|
||||
addKeyListener(this);
|
||||
}
|
||||
|
||||
void Slider::setScale(double scaleStart, double scaleEnd)
|
||||
{
|
||||
mScaleStart = scaleStart;
|
||||
mScaleEnd = scaleEnd;
|
||||
}
|
||||
|
||||
double Slider::getScaleStart() const
|
||||
{
|
||||
return mScaleStart;
|
||||
}
|
||||
|
||||
void Slider::setScaleStart(double scaleStart)
|
||||
{
|
||||
mScaleStart = scaleStart;
|
||||
}
|
||||
|
||||
double Slider::getScaleEnd() const
|
||||
{
|
||||
return mScaleEnd;
|
||||
}
|
||||
|
||||
void Slider::setScaleEnd(double scaleEnd)
|
||||
{
|
||||
mScaleEnd = scaleEnd;
|
||||
}
|
||||
|
||||
void Slider::draw(gcn::Graphics* graphics)
|
||||
{
|
||||
Color shadowColor = getBaseColor() - 0x101010;
|
||||
int alpha = getBaseColor().a;
|
||||
shadowColor.a = alpha;
|
||||
|
||||
graphics->setColor(shadowColor);
|
||||
graphics->fillRectangle(gcn::Rectangle(0,0,getWidth(),getHeight()));
|
||||
|
||||
drawMarker(graphics);
|
||||
}
|
||||
|
||||
void Slider::drawMarker(gcn::Graphics* graphics)
|
||||
{
|
||||
gcn::Color faceColor = getBaseColor();
|
||||
Color highlightColor, shadowColor;
|
||||
int alpha = getBaseColor().a;
|
||||
highlightColor = faceColor + 0x303030;
|
||||
highlightColor.a = alpha;
|
||||
shadowColor = faceColor - 0x303030;
|
||||
shadowColor.a = alpha;
|
||||
|
||||
graphics->setColor(faceColor);
|
||||
|
||||
if (getOrientation() == HORIZONTAL)
|
||||
{
|
||||
int v = getMarkerPosition();
|
||||
graphics->fillRectangle(gcn::Rectangle(v + 1, 1, getMarkerLength() - 2, getHeight() - 2));
|
||||
graphics->setColor(highlightColor);
|
||||
graphics->drawLine(v, 0, v + getMarkerLength() - 1,0);
|
||||
graphics->drawLine(v, 0, v, getHeight() - 1);
|
||||
graphics->setColor(shadowColor);
|
||||
graphics->drawLine(v + getMarkerLength() - 1, 1, v + getMarkerLength() - 1, getHeight() - 1);
|
||||
graphics->drawLine(v + 1, getHeight() - 1, v + getMarkerLength() - 1, getHeight() - 1);
|
||||
|
||||
if (isFocused())
|
||||
{
|
||||
graphics->setColor(getForegroundColor());
|
||||
graphics->drawRectangle(Rectangle(v + 2, 2, getMarkerLength() - 4, getHeight() - 4));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
int v = (getHeight() - getMarkerLength()) - getMarkerPosition();
|
||||
graphics->fillRectangle(gcn::Rectangle(1, v + 1, getWidth() - 2, getMarkerLength() - 2));
|
||||
graphics->setColor(highlightColor);
|
||||
graphics->drawLine(0, v, 0, v + getMarkerLength() - 1);
|
||||
graphics->drawLine(0, v, getWidth() - 1, v);
|
||||
graphics->setColor(shadowColor);
|
||||
graphics->drawLine(1, v + getMarkerLength() - 1, getWidth() - 1, v + getMarkerLength() - 1);
|
||||
graphics->drawLine(getWidth() - 1, v + 1, getWidth() - 1, v + getMarkerLength() - 1);
|
||||
|
||||
if (isFocused())
|
||||
{
|
||||
graphics->setColor(getForegroundColor());
|
||||
graphics->drawRectangle(Rectangle(2, v + 2, getWidth() - 4, getMarkerLength() - 4));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Slider::mousePressed(MouseEvent& mouseEvent)
|
||||
{
|
||||
if (mouseEvent.getButton() == gcn::MouseEvent::LEFT
|
||||
&& mouseEvent.getX() >= 0
|
||||
&& mouseEvent.getX() <= getWidth()
|
||||
&& mouseEvent.getY() >= 0
|
||||
&& mouseEvent.getY() <= getHeight())
|
||||
{
|
||||
if (getOrientation() == HORIZONTAL)
|
||||
{
|
||||
setValue(markerPositionToValue(mouseEvent.getX() - getMarkerLength() / 2));
|
||||
}
|
||||
else
|
||||
{
|
||||
setValue(markerPositionToValue(getHeight() - mouseEvent.getY() - getMarkerLength() / 2));
|
||||
}
|
||||
|
||||
distributeActionEvent();
|
||||
}
|
||||
}
|
||||
|
||||
void Slider::mouseDragged(MouseEvent& mouseEvent)
|
||||
{
|
||||
if (getOrientation() == HORIZONTAL)
|
||||
{
|
||||
setValue(markerPositionToValue(mouseEvent.getX() - getMarkerLength() / 2));
|
||||
}
|
||||
else
|
||||
{
|
||||
setValue(markerPositionToValue(getHeight() - mouseEvent.getY() - getMarkerLength() / 2));
|
||||
}
|
||||
|
||||
distributeActionEvent();
|
||||
|
||||
mouseEvent.consume();
|
||||
}
|
||||
|
||||
void Slider::setValue(double value)
|
||||
{
|
||||
if (value > getScaleEnd())
|
||||
{
|
||||
mValue = getScaleEnd();
|
||||
return;
|
||||
}
|
||||
|
||||
if (value < getScaleStart())
|
||||
{
|
||||
mValue = getScaleStart();
|
||||
return;
|
||||
}
|
||||
|
||||
mValue = value;
|
||||
}
|
||||
|
||||
double Slider::getValue() const
|
||||
{
|
||||
return mValue;
|
||||
}
|
||||
|
||||
int Slider::getMarkerLength() const
|
||||
{
|
||||
return mMarkerLength;
|
||||
}
|
||||
|
||||
void Slider::setMarkerLength(int length)
|
||||
{
|
||||
mMarkerLength = length;
|
||||
}
|
||||
|
||||
void Slider::keyPressed(KeyEvent& keyEvent)
|
||||
{
|
||||
Key key = keyEvent.getKey();
|
||||
|
||||
if (getOrientation() == HORIZONTAL)
|
||||
{
|
||||
if (key.getValue() == Key::RIGHT)
|
||||
{
|
||||
setValue(getValue() + getStepLength());
|
||||
distributeActionEvent();
|
||||
keyEvent.consume();
|
||||
}
|
||||
else if (key.getValue() == Key::LEFT)
|
||||
{
|
||||
setValue(getValue() - getStepLength());
|
||||
distributeActionEvent();
|
||||
keyEvent.consume();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (key.getValue() == Key::UP)
|
||||
{
|
||||
setValue(getValue() + getStepLength());
|
||||
distributeActionEvent();
|
||||
keyEvent.consume();
|
||||
}
|
||||
else if (key.getValue() == Key::DOWN)
|
||||
{
|
||||
setValue(getValue() - getStepLength());
|
||||
distributeActionEvent();
|
||||
keyEvent.consume();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Slider::setOrientation(Slider::Orientation orientation)
|
||||
{
|
||||
mOrientation = orientation;
|
||||
}
|
||||
|
||||
Slider::Orientation Slider::getOrientation() const
|
||||
{
|
||||
return mOrientation;
|
||||
}
|
||||
|
||||
double Slider::markerPositionToValue(int v) const
|
||||
{
|
||||
int w;
|
||||
if (getOrientation() == HORIZONTAL)
|
||||
{
|
||||
w = getWidth();
|
||||
}
|
||||
else
|
||||
{
|
||||
w = getHeight();
|
||||
}
|
||||
|
||||
double pos = v / ((double)w - getMarkerLength());
|
||||
return (1.0 - pos) * getScaleStart() + pos * getScaleEnd();
|
||||
|
||||
}
|
||||
|
||||
int Slider::valueToMarkerPosition(double value) const
|
||||
{
|
||||
int v;
|
||||
if (getOrientation() == HORIZONTAL)
|
||||
{
|
||||
v = getWidth();
|
||||
}
|
||||
else
|
||||
{
|
||||
v = getHeight();
|
||||
}
|
||||
|
||||
int w = (int)((v - getMarkerLength())
|
||||
* (value - getScaleStart())
|
||||
/ (getScaleEnd() - getScaleStart()));
|
||||
|
||||
if (w < 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (w > v - getMarkerLength())
|
||||
{
|
||||
return v - getMarkerLength();
|
||||
}
|
||||
|
||||
return w;
|
||||
}
|
||||
|
||||
void Slider::setStepLength(double length)
|
||||
{
|
||||
mStepLength = length;
|
||||
}
|
||||
|
||||
double Slider::getStepLength() const
|
||||
{
|
||||
return mStepLength;
|
||||
}
|
||||
|
||||
int Slider::getMarkerPosition() const
|
||||
{
|
||||
return valueToMarkerPosition(getValue());
|
||||
}
|
||||
|
||||
void Slider::mouseWheelMovedUp(MouseEvent& mouseEvent)
|
||||
{
|
||||
setValue(getValue() + getStepLength());
|
||||
distributeActionEvent();
|
||||
|
||||
mouseEvent.consume();
|
||||
}
|
||||
|
||||
void Slider::mouseWheelMovedDown(MouseEvent& mouseEvent)
|
||||
{
|
||||
setValue(getValue() - getStepLength());
|
||||
distributeActionEvent();
|
||||
|
||||
mouseEvent.consume();
|
||||
}
|
||||
}
|
||||
181
project/jni/guichan/src/widgets/tab.cpp
Normal file
181
project/jni/guichan/src/widgets/tab.cpp
Normal file
@@ -0,0 +1,181 @@
|
||||
/* _______ __ __ __ ______ __ __ _______ __ __
|
||||
* / _____/\ / /\ / /\ / /\ / ____/\ / /\ / /\ / ___ /\ / |\/ /\
|
||||
* / /\____\// / // / // / // /\___\// /_// / // /\_/ / // , |/ / /
|
||||
* / / /__ / / // / // / // / / / ___ / // ___ / // /| ' / /
|
||||
* / /_// /\ / /_// / // / // /_/_ / / // / // /\_/ / // / | / /
|
||||
* /______/ //______/ //_/ //_____/\ /_/ //_/ //_/ //_/ //_/ /|_/ /
|
||||
* \______\/ \______\/ \_\/ \_____\/ \_\/ \_\/ \_\/ \_\/ \_\/ \_\/
|
||||
*
|
||||
* Copyright (c) 2004 - 2008 Olof Naessén and Per Larsson
|
||||
*
|
||||
*
|
||||
* Per Larsson a.k.a finalman
|
||||
* Olof Naessén a.k.a jansem/yakslem
|
||||
*
|
||||
* Visit: http://guichan.sourceforge.net
|
||||
*
|
||||
* License: (BSD)
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* 3. Neither the name of Guichan nor the names of its contributors may
|
||||
* be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
|
||||
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* For comments regarding functions please see the header file.
|
||||
*/
|
||||
|
||||
#include "guichan/widgets/tab.hpp"
|
||||
|
||||
#include "guichan/font.hpp"
|
||||
#include "guichan/graphics.hpp"
|
||||
#include "guichan/widgets/button.hpp"
|
||||
#include "guichan/widgets/label.hpp"
|
||||
#include "guichan/widgets/tabbedarea.hpp"
|
||||
|
||||
namespace gcn
|
||||
{
|
||||
Tab::Tab()
|
||||
:mHasMouse(false),
|
||||
mTabbedArea(NULL)
|
||||
{
|
||||
mLabel = new Label();
|
||||
mLabel->setPosition(4, 4);
|
||||
add(mLabel);
|
||||
|
||||
addMouseListener(this);
|
||||
}
|
||||
|
||||
Tab::~Tab()
|
||||
{
|
||||
delete mLabel;
|
||||
}
|
||||
|
||||
void Tab::adjustSize()
|
||||
{
|
||||
setSize(mLabel->getWidth() + 8,
|
||||
mLabel->getHeight() + 8);
|
||||
|
||||
if (mTabbedArea != NULL)
|
||||
{
|
||||
mTabbedArea->adjustTabPositions();
|
||||
}
|
||||
}
|
||||
|
||||
void Tab::setTabbedArea(TabbedArea* tabbedArea)
|
||||
{
|
||||
mTabbedArea = tabbedArea;
|
||||
}
|
||||
|
||||
TabbedArea* Tab::getTabbedArea()
|
||||
{
|
||||
return mTabbedArea;
|
||||
}
|
||||
|
||||
void Tab::setCaption(const std::string& caption)
|
||||
{
|
||||
mLabel->setCaption(caption);
|
||||
mLabel->adjustSize();
|
||||
adjustSize();
|
||||
}
|
||||
|
||||
const std::string& Tab::getCaption() const
|
||||
{
|
||||
return mLabel->getCaption();
|
||||
}
|
||||
|
||||
void Tab::draw(Graphics *graphics)
|
||||
{
|
||||
const Color &faceColor = getBaseColor();
|
||||
const int alpha = getBaseColor().a;
|
||||
Color highlightColor = faceColor + 0x303030;
|
||||
highlightColor.a = alpha;
|
||||
Color shadowColor = faceColor - 0x303030;
|
||||
shadowColor.a = alpha;
|
||||
|
||||
Color borderColor;
|
||||
Color baseColor;
|
||||
|
||||
if ((mTabbedArea != NULL && mTabbedArea->isTabSelected(this))
|
||||
|| mHasMouse)
|
||||
{
|
||||
// Draw a border.
|
||||
graphics->setColor(highlightColor);
|
||||
graphics->drawLine(0, 0, getWidth() - 1, 0);
|
||||
graphics->drawLine(0, 1, 0, getHeight() - 1);
|
||||
graphics->setColor(shadowColor);
|
||||
graphics->drawLine(getWidth() - 1, 1, getWidth() - 1, getHeight() - 1);
|
||||
|
||||
borderColor = highlightColor;
|
||||
baseColor = getBaseColor();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Draw a border.
|
||||
graphics->setColor(shadowColor);
|
||||
graphics->drawLine(0, 0, getWidth() - 1, 0);
|
||||
graphics->drawLine(0, 1, 0, getHeight() - 1);
|
||||
graphics->drawLine(getWidth() - 1, 1, getWidth() - 1, getHeight() - 1);
|
||||
|
||||
baseColor = getBaseColor() - 0x151515;
|
||||
baseColor.a = alpha;
|
||||
}
|
||||
|
||||
// Push a clip area so the other drawings don't need to worry
|
||||
// about the border.
|
||||
graphics->pushClipArea(Rectangle(1, 1, getWidth() - 2, getHeight() - 1));
|
||||
const Rectangle currentClipArea = graphics->getCurrentClipArea();
|
||||
|
||||
graphics->setColor(baseColor);
|
||||
graphics->fillRectangle(Rectangle(0,
|
||||
0,
|
||||
currentClipArea.width,
|
||||
currentClipArea.height));
|
||||
|
||||
drawChildren(graphics);
|
||||
|
||||
if (mTabbedArea != NULL
|
||||
&& mTabbedArea->isFocused()
|
||||
&& mTabbedArea->isTabSelected(this))
|
||||
{
|
||||
graphics->setColor(Color(0x000000));
|
||||
graphics->drawRectangle(Rectangle(2,
|
||||
2,
|
||||
currentClipArea.width - 4,
|
||||
currentClipArea.height - 4));
|
||||
}
|
||||
|
||||
graphics->popClipArea();
|
||||
}
|
||||
|
||||
void Tab::mouseEntered(MouseEvent& mouseEvent)
|
||||
{
|
||||
mHasMouse = true;
|
||||
}
|
||||
|
||||
void Tab::mouseExited(MouseEvent& mouseEvent)
|
||||
{
|
||||
mHasMouse = false;
|
||||
}
|
||||
}
|
||||
|
||||
482
project/jni/guichan/src/widgets/tabbedarea.cpp
Normal file
482
project/jni/guichan/src/widgets/tabbedarea.cpp
Normal file
@@ -0,0 +1,482 @@
|
||||
/* _______ __ __ __ ______ __ __ _______ __ __
|
||||
* / _____/\ / /\ / /\ / /\ / ____/\ / /\ / /\ / ___ /\ / |\/ /\
|
||||
* / /\____\// / // / // / // /\___\// /_// / // /\_/ / // , |/ / /
|
||||
* / / /__ / / // / // / // / / / ___ / // ___ / // /| ' / /
|
||||
* / /_// /\ / /_// / // / // /_/_ / / // / // /\_/ / // / | / /
|
||||
* /______/ //______/ //_/ //_____/\ /_/ //_/ //_/ //_/ //_/ /|_/ /
|
||||
* \______\/ \______\/ \_\/ \_____\/ \_\/ \_\/ \_\/ \_\/ \_\/ \_\/
|
||||
*
|
||||
* Copyright (c) 2004 - 2008 Olof Naessén and Per Larsson
|
||||
*
|
||||
*
|
||||
* Per Larsson a.k.a finalman
|
||||
* Olof Naessén a.k.a jansem/yakslem
|
||||
*
|
||||
* Visit: http://guichan.sourceforge.net
|
||||
*
|
||||
* License: (BSD)
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* 3. Neither the name of Guichan nor the names of its contributors may
|
||||
* be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
|
||||
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* For comments regarding functions please see the header file.
|
||||
*/
|
||||
|
||||
#include "guichan/widgets/tabbedarea.hpp"
|
||||
|
||||
#include "guichan/exception.hpp"
|
||||
#include "guichan/focushandler.hpp"
|
||||
#include "guichan/font.hpp"
|
||||
#include "guichan/graphics.hpp"
|
||||
|
||||
#include "guichan/widgets/container.hpp"
|
||||
#include "guichan/widgets/tab.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
namespace gcn
|
||||
{
|
||||
TabbedArea::TabbedArea()
|
||||
:mSelectedTab(NULL),
|
||||
mOpaque(false)
|
||||
{
|
||||
setFocusable(true);
|
||||
addKeyListener(this);
|
||||
addMouseListener(this);
|
||||
|
||||
mTabContainer = new Container();
|
||||
mTabContainer->setOpaque(false);
|
||||
mWidgetContainer = new Container();
|
||||
|
||||
add(mTabContainer);
|
||||
add(mWidgetContainer);
|
||||
}
|
||||
|
||||
TabbedArea::~TabbedArea()
|
||||
{
|
||||
remove(mTabContainer);
|
||||
remove(mWidgetContainer);
|
||||
|
||||
delete mTabContainer;
|
||||
delete mWidgetContainer;
|
||||
|
||||
for (unsigned int i = 0; i < mTabsToDelete.size(); i++)
|
||||
{
|
||||
delete mTabsToDelete[i];
|
||||
}
|
||||
}
|
||||
|
||||
void TabbedArea::addTab(const std::string& caption, Widget* widget)
|
||||
{
|
||||
Tab* tab = new Tab();
|
||||
tab->setCaption(caption);
|
||||
mTabsToDelete.push_back(tab);
|
||||
|
||||
addTab(tab, widget);
|
||||
}
|
||||
|
||||
void TabbedArea::addTab(Tab* tab, Widget* widget)
|
||||
{
|
||||
tab->setTabbedArea(this);
|
||||
tab->addActionListener(this);
|
||||
|
||||
mTabContainer->add(tab);
|
||||
mTabs.push_back(std::pair<Tab*, Widget*>(tab, widget));
|
||||
|
||||
if (mSelectedTab == NULL)
|
||||
{
|
||||
setSelectedTab(tab);
|
||||
}
|
||||
|
||||
adjustTabPositions();
|
||||
adjustSize();
|
||||
}
|
||||
|
||||
void TabbedArea::removeTabWithIndex(unsigned int index)
|
||||
{
|
||||
if (index >= mTabs.size())
|
||||
{
|
||||
throw GCN_EXCEPTION("No such tab index.");
|
||||
}
|
||||
|
||||
removeTab(mTabs[index].first);
|
||||
}
|
||||
|
||||
void TabbedArea::removeTab(Tab* tab)
|
||||
{
|
||||
int tabIndexToBeSelected = - 1;
|
||||
|
||||
if (tab == mSelectedTab)
|
||||
{
|
||||
int index = getSelectedTabIndex();
|
||||
|
||||
if (index == (int)mTabs.size() - 1
|
||||
&& mTabs.size() >= 2)
|
||||
{
|
||||
tabIndexToBeSelected = index--;
|
||||
}
|
||||
else if (index == (int)mTabs.size() - 1
|
||||
&& mTabs.size() == 1)
|
||||
{
|
||||
tabIndexToBeSelected = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
tabIndexToBeSelected = index;
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<std::pair<Tab*, Widget*> >::iterator iter;
|
||||
for (iter = mTabs.begin(); iter != mTabs.end(); iter++)
|
||||
{
|
||||
if (iter->first == tab)
|
||||
{
|
||||
mTabContainer->remove(tab);
|
||||
mTabs.erase(iter);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<Tab*>::iterator iter2;
|
||||
for (iter2 = mTabsToDelete.begin(); iter2 != mTabsToDelete.end(); iter2++)
|
||||
{
|
||||
if (*iter2 == tab)
|
||||
{
|
||||
mTabsToDelete.erase(iter2);
|
||||
delete tab;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (tabIndexToBeSelected == -1)
|
||||
{
|
||||
mSelectedTab = NULL;
|
||||
mWidgetContainer->clear();
|
||||
}
|
||||
else
|
||||
{
|
||||
setSelectedTab(tabIndexToBeSelected);
|
||||
}
|
||||
|
||||
adjustSize();
|
||||
adjustTabPositions();
|
||||
}
|
||||
|
||||
bool TabbedArea::isTabSelected(unsigned int index) const
|
||||
{
|
||||
if (index >= mTabs.size())
|
||||
{
|
||||
throw GCN_EXCEPTION("No such tab index.");
|
||||
}
|
||||
|
||||
return mSelectedTab == mTabs[index].first;
|
||||
}
|
||||
|
||||
bool TabbedArea::isTabSelected(Tab* tab)
|
||||
{
|
||||
return mSelectedTab == tab;
|
||||
}
|
||||
|
||||
void TabbedArea::setSelectedTab(unsigned int index)
|
||||
{
|
||||
if (index >= mTabs.size())
|
||||
{
|
||||
throw GCN_EXCEPTION("No such tab index.");
|
||||
}
|
||||
|
||||
setSelectedTab(mTabs[index].first);
|
||||
}
|
||||
|
||||
void TabbedArea::setSelectedTab(Tab* tab)
|
||||
{
|
||||
unsigned int i;
|
||||
for (i = 0; i < mTabs.size(); i++)
|
||||
{
|
||||
if (mTabs[i].first == mSelectedTab)
|
||||
{
|
||||
mWidgetContainer->remove(mTabs[i].second);
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < mTabs.size(); i++)
|
||||
{
|
||||
if (mTabs[i].first == tab)
|
||||
{
|
||||
mSelectedTab = tab;
|
||||
mWidgetContainer->add(mTabs[i].second);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int TabbedArea::getSelectedTabIndex() const
|
||||
{
|
||||
unsigned int i;
|
||||
for (i = 0; i < mTabs.size(); i++)
|
||||
{
|
||||
if (mTabs[i].first == mSelectedTab)
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
Tab* TabbedArea::getSelectedTab()
|
||||
{
|
||||
return mSelectedTab;
|
||||
}
|
||||
|
||||
void TabbedArea::setOpaque(bool opaque)
|
||||
{
|
||||
mOpaque = opaque;
|
||||
}
|
||||
|
||||
bool TabbedArea::isOpaque() const
|
||||
{
|
||||
return mOpaque;
|
||||
}
|
||||
|
||||
void TabbedArea::draw(Graphics *graphics)
|
||||
{
|
||||
const Color &faceColor = getBaseColor();
|
||||
const int alpha = getBaseColor().a;
|
||||
Color highlightColor = faceColor + 0x303030;
|
||||
highlightColor.a = alpha;
|
||||
Color shadowColor = faceColor - 0x303030;
|
||||
shadowColor.a = alpha;
|
||||
|
||||
// Draw a border.
|
||||
graphics->setColor(highlightColor);
|
||||
graphics->drawLine(0,
|
||||
mTabContainer->getHeight(),
|
||||
0,
|
||||
getHeight() - 2);
|
||||
graphics->setColor(shadowColor);
|
||||
graphics->drawLine(getWidth() - 1,
|
||||
mTabContainer->getHeight() + 1,
|
||||
getWidth() - 1,
|
||||
getHeight() - 1);
|
||||
graphics->drawLine(1,
|
||||
getHeight() - 1,
|
||||
getWidth() - 1,
|
||||
getHeight() - 1);
|
||||
|
||||
if (isOpaque())
|
||||
{
|
||||
graphics->setColor(getBaseColor());
|
||||
graphics->fillRectangle(Rectangle(1, 1,
|
||||
getWidth() - 2,
|
||||
getHeight() - 2));
|
||||
}
|
||||
|
||||
// Draw a line underneath the tabs.
|
||||
graphics->setColor(highlightColor);
|
||||
graphics->drawLine(1,
|
||||
mTabContainer->getHeight(),
|
||||
getWidth() - 1,
|
||||
mTabContainer->getHeight());
|
||||
|
||||
// If a tab is selected, remove the line right underneath
|
||||
// the selected tab.
|
||||
if (mSelectedTab != NULL)
|
||||
{
|
||||
graphics->setColor(getBaseColor());
|
||||
graphics->drawLine(mSelectedTab->getX() + 1,
|
||||
mTabContainer->getHeight(),
|
||||
mSelectedTab->getX() + mSelectedTab->getWidth() - 2,
|
||||
mTabContainer->getHeight());
|
||||
|
||||
}
|
||||
|
||||
drawChildren(graphics);
|
||||
}
|
||||
|
||||
void TabbedArea::logic()
|
||||
{
|
||||
}
|
||||
|
||||
void TabbedArea::adjustSize()
|
||||
{
|
||||
int maxTabHeight = 0;
|
||||
|
||||
for (unsigned int i = 0; i < mTabs.size(); i++)
|
||||
{
|
||||
if (mTabs[i].first->getHeight() > maxTabHeight)
|
||||
{
|
||||
maxTabHeight = mTabs[i].first->getHeight();
|
||||
}
|
||||
}
|
||||
|
||||
mTabContainer->setSize(getWidth() - 2,
|
||||
maxTabHeight);
|
||||
|
||||
mWidgetContainer->setPosition(1, maxTabHeight + 1);
|
||||
mWidgetContainer->setSize(getWidth() - 2,
|
||||
getHeight() - maxTabHeight - 2);
|
||||
}
|
||||
|
||||
void TabbedArea::adjustTabPositions()
|
||||
{
|
||||
int maxTabHeight = 0;
|
||||
unsigned int i;
|
||||
for (i = 0; i < mTabs.size(); i++)
|
||||
{
|
||||
if (mTabs[i].first->getHeight() > maxTabHeight)
|
||||
{
|
||||
maxTabHeight = mTabs[i].first->getHeight();
|
||||
}
|
||||
}
|
||||
|
||||
int x = 0;
|
||||
for (i = 0; i < mTabs.size(); i++)
|
||||
{
|
||||
Tab* tab = mTabs[i].first;
|
||||
tab->setPosition(x, maxTabHeight - tab->getHeight());
|
||||
x += tab->getWidth();
|
||||
}
|
||||
}
|
||||
|
||||
void TabbedArea::setWidth(int width)
|
||||
{
|
||||
Widget::setWidth(width);
|
||||
adjustSize();
|
||||
}
|
||||
|
||||
void TabbedArea::setHeight(int height)
|
||||
{
|
||||
Widget::setHeight(height);
|
||||
adjustSize();
|
||||
}
|
||||
|
||||
void TabbedArea::setSize(int width, int height)
|
||||
{
|
||||
Widget::setSize(width, height);
|
||||
adjustSize();
|
||||
}
|
||||
|
||||
void TabbedArea::setDimension(const Rectangle& dimension)
|
||||
{
|
||||
Widget::setDimension(dimension);
|
||||
adjustSize();
|
||||
}
|
||||
|
||||
void TabbedArea::keyPressed(KeyEvent& keyEvent)
|
||||
{
|
||||
if (keyEvent.isConsumed() || !isFocused())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (keyEvent.getKey().getValue() == Key::LEFT)
|
||||
{
|
||||
int index = getSelectedTabIndex();
|
||||
index--;
|
||||
|
||||
if (index < 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
setSelectedTab(mTabs[index].first);
|
||||
}
|
||||
|
||||
keyEvent.consume();
|
||||
}
|
||||
else if (keyEvent.getKey().getValue() == Key::RIGHT)
|
||||
{
|
||||
int index = getSelectedTabIndex();
|
||||
index++;
|
||||
|
||||
if (index >= (int)mTabs.size())
|
||||
{
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
setSelectedTab(mTabs[index].first);
|
||||
}
|
||||
|
||||
keyEvent.consume();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void TabbedArea::mousePressed(MouseEvent& mouseEvent)
|
||||
{
|
||||
if (mouseEvent.isConsumed())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (mouseEvent.getButton() == MouseEvent::LEFT)
|
||||
{
|
||||
Widget* widget = mTabContainer->getWidgetAt(mouseEvent.getX(), mouseEvent.getY());
|
||||
Tab* tab = dynamic_cast<Tab*>(widget);
|
||||
|
||||
if (tab != NULL)
|
||||
{
|
||||
setSelectedTab(tab);
|
||||
}
|
||||
}
|
||||
|
||||
// Request focus only if the source of the event
|
||||
// is not focusble. If the source of the event
|
||||
// is focused we don't want to steal the focus.
|
||||
if (!mouseEvent.getSource()->isFocusable())
|
||||
{
|
||||
requestFocus();
|
||||
}
|
||||
}
|
||||
|
||||
void TabbedArea::death(const Event& event)
|
||||
{
|
||||
Tab* tab = dynamic_cast<Tab*>(event.getSource());
|
||||
|
||||
if (tab != NULL)
|
||||
{
|
||||
removeTab(tab);
|
||||
}
|
||||
else
|
||||
{
|
||||
BasicContainer::death(event);
|
||||
}
|
||||
}
|
||||
|
||||
void TabbedArea::action(const ActionEvent& actionEvent)
|
||||
{
|
||||
Widget* source = actionEvent.getSource();
|
||||
Tab* tab = dynamic_cast<Tab*>(source);
|
||||
|
||||
if (tab == NULL)
|
||||
{
|
||||
throw GCN_EXCEPTION("Received an action from a widget that's not a tab!");
|
||||
}
|
||||
|
||||
setSelectedTab(tab);
|
||||
}
|
||||
}
|
||||
517
project/jni/guichan/src/widgets/textbox.cpp
Normal file
517
project/jni/guichan/src/widgets/textbox.cpp
Normal file
@@ -0,0 +1,517 @@
|
||||
/* _______ __ __ __ ______ __ __ _______ __ __
|
||||
* / _____/\ / /\ / /\ / /\ / ____/\ / /\ / /\ / ___ /\ / |\/ /\
|
||||
* / /\____\// / // / // / // /\___\// /_// / // /\_/ / // , |/ / /
|
||||
* / / /__ / / // / // / // / / / ___ / // ___ / // /| ' / /
|
||||
* / /_// /\ / /_// / // / // /_/_ / / // / // /\_/ / // / | / /
|
||||
* /______/ //______/ //_/ //_____/\ /_/ //_/ //_/ //_/ //_/ /|_/ /
|
||||
* \______\/ \______\/ \_\/ \_____\/ \_\/ \_\/ \_\/ \_\/ \_\/ \_\/
|
||||
*
|
||||
* Copyright (c) 2004 - 2008 Olof Naessén and Per Larsson
|
||||
*
|
||||
*
|
||||
* Per Larsson a.k.a finalman
|
||||
* Olof Naessén a.k.a jansem/yakslem
|
||||
*
|
||||
* Visit: http://guichan.sourceforge.net
|
||||
*
|
||||
* License: (BSD)
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* 3. Neither the name of Guichan nor the names of its contributors may
|
||||
* be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
|
||||
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* For comments regarding functions please see the header file.
|
||||
*/
|
||||
|
||||
#include "guichan/widgets/textbox.hpp"
|
||||
|
||||
#include "guichan/basiccontainer.hpp"
|
||||
#include "guichan/font.hpp"
|
||||
#include "guichan/graphics.hpp"
|
||||
#include "guichan/key.hpp"
|
||||
#include "guichan/mouseinput.hpp"
|
||||
|
||||
namespace gcn
|
||||
{
|
||||
TextBox::TextBox()
|
||||
{
|
||||
mCaretColumn = 0;
|
||||
mCaretRow = 0;
|
||||
mEditable = true;
|
||||
mOpaque = true;
|
||||
|
||||
setText("");
|
||||
|
||||
setFocusable(true);
|
||||
|
||||
addMouseListener(this);
|
||||
addKeyListener(this);
|
||||
adjustSize();
|
||||
}
|
||||
|
||||
TextBox::TextBox(const std::string& text)
|
||||
{
|
||||
mCaretColumn = 0;
|
||||
mCaretRow = 0;
|
||||
mEditable = true;
|
||||
mOpaque = true;
|
||||
|
||||
setText(text);
|
||||
|
||||
setFocusable(true);
|
||||
|
||||
addMouseListener(this);
|
||||
addKeyListener(this);
|
||||
adjustSize();
|
||||
}
|
||||
|
||||
void TextBox::setText(const std::string& text)
|
||||
{
|
||||
mCaretColumn = 0;
|
||||
mCaretRow = 0;
|
||||
|
||||
mTextRows.clear();
|
||||
|
||||
std::string::size_type pos, lastPos = 0;
|
||||
int length;
|
||||
do
|
||||
{
|
||||
pos = text.find("\n", lastPos);
|
||||
|
||||
if (pos != std::string::npos)
|
||||
{
|
||||
length = pos - lastPos;
|
||||
}
|
||||
else
|
||||
{
|
||||
length = text.size() - lastPos;
|
||||
}
|
||||
std::string sub = text.substr(lastPos, length);
|
||||
mTextRows.push_back(sub);
|
||||
lastPos = pos + 1;
|
||||
|
||||
} while (pos != std::string::npos);
|
||||
|
||||
adjustSize();
|
||||
}
|
||||
|
||||
void TextBox::draw(Graphics* graphics)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
if (mOpaque)
|
||||
{
|
||||
graphics->setColor(getBackgroundColor());
|
||||
graphics->fillRectangle(Rectangle(0, 0, getWidth(), getHeight()));
|
||||
}
|
||||
|
||||
if (isFocused() && isEditable())
|
||||
{
|
||||
drawCaret(graphics, getFont()->getWidth(mTextRows[mCaretRow].substr(0, mCaretColumn)), mCaretRow * getFont()->getHeight());
|
||||
}
|
||||
|
||||
graphics->setColor(getForegroundColor());
|
||||
graphics->setFont(getFont());
|
||||
|
||||
for (i = 0; i < mTextRows.size(); i++)
|
||||
{
|
||||
// Move the text one pixel so we can have a caret before a letter.
|
||||
graphics->drawText(mTextRows[i], 1, i * getFont()->getHeight());
|
||||
}
|
||||
}
|
||||
|
||||
void TextBox::drawCaret(Graphics* graphics, int x, int y)
|
||||
{
|
||||
graphics->setColor(getForegroundColor());
|
||||
graphics->drawLine(x, getFont()->getHeight() + y, x, y);
|
||||
}
|
||||
|
||||
void TextBox::mousePressed(MouseEvent& mouseEvent)
|
||||
{
|
||||
if (mouseEvent.getButton() == MouseEvent::LEFT)
|
||||
{
|
||||
mCaretRow = mouseEvent.getY() / getFont()->getHeight();
|
||||
|
||||
if (mCaretRow >= (int)mTextRows.size())
|
||||
{
|
||||
mCaretRow = mTextRows.size() - 1;
|
||||
}
|
||||
|
||||
mCaretColumn = getFont()->getStringIndexAt(mTextRows[mCaretRow], mouseEvent.getX());
|
||||
}
|
||||
}
|
||||
|
||||
void TextBox::mouseDragged(MouseEvent& mouseEvent)
|
||||
{
|
||||
mouseEvent.consume();
|
||||
}
|
||||
|
||||
void TextBox::keyPressed(KeyEvent& keyEvent)
|
||||
{
|
||||
Key key = keyEvent.getKey();
|
||||
|
||||
if (key.getValue() == Key::LEFT)
|
||||
{
|
||||
--mCaretColumn;
|
||||
if (mCaretColumn < 0)
|
||||
{
|
||||
--mCaretRow;
|
||||
|
||||
if (mCaretRow < 0)
|
||||
{
|
||||
mCaretRow = 0;
|
||||
mCaretColumn = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
mCaretColumn = mTextRows[mCaretRow].size();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
else if (key.getValue() == Key::RIGHT)
|
||||
{
|
||||
++mCaretColumn;
|
||||
if (mCaretColumn > (int)mTextRows[mCaretRow].size())
|
||||
{
|
||||
++mCaretRow;
|
||||
|
||||
if (mCaretRow >= (int)mTextRows.size())
|
||||
{
|
||||
mCaretRow = mTextRows.size() - 1;
|
||||
if (mCaretRow < 0)
|
||||
{
|
||||
mCaretRow = 0;
|
||||
}
|
||||
|
||||
mCaretColumn = mTextRows[mCaretRow].size();
|
||||
}
|
||||
else
|
||||
{
|
||||
mCaretColumn = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
else if (key.getValue() == Key::DOWN)
|
||||
{
|
||||
setCaretRow(mCaretRow + 1);
|
||||
}
|
||||
|
||||
else if (key.getValue() == Key::UP)
|
||||
{
|
||||
setCaretRow(mCaretRow - 1);
|
||||
}
|
||||
|
||||
else if (key.getValue() == Key::HOME)
|
||||
{
|
||||
mCaretColumn = 0;
|
||||
}
|
||||
|
||||
else if (key.getValue() == Key::END)
|
||||
{
|
||||
mCaretColumn = mTextRows[mCaretRow].size();
|
||||
}
|
||||
|
||||
else if (key.getValue() == Key::ENTER && mEditable)
|
||||
{
|
||||
mTextRows.insert(mTextRows.begin() + mCaretRow + 1,
|
||||
mTextRows[mCaretRow].substr(mCaretColumn, mTextRows[mCaretRow].size() - mCaretColumn));
|
||||
mTextRows[mCaretRow].resize(mCaretColumn);
|
||||
++mCaretRow;
|
||||
mCaretColumn = 0;
|
||||
}
|
||||
|
||||
else if (key.getValue() == Key::BACKSPACE
|
||||
&& mCaretColumn != 0
|
||||
&& mEditable)
|
||||
{
|
||||
mTextRows[mCaretRow].erase(mCaretColumn - 1, 1);
|
||||
--mCaretColumn;
|
||||
}
|
||||
|
||||
else if (key.getValue() == Key::BACKSPACE
|
||||
&& mCaretColumn == 0
|
||||
&& mCaretRow != 0
|
||||
&& mEditable)
|
||||
{
|
||||
mCaretColumn = mTextRows[mCaretRow - 1].size();
|
||||
mTextRows[mCaretRow - 1] += mTextRows[mCaretRow];
|
||||
mTextRows.erase(mTextRows.begin() + mCaretRow);
|
||||
--mCaretRow;
|
||||
}
|
||||
|
||||
else if (key.getValue() == Key::DELETE
|
||||
&& mCaretColumn < (int)mTextRows[mCaretRow].size()
|
||||
&& mEditable)
|
||||
{
|
||||
mTextRows[mCaretRow].erase(mCaretColumn, 1);
|
||||
}
|
||||
|
||||
else if (key.getValue() == Key::DELETE
|
||||
&& mCaretColumn == (int)mTextRows[mCaretRow].size()
|
||||
&& mCaretRow < ((int)mTextRows.size() - 1)
|
||||
&& mEditable)
|
||||
{
|
||||
mTextRows[mCaretRow] += mTextRows[mCaretRow + 1];
|
||||
mTextRows.erase(mTextRows.begin() + mCaretRow + 1);
|
||||
}
|
||||
|
||||
else if(key.getValue() == Key::PAGE_UP)
|
||||
{
|
||||
Widget* par = getParent();
|
||||
|
||||
if (par != NULL)
|
||||
{
|
||||
int rowsPerPage = par->getChildrenArea().height / getFont()->getHeight();
|
||||
mCaretRow -= rowsPerPage;
|
||||
|
||||
if (mCaretRow < 0)
|
||||
{
|
||||
mCaretRow = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
else if(key.getValue() == Key::PAGE_DOWN)
|
||||
{
|
||||
Widget* par = getParent();
|
||||
|
||||
if (par != NULL)
|
||||
{
|
||||
int rowsPerPage = par->getChildrenArea().height / getFont()->getHeight();
|
||||
mCaretRow += rowsPerPage;
|
||||
|
||||
if (mCaretRow >= (int)mTextRows.size())
|
||||
{
|
||||
mCaretRow = mTextRows.size() - 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
else if(key.getValue() == Key::TAB
|
||||
&& mEditable)
|
||||
{
|
||||
mTextRows[mCaretRow].insert(mCaretColumn,std::string(" "));
|
||||
mCaretColumn += 4;
|
||||
}
|
||||
|
||||
else if (key.isCharacter()
|
||||
&& mEditable)
|
||||
{
|
||||
mTextRows[mCaretRow].insert(mCaretColumn,std::string(1,(char)key.getValue()));
|
||||
++mCaretColumn;
|
||||
}
|
||||
|
||||
adjustSize();
|
||||
scrollToCaret();
|
||||
|
||||
keyEvent.consume();
|
||||
}
|
||||
|
||||
void TextBox::adjustSize()
|
||||
{
|
||||
unsigned int i;
|
||||
int width = 0;
|
||||
for (i = 0; i < mTextRows.size(); ++i)
|
||||
{
|
||||
int w = getFont()->getWidth(mTextRows[i]);
|
||||
if (width < w)
|
||||
{
|
||||
width = w;
|
||||
}
|
||||
}
|
||||
|
||||
setWidth(width + 1);
|
||||
setHeight(getFont()->getHeight() * mTextRows.size());
|
||||
}
|
||||
|
||||
void TextBox::setCaretPosition(unsigned int position)
|
||||
{
|
||||
int row;
|
||||
|
||||
for (row = 0; row < (int)mTextRows.size(); row++)
|
||||
{
|
||||
if (position <= mTextRows[row].size())
|
||||
{
|
||||
mCaretRow = row;
|
||||
mCaretColumn = position;
|
||||
return; // we are done
|
||||
}
|
||||
else
|
||||
{
|
||||
position--;
|
||||
}
|
||||
}
|
||||
|
||||
// position beyond end of text
|
||||
mCaretRow = mTextRows.size() - 1;
|
||||
mCaretColumn = mTextRows[mCaretRow].size();
|
||||
}
|
||||
|
||||
unsigned int TextBox::getCaretPosition() const
|
||||
{
|
||||
int pos = 0, row;
|
||||
|
||||
for (row = 0; row < mCaretRow; row++)
|
||||
{
|
||||
pos += mTextRows[row].size();
|
||||
}
|
||||
|
||||
return pos + mCaretColumn;
|
||||
}
|
||||
|
||||
void TextBox::setCaretRowColumn(int row, int column)
|
||||
{
|
||||
setCaretRow(row);
|
||||
setCaretColumn(column);
|
||||
}
|
||||
|
||||
void TextBox::setCaretRow(int row)
|
||||
{
|
||||
mCaretRow = row;
|
||||
|
||||
if (mCaretRow >= (int)mTextRows.size())
|
||||
{
|
||||
mCaretRow = mTextRows.size() - 1;
|
||||
}
|
||||
|
||||
if (mCaretRow < 0)
|
||||
{
|
||||
mCaretRow = 0;
|
||||
}
|
||||
|
||||
setCaretColumn(mCaretColumn);
|
||||
}
|
||||
|
||||
unsigned int TextBox::getCaretRow() const
|
||||
{
|
||||
return mCaretRow;
|
||||
}
|
||||
|
||||
void TextBox::setCaretColumn(int column)
|
||||
{
|
||||
mCaretColumn = column;
|
||||
|
||||
if (mCaretColumn > (int)mTextRows[mCaretRow].size())
|
||||
{
|
||||
mCaretColumn = mTextRows[mCaretRow].size();
|
||||
}
|
||||
|
||||
if (mCaretColumn < 0)
|
||||
{
|
||||
mCaretColumn = 0;
|
||||
}
|
||||
}
|
||||
|
||||
unsigned int TextBox::getCaretColumn() const
|
||||
{
|
||||
return mCaretColumn;
|
||||
}
|
||||
|
||||
const std::string& TextBox::getTextRow(int row) const
|
||||
{
|
||||
return mTextRows[row];
|
||||
}
|
||||
|
||||
void TextBox::setTextRow(int row, const std::string& text)
|
||||
{
|
||||
mTextRows[row] = text;
|
||||
|
||||
if (mCaretRow == row)
|
||||
{
|
||||
setCaretColumn(mCaretColumn);
|
||||
}
|
||||
|
||||
adjustSize();
|
||||
}
|
||||
|
||||
unsigned int TextBox::getNumberOfRows() const
|
||||
{
|
||||
return mTextRows.size();
|
||||
}
|
||||
|
||||
std::string TextBox::getText() const
|
||||
{
|
||||
if (mTextRows.size() == 0)
|
||||
{
|
||||
return std::string("");
|
||||
}
|
||||
|
||||
int i;
|
||||
std::string text;
|
||||
|
||||
for (i = 0; i < (int)mTextRows.size() - 1; ++i)
|
||||
{
|
||||
text = text + mTextRows[i] + "\n";
|
||||
}
|
||||
|
||||
text = text + mTextRows[i];
|
||||
|
||||
return text;
|
||||
}
|
||||
|
||||
void TextBox::fontChanged()
|
||||
{
|
||||
adjustSize();
|
||||
}
|
||||
|
||||
void TextBox::scrollToCaret()
|
||||
{
|
||||
Rectangle scroll;
|
||||
scroll.x = getFont()->getWidth(mTextRows[mCaretRow].substr(0, mCaretColumn));
|
||||
scroll.y = getFont()->getHeight() * mCaretRow;
|
||||
scroll.width = getFont()->getWidth(" ");
|
||||
scroll.height = getFont()->getHeight() + 2; // add 2 for some extra space
|
||||
|
||||
showPart(scroll);
|
||||
}
|
||||
|
||||
void TextBox::setEditable(bool editable)
|
||||
{
|
||||
mEditable = editable;
|
||||
}
|
||||
|
||||
bool TextBox::isEditable() const
|
||||
{
|
||||
return mEditable;
|
||||
}
|
||||
|
||||
void TextBox::addRow(const std::string row)
|
||||
{
|
||||
mTextRows.push_back(row);
|
||||
adjustSize();
|
||||
}
|
||||
|
||||
bool TextBox::isOpaque()
|
||||
{
|
||||
return mOpaque;
|
||||
}
|
||||
|
||||
void TextBox::setOpaque(bool opaque)
|
||||
{
|
||||
mOpaque = opaque;
|
||||
}
|
||||
}
|
||||
280
project/jni/guichan/src/widgets/textfield.cpp
Normal file
280
project/jni/guichan/src/widgets/textfield.cpp
Normal file
@@ -0,0 +1,280 @@
|
||||
/* _______ __ __ __ ______ __ __ _______ __ __
|
||||
* / _____/\ / /\ / /\ / /\ / ____/\ / /\ / /\ / ___ /\ / |\/ /\
|
||||
* / /\____\// / // / // / // /\___\// /_// / // /\_/ / // , |/ / /
|
||||
* / / /__ / / // / // / // / / / ___ / // ___ / // /| ' / /
|
||||
* / /_// /\ / /_// / // / // /_/_ / / // / // /\_/ / // / | / /
|
||||
* /______/ //______/ //_/ //_____/\ /_/ //_/ //_/ //_/ //_/ /|_/ /
|
||||
* \______\/ \______\/ \_\/ \_____\/ \_\/ \_\/ \_\/ \_\/ \_\/ \_\/
|
||||
*
|
||||
* Copyright (c) 2004 - 2008 Olof Naessén and Per Larsson
|
||||
*
|
||||
*
|
||||
* Per Larsson a.k.a finalman
|
||||
* Olof Naessén a.k.a jansem/yakslem
|
||||
*
|
||||
* Visit: http://guichan.sourceforge.net
|
||||
*
|
||||
* License: (BSD)
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* 3. Neither the name of Guichan nor the names of its contributors may
|
||||
* be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
|
||||
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* For comments regarding functions please see the header file.
|
||||
*/
|
||||
|
||||
#include "guichan/widgets/textfield.hpp"
|
||||
|
||||
#include "guichan/font.hpp"
|
||||
#include "guichan/graphics.hpp"
|
||||
#include "guichan/key.hpp"
|
||||
#include "guichan/mouseinput.hpp"
|
||||
|
||||
namespace gcn
|
||||
{
|
||||
TextField::TextField()
|
||||
{
|
||||
mCaretPosition = 0;
|
||||
mXScroll = 0;
|
||||
|
||||
setFocusable(true);
|
||||
|
||||
addMouseListener(this);
|
||||
addKeyListener(this);
|
||||
}
|
||||
|
||||
TextField::TextField(const std::string& text)
|
||||
{
|
||||
mCaretPosition = 0;
|
||||
mXScroll = 0;
|
||||
|
||||
mText = text;
|
||||
adjustSize();
|
||||
|
||||
setFocusable(true);
|
||||
|
||||
addMouseListener(this);
|
||||
addKeyListener(this);
|
||||
}
|
||||
|
||||
void TextField::setText(const std::string& text)
|
||||
{
|
||||
if(text.size() < mCaretPosition )
|
||||
{
|
||||
mCaretPosition = text.size();
|
||||
}
|
||||
|
||||
mText = text;
|
||||
}
|
||||
|
||||
void TextField::draw(Graphics* graphics)
|
||||
{
|
||||
Color faceColor = getBaseColor();
|
||||
Color highlightColor, shadowColor;
|
||||
int alpha = getBaseColor().a;
|
||||
highlightColor = faceColor + 0x303030;
|
||||
highlightColor.a = alpha;
|
||||
shadowColor = faceColor - 0x303030;
|
||||
shadowColor.a = alpha;
|
||||
|
||||
// Draw a border.
|
||||
graphics->setColor(shadowColor);
|
||||
graphics->drawLine(0, 0, getWidth() - 1, 0);
|
||||
graphics->drawLine(0, 1, 0, getHeight() - 2);
|
||||
graphics->setColor(highlightColor);
|
||||
graphics->drawLine(getWidth() - 1, 1, getWidth() - 1, getHeight() - 1);
|
||||
graphics->drawLine(0, getHeight() - 1, getWidth() - 1, getHeight() - 1);
|
||||
|
||||
// Push a clip area so the other drawings don't need to worry
|
||||
// about the border.
|
||||
graphics->pushClipArea(Rectangle(1, 1, getWidth() - 2, getHeight() - 2));
|
||||
|
||||
graphics->setColor(getBackgroundColor());
|
||||
graphics->fillRectangle(Rectangle(0, 0, getWidth(), getHeight()));
|
||||
|
||||
if (isFocused())
|
||||
{
|
||||
graphics->setColor(getSelectionColor());
|
||||
graphics->drawRectangle(Rectangle(0, 0, getWidth() - 2, getHeight() - 2));
|
||||
graphics->drawRectangle(Rectangle(1, 1, getWidth() - 4, getHeight() - 4));
|
||||
}
|
||||
|
||||
if (isFocused())
|
||||
{
|
||||
drawCaret(graphics, getFont()->getWidth(mText.substr(0, mCaretPosition)) - mXScroll);
|
||||
}
|
||||
|
||||
graphics->setColor(getForegroundColor());
|
||||
graphics->setFont(getFont());
|
||||
graphics->drawText(mText, 3 - mXScroll, 1);
|
||||
|
||||
graphics->popClipArea();
|
||||
}
|
||||
|
||||
void TextField::drawCaret(Graphics* graphics, int x)
|
||||
{
|
||||
// Check the current clip area as a clip area with a different
|
||||
// size than the widget might have been pushed (which is the
|
||||
// case in the draw method when we push a clip area after we have
|
||||
// drawn a border).
|
||||
const Rectangle clipArea = graphics->getCurrentClipArea();
|
||||
|
||||
graphics->setColor(getForegroundColor());
|
||||
graphics->drawLine(x, clipArea.height - 2, x, 1);
|
||||
}
|
||||
|
||||
void TextField::mousePressed(MouseEvent& mouseEvent)
|
||||
{
|
||||
if (mouseEvent.getButton() == MouseEvent::LEFT)
|
||||
{
|
||||
mCaretPosition = getFont()->getStringIndexAt(mText, mouseEvent.getX() + mXScroll);
|
||||
fixScroll();
|
||||
}
|
||||
}
|
||||
|
||||
void TextField::mouseDragged(MouseEvent& mouseEvent)
|
||||
{
|
||||
mouseEvent.consume();
|
||||
}
|
||||
|
||||
void TextField::keyPressed(KeyEvent& keyEvent)
|
||||
{
|
||||
Key key = keyEvent.getKey();
|
||||
|
||||
if (key.getValue() == Key::LEFT && mCaretPosition > 0)
|
||||
{
|
||||
--mCaretPosition;
|
||||
}
|
||||
|
||||
else if (key.getValue() == Key::RIGHT && mCaretPosition < mText.size())
|
||||
{
|
||||
++mCaretPosition;
|
||||
}
|
||||
|
||||
else if (key.getValue() == Key::DELETE && mCaretPosition < mText.size())
|
||||
{
|
||||
mText.erase(mCaretPosition, 1);
|
||||
}
|
||||
|
||||
else if (key.getValue() == Key::BACKSPACE && mCaretPosition > 0)
|
||||
{
|
||||
mText.erase(mCaretPosition - 1, 1);
|
||||
--mCaretPosition;
|
||||
}
|
||||
|
||||
else if (key.getValue() == Key::ENTER)
|
||||
{
|
||||
distributeActionEvent();
|
||||
}
|
||||
|
||||
else if (key.getValue() == Key::HOME)
|
||||
{
|
||||
mCaretPosition = 0;
|
||||
}
|
||||
|
||||
else if (key.getValue() == Key::END)
|
||||
{
|
||||
mCaretPosition = mText.size();
|
||||
}
|
||||
|
||||
else if (key.isCharacter()
|
||||
&& key.getValue() != Key::TAB)
|
||||
{
|
||||
mText.insert(mCaretPosition, std::string(1,(char)key.getValue()));
|
||||
++mCaretPosition;
|
||||
}
|
||||
|
||||
if (key.getValue() != Key::TAB)
|
||||
{
|
||||
keyEvent.consume();
|
||||
}
|
||||
|
||||
fixScroll();
|
||||
}
|
||||
|
||||
void TextField::adjustSize()
|
||||
{
|
||||
setWidth(getFont()->getWidth(mText) + 7);
|
||||
adjustHeight();
|
||||
|
||||
fixScroll();
|
||||
}
|
||||
|
||||
void TextField::adjustHeight()
|
||||
{
|
||||
setHeight(getFont()->getHeight() + 4);
|
||||
}
|
||||
|
||||
void TextField::fixScroll()
|
||||
{
|
||||
if (isFocused())
|
||||
{
|
||||
int caretX = getFont()->getWidth(mText.substr(0, mCaretPosition));
|
||||
|
||||
if (caretX - mXScroll >= getWidth() - 4)
|
||||
{
|
||||
mXScroll = caretX - getWidth() + 4;
|
||||
}
|
||||
else if (caretX - mXScroll <= 0)
|
||||
{
|
||||
mXScroll = caretX - getWidth() / 2;
|
||||
|
||||
if (mXScroll < 0)
|
||||
{
|
||||
mXScroll = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TextField::setCaretPosition(unsigned int position)
|
||||
{
|
||||
if (position > mText.size())
|
||||
{
|
||||
mCaretPosition = mText.size();
|
||||
}
|
||||
else
|
||||
{
|
||||
mCaretPosition = position;
|
||||
}
|
||||
|
||||
fixScroll();
|
||||
}
|
||||
|
||||
unsigned int TextField::getCaretPosition() const
|
||||
{
|
||||
return mCaretPosition;
|
||||
}
|
||||
|
||||
const std::string& TextField::getText() const
|
||||
{
|
||||
return mText;
|
||||
}
|
||||
|
||||
void TextField::fontChanged()
|
||||
{
|
||||
fixScroll();
|
||||
}
|
||||
}
|
||||
308
project/jni/guichan/src/widgets/window.cpp
Normal file
308
project/jni/guichan/src/widgets/window.cpp
Normal file
@@ -0,0 +1,308 @@
|
||||
/* _______ __ __ __ ______ __ __ _______ __ __
|
||||
* / _____/\ / /\ / /\ / /\ / ____/\ / /\ / /\ / ___ /\ / |\/ /\
|
||||
* / /\____\// / // / // / // /\___\// /_// / // /\_/ / // , |/ / /
|
||||
* / / /__ / / // / // / // / / / ___ / // ___ / // /| ' / /
|
||||
* / /_// /\ / /_// / // / // /_/_ / / // / // /\_/ / // / | / /
|
||||
* /______/ //______/ //_/ //_____/\ /_/ //_/ //_/ //_/ //_/ /|_/ /
|
||||
* \______\/ \______\/ \_\/ \_____\/ \_\/ \_\/ \_\/ \_\/ \_\/ \_\/
|
||||
*
|
||||
* Copyright (c) 2004 - 2008 Olof Naessén and Per Larsson
|
||||
*
|
||||
*
|
||||
* Per Larsson a.k.a finalman
|
||||
* Olof Naessén a.k.a jansem/yakslem
|
||||
*
|
||||
* Visit: http://guichan.sourceforge.net
|
||||
*
|
||||
* License: (BSD)
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* 3. Neither the name of Guichan nor the names of its contributors may
|
||||
* be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
|
||||
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* For comments regarding functions please see the header file.
|
||||
*/
|
||||
|
||||
#include "guichan/widgets/window.hpp"
|
||||
|
||||
#include "guichan/exception.hpp"
|
||||
#include "guichan/font.hpp"
|
||||
#include "guichan/graphics.hpp"
|
||||
#include "guichan/mouseinput.hpp"
|
||||
|
||||
namespace gcn
|
||||
{
|
||||
Window::Window()
|
||||
:mMoved(false)
|
||||
{
|
||||
setFrameSize(1);
|
||||
setPadding(2);
|
||||
setTitleBarHeight(16);
|
||||
setAlignment(Graphics::CENTER);
|
||||
addMouseListener(this);
|
||||
setMovable(true);
|
||||
setOpaque(true);
|
||||
}
|
||||
|
||||
Window::Window(const std::string& caption)
|
||||
:mMoved(false)
|
||||
{
|
||||
setCaption(caption);
|
||||
setFrameSize(1);
|
||||
setPadding(2);
|
||||
setTitleBarHeight(16);
|
||||
setAlignment(Graphics::CENTER);
|
||||
addMouseListener(this);
|
||||
setMovable(true);
|
||||
setOpaque(true);
|
||||
}
|
||||
|
||||
Window::~Window()
|
||||
{
|
||||
}
|
||||
|
||||
void Window::setPadding(unsigned int padding)
|
||||
{
|
||||
mPadding = padding;
|
||||
}
|
||||
|
||||
unsigned int Window::getPadding() const
|
||||
{
|
||||
return mPadding;
|
||||
}
|
||||
|
||||
void Window::setTitleBarHeight(unsigned int height)
|
||||
{
|
||||
mTitleBarHeight = height;
|
||||
}
|
||||
|
||||
unsigned int Window::getTitleBarHeight()
|
||||
{
|
||||
return mTitleBarHeight;
|
||||
}
|
||||
|
||||
void Window::setCaption(const std::string& caption)
|
||||
{
|
||||
mCaption = caption;
|
||||
}
|
||||
|
||||
const std::string& Window::getCaption() const
|
||||
{
|
||||
return mCaption;
|
||||
}
|
||||
|
||||
void Window::setAlignment(Graphics::Alignment alignment)
|
||||
{
|
||||
mAlignment = alignment;
|
||||
}
|
||||
|
||||
Graphics::Alignment Window::getAlignment() const
|
||||
{
|
||||
return mAlignment;
|
||||
}
|
||||
|
||||
void Window::draw(Graphics* graphics)
|
||||
{
|
||||
const Color &faceColor = getBaseColor();
|
||||
Color highlightColor, shadowColor;
|
||||
const int alpha = getBaseColor().a;
|
||||
highlightColor = faceColor + 0x303030;
|
||||
highlightColor.a = alpha;
|
||||
shadowColor = faceColor - 0x303030;
|
||||
shadowColor.a = alpha;
|
||||
|
||||
Rectangle d = getChildrenArea();
|
||||
|
||||
// Fill the background around the content
|
||||
graphics->setColor(faceColor);
|
||||
// Fill top
|
||||
graphics->fillRectangle(Rectangle(0,0,getWidth(),d.y - 1));
|
||||
// Fill left
|
||||
graphics->fillRectangle(Rectangle(0,d.y - 1, d.x - 1, getHeight() - d.y + 1));
|
||||
// Fill right
|
||||
graphics->fillRectangle(Rectangle(d.x + d.width + 1,
|
||||
d.y - 1,
|
||||
getWidth() - d.x - d.width - 1,
|
||||
getHeight() - d.y + 1));
|
||||
// Fill bottom
|
||||
graphics->fillRectangle(Rectangle(d.x - 1,
|
||||
d.y + d.height + 1,
|
||||
d.width + 2,
|
||||
getHeight() - d.height - d.y - 1));
|
||||
|
||||
if (isOpaque())
|
||||
{
|
||||
graphics->fillRectangle(d);
|
||||
}
|
||||
|
||||
// Construct a rectangle one pixel bigger than the content
|
||||
d.x -= 1;
|
||||
d.y -= 1;
|
||||
d.width += 2;
|
||||
d.height += 2;
|
||||
|
||||
// Draw a border around the content
|
||||
graphics->setColor(shadowColor);
|
||||
// Top line
|
||||
graphics->drawLine(d.x,
|
||||
d.y,
|
||||
d.x + d.width - 2,
|
||||
d.y);
|
||||
|
||||
// Left line
|
||||
graphics->drawLine(d.x,
|
||||
d.y + 1,
|
||||
d.x,
|
||||
d.y + d.height - 1);
|
||||
|
||||
graphics->setColor(highlightColor);
|
||||
// Right line
|
||||
graphics->drawLine(d.x + d.width - 1,
|
||||
d.y,
|
||||
d.x + d.width - 1,
|
||||
d.y + d.height - 2);
|
||||
// Bottom line
|
||||
graphics->drawLine(d.x + 1,
|
||||
d.y + d.height - 1,
|
||||
d.x + d.width - 1,
|
||||
d.y + d.height - 1);
|
||||
|
||||
drawChildren(graphics);
|
||||
|
||||
int textX;
|
||||
int textY;
|
||||
|
||||
textY = ((int)getTitleBarHeight() - getFont()->getHeight()) / 2;
|
||||
|
||||
switch (getAlignment())
|
||||
{
|
||||
case Graphics::LEFT:
|
||||
textX = 4;
|
||||
break;
|
||||
case Graphics::CENTER:
|
||||
textX = getWidth() / 2;
|
||||
break;
|
||||
case Graphics::RIGHT:
|
||||
textX = getWidth() - 4;
|
||||
break;
|
||||
default:
|
||||
throw GCN_EXCEPTION("Unknown alignment.");
|
||||
}
|
||||
|
||||
graphics->setColor(getForegroundColor());
|
||||
graphics->setFont(getFont());
|
||||
graphics->pushClipArea(Rectangle(0, 0, getWidth(), getTitleBarHeight() - 1));
|
||||
graphics->drawText(getCaption(), textX, textY, getAlignment());
|
||||
graphics->popClipArea();
|
||||
}
|
||||
|
||||
void Window::mousePressed(MouseEvent& mouseEvent)
|
||||
{
|
||||
if (mouseEvent.getSource() != this)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (getParent() != NULL)
|
||||
{
|
||||
getParent()->moveToTop(this);
|
||||
}
|
||||
|
||||
mDragOffsetX = mouseEvent.getX();
|
||||
mDragOffsetY = mouseEvent.getY();
|
||||
|
||||
mMoved = mouseEvent.getY() <= (int)mTitleBarHeight;
|
||||
}
|
||||
|
||||
void Window::mouseReleased(MouseEvent& mouseEvent)
|
||||
{
|
||||
mMoved = false;
|
||||
}
|
||||
|
||||
void Window::mouseDragged(MouseEvent& mouseEvent)
|
||||
{
|
||||
if (mouseEvent.isConsumed() || mouseEvent.getSource() != this)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (isMovable() && mMoved)
|
||||
{
|
||||
setPosition(mouseEvent.getX() - mDragOffsetX + getX(),
|
||||
mouseEvent.getY() - mDragOffsetY + getY());
|
||||
}
|
||||
|
||||
mouseEvent.consume();
|
||||
}
|
||||
|
||||
Rectangle Window::getChildrenArea()
|
||||
{
|
||||
return Rectangle(getPadding(),
|
||||
getTitleBarHeight(),
|
||||
getWidth() - getPadding() * 2,
|
||||
getHeight() - getPadding() - getTitleBarHeight());
|
||||
}
|
||||
|
||||
void Window::setMovable(bool movable)
|
||||
{
|
||||
mMovable = movable;
|
||||
}
|
||||
|
||||
bool Window::isMovable() const
|
||||
{
|
||||
return mMovable;
|
||||
}
|
||||
|
||||
void Window::setOpaque(bool opaque)
|
||||
{
|
||||
mOpaque = opaque;
|
||||
}
|
||||
|
||||
bool Window::isOpaque()
|
||||
{
|
||||
return mOpaque;
|
||||
}
|
||||
|
||||
void Window::resizeToContent()
|
||||
{
|
||||
WidgetListIterator it;
|
||||
|
||||
int w = 0, h = 0;
|
||||
for (it = mWidgets.begin(); it != mWidgets.end(); it++)
|
||||
{
|
||||
if ((*it)->getX() + (*it)->getWidth() > w)
|
||||
{
|
||||
w = (*it)->getX() + (*it)->getWidth();
|
||||
}
|
||||
|
||||
if ((*it)->getY() + (*it)->getHeight() > h)
|
||||
{
|
||||
h = (*it)->getY() + (*it)->getHeight();
|
||||
}
|
||||
}
|
||||
|
||||
setSize(w + 2* getPadding(), h + getPadding() + getTitleBarHeight());
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user