File indexing completed on 2024-05-05 05:40:35

0001 /***************************************************************************
0002  *   Copyright (C) 2018 by Renaud Guezennec                                *
0003  *   https://rolisteam.org/contact                   *
0004  *                                                                         *
0005  *   This program is free software; you can redistribute it and/or modify  *
0006  *   it under the terms of the GNU General Public License as published by  *
0007  *   the Free Software Foundation; either version 2 of the License, or     *
0008  *   (at your option) any later version.                                   *
0009  *                                                                         *
0010  *   This program is distributed in the hope that it will be useful,       *
0011  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
0012  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
0013  *   GNU General Public License for more details.                          *
0014  *                                                                         *
0015  *   You should have received a copy of the GNU General Public License     *
0016  *   along with this program; if not, write to the                         *
0017  *   Free Software Foundation, Inc.,                                       *
0018  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
0019  ***************************************************************************/
0020 #include "undoCmd/changesizevmapitem.h"
0021 
0022 #include "controller/item_controllers/visualitemcontroller.h"
0023 #include <QDebug>
0024 
0025 ChangeSizeVmapItemCommand::ChangeSizeVmapItemCommand(const QList<vmap::VisualItemController*>& list,
0026                                                      VectorialMapController::Method method, const QPointF& mousePos,
0027                                                      QUndoCommand* parent)
0028     : QUndoCommand(parent)
0029 {
0030     m_data.reserve(static_cast<std::size_t>(list.size()));
0031     QRectF ref;
0032     if(method == VectorialMapController::Bigger)
0033     {
0034         auto it= std::max_element(std::begin(list), std::end(list),
0035                                   [](vmap::VisualItemController* a, vmap::VisualItemController* b)
0036                                   {
0037                                       auto areaA= a->rect().height() * a->rect().width();
0038                                       auto areaB= b->rect().height() * b->rect().width();
0039                                       return areaA < areaB;
0040                                   });
0041         ref= (*it)->rect();
0042     }
0043     else if(method == VectorialMapController::Smaller)
0044     {
0045         auto it= std::min_element(std::begin(list), std::end(list),
0046                                   [](vmap::VisualItemController* a, vmap::VisualItemController* b)
0047                                   {
0048                                       auto areaA= a->rect().height() * a->rect().width();
0049                                       auto areaB= b->rect().height() * b->rect().width();
0050                                       return areaA < areaB;
0051                                   });
0052         ref= (*it)->rect();
0053     }
0054     else if(method == VectorialMapController::Average)
0055     {
0056         qreal averageHeight= 0.0;
0057         qreal averageWidth= 0.0;
0058         std::for_each(std::begin(list), std::end(list),
0059                       [&averageHeight, &averageWidth](vmap::VisualItemController* a)
0060                       {
0061                           averageHeight+= a->rect().height();
0062                           averageWidth+= a->rect().width();
0063                       });
0064         averageWidth/= list.size();
0065         averageHeight/= list.size();
0066         ref= QRectF(0.0, 0.0, averageWidth, averageHeight);
0067     }
0068     else if(method == VectorialMapController::UnderMouse)
0069     {
0070         auto it= std::find_if(std::begin(list), std::end(list),
0071                               [mousePos](vmap::VisualItemController* a)
0072                               {
0073                                   auto rect= a->rect();
0074                                   rect.translate(a->pos());
0075                                   return rect.contains(mousePos);
0076                               });
0077 
0078         if(it == std::end(list))
0079             qCritical() << "ChangeSizeVmapItemCommand - no item under the mouse";
0080         else
0081             ref= (*it)->rect();
0082     }
0083 
0084     if(!ref.isEmpty())
0085     {
0086         std::transform(std::begin(list), std::end(list), std::back_inserter(m_data),
0087                        [ref](vmap::VisualItemController* a) -> ChangeSizeData
0088                        {
0089                            ChangeSizeData data;
0090                            data.m_ctrl= a;
0091                            auto rect= a->rect();
0092                            data.m_move= QPointF(ref.width() - rect.width(), ref.height() - rect.height());
0093                            data.m_resetMove= QPointF(-data.m_move.x(), -data.m_move.y());
0094                            return data;
0095                        });
0096     }
0097 
0098     setText(QObject::tr("Change size of %1 item(s)").arg(list.size()));
0099 }
0100 
0101 void ChangeSizeVmapItemCommand::undo()
0102 {
0103     qInfo() << QStringLiteral("undo command ChangeSizeVmapItemCommand: %1 ").arg(text());
0104     std::for_each(std::begin(m_data), std::end(m_data),
0105                   [](const ChangeSizeData& data) { data.m_ctrl->setCorner(data.m_resetMove, 2); });
0106 }
0107 
0108 void ChangeSizeVmapItemCommand::redo()
0109 {
0110     qInfo() << QStringLiteral("redo command ChangeSizeVmapItemCommand: %1 ").arg(text());
0111     std::for_each(std::begin(m_data), std::end(m_data),
0112                   [](const ChangeSizeData& data) { data.m_ctrl->setCorner(data.m_move, 2); });
0113 }