summaryrefslogtreecommitdiff
path: root/src/gui/table.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui/table.cpp')
-rw-r--r--src/gui/table.cpp263
1 files changed, 212 insertions, 51 deletions
diff --git a/src/gui/table.cpp b/src/gui/table.cpp
index 7e855523..19039b2d 100644
--- a/src/gui/table.cpp
+++ b/src/gui/table.cpp
@@ -19,13 +19,19 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#include <cassert>
-
-#include <guichan/graphics.hpp>
#include <guichan/actionlistener.hpp>
+#include <guichan/graphics.hpp>
+#include <guichan/key.hpp>
+#include "colour.h"
#include "table.h"
+#include "../configuration.h"
+
+#include "../utils/dtor.h"
+
+float GuiTable::mAlpha = config.getValue("guialpha", 0.8);
+
class GuiTableActionListener : public gcn::ActionListener
{
public:
@@ -49,7 +55,8 @@ GuiTableActionListener::GuiTableActionListener(GuiTable *table, gcn::Widget *wid
mColumn(column),
mWidget(widget)
{
- if (widget) {
+ if (widget)
+ {
widget->addActionListener(this);
widget->_setParent(table);
}
@@ -57,7 +64,8 @@ GuiTableActionListener::GuiTableActionListener(GuiTable *table, gcn::Widget *wid
GuiTableActionListener::~GuiTableActionListener()
{
- if (mWidget) {
+ if (mWidget)
+ {
mWidget->removeActionListener(this);
mWidget->_setParent(NULL);
}
@@ -70,14 +78,20 @@ void GuiTableActionListener::action(const gcn::ActionEvent& actionEvent)
}
-GuiTable::GuiTable(TableModel *initial_model) :
+GuiTable::GuiTable(TableModel *initial_model, gcn::Color background,
+ bool opacity) :
mLinewiseMode(false),
+ mWrappingEnabled(false),
+ mOpaque(opacity),
+ mBackgroundColor(background),
mModel(NULL),
mSelectedRow(0),
mSelectedColumn(0),
mTopWidget(NULL)
{
setModel(initial_model);
+ setFocusable(true);
+
addMouseListener(this);
addKeyListener(this);
}
@@ -94,16 +108,17 @@ TableModel *GuiTable::getModel() const
void GuiTable::setModel(TableModel *new_model)
{
- if (mModel) {
+ if (mModel)
+ {
uninstallActionListeners();
mModel->removeListener(this);
}
-
mModel = new_model;
installActionListeners();
- if (new_model) {
+ if (new_model)
+ {
new_model->installListener(this);
recomputeDimensions();
}
@@ -168,10 +183,62 @@ int GuiTable::getColumnWidth(int i)
return 0;
}
-void GuiTable::uninstallActionListeners()
+void GuiTable::setSelectedRow(int selected)
+{
+ if (mModel == NULL)
+ {
+ mSelectedRow = -1;
+ }
+ else
+ {
+ if (selected < 0 && !mWrappingEnabled)
+ {
+ mSelectedRow = -1;
+ }
+ else if (selected >= mModel->getRows() && mWrappingEnabled)
+ {
+ mSelectedRow = 0;
+ }
+ else if ((selected >= mModel->getRows() && !mWrappingEnabled) ||
+ (selected < 0 && mWrappingEnabled))
+ {
+ mSelectedRow = mModel->getRows() - 1;
+ }
+ else
+ {
+ mSelectedRow = selected;
+ }
+ }
+}
+
+void GuiTable::setSelectedColumn(int selected)
{
- for (std::vector<GuiTableActionListener *>::const_iterator it = action_listeners.begin(); it != action_listeners.end(); it++)
- delete *it;
+ if (mModel == NULL)
+ {
+ mSelectedColumn = -1;
+ }
+ else
+ {
+ if ((selected >= mModel->getColumns() && mWrappingEnabled) ||
+ (selected < 0 && !mWrappingEnabled))
+ {
+ mSelectedColumn = 0;
+ }
+ else if ((selected >= mModel->getColumns() && !mWrappingEnabled) ||
+ (selected < 0 && mWrappingEnabled))
+ {
+ mSelectedColumn = mModel->getColumns() - 1;
+ }
+ else
+ {
+ mSelectedColumn = selected;
+ }
+ }
+}
+
+void GuiTable::uninstallActionListeners(void)
+{
+ delete_all(action_listeners);
action_listeners.clear();
}
@@ -184,10 +251,11 @@ void GuiTable::installActionListeners()
int columns = mModel->getColumns();
for (int row = 0; row < rows; ++row)
- for (int column = 0; column < columns; ++column) {
+ for (int column = 0; column < columns; ++column)
+ {
gcn::Widget *widget = mModel->getElementAt(row, column);
action_listeners.push_back(new GuiTableActionListener(this, widget,
- row, column));
+ row, column));
}
_setFocusHandler(_getFocusHandler()); // propagate focus handler to widgets
@@ -196,12 +264,22 @@ void GuiTable::installActionListeners()
// -- widget ops
void GuiTable::draw(gcn::Graphics* graphics)
{
- graphics->setColor(getBackgroundColor());
- graphics->fillRectangle(gcn::Rectangle(0, 0, getWidth(), getHeight()));
-
if (!mModel)
return;
+ if (config.getValue("guialpha", 0.8) != mAlpha)
+ mAlpha = config.getValue("guialpha", 0.8);
+
+ if (mOpaque)
+ {
+ const int red = getBackgroundColor().r;
+ const int green = getBackgroundColor().g;
+ const int blue = getBackgroundColor().b;
+ const int alpha = mAlpha * 255;
+ graphics->setColor(gcn::Color(red, green, blue, alpha));
+ graphics->fillRectangle(gcn::Rectangle(0, 0, getWidth(), getHeight()));
+ }
+
// First, determine how many rows we need to draw, and where we should start.
int first_row = -(getY() / getRowHeight());
@@ -223,44 +301,68 @@ void GuiTable::draw(gcn::Graphics* graphics)
int height = getRowHeight();
int y_offset = first_row * height;
- for (int r = first_row; r < first_row + rows_nr; ++r) {
+ for (int r = first_row; r < first_row + rows_nr; ++r)
+ {
int x_offset = 0;
- for (int c = first_column; c <= last_column; ++c) {
+ for (int c = first_column; c <= last_column; ++c)
+ {
gcn::Widget *widget = mModel->getElementAt(r, c);
int width = getColumnWidth(c);
- if (widget) {
+ if (widget)
+ {
gcn::Rectangle bounds(x_offset, y_offset, width, height);
- if (widget == mTopWidget) {
+ if (widget == mTopWidget)
+ {
bounds.height = widget->getHeight();
bounds.width = widget->getWidth();
}
widget->setDimension(bounds);
+ if (!mLinewiseMode && c == mSelectedColumn && r == mSelectedRow)
+ {
+ bool valid;
+ const int red =
+ (textColour->getColour('H', valid) >> 16) & 0xFF;
+ const int green =
+ (textColour->getColour('H', valid) >> 8) & 0xFF;
+ const int blue = textColour->getColour('H', valid) & 0xFF;
+ const int alpha = mAlpha * 127;
+
+ graphics->setColor(gcn::Color(red, green, blue, alpha));
+ graphics->fillRectangle(bounds);
+ }
+
graphics->pushClipArea(bounds);
widget->draw(graphics);
graphics->popClipArea();
-
- if (!mLinewiseMode
- && c == mSelectedColumn
- && r == mSelectedRow)
- graphics->drawRectangle(bounds);
}
x_offset += width;
}
- if (mLinewiseMode
- && r == mSelectedRow)
- graphics->drawRectangle(gcn::Rectangle(0, y_offset,
+ if (mLinewiseMode && r == mSelectedRow)
+ {
+ bool valid;
+ const int red =
+ (textColour->getColour('H', valid) >> 16) & 0xFF;
+ const int green =
+ (textColour->getColour('H', valid) >> 8) & 0xFF;
+ const int blue = textColour->getColour('H', valid) & 0xFF;
+ const int alpha = mAlpha * 127;
+
+ graphics->setColor(gcn::Color(red, green, blue, alpha));
+ graphics->fillRectangle(gcn::Rectangle(0, y_offset,
x_offset, height));
+ }
y_offset += height;
}
- if (mTopWidget) {
+ if (mTopWidget)
+ {
gcn::Rectangle bounds = mTopWidget->getDimension();
graphics->pushClipArea(bounds);
mTopWidget->draw(graphics);
@@ -268,21 +370,17 @@ void GuiTable::draw(gcn::Graphics* graphics)
}
}
-void GuiTable::logic()
-{
-}
-
void GuiTable::moveToTop(gcn::Widget *widget)
{
gcn::Widget::moveToTop(widget);
- this->mTopWidget = widget;
+ mTopWidget = widget;
}
void GuiTable::moveToBottom(gcn::Widget *widget)
{
gcn::Widget::moveToBottom(widget);
- if (widget == this->mTopWidget)
- this->mTopWidget = NULL;
+ if (widget == mTopWidget)
+ mTopWidget = NULL;
}
gcn::Rectangle GuiTable::getChildrenArea()
@@ -293,16 +391,62 @@ gcn::Rectangle GuiTable::getChildrenArea()
// -- KeyListener notifications
void GuiTable::keyPressed(gcn::KeyEvent& keyEvent)
{
+ gcn::Key key = keyEvent.getKey();
+
+ if (key.getValue() == gcn::Key::ENTER || key.getValue() == gcn::Key::SPACE)
+ {
+ distributeActionEvent();
+ keyEvent.consume();
+ }
+ else if (key.getValue() == gcn::Key::UP)
+ {
+ setSelectedRow(mSelectedRow - 1);
+
+ keyEvent.consume();
+ }
+ else if (key.getValue() == gcn::Key::DOWN)
+ {
+ setSelectedRow(mSelectedRow + 1);
+
+ keyEvent.consume();
+ }
+ else if (key.getValue() == gcn::Key::LEFT)
+ {
+ setSelectedColumn(mSelectedColumn - 1);
+
+ keyEvent.consume();
+ }
+ else if (key.getValue() == gcn::Key::RIGHT)
+ {
+ setSelectedColumn(mSelectedColumn + 1);
+
+ keyEvent.consume();
+ }
+ else if (key.getValue() == gcn::Key::HOME)
+ {
+ setSelectedRow(0);
+ setSelectedColumn(0);
+ keyEvent.consume();
+ }
+ else if (key.getValue() == gcn::Key::END)
+ {
+ setSelectedRow(mModel->getRows() - 1);
+ setSelectedColumn(mModel->getColumns() - 1);
+ keyEvent.consume();
+ }
}
// -- MouseListener notifications
void GuiTable::mousePressed(gcn::MouseEvent& mouseEvent)
{
- if (mouseEvent.getButton() == gcn::MouseEvent::LEFT) {
+ if (mouseEvent.getButton() == gcn::MouseEvent::LEFT)
+ {
int row = getRowForY(mouseEvent.getY());
int column = getColumnForX(mouseEvent.getX());
- if (row > -1 && column > -1) {
+ if (row > -1 && column > -1 &&
+ row < mModel->getRows() && column < mModel->getColumns())
+ {
mSelectedColumn = column;
mSelectedRow = row;
}
@@ -313,10 +457,25 @@ void GuiTable::mousePressed(gcn::MouseEvent& mouseEvent)
void GuiTable::mouseWheelMovedUp(gcn::MouseEvent& mouseEvent)
{
+ if (isFocused())
+ {
+ if (getSelectedRow() >= 0 )
+ {
+ setSelectedRow(getSelectedRow() - 1);
+ }
+
+ mouseEvent.consume();
+ }
}
void GuiTable::mouseWheelMovedDown(gcn::MouseEvent& mouseEvent)
{
+ if (isFocused())
+ {
+ setSelectedRow(getSelectedRow() + 1);
+
+ mouseEvent.consume();
+ }
}
void GuiTable::mouseDragged(gcn::MouseEvent& mouseEvent)
@@ -326,10 +485,13 @@ void GuiTable::mouseDragged(gcn::MouseEvent& mouseEvent)
// -- TableModelListener notifications
void GuiTable::modelUpdated(bool completed)
{
- if (completed) {
+ if (completed)
+ {
recomputeDimensions();
installActionListeners();
- } else { // before the update?
+ }
+ else
+ { // before the update?
mTopWidget = NULL; // No longer valid in general
uninstallActionListeners();
}
@@ -340,18 +502,18 @@ gcn::Widget *GuiTable::getWidgetAt(int x, int y)
int row = getRowForY(y);
int column = getColumnForX(x);
- if (mTopWidget
- && mTopWidget->getDimension().isPointInRect(x, y))
+ if (mTopWidget && mTopWidget->getDimension().isPointInRect(x, y))
return mTopWidget;
- if (row > -1
- && column > -1) {
+ if (row > -1 && column > -1)
+ {
gcn::Widget *w = mModel->getElementAt(row, column);
if (w && w->isFocusable())
return w;
else
return NULL; // Grab the event locally
- } else
+ }
+ else
return NULL;
}
@@ -359,8 +521,7 @@ int GuiTable::getRowForY(int y)
{
int row = y / getRowHeight();
- if (row < 0
- || row >= mModel->getRows())
+ if (row < 0 || row >= mModel->getRows())
return -1;
else
return row;
@@ -371,14 +532,14 @@ int GuiTable::getColumnForX(int x)
int column;
int delta = 0;
- for (column = 0; column < mModel->getColumns(); column++) {
+ for (column = 0; column < mModel->getColumns(); column++)
+ {
delta += getColumnWidth(column);
if (x <= delta)
break;
}
- if (column < 0
- || column >= mModel->getColumns())
+ if (column < 0 || column >= mModel->getColumns())
return -1;
else
return column;