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"