Version: 2.1.0 (using KDE 3.2.1 RC1) (using KDE KDE 3.2.0) Installed from: Gentoo Packages Compiler: gcc version 3.2.3 20030422 (Gentoo Linux 1.4 3.2.3-r1, propolice) OS: Linux There are two problems that I have observed with a horizontal kicker containing the kweather applet. I believe that they are related. Neither of these problems occurs all of the time, but there is a series of steps that can be performed to reproduce them. The first problem appears when kweather is using "show icon and temerature" mode. The base of the temperature text is roughly aligned with the center of the weather icon. At the font size that is used, the top of the temperature text is cut off. To reproduce this problem: 1) Start kweather in a horizontal kicker 2) Go to the kweather configuration dialog. 3) Select "Show icon only". Press apply. 4) Select "Show icon, temperature, wind, and pressure information". Press apply. 5) Select "Show icon and temperature". Press apply. The problem should now be apparent. The second problem involves the temperature not being displayed when kweather is in "show icon, temperature, wind, and pressure information" mode. The icon, wind speed, and pressure are all shown, but the temperature is missing. To produce this problem. 1) Start kweather in a horizontal kicker 2) Go to the kweather configuration dialog. 3) Select "Show icon only". Press apply. 4) Select "Show icon and temperature". Press apply. 5) Select "Show icon, temperature, wind, and pressure information". Press apply. The problem should now be apparent. Note that the two procedures are almost identical, except that steps 4 and 5 are reversed. Either of "Show icon and temperature" or "Show icon, temperature, wind, and pressure information" will display the text correctly if kweather has just been in "show icon only" mode.
Created attachment 4284 [details] Image of kweather exhibiting the first problem.
Created attachment 4285 [details] Image of kweather exhibiting the first problem.
Created attachment 10586 [details] Shot showing problem (applet is on the left)
About a year later, I have the same problem on KDE 3.4 on (K)Ubuntu. The text of the weather applet is cut off unless I increase the size of my panel. I'm not sure if it is a problem with the icon being too big or the text being too big.
A few things to add... the applet is on the RIGHT, and my kindergarten teacher should shoot me.
SVN commit 617101 by mkoller: BUG: 81098 BUG: 73202 BUG: 134387 Fix layouting in all different display modes and kicker orientation modes Always use a sane font size and limit overall size of applet M +209 -68 dockwidget.cpp M +2 -2 weatherbutton.h --- branches/KDE/3.5/kdetoys/kweather/dockwidget.cpp #617100:617101 @@ -21,7 +21,7 @@ #include "weatherservice_stub.h" #include <qtooltip.h> -#include <qvbox.h> +#include <qlayout.h> #include <qlabel.h> #include <qtimer.h> @@ -32,11 +32,11 @@ dockwidget::dockwidget(const QString &location, QWidget *parent, const char *name) : QWidget(parent,name), m_locationCode( location ), m_orientation( Horizontal ) { + m_font = KGlobalSettings::generalFont(); initDock(); connect(m_button, SIGNAL( clicked() ), SIGNAL( buttonClicked() )); m_weatherService = new WeatherService_stub( "KWeatherService", "WeatherService" ); - m_font = KGlobalSettings::generalFont(); setBackgroundOrigin( AncestorOrigin ); } @@ -176,6 +176,18 @@ m_lblWind->setMargin(0); m_lblPres->setMargin(0); + QBoxLayout *mainLayout = new QBoxLayout(this, QBoxLayout::TopToBottom); + mainLayout->setSpacing(0); + mainLayout->setMargin(0); + mainLayout->addWidget(m_button, 0, Qt::AlignCenter); + + QBoxLayout *layout = new QBoxLayout(mainLayout, QBoxLayout::TopToBottom); + layout->setSpacing(0); + layout->setMargin(0); + layout->addWidget(m_lblTemp); + layout->addWidget(m_lblWind); + layout->addWidget(m_lblPres); + updateFont(); QTimer::singleShot( 0, this, SLOT( showWeather() ) ); @@ -187,86 +199,168 @@ kdDebug(12004) << "Changing to size " << size << endl; resize(size); - int w = size.width(); - int h = size.height(); - - if (m_orientation == Horizontal) + if ( m_orientation == Horizontal ) // Kicker in horizontal mode { - // in case we previously set this to hcenter previously - // and now change the layout - m_lblTemp->setAlignment(AlignVCenter); + int h = size.height(); - // Kicker in horizontal mode - if( m_mode == ShowAll) + if ( m_mode == ShowAll ) { - m_lblTemp->setGeometry(h+1, 0, w-h, h/3); - m_lblWind->setGeometry(h+1, h/3, w-h, h/3); - m_lblPres->setGeometry(h+1, 2*h/3, w-h, h/3); - m_button->setGeometry(0, 0, h, h); + if ( h <= 128 ) // left to right layout + { + static_cast<QBoxLayout*>(layout())->setDirection(QBoxLayout::LeftToRight); + m_lblTemp->setAlignment(Qt::AlignAuto | Qt::AlignVCenter); + m_lblWind->setAlignment(Qt::AlignAuto | Qt::AlignVCenter); + m_lblPres->setAlignment(Qt::AlignAuto | Qt::AlignVCenter); + } + else // top to bottom + { + static_cast<QBoxLayout*>(layout())->setDirection(QBoxLayout::TopToBottom); + QFontMetrics fm(m_font); + h = 128 - (3 * fm.height()); // 3 lines of text below the button + m_lblTemp->setAlignment(Qt::AlignCenter); + m_lblWind->setAlignment(Qt::AlignCenter); + m_lblPres->setAlignment(Qt::AlignCenter); + } + m_button->setFixedSize(h, h); } - else if ( m_mode == ShowTempOnly) + else if ( m_mode == ShowTempOnly ) { - if (h > 32) + if ( h <= 32 ) // left to right { - m_lblTemp->setAlignment(AlignVCenter | AlignHCenter); - m_lblTemp->setGeometry(1, h - h/5, w - 2, h/5); - m_button->setGeometry(0, 0, 4*h/5, 4*h/5); + static_cast<QBoxLayout*>(layout())->setDirection(QBoxLayout::LeftToRight); + m_lblTemp->setAlignment(Qt::AlignAuto | Qt::AlignVCenter); } - else + else // top to bottom { - m_lblTemp->setGeometry(h+1, 0, w-h, h); - m_button->setGeometry(0, 0, h, h ); + static_cast<QBoxLayout*>(layout())->setDirection(QBoxLayout::TopToBottom); + QFontMetrics fm(m_font); + h = QMIN(128, h) - fm.height(); + m_lblTemp->setAlignment(Qt::AlignCenter); } + m_button->setFixedSize(h, h); } else { - m_button->setGeometry(0, 0, h, h ); + h = QMIN(h, 128); + m_button->setFixedSize(h, h); } } - else + else // Kicker in vertical mode { - // Kicker in vertical mode - if( m_mode == ShowAll) + int w = size.width(); + int h = size.height(); + + if ( m_mode == ShowAll ) { - m_lblTemp->setGeometry(0, w, w, w/3); - m_lblWind->setGeometry(0, 4*w/3, w, w/3); - m_lblPres->setGeometry(0, 5*w/3, w, w/3); + if ( w <= 128 ) // top to bottom + { + static_cast<QBoxLayout*>(layout())->setDirection(QBoxLayout::TopToBottom); + m_lblTemp->setAlignment(Qt::AlignCenter); + m_lblWind->setAlignment(Qt::AlignCenter); + m_lblPres->setAlignment(Qt::AlignCenter); + + QFontMetrics fm(m_font); + h = h - (3 * fm.height()); // 3 lines of text below the button + h = QMIN(w, h); + } + else // left to right layout + { + static_cast<QBoxLayout*>(layout())->setDirection(QBoxLayout::LeftToRight); + m_lblTemp->setAlignment(Qt::AlignAuto | Qt::AlignVCenter); + m_lblWind->setAlignment(Qt::AlignAuto | Qt::AlignVCenter); + m_lblPres->setAlignment(Qt::AlignAuto | Qt::AlignVCenter); + } + m_button->setFixedSize(h, h); } - else if ( m_mode == ShowTempOnly) + else if ( m_mode == ShowTempOnly ) { - m_lblTemp->setGeometry(1, w, w, h-(w+1) ); + if ( w <= 128 ) // top to bottom + { + static_cast<QBoxLayout*>(layout())->setDirection(QBoxLayout::TopToBottom); + m_lblTemp->setAlignment(Qt::AlignCenter); + + h = w; + } + else // left to right layout + { + static_cast<QBoxLayout*>(layout())->setDirection(QBoxLayout::LeftToRight); + m_lblTemp->setAlignment(Qt::AlignAuto | Qt::AlignVCenter); + + h = static_cast<int>(w * 0.33); + } + m_button->setFixedSize(h, h); } - m_button->setGeometry(0, 0, w, w ); + else + { + w = QMIN(w, 128); + m_button->setFixedSize(w, w); + } } - updateFont(); } int dockwidget::widthForHeight(int h) { - int w=h; - QFontMetrics fm(m_font); + int w; + QFontInfo fi(KGlobalSettings::generalFont()); - if( m_mode == ShowAll) + if ( m_mode == ShowAll ) { - m_font.setPixelSize( h/3-2 ); - w = h + QMAX(fm.width(m_lblWind->text()), - fm.width(m_lblPres->text())) + 1; + if ( h <= 128 ) // left to right layout + { + int pixelSize = h/3 - 3; + pixelSize = QMIN(pixelSize, fi.pixelSize()); // don't make it too large + m_font.setPixelSize(pixelSize); + QFontMetrics fm(m_font); + w = h + QMAX(fm.width(m_lblWind->text()), fm.width(m_lblPres->text())) + 1; + } + else // top to bottom + { + if ( fi.pixelSize() * 3 <= (h/2) ) // half icon, half text + { + m_font = KGlobalSettings::generalFont(); + } + else + { + m_font.setPixelSize(h/2/3); + } + QFontMetrics fm(m_font); + // size of icon + h = 128 - (3 * fm.height()); // 3 lines of text below the button + w = QMAX(fm.width(m_lblWind->text()), fm.width(m_lblPres->text())) + 1; + w = QMAX(h, w); // at least width of square icon + } } - else if ( m_mode == ShowTempOnly) + else if ( m_mode == ShowTempOnly ) { - QFontInfo fi( KGlobalSettings::generalFont() ); - int pixelSize = QMIN( h, fi.pixelSize() ); - m_font.setPixelSize( pixelSize ); - - if (h > 32) + if ( h <= 32 ) // left to right layout { - w = 4*h/5; + int pixelSize = h - 3; + pixelSize = QMIN(pixelSize, fi.pixelSize()); // don't make it too large + m_font.setPixelSize(pixelSize); + QFontMetrics fm(m_font); + w = h + fm.width(m_lblTemp->text()) + 1; } - else + else // top to bottom { - w = h + fm.width(m_lblTemp->text()) + 1; + if ( fi.pixelSize() <= (h/2) ) // half icon, half text + { + m_font = KGlobalSettings::generalFont(); + } + else + { + m_font.setPixelSize(h/2); + } + QFontMetrics fm(m_font); + // size of icon + h = QMIN(128, h) - fm.height(); + w = fm.width(m_lblTemp->text()) + 1; + w = QMAX(h, w); // at least width of square icon } } + else + { + w = QMIN(128, h); // don't make it too large + } updateFont(); return w; @@ -275,33 +369,80 @@ int dockwidget::heightForWidth( int w ) { int h; - // Adjust the height of the font to compensate for width - int startSize = w; - int width = w + 1; if ( m_mode == ShowAll ) { - while( (width > w) && (startSize > 0)) - { - m_font.setPixelSize( --startSize ); - QFontMetrics fm(m_font); - width = QMAX(fm.width(m_lblWind->text()), - fm.width(m_lblPres->text())); - } - h = ( w * 2 ); + QFontMetrics fmg(KGlobalSettings::generalFont()); + int maxWidth = fmg.width("888 km/h NNWW"); // a good approximation + + if ( w <= 128 ) // top to bottom + { + if ( maxWidth <= w ) // enough space to use global font + { + m_font = KGlobalSettings::generalFont(); + } + else // we have to reduce the fontsize + { + m_font.setPixelSize(static_cast<int>(fmg.height() * double(w) / maxWidth)); + } + + QFontMetrics fm(m_font); + h = w + (3 * fm.height()); // 3 lines of text below the button + } + else + { + if ( w >= (maxWidth * 1.5) ) // half of text width shall be icon + { + m_font = KGlobalSettings::generalFont(); + } + else + { + m_font.setPixelSize(static_cast<int>(fmg.height() * (w*0.66) / maxWidth)); + } + + QFontMetrics fm(m_font); + h = 3 * fm.height(); // 3 lines of text + + } } else if ( m_mode == ShowTempOnly ) { - while( (width > w) && (startSize > 0)) - { - m_font.setPixelSize( --startSize ); - QFontMetrics fm(m_font); - width = fm.width(m_lblTemp->text()); - } - h = w + startSize + 2; + QFontMetrics fmg(KGlobalSettings::generalFont()); + int maxWidth = fmg.width("888.88 CC"); // a good approximation + + if ( w <= 128 ) // top to bottom + { + if ( maxWidth <= w ) // enough space to use global font + { + m_font = KGlobalSettings::generalFont(); + } + else // we have to reduce the fontsize + { + m_font.setPixelSize(static_cast<int>(fmg.height() * double(w) / maxWidth)); + } + + QFontMetrics fm(m_font); + h = w + fm.height(); // text below the button + } + else + { + if ( w >= (maxWidth * 1.5) ) // half of text width shall be icon + { + m_font = KGlobalSettings::generalFont(); + } + else + { + m_font.setPixelSize(static_cast<int>(fmg.height() * (w*0.66) / maxWidth)); + } + + QFontMetrics fm(m_font); + h = QMAX(fm.height(), static_cast<int>(w * 0.33)); + } } else - h = w; + { + h = QMIN(128, w); // don't make it too large + } updateFont(); return h; --- branches/KDE/3.5/kdetoys/kweather/weatherbutton.h #617100:617101 @@ -34,8 +34,8 @@ protected: void drawButton( QPainter *p ); void drawButtonLabel( QPainter *p ); - QSize margin() const { return QSize( 5, 5 ); } - QSize pixmapSize() const { return size() - margin(); } + QSize margin() const { return QSize( 3, 3 ); } + QSize pixmapSize() const { return size() - margin()*2; } QPoint pixmapOrigin() const; void generateIcons();