File indexing completed on 2025-02-02 04:11:26
0001 /* 0002 * SPDX-FileCopyrightText: 2019-2023 Mattia Basaglia <dev@dragon.best> 0003 * 0004 * SPDX-License-Identifier: GPL-3.0-or-later 0005 */ 0006 0007 #include "layer_view.hpp" 0008 0009 #include <QHeaderView> 0010 0011 #include <QtColorWidgets/ColorDelegate> 0012 0013 #include "item_models/document_node_model.hpp" 0014 #include "item_models/comp_filter_model.hpp" 0015 0016 0017 using namespace glaxnimate::gui; 0018 0019 0020 class glaxnimate::gui::LayerView::Private 0021 { 0022 public: 0023 item_models::DocumentModelBase* base_model; 0024 item_models::CompFilterModel proxy_model; 0025 0026 color_widgets::ColorDelegate color_delegate; 0027 }; 0028 0029 glaxnimate::gui::LayerView::LayerView(QWidget*parent) 0030 : CustomTreeView(parent), d(std::make_unique<Private>()) 0031 { 0032 header()->setStretchLastSection(false); 0033 setHeaderHidden(true); 0034 setDragDropMode(InternalMove); 0035 setDragEnabled(true); 0036 } 0037 0038 glaxnimate::gui::LayerView::~LayerView() = default; 0039 0040 item_models::DocumentModelBase * glaxnimate::gui::LayerView::base_model() const 0041 { 0042 return d->base_model; 0043 } 0044 0045 void glaxnimate::gui::LayerView::set_base_model(item_models::DocumentModelBase* base_model) 0046 { 0047 d->base_model = base_model; 0048 d->proxy_model.setSourceModel(base_model); 0049 0050 0051 setModel(&d->proxy_model); 0052 0053 header()->setSectionResizeMode(item_models::DocumentNodeModel::ColumnName, QHeaderView::Stretch); 0054 header()->setSectionResizeMode(item_models::DocumentNodeModel::ColumnColor, QHeaderView::ResizeToContents); 0055 setItemDelegateForColumn(item_models::DocumentNodeModel::ColumnColor, &d->color_delegate); 0056 header()->hideSection(item_models::DocumentNodeModel::ColumnUsers); 0057 0058 #ifdef Q_OS_ANDROID 0059 int icon_size = style()->pixelMetric(QStyle::PM_SmallIconSize, nullptr, nullptr); 0060 header()->setDefaultSectionSize(icon_size); 0061 #endif 0062 0063 connect(selectionModel(), &QItemSelectionModel::currentChanged, 0064 this, &LayerView::on_current_node_changed); 0065 connect(selectionModel(), &QItemSelectionModel::selectionChanged, 0066 this, &LayerView::on_selection_changed); 0067 } 0068 0069 0070 0071 void glaxnimate::gui::LayerView::on_current_node_changed(const QModelIndex& index) 0072 { 0073 Q_EMIT current_node_changed(d->base_model->visual_node(d->proxy_model.mapToSource(index))); 0074 } 0075 0076 void glaxnimate::gui::LayerView::on_selection_changed(const QItemSelection& selected, const QItemSelection& deselected) 0077 { 0078 std::vector<model::VisualNode*> selected_nodes; 0079 std::vector<model::VisualNode*> deselected_nodes; 0080 0081 for ( const auto& index : deselected.indexes() ) 0082 if ( index.column() == 0 ) 0083 if ( auto node = d->base_model->visual_node(d->proxy_model.mapToSource(index)) ) 0084 deselected_nodes.push_back(node); 0085 0086 for ( const auto& index : selected.indexes() ) 0087 if ( index.column() == 0 ) 0088 if ( auto node = d->base_model->visual_node(d->proxy_model.mapToSource(index)) ) 0089 selected_nodes.push_back(node); 0090 0091 Q_EMIT selection_changed(selected_nodes, deselected_nodes); 0092 } 0093 0094 void glaxnimate::gui::LayerView::set_current_node(model::DocumentNode* node) 0095 { 0096 if ( !node ) 0097 { 0098 setCurrentIndex({}); 0099 } 0100 else 0101 { 0102 auto index = d->proxy_model.mapFromSource(d->base_model->node_index(node)); 0103 setCurrentIndex(index); 0104 } 0105 } 0106 0107 glaxnimate::model::VisualNode* glaxnimate::gui::LayerView::node(const QModelIndex& index) const 0108 { 0109 return d->base_model->visual_node(d->proxy_model.mapToSource(index)); 0110 } 0111 0112 void glaxnimate::gui::LayerView::set_composition(model::Composition* comp) 0113 { 0114 d->proxy_model.set_composition(comp); 0115 } 0116 0117 glaxnimate::model::VisualNode * glaxnimate::gui::LayerView::current_node() const 0118 { 0119 return node(currentIndex()); 0120 } 0121 0122 void glaxnimate::gui::LayerView::replace_selection(model::VisualNode* node) 0123 { 0124 auto index = d->proxy_model.mapFromSource(d->base_model->node_index(node)); 0125 selectionModel()->select(index, QItemSelectionModel::ClearAndSelect); 0126 } 0127 0128 0129 void glaxnimate::gui::LayerView::update_selection(const std::vector<model::VisualNode *>& selected, const std::vector<model::VisualNode *>& deselected) 0130 { 0131 for ( model::VisualNode* node : deselected ) 0132 { 0133 selectionModel()->select( 0134 d->proxy_model.mapFromSource(d->base_model->node_index(node)), 0135 QItemSelectionModel::Deselect|QItemSelectionModel::Rows 0136 ); 0137 } 0138 0139 for ( model::VisualNode* node : selected ) 0140 { 0141 selectionModel()->select( 0142 d->proxy_model.mapFromSource(d->base_model->node_index(node)), 0143 QItemSelectionModel::Select|QItemSelectionModel::Rows 0144 ); 0145 } 0146 } 0147 0148 0149 void glaxnimate::gui::LayerView::mouseReleaseEvent(QMouseEvent * event) 0150 { 0151 CustomTreeView::mouseReleaseEvent(event); 0152 0153 if ( event->button() == Qt::LeftButton ) 0154 { 0155 auto index = indexAt(event->pos()); 0156 auto node = this->node(index); 0157 if ( !node ) 0158 return; 0159 0160 if ( index.column() == item_models::DocumentNodeModel::ColumnVisible ) 0161 node->visible.set(!node->visible.get()); 0162 else if ( index.column() == item_models::DocumentNodeModel::ColumnLocked ) 0163 node->locked.set(!node->locked.get()); 0164 } 0165 }