/*************************************************************************** copyright : (C) 2003-2005 by Robby Stephenson email : robby@periapsis.org ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of version 2 of the GNU General Public License as * * published by the Free Software Foundation; * * * ***************************************************************************/ #include "ratingwidget.h" #include // needed for KMAX #include #include #include #include namespace { static const int RATING_WIDGET_MAX_STAR_SIZE = 24; } const TQPixmap& RatingWidget::pixmap(const TQString& value_) { static TQIntDict pixmaps; if(pixmaps.isEmpty()) { pixmaps.insert(-1, new TQPixmap()); } bool ok; int n = value_.toInt(&ok); if(!ok || n < 1 || n > 10) { return *pixmaps[-1]; } if(pixmaps[n]) { return *pixmaps[n]; } TQString picName = TQString::fromLatin1("stars%1").arg(n); TQPixmap* pix = new TQPixmap(UserIcon(picName)); pixmaps.insert(n, pix); return *pix; } RatingWidget::RatingWidget(int stars, TQWidget* parent_, const char* name_/*=0*/) : TQHBox(parent_, name_), m_currIndex(-1), m_min(0), m_max(stars*2) { m_pixOn = UserIcon(TQString::fromLatin1("star_on")); m_pixOff = UserIcon(TQString::fromLatin1("star_off")); m_pixHalf = UserIcon(TQString::fromLatin1("star_half")); setSpacing(0); // find maximum width and height int w = KMAX(RATING_WIDGET_MAX_STAR_SIZE, KMAX(m_pixOn.width(), m_pixOff.width())); int h = KMAX(RATING_WIDGET_MAX_STAR_SIZE, KMAX(m_pixOn.height(), m_pixOff.height())); for(int i = 0; i < stars; ++i) { TQLabel* l = new TQLabel(this); l->setFixedSize(w, h); m_widgets.append(l); } init(); TQBoxLayout* l = dynamic_cast(layout()); if(l) { l->addStretch(1); } } void RatingWidget::init() { m_total = KMIN(m_max/2, static_cast(m_widgets.count())); uint i = 0; for( ; static_cast(i) < m_total; ++i) { m_widgets.at(i)->setPixmap(m_pixOff); } for( ; i < m_widgets.count(); ++i) { m_widgets.at(i)->setPixmap(TQPixmap()); } update(); } void RatingWidget::update() { int i = 0; for( ; i <= (m_currIndex-1)/2; ++i) { m_widgets.at(i)->setPixmap(m_pixOn); } for( ; i < m_total; ++i) { m_widgets.at(i)->setPixmap(m_pixOff); } if ( m_currIndex % 2 == 0 ) { m_widgets.at(m_currIndex/2)->setPixmap(m_pixHalf); } TQHBox::update(); } void RatingWidget::mousePressEvent(TQMouseEvent* event_) { // only react to left button if(event_->button() != TQt::LeftButton) { return; } int idx; TQWidget* child = childAt(event_->pos()); bool left = false; if(child) { TQRect child_geom_left_half = child->geometry(); child_geom_left_half.setWidth(child_geom_left_half.width()/2); if ( child_geom_left_half.contains(event_->pos()) ) left = true; idx = m_widgets.findRef(static_cast(child)); // if the widget is clicked beyond the maximum value, clear it // remember total and min are values, but index is zero-based! if(idx > m_total-1) { idx = -1; } else if(idx < m_min-1) { idx = m_min-1; // limit to minimum, remember index is zero-based } } else { idx = -1; } int oldCurrent = m_currIndex; m_currIndex = idx*2+1; if ( left ) m_currIndex--; if ( oldCurrent != m_currIndex ) { update(); emit modified(); } } void RatingWidget::clear() { m_currIndex = -1; update(); } TQString RatingWidget::text() const { // index is index of the list, which is zero-based. Add 1! return m_currIndex == -1 ? TQString::null : TQString::number(double(m_currIndex+1)/2); } void RatingWidget::setText(const TQString& text_) { bool ok; // text is value, subtract one to get index m_currIndex =text_.toInt(&ok)-1; if(ok) { if(m_currIndex > m_total-1) { m_currIndex = -1; } else if(m_currIndex < m_min-1) { m_currIndex = m_min-1; // limit to minimum, remember index is zero-based } } else { m_currIndex = -1; } update(); } #include "ratingwidget.moc"