File indexing completed on 2025-02-02 04:11:32

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 "composition_tab_bar.hpp"
0008 
0009 #include <QMenu>
0010 #include <QIcon>
0011 #include <QSignalBlocker>
0012 #include <QInputDialog>
0013 
0014 #include "model/assets/assets.hpp"
0015 #include "command/object_list_commands.hpp"
0016 
0017 #include "widgets/tab_bar/tab_bar_close_button.hpp"
0018 
0019 using namespace glaxnimate::gui;
0020 using namespace glaxnimate;
0021 
0022 
0023 CompositionTabBar::CompositionTabBar(QWidget* parent)
0024     : ClickableTabBar(parent)
0025 {
0026     setDocumentMode(true);
0027     setExpanding(false);
0028     setAutoHide(true);
0029     setDrawBase(false);
0030 
0031     connect(this, &QTabBar::currentChanged, this, &CompositionTabBar::fw_switch);
0032     connect(this, &QTabBar::tabCloseRequested, this, &CompositionTabBar::on_close);
0033     connect(this, &ClickableTabBar::context_menu_requested, this, &CompositionTabBar::on_menu);
0034 }
0035 
0036 model::Composition * CompositionTabBar::index_to_comp(int index) const
0037 {
0038     if ( !document || index < 0 || index >= document->assets()->compositions->values.size() )
0039         return nullptr;
0040 
0041     return document->assets()->compositions->values[index];
0042 }
0043 
0044 void CompositionTabBar::fw_switch(int i)
0045 {
0046     if ( auto comp = index_to_comp(i) )
0047         Q_EMIT switch_composition(comp, i);
0048 }
0049 
0050 void CompositionTabBar::on_close(int index)
0051 {
0052     if ( document && index >= 0 && index < document->assets()->compositions->values.size() )
0053     {
0054         document->push_command(new command::RemoveObject<model::Composition>(
0055             index, &document->assets()->compositions->values
0056         ));
0057     }
0058 }
0059 
0060 void CompositionTabBar::on_menu(int index)
0061 {
0062     if ( auto precomp = index_to_comp(index) )
0063     {
0064         QMenu menu;
0065         menu.addSection(precomp->object_name());
0066         menu.addAction(QIcon::fromTheme("edit-delete"), i18n("Delete"), precomp, [this, index]{
0067             on_close(index);
0068         });
0069         menu.addAction(QIcon::fromTheme("edit-duplicate"), i18n("Duplicate"), precomp, [this, precomp]{
0070             std::unique_ptr<model::Composition> new_comp (
0071                 static_cast<model::Composition*>(precomp->clone().release())
0072             );
0073             new_comp->recursive_rename();
0074             new_comp->set_time(document->current_time());
0075 
0076             document->push_command(
0077                 new command::AddObject(
0078                     &document->assets()->compositions->values,
0079                     std::move(new_comp),
0080                     -1,
0081                     nullptr,
0082                     i18n("Duplicate %1", precomp->object_name())
0083                 )
0084             );
0085         });
0086         menu.addAction(QIcon::fromTheme("edit-rename"), i18n("Rename"), precomp, [this, precomp]{
0087             bool ok = false;
0088             QString str = QInputDialog::getText(
0089                 this, i18n("Rename Composition"), i18n("Name"), QLineEdit::Normal,
0090                 precomp->object_name(), &ok
0091             );
0092             if ( ok )
0093                 precomp->name.set_undoable(str);
0094         });
0095 
0096         menu.exec(QCursor::pos());
0097     }
0098 }
0099 
0100 void CompositionTabBar::set_document(model::Document* document)
0101 {
0102     QSignalBlocker guard(this);
0103 
0104     if ( this->document )
0105     {
0106         disconnect(this->document->assets()->compositions.get(), nullptr, this, nullptr);
0107     }
0108 
0109     while ( count() )
0110         removeTab(0);
0111 
0112     this->document = document;
0113 
0114     if ( document )
0115     {
0116         for ( int i = 0; i < document->assets()->compositions->values.size(); i++ )
0117             setup_composition(document->assets()->compositions->values[i], i);
0118 
0119         connect(document->assets()->compositions.get(), &model::CompositionList::docnode_child_remove_begin, this, &CompositionTabBar::on_precomp_removed);
0120         connect(document->assets()->compositions.get(), &model::CompositionList::precomp_added, this, [this](model::Composition* node, int row){setup_composition(node, row+1);});
0121     }
0122 }
0123 
0124 void CompositionTabBar::setup_composition(model::Composition* comp, int index)
0125 {
0126     index = insertTab(index, comp->tree_icon(), comp->object_name());
0127     update_comp_color(index, comp);
0128 
0129     connect(comp, &model::DocumentNode::name_changed, this, [this, index, comp](){
0130         setTabText(index, comp->object_name());
0131     });
0132     connect(comp, &model::VisualNode::docnode_group_color_changed, this, [this, index, comp](){
0133         update_comp_color(index, comp);
0134     });
0135 }
0136 
0137 void CompositionTabBar::update_comp_color(int index, model::Composition* comp)
0138 {
0139     QColor c = comp->group_color.get();
0140     if ( c.alpha() == 0 )
0141         c = palette().text().color();
0142     else
0143         c.setAlpha(255);
0144 
0145     setTabTextColor(index, c);
0146 }
0147 
0148 void CompositionTabBar::set_current_composition(model::Composition* comp)
0149 {
0150     int index = document->assets()->compositions->values.index_of(comp);
0151     setCurrentIndex(index);
0152 }
0153 
0154 void CompositionTabBar::on_precomp_removed(int index)
0155 {
0156     if ( currentIndex() == index )
0157         setCurrentIndex(0);
0158 
0159     removeTab(index);
0160 }