/********************************************************************** * * FreeDoko a Doppelkopf-Game * * Copyright (C) 2001 – 2018 by Diether Knof and Borg Enders * * 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. * * 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 can find this license in the file 'gpl.txt'. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, * MA 02111-1307 USA * * Contact: * Diether Knof dknof@posteo.de * *********************************************************************/ #include "constants.h" #ifdef USE_UI_GTKMM #include "table_part.h" #include "ui.h" namespace UI_GTKMM_NS { /** constructor ** ** @param table the table **/ Table::Part::Part(Table& table) : Base{&table} { } /** destructor **/ Table::Part::~Part() = default; /** @return the table **/ Table& Table::Part::table() { return *dynamic_cast(this->parent); } // Table& Part::table() /** @return the table **/ Table const& Table::Part::table() const { return *dynamic_cast(this->parent); } // Table const& Part::table() const /** @return the corresponding game **/ Game const& Table::Part::game() const { return this->ui->game(); } // Game const& Part::game() const /** returns the surface ** If the surface is outdated, redraw it. ** ** @return surface with the drawing in it **/ Cairo::RefPtr Table::Part::surface() { if ( this->surface_ && !this->changed()) return this->surface_; auto const outline = this->outline(); this->surface_ = Cairo::ImageSurface::create(Cairo::FORMAT_ARGB32, outline.width(), outline.height()); auto cr = Cairo::Context::create(this->surface_); if (::debug("table")) { cr->save(); cr->set_source_rgba(0, 0, 1, 0.2); cr->rectangle(0, 0, outline.width(), outline.height()); cr->fill(); cr->restore(); } //cr->set_source(this->surface_, outline.x(), outline.y()); cr->set_source(this->surface_, 0, 0); cr->translate(-outline.x(), -outline.y()); this->draw(cr); return this->surface_; } // Cairo::RefPtr Table::Part::surface() /** Force a redraw **/ void Table::Part::force_redraw() { this->surface_.clear(); } // void Part::force_redraw() /** constructor ** ** @param values **/ Table::Part::Outline::Outline(int x, int y, int width, int height) : x([x](){ return x; }), y([y](){ return y; }), width([width](){ return width; }), height([height](){ return height; }) { } /** constructor ** ** @param values **/ Table::Part::Outline::Outline(function x, function y, function width, function height) : x(std::move(x)), y(std::move(y)), width(std::move(width)), height(std::move(height)) { } /** transform the cr according to the geometry ** ** @param cr context to transfomrm **/ void Table::Part::Geometry::transform(Cairo::RefPtr<::Cairo::Context> cr) const { switch (this->rotation) { case Rotation::up: cr->transform(Cairo::Matrix(1, 0, 0, 1, this->pos_x(), this->pos_y())); break; case Rotation::down: cr->transform(Cairo::Matrix(-1, 0, 0, -1, this->pos_x(), this->pos_y())); break; case Rotation::right: cr->transform(Cairo::Matrix(0, 1, -1, 0, this->pos_x(), this->pos_y())); break; case Rotation::left: cr->transform(Cairo::Matrix(0, -1, 1, 0, this->pos_x(), this->pos_y())); break; } // switch (this->rotation) } // void Table::Part::Geometry::transform(Cairo::RefPtr<::Cairo::Context> cr) const /** transform the coordinates ** ** @param x x position ** @param y y position ** @param width width ** @param height height **/ Table::Part::Outline Table::Part::Geometry::transform(Outline const outline) const { auto const x = outline.x(); auto const y = outline.y(); auto const width = outline.width(); auto const height = outline.height(); switch (this->rotation) { case Rotation::up: return {this->pos_x() + x, this->pos_y() + y, width, height}; case Rotation::down: return {this->pos_x() - x - width, this->pos_y() - y - height, width, height}; case Rotation::right: return {this->pos_x() - y - height, this->pos_y() + x, height, width}; case Rotation::left: return {this->pos_x() + y, this->pos_y() - x - width, height, width}; } // switch (this->rotation) return {}; } // Outline Table::Part::Geometry::transform(Outline outline) const /** retransforms the coordinates ** ** @param x x position ** @param y y position **/ void Table::Part::Geometry::retransform(int& x, int& y) const { x -= this->pos_x(); y -= this->pos_y(); switch (this->rotation) { case Rotation::up: return ; case Rotation::down: x = -x; y = -y; return ; case Rotation::right: { int const t = x; x = y; y = -t; } return ; case Rotation::left: { int const t = x; x = -y; y = t; } return ; } // switch (this->rotation) } // void Table::Part::Geometry::retransform(int& x, int& y) const /** write the outline into the output stream ** ** @param ostr output stream ** @param outline outline to write ** ** @return output stream **/ ostream& operator<<(ostream& ostr, Table::Part::Outline const& outline) { ostr << outline.width() << 'x' << outline.height() << '+' << outline.x() << '+' << outline.y(); return ostr; } // ostream& operator<<(ostream& ostr, Table::Part::Outline outline) /** write the geometry into the output stream ** ** @param ostr output stream ** @param geometry geometry to write ** ** @return output stream **/ ostream& operator<<(ostream& ostr, Table::Part::Geometry const& geometry) { ostr << geometry.width() << 'x' << geometry.height() << '+' << geometry.pos_x() << '+' << geometry.pos_y(); return ostr; } // ostream& operator<<(ostream& ostr, Table::Part::Geometry geometry) /** write the geometry into the output stream ** ** @param ostr output stream ** @param geometry geometry to write ** ** @return output stream **/ Table::Part::Outline operator+(Table::Part::Outline const lhs, Table::Part::Outline const rhs) { return {[=](){ return min(lhs.x(), rhs.x()); }, [=](){ return min(lhs.y(), rhs.y()); }, [=](){ return (max(lhs.x() + lhs.width(), rhs.x() + rhs.width()) - min(lhs.x(), rhs.x())); }, [=](){ return (max(lhs.y() + lhs.height(), rhs.y() + rhs.height()) - min(lhs.y(), rhs.y())); } }; } // Outline operator+(Outline lhs, Outline rhs) } // namespace UI_GTKMM_NS #endif // #ifdef USE_UI_GTKMM