HierarchyMappingTable.cpp (8194B)
1 /*---------------------------------------------------------------------------------------- 2 3 Copyright (c) 2023 AUDIOKINETIC Inc. 4 5 This file is licensed to use under the license available at: 6 https://github.com/audiokinetic/ReaWwise/blob/main/License.txt (the "License"). 7 You may not use this file except in compliance with the License. 8 9 Unless required by applicable law or agreed to in writing, software distributed 10 under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 11 CONDITIONS OF ANY KIND, either express or implied. See the License for the 12 specific language governing permissions and limitations under the License. 13 14 ----------------------------------------------------------------------------------------*/ 15 16 #include "HierarchyMappingTable.h" 17 18 #include "Helpers/ImportHelper.h" 19 #include "Model/Import.h" 20 #include "Theme/CustomLookAndFeel.h" 21 22 namespace AK::WwiseTransfer 23 { 24 enum HierarchyMappingTableColumn 25 { 26 ObjectType = 1, 27 ObjectName, 28 PropertyTemplatePath 29 }; 30 31 namespace HierarchyMappingTableConstants 32 { 33 constexpr int tableHeaderHeight = 24; 34 constexpr int columnInitialWidth = 10; 35 constexpr int margin = 4; 36 inline const std::initializer_list<juce::String> tableHeaders{"Object Type", "Object Name", "Property Template Path"}; 37 constexpr int columnMinimumWidth = 10; 38 constexpr int columnMaximumWidth = 1000; 39 constexpr int defaultColumnPropertyFlags = juce::TableHeaderComponent::ColumnPropertyFlags::visible | juce::TableHeaderComponent::ColumnPropertyFlags::resizable; 40 constexpr int disabledFlag = 128; 41 } // namespace HierarchyMappingTableConstants 42 43 HierarchyMappingTable::HierarchyMappingTable(juce::ValueTree appState) 44 : applicationState(appState) 45 , hierarchyMapping(applicationState.getChildWithName(IDs::hierarchyMapping)) 46 , selectedRow(hierarchyMapping, IDs::selectedRow, nullptr) 47 , model(appState) 48 { 49 using namespace HierarchyMappingTableConstants; 50 51 auto featureSupport = appState.getChildWithName(IDs::featureSupport); 52 applyTemplateFeatureEnabled.referTo(featureSupport, IDs::applyTemplateFeatureEnabled, nullptr); 53 54 setModel(&model); 55 56 for(const auto& tableHeader : tableHeaders) 57 { 58 auto index = (&tableHeader - tableHeaders.begin()); 59 getHeader().addColumn(tableHeader, index + 1, columnInitialWidth, columnMinimumWidth, columnMaximumWidth, defaultColumnPropertyFlags); 60 } 61 62 getHeader().setPopupMenuActive(false); 63 setHeaderHeight(tableHeaderHeight); 64 applicationState.addListener(this); 65 66 selectRow(selectedRow.get()); 67 68 refreshHeader(); 69 } 70 71 HierarchyMappingTable::~HierarchyMappingTable() 72 { 73 applicationState.removeListener(this); 74 } 75 76 void HierarchyMappingTable::valueTreePropertyChanged(juce::ValueTree& treeWhosePropertyHasChanged, const juce::Identifier& property) 77 { 78 auto treeType = treeWhosePropertyHasChanged.getType(); 79 80 if(treeType == IDs::hierarchyMappingNode || treeType == IDs::hierarchyMapping && property == IDs::selectedRow) 81 { 82 repaint(); 83 } 84 85 if(treeType == IDs::featureSupport && property == IDs::applyTemplateFeatureEnabled) 86 { 87 refreshHeader(); 88 } 89 } 90 91 void HierarchyMappingTable::valueTreeChildAdded(juce::ValueTree& parentTree, juce::ValueTree& childWhichHasBeenAdded) 92 { 93 if(parentTree.getType() == IDs::hierarchyMapping) 94 { 95 updateContent(); 96 resized(); 97 98 if(parentTree.getNumChildren() == 1) 99 selectRow(0); 100 } 101 } 102 103 void HierarchyMappingTable::valueTreeChildRemoved(juce::ValueTree& parentTree, juce::ValueTree& childWhichHasBeenRemoved, int indexFromWhichChildWasRemoved) 104 { 105 if(parentTree.getType() == IDs::hierarchyMapping) 106 { 107 updateContent(); 108 resized(); 109 110 if(selectedRow == -1 && indexFromWhichChildWasRemoved != 0) 111 selectRow(indexFromWhichChildWasRemoved - 1); 112 } 113 } 114 115 void HierarchyMappingTable::valueTreeChildOrderChanged(juce::ValueTree& parentTreeWhoseChildrenHaveMoved, int oldIndex, int newIndex) 116 { 117 if(parentTreeWhoseChildrenHaveMoved.getType() == IDs::hierarchyMapping) 118 { 119 repaint(); 120 121 selectRow(newIndex); 122 } 123 } 124 125 void HierarchyMappingTable::selectedRowsChanged(int row) 126 { 127 selectedRow = row; 128 } 129 130 void HierarchyMappingTable::refreshHeader() 131 { 132 using namespace HierarchyMappingTableConstants; 133 134 // For some reason, the column width measurement only works properly if the following attribute is set to false 135 getHeader().setStretchToFitActive(false); 136 137 auto currentWidth = getHeader().getColumnWidth(tableHeaders.size()); 138 auto propertyFlags = defaultColumnPropertyFlags; 139 140 if(!applyTemplateFeatureEnabled.get()) 141 propertyFlags |= disabledFlag; 142 143 getHeader().removeColumn(tableHeaders.size()); 144 getHeader().addColumn(*(tableHeaders.end() - 1), tableHeaders.size(), currentWidth, columnMinimumWidth, columnMaximumWidth, propertyFlags); 145 146 getHeader().setStretchToFitActive(true); 147 } 148 149 HierarchyMappingTable::HierarchyMappingTableModel::HierarchyMappingTableModel(juce::ValueTree appState) 150 : hierarchyMapping(appState.getChildWithName(IDs::hierarchyMapping)) 151 { 152 auto featureSupport = appState.getChildWithName(IDs::featureSupport); 153 applyTemplateFeatureEnabled.referTo(featureSupport, IDs::applyTemplateFeatureEnabled, nullptr); 154 } 155 156 int HierarchyMappingTable::HierarchyMappingTableModel::getNumRows() 157 { 158 return hierarchyMapping.getNumChildren(); 159 } 160 161 void HierarchyMappingTable::HierarchyMappingTableModel::paintRowBackground(juce::Graphics& g, int rowNumber, int width, int height, bool rowIsSelected) 162 { 163 if(rowIsSelected) 164 g.fillAll(juce::LookAndFeel::getDefaultLookAndFeel().findColour(juce::TextEditor::highlightColourId)); 165 else 166 g.fillAll(juce::LookAndFeel::getDefaultLookAndFeel().findColour(juce::ListBox::backgroundColourId)); 167 } 168 169 void HierarchyMappingTable::HierarchyMappingTableModel::paintCell(juce::Graphics& g, int rowNumber, int columnId, int width, int height, bool rowIsSelected) 170 { 171 using namespace HierarchyMappingTableConstants; 172 173 auto hierarchyMappingNode = ImportHelper::valueTreeToHiarchyMappingNode(hierarchyMapping.getChild(rowNumber)); 174 175 juce::String text; 176 bool cellEnabled = true; 177 bool validCell = true; 178 179 switch(columnId) 180 { 181 case HierarchyMappingTableColumn::ObjectType: 182 { 183 text = hierarchyMappingNode.type == Wwise::ObjectType::Unknown ? "Select Object Type" : WwiseHelper::objectTypeToReadableString(hierarchyMappingNode.type); 184 validCell = hierarchyMappingNode.typeValid; 185 break; 186 } 187 case HierarchyMappingTableColumn::ObjectName: 188 { 189 text = hierarchyMappingNode.name; 190 validCell = hierarchyMappingNode.nameValid; 191 break; 192 } 193 case HierarchyMappingTableColumn::PropertyTemplatePath: 194 { 195 text = hierarchyMappingNode.propertyTemplatePath; 196 cellEnabled = hierarchyMappingNode.propertyTemplatePathEnabled && applyTemplateFeatureEnabled; 197 validCell = hierarchyMappingNode.propertyTemplatePathValid; 198 break; 199 } 200 } 201 202 // Cell color depends on table enablement, field enablement and field error STATE 203 auto textColor = juce::LookAndFeel::getDefaultLookAndFeel().findColour(juce::TextEditor::textColourId); 204 205 auto alpha = cellEnabled ? 1.0f : 0.5f; 206 207 g.setFont(CustomLookAndFeelConstants::smallFontSize); 208 g.setColour(textColor.withAlpha(alpha)); 209 g.drawText(text, margin, 0, width, height, juce::Justification::left); 210 211 if(cellEnabled && !validCell) 212 { 213 auto errorOutlineColor = juce::LookAndFeel::getDefaultLookAndFeel().findColour(HierarchyMappingTable::errorOutlineColor); 214 g.setColour(errorOutlineColor.withAlpha(alpha)); 215 g.drawRect(1, 1, width - 1, height - 1); 216 } 217 } 218 219 juce::String HierarchyMappingTable::HierarchyMappingTableModel::getCellTooltip(int rowNumber, int columnId) 220 { 221 juce::String tooltipText; 222 223 auto hierarchyMappingNode = ImportHelper::valueTreeToHiarchyMappingNode(hierarchyMapping.getChild(rowNumber)); 224 225 switch(columnId) 226 { 227 case HierarchyMappingTableColumn::ObjectType: 228 { 229 tooltipText = hierarchyMappingNode.typeErrorMessage; 230 break; 231 } 232 case HierarchyMappingTableColumn::ObjectName: 233 { 234 tooltipText = hierarchyMappingNode.nameErrorMessage; 235 break; 236 } 237 case HierarchyMappingTableColumn::PropertyTemplatePath: 238 { 239 tooltipText = hierarchyMappingNode.propertyTemplatePathErrorMessage; 240 break; 241 } 242 } 243 244 return tooltipText; 245 } 246 } // namespace AK::WwiseTransfer