Go back to Richel Bilderbeek's homepage.

Go back to Richel Bilderbeek's C++ page.

 

 

 

 

 

(C++) QtLed

 

Technical facts

 

 

 

 

 

 

./CppQtLed/CppQtLed.pri

 

INCLUDEPATH += \
    ../../Classes/CppQtLed

SOURCES += \
    ../../Classes/CppQtLed/qtled.cpp \
    ../../Classes/CppQtLed/qtleddialog.cpp

HEADERS  += \
    ../../Classes/CppQtLed/qtled.h \
    ../../Classes/CppQtLed/qtleddialog.h

OTHER_FILES += \
    ../../Classes/CppQtLed/Licence.txt

FORMS += \
    ../../Classes/CppQtLed/qtleddialog.ui

 

 

 

 

 

./CppQtLed/qtled.h

 

//---------------------------------------------------------------------------
/*
QtLed, Qt widget for displaying the Led class
Copyright (C) 2011-2015 Richel Bilderbeek

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 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
//---------------------------------------------------------------------------
//From http://www.richelbilderbeek.nl/CppQtLed.htm
//---------------------------------------------------------------------------
#ifndef QTLED_H
#define QTLED_H

#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Weffc++"
#pragma GCC diagnostic ignored "-Wunused-local-typedefs"
#pragma GCC diagnostic ignored "-Wunused-but-set-parameter"
#include <boost/shared_ptr.hpp>
#include <QWidget>
#pragma GCC diagnostic pop

namespace ribi {

struct Led;

///QtLed is the Qt display widhet of an LED
class QtLed : public QWidget
{
  Q_OBJECT
public:
  //Creates an Led
  explicit QtLed(
    const double intensity    = 0.0,
    const unsigned char red   = 255,
    const unsigned char green =   0,
    const unsigned char blue  =   0,
    QWidget *parent = 0
  );

  ///Draw a Led from a Led
  static void DrawLed(
    QPainter& painter,
    const int left, const int top,
    const int width, const int height,
    const Led& led
  ) noexcept;


  boost::shared_ptr<const Led> GetLed() const noexcept { return m_led; }
  boost::shared_ptr<      Led> GetLed()       noexcept { return m_led; }

  void SetLed(
    const boost::shared_ptr<Led>& led
  ) noexcept;

protected:
  void paintEvent(QPaintEvent *);
  //void resizeEvent(QResizeEvent *);

private:
  boost::shared_ptr<Led> m_led;

  ///OnResize is called when the geometry of the LedWidget is changed
  //void OnResize();
  void OnColorChanged(Led * const) noexcept;
  void OnIntensityChanged(Led * const) noexcept;

public:
  static std::string GetVersion() noexcept;
  static std::vector<std::string> GetVersionHistory() noexcept;

};

} //~namespace ribi

#endif // QTLED_H

 

 

 

 

 

./CppQtLed/qtled.cpp

 

//---------------------------------------------------------------------------
/*
QtLed, Qt widget for displaying the Led class
Copyright (C) 2011-2015 Richel Bilderbeek

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 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
//---------------------------------------------------------------------------
//From http://www.richelbilderbeek.nl/CppQtLed.htm
//---------------------------------------------------------------------------
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Weffc++"
#pragma GCC diagnostic ignored "-Wunused-local-typedefs"
#pragma GCC diagnostic ignored "-Wunused-but-set-parameter"
#include "qtled.h"

#include <cassert>
#include <sstream>
#include <boost/lambda/lambda.hpp>
#include <boost/numeric/conversion/cast.hpp>

#include <QPainter>

#include "led.h"
#include "trace.h"

#pragma GCC diagnostic pop

ribi::QtLed::QtLed(
  const double intensity,
  const unsigned char red,
  const unsigned char green,
  const unsigned char blue,
  QWidget *parent
)
  : QWidget(parent),
    m_led{}
{
  const auto led = boost::make_shared<Led>(intensity,red,green,blue);
  this->SetLed(led);
  assert(m_led);
}

///Draw a Led from a Led
void ribi::QtLed::DrawLed(
  QPainter& painter,
  const int left, const int top,
  const int width, const int height,
  const Led& led
) noexcept
{
  assert(width  > 0);
  assert(height > 0);
  const int red   = boost::numeric_cast<int>(led.GetRed());
  const int green = boost::numeric_cast<int>(led.GetGreen());
  const int blue  = boost::numeric_cast<int>(led.GetBlue());
  const double intensity = led.GetIntensity();
  //Fraction red/green/blue
  const double fR = static_cast<double>(red  ) / 255.0;
  const double fG = static_cast<double>(green) / 255.0;
  const double fB = static_cast<double>(blue ) / 255.0;

  {
    //Draw circle and major surface
    const double maxBrightness = 0.66 * 255.0;
    const double minBrightness = 0.25 * maxBrightness;
    const int r = static_cast<int>(
      minBrightness + (fR * intensity * (maxBrightness - minBrightness) ) );
    const int g = static_cast<int>(
      minBrightness + (fG * intensity * (maxBrightness - minBrightness) ) );
    const int b = static_cast<int>(
      minBrightness + (fB * intensity * (maxBrightness - minBrightness) ) );
    assert( r >= 0 ); assert( r < 256);
    assert( g >= 0 ); assert( g < 256);
    assert( b >= 0 ); assert( b < 256);
    const int pen_width = 1 + (std::min(width,height) / 25);
    assert(pen_width > 0);
    {
      QPen pen = painter.pen();
      pen.setWidth(pen_width);
      pen.setColor(QColor(0,0,0));
      painter.setPen(pen);
    }
    painter.setBrush(QBrush(QColor(r,g,b)));
    painter.drawEllipse(
      left + pen_width,
      top + pen_width,
      width  - (4 * pen_width),
      height - (4 * pen_width)
    );
  }
  {
    //Draw topleft smaller lighter surface
    const double maxBrightness = 1.00 * 255.0;
    const double minBrightness = 0.25 * maxBrightness;
    const int r = static_cast<int>(
      minBrightness + (fR * intensity * (maxBrightness - minBrightness) ) );
    const int g = static_cast<int>(
      minBrightness + (fG * intensity * (maxBrightness - minBrightness) ) );
    const int b = static_cast<int>(
      minBrightness + (fB * intensity * (maxBrightness - minBrightness) ) );
    assert( r >= 0 ); assert( r < 256);
    assert( g >= 0 ); assert( g < 256);
    assert( b >= 0 ); assert( b < 256);
    const int x = left + (width  / 2) - (0.707 * static_cast<double>(width ) * 0.5);
    const int y = top  + (height / 2) - (0.707 * static_cast<double>(height) * 0.5);
    const int w = (0.707 * static_cast<double>(width ) * 0.5);
    const int h = (0.707 * static_cast<double>(height) * 0.5);
    {
      QPen pen = painter.pen();
      pen.setWidth(1);
      pen.setColor(QColor(r,g,b));
      painter.setPen(pen);
    }
    painter.setBrush(QBrush(QColor(r,g,b)));
    painter.drawEllipse(x,y,w,h);
  }
  {
    //Draw bottomright smaller darker surface
    const double maxBrightness = 0.33 * 255.0;
    const double minBrightness = 0.25 * maxBrightness;
    const int r = static_cast<int>(
      minBrightness + (fR * intensity * (maxBrightness - minBrightness) ) );
    const int g = static_cast<int>(
      minBrightness + (fG * intensity * (maxBrightness - minBrightness) ) );
    const int b = static_cast<int>(
      minBrightness + (fB * intensity * (maxBrightness - minBrightness) ) );
    assert( r >= 0 ); assert( r < 256);
    assert( g >= 0 ); assert( g < 256);
    assert( b >= 0 ); assert( b < 256);
    const int x = left + (width  / 2) - 1;
    const int y = top  + (height / 2) - 1;
    const int w = (0.707 * static_cast<double>(width ) * 0.5);
    const int h = (0.707 * static_cast<double>(height) * 0.5);

    {
      QPen pen = painter.pen();
      pen.setWidth(1);
      pen.setColor(QColor(r,g,b));
      painter.setPen(pen);
    }
    painter.setBrush(QBrush(QColor(r,g,b)));
    painter.drawEllipse(x,y,w,h);
  }
}

std::string ribi::QtLed::GetVersion() noexcept
{
  return "1.0";
}

std::vector<std::string> ribi::QtLed::GetVersionHistory() noexcept
{
  return {
    "2014-06-20: Version 1.0: initial version"
  };
}

void ribi::QtLed::OnColorChanged(Led * const) noexcept
{
  this->update();
}

void ribi::QtLed::OnIntensityChanged(Led * const) noexcept
{
  this->update();
}

void ribi::QtLed::paintEvent(QPaintEvent *)
{
  QPainter p(this);
  DrawLed(
    p,
    this->rect().left(),
    this->rect().top(),
    this->rect().width(),
    this->rect().height(),
    //this->geometry().left(),
    //this->geometry().top(),
    //this->geometry().width(),
    //this->geometry().height(),
    *m_led
  );
}

void ribi::QtLed::SetLed(const boost::shared_ptr<Led>& led) noexcept
{
  const bool verbose{false};

  assert(led);
  if (m_led == led)
  {
    return;
  }
  if (verbose)
  {
    std::stringstream s;
    s << "Setting led '" << (*led) << "'\n";
  }

  const auto blue_after = led->GetBlue();
  const auto green_after = led->GetGreen();
  const auto intensity_after = led->GetIntensity();
  const auto red_after = led->GetRed();


  bool blue_changed  = true;
  bool green_changed  = true;
  bool intensity_changed = true;
  bool red_changed = true;

  if (m_led)
  {
    const auto blue_before = m_led->GetBlue();
    const auto green_before = m_led->GetGreen();
    const auto intensity_before = m_led->GetIntensity();
    const auto red_before = m_led->GetRed();

    blue_changed  = blue_before != blue_after;
    green_changed  = green_before != green_after;
    intensity_changed = intensity_before != intensity_after;
    red_changed = red_before != red_after;


    if (verbose)
    {
      if (blue_changed)
      {
        std::stringstream s;
        s
          << "Blue will change from "
          << blue_before
          << " to "
          << blue_after
          << '\n'
        ;
        TRACE(s.str());
      }
      if (green_changed)
      {
        std::stringstream s;
        s << "Green will change from " << green_before
          << " to " << green_after << '\n';
        TRACE(s.str());
      }
      if (intensity_changed)
      {
        std::stringstream s;
        s << "Intensity will change from '" << intensity_before
          << "' to '" << intensity_after << "'\n";
        TRACE(s.str());
      }
      if (red_changed)
      {
        std::stringstream s;
        s << "Red will change from " << red_before
          << " to " << red_after << '\n';
        TRACE(s.str());
      }
    }

    //Disconnect m_led
    m_led->m_signal_color_changed.disconnect(
      boost::bind(&ribi::QtLed::OnColorChanged,this,boost::lambda::_1)
    );
    m_led->m_signal_intensity_changed.disconnect(
      boost::bind(&ribi::QtLed::OnIntensityChanged,this,boost::lambda::_1)
    );
  }

  //Replace m_led by the new one
  m_led = led;

  assert(m_led->GetBlue() == blue_after);
  assert(m_led->GetGreen() == green_after);
  assert(m_led->GetIntensity() == intensity_after);
  assert(m_led->GetRed() == red_after);

  m_led->m_signal_color_changed.connect(
    boost::bind(&ribi::QtLed::OnColorChanged,this,boost::lambda::_1)
  );
  m_led->m_signal_intensity_changed.connect(
    boost::bind(&ribi::QtLed::OnIntensityChanged,this,boost::lambda::_1)
  );

  //Emit everything that has changed
  if (blue_changed || green_changed || red_changed)
  {
    m_led->m_signal_color_changed(m_led.get());
  }
  if (intensity_changed)
  {
    m_led->m_signal_intensity_changed(m_led.get());
  }

  assert( led ==  m_led);
  assert(*led == *m_led);
}

 

 

 

 

 

./CppQtLed/qtleddialog.h

 

//---------------------------------------------------------------------------
/*
QtLedWidget, Qt widget for displaying the Led class
Copyright (C) 2011-2015 Richel Bilderbeek

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 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
//---------------------------------------------------------------------------
//From http://www.richelbilderbeek.nl/CppQtLedWidget.htm
//---------------------------------------------------------------------------
#ifndef QTLEDDIALOG_H
#define QTLEDDIALOG_H

#include <string>
#include <vector>

#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Weffc++"
#pragma GCC diagnostic ignored "-Wunused-local-typedefs"
#pragma GCC diagnostic ignored "-Wunused-but-set-parameter"
#include <boost/shared_ptr.hpp>
#include "qthideandshowdialog.h"
#pragma GCC diagnostic pop

namespace Ui {
  class QtLedDialog;
}

namespace ribi {

struct Led;

///Displays an LED as a dialog
class QtLedDialog : public ::ribi::QtHideAndShowDialog
{
  Q_OBJECT

public:
  explicit QtLedDialog(QWidget *parent = 0);
  QtLedDialog(const QtLedDialog&) = delete;
  QtLedDialog& operator=(const QtLedDialog&) = delete;
  ~QtLedDialog() noexcept;

  void SetLed(const boost::shared_ptr<Led>& led) noexcept;
  boost::shared_ptr<Led> GetLed() const noexcept { return m_led; }


private slots:
  void on_box_blue_valueChanged(int arg1);
  void on_box_green_valueChanged(int arg1);
  void on_box_intensity_valueChanged(double arg1);
  void on_box_red_valueChanged(int arg1);

private:
  Ui::QtLedDialog *ui;

  ///The LED to work on
  boost::shared_ptr<Led> m_led;

  void OnColorChanged(Led * const led) noexcept;
  void OnIntensityChanged(Led * const led) noexcept;
};

} //~namespace ribi

#endif // QTLEDDIALOG_H

 

 

 

 

 

./CppQtLed/qtleddialog.cpp

 

//---------------------------------------------------------------------------
/*
QtLedWidget, Qt led for displaying the Led class
Copyright (C) 2011-2015 Richel Bilderbeek

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 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
//---------------------------------------------------------------------------
//From http://www.richelbilderbeek.nl/CppQtLedWidget.htm
//---------------------------------------------------------------------------
#include "qtleddialog.h"

#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Weffc++"
#pragma GCC diagnostic ignored "-Wunused-local-typedefs"
#pragma GCC diagnostic ignored "-Wunused-but-set-parameter"
#include <cassert>
#include <sstream>

#include <boost/lambda/bind.hpp>
#include <boost/lambda/lambda.hpp>

#include "led.h"
#include "trace.h"
#include "ui_qtleddialog.h"
#pragma GCC diagnostic pop

ribi::QtLedDialog::QtLedDialog(QWidget *parent)
  : QtHideAndShowDialog(parent),
    ui(new Ui::QtLedDialog),
    m_led{}
{
  ui->setupUi(this);
}

ribi::QtLedDialog::~QtLedDialog() noexcept
{
  delete ui;
}

void ribi::QtLedDialog::on_box_intensity_valueChanged(double arg1)
{
  m_led->SetIntensity(arg1);
}

void ribi::QtLedDialog::on_box_blue_valueChanged(int arg1)
{
  m_led->SetBlue(arg1);
}

void ribi::QtLedDialog::on_box_green_valueChanged(int arg1)
{
  m_led->SetGreen(arg1);
}

void ribi::QtLedDialog::on_box_red_valueChanged(int arg1)
{
  m_led->SetRed(arg1);
}

void ribi::QtLedDialog::OnColorChanged(Led * const led) noexcept
{
  assert(led);
  ui->box_red->setValue(led->GetRed());
  ui->box_green->setValue(led->GetGreen());
  ui->box_blue->setValue(led->GetBlue());
}

void ribi::QtLedDialog::OnIntensityChanged(Led * const led) noexcept
{
  assert(led);
  ui->box_intensity->setValue(led->GetIntensity());
}

void ribi::QtLedDialog::SetLed(const boost::shared_ptr<Led>& led) noexcept
{
  const bool verbose{false};

  assert(led);
  if (m_led == led)
  {
    return;
  }
  if (verbose)
  {
    std::stringstream s;
    s << "Setting led '" << (*led) << "'\n";
  }

  const auto blue_after      = led->GetBlue();
  const auto green_after     = led->GetGreen();
  const auto intensity_after = led->GetIntensity();
  const auto red_after       = led->GetRed();


  bool blue_changed  = true;
  bool green_changed  = true;
  bool intensity_changed = true;
  bool red_changed = true;

  if (m_led)
  {
    const auto blue_before  = m_led->GetBlue();
    const auto green_before  = m_led->GetGreen();
    const auto intensity_before = m_led->GetIntensity();
    const auto red_before = m_led->GetRed();

    blue_changed  = blue_before != blue_after;
    green_changed  = green_before != green_after;
    intensity_changed = intensity_before != intensity_after;
    red_changed = red_before != red_after;

    if (verbose)
    {
      if (blue_changed)
      {
        std::stringstream s;
        s
          << "Blue will change from "
          << blue_before
          << " to "
          << blue_after
          << '\n'
        ;
        TRACE(s.str());
      }
      if (green_changed)
      {
        std::stringstream s;
        s << "Green will change from " << green_before
          << " to " << green_after << '\n';
        TRACE(s.str());
      }
      if (intensity_changed)
      {
        std::stringstream s;
        s << "Intensity will change from " << intensity_before
          << " to " << intensity_after << '\n';
        TRACE(s.str());
      }
      if (red_changed)
      {
        std::stringstream s;
        s << "Red will change from " << red_before
          << " to " << red_after << '\n';
        TRACE(s.str());
      }
    }

    //Disconnect m_led
    m_led->m_signal_color_changed.disconnect(
      boost::bind(&ribi::QtLedDialog::OnColorChanged,this,boost::lambda::_1)
    );
    m_led->m_signal_intensity_changed.disconnect(
      boost::bind(&ribi::QtLedDialog::OnIntensityChanged,this,boost::lambda::_1)
    );
  }

  //Replace m_led by the new one
  m_led = led;

  assert(m_led->GetBlue() == blue_after );
  assert(m_led->GetGreen()  == green_after );
  assert(m_led->GetIntensity() == intensity_after);
  assert(m_led->GetRed() == red_after);

  m_led->m_signal_color_changed.connect(
    boost::bind(&ribi::QtLedDialog::OnColorChanged,this,boost::lambda::_1)
  );
  m_led->m_signal_intensity_changed.connect(
    boost::bind(&ribi::QtLedDialog::OnIntensityChanged,this,boost::lambda::_1)
  );

  //Emit everything that has changed
  if (blue_changed || green_changed || red_changed)
  {
    m_led->m_signal_color_changed(m_led.get());
  }
  if (intensity_changed)
  {
    m_led->m_signal_intensity_changed(m_led.get());
  }
  assert( led ==  m_led);
  assert(*led == *m_led);
}

 

 

 

 

 

Go back to Richel Bilderbeek's C++ page.

Go back to Richel Bilderbeek's homepage.

 

Valid XHTML 1.0 Strict

This page has been created by the tool CodeToHtml