You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
tderadio/tderadio3/plugins/gui-standard-display/radioview_frequencyradio.cpp

444 lines
14 KiB

/***************************************************************************
tderadiodisplay.cpp - description
-------------------
begin : Mit Jan 29 2003
copyright : (C) 2003 by Martin Witte
email : witte@kawo1.rwth-aachen.de
***************************************************************************/
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#include "../../src/include/utils.h"
#include <tqpainter.h>
#include <tqimage.h>
#include <tqpixmap.h>
#include <kimageeffect.h> // fading, blending, ...
#include <kpixmapio.h> // fast conversion between TQPixmap/TQImage
#include "radioview_frequencyradio.h"
#include "displaycfg.h"
RadioViewFrequencyRadio::RadioViewFrequencyRadio(TQWidget *parent, const TQString &name )
: RadioViewElement(parent, name, clsRadioDisplay),
m_power(false),
m_valid(false),
m_frequency(0),
m_quality(0.0),
m_stereo(false)
{
setFrameStyle(Box | Sunken);
setLineWidth(1);
setMidLineWidth(1);
// set some sensless default colors
// real values are read in restoreState
setDisplayColors(TQColor(20, 244, 20),
TQColor(10, 117, 10).light(75),
TQColor(10, 117, 10));
setDisplayFont(TQFont("Helvetica"));
}
RadioViewFrequencyRadio::~RadioViewFrequencyRadio(){
}
float RadioViewFrequencyRadio::getUsability (Interface *i) const
{
if (dynamic_cast<IFrequencyRadio*>(i))
return 1.0;
else
return 0.0;
}
void RadioViewFrequencyRadio::saveState (TDEConfig *config) const
{
config->writeEntry("frequency-view-colorActiveText", m_colorActiveText);
config->writeEntry("frequency-view-colorInactiveText", m_colorInactiveText);
config->writeEntry("frequency-view-colorButton", m_colorButton);
config->writeEntry("frequency-view-font", m_font);
}
void RadioViewFrequencyRadio::restoreState (TDEConfig *config)
{
TQColor defaultActive (20, 244, 20),
defaultInactive(TQColor(10, 117, 10).light(75)),
defaultButton (10, 117, 10);
TQFont defaultFont ("Helvetica");
TQColor a, b, c;
TQFont f;
a = config->readColorEntry ("frequency-view-colorActiveText",
&defaultActive);
b = config->readColorEntry ("frequency-view-colorInactiveText",
&defaultInactive);
c = config->readColorEntry ("frequency-view-colorButton",
&defaultButton);
f = config->readFontEntry ("frequency-view-font",
&defaultFont);
setDisplayColors(a, b, c);
setDisplayFont(f);
}
ConfigPageInfo RadioViewFrequencyRadio::createConfigurationPage()
{
DisplayConfiguration *a = new DisplayConfiguration(NULL);
connectI(a);
return ConfigPageInfo (a,
i18n("Frequency Display"),
i18n("Frequency Display"),
TQString()
);
}
// Interface
bool RadioViewFrequencyRadio::connectI(Interface *i)
{
bool o = IDisplayCfg::connectI(i);
bool c = ISoundStreamClient::connectI(i);
if (dynamic_cast<IFrequencyRadio *>(i)) {
bool a = IRadioDeviceClient::connectI(i);
bool b = IFrequencyRadioClient::connectI(i);
return o || a || b || c;
} else {
return o || c;
}
}
bool RadioViewFrequencyRadio::disconnectI(Interface *i)
{
// no check for IFrequencyRadio, it's just a disconnect
bool a = IRadioDeviceClient::disconnectI(i);
bool b = IFrequencyRadioClient::disconnectI(i);
bool c = ISoundStreamClient::disconnectI(i);
bool o = IDisplayCfg::disconnectI(i);
return a || b || c || o;
}
void RadioViewFrequencyRadio::noticeConnectedI (ISoundStreamServer *s, bool pointer_valid)
{
ISoundStreamClient::noticeConnectedI(s, pointer_valid);
if (s && pointer_valid) {
s->register4_notifySignalQualityChanged(this);
s->register4_notifyStereoChanged(this);
}
}
// IDisplayCfg
bool RadioViewFrequencyRadio::setDisplayColors(const TQColor &activeText,
const TQColor &inactiveText,
const TQColor &button)
{
bool change = (activeText != m_colorActiveText || inactiveText != m_colorInactiveText || button != m_colorButton);
m_colorActiveText = activeText;
m_colorInactiveText = inactiveText;
m_colorButton = button;
TQPalette pl = palette();
TQColorGroup cg = pl.inactive();
TQBrush fg = cg.brush(TQColorGroup::Foreground),
btn = cg.brush(TQColorGroup::Button),
lgt = cg.brush(TQColorGroup::Light),
drk = cg.brush(TQColorGroup::Dark),
mid = cg.brush(TQColorGroup::Mid),
txt = cg.brush(TQColorGroup::Text),
btx = cg.brush(TQColorGroup::BrightText),
bas = cg.brush(TQColorGroup::Base),
bg = cg.brush(TQColorGroup::Background);
fg.setColor (m_colorActiveText);
btn.setColor(m_colorButton);
lgt.setColor(m_colorButton.light(180));
drk.setColor(m_colorButton.light( 50));
mid.setColor(m_colorInactiveText);
txt.setColor(m_colorActiveText);
btx.setColor(m_colorActiveText);
bas.setColor(m_colorButton);
bg.setColor (m_colorButton);
TQColorGroup ncg(fg, btn, lgt, drk, mid, txt, btx, bas, bg);
pl.setInactive(ncg);
pl.setActive(ncg);
setPalette(pl);
if (parentWidget() && parentWidget()->backgroundPixmap() ){
KPixmapIO io;
TQImage i = io.convertToImage(*parentWidget()->backgroundPixmap());
KImageEffect::fade(i, 0.5, colorGroup().color(TQColorGroup::Dark));
setPaletteBackgroundPixmap(io.convertToPixmap(i));
setBackgroundOrigin(WindowOrigin);
} else {
setBackgroundColor(colorGroup().color(TQColorGroup::Button));
}
if (change)
notifyDisplayColorsChanged(m_colorActiveText, m_colorInactiveText, m_colorButton);
return true;
}
bool RadioViewFrequencyRadio::setDisplayFont (const TQFont &f)
{
if (m_font != f) {
m_font = f;
notifyDisplayFontChanged(m_font);
RadioViewElement::setFont(f);
}
return true;
}
// IRadioDeviceClient
bool RadioViewFrequencyRadio::noticePowerChanged (bool on, const IRadioDevice */*sender*/)
{
m_power = on;
SoundStreamID ssid = queryCurrentSoundStreamID();
float q = 0.0;
bool s = false;
querySignalQuality(ssid, q);
noticeSignalQualityChanged(ssid, q);
queryIsStereo(ssid, s);
noticeStereoChanged(ssid, s);
repaint();
return true;
}
bool RadioViewFrequencyRadio::noticeStationChanged (const RadioStation &, const IRadioDevice */*sender*/)
{
return false; // we don't care
}
bool RadioViewFrequencyRadio::noticeDescriptionChanged (const TQString &, const IRadioDevice */*sender*/)
{
return false; // we don't care
}
// IRadioSoundClient
bool RadioViewFrequencyRadio::noticeSignalQualityChanged(SoundStreamID id, float q)
{
if (queryCurrentSoundStreamID() != id)
return false;
m_quality = q;
repaint ();
return true;
}
bool RadioViewFrequencyRadio::noticeStereoChanged(SoundStreamID id, bool s)
{
if (queryCurrentSoundStreamID() != id)
return false;
m_stereo = s;
repaint ();
return true;
}
// IFrequencyRadioClient
bool RadioViewFrequencyRadio::noticeFrequencyChanged(float f, const RadioStation *)
{
m_frequency = f;
repaint ();
return true;
}
bool RadioViewFrequencyRadio::noticeMinMaxFrequencyChanged(float /*min*/, float /*max*/)
{
return false; // we don't care
}
bool RadioViewFrequencyRadio::noticeDeviceMinMaxFrequencyChanged(float /*min*/, float /*max*/)
{
return false; // we don't care
}
bool RadioViewFrequencyRadio::noticeScanStepChanged(float /*s*/)
{
return false; // we don't care
}
void RadioViewFrequencyRadio::drawContents(TQPainter *paint)
{
if (!paint) return;
TQRect r = contentsRect();
int margin = TQMAX(4, TQMIN(r.width() / 50, r.height() / 50)),
tmp = TQMIN(r.height(), (r.width() - 2*margin) / 4),
xd_st = TQMIN((r.height() - margin * 2) / 3, tmp/3),
xw = TQMIN(tmp / 2, xd_st * 3 / 2),
penw = TQMAX(1, xw / 25),
xh_st = xd_st,
xx_st = r.x() + margin + xw + 2 * margin + penw/2,
xy_st = r.y() + margin + penw/2,
xx_am = xx_st,
xy_am = xy_st + xh_st + margin / 2,
xh_am = (r.bottom() - margin - xy_am + 1 - margin/2) / 2,
xx_fm = xx_am,
xy_fm = xy_am + xh_am + margin/2,
xh_fm = xh_am,
xh_sg = r.height() - margin * 2,
xx_sg = r.x() + margin,
xy_sg = r.y() + margin;
TQPen activePen (colorGroup().color(TQColorGroup::Text), penw);
TQPen inactivePen (colorGroup().color(TQColorGroup::Mid), penw);
TQBrush activeBrush = colorGroup().brush(TQColorGroup::Text);
TQBrush inactiveBrush = colorGroup().brush(TQColorGroup::Mid);
// draw stereo symbol
paint->setPen( (m_stereo && m_power) ? activePen : inactivePen);
paint->drawArc((int)xx_st, (int)xy_st,
(int)(xd_st - penw), (int)(xd_st - penw),
0, 360*16);
paint->drawArc((int)(xx_st + xd_st/2), (int)xy_st,
(int)(xd_st - penw), (int)(xd_st - penw),
0, 360*16);
// draw signal quality symbol
float cx = xx_sg,
cy = xy_sg,
cw = xw,
ch = xw;
float open_a = 30.0;
// outer circle
paint->setPen( (m_quality > 0.75 && m_power) ? activePen : inactivePen);
paint->drawArc((int)rint(cx), (int)rint(cy),
(int)rint(cw), (int)rint(ch),
(int)(-90+open_a)*16, (int)(360 - 2*open_a)*16
);
// mid circle
paint->setPen( (m_quality > 0.50 && m_power) ? activePen : inactivePen);
cx += (float)xw/5.0; cy += (float)xw/5.0;
cw -= (float)xw/2.5; ch -= (float)xw/2.5;
paint->drawArc((int)rint(cx), (int)rint(cy),
(int)rint(cw), (int)rint(ch),
(int)(-90+open_a)*16, (int)(360 - 2*open_a)*16
);
// inner circle
paint->setPen( (m_quality > 0.25 && m_power) ? activePen : inactivePen);
cx += (float)xw/5.0; cy += (float)xw/5.0;
cw -= (float)xw/2.5; ch -= (float)xw/2.5;
paint->drawArc((int)rint(cx), (int)rint(cy),
(int)rint(cw), (int)rint(ch),
(int)(-90+open_a)*16, (int)(360 - 2*open_a)*16
);
// triangle
TQPen tmppen = (m_quality > 0.1 && m_power) ? activePen : inactivePen;
tmppen.setWidth(1);
paint->setPen(tmppen);
paint->setBrush( (m_quality > 0.1 && m_power) ? activeBrush : inactiveBrush);
TQPointArray pts(3);
pts.setPoint(0, (int)(xx_sg + xw / 4), (int)(xy_sg + xh_sg - penw/2));
pts.setPoint(1, (int)(xx_sg + xw *3/4), (int)(xy_sg + xh_sg - penw/2));
pts.setPoint(2, (int)(xx_sg + xw / 2), (int)(xy_sg + xw/2 + penw));
paint->drawConvexPolygon(pts);
// AM/FM display
TQFont f = m_font;
paint->setPen ( (m_frequency <= 10 && m_power) ? activePen : inactivePen);
f.setPixelSize(xh_am);
paint->setFont(f);
paint->drawText(xx_am, xy_am + xh_am - 1, i18n("AM"));
int xw_am = TQFontMetrics(f).width(i18n("AM"));
paint->setPen ( (m_frequency > 10 && m_power) ? activePen : inactivePen);
f.setPixelSize(xh_fm);
paint->setFont(f);
paint->drawText(xx_fm, xy_fm + xh_fm - 1, i18n("FM"));
int xw_fm = TQFontMetrics(f).width(i18n("FM"));
int xx_f = TQMAX(xx_fm + xw_fm, TQMAX(xw_am + xx_am, TQMAX(xx_st + xw, xw + xx_sg))) + margin,
xy_f = r.y() + margin,
xw_f = r.right() - margin - xx_f + 1,
xh_f = r.bottom() - margin - xy_f + 1;
// Frequency Display
TQString s;
if (m_frequency < 10) {
s = i18n("%1 kHz").arg(TDEGlobal::locale()->formatNumber((int)(m_frequency * 1000), 0));
} else {
s = i18n("%1 MHz").arg(TDEGlobal::locale()->formatNumber(m_frequency, 2));
}
float pxs = xh_f;
paint->setPen ( m_power ? activePen : inactivePen);
f.setPixelSize((int)pxs);
int n = 30;
while (1) {
TQFontMetrics fm(f);
int sw = fm.boundingRect(xx_f, xy_f, xw_f, xh_f, TQt::AlignRight | TQt::AlignVCenter, s).width();
if (sw <= xw_f || --n <= 0) break;
float fact = (float)xw_f / (float)sw;
pxs = TQMIN(pxs - 1, pxs * fact);
f.setPixelSize(TQMAX(1,(int)pxs));
}
paint->setFont(f);
paint->drawText(xx_f, xy_f, xw_f, xh_f, TQt::AlignRight | TQt::AlignVCenter, s);
}
void RadioViewFrequencyRadio::reparent (TQWidget *prnt,
WFlags f,
const TQPoint &p,
bool showIt)
{
RadioViewElement::reparent(prnt, f, p, showIt);
setDisplayColors(m_colorActiveText, m_colorInactiveText, m_colorButton);
}
#include "radioview_frequencyradio.moc"