~ubuntu-branches/ubuntu/natty/balder2d/natty

« back to all changes in this revision

Viewing changes to src/menu/widgets/skinneddropdown.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Bjørn Hansen
  • Date: 2008-06-15 17:15:38 UTC
  • mfrom: (1.1.1 upstream) (3.1.2 hardy)
  • Revision ID: james.westby@ubuntu.com-20080615171538-e407e07wbtdy0qs8
Tags: 1.0-1
* new upstream release
* update for guichan 8.1 (Closes: #482584)
* use physicsfs to make data/config/map/aiscript loading more flexible
* new skins for menus
* fix typo in control file long description (Closes: #458401)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/***************************************************************************
 
2
 *   Copyright (C) 2008 by Bjorn Hansen                                    *
 
3
 *   holomorph@users.sourceforge.net                                       *
 
4
 *                                                                         *
 
5
 *   This program is free software; you can redistribute it and/or modify  *
 
6
 *   it under the terms of the GNU General Public License as published by  *
 
7
 *   the Free Software Foundation; either version 2 of the License, or     *
 
8
 *   (at your option) any later version.                                   *
 
9
 *                                                                         *
 
10
 *   This program is distributed in the hope that it will be useful,       *
 
11
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 
12
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 
13
 *   GNU General Public License for more details.                          *
 
14
 *                                                                         *
 
15
 *   You should have received a copy of the GNU General Public License     *
 
16
 *   along with this program; if not, write to the                         *
 
17
 *   Free Software Foundation, Inc.,                                       *
 
18
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 
19
 ***************************************************************************/
 
20
 
 
21
#include <sstream>
 
22
#include <guichan/font.hpp>
 
23
#include <guichan/graphics.hpp>
 
24
#include "menu/widgets/skinneddropdown.h"
 
25
#include "balder2dtypes.h"
 
26
 
 
27
using namespace Balder;
 
28
using namespace gcn;
 
29
 
 
30
void SkinnedListBox::draw(Graphics* graphics)
 
31
{
 
32
    Color bgColor = MenuColors::UNFOCUSED;
 
33
    //bgColor.a = MenuColors::bgAlpha;
 
34
    graphics->setColor(bgColor);
 
35
    graphics->fillRectangle(Rectangle(0, 0, getWidth(), getHeight()));
 
36
 
 
37
    if (mListModel == NULL)
 
38
    {
 
39
        return;
 
40
    }
 
41
 
 
42
    graphics->setColor(getForegroundColor());
 
43
    graphics->setFont(getFont());
 
44
 
 
45
    // Check the current clip area so we don't draw unnecessary items
 
46
    // that are not visible.
 
47
    const ClipRectangle currentClipArea = graphics->getCurrentClipArea();
 
48
    int rowHeight = getRowHeight();
 
49
 
 
50
    // Calculate the number of rows to draw by checking the clip area.
 
51
    // The addition of two makes covers a partial visible row at the top
 
52
    // and a partial visible row at the bottom.
 
53
    int numberOfRows = currentClipArea.height / rowHeight + 2;
 
54
 
 
55
    if (numberOfRows > mListModel->getNumberOfElements())
 
56
    {
 
57
        numberOfRows = mListModel->getNumberOfElements();
 
58
    }
 
59
 
 
60
    // Calculate which row to start drawing. If the list box
 
61
    // has a negative y coordinate value we should check if
 
62
    // we should drop rows in the begining of the list as
 
63
    // they might not be visible. A negative y value is very
 
64
    // common if the list box for instance resides in a scroll
 
65
    // area and the user has scrolled the list box downwards.
 
66
    int startRow;
 
67
    if (getY() < 0)
 
68
    {
 
69
        startRow = -1 * (getY() / rowHeight);
 
70
    }
 
71
    else
 
72
    {
 
73
        startRow = 0;
 
74
    }
 
75
 
 
76
    // end row should not exceed list size
 
77
    int endRow = std::min(startRow+numberOfRows, mListModel->getNumberOfElements());
 
78
    // The y coordinate where we start to draw the text is
 
79
    // simply the y coordinate multiplied with the font height.
 
80
    int y = rowHeight * startRow;
 
81
    for (int i = startRow; i < endRow; ++i)
 
82
    {
 
83
        if (i == mSelected)
 
84
        {
 
85
            graphics->setColor(getSelectionColor());
 
86
            graphics->fillRectangle(Rectangle(0, y, getWidth(), rowHeight));
 
87
            graphics->setColor(getForegroundColor());
 
88
        }
 
89
 
 
90
        // If the row height is greater than the font height we
 
91
        // draw the text with a center vertical alignment.
 
92
        if (rowHeight > getFont()->getHeight())
 
93
        {
 
94
            graphics->drawText(mListModel->getElementAt(i), 1, y + rowHeight / 2 - getFont()->getHeight() / 2);
 
95
        }
 
96
        else
 
97
        {
 
98
            graphics->drawText(mListModel->getElementAt(i), 1, y);
 
99
        }
 
100
 
 
101
        y += rowHeight;
 
102
    }
 
103
}
 
104
 
 
105
void SkinnedDropDown::keyPressed(KeyEvent& keyEvent)
 
106
{
 
107
    // work around guichan bug where when the dropdown is open arrow keys get counted twice (skips elements)
 
108
    if (keyEvent.isConsumed()) return;
 
109
    gcn::DropDown::keyPressed(keyEvent);
 
110
}
 
111
 
 
112
void SkinnedDropDown::draw(Graphics* graphics)
 
113
{
 
114
    int h;
 
115
 
 
116
    if (mDroppedDown)
 
117
    {
 
118
        h = mFoldedUpHeight;
 
119
    }
 
120
    else
 
121
    {
 
122
        h = getHeight();
 
123
    }
 
124
 
 
125
    Color highlightColor, shadowColor;
 
126
    highlightColor = MenuColors::HIGHLIGHT;
 
127
    shadowColor = MenuColors::SHADOW;
 
128
 
 
129
    // draw the border
 
130
    for (int i=0; i<5 ;++i)
 
131
    {
 
132
        shadowColor.a -= i*0x10;
 
133
        graphics->setColor(shadowColor);
 
134
        graphics->drawLine(i,i,getWidth()-i,i);
 
135
        graphics->drawLine(i,i,i,getHeight()-i);
 
136
    }
 
137
    for (int i=0; i<5 ;++i)
 
138
    {
 
139
        highlightColor.a -= i*0x10;
 
140
        graphics->setColor(highlightColor);
 
141
        graphics->drawLine(getWidth()-i,i,getWidth()-i,getHeight()-i);
 
142
        graphics->drawLine(i,getHeight()-i,getWidth()-i,getHeight()-i);
 
143
    }
 
144
 
 
145
    // Push a clip area so the other drawings don't need to worry
 
146
    // about the border.
 
147
    graphics->pushClipArea(Rectangle(1, 1, getWidth() - 2, h - 2));
 
148
    const Rectangle currentClipArea = graphics->getCurrentClipArea();
 
149
 
 
150
    Color bgColor = isFocused() ? MenuColors::FOCUSED : MenuColors::UNFOCUSED;
 
151
    bgColor.a = MenuColors::bgAlpha;
 
152
    graphics->setColor(bgColor);
 
153
    graphics->fillRectangle(Rectangle(0, 0, currentClipArea.width, currentClipArea.height));
 
154
 
 
155
    if (mListBox->getListModel()
 
156
            && mListBox->getSelected() >= 0)
 
157
    {
 
158
        graphics->setColor(getForegroundColor());
 
159
        graphics->setFont(getFont());
 
160
 
 
161
        graphics->drawText(mListBox->getListModel()->getElementAt(mListBox->getSelected()), 1, 5);
 
162
    }
 
163
 
 
164
    // Push a clip area before drawing the button.
 
165
    graphics->pushClipArea(Rectangle(currentClipArea.width - currentClipArea.height,
 
166
                                     0,
 
167
                                     currentClipArea.height,
 
168
                                     currentClipArea.height));
 
169
    drawButton(graphics);
 
170
    graphics->popClipArea();
 
171
    graphics->popClipArea();
 
172
 
 
173
    if (mDroppedDown)
 
174
    {
 
175
        // Draw a border around the children.
 
176
//        graphics->setColor(shadowColor);
 
177
//        graphics->drawRectangle(Rectangle(0,
 
178
//                                          mFoldedUpHeight,
 
179
//                                          getWidth(),
 
180
//                                          getHeight() - mFoldedUpHeight));
 
181
        drawChildren(graphics);
 
182
    }
 
183
}
 
184
 
 
185
void SkinnedDropDown::drawButton(Graphics *graphics)
 
186
{
 
187
    Color faceColor, highlightColor, shadowColor;
 
188
    int offset;
 
189
    int alpha = MenuColors::bgAlpha;
 
190
 
 
191
    if (mPushed)
 
192
    {
 
193
        faceColor = MenuColors::FOCUSED;
 
194
        faceColor.a = alpha;
 
195
        highlightColor = MenuColors::SHADOW;
 
196
        highlightColor.a = alpha;
 
197
        shadowColor = MenuColors::HIGHLIGHT;
 
198
        shadowColor.a = alpha;
 
199
        offset = 1;
 
200
    }
 
201
    else
 
202
    {
 
203
        faceColor = MenuColors::FOCUSED;
 
204
        faceColor.a = alpha;
 
205
        highlightColor = MenuColors::HIGHLIGHT;
 
206
        highlightColor.a = alpha;
 
207
        shadowColor = MenuColors::SHADOW;
 
208
        shadowColor.a = alpha;
 
209
        offset = 0;
 
210
    }
 
211
 
 
212
    const Rectangle currentClipArea = graphics->getCurrentClipArea();
 
213
    for (int i = 0; i<3; ++i)
 
214
    {
 
215
        graphics->setColor(highlightColor);
 
216
        graphics->drawLine(i, i, currentClipArea.width - i, i);
 
217
        graphics->drawLine(i, i, i, currentClipArea.height - i);
 
218
        graphics->setColor(shadowColor);
 
219
        graphics->drawLine(currentClipArea.width - i, i, currentClipArea.width - i,currentClipArea.height - i);
 
220
        graphics->drawLine(i, currentClipArea.height - i, currentClipArea.width - i,currentClipArea.height - i);
 
221
    }
 
222
 
 
223
    graphics->setColor(faceColor);
 
224
    graphics->fillRectangle(Rectangle(1,
 
225
                                      1,
 
226
                                      currentClipArea.width - 2,
 
227
                                      currentClipArea.height - 2));
 
228
 
 
229
    graphics->setColor(MenuColors::fontColor);
 
230
 
 
231
    int i;
 
232
    int n = currentClipArea.height / 3;
 
233
    int dx = currentClipArea.height / 2;
 
234
    int dy = (currentClipArea.height * 2) / 3;
 
235
    for (i = 0; i < n; i++)
 
236
    {
 
237
        graphics->drawLine(dx - i + offset,
 
238
                           dy - i + offset,
 
239
                           dx + i + offset,
 
240
                           dy - i + offset);
 
241
    }
 
242
}
 
243
 
 
244
void SkinnedScrollArea::draw(Graphics *graphics)
 
245
{
 
246
        drawBackground(graphics);
 
247
 
 
248
        if (mVBarVisible)
 
249
        {
 
250
//            drawUpButton(graphics);
 
251
//            drawDownButton(graphics);
 
252
            drawVBar(graphics);
 
253
            drawVMarker(graphics);
 
254
 
 
255
        }
 
256
 
 
257
    drawChildren(graphics);
 
258
}
 
259
 
 
260
void SkinnedScrollArea::drawVBar(Graphics* graphics)
 
261
{
 
262
    Rectangle dim(getWidth() - mScrollbarWidth, 0, mScrollbarWidth, getHeight());
 
263
 
 
264
 
 
265
    graphics->pushClipArea(dim);
 
266
 
 
267
    int alpha = MenuColors::bgAlpha;
 
268
    Color trackColor = MenuColors::UNFOCUSED;
 
269
    trackColor.a = alpha;
 
270
    Color shadowColor = MenuColors::SHADOW;
 
271
    shadowColor.a = alpha;
 
272
 
 
273
    graphics->setColor(trackColor);
 
274
    graphics->fillRectangle(Rectangle(0, 0, dim.width, dim.height));
 
275
 
 
276
    graphics->setColor(shadowColor);
 
277
    graphics->drawLine(0, 0, 0, dim.height);
 
278
 
 
279
    graphics->popClipArea();
 
280
}
 
281
 
 
282
void SkinnedScrollArea::drawVMarker(Graphics* graphics)
 
283
{
 
284
    Rectangle dim = getVerticalMarkerDimension();
 
285
    graphics->pushClipArea(dim);
 
286
 
 
287
    int alpha = MenuColors::bgAlpha;
 
288
    Color faceColor = MenuColors::fontColor;
 
289
    Color highlightColor = MenuColors::HIGHLIGHT;
 
290
    highlightColor.a = alpha;
 
291
    Color shadowColor = MenuColors::SHADOW;
 
292
    shadowColor.a = alpha;
 
293
 
 
294
    graphics->setColor(faceColor);
 
295
    graphics->fillRectangle(Rectangle(1, 1, dim.width - 1, dim.height - 1));
 
296
 
 
297
    graphics->setColor(highlightColor);
 
298
    graphics->drawLine(0, 0, dim.width - 1, 0);
 
299
    graphics->drawLine(0, 1, 0, dim.height - 1);
 
300
 
 
301
    graphics->setColor(shadowColor);
 
302
    graphics->drawLine(1, dim.height - 1, dim.width - 1, dim.height - 1);
 
303
    graphics->drawLine(dim.width - 1, 0, dim.width - 1, dim.height - 1);
 
304
 
 
305
    graphics->popClipArea();
 
306
}