Commit e432c672 authored by Leander Schulten's avatar Leander Schulten
Browse files

Changed module interface for fftOutput.

Add CodeCompletion to the ModuleView Editor
parent a972e7ab
......@@ -248,18 +248,153 @@ Item{
id: codeEditor
selectByMouse: true
text: listView.currentItem.itemData.code
onCursorPositionChanged: {
if(codeCompletionPopup.visible){
codeEditorHelper.updateCodeCompletionModel(codeEditor.cursorPosition);
}
}
//onTextChanged: listView.currentItem.itemData.code = text
Keys.onDownPressed: {
if(codeCompletionPopup.visible){
event.accepted = true;
codeCompletionListView.incrementCurrentIndex();
}else{
event.accepted = false;
}
}
Keys.onUpPressed: {
if(codeCompletionPopup.visible){
event.accepted = true;
codeCompletionListView.decrementCurrentIndex();
}else{
event.accepted = false;
}
}
Keys.onSpacePressed: {
if(event.modifiers & (Qt.MetaModifier|Qt.ControlModifier)){
event.accepted = true;
var old = codeCompletionPopup.visible;
//descriptionPopup.visible = !old;
codeCompletionPopup.visible = !old;
}else{
event.accepted = false;
}
}
Keys.onReturnPressed: {
if(codeCompletionPopup.visible){
event.accepted = true;
codeCompletionListView.clickCurrentItem();
}else{
event.accepted = false;
}
}
Popup{
id: descriptionPopup
x: codeCompletionPopup.x
y: codeCompletionPopup.y - 20 - descriptionPopup.height
width: codeCompletionPopup.width
padding: 0
height: descriptionLabel.implicitHeight + 4*2
contentItem: Rectangle{
Label{
anchors.margins: 4
anchors.fill: parent
id: descriptionLabel
wrapMode: "WordWrap"
text: codeCompletionListView.currentItem.itemData.description
background: null
}
color: "beige"
}
}
Popup{
padding: 0
id:codeCompletionPopup
x: codeEditor.cursorRectangle.x
y: codeEditor.cursorRectangle.y + codeEditor.cursorRectangle.height
width: contentItem.implicitWidth
height: Math.max(Math.min(150,codeCompletionListView.count*20),20)
onAboutToShow: {
codeEditorHelper.updateCodeCompletionModel(codeEditor.cursorPosition);
descriptionPopup.visible = codeCompletionListView.count > 0;
codeCompletionListView.updateWidth();
}
onAboutToHide: descriptionPopup.visible = false
contentItem: ListView{
clip: true
id: codeCompletionListView
model: codeEditorHelper.codeCompletions
delegate: ItemDelegate {
property var itemData: modelData
text: modelData.completion.replace(/\n*\t*/g,"")
onClicked: codeCompletionListView.clickCurrentItem()
highlighted: ListView.isCurrentItem
width: codeCompletionPopup.width
height: 20
leftPadding: 1
rightPadding: 1
onHoveredChanged: {
if(hovered){
codeCompletionListView.currentIndex = index;
}
}
background: Rectangle{
color: parent.ListView.isCurrentItem?Qt.darker("beige"):"beige"
}
}
implicitWidth: 150
onCountChanged: {
if(codeCompletionPopup.opened){
descriptionPopup.visible = count > 0;
}
updateWidth();
}
function updateWidth(){
var max = 150;
for(var child in codeCompletionListView.contentItem.children){
max = Math.max(max,codeCompletionListView.contentItem.children[child].implicitWidth);
}
codeCompletionListView.implicitWidth = max;
}
function clickCurrentItem(){
if(codeCompletionListView.currentIndex!==-1){
console.log("close after " + codeCompletionListView.currentItem.itemData.closeAfterCompletion);
if(codeCompletionListView.currentItem.itemData.closeAfterCompletion){
codeCompletionPopup.visible = false;
descriptionPopup.visible = false;
}
// finde heraus was schon eingegeben wurde
var start = codeEditor.cursorPosition-1;
while(start>=0 && /[\w_\d]/.test(codeEditor.text.charAt(start))){
--start;
}
// wenn wir uns in dem zu vervollständigem Wort befinden und das Wort schon vervollständigt im code steht, springen wir mit dem Cursor zum Ende des Wortes
var completion = codeCompletionListView.currentItem.itemData.completion;
if(codeEditor.text.substr(start+1,completion.length) === codeCompletionListView.completion){
codeEditor.cursorPosition += completion.length - (codeEditor.cursorPosition-start) + 1;
return;
}
codeEditor.insert(codeEditor.cursorPosition,completion.substring(codeEditor.cursorPosition-start-1));
}
}
}
}
CodeEditorHelper{
id:codeEditorHelper
module: listView.currentItem.itemData
document: codeEditor.textDocument
onInsertText: {
console.log(newText)
console.log(newText);
codeEditor.insert(codeEditor.cursorPosition,newText);
// Hack to display all new text, sometimes new text disappear
codeEditor.selectAll();
codeEditor.deselect();
//codeEditor.selectAll();
//codeEditor.deselect();
codeEditor.cursorPosition = pos;
}
onInformation:{
......
This diff is collapsed.
......@@ -7,6 +7,7 @@
#include <QTextCharFormat>
#include <QRegularExpression>
#include <programms/modulemanager.h>
#include <QSortFilterProxyModel>
// Highlight code from https://doc.qt.io/qt-5/qtwidgets-richtext-syntaxhighlighter-example.html
class CodeHighlighter : public QSyntaxHighlighter{
......@@ -34,13 +35,50 @@ public:
CodeHighlighter(const CodeHighlighter &) = delete ;
};
class CodeCompletionEntry : public QObject{
Q_OBJECT
public:
const QString type;
const QString description;
const QString completion;
const bool closeAfterCompletion;
Q_PROPERTY(QString type MEMBER type CONSTANT)
Q_PROPERTY(QString description MEMBER description CONSTANT)
Q_PROPERTY(QString completion MEMBER completion CONSTANT)
Q_PROPERTY(bool closeAfterCompletion MEMBER closeAfterCompletion CONSTANT)
public:
CodeCompletionEntry(QString completion,QString type,QString description,bool closeAfterCompletion = true):type(type.trimmed()),description(description),completion(completion.trimmed()),closeAfterCompletion(closeAfterCompletion){
}
};
class PossibleCodeCompletions : public ModelVector<CodeCompletionEntry*>{
Q_OBJECT
};
class CodeCompletions : public QSortFilterProxyModel{
Q_OBJECT
public:
PossibleCodeCompletions model;
CodeCompletions(){
setSourceModel(&model);
}
protected:
virtual bool lessThan(const QModelIndex &source_left, const QModelIndex &source_right)const override;
virtual bool filterAcceptsRow(int sourceRow,const QModelIndex &sourceParent) const override;
};
class CodeEditorHelper : public QObject
{
QQuickTextDocument* documentWrapper = nullptr;
QTextDocument * document = nullptr;
QMetaObject::Connection typeConnection;
CodeCompletions codeCompletions;
Q_PROPERTY(QQuickTextDocument* document READ getDocument WRITE setDocument NOTIFY documentChanged)
Q_PROPERTY(Modules::Module* module READ getModule WRITE setModule NOTIFY moduleChanged)
Q_PROPERTY(QAbstractItemModel * codeCompletions READ getCodeCompletions CONSTANT)
Q_OBJECT
/** Wird automatisch gelöscht, wenn das textdocument zerstört wird
* @brief highlighter
......@@ -50,8 +88,11 @@ class CodeEditorHelper : public QObject
protected:
int countTabs(int startPos);
QString getType(QString variable, int pos);
public:
QAbstractItemModel * getCodeCompletions(){
return &codeCompletions;
}
void setModule( Modules::Module* _module){
if(_module != module){
......@@ -68,6 +109,7 @@ public:
CodeEditorHelper();
Q_INVOKABLE void compile();
Q_INVOKABLE void updateCodeCompletionModel(int cursorPosition);
void setDocument( QQuickTextDocument* _document){
if(_document != documentWrapper){
......
......@@ -86,7 +86,7 @@ public:
}
/// Returns a pointer to the beginning of the span
T*
const T*
data() const
{
return data_;
......@@ -149,14 +149,21 @@ public:
return getMaxFrequency()/static_cast<double>(size_);
}
int getLowerBlockFrequency(const_iterator i){
int getLowerBlockFrequency(const_iterator i)const{
return getMaxFrequency() * std::distance(cbegin(),i) / size();
}
int getLowerBlockFrequency(int index)const{
return getMaxFrequency() * index / size();
}
int getUpperBlockFrequency(const_iterator i){
int getUpperBlockFrequency(const_iterator i)const{
return getLowerBlockFrequency(++i);
}
int getUpperBlockFrequency(int index)const{
return getLowerBlockFrequency(++index);
}
/// Returns an iterator to the beginning of the span
const_iterator
begin(int frequency) const
......@@ -174,6 +181,13 @@ public:
return *begin(frequency);
}
T at(int index){
if(static_cast<unsigned int>(index)>=size()){
return -1;
}
return data_[index];
}
};
......
......@@ -104,11 +104,10 @@ MODULE_EXPORT Modules::Consumer * createConsumer(unsigned int index);
#ifdef HAVE_AUDIO
Modules::FFTOutputView<float> _emptyView;
Modules::FFTOutputView<float> * _fftOutputView = &_emptyView;
Modules::FFTOutputView<float> & fftOutput = _emptyView;
bool __supportAudio = false;
MODULE_EXPORT void _supportAudio(bool b){__supportAudio = b;}
MODULE_EXPORT void _setFFTOutputView(Modules::FFTOutputView<float> * fftOutputView){_fftOutputView = fftOutputView?fftOutputView:&_emptyView;}
const Modules::FFTOutputView<float> & getFFTOutput(){return *_fftOutputView;}
MODULE_EXPORT void _setFFTOutputView(Modules::FFTOutputView<float> * fftOutputView){fftOutput = fftOutputView?*fftOutputView:_emptyView;}
bool supportAudio(){return __supportAudio;}
#endif
......
Markdown is supported
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