diff --git a/plugins/dockers/storyboarddocker/CMakeLists.txt b/plugins/dockers/storyboarddocker/CMakeLists.txt index 8251044aca..00a42f89c6 100644 --- a/plugins/dockers/storyboarddocker/CMakeLists.txt +++ b/plugins/dockers/storyboarddocker/CMakeLists.txt @@ -1,32 +1,34 @@ #add_subdirectory(tests) set(KRITA_STORYBOARDDOCKER_SOURCES commentModel.cpp storyboarddocker.cpp storyboarddocker_dock.cpp commentDelegate.cpp storyboardModel.cpp storyboardItem.cpp storyboardDelegate.cpp + storyboardView.cpp ) set(KRITA_STORYBOARDDOCKER_PART_HEADERS commentModel.h storyboarddocker.h storyboarddocker_dock.h commentDelegate.h storyboardModel.h storyboardItem.h storyboardDelegate.h + storyboardView.h ) ki18n_wrap_ui(KRITA_STORYBOARDDOCKER_SOURCES wdgstoryboarddock.ui wdgarrangemenu.ui wdgcommentmenu.ui ) add_library(kritastoryboarddocker MODULE ${KRITA_STORYBOARDDOCKER_SOURCES} ${KRITA_STORYBOARDDOCKER_PART_HEADERS} ) target_link_libraries(kritastoryboarddocker kritaui) install(TARGETS kritastoryboarddocker DESTINATION ${KRITA_PLUGIN_INSTALL_DIR}) diff --git a/plugins/dockers/storyboarddocker/storyboardDelegate.cpp b/plugins/dockers/storyboarddocker/storyboardDelegate.cpp index f15f5aa7ea..76d8b9c7a2 100644 --- a/plugins/dockers/storyboarddocker/storyboardDelegate.cpp +++ b/plugins/dockers/storyboarddocker/storyboardDelegate.cpp @@ -1,228 +1,226 @@ /* * Copyright (c) 2020 Saurabh Kumar * * 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 should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "storyboardDelegate.h" #include #include #include #include #include #include #include #include #include #include "storyboardModel.h" StoryboardDelegate::StoryboardDelegate(QObject *parent) : QStyledItemDelegate(parent) { } StoryboardDelegate::~StoryboardDelegate() { } void StoryboardDelegate::paint(QPainter *p, const QStyleOptionViewItem &option, const QModelIndex &index) const { p->save(); { QStyle *style = option.widget ? option.widget->style() : QApplication::style(); style->drawPrimitive(QStyle::PE_PanelItemViewItem, &option, p, option.widget); p->setFont(option.font); if (!index.isValid()){ p->restore(); return; } if (!index.parent().isValid()){ - QRect parentRect = option.rect; QSize cellSize = sizeHint(option, index); parentRect.setSize(cellSize); p->drawRect(parentRect); - QSize itemSize = QSize(190, 240); - parentRect.translate(5 + (cellSize.width() - itemSize.width())/2, 5); - parentRect.setSize(itemSize); + //draw frame number rect + parentRect.setTopLeft(parentRect.topLeft() + QPoint(5, 5)); + } + else{ + //paint Child index (the indices that hold data) + QModelIndex parent = index.parent(); //draw the child items - const QAbstractItemModel *model = index.model(); - for (int row = 0; row < model->rowCount(); row++){ - QModelIndex childIndex = model->index(row, 0, index); - switch (row) + int rowNum = index.model()->rowCount(parent); + int childNum = index.row(); + QString data = index.model()->data(index, Qt::DisplayRole).toString(); + + switch (childNum) + { + case 0: + { + QRect frameNumRect = option.rect; + frameNumRect.setHeight(m_view->fontMetrics().height()+3); + frameNumRect.setWidth(3 * m_view->fontMetrics().width("0")+2); + frameNumRect.moveBottom(option.rect.top()-1); + p->drawRect(frameNumRect); + p->drawText(frameNumRect, Qt::AlignHCenter | Qt::AlignVCenter, data); + + QIcon icon = KisIconUtils::loadIcon("krita-base"); + icon.paint(p, option.rect); + p->drawRect(option.rect); + break; + } + case 1: + { + QRect itemNameRect = option.rect; + itemNameRect.setLeft(option.rect.left() + 5); + p->drawText(itemNameRect, Qt::AlignLeft | Qt::AlignVCenter, data); + p->drawRect(option.rect); + break; + } + case 2: + { + p->drawText(option.rect, Qt::AlignHCenter | Qt::AlignVCenter, data); + //TODO: draw spin boxes + p->drawRect(option.rect); + break; + } + case 3: //frame duration + { + p->drawText(option.rect, Qt::AlignHCenter | Qt::AlignVCenter, data); + //TODO: draw spin boxes. + p->drawRect(option.rect); + break; + } + default: { - case 0: - { - int frameNum = model->data(childIndex, Qt::DisplayRole).toInt(); - QString value = QString::number(frameNum); - - QRect frameRect = parentRect; - - frameRect.setHeight(20); - p->drawRect(frameRect); - frameRect.setWidth(20); - p->drawRect(frameRect); - - frameRect.translate(5,5); - frameRect.setSize(QSize(10,15)); - p->drawText(frameRect, Qt::AlignLeft | Qt::AlignVCenter, value); - - //drawImage rect - QRect imageRect = parentRect; - imageRect.translate(0,20); - imageRect.setHeight(115); - p->drawRect(imageRect); - - //draw image(placeholder for now) - QIcon icon = KisIconUtils::loadIcon("krita-base"); - icon.paint(p, imageRect); - break; - //drawFrame(p, option, index, parentRect); - - } - case 1: - { - QString itemName = model->data(childIndex, Qt::DisplayRole).toString(); - QRect nameRect = parentRect; - - nameRect.setSize(QSize(120, 20)); - nameRect.translate(20, 0); - p->drawRect(nameRect); - nameRect.setWidth(110); - p->drawText(nameRect, Qt::AlignRight | Qt::AlignVCenter, itemName); - - break; - //drawItemName(p, option, index); - } - case 2: - { - int duration = model->data(childIndex, Qt::DisplayRole).toInt(); - QRect durationRect = parentRect; - - durationRect.setSize(QSize(50, 20)); - durationRect.translate(140, 0); - - QStyleOptionSpinBox opt; - opt.rect = durationRect; - opt.state = option.state; - style->drawComplexControl(QStyle::CC_SpinBox, &opt, p, option.widget); - break; - } //drawDuration() - default: - { - QString comment = model->data(childIndex, Qt::DisplayRole).toString(); - //should we use Qt::TextWordWrap ?? - } + p->drawRect(option.rect); + break; } } } } p->restore(); } QSize StoryboardDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const { if (!index.parent().isValid()){ int width = option.widget->width() - 17; + const StoryboardModel* model = dynamic_cast(index.model()); + int numComments = model->commentCount(); int numItem = width/200; - int spacingItem = (width - numItem*200) / (numItem + 1); - if (option.Middle){ - return QSize(200 + spacingItem, 250); - } - else{ - return QSize(200 + (3 * spacingItem)/2, 250); + if(numItem <=0){ + return QSize(0, 0); } + return QSize(width / numItem, 140 + numComments*100); + //return QSize(200,250); + } + else { + return option.rect.size(); } - /* - else if (!index.parent().parent().isValid()){ - - }*/ return QSize(0,0); } /* QWidget *StoryboardDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option , const QModelIndex &index) const { - //QLineEdit *editor = new QLineEdit(parent); - //return editor; + //only create editor for children + if (index.parent().isValid()){ + int row = index.row(); + switch (row) + { + case 0: + case 2: //we handle spinbox edit event separately + { + return nullptr; + } + default: // for itemName and comments + { + QLineEdit *editor = new QLineEdit(parent); + return editor; + } + } + } + return nullptr; } bool StoryboardDelegate::editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index) { QStyleOptionViewItem newOption = option; if ((event->type() == QEvent::MouseButtonPress || event->type() == QEvent::MouseButtonDblClick) && (index.flags() & Qt::ItemIsEnabled)) { QMouseEvent *mouseEvent = static_cast(event); + //handle the duration edit event + if (index.row() == 2){ + } QRect visibilityRect = option.rect; visibilityRect.setSize(QSize(22, 22)); const bool visibilityClicked = visibilityRect.isValid() && visibilityRect.contains(mouseEvent->pos()); const bool leftButton = mouseEvent->buttons() & Qt::LeftButton; if (leftButton && visibilityClicked) { model->setData(index, true, Qt::DecorationRole); return true; } } return false; } //set the existing data in the editor void StoryboardDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const { QString value = index.model()->data(index, Qt::EditRole).toString(); QLineEdit *lineEdit = static_cast(editor); lineEdit->setText(value); } void StoryboardDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const { QLineEdit *lineEdit = static_cast(editor); QString value = lineEdit->text(); //don't add empty string model->setData(index, value, Qt::EditRole); //do we need to emit closeEditor() ??? } void StoryboardDelegate::updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const { editor->setGeometry(option.rect); qDebug()<<"setting geometry"; } */ - void StoryboardDelegate::setView(QListView *view){ m_view = view; } \ No newline at end of file diff --git a/plugins/dockers/storyboarddocker/storyboardDelegate.h b/plugins/dockers/storyboarddocker/storyboardDelegate.h index 5132466a8b..28a4026664 100644 --- a/plugins/dockers/storyboarddocker/storyboardDelegate.h +++ b/plugins/dockers/storyboarddocker/storyboardDelegate.h @@ -1,58 +1,54 @@ /* * Copyright (c) 2020 Saurabh Kumar * * 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 should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __STORYBOARD_DELEGATE_H #define __STORYBOARD_DELEGATE_H #include class QListView; class StoryboardModel; class StoryboardDelegate : public QStyledItemDelegate { public: StoryboardDelegate(QObject *parent); ~StoryboardDelegate() override; - //display functions void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const override; QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const override; - /* bool editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index); - //editor functions. QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const; void setEditorData(QWidget *editor, const QModelIndex &index) const; void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const; void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const; */ - void setView(QListView *view); private: QListView *m_view; }; #endif diff --git a/plugins/dockers/storyboarddocker/storyboardItem.cpp b/plugins/dockers/storyboarddocker/storyboardItem.cpp index e8aeb96590..5284d9435f 100644 --- a/plugins/dockers/storyboarddocker/storyboardItem.cpp +++ b/plugins/dockers/storyboarddocker/storyboardItem.cpp @@ -1,61 +1,62 @@ /* * Copyright (c) 2020 Saurabh Kumar * * 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 should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "storyboardItem.h" //create 3 rows by default StoryboardItem::StoryboardItem() { insertChild(childCount(), 1); insertChild(childCount(), QString("scene 1")); - insertChild(childCount(), 100); + insertChild(childCount(), 100); //duration-seconds + insertChild(childCount(), 23); //duration-frames } StoryboardItem::~StoryboardItem() { qDeleteAll(m_childData); } void StoryboardItem::appendChild(QVariant data) { StoryboardChild* child = new StoryboardChild(data, this); m_childData.append(child); } void StoryboardItem::insertChild(int row, QVariant data) { StoryboardChild* child = new StoryboardChild(data, this); m_childData.insert(row, child); } void StoryboardItem::removeChild(int row) { m_childData.removeAt(row); } int StoryboardItem::childCount() const { return m_childData.count(); } StoryboardChild* StoryboardItem::child(int row) { if (row < 0 || row >= m_childData.size()) return nullptr; return m_childData.at(row); } diff --git a/plugins/dockers/storyboarddocker/storyboardModel.cpp b/plugins/dockers/storyboarddocker/storyboardModel.cpp index e2090d363b..2185590310 100644 --- a/plugins/dockers/storyboarddocker/storyboardModel.cpp +++ b/plugins/dockers/storyboarddocker/storyboardModel.cpp @@ -1,216 +1,225 @@ /* * Copyright (c) 2020 Saurabh Kumar * * 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 should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "storyboardModel.h" #include #include StoryboardModel::StoryboardModel(QObject *parent) : QAbstractItemModel(parent) + , m_commentCount(1) //dummy value {} QModelIndex StoryboardModel::index(int row, int column, const QModelIndex &parent) const { if (!hasIndex(row, column, parent)) return QModelIndex(); if (row < 0 || row >= rowCount()) return QModelIndex(); if (column !=0) return QModelIndex(); //1st level node has invalid parent if (!parent.isValid()){ return createIndex(row, column, m_items.at(row)); } else if (!parent.parent().isValid()){ StoryboardItem *parentItem = static_cast(parent.internalPointer()); StoryboardChild *childItem = parentItem->child(row); if (childItem) return createIndex(row, column, childItem); } return QModelIndex(); } QModelIndex StoryboardModel::parent(const QModelIndex &index) const { if (!index.isValid()) return QModelIndex(); { //no parent for 1st level node StoryboardItem *childItem = static_cast(index.internalPointer()); if (m_items.contains(childItem)){ return QModelIndex(); } } //return parent only for 2nd level nodes StoryboardChild *childItem = static_cast(index.internalPointer()); StoryboardItem *parentItem = childItem->parent(); int indexOfParent = m_items.indexOf(const_cast(parentItem)); return createIndex(indexOfParent, 0, parentItem); } int StoryboardModel::rowCount(const QModelIndex &parent) const { if (!parent.isValid()) return m_items.count(); else if (!parent.parent().isValid()){ StoryboardItem *parentItem = static_cast(parent.internalPointer()); return parentItem->childCount(); } return 0; //2nd level nodes have no child } int StoryboardModel::columnCount(const QModelIndex &parent) const { if (!parent.isValid()){ return 1; } //1st level nodes have 1 column if (!parent.parent().isValid()){ return 1; } //end level nodes have no child return 0; } QVariant StoryboardModel::data(const QModelIndex &index, int role) const { if (!index.isValid()) return QVariant(); if (index.row() >= m_items.size()) return QVariant(); if(role == Qt::SizeHintRole){ return QSize(200,200); } //return data only for the storyboardChild i.e. 2nd level nodes if (!index.parent().isValid()){ return QVariant(); } if (role == Qt::DisplayRole || role == Qt::EditRole) { StoryboardChild *child = static_cast(index.internalPointer()); return child->data(); } return QVariant(); } bool StoryboardModel::setData(const QModelIndex & index, const QVariant & value, int role) { //qDebug()<<"attempting data set"<(index.internalPointer()); if (child){ + int fps = 24; + if(index.row() == 3 && value.toInt() >= fps){ //TODO : set fps + setData(index.siblingAtRow(2), value.toInt() / fps, role); + child->setData(value.toInt() % fps); + } + else { + child->setData(value); + } child->setData(value); emit dataChanged(index, index); return true; } } return false; } Qt::ItemFlags StoryboardModel::flags(const QModelIndex & index) const { //qDebug()<<"flags requested"; if(!index.isValid()) return Qt::ItemIsDropEnabled; //1st level nodes if (!index.parent().isValid()) return Qt::ItemIsDragEnabled | Qt::ItemIsSelectable | Qt::ItemIsEnabled; //2nd level nodes return Qt::ItemIsSelectable | Qt::ItemIsEditable | Qt::ItemIsEnabled; } bool StoryboardModel::insertRows(int position, int rows, const QModelIndex &parent) { qDebug()<<"row inserted"; if (!parent.isValid()){ beginInsertRows(QModelIndex(), position, position+rows-1); for (int row = 0; row < rows; ++row) { StoryboardItem *newItem = new StoryboardItem(); m_items.insert(position, newItem); } endInsertRows(); return true; } //insert 2nd level nodes if (!parent.parent().isValid()){ StoryboardItem *item = static_cast(parent.internalPointer()); beginInsertRows(QModelIndex(), position, position+rows-1); for (int row = 0; row < rows; ++row) { item->insertChild(position, QVariant()); } endInsertRows(); return true; } //we can't insert to 2nd level nodes as they are leaf nodes return false; } bool StoryboardModel::removeRows(int position, int rows, const QModelIndex &parent) { qDebug()<<"row removed"; //remove 1st level nodes if (!parent.isValid()){ beginRemoveRows(QModelIndex(), position, position+rows-1); for (int row = 0; row < rows; ++row) { delete m_items.at(row); m_items.removeAt(position); } endRemoveRows(); return true; } //remove 2nd level nodes if (!parent.parent().isValid()){ StoryboardItem *item = static_cast(parent.internalPointer()); if (m_items.contains(item)){ beginRemoveRows(QModelIndex(), position, position+rows-1); for (int row = 0; row < rows; ++row) { item->removeChild(position); } endRemoveRows(); return true; } } //2nd level node has no child return false; } Qt::DropActions StoryboardModel::supportedDropActions() const { return Qt::CopyAction | Qt::MoveAction; } Qt::DropActions StoryboardModel::supportedDragActions() const { return Qt::CopyAction | Qt::MoveAction; } diff --git a/plugins/dockers/storyboarddocker/storyboardModel.h b/plugins/dockers/storyboarddocker/storyboardModel.h index afbd957156..248325c557 100644 --- a/plugins/dockers/storyboarddocker/storyboardModel.h +++ b/plugins/dockers/storyboarddocker/storyboardModel.h @@ -1,65 +1,67 @@ /* * Copyright (c) 2020 Saurabh Kumar * * 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 should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef STORYBOARD_MODEL #define STORYBOARD_MODEL #include #include #include "storyboardItem.h" /* The main storyboard model. */ class StoryboardModel : public QAbstractItemModel { Q_OBJECT public: //if we don't need this constructor change it StoryboardModel(QObject *parent = nullptr); QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const override; QModelIndex parent(const QModelIndex &index) const override; int rowCount(const QModelIndex &parent = QModelIndex()) const override; int columnCount(const QModelIndex &parent = QModelIndex()) const override; QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override; //QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override; Qt::ItemFlags flags(const QModelIndex &index) const override; //for removing and inserting rows bool insertRows(int position, int rows, const QModelIndex &index = QModelIndex()); bool removeRows(int position, int rows, const QModelIndex &index = QModelIndex()); //for drag and drop Qt::DropActions supportedDropActions() const override; Qt::DropActions supportedDragActions() const override; //this function accesses the value from the comment model - int commentCount(); + int commentCount() const { + return m_commentCount; + } private: QVector m_items; int m_commentCount = 0; }; #endif \ No newline at end of file diff --git a/plugins/dockers/storyboarddocker/storyboardView.cpp b/plugins/dockers/storyboarddocker/storyboardView.cpp new file mode 100644 index 0000000000..2ec9eb1bc3 --- /dev/null +++ b/plugins/dockers/storyboarddocker/storyboardView.cpp @@ -0,0 +1,134 @@ +/* + Copyright (c) 2020 Saurabh Kumar + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include +#include +#include + +#include "storyboardView.h" +#include "storyboardModel.h" + +/** + * This view draws the children of every index in the first column of + * the model inside the parent + * + * */ + +StoryboardView::StoryboardView(QWidget *parent) + :QListView(parent) +{ + + setWrapping(true); + setFlow(QListView::LeftToRight); + setResizeMode(QListView::Adjust); + setUniformItemSizes(true); + setVerticalScrollMode(QAbstractItemView::ScrollPerPixel); + + qDebug()<<"storyview created"; +} + +StoryboardView::~StoryboardView() +{} + +void StoryboardView::paintEvent(QPaintEvent *event) +{ + event->accept(); + QListView::paintEvent(event); + + //ask delegate to draw the child nodes too + QPainter painter(viewport()); + int itemNum = model()->rowCount(); + for (int row = 0; row < itemNum; row++){ + QModelIndex index = model()->index(row, 0); + int childNum = model()->rowCount(index); + for (int childRow = 0; childRow < childNum; childRow++){ + + QModelIndex childIndex = model()->index(childRow, 0, index); + + QStyleOptionViewItem option; + //TO DO: check if the childIndex is in focus + //TO DO: set proper options for spinbox type indices + if (selectionModel()->isSelected(index)) { + option.state |= QStyle::State_Selected; + } + if (index == selectionModel()->currentIndex()) { + option.state |= QStyle::State_HasFocus; + } + + option.rect = visualRect(childIndex); + itemDelegate()->paint(&painter, option, childIndex); + } + } + +} + +QRect StoryboardView::visualRect(const QModelIndex &index) const +{ + if (!index.isValid() || !index.parent().isValid()){ + return QListView::visualRect(index); + } + else { + QRect parentRect = visualRect(index.parent()); + parentRect.setTopLeft(parentRect.topLeft() + QPoint(5, 5)); + parentRect.setBottomRight(parentRect.bottomRight() - QPoint(5, 5)); + int fontHeight = fontMetrics().height() + 3; + int numericFontWidth = fontMetrics().width("0"); + int height = parentRect.height(); + int width = parentRect.width(); + int childRow = index.row(); + switch (childRow) + { + case 0: + { + //the frame thumbnail rect + parentRect.setSize(QSize(width, 120)); + parentRect.translate(0, fontHeight); + return parentRect; + } + case 1: + { + QRect itemNameRect = parentRect; + itemNameRect.setSize(QSize(width - (10 * numericFontWidth + 6), fontHeight)); + itemNameRect.moveLeft(parentRect.left() + 3*numericFontWidth + 2); + return itemNameRect; + } + case 2: + { + QRect secondRect = parentRect; + secondRect.setSize(QSize(4 * numericFontWidth + 2, fontHeight)); + secondRect.moveRight(parentRect.right() - 3*numericFontWidth -2); + return secondRect; + } + case 3: + { + QRect frameRect = parentRect; + frameRect.setSize(QSize(3 * numericFontWidth + 2, fontHeight)); + frameRect.moveRight(parentRect.right()); + return frameRect; + } + default: + { + //comment rect + parentRect.setTop(parentRect.top() + 120+fontHeight); + return parentRect; + } + } + } + return QRect(); +} diff --git a/plugins/dockers/storyboarddocker/storyboardView.h b/plugins/dockers/storyboarddocker/storyboardView.h new file mode 100644 index 0000000000..8b70e92570 --- /dev/null +++ b/plugins/dockers/storyboarddocker/storyboardView.h @@ -0,0 +1,47 @@ +/* + Copyright (c) 2020 Saurabh Kumar + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef STORYBOARD_VIEW_H +#define STORYBOARD_VIEW_H + +#include +#include + +class QStyleOptionViewItem; +class StoryboardModel; + +/** + * This view draws the children of every index in the first column of + * the model inside the parent index + * + * */ + +class StoryboardView: public QListView +{ + Q_OBJECT +public: + explicit StoryboardView(QWidget *parent = 0); + ~StoryboardView() override; + + void paintEvent(QPaintEvent *event) override; + QRect visualRect(const QModelIndex &index) const override; + +}; + +#endif diff --git a/plugins/dockers/storyboarddocker/storyboarddocker_dock.cpp b/plugins/dockers/storyboarddocker/storyboarddocker_dock.cpp index 184c75c34b..5b35b7cb04 100644 --- a/plugins/dockers/storyboarddocker/storyboarddocker_dock.cpp +++ b/plugins/dockers/storyboarddocker/storyboarddocker_dock.cpp @@ -1,244 +1,238 @@ /* * Copyright (c) 2020 Saurabh Kumar * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 2 of the License, or * (at your option) any later version. * * This library 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "storyboarddocker_dock.h" #include "commentDelegate.h" #include "commentModel.h" #include "storyboardModel.h" #include "storyboardDelegate.h" #include #include #include #include #include #include #include #include #include #include #include "ui_wdgstoryboarddock.h" #include "ui_wdgcommentmenu.h" #include "ui_wdgarrangemenu.h" class CommentMenu: public QMenu { Q_OBJECT public: CommentMenu(QWidget *parent) : QMenu(parent) , m_menuUI(new Ui_WdgCommentMenu()) , model(new CommentModel(this)) , delegate(new CommentDelegate(this)) { QWidget* commentWidget = new QWidget(this); m_menuUI->setupUi(commentWidget); m_menuUI->fieldListView->setDragEnabled(true); m_menuUI->fieldListView->setAcceptDrops(true); m_menuUI->fieldListView->setDropIndicatorShown(true); m_menuUI->fieldListView->setDragDropMode(QAbstractItemView::InternalMove); m_menuUI->fieldListView->setModel(model); m_menuUI->fieldListView->setItemDelegate(delegate); m_menuUI->fieldListView->setEditTriggers(QAbstractItemView::AnyKeyPressed | QAbstractItemView::DoubleClicked ); m_menuUI->btnAddField->setIcon(KisIconUtils::loadIcon("list-add")); m_menuUI->btnDeleteField->setIcon(KisIconUtils::loadIcon("trash-empty")); m_menuUI->btnAddField->setIconSize(QSize(22, 22)); m_menuUI->btnDeleteField->setIconSize(QSize(22, 22)); connect(m_menuUI->btnAddField, SIGNAL(clicked()), this, SLOT(slotaddItem())); connect(m_menuUI->btnDeleteField, SIGNAL(clicked()), this, SLOT(slotdeleteItem())); KisAction *commentAction = new KisAction(commentWidget); commentAction->setDefaultWidget(commentWidget); this->addAction(commentAction); } private Q_SLOTS: void slotaddItem() { int row = m_menuUI->fieldListView->currentIndex().row()+1; model->insertRows(row, 1); QModelIndex index = model->index(row); m_menuUI->fieldListView->setCurrentIndex(index); m_menuUI->fieldListView->edit(index); } void slotdeleteItem() { model->removeRows(m_menuUI->fieldListView->currentIndex().row(), 1); } private: QScopedPointer m_menuUI; CommentModel *model; CommentDelegate *delegate; }; class ArrangeMenu: public QMenu { public: ArrangeMenu(QWidget *parent) : QMenu(parent) , m_menuUI(new Ui_WdgArrangeMenu()) , modeGroup(new QButtonGroup(this)) , viewGroup(new QButtonGroup(this)) { QWidget* arrangeWidget = new QWidget(this); m_menuUI->setupUi(arrangeWidget); modeGroup->addButton(m_menuUI->btnColumnMode, Qt::FlatCap); modeGroup->addButton(m_menuUI->btnRowMode, Qt::FlatCap); modeGroup->addButton(m_menuUI->btnGridMode, Qt::FlatCap); viewGroup->addButton(m_menuUI->btnAllView, Qt::FlatCap); viewGroup->addButton(m_menuUI->btnThumbnailsView, Qt::FlatCap); viewGroup->addButton(m_menuUI->btnCommentsView, Qt::FlatCap); KisAction *arrangeAction = new KisAction(arrangeWidget); arrangeAction->setDefaultWidget(arrangeWidget); this->addAction(arrangeAction); } QButtonGroup* getModeGroup(){ return modeGroup;} QButtonGroup* getViewGroup(){ return viewGroup;} private: QScopedPointer m_menuUI; QButtonGroup *modeGroup; QButtonGroup *viewGroup; }; StoryboardDockerDock::StoryboardDockerDock( ) : QDockWidget(i18n("Storyboard")) , m_ui(new Ui_WdgStoryboardDock()) { QWidget* mainWidget = new QWidget(this); setWidget(mainWidget); m_ui->setupUi(mainWidget); m_exportMenu = new QMenu(this); m_ui->btnExport->setMenu(m_exportMenu); m_ui->btnExport->setPopupMode(QToolButton::MenuButtonPopup); m_exportAsPdfAction = new KisAction("Export as PDF", m_exportMenu); m_exportMenu->addAction(m_exportAsPdfAction); m_exportAsSvgAction = new KisAction("Export as SVG"); m_exportMenu->addAction(m_exportAsSvgAction); connect(m_exportAsPdfAction, SIGNAL(triggered()), this, SLOT(slotExportAsPdf())); connect(m_exportAsSvgAction, SIGNAL(triggered()), this, SLOT(slotExportAsSvg())); m_commentMenu = new CommentMenu(this); m_ui->btnComment->setMenu(m_commentMenu); m_ui->btnComment->setPopupMode(QToolButton::MenuButtonPopup); m_lockAction = new KisAction(KisIconUtils::loadIcon("unlocked"), "Lock", m_ui->btnLock); m_lockAction->setCheckable(true); m_ui->btnLock->setDefaultAction(m_lockAction); m_ui->btnLock->setIconSize(QSize(22, 22)); connect(m_lockAction, SIGNAL(toggled(bool)), this, SLOT(slotLockClicked(bool))); m_arrangeMenu = new ArrangeMenu(this); m_ui->btnArrange->setMenu(m_arrangeMenu); m_ui->btnArrange->setPopupMode(QToolButton::InstantPopup); m_ui->btnArrange->setIcon(KisIconUtils::loadIcon("view-choose")); m_ui->btnArrange->setIconSize(QSize(22, 22)); m_modeGroup = m_arrangeMenu->getModeGroup(); m_viewGroup = m_arrangeMenu->getViewGroup(); connect(m_modeGroup, SIGNAL(buttonClicked(QAbstractButton*)), this, SLOT(slotModeChanged(QAbstractButton*))); connect(m_viewGroup, SIGNAL(buttonClicked(QAbstractButton*)), this, SLOT(slotViewChanged(QAbstractButton*))); StoryboardModel *model = new StoryboardModel(this); StoryboardDelegate *delegate = new StoryboardDelegate(this); delegate->setView(m_ui->listView); m_ui->listView->setModel(model); m_ui->listView->setItemDelegate(delegate); delegate->setView(m_ui->listView); model->insertRows(0, 10); - - m_ui->listView->setWrapping(true); - m_ui->listView->setFlow(QListView::LeftToRight); - m_ui->listView->setResizeMode(QListView::Adjust); - m_ui->listView->setUniformItemSizes(true); - m_ui->listView->setVerticalScrollMode(QAbstractItemView::ScrollPerPixel); } StoryboardDockerDock::~StoryboardDockerDock() { } void StoryboardDockerDock::setCanvas(KoCanvasBase *canvas) { } void StoryboardDockerDock::setViewManager(KisViewManager* kisview) { } void StoryboardDockerDock::slotExportAsPdf() { qDebug()<<"export as pdf"; slotExport("pdf"); } void StoryboardDockerDock::slotExportAsSvg() { qDebug()<<"export as svg"; slotExport("svg"); } void StoryboardDockerDock::slotExport(QString mode) { qDebug()<<"mode is "<setIcon(KisIconUtils::loadIcon("locked")); } else{ m_lockAction->setIcon(KisIconUtils::loadIcon("unlocked")); } } void StoryboardDockerDock::slotModeChanged(QAbstractButton* button) { qDebug()<<"Mode changed to "<text(); } void StoryboardDockerDock::slotViewChanged(QAbstractButton* button) { qDebug()<<"View changed to "<text(); } #include "storyboarddocker_dock.moc" \ No newline at end of file diff --git a/plugins/dockers/storyboarddocker/wdgstoryboarddock.ui b/plugins/dockers/storyboarddocker/wdgstoryboarddock.ui index 0f23a42abd..031d28d6cc 100644 --- a/plugins/dockers/storyboarddocker/wdgstoryboarddock.ui +++ b/plugins/dockers/storyboarddocker/wdgstoryboarddock.ui @@ -1,104 +1,111 @@ WdgStoryboardDock 0 0 604 561 Form Export true Comments true Qt::Horizontal 40 20 true Lock false false Qt::ToolButtonIconOnly true Mode true Qt::NoArrow - + + + + StoryboardView + QListView +
storyboardView.h
+
+