Go back to Richel Bilderbeek's homepage.

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

 

 

 

 

 

(C++) QtCanvas

 

Technical facts

 

 

 

 

 

 

./CppQtCanvas/CppQtCanvas.pri

 

INCLUDEPATH += \
    ../../Classes/CppQtCanvas

SOURCES += \
    ../../Classes/CppQtCanvas/qtcanvas.cpp \
    ../../Classes/CppQtCanvas/qtcanvasdialog.cpp

HEADERS  += \
    ../../Classes/CppQtCanvas/qtcanvas.h \
    ../../Classes/CppQtCanvas/qtcanvasdialog.h

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

 

 

 

 

 

./CppQtCanvas/qtcanvas.h

 

#ifndef RIBI_QTCANVAS_H
#define RIBI_QTCANVAS_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/scoped_ptr.hpp>
#include <boost/signals2.hpp>
#include "textcanvas.h"
#include "imagecanvas.h"
#include <QPlainTextEdit>
#include "canvas.h"
#pragma GCC diagnostic pop

namespace ribi {

struct Canvas;
struct ImageCanvas;
struct TextCanvas;

///A Canvas class that can be used on a QDialog
///If the Canvas is modified, this is displayed in the QtCanvas
class QtCanvas : public QWidget
{
  Q_OBJECT

public:

  QtCanvas();
  QtCanvas(const boost::shared_ptr<Canvas> canvas);
  QtCanvas(const QtCanvas&) = delete;
  QtCanvas& operator=(const QtCanvas&) = delete;
  virtual ~QtCanvas() noexcept;

  const Canvas * GetCanvas() const noexcept { return m_active_canvas; }
        Canvas * GetCanvas()       noexcept { return m_active_canvas; }

  void SetCanvas(const boost::shared_ptr<Canvas> canvas);
  void SetImageCanvas(const ImageCanvas& canvas);
  void SetTextCanvas(const TextCanvas& canvas);

  ///Emitted when the QtCanvas is destroyed
  boost::signals2::signal<void()> m_signal_on_destroy;

  virtual void keyPressEvent(QKeyEvent * e) override;
  virtual void keyReleaseEvent(QKeyEvent * e) override;
  virtual void paintEvent(QPaintEvent *) override;

private:
  friend void boost::checked_delete<>(QtCanvas* x);
  friend void boost::checked_delete<>(const QtCanvas* x);

  Canvas * m_active_canvas;
  boost::shared_ptr<QImage> m_image; //Used as buffer
  ImageCanvas m_image_canvas;
  boost::shared_ptr<Canvas> m_smart_canvas;
  TextCanvas m_text_canvas;

  void ShowCanvas(const Canvas * const);
};

} //~namespace ribi

#endif // RIBI_QTCANVAS_H

 

 

 

 

 

./CppQtCanvas/qtcanvas.cpp

 

#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 "qtcanvas.h"

#include <cassert>
#include <sstream>

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

#include <QPainter>

#include "canvas.h"
#include "dotmatrixtext.h"
#include "trace.h"
#pragma GCC diagnostic pop

ribi::QtCanvas::QtCanvas()
  : m_signal_on_destroy{},
    m_active_canvas{nullptr},
    m_image{},
    m_image_canvas{},
    m_smart_canvas{},
    m_text_canvas{}
{
}

ribi::QtCanvas::QtCanvas(const boost::shared_ptr<ribi::Canvas> canvas)
  : m_signal_on_destroy{},
    m_active_canvas{nullptr},
    m_image{},
    m_image_canvas{},
    m_smart_canvas{canvas},
    m_text_canvas{}
{
  assert(canvas);
  SetCanvas(canvas);
  assert(m_active_canvas);
}

ribi::QtCanvas::~QtCanvas() noexcept
{
  if (m_active_canvas)
  {
    m_active_canvas->m_signal_changed.disconnect(
      boost::bind(
        &ribi::QtCanvas::ShowCanvas,this,
        boost::lambda::_1
      )
    );
  }
  m_signal_on_destroy();
}

void ribi::QtCanvas::keyPressEvent(QKeyEvent* event)
{
  if (event->key() == Qt::Key_Escape)
  {
    m_signal_on_destroy();
    close();
    return;
  }
  QWidget::keyPressEvent(event);
}

void ribi::QtCanvas::keyReleaseEvent(QKeyEvent* event)
{
  QWidget::keyReleaseEvent(event);
}

void ribi::QtCanvas::paintEvent(QPaintEvent *)
{
  if (!m_active_canvas)
  {
    return;
  }
  std::vector<std::string> text;
  for (std::string line: m_active_canvas->ToStrings()) { text.push_back(line); }

  DotMatrixText t(text,1,DotMatrixText::ColorSystem::inverted);
  m_image = t.CreateImage();

  QPainter painter(this);
  painter.drawPixmap(rect(),QPixmap::fromImage(*m_image.get()));
  //painter.drawImage(rect(),*m_image.get());

}

void ribi::QtCanvas::SetCanvas(const boost::shared_ptr<Canvas> canvas)
{
  assert(canvas);

  if (canvas == m_smart_canvas) { return; }

  //Disconnect current Canvas
  if (m_active_canvas)
  {
    m_active_canvas->m_signal_changed.disconnect(
      boost::bind(
        &ribi::QtCanvas::ShowCanvas,this,
        boost::lambda::_1
      )
    );
  }

  //Use new Canvas
  m_smart_canvas = canvas;

  //Connect new Canvas
  m_active_canvas->m_signal_changed.connect(
    boost::bind(
      &ribi::QtCanvas::ShowCanvas,this,
      boost::lambda::_1)
    );

  //Set minimum size
  {
    std::vector<std::string> text;
    for (std::string line: m_active_canvas->ToStrings()) { text.push_back(line); }
    DotMatrixText t(text,1);
    setMinimumSize(
      t.GetMatrixHeight(),
      t.GetMatrixWidth()
    );
  }

  m_active_canvas = m_smart_canvas.get();
  ShowCanvas(m_active_canvas);
}

void ribi::QtCanvas::SetImageCanvas(const ImageCanvas& canvas)
{
  if (canvas == m_image_canvas) { return; }

  //Disconnect current Canvas
  if (m_active_canvas)
  {
    m_active_canvas->m_signal_changed.disconnect(
      boost::bind(
        &ribi::QtCanvas::ShowCanvas,this,
        boost::lambda::_1
      )
    );
  }

  //Use new Canvas
  m_image_canvas = canvas;
  m_active_canvas = &m_image_canvas;

  //Connect new Canvas
  m_active_canvas->m_signal_changed.connect(
    boost::bind(
      &ribi::QtCanvas::ShowCanvas,this,
      boost::lambda::_1
    )
  );

  //Set minimum size
  {
    std::vector<std::string> text;
    for (std::string line: m_active_canvas->ToStrings()) { text.push_back(line); }
    DotMatrixText t(text,1);
    setMinimumSize(
      t.GetMatrixHeight(),
      t.GetMatrixWidth()
    );
  }

  m_active_canvas = m_smart_canvas.get();
  ShowCanvas(m_active_canvas);
}

void ribi::QtCanvas::SetTextCanvas(const TextCanvas& canvas)
{
  if (canvas == m_text_canvas) { return; }

  //Disconnect current Canvas
  if (m_active_canvas)
  {
    m_active_canvas->m_signal_changed.disconnect(
      boost::bind(
        &ribi::QtCanvas::ShowCanvas,this,
        boost::lambda::_1
      )
    );
  }

  //Use new Canvas
  m_text_canvas = canvas;
  m_active_canvas = &m_text_canvas;

  //Connect new Canvas
  m_active_canvas->m_signal_changed.connect(
    boost::bind(
      &ribi::QtCanvas::ShowCanvas,this,
      boost::lambda::_1
    )
  );

  //Set minimum size
  {
    std::vector<std::string> text;
    for (std::string line: m_active_canvas->ToStrings()) { text.push_back(line); }
    DotMatrixText t(text,1);
    setMinimumSize(
      t.GetMatrixHeight(),
      t.GetMatrixWidth()
    );
  }

  m_active_canvas = m_smart_canvas.get();
  ShowCanvas(m_active_canvas);
}

void ribi::QtCanvas::ShowCanvas(const Canvas * const)
{
  repaint();
}

 

 

 

 

 

./CppQtCanvas/qtcanvasdialog.h

 

#ifndef RIBI_QTCANVASDIALOG_H
#define RIBI_QTCANVASDIALOG_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/checked_delete.hpp>
#include <boost/make_shared.hpp>
#include <boost/scoped_ptr.hpp>
#include <boost/shared_ptr.hpp>

#include "qthideandshowdialog.h"
#pragma GCC diagnostic pop


namespace ribi {

struct QtCanvas;

///QtCanvasDialog makes QtCanvas displayable as a modal dialog
class QtCanvasDialog : public QtHideAndShowDialog
{
  Q_OBJECT

public:
  ///qtcanvas will be deleted when this object goes out of scope!
  QtCanvasDialog(QtCanvas * const qtcanvas);
  QtCanvasDialog(const QtCanvasDialog&) = delete;
  QtCanvasDialog& operator=(const QtCanvasDialog&) = delete;

  protected:
  void keyPressEvent(QKeyEvent *event) override;
  void keyReleaseEvent(QKeyEvent *event) override;
  void resizeEvent(QResizeEvent *) override;

  private:
  ~QtCanvasDialog() noexcept;
  friend void boost::checked_delete<>(QtCanvasDialog* x);
  friend void boost::checked_delete<>(const QtCanvasDialog* x);
  friend class boost::detail::sp_ms_deleter<QtCanvasDialog>;
  friend class boost::detail::sp_ms_deleter<const QtCanvasDialog>;

  QtCanvas * const m_qtcanvas;

  void OnQtCanvasDestroy();
};

} //~namespace ribi

#endif // RIBI_QTCANVASDIALOG_H

 

 

 

 

 

./CppQtCanvas/qtcanvasdialog.cpp

 

#include "qtcanvasdialog.h"

#include <cassert>

#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Weffc++"
#pragma GCC diagnostic ignored "-Wunused-local-typedefs"
#include <QVBoxLayout>

#include "qtcanvas.h"
#include "trace.h"
#pragma GCC diagnostic pop

ribi::QtCanvasDialog::QtCanvasDialog(QtCanvas * const qtcanvas)
  : m_qtcanvas(qtcanvas)
{
  assert(!layout());
  QLayout * const my_layout = new QVBoxLayout;
  my_layout->setMargin(0);
  my_layout->setSpacing(0);
  my_layout->setContentsMargins(0,0,0,0);
  my_layout->addWidget(m_qtcanvas);
  m_qtcanvas->setSizePolicy(QSizePolicy::Minimum,QSizePolicy::Minimum);
  my_layout->setAlignment(m_qtcanvas,Qt::AlignCenter);
  my_layout->setAlignment(my_layout,Qt::AlignCenter);
  setLayout(my_layout);

  setStyleSheet("QDialog { background-color: rgb(0, 0, 0); }");

  m_qtcanvas->m_signal_on_destroy.connect(boost::bind(
    &ribi::QtCanvasDialog::OnQtCanvasDestroy,this)
  );

}

ribi::QtCanvasDialog::~QtCanvasDialog() noexcept
{

}

void ribi::QtCanvasDialog::keyPressEvent(QKeyEvent* event)
{
  if (event->key() == Qt::Key_Escape)
  {
    close();
    close_me();
    return;
  }
  m_qtcanvas->keyPressEvent(event);
}

void ribi::QtCanvasDialog::keyReleaseEvent(QKeyEvent* event)
{
  m_qtcanvas->keyReleaseEvent(event);
}

void ribi::QtCanvasDialog::OnQtCanvasDestroy()
{
  close_me();
  m_show_child = false;
  close();
}

void ribi::QtCanvasDialog::resizeEvent(QResizeEvent *)
{
  m_qtcanvas->setGeometry(rect());
}

 

 

 

 

 

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