00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061 #include "guichan/widgets/radiobutton.hpp"
00062
00063 #include "guichan/font.hpp"
00064 #include "guichan/graphics.hpp"
00065 #include "guichan/key.hpp"
00066 #include "guichan/mouseinput.hpp"
00067
00068 namespace gcn
00069 {
00070 RadioButton::GroupMap RadioButton::mGroupMap;
00071
00072 RadioButton::RadioButton()
00073 {
00074 setMarked(false);
00075
00076 setFocusable(true);
00077 addMouseListener(this);
00078 addKeyListener(this);
00079 }
00080
00081 RadioButton::RadioButton(const std::string &caption,
00082 const std::string &group,
00083 bool marked)
00084 {
00085 setCaption(caption);
00086 setGroup(group);
00087 setMarked(marked);
00088
00089 setFocusable(true);
00090 addMouseListener(this);
00091 addKeyListener(this);
00092
00093 adjustSize();
00094 }
00095
00096 RadioButton::~RadioButton()
00097 {
00098
00099 setGroup("");
00100 }
00101
00102 void RadioButton::draw(Graphics* graphics)
00103 {
00104 drawBox(graphics);
00105
00106 graphics->setFont(getFont());
00107 graphics->setColor(getForegroundColor());
00108
00109 int h = getHeight() + getHeight() / 2;
00110
00111 graphics->drawText(getCaption(), h - 2, 0);
00112
00113 if (isFocused())
00114 {
00115 graphics->drawRectangle(Rectangle(h - 4, 0, getWidth() - h + 3, getHeight()));
00116 }
00117 }
00118
00119 void RadioButton::drawBorder(Graphics* graphics)
00120 {
00121 Color faceColor = getBaseColor();
00122 Color highlightColor, shadowColor;
00123 int alpha = getBaseColor().a;
00124 int width = getWidth() + getBorderSize() * 2 - 1;
00125 int height = getHeight() + getBorderSize() * 2 - 1;
00126 highlightColor = faceColor + 0x303030;
00127 highlightColor.a = alpha;
00128 shadowColor = faceColor - 0x303030;
00129 shadowColor.a = alpha;
00130
00131 unsigned int i;
00132 for (i = 0; i < getBorderSize(); ++i)
00133 {
00134 graphics->setColor(shadowColor);
00135 graphics->drawLine(i,i, width - i, i);
00136 graphics->drawLine(i,i + 1, i, height - i - 1);
00137 graphics->setColor(highlightColor);
00138 graphics->drawLine(width - i,i + 1, width - i, height - i);
00139 graphics->drawLine(i,height - i, width - i - 1, height - i);
00140 }
00141 }
00142
00143 void RadioButton::drawBox(Graphics *graphics)
00144 {
00145 int h;
00146
00147 if (getHeight()%2 == 0)
00148 {
00149 h = getHeight() - 2;
00150 }
00151 else
00152 {
00153 h = getHeight() - 1;
00154 }
00155
00156 int alpha = getBaseColor().a;
00157 Color faceColor = getBaseColor();
00158 faceColor.a = alpha;
00159 Color highlightColor = faceColor + 0x303030;
00160 highlightColor.a = alpha;
00161 Color shadowColor = faceColor - 0x303030;
00162 shadowColor.a = alpha;
00163
00164 graphics->setColor(getBackgroundColor());
00165
00166 int i;
00167 int hh = (h + 1) / 2;
00168
00169 for (i = 1; i <= hh; ++i)
00170 {
00171 graphics->drawLine(hh - i + 1,
00172 i,
00173 hh + i - 1,
00174 i);
00175 }
00176
00177 for (i = 1; i < hh; ++i)
00178 {
00179 graphics->drawLine(hh - i + 1,
00180 h - i,
00181 hh + i - 1,
00182 h - i);
00183 }
00184
00185 graphics->setColor(shadowColor);
00186 graphics->drawLine(hh, 0, 0, hh);
00187 graphics->drawLine(hh + 1, 1, h - 1, hh - 1);
00188
00189 graphics->setColor(highlightColor);
00190 graphics->drawLine(1, hh + 1, hh, h);
00191 graphics->drawLine(hh + 1, h - 1, h, hh);
00192
00193 graphics->setColor(getForegroundColor());
00194
00195 int hhh = hh - 3;
00196 if (isMarked())
00197 {
00198 for (i = 0; i < hhh; ++i)
00199 {
00200 graphics->drawLine(hh - i, 4 + i, hh + i, 4 + i);
00201 }
00202 for (i = 0; i < hhh; ++i)
00203 {
00204 graphics->drawLine(hh - i, h - 4 - i, hh + i, h - 4 - i);
00205 }
00206
00207 }
00208 }
00209
00210 bool RadioButton::isMarked() const
00211 {
00212 return mMarked;
00213 }
00214
00215 void RadioButton::setMarked(bool marked)
00216 {
00217 if (marked && mGroup != "")
00218 {
00219 GroupIterator iter, iterEnd;
00220 iterEnd = mGroupMap.upper_bound(mGroup);
00221
00222 for (iter = mGroupMap.lower_bound(mGroup);
00223 iter != iterEnd;
00224 iter++)
00225 {
00226 if (iter->second->isMarked())
00227 {
00228 iter->second->setMarked(false);
00229 }
00230 }
00231 }
00232
00233 mMarked = marked;
00234 }
00235
00236 const std::string &RadioButton::getCaption() const
00237 {
00238 return mCaption;
00239 }
00240
00241 void RadioButton::setCaption(const std::string caption)
00242 {
00243 mCaption = caption;
00244 }
00245
00246 void RadioButton::keyPress(const Key& key)
00247 {
00248 if (key.getValue() == Key::ENTER ||
00249 key.getValue() == Key::SPACE)
00250 {
00251 setMarked(true);
00252 generateAction();
00253 }
00254 }
00255
00256 void RadioButton::mouseClick(int x, int y, int button, int count)
00257 {
00258 if (button == MouseInput::LEFT)
00259 {
00260 setMarked(true);
00261 generateAction();
00262 }
00263 }
00264
00265 void RadioButton::setGroup(const std::string &group)
00266 {
00267 if (mGroup != "")
00268 {
00269 GroupIterator iter, iterEnd;
00270 iterEnd = mGroupMap.upper_bound(mGroup);
00271
00272 for (iter = mGroupMap.lower_bound(mGroup);
00273 iter != iterEnd;
00274 iter++)
00275 {
00276 if (iter->second == this)
00277 {
00278 mGroupMap.erase(iter);
00279 break;
00280 }
00281 }
00282 }
00283
00284 if (group != "")
00285 {
00286 mGroupMap.insert(
00287 std::pair<std::string, RadioButton *>(group, this));
00288 }
00289
00290 mGroup = group;
00291 }
00292
00293 const std::string &RadioButton::getGroup() const
00294 {
00295 return mGroup;
00296 }
00297
00298 void RadioButton::adjustSize()
00299 {
00300 int height = getFont()->getHeight();
00301
00302 setHeight(height);
00303 setWidth(getFont()->getWidth(getCaption()) + height + height/2);
00304 }
00305 }