Skip to content

Commit

Permalink
Introduce a map renderer class
Browse files Browse the repository at this point in the history
It is meant to incorporate the functionality of mapview_common needed to draw
the map. Right now it delegates most (all) of its work to mapview_common.
  • Loading branch information
lmoureaux authored and psampathkumar committed Aug 1, 2022
1 parent 4f5fe2b commit 4f85b9a
Show file tree
Hide file tree
Showing 6 changed files with 148 additions and 23 deletions.
1 change: 1 addition & 0 deletions client/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@ add_library(
plrdlg_common.cpp
pregameoptions.cpp
ratesdlg.cpp
renderer.cpp
repodlgs_common.cpp
reqtree.cpp
sciencedlg.cpp
Expand Down
35 changes: 15 additions & 20 deletions client/mapview.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
#include "mapview_common.h"
#include "mapview_g.h"
#include "minimap_panel.h"
#include "renderer.h"
#include "sprite.h"
#include "text.h"
#include "tilespec.h"
Expand Down Expand Up @@ -134,7 +135,7 @@ void draw_calculated_trade_routes(QPainter *painter)
Constructor for map
*/
map_view::map_view()
: QWidget(),
: QWidget(), m_renderer(new freeciv::renderer(this)),
m_scale_animation(std::make_unique<QPropertyAnimation>(this, "scale"))
{
menu_click = false;
Expand Down Expand Up @@ -209,6 +210,11 @@ void map_view::zoom_reset() { set_scale(1); }
*/
void map_view::zoom_out() { set_scale(scale() / 1.2); }

/**
* Retrieves the current scale (zoom level) of the map.
*/
double map_view::scale() const { return m_renderer->scale(); }

/**
* Sets the map scale.
*/
Expand All @@ -226,11 +232,7 @@ void map_view::set_scale(double scale)
*/
void map_view::set_scale_now(double scale)
{
m_scale = scale;
// When zoomed in, we pretend that the canvas is smaller than it is. This
// makes text look bad, but everything else is drawn correctly.
map_canvas_resized(width() / m_scale, height() / m_scale);

m_renderer->set_scale(scale);
emit scale_changed(m_scale);
}

Expand Down Expand Up @@ -314,26 +316,19 @@ void map_view::paintEvent(QPaintEvent *event)
QPainter painter;

painter.begin(this);
paint(&painter, event);
m_renderer->render(painter, event->region());
painter.scale(1 / scale(), 1 / scale());
draw_calculated_trade_routes(&painter);
painter.end();
}

/**
Redraws given rectangle on map
* The widget has been resized.
*/
void map_view::paint(QPainter *painter, QPaintEvent *event)
void map_view::resizeEvent(QResizeEvent *event)
{
if (scale() != 1) {
painter->setRenderHint(QPainter::SmoothPixmapTransform);
}
auto widget_rect = QRectF(event->rect());
auto mapview_rect =
QRectF(widget_rect.left() / scale(), widget_rect.top() / scale(),
widget_rect.width() / scale(), widget_rect.height() / scale());
painter->drawPixmap(widget_rect, *mapview.store, mapview_rect);

painter->scale(1 / scale(), 1 / scale());
draw_calculated_trade_routes(painter);
m_renderer->set_viewport_size(event->size());
event->accept();
}

/**
Expand Down
8 changes: 6 additions & 2 deletions client/mapview.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ class QPaintEvent;
class QPainter;

class fcwidget;
namespace freeciv {
class renderer;
}

bool is_point_in_area(int x, int y, int px, int py, int pxe, int pye);
void draw_calculated_trade_routes(QPainter *painter);
Expand All @@ -51,7 +54,6 @@ class map_view : public QWidget {

public:
map_view();
void paint(QPainter *painter, QPaintEvent *event);
void find_place(int pos_x, int pos_y, int &w, int &h, int wdth, int hght,
int recursive_nr, bool direction = false);
void resume_searching(int pos_x, int pos_y, int &w, int &h, int wdtht,
Expand All @@ -63,7 +65,7 @@ class map_view : public QWidget {

bool menu_click;

double scale() const { return m_scale; }
double scale() const;

freeciv::tileset_debugger *debugger() const { return m_debugger; }

Expand All @@ -89,6 +91,7 @@ public slots:
void mouseMoveEvent(QMouseEvent *event) override;
void focusOutEvent(QFocusEvent *event) override;
void leaveEvent(QEvent *event) override;
void resizeEvent(QResizeEvent *event) override;

private slots:
void set_scale_now(double scale);
Expand All @@ -98,6 +101,7 @@ private slots:
bool stored_autocenter;
int cursor_frame{0};
int cursor;
freeciv::renderer *m_renderer;
double m_scale = 1;
std::unique_ptr<QPropertyAnimation> m_scale_animation;
QPointer<freeciv::tileset_debugger> m_debugger = nullptr;
Expand Down
1 change: 0 additions & 1 deletion client/page_game.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -513,7 +513,6 @@ bool fc_game_tab_widget::event(QEvent *event)
? static_cast<QResizeEvent *>(event)->size()
: this->size();
if (event->type() == QEvent::Resize) {
map_canvas_resized(size.width(), size.height());
queen()->message->resize(
qRound((size.width() * king()->qt_settings.chat_fwidth)),
qRound((size.height() * king()->qt_settings.chat_fheight)));
Expand Down
85 changes: 85 additions & 0 deletions client/renderer.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
/*
* SPDX-FileCopyrightText: 2022 Louis Moureaux <[email protected]>
*
* SPDX-License-Identifier: GPLv3-or-later
*/

#include "renderer.h"

#include "mapview_common.h"

namespace freeciv {

/**
* @class renderer
* @brief Renders the map on widgets
*
* This class is used to draw the map. It can handle zoom via the @ref scale
* property.
*
* @property scale By how much the map is scaled before being drawn (a scale
* of 2 means that everything is 2x bigger)
*/

/**
* Constructor.
*/
renderer::renderer(QObject *parent) : QObject(parent) {}

/**
* Changes the scale of the rendering (zooms in or out).
*/
void renderer::set_scale(double scale)
{
m_scale = scale;

// When zoomed in, we pretend that the canvas is smaller than it actually
// is. This makes text look bad, but everything else is drawn correctly.
map_canvas_resized(m_viewport_size.width() / m_scale,
m_viewport_size.height() / m_scale);
}

/**
* Instructs the renderer to draw a viewport with a different size.
*/
void renderer::set_viewport_size(const QSize &size)
{
m_viewport_size = size;

// When zoomed in, we pretend that the canvas is smaller than it actually
// is. This makes text look bad, but everything else is drawn correctly.
map_canvas_resized(m_viewport_size.width() / m_scale,
m_viewport_size.height() / m_scale);
}

/**
* Renders the specified region of the visible portion of the map on @c
* painter.
* @see @ref render(QPainter&, const QRect&)
*/
void renderer::render(QPainter &painter, const QRegion &region) const
{
for (const auto &rect : region) {
render(painter, rect);
}
}

/**
* Renders the specified area of the visible portion of the map on @c
* painter. This is meant to be used directly from @c paintEvent, so the
* position of
* @c area is relative to the @ref viewport.
*/
void renderer::render(QPainter &painter, const QRect &area) const
{
if (scale() != 1) {
painter.setRenderHint(QPainter::SmoothPixmapTransform);
}

auto mapview_rect =
QRectF(area.left() / scale(), area.top() / scale(),
area.width() / scale(), area.height() / scale());
painter.drawPixmap(area, *mapview.store, mapview_rect);
}

} // namespace freeciv
41 changes: 41 additions & 0 deletions client/renderer.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/*
* SPDX-FileCopyrightText: 2022 Louis Moureaux <[email protected]>
*
* SPDX-License-Identifier: GPLv3-or-later
*/

#pragma once

#include <QObject>
#include <QPainter>
#include <QRect>
#include <QRegion>
#include <QSize>

namespace freeciv {

class renderer : public QObject {
Q_OBJECT
Q_PROPERTY(double scale READ scale WRITE set_scale);

public:
explicit renderer(QObject *parent = nullptr);
virtual ~renderer() = default;

/// The scale (zoom) at which rendering is performed
double scale() const { return m_scale; }
void set_scale(double scale);

/// The current dimensions of the viewport
QSize viewport_size() const { return m_viewport_size; }
void set_viewport_size(const QSize &size);

void render(QPainter &painter, const QRegion &region) const;
void render(QPainter &painter, const QRect &area) const;

private:
double m_scale = 1.0;
QSize m_viewport_size;
};

} // namespace freeciv

0 comments on commit 4f85b9a

Please sign in to comment.