File indexing completed on 2024-09-08 06:47:57
0001 /* 0002 SPDX-FileCopyrightText: 2007 Riccardo Iaconelli <ruphy@fsfe.org> 0003 SPDX-FileCopyrightText: 2007 Paolo Capriotti <p.capriotti@gmail.com> 0004 0005 SPDX-License-Identifier: GPL-2.0-or-later 0006 */ 0007 0008 #include "button.h" 0009 0010 #include <QPainter> 0011 #include <QPen> 0012 #include "knavalbattle_debug.h" 0013 0014 #include <math.h> // fabs 0015 0016 #include "animator.h" 0017 0018 Button::Button(QGraphicsItem* parent, const QIcon& icon, 0019 const QFont& font, const QString& text) 0020 : QGraphicsObject(parent) 0021 , m_icon(icon) 0022 , m_font(font) 0023 , m_text(text) 0024 , m_fixed_width(false) 0025 , m_down(false) 0026 , m_hover(false) 0027 , m_brightness(BRIGHTNESS_NORMAL) 0028 , m_editor(nullptr) 0029 { 0030 computeSize(); 0031 } 0032 0033 Button::~Button() 0034 { 0035 if (m_animation) { 0036 m_animation->abort(); 0037 } 0038 //delete m_editor; 0039 } 0040 0041 void Button::setWidth(int width) 0042 { 0043 m_fixed_width = width != -1; 0044 m_size.setWidth(width); 0045 computeSize(); 0046 } 0047 0048 void Button::computeSize() 0049 { 0050 QFontMetrics fm(m_font); 0051 m_text_width = fm.boundingRect(m_text).width(); 0052 int h = fm.height(); 0053 if (h < 32) { 0054 h = 32; 0055 } 0056 if (!m_fixed_width) { 0057 m_size = QSize(m_text_width, h); 0058 m_size.rwidth() += 10 + 32 + 10 + 10; 0059 } 0060 else { 0061 m_size.setHeight(h); 0062 } 0063 0064 m_size.rheight() += 10 + 10; 0065 } 0066 0067 void Button::paint(QPainter *p, const QStyleOptionGraphicsItem *, QWidget *) 0068 { 0069 QPen pen(QColor(200, 200, 220, 255)); 0070 pen.setWidth(2); 0071 0072 p->setPen(pen); 0073 p->setRenderHint(QPainter::Antialiasing); 0074 p->setBrush(QBrush(QColor(static_cast<int>(m_brightness), 0075 static_cast<int>(m_brightness), 0076 static_cast<int>(m_brightness), 100))); 0077 0078 p->drawRoundedRect(1, 1, 0079 m_size.width() - 2, 0080 m_size.height() - 2, 0081 2000 / m_size.width(), 0082 2000 / m_size.height(), Qt::RelativeSize); 0083 0084 p->drawPixmap(10, // x coordinate of the icon. 0085 m_size.height() / 2 - 16, // y coordinate of the icon. 0086 32, // Icon's width. 0087 32, // Icon's height. 0088 m_icon.pixmap(32, 32)); // Icon's pixmap source. 0089 0090 p->setFont(m_font); 0091 0092 // 42 is the distance from the button's left margin to the 0093 // icon's right margin. The icon's x coordinate is 10 and its 0094 // width is 32. 0095 qreal x = boundingRect().x() + 42; 0096 qreal y = boundingRect().y(); 0097 qreal w = boundingRect().width() - 42; 0098 qreal h = boundingRect().height(); 0099 0100 // This is the rectangle which ranges from the icon's right margin 0101 // to the button's right margin. 0102 QRectF rect(x, y, w, h); 0103 0104 p->drawText(rect, Qt::AlignLeft | Qt::AlignVCenter, m_text); 0105 // updateEditor(); 0106 } 0107 0108 QRectF Button::boundingRect() const 0109 { 0110 return QRectF(1, 1, m_size.width() - 2, m_size.height() - 2); 0111 } 0112 0113 QSize Button::size() const 0114 { 0115 return m_size; 0116 } 0117 0118 void Button::onMousePress() 0119 { 0120 if (!m_down) { 0121 m_down = true; 0122 if (m_animation) { 0123 m_animation->abort(); 0124 } 0125 m_brightness = BRIGHTNESS_DOWN; 0126 0127 update(); 0128 } 0129 } 0130 0131 void Button::onMouseRelease() 0132 { 0133 if (m_down) { 0134 m_down = false; 0135 if (m_animation) { 0136 m_animation->abort(); 0137 } 0138 m_brightness = BRIGHTNESS_NORMAL; 0139 update(); 0140 } 0141 } 0142 0143 void Button::onMouseMove() 0144 { 0145 if (!m_hover) { 0146 m_hover = true; 0147 0148 if (m_down) { 0149 if (m_animation) { 0150 m_animation->abort(); 0151 } 0152 m_brightness = BRIGHTNESS_HOVER; 0153 } 0154 else if (m_animation) { 0155 m_animation->setBrightness(BRIGHTNESS_HOVER); 0156 } 0157 else { 0158 m_animation = new ButtonAnimation(this, BRIGHTNESS_HOVER); 0159 Animator::instance()->add(m_animation); 0160 } 0161 0162 update(); 0163 } 0164 } 0165 0166 void Button::onMouseLeave() 0167 { 0168 if (m_hover) { 0169 m_hover = false; 0170 0171 if (m_down) { 0172 if (m_animation) { 0173 m_animation->abort(); 0174 } 0175 m_brightness = BRIGHTNESS_NORMAL; 0176 } 0177 else if (m_animation) { 0178 m_animation->setBrightness(BRIGHTNESS_NORMAL); 0179 } 0180 else { 0181 m_animation = new ButtonAnimation(this, BRIGHTNESS_NORMAL); 0182 Animator::instance()->add(m_animation); 0183 } 0184 0185 update(); 0186 } 0187 } 0188 0189 bool Button::onClicked() 0190 { 0191 if (true) { 0192 qCDebug(KNAVALBATTLE_LOG) << "clicked"; 0193 Q_EMIT clicked(); 0194 return true; 0195 } 0196 else { 0197 return false; 0198 } 0199 } 0200 0201 void Button::setText(const QString& text) 0202 { 0203 m_text = text; 0204 update(); 0205 } 0206 0207 double Button::brightness() const 0208 { 0209 return m_brightness; 0210 } 0211 0212 void Button::setBrightness(double value) 0213 { 0214 m_brightness = value; 0215 update(); 0216 } 0217 0218 // ------------ 0219 0220 double ButtonAnimation::m_speed = 0.46; 0221 0222 ButtonAnimation::ButtonAnimation(Button* button, int brightness) 0223 : m_button(button) 0224 , m_brightness(brightness) 0225 { 0226 m_last = -1; 0227 } 0228 0229 void ButtonAnimation::start(int t) 0230 { 0231 m_last = t; 0232 } 0233 0234 bool ButtonAnimation::step(int t) 0235 { 0236 if (m_last == -1) { 0237 return true; 0238 } 0239 0240 int sign = (m_button->brightness() > m_brightness) ? -1 : 1; 0241 double delta = (t - m_last) * m_speed; 0242 // qCDebug(KNAVALBATTLE_LOG) << "button step t =" << t << "sign =" << sign << "delta =" << delta; 0243 m_last = t; 0244 if (fabs(m_button->brightness() - m_brightness) <= delta) { 0245 m_button->setBrightness(m_brightness); 0246 return true; 0247 } 0248 else { 0249 m_button->setBrightness(m_button->brightness() + sign * delta); 0250 return false; 0251 } 0252 } 0253 0254 void ButtonAnimation::abort() 0255 { 0256 m_last = -1; 0257 } 0258 0259 void ButtonAnimation::setBrightness(int value) 0260 { 0261 m_brightness = value; 0262 } 0263 0264 ButtonAnimation::~ButtonAnimation() 0265 { 0266 } 0267 0268 #include "moc_button.cpp"