diff options
author | Alex Zolotarev <deathbaba@gmail.com> | 2010-12-05 19:24:16 +0300 |
---|---|---|
committer | Alex Zolotarev <alex@maps.me> | 2015-09-22 22:33:57 +0300 |
commit | d6e12b7ce4bcbf0ccd1c07eb25de143422913c34 (patch) | |
tree | a7e910c330ce4da9b4f2d8be76067adece2561c4 /qt_tstfrm |
One Month In Minsk. Made in Belarus.
Diffstat (limited to 'qt_tstfrm')
-rw-r--r-- | qt_tstfrm/macros.hpp | 216 | ||||
-rw-r--r-- | qt_tstfrm/main_tester.cpp | 45 | ||||
-rw-r--r-- | qt_tstfrm/main_tester.hpp | 18 | ||||
-rw-r--r-- | qt_tstfrm/qt_tstfrm.pro | 23 | ||||
-rw-r--r-- | qt_tstfrm/screen_qt.cpp | 44 | ||||
-rw-r--r-- | qt_tstfrm/screen_qt.hpp | 52 | ||||
-rw-r--r-- | qt_tstfrm/tstwidgets.cpp | 102 | ||||
-rw-r--r-- | qt_tstfrm/tstwidgets.hpp | 51 | ||||
-rw-r--r-- | qt_tstfrm/widgets.hpp | 58 | ||||
-rw-r--r-- | qt_tstfrm/widgets_impl.hpp | 34 |
10 files changed, 643 insertions, 0 deletions
diff --git a/qt_tstfrm/macros.hpp b/qt_tstfrm/macros.hpp new file mode 100644 index 0000000000..a2ec2edced --- /dev/null +++ b/qt_tstfrm/macros.hpp @@ -0,0 +1,216 @@ +#pragma once + +#include "widgets.hpp" +#include "main_tester.hpp" +#include "tstwidgets.hpp" + +#include "../../testing/testing.hpp" +#include "../../map/qgl_render_context.hpp" + +#include <QtOpenGL/QGLContext> +#include <QtOpenGL/QGLPixelBuffer> +#include <QtGui/QApplication> + +//#include <iostream> + +template<class T, bool (T::*)(QKeyEvent *)> +struct key_event_fn_bind +{ + typedef T type; +}; + +template <class T, bool (T::*)(QMouseEvent*)> +struct mouse_event_fn_bind +{ + typedef T type; +}; + +template <class T, void (T::*)()> +struct void_fn_bind +{ + typedef T type; +}; + +template <class T, class RC, void (T::*)(shared_ptr<RC>)> +struct init_with_context_fn_bind +{ + typedef T type; +}; + +template<class T, class U> +struct has_on_keypress +{ + static const bool value = false; +}; + +template<class T> +struct has_on_keypress<T, typename key_event_fn_bind<T, &T::OnKeyPress>::type> +{ + static const bool value = true; +}; + +template <class T, class U> +struct has_on_mousemove +{ + static const bool value = false; +}; + +template <class T> +struct has_on_mousemove<T, typename mouse_event_fn_bind<T, &T::OnMouseMove>::type > +{ + static const bool value = true; +}; + +template <class T, class U> +struct has_on_mousepress +{ + static bool const value = false; +}; + +template <class T> +struct has_on_mousepress<T, typename mouse_event_fn_bind<T, &T::OnMousePress>::type > +{ + static const bool value = true; +}; + +template <class T, class U> +struct has_init +{ + static bool const value = false; +}; + +template <class T> +struct has_init<T, typename void_fn_bind<T, &T::Init>::type > +{ + static const bool value = true; +}; + +template <class T, class U, class RC> +struct has_init_with_context +{ + static bool const value = false; +}; + +template <class T, class RC> +struct has_init_with_context<T, typename init_with_context_fn_bind<T, RC, &T::Init>::type, RC > +{ + static const bool value = true; +}; + +template <bool T> +struct bool_tag{}; + +template <typename TTest> +class GLTestWidget : public tst::GLDrawWidget +{ + TTest test; + +public: + + virtual void DoDraw(shared_ptr<yg::gl::Screen> p) + { + test.DoDraw(p); + } + virtual void DoResize(int, int) + { + } + + bool keyPressEventImpl(QKeyEvent * ev, bool_tag<true> const &) + { + return test.OnKeyPress(ev); + } + + bool keyPressEventImpl(QKeyEvent *, bool_tag<false> const & ) + { + return false; + } + + virtual void keyPressEvent(QKeyEvent * ev) + { + if (keyPressEventImpl(ev, bool_tag<has_on_keypress<TTest, TTest>::value >())) + repaint(); + } + + bool mousePressEventImpl(QMouseEvent * ev, bool_tag<true> const &) + { + return test.OnMousePress(ev); + } + + bool mousePressEventImpl(QMouseEvent *, bool_tag<false> const &) + { + return false; + } + + virtual void mousePressEvent(QMouseEvent * ev) + { + if (mousePressEventImpl(ev, bool_tag<has_on_mousepress<TTest, TTest>::value >())) + repaint(); + } + + bool mouseMoveEventImpl(QMouseEvent * ev, bool_tag<true> const &) + { + return test.OnMouseMove(ev); + } + + bool mouseMoveEventImpl(QMouseEvent *, bool_tag<false> const &) + { + return false; + } + + void mouseMoveEvent(QMouseEvent * ev) + { + if (mouseMoveEventImpl(ev, bool_tag<has_on_mousemove<TTest, TTest>::value >())) + repaint(); + } + + void InitImpl(bool_tag<true> const & ) + { + test.Init(); + } + + void InitImpl(bool_tag<false> const & ) + {} + + void Init() + { + InitImpl(bool_tag<has_init<TTest, TTest>::value >()); + } + + void InitWithContextImpl(bool_tag<true> const &) + { + test.Init(shared_ptr<qt::gl::RenderContext>(new qt::gl::RenderContext(this))); + } + + void InitWithContextImpl(bool_tag<false> const &) + {} + + void initializeGL() + { + tst::GLDrawWidget::initializeGL(); + InitWithContextImpl(bool_tag<has_init_with_context<TTest, TTest, qt::gl::RenderContext>::value>()); + } +}; + +template <class Test> QWidget * create_widget() +{ + GLTestWidget<Test> * w = new GLTestWidget<Test>(); + w->Init(); + return w; +} + +#define GL_TEST_START \ + int argc = 0; \ + QApplication app(argc, 0); \ + QGLWidget * buf = new QGLWidget(); \ + QGLContext ctx(QGLFormat::defaultFormat(), buf); \ + ctx.create(); \ + ctx.makeCurrent(); + +#define UNIT_TEST_GL(name)\ + void UnitTestGL_##name();\ + TestRegister g_TestRegister_##name("Test::"#name, __FILE__, &UnitTestGL_##name);\ + void UnitTestGL_##name()\ + {\ + tst::BaseTester tester;\ + tester.Run(#name, &create_widget<name>);\ + } diff --git a/qt_tstfrm/main_tester.cpp b/qt_tstfrm/main_tester.cpp new file mode 100644 index 0000000000..80bde2a7ff --- /dev/null +++ b/qt_tstfrm/main_tester.cpp @@ -0,0 +1,45 @@ +#include "main_tester.hpp" + +#include <QtGui/QApplication> +#include <QtGui/QFrame> +#include <QtGui/QBoxLayout> + +#include "../base/start_mem_debug.hpp" + + +namespace tst +{ + class MainWindow : public QFrame + { + public: + MainWindow(QWidget * pWidget) + { + QHBoxLayout * pMainLayout = new QHBoxLayout(); + pMainLayout->setContentsMargins(0, 0, 0, 0); + + pMainLayout->addWidget(pWidget); + + setLayout(pMainLayout); + + setWindowTitle(tr("Testing Framework Form")); + + pWidget->setFocus(); + + resize(640, 480); + } + }; + +int BaseTester::Run(char const * name, function<QWidget * (void)> const & fn) +{ + char * argv[] = { const_cast<char *>(name) }; + int argc = 1; + + QApplication app(argc, argv); + + MainWindow wnd(fn()); + wnd.show(); + + return app.exec(); +} + +} diff --git a/qt_tstfrm/main_tester.hpp b/qt_tstfrm/main_tester.hpp new file mode 100644 index 0000000000..c72bec542e --- /dev/null +++ b/qt_tstfrm/main_tester.hpp @@ -0,0 +1,18 @@ +#pragma once + +#include "../std/function.hpp" + +class QWidget; + +namespace tst +{ + /// Base tester. Can work with any widgets from widgets.hpp + /// Works in screen coordinates with user defined widget. + class BaseTester + { + public: + + /// Main run function. + int Run(char const * name, function<QWidget * (void)> const & fn); + }; +} diff --git a/qt_tstfrm/qt_tstfrm.pro b/qt_tstfrm/qt_tstfrm.pro new file mode 100644 index 0000000000..de6c164d09 --- /dev/null +++ b/qt_tstfrm/qt_tstfrm.pro @@ -0,0 +1,23 @@ +TARGET = qt_tstfrm +TEMPLATE = lib +CONFIG += staticlib + +ROOT_DIR = .. +DEPENDENCIES = map yg geometry coding base + +include($$ROOT_DIR/common.pri) + +QT *= core gui opengl + +HEADERS += \ + main_tester.hpp \ + tstwidgets.hpp \ + widgets.hpp \ + widgets_impl.hpp \ + screen_qt.hpp \ + macros.hpp + +SOURCES += \ + main_tester.cpp \ + tstwidgets.cpp \ + screen_qt.cpp \ diff --git a/qt_tstfrm/screen_qt.cpp b/qt_tstfrm/screen_qt.cpp new file mode 100644 index 0000000000..329d015a94 --- /dev/null +++ b/qt_tstfrm/screen_qt.cpp @@ -0,0 +1,44 @@ +#include "screen_qt.hpp" + +#include <QtGui/QPainter> + +#include "../base/start_mem_debug.hpp" + + +namespace qt +{ + void Screen::drawPathImpl(vector<QPoint> const & path) + { + m_p->drawPolyline(&path[0], path.size()); + } + + void Screen::drawRect(m2::RectD const & r) + { + vector<m2::PointD> pts(5); + pts[0] = r.LeftTop(); + pts[1] = r.RightTop(); + pts[2] = r.RightBottom(); + pts[3] = r.LeftBottom(); + pts[4] = r.LeftTop(); + + drawPath(pts); + } + + void Screen::drawLine(m2::PointD const & p1, m2::PointD const & p2) + { + m_p->drawLine(qpoint(p1), qpoint(p2)); + } + + void Screen::hatchRect(m2::RectD const & r) + { + const size_t numPoints = 8; + for (size_t x = 0; x < numPoints; ++x) + { + for (size_t y = 0; y < numPoints; ++y) + { + m2::PointD point(r.LeftBottom().x + r.SizeX() * x / 8.0, r.LeftBottom().y + r.SizeY() * y / 8.0); + drawLine(point, m2::PointD(point.x + r.SizeX() / 16.0, point.y + r.SizeY() / 16.0)); + } + } + } +} diff --git a/qt_tstfrm/screen_qt.hpp b/qt_tstfrm/screen_qt.hpp new file mode 100644 index 0000000000..aee42e5098 --- /dev/null +++ b/qt_tstfrm/screen_qt.hpp @@ -0,0 +1,52 @@ +#pragma once + +#include "../geometry/screenbase.hpp" +#include "../geometry/rect2d.hpp" +#include "../geometry/point2d.hpp" + +#include <QtCore/QPoint> + +class QPainter; + +namespace qt +{ + class Screen + { + QPainter * m_p; + ScreenBase m_convertor; + + void drawPathImpl(vector<QPoint> const & path); + + template <class T> + inline QPoint qpoint(std::pair<T, T> const & p) const + { + m2::PointD pp = m_convertor.GtoP(m2::PointD(p.first, p.second)); + return QPoint(pp.x, pp.y); + } + inline QPoint qpoint(m2::PointD const & p) const + { + m2::PointD pp = m_convertor.GtoP(p); + return QPoint(pp.x, pp.y); + } + + public: + void setPainter(QPainter * p) { m_p = p; } + void onSize(int w, int h) { m_convertor.OnSize(0, 0, w, h); } + void setFromRect(m2::RectD const & r) { m_convertor.SetFromRect(r); } + + template <class TCont> void drawPath(TCont const & c) + { + vector<QPoint> qvec; + qvec.reserve(c.size()); + for (typename TCont::const_iterator i = c.begin(); i != c.end(); ++i) + qvec.push_back(qpoint(*i)); + + drawPathImpl(qvec); + } + + void drawLine(m2::PointD const & p1, m2::PointD const & p2); + + void drawRect(m2::RectD const & r); + void hatchRect(m2::RectD const & r); + }; +} diff --git a/qt_tstfrm/tstwidgets.cpp b/qt_tstfrm/tstwidgets.cpp new file mode 100644 index 0000000000..8cea4bea69 --- /dev/null +++ b/qt_tstfrm/tstwidgets.cpp @@ -0,0 +1,102 @@ +#include "tstwidgets.hpp" +#include "widgets_impl.hpp" +#include "screen_qt.hpp" + +#include "../yg/screen.hpp" +#include "../yg/utils.hpp" +#include "../yg/skin.hpp" +#include "../yg/framebuffer.hpp" +#include "../yg/renderbuffer.hpp" +#include "../yg/resource_manager.hpp" + +#ifdef WIN32 +#include "../yg/internal/opengl_win32.hpp" +#endif + +#include "../platform/platform.hpp" + +#include "../base/start_mem_debug.hpp" +#include "../base/ptr_utils.hpp" + + +template class qt::GLDrawWidgetT<yg::gl::Screen>; + +namespace tst { + +GLDrawWidget::GLDrawWidget() : base_type(0) +{ +} + +GLDrawWidget::~GLDrawWidget() +{ +} + +void GLDrawWidget::initializeGL() +{ +#ifdef WIN32 + win32::InitOpenGL(); +#endif + + m_primaryContext = make_shared_ptr(new qt::gl::RenderContext(this)); + + m_resourceManager = make_shared_ptr(new yg::ResourceManager( + 30000 * sizeof(yg::gl::Vertex), + 50000 * sizeof(unsigned short), + 20, + 3000 * sizeof(yg::gl::Vertex), + 5000 * sizeof(unsigned short), + 100, + 512, 256, 15)); +/* m_resourceManager = make_shared_ptr(new yg::ResourceManager( + 5000 * sizeof(yg::gl::Vertex), + 10000 * sizeof(unsigned short), + 20, + 256, 256, 10));*/ + + m_p = make_shared_ptr(new yg::gl::Screen(m_resourceManager)); + + m_primaryFrameBuffer = make_shared_ptr(new yg::gl::FrameBuffer(true)); + + m_frameBuffer = make_shared_ptr(new yg::gl::FrameBuffer()); + + m_p->setFrameBuffer(m_frameBuffer); + + m_skin = shared_ptr<yg::Skin>(loadSkin(m_resourceManager, GetPlatform().SkinName())); + m_p->setSkin(m_skin); +} + +void GLDrawWidget::resizeGL(int w, int h) +{ + m_p->onSize(w, h); + + m_frameBuffer->onSize(w, h); + m_primaryFrameBuffer->onSize(w, h); + + m_depthBuffer.reset(); + m_depthBuffer = make_shared_ptr(new yg::gl::RenderBuffer(w, h, true)); + m_frameBuffer->setDepthBuffer(m_depthBuffer); + + m_renderTarget.reset(); + m_renderTarget = make_shared_ptr(new yg::gl::RGBA8Texture(w, h)); + m_frameBuffer->setRenderTarget(m_renderTarget); +} + +void GLDrawWidget::paintGL() +{ + base_type::paintGL(); + + m_p->setFrameBuffer(m_primaryFrameBuffer); + + m_p->beginFrame(); + + m_p->immDrawTexturedRect( + m2::RectF(0, 0, m_renderTarget->width(), m_renderTarget->height()), + m2::RectF(0, 0, 1, 1), + m_renderTarget + ); + + m_p->endFrame(); + + m_p->setFrameBuffer(m_frameBuffer); +} +} diff --git a/qt_tstfrm/tstwidgets.hpp b/qt_tstfrm/tstwidgets.hpp new file mode 100644 index 0000000000..054c743099 --- /dev/null +++ b/qt_tstfrm/tstwidgets.hpp @@ -0,0 +1,51 @@ +#pragma once + +#include "widgets.hpp" + +#include "../yg/texture.hpp" +#include "../yg/resource_manager.hpp" +#include "../yg/renderbuffer.hpp" +#include "../map/drawer_yg.hpp" +#include "../map/qgl_render_context.hpp" + +#include "../std/shared_ptr.hpp" + + +namespace yg +{ + class Skin; + namespace gl + { + class Screen; + } +} + +namespace qt { class Screen; } + +namespace tst +{ + class GLDrawWidget : public qt::GLDrawWidgetT<yg::gl::Screen> + { + protected: + typedef qt::GLDrawWidgetT<yg::gl::Screen> base_type; + + shared_ptr<yg::ResourceManager> m_resourceManager; + + shared_ptr<yg::gl::FrameBuffer> m_primaryFrameBuffer; + shared_ptr<yg::gl::FrameBuffer> m_frameBuffer; + shared_ptr<yg::gl::RGBA8Texture> m_renderTarget; + shared_ptr<yg::gl::RenderBuffer> m_depthBuffer; + shared_ptr<yg::Skin> m_skin; + shared_ptr<qt::gl::RenderContext> m_primaryContext; + + public: + + GLDrawWidget(); + virtual ~GLDrawWidget(); + + protected: + virtual void initializeGL(); + virtual void resizeGL(int w, int h); + virtual void paintGL(); + }; +} diff --git a/qt_tstfrm/widgets.hpp b/qt_tstfrm/widgets.hpp new file mode 100644 index 0000000000..5b331fd2f9 --- /dev/null +++ b/qt_tstfrm/widgets.hpp @@ -0,0 +1,58 @@ +#pragma once + +#include <QtGui/QWidget> + +#include <QtOpenGL/qgl.h> + +#include "../base/start_mem_debug.hpp" +#include "../std/shared_ptr.hpp" +#include "../yg/screen.hpp" +#include "../map/drawer_yg.hpp" + +namespace qt +{ + template <class TScreen, class TBase> class BaseDrawWidget : public TBase + { + typedef TBase base_type; + + public: + typedef TScreen screen_t; + + BaseDrawWidget(QWidget * pParent) : base_type(pParent) + { + } + + protected: + /// Override this function to make drawing and additional resize processing. + //@{ + virtual void DoDraw(shared_ptr<screen_t> p) = 0; + virtual void DoResize(int w, int h) = 0; + //@} + }; + + /// Widget uses yg for drawing. + template <class T> class GLDrawWidgetT : public BaseDrawWidget<T, QGLWidget> + { + typedef BaseDrawWidget<T, QGLWidget> base_type; + protected: + + shared_ptr<T> m_p; + + public: + + shared_ptr<T> GetDrawer() {return m_p;} + + GLDrawWidgetT(QWidget * pParent) : base_type(pParent){} + virtual ~GLDrawWidgetT(); + + protected: + /// Overriden from QGLWidget. + //@{ + virtual void initializeGL() = 0; + virtual void paintGL(); + virtual void resizeGL(int w, int h); + //@} + }; +} + +#include "../base/stop_mem_debug.hpp" diff --git a/qt_tstfrm/widgets_impl.hpp b/qt_tstfrm/widgets_impl.hpp new file mode 100644 index 0000000000..a34c2168cf --- /dev/null +++ b/qt_tstfrm/widgets_impl.hpp @@ -0,0 +1,34 @@ +#pragma once + +#include "widgets.hpp" + +#include "../base/start_mem_debug.hpp" + +namespace qt +{ + template <class T> + GLDrawWidgetT<T>::~GLDrawWidgetT() + {} + + template <class T> + void GLDrawWidgetT<T>::paintGL() + { + if (m_p) + { + m_p->beginFrame(); + m_p->clear(); + DoDraw(m_p); + m_p->endFrame(); + } + } + + template <class T> + void GLDrawWidgetT<T>::resizeGL(int w, int h) + { + if (m_p) + { + m_p->onSize(w, h); + this->DoResize(w, h); + } + } +} |