File indexing completed on 2024-04-28 07:52:38

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"