File indexing completed on 2024-05-12 05:39:39
0001 /*************************************************************************** 0002 * Copyright (C) 2018 by Renaud Guezennec * 0003 * http://www.rolisteam.org/ * 0004 * * 0005 * This file is part of rcse * 0006 * * 0007 * rcse is free software; you can redistribute it and/or modify * 0008 * it under the terms of the GNU General Public License as published by * 0009 * the Free Software Foundation; either version 2 of the License, or * 0010 * (at your option) any later version. * 0011 * * 0012 * rcse is distributed in the hope that it will be useful, * 0013 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 0014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 0015 * GNU General Public License for more details. * 0016 * * 0017 * You should have received a copy of the GNU General Public License * 0018 * along with this program; if not, write to the * 0019 * Free Software Foundation, Inc., * 0020 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * 0021 ***************************************************************************/ 0022 #include "tablecanvasfield.h" 0023 #include <QDebug> 0024 #include <QGraphicsSceneMouseEvent> 0025 #include <QJsonArray> 0026 #include <QPainter> 0027 #include <QStyle> 0028 #include <QStyleOptionGraphicsItem> 0029 0030 #include "charactersheet/controllers/fieldcontroller.h" 0031 #include "charactersheet/controllers/tablefield.h" 0032 #define SQUARE_SIZE 12 0033 0034 ////////////////////////////////////////////////////// 0035 // 0036 // 0037 // 0038 ///////////////////////////////////////////////////// 0039 bool compareHandles(HandleItem* first, HandleItem* two) 0040 { 0041 return (first->pos().x() < two->pos().x()); 0042 } 0043 0044 TableCanvasField::TableCanvasField(FieldController* field) 0045 : CanvasField(field), m_colunmCount(1), m_lineCount(1), m_dataReset(true) 0046 { 0047 m_addColumn= new ButtonCanvas(); 0048 m_addColumn->setParentItem(this); 0049 0050 m_dialog.reset(new ColumnDefinitionDialog()); 0051 0052 connect(m_dialog.get(), &ColumnDefinitionDialog::columnCountChanged, this, [=](int i) { 0053 while(i > m_colunmCount) 0054 { 0055 addColumn(); 0056 } 0057 while(i < m_colunmCount) 0058 { 0059 removeColumn(); 0060 } 0061 }); 0062 0063 connect(m_dialog.get(), &ColumnDefinitionDialog::lineCountChanged, this, [=](int i) { 0064 m_lineCount= i; 0065 update(); 0066 }); 0067 0068 m_addLine= new ButtonCanvas(); 0069 m_addLine->setParentItem(this); 0070 0071 m_defineColumns= new QAction(tr("Properties"), this); 0072 // m_properties = new QAction(tr("Properties"),this); 0073 0074 connect(m_defineColumns, &QAction::triggered, this, &TableCanvasField::defineColumns); 0075 0076 m_addLine->setMsg("+"); 0077 m_addColumn->setMsg("+"); 0078 0079 m_addLine->setPos(24, 200); 0080 m_addColumn->setPos(200, 24); 0081 0082 connect(m_addColumn, SIGNAL(clicked()), this, SLOT(addColumn())); 0083 connect(m_addLine, SIGNAL(clicked()), this, SLOT(addLine())); 0084 } 0085 TableCanvasField::~TableCanvasField() {} 0086 void TableCanvasField::addColumn() 0087 { 0088 m_colunmCount++; 0089 0090 HandleItem* item= new HandleItem(this); 0091 m_handles.append(item); 0092 0093 qreal colW= boundingRect().width() / (m_handles.size() + 1); 0094 for(auto item : m_handles) 0095 { 0096 item->setPos(colW * (m_handles.indexOf(item) + 1), boundingRect().height() / 2); 0097 } 0098 if(m_columnDefined) 0099 { 0100 m_dataReset= true; 0101 defineColumns(); 0102 } 0103 update(); 0104 } 0105 void TableCanvasField::removeColumn() 0106 { 0107 m_colunmCount--; 0108 if(m_handles.isEmpty()) 0109 return; 0110 0111 m_handles.removeLast(); 0112 0113 qreal colW= boundingRect().width() / (m_handles.size() + 1); 0114 for(auto item : m_handles) 0115 { 0116 item->setPos(colW * (m_handles.indexOf(item) + 1), boundingRect().height() / 2); 0117 } 0118 if(m_columnDefined) 0119 { 0120 m_dataReset= true; 0121 defineColumns(); 0122 } 0123 update(); 0124 } 0125 0126 void TableCanvasField::addLine() 0127 { 0128 m_lineCount++; 0129 update(); 0130 } 0131 0132 void TableCanvasField::defineColumns() 0133 { 0134 std::sort(m_handles.begin(), m_handles.end(), compareHandles); 0135 0136 if(m_dataReset) 0137 { 0138 m_dialog->setData(m_handles, boundingRect().width(), m_lineCount, boundingRect().height()); 0139 m_dataReset= false; 0140 } 0141 0142 if(m_dialog->isHidden()) 0143 { 0144 m_dialog->exec(); 0145 update(); 0146 m_columnDefined= true; 0147 } 0148 } 0149 0150 void TableCanvasField::setMenu(QMenu& menu) 0151 { 0152 menu.addAction(m_defineColumns); 0153 } 0154 0155 int TableCanvasField::lineCount() const 0156 { 0157 return m_lineCount; 0158 } 0159 0160 void TableCanvasField::setLineCount(int lineCount) 0161 { 0162 m_lineCount= lineCount; 0163 } 0164 0165 int TableCanvasField::colunmCount() const 0166 { 0167 return m_colunmCount; 0168 } 0169 0170 void TableCanvasField::setColunmCount(int colunmCount) 0171 { 0172 m_colunmCount= colunmCount; 0173 } 0174 0175 void TableCanvasField::paint(QPainter* painter, const QStyleOptionGraphicsItem*, QWidget*) 0176 { 0177 if(nullptr == m_ctrl) 0178 return; 0179 auto rect= boundingRect(); 0180 painter->save(); 0181 painter->fillRect(rect, m_ctrl->bgColor()); 0182 painter->setPen(Qt::black); 0183 painter->drawRect(rect); 0184 0185 m_addLine->setPos(0, boundingRect().height() / 2); 0186 m_addColumn->setPos(boundingRect().width() / 2, 0); 0187 0188 if(hasFocusOrChild()) 0189 { 0190 painter->save(); 0191 QPen pen= painter->pen(); 0192 pen.setColor(Qt::red); 0193 pen.setWidth(5); 0194 painter->setPen(pen); 0195 painter->drawRect(rect); 0196 painter->restore(); 0197 } 0198 0199 for(auto handle : m_handles) 0200 { 0201 painter->drawLine(handle->pos().x(), 0, handle->pos().x(), boundingRect().height()); 0202 handle->setVisible(hasFocusOrChild()); 0203 } 0204 0205 auto yStep= boundingRect().height() / (m_lineCount); 0206 0207 if(!m_dataReset) 0208 { 0209 auto model= m_dialog->model(); 0210 if(nullptr != model) 0211 { 0212 auto list= model->children(); 0213 for(int x= 0; x < std::min(m_colunmCount, static_cast<int>(list.size())); ++x) 0214 { 0215 auto field= list.at(x); 0216 qreal xPos= 0; 0217 if(x != 0) 0218 { 0219 xPos= m_handles.at(x - 1)->pos().x(); 0220 } 0221 qreal xEnd= boundingRect().width() - xPos; 0222 if(x < m_colunmCount - 1) 0223 { 0224 xEnd= m_handles.at(x)->pos().x() - xPos; 0225 } 0226 auto itemType= m_ctrl->itemType(); 0227 auto fieldH= boundingRect().height() / m_lineCount; 0228 for(int y= 0; y < m_lineCount; ++y) 0229 { 0230 QRectF rect(xPos, y * yStep, xEnd, fieldH); 0231 QPixmap map= QPixmap(m_pictureMap[itemType]); 0232 m_pix= map.scaled(32, 32); 0233 if((!m_pix.isNull()) && m_showImageField) 0234 { 0235 painter->drawPixmap(rect.center(), m_pix, m_pix.rect()); //-m_pix.rect().center() 0236 } 0237 painter->save(); 0238 painter->setPen(Qt::green); 0239 painter->drawRect(rect); 0240 painter->restore(); 0241 } 0242 } 0243 } 0244 } 0245 0246 for(int i= 0; i < m_lineCount; ++i) 0247 { 0248 painter->drawLine(0, i * yStep, boundingRect().width(), i * yStep); 0249 } 0250 painter->drawText(QPoint(0, 0), m_ctrl->id()); 0251 painter->restore(); 0252 } 0253 bool TableCanvasField::hasFocusOrChild() 0254 { 0255 if(isSelected()) 0256 { 0257 return true; 0258 } 0259 else 0260 { 0261 if(m_handles.isEmpty()) 0262 { 0263 return false; 0264 } 0265 for(int i= 0; i < m_handles.size(); ++i) 0266 { 0267 if((m_handles.at(i) != nullptr) && (m_handles.at(i)->isSelected())) 0268 { 0269 return true; 0270 } 0271 } 0272 } 0273 0274 return false; 0275 } 0276 void TableCanvasField::generateSubFields(QTextStream& out) 0277 { 0278 auto model= m_dialog->model(); 0279 if(nullptr != model) 0280 { 0281 model->generateQML(out, 1, true); 0282 } 0283 } 0284 0285 TreeSheetItem* TableCanvasField::getRoot() 0286 { 0287 auto model= m_dialog->model(); 0288 Section* sec= nullptr; 0289 if(nullptr != model) 0290 { 0291 sec= model->getRootSection(); 0292 } 0293 return sec; 0294 } 0295 void TableCanvasField::fillLineModel(LineModel* lineModel, TableField* parent) 0296 { 0297 auto model= m_dialog->model(); 0298 for(int i= 0; i < m_lineCount; ++i) 0299 { 0300 LineFieldItem* line= new LineFieldItem(); 0301 for(TreeSheetItem* child : model->children()) 0302 { 0303 auto field= dynamic_cast<FieldController*>(child); 0304 if(nullptr != field) 0305 { 0306 auto newField= new FieldController(TreeSheetItem::FieldItem, true); 0307 newField->copyField(field, true, false); 0308 newField->setParent(parent); 0309 line->insertField(newField); 0310 } 0311 } 0312 lineModel->insertLine(line); 0313 } 0314 } 0315 0316 void TableCanvasField::load(QJsonObject& json) 0317 { 0318 m_lineCount= json["lineCount"].toInt(); 0319 m_colunmCount= json["colunmCount"].toInt(); 0320 m_dataReset= json["dataReset"].toBool(); 0321 m_columnDefined= json["columnDefined"].toBool(); 0322 0323 QJsonArray handles= json["handles"].toArray(); 0324 for(auto handle : handles) 0325 { 0326 auto handleItem= new HandleItem(this); 0327 auto obj= handle.toObject(); 0328 handleItem->load(obj); 0329 m_handles.append(handleItem); 0330 } 0331 0332 QJsonObject dialog= json["dialog"].toObject(); 0333 m_dialog->load(dialog); 0334 } 0335 void TableCanvasField::save(QJsonObject& json) 0336 { 0337 json["lineCount"]= m_lineCount; 0338 json["colunmCount"]= m_colunmCount; 0339 json["dataReset"]= m_dataReset; 0340 json["columnDefined"]= m_columnDefined; 0341 0342 QJsonArray handles; 0343 for(auto handle : m_handles) 0344 { 0345 QJsonObject obj; 0346 handle->save(obj); 0347 handles.push_back(obj); 0348 } 0349 json["handles"]= handles; 0350 0351 QJsonObject dialog; 0352 m_dialog->save(dialog); 0353 json["dialog"]= dialog; 0354 } 0355 0356 ////////////////////////////////////////////////////// 0357 // 0358 // 0359 // 0360 ///////////////////////////////////////////////////// 0361 ButtonCanvas::ButtonCanvas() : m_rect(QRectF(0, 0, SQUARE_SIZE * 2, SQUARE_SIZE * 2)) 0362 { 0363 setAcceptedMouseButtons(Qt::LeftButton); 0364 setFlags(QGraphicsItem::ItemIsSelectable | QGraphicsItem::ItemIsFocusable); 0365 } 0366 0367 QRectF ButtonCanvas::boundingRect() const 0368 { 0369 return m_rect; 0370 } 0371 0372 void ButtonCanvas::paint(QPainter* painter, const QStyleOptionGraphicsItem*, QWidget*) 0373 { 0374 painter->save(); 0375 painter->fillRect(boundingRect(), Qt::cyan); 0376 painter->setPen(Qt::black); 0377 painter->drawRect(boundingRect()); 0378 painter->drawText(boundingRect(), Qt::AlignCenter, m_msg); 0379 painter->restore(); 0380 } 0381 0382 QString ButtonCanvas::msg() const 0383 { 0384 return m_msg; 0385 } 0386 0387 void ButtonCanvas::setMsg(const QString& msg) 0388 { 0389 m_msg= msg; 0390 } 0391 0392 void ButtonCanvas::mousePressEvent(QGraphicsSceneMouseEvent* event) 0393 { 0394 if(event->buttons() & Qt::LeftButton) 0395 { 0396 if(boundingRect().contains(event->pos())) 0397 { 0398 emit clicked(); 0399 } 0400 } 0401 else 0402 { 0403 QGraphicsObject::mousePressEvent(event); 0404 } 0405 } 0406 0407 QRectF ButtonCanvas::rect() const 0408 { 0409 return m_rect; 0410 } 0411 0412 void ButtonCanvas::setRect(const QRectF& rect) 0413 { 0414 m_rect= rect; 0415 }