diff options
author | Andrei Karas <akaras@inbox.ru> | 2011-01-02 01:48:38 +0200 |
---|---|---|
committer | Andrei Karas <akaras@inbox.ru> | 2011-01-02 02:41:24 +0200 |
commit | 3eeae12c498d1a4dbe969462d2ba841f77ee3ccb (patch) | |
tree | ff8eab35e732bc0749fc11677c8873a7b3a58704 /src/gui/widgets/dropdown.cpp | |
download | mv-3eeae12c498d1a4dbe969462d2ba841f77ee3ccb.tar.gz mv-3eeae12c498d1a4dbe969462d2ba841f77ee3ccb.tar.bz2 mv-3eeae12c498d1a4dbe969462d2ba841f77ee3ccb.tar.xz mv-3eeae12c498d1a4dbe969462d2ba841f77ee3ccb.zip |
Initial commit.
This code based on mana client http://www.gitorious.org/mana/mana
and my private repository.
Diffstat (limited to 'src/gui/widgets/dropdown.cpp')
-rw-r--r-- | src/gui/widgets/dropdown.cpp | 303 |
1 files changed, 303 insertions, 0 deletions
diff --git a/src/gui/widgets/dropdown.cpp b/src/gui/widgets/dropdown.cpp new file mode 100644 index 000000000..b8616643b --- /dev/null +++ b/src/gui/widgets/dropdown.cpp @@ -0,0 +1,303 @@ +/* + * The Mana Client + * Copyright (C) 2006-2009 The Mana World Development Team + * Copyright (C) 2009-2010 The Mana Developers + * + * This file is part of The Mana Client. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "gui/widgets/dropdown.h" + +#include "client.h" +#include "configuration.h" +#include "graphics.h" + +#include "gui/palette.h" +#include "gui/sdlinput.h" +#include "gui/theme.h" + +#include "gui/widgets/listbox.h" +#include "gui/widgets/scrollarea.h" + +#include "resources/image.h" + +#include "utils/dtor.h" + +#include <algorithm> + +int DropDown::instances = 0; +Image *DropDown::buttons[2][2]; +ImageRect DropDown::skin; +float DropDown::mAlpha = 1.0; + +DropDown::DropDown(gcn::ListModel *listModel): + gcn::DropDown::DropDown(listModel, + new ScrollArea, + new ListBox(listModel)) +{ + setFrameSize(2); + + // Initialize graphics + if (instances == 0) + { + // Load the background skin + + // Get the button skin + buttons[1][0] = Theme::getImageFromTheme("vscroll_up_default.png"); + buttons[0][0] = Theme::getImageFromTheme("vscroll_down_default.png"); + buttons[1][1] = Theme::getImageFromTheme("vscroll_up_pressed.png"); + buttons[0][1] = Theme::getImageFromTheme("vscroll_down_pressed.png"); + + if (buttons[0][0]) + buttons[0][0]->setAlpha(mAlpha); + if (buttons[0][1]) + buttons[0][1]->setAlpha(mAlpha); + if (buttons[1][0]) + buttons[1][0]->setAlpha(mAlpha); + if (buttons[1][1]) + buttons[1][1]->setAlpha(mAlpha); + + // get the border skin + Image *boxBorder = Theme::getImageFromTheme("deepbox.png"); + if (boxBorder) + { + int gridx[4] = {0, 3, 28, 31}; + int gridy[4] = {0, 3, 28, 31}; + int a = 0, x, y; + + for (y = 0; y < 3; y++) + { + for (x = 0; x < 3; x++) + { + skin.grid[a] = boxBorder->getSubImage(gridx[x], gridy[y], + gridx[x + 1] - + gridx[x] + 1, + gridy[y + 1] - + gridy[y] + 1); + if (skin.grid[a]) + skin.grid[a]->setAlpha(mAlpha); + a++; + } + } + + boxBorder->decRef(); + } + } + + instances++; +} + +DropDown::~DropDown() +{ + instances--; + // Free images memory + if (instances == 0) + { + if (buttons[0][0]) + buttons[0][0]->decRef(); + if (buttons[0][1]) + buttons[0][1]->decRef(); + if (buttons[1][0]) + buttons[1][0]->decRef(); + if (buttons[1][1]) + buttons[1][1]->decRef(); + + for_each(skin.grid, skin.grid + 9, dtor<Image*>()); + } + + delete mScrollArea; + mScrollArea = 0; +} + +void DropDown::updateAlpha() +{ + float alpha = std::max(Client::getGuiAlpha(), + Theme::instance()->getMinimumOpacity()); + + if (mAlpha != alpha) + { + mAlpha = alpha; + + if (buttons[0][0]) + buttons[0][0]->setAlpha(mAlpha); + if (buttons[0][1]) + buttons[0][1]->setAlpha(mAlpha); + if (buttons[1][0]) + buttons[1][0]->setAlpha(mAlpha); + if (buttons[1][1]) + buttons[1][1]->setAlpha(mAlpha); + + for (int a = 0; a < 9; a++) + { + if (skin.grid[a]) + skin.grid[a]->setAlpha(mAlpha); + } + } +} + +void DropDown::draw(gcn::Graphics* graphics) +{ + int h; + + if (mDroppedDown) + h = mFoldedUpHeight; + else + h = getHeight(); + + updateAlpha(); + + const int alpha = static_cast<int>(mAlpha * 255.0f); + gcn::Color faceColor = getBaseColor(); + faceColor.a = alpha; + const gcn::Color *highlightColor = &Theme::getThemeColor(Theme::HIGHLIGHT, + alpha); + gcn::Color shadowColor = faceColor - 0x303030; + shadowColor.a = alpha; + + if (mListBox->getListModel() && mListBox->getSelected() >= 0) + { + graphics->setFont(getFont()); + graphics->setColor(Theme::getThemeColor(Theme::TEXT)); + graphics->drawText(mListBox->getListModel()->getElementAt( + mListBox->getSelected()), 1, 0); + } + + if (isFocused()) + { + if (highlightColor) + graphics->setColor(*highlightColor); + graphics->drawRectangle(gcn::Rectangle(0, 0, getWidth() - h, h)); + } + + drawButton(graphics); + + if (mDroppedDown) + { + drawChildren(graphics); + + // Draw two lines separating the ListBox with selected + // element view. + if (highlightColor) + graphics->setColor(*highlightColor); + graphics->drawLine(0, h, getWidth(), h); + graphics->setColor(shadowColor); + graphics->drawLine(0, h + 1, getWidth(), h + 1); + } +} + +void DropDown::drawFrame(gcn::Graphics *graphics) +{ + const int bs = getFrameSize(); + const int w = getWidth() + bs * 2; + const int h = getHeight() + bs * 2; + + static_cast<Graphics*>(graphics)->drawImageRect(0, 0, w, h, skin); +} + +void DropDown::drawButton(gcn::Graphics *graphics) +{ + int height = mDroppedDown ? mFoldedUpHeight : getHeight(); + + if (buttons[mDroppedDown][mPushed]) + { + static_cast<Graphics*>(graphics)-> + drawImage(buttons[mDroppedDown][mPushed], + getWidth() - height + 2, 1); + } +} + +// -- KeyListener notifications +void DropDown::keyPressed(gcn::KeyEvent& keyEvent) +{ + if (keyEvent.isConsumed()) + return; + + gcn::Key key = keyEvent.getKey(); + + if (key.getValue() == Key::ENTER || key.getValue() == Key::SPACE) + dropDown(); + else if (key.getValue() == Key::UP) + setSelected(getSelected() - 1); + else if (key.getValue() == Key::DOWN) + setSelected(getSelected() + 1); + else if (key.getValue() == Key::HOME) + setSelected(0); + else if (key.getValue() == Key::END && mListBox->getListModel()) + setSelected(mListBox->getListModel()->getNumberOfElements() - 1); + else + return; + + keyEvent.consume(); +} + +void DropDown::focusLost(const gcn::Event& event) +{ + gcn::DropDown::focusLost(event); + releaseModalMouseInputFocus(); +} + +void DropDown::mousePressed(gcn::MouseEvent& mouseEvent) +{ + gcn::DropDown::mousePressed(mouseEvent); + + if (0 <= mouseEvent.getY() && mouseEvent.getY() < getHeight() && + mouseEvent.getX() >= 0 && mouseEvent.getX() < getWidth() && + mouseEvent.getButton() == gcn::MouseEvent::LEFT && mDroppedDown && + mouseEvent.getSource() == mListBox) + { + mPushed = false; + foldUp(); + releaseModalMouseInputFocus(); + distributeActionEvent(); + } +} + +void DropDown::mouseWheelMovedUp(gcn::MouseEvent& mouseEvent) +{ + setSelected(getSelected() - 1); + mouseEvent.consume(); +} + +void DropDown::mouseWheelMovedDown(gcn::MouseEvent& mouseEvent) +{ + setSelected(getSelected() + 1); + mouseEvent.consume(); +} + +void DropDown::setSelectedString(std::string str) +{ + gcn::ListModel *listModel = mListBox->getListModel(); + if (!listModel) + return; + + for (int f = 0; f < listModel->getNumberOfElements(); f ++) + { + if (listModel->getElementAt(f) == str) + { + setSelected(f); + break; + } + } +} + +std::string DropDown::getSelectedString() const +{ + gcn::ListModel *listModel = mListBox->getListModel(); + if (!listModel) + return ""; + + return listModel->getElementAt(getSelected()); +} |