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