annotate layer/LayerFactory.cpp @ 299:5c59c433b358

* Show colour swatch next to layer name in pane (if available) * Fix for incorrect layer name prefix handling (was making some layers appear to have the same model name in cases where the model names differed by the final character only)
author Chris Cannam
date Wed, 05 Sep 2007 15:17:15 +0000
parents 447cb52adc6b
children 46faec7aae12
rev   line source
Chris@58 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
Chris@0 2
Chris@0 3 /*
Chris@59 4 Sonic Visualiser
Chris@59 5 An audio file viewer and annotation editor.
Chris@59 6 Centre for Digital Music, Queen Mary, University of London.
Chris@59 7 This file copyright 2006 Chris Cannam.
Chris@0 8
Chris@59 9 This program is free software; you can redistribute it and/or
Chris@59 10 modify it under the terms of the GNU General Public License as
Chris@59 11 published by the Free Software Foundation; either version 2 of the
Chris@59 12 License, or (at your option) any later version. See the file
Chris@59 13 COPYING included with this distribution for more information.
Chris@0 14 */
Chris@0 15
Chris@0 16 #include "LayerFactory.h"
Chris@0 17
Chris@0 18 #include "WaveformLayer.h"
Chris@0 19 #include "SpectrogramLayer.h"
Chris@0 20 #include "TimeRulerLayer.h"
Chris@0 21 #include "TimeInstantLayer.h"
Chris@0 22 #include "TimeValueLayer.h"
Chris@30 23 #include "NoteLayer.h"
Chris@35 24 #include "TextLayer.h"
Chris@0 25 #include "Colour3DPlotLayer.h"
Chris@133 26 #include "SpectrumLayer.h"
Chris@193 27 #include "SliceLayer.h"
Chris@193 28 #include "SliceableLayer.h"
Chris@0 29
Chris@128 30 #include "data/model/RangeSummarisableTimeValueModel.h"
Chris@128 31 #include "data/model/DenseTimeValueModel.h"
Chris@128 32 #include "data/model/SparseOneDimensionalModel.h"
Chris@128 33 #include "data/model/SparseTimeValueModel.h"
Chris@128 34 #include "data/model/NoteModel.h"
Chris@128 35 #include "data/model/TextModel.h"
Chris@128 36 #include "data/model/DenseThreeDimensionalModel.h"
Chris@156 37 #include "data/model/WaveFileModel.h"
Chris@156 38 #include "data/model/WritableWaveFileModel.h"
Chris@0 39
Chris@0 40 LayerFactory *
Chris@0 41 LayerFactory::m_instance = new LayerFactory;
Chris@0 42
Chris@0 43 LayerFactory *
Chris@125 44 LayerFactory::getInstance()
Chris@0 45 {
Chris@0 46 return m_instance;
Chris@0 47 }
Chris@0 48
Chris@0 49 LayerFactory::~LayerFactory()
Chris@0 50 {
Chris@0 51 }
Chris@0 52
Chris@0 53 QString
Chris@0 54 LayerFactory::getLayerPresentationName(LayerType type)
Chris@0 55 {
Chris@0 56 switch (type) {
Chris@0 57 case Waveform: return Layer::tr("Waveform");
Chris@0 58 case Spectrogram: return Layer::tr("Spectrogram");
Chris@0 59 case TimeRuler: return Layer::tr("Ruler");
Chris@0 60 case TimeInstants: return Layer::tr("Time Instants");
Chris@0 61 case TimeValues: return Layer::tr("Time Values");
Chris@30 62 case Notes: return Layer::tr("Notes");
Chris@35 63 case Text: return Layer::tr("Text");
Chris@0 64 case Colour3DPlot: return Layer::tr("Colour 3D Plot");
Chris@133 65 case Spectrum: return Layer::tr("Spectrum");
Chris@193 66 case Slice: return Layer::tr("Time Slice");
Chris@0 67
Chris@0 68 case MelodicRangeSpectrogram:
Chris@0 69 // The user can change all the parameters of this after the
Chris@0 70 // fact -- there's nothing permanently melodic-range about it
Chris@0 71 // that should be encoded in its name
Chris@0 72 return Layer::tr("Spectrogram");
Chris@11 73
Chris@37 74 case PeakFrequencySpectrogram:
Chris@37 75 // likewise
Chris@37 76 return Layer::tr("Spectrogram");
Chris@37 77
Chris@11 78 default: break;
Chris@0 79 }
Chris@0 80
Chris@0 81 return Layer::tr("Layer");
Chris@0 82 }
Chris@0 83
Chris@193 84 bool
Chris@193 85 LayerFactory::isLayerSliceable(const Layer *layer)
Chris@193 86 {
Chris@193 87 if (dynamic_cast<const SliceableLayer *>(layer)) {
Chris@193 88 if (dynamic_cast<const SpectrogramLayer *>(layer)) {
Chris@193 89
Chris@193 90 //!!! We can create slices of spectrograms, but there's a
Chris@193 91 // problem managing the models. The source model for the
Chris@193 92 // slice layer has to be one of the spectrogram's FFT
Chris@193 93 // models -- that's fine, except that we can't store &
Chris@193 94 // recall the slice layer with a reference to that model
Chris@193 95 // because the model is internal to the spectrogram layer
Chris@193 96 // and the document has no record of it. We would need
Chris@193 97 // some other way of managing models that are used in this
Chris@193 98 // way. For the moment we just don't allow slices of
Chris@193 99 // spectrograms -- and provide a spectrum layer for this
Chris@193 100 // instead.
Chris@193 101 //
Chris@193 102 // This business needs a bit more thought -- either come
Chris@193 103 // up with a sensible way to deal with that stuff, or
Chris@193 104 // simplify the existing slice layer logic so that it
Chris@193 105 // doesn't have to deal with models disappearing on it at
Chris@193 106 // all (and use the normal Document setModel mechanism to
Chris@193 107 // set its sliceable model instead of the fancy pants
Chris@193 108 // nonsense it's doing at the moment).
Chris@193 109
Chris@193 110 return false;
Chris@193 111 }
Chris@193 112 return true;
Chris@193 113 }
Chris@193 114 return false;
Chris@193 115 }
Chris@193 116
Chris@0 117 LayerFactory::LayerTypeSet
Chris@0 118 LayerFactory::getValidLayerTypes(Model *model)
Chris@0 119 {
Chris@0 120 LayerTypeSet types;
Chris@0 121
Chris@0 122 if (dynamic_cast<DenseThreeDimensionalModel *>(model)) {
Chris@0 123 types.insert(Colour3DPlot);
Chris@193 124 types.insert(Slice);
Chris@193 125 }
Chris@193 126
Chris@193 127 if (dynamic_cast<RangeSummarisableTimeValueModel *>(model)) {
Chris@193 128 types.insert(Waveform);
Chris@0 129 }
Chris@0 130
Chris@0 131 if (dynamic_cast<DenseTimeValueModel *>(model)) {
Chris@0 132 types.insert(Spectrogram);
Chris@0 133 types.insert(MelodicRangeSpectrogram);
Chris@37 134 types.insert(PeakFrequencySpectrogram);
Chris@0 135 }
Chris@0 136
Chris@0 137 if (dynamic_cast<SparseOneDimensionalModel *>(model)) {
Chris@0 138 types.insert(TimeInstants);
Chris@0 139 }
Chris@0 140
Chris@0 141 if (dynamic_cast<SparseTimeValueModel *>(model)) {
Chris@0 142 types.insert(TimeValues);
Chris@35 143
Chris@35 144 }
Chris@35 145 if (dynamic_cast<NoteModel *>(model)) {
Chris@35 146 types.insert(Notes);
Chris@0 147 }
Chris@0 148
Chris@35 149 if (dynamic_cast<TextModel *>(model)) {
Chris@35 150 types.insert(Text);
Chris@30 151 }
Chris@30 152
Chris@133 153 if (dynamic_cast<DenseTimeValueModel *>(model)) {
Chris@133 154 types.insert(Spectrum);
Chris@133 155 }
Chris@133 156
Chris@0 157 // We don't count TimeRuler here as it doesn't actually display
Chris@0 158 // the data, although it can be backed by any model
Chris@0 159
Chris@0 160 return types;
Chris@0 161 }
Chris@0 162
Chris@17 163 LayerFactory::LayerTypeSet
Chris@17 164 LayerFactory::getValidEmptyLayerTypes()
Chris@17 165 {
Chris@17 166 LayerTypeSet types;
Chris@17 167 types.insert(TimeInstants);
Chris@17 168 types.insert(TimeValues);
Chris@30 169 types.insert(Notes);
Chris@35 170 types.insert(Text);
Chris@17 171 //!!! and in principle Colour3DPlot -- now that's a challenge
Chris@17 172 return types;
Chris@17 173 }
Chris@17 174
Chris@0 175 LayerFactory::LayerType
Chris@6 176 LayerFactory::getLayerType(const Layer *layer)
Chris@0 177 {
Chris@6 178 if (dynamic_cast<const WaveformLayer *>(layer)) return Waveform;
Chris@6 179 if (dynamic_cast<const SpectrogramLayer *>(layer)) return Spectrogram;
Chris@6 180 if (dynamic_cast<const TimeRulerLayer *>(layer)) return TimeRuler;
Chris@6 181 if (dynamic_cast<const TimeInstantLayer *>(layer)) return TimeInstants;
Chris@6 182 if (dynamic_cast<const TimeValueLayer *>(layer)) return TimeValues;
Chris@30 183 if (dynamic_cast<const NoteLayer *>(layer)) return Notes;
Chris@35 184 if (dynamic_cast<const TextLayer *>(layer)) return Text;
Chris@6 185 if (dynamic_cast<const Colour3DPlotLayer *>(layer)) return Colour3DPlot;
Chris@133 186 if (dynamic_cast<const SpectrumLayer *>(layer)) return Spectrum;
Chris@193 187 if (dynamic_cast<const SliceLayer *>(layer)) return Slice;
Chris@6 188 return UnknownLayer;
Chris@6 189 }
Chris@6 190
Chris@6 191 QString
Chris@17 192 LayerFactory::getLayerIconName(LayerType type)
Chris@17 193 {
Chris@17 194 switch (type) {
Chris@17 195 case Waveform: return "waveform";
Chris@17 196 case Spectrogram: return "spectrogram";
Chris@17 197 case TimeRuler: return "timeruler";
Chris@17 198 case TimeInstants: return "instants";
Chris@17 199 case TimeValues: return "values";
Chris@30 200 case Notes: return "notes";
Chris@35 201 case Text: return "text";
Chris@17 202 case Colour3DPlot: return "colour3d";
Chris@133 203 case Spectrum: return "spectrum";
Chris@193 204 case Slice: return "spectrum";
Chris@17 205 default: return "unknown";
Chris@17 206 }
Chris@17 207 }
Chris@17 208
Chris@17 209 QString
Chris@6 210 LayerFactory::getLayerTypeName(LayerType type)
Chris@6 211 {
Chris@6 212 switch (type) {
Chris@6 213 case Waveform: return "waveform";
Chris@6 214 case Spectrogram: return "spectrogram";
Chris@6 215 case TimeRuler: return "timeruler";
Chris@6 216 case TimeInstants: return "timeinstants";
Chris@6 217 case TimeValues: return "timevalues";
Chris@30 218 case Notes: return "notes";
Chris@35 219 case Text: return "text";
Chris@6 220 case Colour3DPlot: return "colour3dplot";
Chris@133 221 case Spectrum: return "spectrum";
Chris@193 222 case Slice: return "slice";
Chris@6 223 default: return "unknown";
Chris@6 224 }
Chris@6 225 }
Chris@6 226
Chris@6 227 LayerFactory::LayerType
Chris@6 228 LayerFactory::getLayerTypeForName(QString name)
Chris@6 229 {
Chris@6 230 if (name == "waveform") return Waveform;
Chris@6 231 if (name == "spectrogram") return Spectrogram;
Chris@6 232 if (name == "timeruler") return TimeRuler;
Chris@6 233 if (name == "timeinstants") return TimeInstants;
Chris@6 234 if (name == "timevalues") return TimeValues;
Chris@30 235 if (name == "notes") return Notes;
Chris@35 236 if (name == "text") return Text;
Chris@6 237 if (name == "colour3dplot") return Colour3DPlot;
Chris@133 238 if (name == "spectrum") return Spectrum;
Chris@193 239 if (name == "slice") return Slice;
Chris@0 240 return UnknownLayer;
Chris@0 241 }
Chris@0 242
Chris@0 243 void
Chris@0 244 LayerFactory::setModel(Layer *layer, Model *model)
Chris@0 245 {
Chris@156 246 // if (trySetModel<WaveformLayer, RangeSummarisableTimeValueModel>(layer, model))
Chris@156 247 // return;
Chris@156 248
Chris@156 249 if (trySetModel<WaveformLayer, WaveFileModel>(layer, model))
Chris@156 250 return;
Chris@156 251
Chris@156 252 if (trySetModel<WaveformLayer, WritableWaveFileModel>(layer, model))
Chris@0 253 return;
Chris@0 254
Chris@0 255 if (trySetModel<SpectrogramLayer, DenseTimeValueModel>(layer, model))
Chris@0 256 return;
Chris@0 257
Chris@0 258 if (trySetModel<TimeRulerLayer, Model>(layer, model))
Chris@0 259 return;
Chris@0 260
Chris@0 261 if (trySetModel<TimeInstantLayer, SparseOneDimensionalModel>(layer, model))
Chris@0 262 return;
Chris@0 263
Chris@0 264 if (trySetModel<TimeValueLayer, SparseTimeValueModel>(layer, model))
Chris@0 265 return;
Chris@0 266
Chris@30 267 if (trySetModel<NoteLayer, NoteModel>(layer, model))
Chris@30 268 return;
Chris@30 269
Chris@35 270 if (trySetModel<TextLayer, TextModel>(layer, model))
Chris@35 271 return;
Chris@35 272
Chris@0 273 if (trySetModel<Colour3DPlotLayer, DenseThreeDimensionalModel>(layer, model))
Chris@0 274 return;
Chris@0 275
Chris@0 276 if (trySetModel<SpectrogramLayer, DenseTimeValueModel>(layer, model))
Chris@0 277 return;
Chris@133 278
Chris@133 279 if (trySetModel<SpectrumLayer, DenseTimeValueModel>(layer, model))
Chris@133 280 return;
Chris@193 281
Chris@193 282 // if (trySetModel<SliceLayer, DenseThreeDimensionalModel>(layer, model))
Chris@193 283 // return;
Chris@0 284 }
Chris@0 285
Chris@17 286 Model *
Chris@17 287 LayerFactory::createEmptyModel(LayerType layerType, Model *baseModel)
Chris@17 288 {
Chris@17 289 if (layerType == TimeInstants) {
Chris@17 290 return new SparseOneDimensionalModel(baseModel->getSampleRate(), 1);
Chris@17 291 } else if (layerType == TimeValues) {
Chris@245 292 return new SparseTimeValueModel(baseModel->getSampleRate(), 1, true);
Chris@30 293 } else if (layerType == Notes) {
Chris@245 294 return new NoteModel(baseModel->getSampleRate(), 1, true);
Chris@35 295 } else if (layerType == Text) {
Chris@35 296 return new TextModel(baseModel->getSampleRate(), 1, true);
Chris@17 297 } else {
Chris@17 298 return 0;
Chris@17 299 }
Chris@17 300 }
Chris@17 301
Chris@53 302 int
Chris@53 303 LayerFactory::getChannel(Layer *layer)
Chris@53 304 {
Chris@53 305 if (dynamic_cast<WaveformLayer *>(layer)) {
Chris@53 306 return dynamic_cast<WaveformLayer *>(layer)->getChannel();
Chris@53 307 }
Chris@53 308 if (dynamic_cast<SpectrogramLayer *>(layer)) {
Chris@53 309 return dynamic_cast<SpectrogramLayer *>(layer)->getChannel();
Chris@53 310 }
Chris@53 311 return -1;
Chris@53 312 }
Chris@53 313
Chris@53 314 void
Chris@53 315 LayerFactory::setChannel(Layer *layer, int channel)
Chris@53 316 {
Chris@53 317 if (dynamic_cast<WaveformLayer *>(layer)) {
Chris@53 318 dynamic_cast<WaveformLayer *>(layer)->setChannel(channel);
Chris@53 319 return;
Chris@53 320 }
Chris@53 321 if (dynamic_cast<SpectrogramLayer *>(layer)) {
Chris@53 322 dynamic_cast<SpectrogramLayer *>(layer)->setChannel(channel);
Chris@53 323 return;
Chris@53 324 }
Chris@53 325 }
Chris@53 326
Chris@0 327 Layer *
Chris@53 328 LayerFactory::createLayer(LayerType type)
Chris@0 329 {
Chris@0 330 Layer *layer = 0;
Chris@0 331
Chris@0 332 switch (type) {
Chris@0 333
Chris@0 334 case Waveform:
Chris@44 335 layer = new WaveformLayer;
Chris@0 336 break;
Chris@0 337
Chris@0 338 case Spectrogram:
Chris@44 339 layer = new SpectrogramLayer;
Chris@0 340 break;
Chris@0 341
Chris@0 342 case TimeRuler:
Chris@44 343 layer = new TimeRulerLayer;
Chris@0 344 break;
Chris@0 345
Chris@0 346 case TimeInstants:
Chris@44 347 layer = new TimeInstantLayer;
Chris@0 348 break;
Chris@0 349
Chris@0 350 case TimeValues:
Chris@44 351 layer = new TimeValueLayer;
Chris@0 352 break;
Chris@0 353
Chris@30 354 case Notes:
Chris@44 355 layer = new NoteLayer;
Chris@30 356 break;
Chris@30 357
Chris@35 358 case Text:
Chris@44 359 layer = new TextLayer;
Chris@35 360 break;
Chris@35 361
Chris@0 362 case Colour3DPlot:
Chris@44 363 layer = new Colour3DPlotLayer;
Chris@0 364 break;
Chris@0 365
Chris@133 366 case Spectrum:
Chris@133 367 layer = new SpectrumLayer;
Chris@133 368 break;
Chris@133 369
Chris@193 370 case Slice:
Chris@193 371 layer = new SliceLayer;
Chris@193 372 break;
Chris@193 373
Chris@0 374 case MelodicRangeSpectrogram:
Chris@44 375 layer = new SpectrogramLayer(SpectrogramLayer::MelodicRange);
Chris@0 376 break;
Chris@11 377
Chris@37 378 case PeakFrequencySpectrogram:
Chris@44 379 layer = new SpectrogramLayer(SpectrogramLayer::MelodicPeaks);
Chris@37 380 break;
Chris@37 381
Chris@11 382 default: break;
Chris@0 383 }
Chris@0 384
Chris@0 385 if (!layer) {
Chris@0 386 std::cerr << "LayerFactory::createLayer: Unknown layer type "
Chris@0 387 << type << std::endl;
Chris@0 388 } else {
Chris@101 389 // std::cerr << "LayerFactory::createLayer: Setting object name "
Chris@101 390 // << getLayerPresentationName(type).toStdString() << " on " << layer << std::endl;
Chris@0 391 layer->setObjectName(getLayerPresentationName(type));
Chris@0 392 }
Chris@0 393
Chris@0 394 return layer;
Chris@0 395 }
Chris@0 396