comparison layer/RegionLayer.cpp @ 427:1304dbe4542e

* Support importing features from RDF whose times are intervals rather than only instants; import them into region or note models. Sadly this makes RDF import much, much slower, because we need to work around Rasqal's single-OPTIONAL limitation by repeatedly querying each feature for time and range. * Add segmentation view to region layer, and display label texts
author Chris Cannam
date Tue, 07 Oct 2008 12:42:17 +0000
parents 31f222929319
children 8b2b497d302c
comparison
equal deleted inserted replaced
426:6bf3c906b7a5 427:1304dbe4542e
18 #include "data/model/Model.h" 18 #include "data/model/Model.h"
19 #include "base/RealTime.h" 19 #include "base/RealTime.h"
20 #include "base/Profiler.h" 20 #include "base/Profiler.h"
21 #include "base/LogRange.h" 21 #include "base/LogRange.h"
22 #include "ColourDatabase.h" 22 #include "ColourDatabase.h"
23 #include "ColourMapper.h"
23 #include "view/View.h" 24 #include "view/View.h"
24 25
25 #include "data/model/RegionModel.h" 26 #include "data/model/RegionModel.h"
26 27
27 #include "widgets/ItemEditDialog.h" 28 #include "widgets/ItemEditDialog.h"
41 m_editing(false), 42 m_editing(false),
42 m_originalPoint(0, 0.0, 0, tr("New Point")), 43 m_originalPoint(0, 0.0, 0, tr("New Point")),
43 m_editingPoint(0, 0.0, 0, tr("New Point")), 44 m_editingPoint(0, 0.0, 0, tr("New Point")),
44 m_editingCommand(0), 45 m_editingCommand(0),
45 m_verticalScale(AutoAlignScale), 46 m_verticalScale(AutoAlignScale),
47 m_colourMap(0),
46 m_plotStyle(PlotLines) 48 m_plotStyle(PlotLines)
47 { 49 {
48 50
49 } 51 }
50 52
84 RegionLayer::getPropertyType(const PropertyName &name) const 86 RegionLayer::getPropertyType(const PropertyName &name) const
85 { 87 {
86 if (name == "Scale Units") return UnitsProperty; 88 if (name == "Scale Units") return UnitsProperty;
87 if (name == "Vertical Scale") return ValueProperty; 89 if (name == "Vertical Scale") return ValueProperty;
88 if (name == "Plot Type") return ValueProperty; 90 if (name == "Plot Type") return ValueProperty;
91 if (name == "Colour" && m_plotStyle == PlotSegmentation) return ValueProperty;
89 return SingleColourLayer::getPropertyType(name); 92 return SingleColourLayer::getPropertyType(name);
90 } 93 }
91 94
92 QString 95 QString
93 RegionLayer::getPropertyGroupName(const PropertyName &name) const 96 RegionLayer::getPropertyGroupName(const PropertyName &name) const
102 RegionLayer::getPropertyRangeAndValue(const PropertyName &name, 105 RegionLayer::getPropertyRangeAndValue(const PropertyName &name,
103 int *min, int *max, int *deflt) const 106 int *min, int *max, int *deflt) const
104 { 107 {
105 int val = 0; 108 int val = 0;
106 109
107 if (name == "Plot Type") { 110 if (name == "Colour" && m_plotStyle == PlotSegmentation) {
111
112 if (min) *min = 0;
113 if (max) *max = ColourMapper::getColourMapCount() - 1;
114 if (deflt) *deflt = 0;
115
116 val = m_colourMap;
117
118 } else if (name == "Plot Type") {
108 119
109 if (min) *min = 0; 120 if (min) *min = 0;
110 if (max) *max = 1; 121 if (max) *max = 1;
111 if (deflt) *deflt = 0; 122 if (deflt) *deflt = 0;
112 123
136 return val; 147 return val;
137 } 148 }
138 149
139 QString 150 QString
140 RegionLayer::getPropertyValueLabel(const PropertyName &name, 151 RegionLayer::getPropertyValueLabel(const PropertyName &name,
141 int value) const 152 int value) const
142 { 153 {
143 if (name == "Plot Type") { 154 if (name == "Colour" && m_plotStyle == PlotSegmentation) {
155 return ColourMapper::getColourMapName(value);
156 } else if (name == "Plot Type") {
144 157
145 switch (value) { 158 switch (value) {
146 default: 159 default:
147 case 0: return tr("Lines"); 160 case 0: return tr("Bars");
148 case 1: return tr("Segmentation"); 161 case 1: return tr("Segmentation");
149 } 162 }
150 163
151 } else if (name == "Vertical Scale") { 164 } else if (name == "Vertical Scale") {
152 switch (value) { 165 switch (value) {
160 } 173 }
161 174
162 void 175 void
163 RegionLayer::setProperty(const PropertyName &name, int value) 176 RegionLayer::setProperty(const PropertyName &name, int value)
164 { 177 {
165 if (name == "Plot Type") { 178 if (name == "Colour" && m_plotStyle == PlotSegmentation) {
179 setFillColourMap(value);
180 } else if (name == "Plot Type") {
166 setPlotStyle(PlotStyle(value)); 181 setPlotStyle(PlotStyle(value));
167 } else if (name == "Vertical Scale") { 182 } else if (name == "Vertical Scale") {
168 setVerticalScale(VerticalScale(value)); 183 setVerticalScale(VerticalScale(value));
169 } else if (name == "Scale Units") { 184 } else if (name == "Scale Units") {
170 if (m_model) { 185 if (m_model) {
176 return SingleColourLayer::setProperty(name, value); 191 return SingleColourLayer::setProperty(name, value);
177 } 192 }
178 } 193 }
179 194
180 void 195 void
196 RegionLayer::setFillColourMap(int map)
197 {
198 if (m_colourMap == map) return;
199 m_colourMap = map;
200 emit layerParametersChanged();
201 }
202
203 void
181 RegionLayer::setPlotStyle(PlotStyle style) 204 RegionLayer::setPlotStyle(PlotStyle style)
182 { 205 {
183 if (m_plotStyle == style) return; 206 if (m_plotStyle == style) return;
207 bool colourTypeChanged = (style == PlotSegmentation ||
208 m_plotStyle == PlotSegmentation);
184 m_plotStyle = style; 209 m_plotStyle = style;
210 if (colourTypeChanged) {
211 emit layerParameterRangesChanged();
212 }
185 emit layerParametersChanged(); 213 emit layerParametersChanged();
186 } 214 }
187 215
188 void 216 void
189 RegionLayer::setVerticalScale(VerticalScale scale) 217 RegionLayer::setVerticalScale(VerticalScale scale)
485 int y = margin + int(h - ((val - min) * h) / (max - min)) - 1; 513 int y = margin + int(h - ((val - min) * h) / (max - min)) - 1;
486 std::cerr << "y = " << y << std::endl; 514 std::cerr << "y = " << y << std::endl;
487 return y; 515 return y;
488 } 516 }
489 517
518 QColor
519 RegionLayer::getColourForValue(View *v, float val) const
520 {
521 float min, max;
522 bool log;
523 getScaleExtents(v, min, max, log);
524
525 if (min > max) std::swap(min, max);
526 if (max == min) max = min + 1;
527
528 if (log) {
529 LogRange::mapRange(min, max);
530 val = LogRange::map(val);
531 }
532
533 // std::cerr << "RegionLayer::getColourForValue: min " << min << ", max "
534 // << max << ", log " << log << ", value " << val << std::endl;
535
536 QColor solid = ColourMapper(m_colourMap, min, max).map(val);
537 return QColor(solid.red(), solid.green(), solid.blue(), 120);
538 }
539
540 int
541 RegionLayer::getDefaultColourHint(bool darkbg, bool &impose)
542 {
543 impose = false;
544 return ColourDatabase::getInstance()->getColourIndex
545 (QString(darkbg ? "Bright Blue" : "Blue"));
546 }
547
490 float 548 float
491 RegionLayer::getValueForY(View *v, int y) const 549 RegionLayer::getValueForY(View *v, int y) const
492 { 550 {
493 float min = 0.0, max = 0.0; 551 float min = 0.0, max = 0.0;
494 bool logarithmic = false; 552 bool logarithmic = false;
550 //!!! be assigned to avoid overlaps 608 //!!! be assigned to avoid overlaps
551 609
552 //!!! if it does have distinct values, we should still ensure y 610 //!!! if it does have distinct values, we should still ensure y
553 //!!! coord is never completely flat on the top or bottom 611 //!!! coord is never completely flat on the top or bottom
554 612
613 int textY = 0;
614 if (m_plotStyle == PlotSegmentation) {
615 textY = v->getTextLabelHeight(this, paint);
616 }
617
555 for (RegionModel::PointList::const_iterator i = points.begin(); 618 for (RegionModel::PointList::const_iterator i = points.begin();
556 i != points.end(); ++i) { 619 i != points.end(); ++i) {
557 620
558 const RegionModel::Point &p(*i); 621 const RegionModel::Point &p(*i);
559 622
560 int x = v->getXForFrame(p.frame); 623 int x = v->getXForFrame(p.frame);
561 int y = getYForValue(v, p.value); 624 int y = getYForValue(v, p.value);
562 int w = v->getXForFrame(p.frame + p.duration) - x; 625 int w = v->getXForFrame(p.frame + p.duration) - x;
563 int h = 9; 626 int h = 9;
564 627
628 bool haveNext = false;
629 int nx = v->getXForFrame(v->getModelsEndFrame());
630
631 RegionModel::PointList::const_iterator j = i;
632 ++j;
633
634 if (j != points.end()) {
635 const RegionModel::Point &q(*j);
636 nx = v->getXForFrame(q.frame);
637 haveNext = true;
638 }
639
640 if (m_plotStyle != PlotSegmentation) {
641 textY = y - paint.fontMetrics().height()
642 + paint.fontMetrics().ascent();
643 if (textY < paint.fontMetrics().ascent() + 1) {
644 textY = paint.fontMetrics().ascent() + 1;
645 }
646 }
647
565 if (m_model->getValueQuantization() != 0.0) { 648 if (m_model->getValueQuantization() != 0.0) {
566 h = y - getYForValue(v, p.value + m_model->getValueQuantization()); 649 h = y - getYForValue(v, p.value + m_model->getValueQuantization());
567 if (h < 3) h = 3; 650 if (h < 3) h = 3;
568 } 651 }
569 652
570 if (w < 1) w = 1; 653 if (w < 1) w = 1;
571 paint.setPen(getBaseQColor()); 654
572 paint.setBrush(brushColour); 655 if (m_plotStyle == PlotSegmentation) {
573 656 paint.setPen(getForegroundQColor(v));
574 if (illuminateFrame == p.frame) { 657 paint.setBrush(getColourForValue(v, p.value));
575 if (localPos.y() >= y - h && localPos.y() < y) { 658 } else {
576 paint.setPen(v->getForeground()); 659 paint.setPen(getBaseQColor());
577 paint.setBrush(v->getForeground()); 660 paint.setBrush(brushColour);
661 }
662
663 if (m_plotStyle == PlotSegmentation) {
664
665 if (nx <= x) continue;
666
667 if (illuminateFrame != p.frame &&
668 (nx < x + 5 || x >= v->width() - 1)) {
669 paint.setPen(Qt::NoPen);
578 } 670 }
671
672 paint.drawRect(x, -1, nx - x, v->height() + 1);
673
674 } else {
675
676 if (illuminateFrame == p.frame) {
677 if (localPos.y() >= y - h && localPos.y() < y) {
678 paint.setPen(v->getForeground());
679 paint.setBrush(v->getForeground());
680 }
681 }
682
683 paint.drawLine(x, y-1, x + w, y-1);
684 paint.drawLine(x, y+1, x + w, y+1);
685 paint.drawLine(x, y - h/2, x, y + h/2);
686 paint.drawLine(x+w, y - h/2, x + w, y + h/2);
687 }
688
689 if (p.label != "") {
690 if (!haveNext || nx > x + 6 + paint.fontMetrics().width(p.label)) {
691 paint.drawText(x + 5, textY, p.label);
692 }
579 } 693 }
580
581 paint.drawLine(x, y-1, x + w, y-1);
582 paint.drawLine(x, y+1, x + w, y+1);
583 paint.drawLine(x, y - h/2, x, y + h/2);
584 paint.drawLine(x+w, y - h/2, x + w, y + h/2);
585
586 /// if (p.label != "") {
587 /// paint.drawText(x + 5, y - paint.fontMetrics().height() + paint.fontMetrics().ascent(), p.label);
588 /// }
589 } 694 }
590 695
591 paint.restore(); 696 paint.restore();
592 } 697 }
593 698
996 1101
997 finish(command); 1102 finish(command);
998 return true; 1103 return true;
999 } 1104 }
1000 1105
1001 int
1002 RegionLayer::getDefaultColourHint(bool darkbg, bool &impose)
1003 {
1004 impose = false;
1005 return ColourDatabase::getInstance()->getColourIndex
1006 (QString(darkbg ? "White" : "Black"));
1007 }
1008
1009 void 1106 void
1010 RegionLayer::toXml(QTextStream &stream, 1107 RegionLayer::toXml(QTextStream &stream,
1011 QString indent, QString extraAttributes) const 1108 QString indent, QString extraAttributes) const
1012 { 1109 {
1013 SingleColourLayer::toXml(stream, indent, extraAttributes + 1110 SingleColourLayer::toXml(stream, indent, extraAttributes +