Commit 12ee81cc authored by Leander Schulten's avatar Leander Schulten
Browse files

Added control points. A control point can be set in the map view and accessed from a module

parent 55cbc825
......@@ -101,6 +101,7 @@ HEADERS += \
applicationdata.h \
namedobject.h \
dmxchannelfilter.h \
programms/controlpoint.hpp \
usermanagment.h \
channelprogrammeditor.h \
modelmanager.h \
......
......@@ -253,6 +253,11 @@ void addCompletionsForType(PossibleCodeCompletions & model, QString type){
model.push_back(new CodeCompletionEntry("currentSection.","SectionObject","The current Section of the Analysis of the current track."));
model.push_back(new CodeCompletionEntry("currentSegment.","SegmentObject","The current Segment of the Analysis of the current track."));
}
if(type=="ControlPoint"){
model.push_back(new CodeCompletionEntry("x","double","the x position of the control point"));
model.push_back(new CodeCompletionEntry("y","double","the y position of the control point"));
model.push_back(new CodeCompletionEntry("positionChanged","bool","A bool that indicates the position change of the control point."));
}
//model.push_back(new CodeCompletionEntry("","float",""));
qDebug()<<"type" << type;
......@@ -267,6 +272,7 @@ void addDefaultVariables(PossibleCodeCompletions & model, Modules::Module * m){
model.push_back(new CodeCompletionEntry("input[i]","unsigned int","Ein Element im Input an der Position index"));
model.push_back(new CodeCompletionEntry("input","unsigned int * ","Der Inputarray"));
model.push_back(new CodeCompletionEntry("spotify->","SpotifyState","Ein Object, dass alle zu Spotify gehörigen Daten enthält."));
model.push_back(new CodeCompletionEntry("controlPoint->","ControlPoint","Der ControlPoint der in dem Map View gesetzt werden kann."));
}
void skipWhitespaces(int & cursor, QTextDocument * d){
......@@ -563,6 +569,8 @@ QString CodeEditorHelper::getType(QString variable, int pos){
return "SegmentObject";
if(variable == "spotify")
return "SpotifyState";
if(variable == "controlPoint")
return "ControlPoint";
return "unknown";
}
......@@ -925,6 +933,7 @@ void CodeEditorHelper::compile(){
stream << "#define MODULE_LIBRARY" << endl;
stream << "#define HAVE_AUDIO" << endl;
stream << "#define HAVE_SPOTIFY" << endl;
stream << "#define HAVE_CONTROL_POINT" << endl;
switch (module->getType()) {
case Modules::Module::Filter:
stream << "#define HAVE_FILTER" << endl;
......
......@@ -114,6 +114,9 @@ MapView * MapView::lastCreated = nullptr;
MapView::MapView()
{
setKeepMouseGrab(true);
setAcceptedMouseButtons(Qt::LeftButton);
lastCreated = this;
auto p = generateBar();
p.first->setParentItem(this);
......@@ -184,4 +187,39 @@ void MapView::writeJsonObject(QJsonObject &o) const{
o.insert("polygons",a);
}
void MapView::mousePressEvent(QMouseEvent *event){
if(event->modifiers().testFlag(Qt::AltModifier) || event->modifiers().testFlag(Qt::ShiftModifier)){
event->accept();
}else{
// compute distance to controlPoint:
if(std::sqrt((event->pos() - controlPoint).manhattanLength())<9){
event->accept();
}else{
event->ignore();
}
}
}
void MapView::mouseMoveEvent(QMouseEvent *event){
event->accept();
controlPoint = event->pos();
controlPoint.setX(controlPoint.x() - 30 - 3);
controlPoint.setY(controlPoint.y() - 30 - 3);
if(controlPoint.x() < 0){
controlPoint.setX(0);
}else if(controlPoint.x() > implicitWidth()){
controlPoint.setX(implicitWidth());
}
if(controlPoint.y() < 0){
controlPoint.setY(0);
}else if(controlPoint.y() > implicitWidth()){
controlPoint.setY(implicitWidth());
}
emit controlPointChanged();
Modules::ModuleManager::singletone()->controller().updateControlPoint(controlPoint);
}
}
......@@ -3,12 +3,15 @@
#include "polygon.h"
#include "gridbackground.h"
#include "programms/modulemanager.h"
namespace GUI{
class MapView : public GridBackground
{
Q_OBJECT
Q_PROPERTY(QPointF controlPoint READ getControlPoint WRITE setControlPoint NOTIFY controlPointChanged)
QPointF controlPoint;
static MapView * lastCreated;
protected:
std::vector<GUI::Polygon *> polygons;
......@@ -19,8 +22,19 @@ public:
static MapView * getLastCreated(){return lastCreated;}
void loadFromJsonObject(const QJsonObject &o);
void writeJsonObject(QJsonObject &o)const;
void setControlPoint(const QPointF & p){
if(p != controlPoint){
controlPoint = p;
emit controlPointChanged();
Modules::ModuleManager::singletone()->controller().updateControlPoint(controlPoint);
}
}
QPointF getControlPoint()const{return controlPoint;}
protected:
void mousePressEvent(QMouseEvent *event)override;
void mouseMoveEvent(QMouseEvent *event)override;
signals:
void controlPointChanged();
public slots:
};
......
......@@ -112,6 +112,7 @@ void Controller::run() noexcept{
}
}
spotifyState.newTrack = false;
controlPoint.positionChanged = false;
}
}
......
......@@ -8,6 +8,8 @@
#include "programblock.h"
#include "spotify.hpp"
#include "spotify/spotify.h"
#include "controlpoint.hpp"
#include <QPointF>
namespace Modules {
......@@ -32,6 +34,8 @@ class Controller
int lastIndexOfCurrentTatum = -1;
int lastIndexOfCurrentSection = -1;
int lastIndexOfCurrentSegment = -1;
// Control Point
ControlPoint controlPoint;
friend class ProgramBlock;
void run() noexcept;
......@@ -41,11 +45,24 @@ public:
* @brief getSpotifyState return the SpotifyState object managed by this controller
*/
const SpotifyState & getSpotifyState(){return spotifyState;}
/**
* @brief getControlPoint return the ControlPoint object managed by this controller
*/
const ControlPoint & getControlPoint(){return controlPoint;}
/**
* @brief setSpotify sets the Spotify object for this controller that is used to fill the Spotify state object
* @param spotify the Spotify object, or a nullptr to unset the Spotify object
*/
void setSpotify(Spotify::Spotify * spotify);
/**
* @brief updateControlPoint updates the control point used by the module programs
* @param controlPointPosition The new control point position on the map
*/
void updateControlPoint(const QPointF & controlPointPosition){
controlPoint.x = controlPointPosition.x();
controlPoint.y = controlPointPosition.y();
controlPoint.positionChanged = true;
}
void start(){
if(!run_){
run_=true;
......
#ifndef CONTROLPOINT_H
#define CONTROLPOINT_H
namespace Modules {
class ControlPoint{
public:
double x = 0;
double y = 0;
bool positionChanged = false;
};
}
#endif // CONTROLPOINT_H
......@@ -7,6 +7,7 @@
//#define HAVE_FILTER
//#define HAVE_CONSUMER
//#define HAVE_SPOTIFY
//#define HAVE_CONTROL_POINT
#ifdef HAVE_PROGRAM
#include "program.hpp"
......@@ -33,6 +34,10 @@
#include "spotify.hpp"
#endif
#ifdef HAVE_CONTROL_POINT
#include "controlpoint.hpp"
#endif
#include <string>
//disable Warning for char * as return type in extern "C" Block with clang
......@@ -49,7 +54,7 @@
#endif
extern "C" {
enum class MODUL_TYPE{Program, LoopProgram,Filter,Consumer,Audio,Spotify};
enum class MODUL_TYPE{Program, LoopProgram,Filter,Consumer,Audio,Spotify,ControlPoint};
#ifdef MODULE_LIBRARY
......@@ -90,6 +95,12 @@ MODULE_EXPORT bool have(MODUL_TYPE t){
return true;
#else
return false;
#endif
case MODUL_TYPE::ControlPoint:
#ifdef HAVE_CONTROL_POINT
return true;
#else
return false;
#endif
}
return false; // Vielleicht wird das enum in einer weiteren Version erweitert.
......@@ -140,6 +151,12 @@ Modules::SpotifyState const * spotify = &__emptySpotifyState;
MODULE_EXPORT void _setSpotifyState(Modules::SpotifyState const * s){spotify = s?s:&__emptySpotifyState;}
#endif
#ifdef HAVE_CONTROL_POINT
Modules::ControlPoint __defaultControlPoint;
Modules::ControlPoint const * controlPoint;
MODULE_EXPORT void _setControlPoint(Modules::ControlPoint const * s){controlPoint = s?s:&__defaultControlPoint;}
#endif
}
#endif // MODULES_GLOBAL_H
......@@ -240,6 +240,13 @@ typedef Modules::Program* (*CreateProgramm)(unsigned int index);
func(&controller_.getSpotifyState());
}
}
if(f(MODUL_TYPE::ControlPoint)){
typedef void (*SetControlPointFunc)(Modules::ControlPoint const *);
SetControlPointFunc func = reinterpret_cast<SetControlPointFunc>(lib.resolve("_setControlPoint"));
if(func){
func(&controller_.getControlPoint());
}
}
loadedLibraryMap.emplace_back(lib.fileName(),LibInfo{lastLibraryIdentifier,supportAudioFunc});
......
......@@ -9,6 +9,15 @@ ColumnLayout{
anchors.margins: 5
property var toPlacedDevice: null
ToolTip.visible: !root.toPlacedDevice && hoverMouseArea.containsMouse
ToolTip.text: "Use the shift or alt modifier to move the control point or no modifier to move the map"
SwipeView.onIsCurrentItemChanged: {
if(!SwipeView.isCurrentItem){
toPlacedDevice = null; // if the item is not placed and we leave the tab ignore the to placed item
}
}
Item{
Layout.fillWidth: true
Layout.fillHeight: true
......@@ -82,14 +91,24 @@ ColumnLayout{
MouseArea{
anchors.fill: parent
acceptedButtons: Qt.LeftButton | Qt.RightButton
enabled: root.toPlacedDevice !== null
onClicked: {
if(root.toPlacedDevice && mouse.button === Qt.LeftButton){
root.toPlacedDevice.position.x = mouse.x - 30;
root.toPlacedDevice.position.y = mouse.y - 30;
}else{
mouse.accepted = false;
}
root.toPlacedDevice = null;
deviceInfo.device = null;
}
}
MouseArea{
id: hoverMouseArea
anchors.fill: parent
acceptedButtons: Qt.NoButton
hoverEnabled: true
scrollGestureEnabled: true
onWheel: {
if(wheel.modifiers & Qt.ControlModifier){
var newScale = map.scale + wheel.angleDelta.y / 120. * 0.1;
......@@ -99,8 +118,8 @@ ColumnLayout{
wheel.accepted = false
}
}
}
Repeater{
model: deviceModel
Rectangle{
......@@ -148,6 +167,28 @@ ColumnLayout{
ToolTip.text: itemData.name + "\nDmx Addess: " + itemData.startDMXChannel
}
}
Rectangle{
id: controlPoint
x: parent.controlPoint.x + 30 - 3
y: parent.controlPoint.y + 30 - 3
width: 7
height: 7
radius: 7
color: "lightgreen"
MouseArea{
id: mouseAreaControlPoint
acceptedButtons: Qt.NoButton
enabled: !root.toPlacedDevice
anchors.fill: parent
anchors.margins: -5
hoverEnabled: true
}
ToolTip.visible: mouseAreaControlPoint.containsMouse
ToolTip.delay: 500
ToolTip.text: "This control point is used by modules programs"
}
}
}
}
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment