mirror of
				https://github.com/subsurface/subsurface.git
				synced 2025-02-19 22:16:15 +00:00 
			
		
		
		
	statistics: support ctrl-selection for all series
Multiple selection using ctrl was only supported for scatter series. Factor out the corresponding code and use it in all series. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
This commit is contained in:
		
							parent
							
								
									64b82b16a2
								
							
						
					
					
						commit
						43b0ccca3e
					
				
					 6 changed files with 72 additions and 56 deletions
				
			
		|  | @ -411,17 +411,16 @@ void BarSeries::unhighlight() | |||
| 	highlighted = Index(); | ||||
| } | ||||
| 
 | ||||
| bool BarSeries::selectItemsUnderMouse(const QPointF &pos, SelectionModifier) | ||||
| bool BarSeries::selectItemsUnderMouse(const QPointF &pos, SelectionModifier modifier) | ||||
| { | ||||
| 	Index index = getItemUnderMouse(pos); | ||||
| 	if (index.bar < 0) { | ||||
| 		setSelection({}, nullptr); | ||||
| 		return false; | ||||
| 	} | ||||
| 
 | ||||
| 	const std::vector<dive *> &dives = items[index.bar].subitems[index.subitem].dives; | ||||
| 	setSelection(dives, dives.empty() ? nullptr : dives.front()); | ||||
| 	return true; | ||||
| 	std::vector<dive *> divesUnderMouse; | ||||
| 	if (index.bar >= 0) | ||||
| 		divesUnderMouse = items[index.bar].subitems[index.subitem].dives; | ||||
| 	processSelection(std::move(divesUnderMouse), modifier); | ||||
| 
 | ||||
| 	return index.bar >= 0; | ||||
| } | ||||
| 
 | ||||
| void BarSeries::divesSelected(const QVector<dive *> &) | ||||
|  |  | |||
|  | @ -146,17 +146,16 @@ void BoxSeries::unhighlight() | |||
| 	highlighted = -1; | ||||
| } | ||||
| 
 | ||||
| bool BoxSeries::selectItemsUnderMouse(const QPointF &pos, SelectionModifier) | ||||
| bool BoxSeries::selectItemsUnderMouse(const QPointF &pos, SelectionModifier modifier) | ||||
| { | ||||
| 	int index = getItemUnderMouse(pos); | ||||
| 	if (index < 0) { | ||||
| 		setSelection({}, nullptr); | ||||
| 		return false; | ||||
| 	} | ||||
| 
 | ||||
| 	const std::vector<dive *> &dives = items[index]->q.dives; | ||||
| 	setSelection(dives, dives.empty() ? nullptr : dives.front()); | ||||
| 	return true; | ||||
| 	std::vector<dive *> divesUnderMouse; | ||||
| 	if (index >= 0) | ||||
| 		divesUnderMouse = items[index]->q.dives; | ||||
| 	processSelection(std::move(divesUnderMouse), modifier); | ||||
| 
 | ||||
| 	return index >= 0; | ||||
| } | ||||
| 
 | ||||
| void BoxSeries::divesSelected(const QVector<dive *> &) | ||||
|  |  | |||
|  | @ -266,17 +266,16 @@ void PieSeries::unhighlight() | |||
| 	highlighted = -1; | ||||
| } | ||||
| 
 | ||||
| bool PieSeries::selectItemsUnderMouse(const QPointF &pos, SelectionModifier) | ||||
| bool PieSeries::selectItemsUnderMouse(const QPointF &pos, SelectionModifier modifier) | ||||
| { | ||||
| 	int index = getItemUnderMouse(pos); | ||||
| 	if (index < 0) { | ||||
| 		setSelection({}, nullptr); | ||||
| 		return false; | ||||
| 	} | ||||
| 
 | ||||
| 	const std::vector<dive *> &dives = items[index].dives; | ||||
| 	setSelection(dives, dives.empty() ? nullptr : dives.front()); | ||||
| 	return true; | ||||
| 	std::vector<dive *> divesUnderMouse; | ||||
| 	if (index >= 0) | ||||
| 		divesUnderMouse = items[index].dives; | ||||
| 	processSelection(std::move(divesUnderMouse), modifier); | ||||
| 
 | ||||
| 	return index >= 0; | ||||
| } | ||||
| 
 | ||||
| void PieSeries::divesSelected(const QVector<dive *> &) | ||||
|  |  | |||
|  | @ -98,41 +98,14 @@ std::vector<int> ScatterSeries::getItemsInRect(const QRectF &rect) const | |||
| 
 | ||||
| bool ScatterSeries::selectItemsUnderMouse(const QPointF &point, SelectionModifier modifier) | ||||
| { | ||||
| 	std::vector<struct dive *> selected; | ||||
| 	std::vector<int> indices = getItemsUnderMouse(point); | ||||
| 	std::vector<struct dive *> divesUnderMouse; | ||||
| 
 | ||||
| 	if (modifier.ctrl) { | ||||
| 		// When shift is pressed, add the items under the mouse to the selection
 | ||||
| 		// or, if all items under the mouse are selected, remove them.
 | ||||
| 		selected = getDiveSelection(); | ||||
| 		selected.reserve(indices.size() + selected.size()); | ||||
| 		bool allSelected = std::all_of(indices.begin(), indices.end(), | ||||
| 					       [this] (int idx) { return items[idx].d->selected; }); | ||||
| 		if (allSelected) { | ||||
| 			// Remove items under cursor from selection. This could be made more efficient.
 | ||||
| 			for (int idx: indices) { | ||||
| 				auto it = std::find(selected.begin(), selected.end(), items[idx].d); | ||||
| 				if (it != selected.end()) { | ||||
| 					// Move last element to deselected element. If this already was
 | ||||
| 					// the last element, this is a no-op. Then, chop off last element.
 | ||||
| 					*it = selected.back(); | ||||
| 					selected.pop_back(); | ||||
| 				} | ||||
| 			} | ||||
| 		} else { | ||||
| 			// Add items under cursor to selection
 | ||||
| 			for (int idx: indices) { | ||||
| 				if (std::find(selected.begin(), selected.end(), items[idx].d) == selected.end()) | ||||
| 					selected.push_back(items[idx].d); | ||||
| 			} | ||||
| 		} | ||||
| 	} else { | ||||
| 		selected.reserve(indices.size()); | ||||
| 		for(int idx: indices) | ||||
| 			selected.push_back(items[idx].d); | ||||
| 	} | ||||
| 	divesUnderMouse.reserve(indices.size()); | ||||
| 	for(int idx: indices) | ||||
| 		divesUnderMouse.push_back(items[idx].d); | ||||
| 
 | ||||
| 	setSelection(selected, selected.empty() ? nullptr : selected.front()); | ||||
| 	processSelection(std::move(divesUnderMouse), modifier); | ||||
| 	return !indices.empty(); | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -1,2 +1,42 @@ | |||
| // SPDX-License-Identifier: GPL-2.0
 | ||||
| #include "statsselection.h" | ||||
| #include "core/dive.h" | ||||
| #include "core/selection.h" | ||||
| 
 | ||||
| #include <algorithm> | ||||
| 
 | ||||
| void processSelection(std::vector<dive *> dives, SelectionModifier modifier) | ||||
| { | ||||
| 	std::vector<dive *> selected; | ||||
| 
 | ||||
| 	if (modifier.ctrl) { | ||||
| 		// When shift is pressed, add the items under the mouse to the selection
 | ||||
| 		// or, if all items under the mouse are selected, remove them.
 | ||||
| 		selected = getDiveSelection(); | ||||
| 		bool allSelected = std::all_of(dives.begin(), dives.end(), | ||||
| 					       [] (const dive *d) { return d->selected; }); | ||||
| 		if (allSelected) { | ||||
| 			// Remove items under cursor from selection. This could be made more efficient.
 | ||||
| 			for (const dive *d: dives) { | ||||
| 				auto it = std::find(selected.begin(), selected.end(), d); | ||||
| 				if (it != selected.end()) { | ||||
| 					// Move last element to deselected element. If this already was
 | ||||
| 					// the last element, this is a no-op. Then, chop off last element.
 | ||||
| 					*it = selected.back(); | ||||
| 					selected.pop_back(); | ||||
| 				} | ||||
| 			} | ||||
| 		} else { | ||||
| 			// Add items under cursor to selection
 | ||||
| 			selected.reserve(dives.size() + selected.size()); | ||||
| 			for (dive *d: dives) { | ||||
| 				if (std::find(selected.begin(), selected.end(), d) == selected.end()) | ||||
| 					selected.push_back(d); | ||||
| 			} | ||||
| 		} | ||||
| 	} else { | ||||
| 		selected = std::move(dives); | ||||
| 	} | ||||
| 
 | ||||
| 	setSelection(selected, selected.empty() ? nullptr : selected.front()); | ||||
| } | ||||
|  |  | |||
|  | @ -4,6 +4,10 @@ | |||
| #ifndef STATS_SELECTION_H | ||||
| #define STATS_SELECTION_H | ||||
| 
 | ||||
| #include <vector> | ||||
| 
 | ||||
| struct dive; | ||||
| 
 | ||||
| struct SelectionModifier { | ||||
| 	unsigned int ctrl : 1; | ||||
| 	unsigned int shift : 1; | ||||
|  | @ -12,4 +16,6 @@ struct SelectionModifier { | |||
| 	SelectionModifier() : ctrl(0), shift(0) {} | ||||
| }; | ||||
| 
 | ||||
| void processSelection(std::vector<dive *> dives, SelectionModifier modifier); | ||||
| 
 | ||||
| #endif | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue