Skip to content

Commit ea2a945

Browse files
committed
scripting: v0.1
Signed-off-by: IonutMuthi <[email protected]>
1 parent cb55f3b commit ea2a945

File tree

10 files changed

+488
-2
lines changed

10 files changed

+488
-2
lines changed

core/include/core/browsemenu.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ public Q_SLOTS:
7575
const QString HOME_ID = "home";
7676
const QString PREFERENCES_ID = "preferences";
7777
const QString ABOUT_ID = "about";
78+
const QString SCRIPTING_ID = "scripting";
7879
};
7980
} // namespace scopy
8081

core/include/core/scopycodeeditor.h

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
/*
2+
* Copyright (c) 2024 Analog Devices Inc.
3+
*
4+
* This file is part of Scopy
5+
* (see https://www.github.com/analogdevicesinc/scopy).
6+
*
7+
* This program is free software: you can redistribute it and/or modify
8+
* it under the terms of the GNU General Public License as published by
9+
* the Free Software Foundation, either version 3 of the License, or
10+
* (at your option) any later version.
11+
*
12+
* This program is distributed in the hope that it will be useful,
13+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15+
* GNU General Public License for more details.
16+
*
17+
* You should have received a copy of the GNU General Public License
18+
* along with this program. If not, see <https://www.gnu.org/licenses/>.
19+
*
20+
*/
21+
22+
#ifndef SCOPYCODEEDITOR_H
23+
#define SCOPYCODEEDITOR_H
24+
25+
#include <QPlainTextEdit>
26+
#include "scopy-core_export.h"
27+
28+
namespace scopy {
29+
30+
class SCOPY_CORE_EXPORT ScopyCodeEditor : public QPlainTextEdit
31+
{
32+
Q_OBJECT
33+
public:
34+
explicit ScopyCodeEditor(QWidget *parent = nullptr);
35+
36+
void lineNumberAreaPaintEvent(QPaintEvent *event);
37+
int lineNumberAreaWidth();
38+
39+
protected:
40+
void resizeEvent(QResizeEvent *event) override;
41+
42+
private slots:
43+
void updateLineNumberAreaWidth(int newBlockCount);
44+
void highlightCurrentLine();
45+
void updateLineNumberArea(const QRect &rect, int dy);
46+
47+
private:
48+
QWidget *lineNumberArea;
49+
};
50+
51+
class LineNumberArea : public QWidget
52+
{
53+
Q_OBJECT
54+
55+
public:
56+
LineNumberArea(ScopyCodeEditor *editor)
57+
: QWidget(editor)
58+
, codeEditor(editor)
59+
{}
60+
61+
QSize sizeHint() const override { return QSize(codeEditor->lineNumberAreaWidth(), 0); }
62+
63+
protected:
64+
void paintEvent(QPaintEvent *event) override { codeEditor->lineNumberAreaPaintEvent(event); }
65+
66+
private:
67+
ScopyCodeEditor *codeEditor;
68+
};
69+
70+
} // namespace scopy
71+
#endif // SCOPYCODEEDITOR_H

core/include/core/scriptingtool.h

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
/*
2+
* Copyright (c) 2024 Analog Devices Inc.
3+
*
4+
* This file is part of Scopy
5+
* (see https://www.github.com/analogdevicesinc/scopy).
6+
*
7+
* This program is free software: you can redistribute it and/or modify
8+
* it under the terms of the GNU General Public License as published by
9+
* the Free Software Foundation, either version 3 of the License, or
10+
* (at your option) any later version.
11+
*
12+
* This program is distributed in the hope that it will be useful,
13+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15+
* GNU General Public License for more details.
16+
*
17+
* You should have received a copy of the GNU General Public License
18+
* along with this program. If not, see <https://www.gnu.org/licenses/>.
19+
*
20+
*/
21+
22+
#ifndef SCRIPTINGTOOL_H
23+
#define SCRIPTINGTOOL_H
24+
25+
#include <QPlainTextEdit>
26+
#include <QWidget>
27+
#include <tooltemplate.h>
28+
#include "scopy-core_export.h"
29+
#include "scopycodeeditor.h"
30+
#include <toolbuttons.h>
31+
32+
namespace scopy {
33+
34+
class SCOPY_CORE_EXPORT ScriptingTool : public QWidget
35+
{
36+
Q_OBJECT
37+
public:
38+
explicit ScriptingTool(QWidget *parent = nullptr);
39+
40+
signals:
41+
42+
private:
43+
ToolTemplate *m_tool;
44+
ScopyCodeEditor *m_codeEditor;
45+
QPlainTextEdit *m_codeOutput;
46+
RunBtn *m_runBtn;
47+
48+
void loadFile();
49+
void saveToFile();
50+
void compileCode(QString code);
51+
};
52+
53+
} // namespace scopy
54+
#endif // SCRIPTINGTOOL_H

core/src/browsemenu.cpp

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,36 @@ BrowseMenu::BrowseMenu(QWidget *parent)
9595
preferencesBtn->setCheckable(true);
9696
m_btnsMap[PREFERENCES_ID] = preferencesBtn;
9797

98+
QPushButton *toolsBtn = createBtn("Tools",
99+
":/gui/icons/" + Style::getAttribute(json::theme::icon_theme_folder) +
100+
"/icons/preferences.svg",
101+
m_content);
102+
toolsBtn->setCheckable(true);
103+
104+
// popup widget for tools
105+
QWidget *toolsPopup = new QWidget(nullptr, Qt::Popup);
106+
QVBoxLayout *popupLayout = new QVBoxLayout(toolsPopup);
107+
Style::setStyle(toolsPopup, style::properties::widget::basicComponent);
108+
Style::setStyle(toolsPopup, style::properties::widget::border_interactive);
109+
popupLayout->setContentsMargins(0, 0, 0, 0);
110+
111+
// Scripting btn
112+
QPushButton *scriptingBtn = new QPushButton(tr("Scripting"), toolsPopup);
113+
scriptingBtn->setCheckable(false);
114+
popupLayout->addWidget(scriptingBtn);
115+
116+
connect(scriptingBtn, &QPushButton::clicked, this, [=]() {
117+
Q_EMIT requestTool(SCRIPTING_ID);
118+
toolsPopup->hide();
119+
});
120+
121+
connect(toolsBtn, &QPushButton::clicked, this, [=]() {
122+
QPoint pos = toolsBtn->mapToGlobal(QPoint(toolsBtn->width(), 0));
123+
toolsPopup->move(pos);
124+
toolsPopup->show();
125+
});
126+
127+
// About button
98128
QPushButton *aboutBtn = createBtn(
99129
"About", ":/gui/icons/" + Style::getAttribute(json::theme::icon_theme_folder) + "/icons/info.svg",
100130
m_content);
@@ -108,6 +138,7 @@ BrowseMenu::BrowseMenu(QWidget *parent)
108138

109139
btnGroup->addButton(homeBtn);
110140
btnGroup->addButton(preferencesBtn);
141+
btnGroup->addButton(toolsBtn);
111142
btnGroup->addButton(aboutBtn);
112143

113144
add(createHLine(m_content), "headerLine", MA_TOPLAST);
@@ -118,6 +149,7 @@ BrowseMenu::BrowseMenu(QWidget *parent)
118149
add(createHLine(m_content), "toolMenuLine2", MA_BOTTOMLAST);
119150
add(saveLoadWidget, "saveLoad", MA_BOTTOMLAST);
120151
add(preferencesBtn, "preferencesBtn", MA_BOTTOMLAST);
152+
add(toolsBtn, "toolsBtn", MA_BOTTOMLAST);
121153
add(aboutBtn, "aboutBtn", MA_BOTTOMLAST);
122154
add(logo, "logo", MA_BOTTOMLAST);
123155

core/src/scopycodeeditor.cpp

Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
/*
2+
* Copyright (c) 2024 Analog Devices Inc.
3+
*
4+
* This file is part of Scopy
5+
* (see https://www.github.com/analogdevicesinc/scopy).
6+
*
7+
* This program is free software: you can redistribute it and/or modify
8+
* it under the terms of the GNU General Public License as published by
9+
* the Free Software Foundation, either version 3 of the License, or
10+
* (at your option) any later version.
11+
*
12+
* This program is distributed in the hope that it will be useful,
13+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15+
* GNU General Public License for more details.
16+
*
17+
* You should have received a copy of the GNU General Public License
18+
* along with this program. If not, see <https://www.gnu.org/licenses/>.
19+
*
20+
*/
21+
22+
#include "scopycodeeditor.h"
23+
24+
#include <QPainter>
25+
#include <QTextBlock>
26+
#include <style.h>
27+
28+
using namespace scopy;
29+
30+
ScopyCodeEditor::ScopyCodeEditor(QWidget *parent)
31+
: QPlainTextEdit{parent}
32+
{
33+
lineNumberArea = new LineNumberArea(this);
34+
35+
connect(this, &ScopyCodeEditor::blockCountChanged, this, &ScopyCodeEditor::updateLineNumberAreaWidth);
36+
connect(this, &ScopyCodeEditor::updateRequest, this, &ScopyCodeEditor::updateLineNumberArea);
37+
connect(this, &ScopyCodeEditor::cursorPositionChanged, this, &ScopyCodeEditor::highlightCurrentLine);
38+
39+
updateLineNumberAreaWidth(0);
40+
highlightCurrentLine();
41+
}
42+
43+
void ScopyCodeEditor::lineNumberAreaPaintEvent(QPaintEvent *event)
44+
{
45+
QPainter painter(lineNumberArea);
46+
painter.fillRect(event->rect(), Qt::lightGray);
47+
QTextBlock block = firstVisibleBlock();
48+
int blockNumber = block.blockNumber();
49+
int top = qRound(blockBoundingGeometry(block).translated(contentOffset()).top());
50+
int bottom = top + qRound(blockBoundingRect(block).height());
51+
while(block.isValid() && top <= event->rect().bottom()) {
52+
if(block.isVisible() && bottom >= event->rect().top()) {
53+
QString number = QString::number(blockNumber + 1);
54+
painter.setPen(Qt::black);
55+
painter.drawText(0, top, lineNumberArea->width(), fontMetrics().height(), Qt::AlignRight,
56+
number);
57+
}
58+
59+
block = block.next();
60+
top = bottom;
61+
bottom = top + qRound(blockBoundingRect(block).height());
62+
++blockNumber;
63+
}
64+
}
65+
66+
int ScopyCodeEditor::lineNumberAreaWidth()
67+
{
68+
int digits = 1;
69+
int max = qMax(1, blockCount());
70+
while(max >= 10) {
71+
max /= 10;
72+
++digits;
73+
}
74+
75+
int space = 3 + fontMetrics().horizontalAdvance(QLatin1Char('9')) * digits;
76+
77+
return space;
78+
}
79+
80+
void ScopyCodeEditor::resizeEvent(QResizeEvent *event)
81+
{
82+
QPlainTextEdit::resizeEvent(event);
83+
QRect cr = contentsRect();
84+
lineNumberArea->setGeometry(QRect(cr.left(), cr.top(), lineNumberAreaWidth(), cr.height()));
85+
}
86+
87+
void ScopyCodeEditor::updateLineNumberAreaWidth(int newBlockCount)
88+
{
89+
setViewportMargins(lineNumberAreaWidth(), 0, 0, 0);
90+
}
91+
92+
void ScopyCodeEditor::highlightCurrentLine()
93+
{
94+
QList<QTextEdit::ExtraSelection> extraSelections;
95+
96+
if(!isReadOnly()) {
97+
QTextEdit::ExtraSelection selection;
98+
99+
QColor lineColor = Style::getColor(json::theme::interactive_subtle_hover);
100+
101+
selection.format.setBackground(lineColor);
102+
selection.format.setProperty(QTextFormat::FullWidthSelection, true);
103+
selection.cursor = textCursor();
104+
selection.cursor.clearSelection();
105+
extraSelections.append(selection);
106+
}
107+
108+
setExtraSelections(extraSelections);
109+
}
110+
111+
void ScopyCodeEditor::updateLineNumberArea(const QRect &rect, int dy)
112+
{
113+
if(dy)
114+
lineNumberArea->scroll(0, dy);
115+
else
116+
lineNumberArea->update(0, rect.y(), lineNumberArea->width(), rect.height());
117+
118+
if(rect.contains(viewport()->rect()))
119+
updateLineNumberAreaWidth(0);
120+
}
121+
122+
#include "moc_scopycodeeditor.cpp"

core/src/scopymainwindow.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
#include <deviceautoconnect.h>
3232
#include <style.h>
3333
#include <whatsnewoverlay.h>
34+
#include <scriptingtool.h>
3435

3536
#include <common/debugtimer.h>
3637
#include "logging_categories.h"
@@ -135,9 +136,12 @@ ScopyMainWindow::ScopyMainWindow(QWidget *parent)
135136
dtm = new DetachedToolWindowManager(this);
136137
m_toolMenuManager = new ToolMenuManager(ts, dtm, browseMenu->toolMenu(), this);
137138

139+
ScriptingTool *scriptingTool = new ScriptingTool(this);
140+
138141
ts->add("home", hp);
139142
ts->add("about", about);
140143
ts->add("preferences", prefPage);
144+
ts->add("scripting", scriptingTool);
141145

142146
connect(scanTask, &IIOScanTask::scanFinished, scc, &ScannedIIOContextCollector::update, Qt::QueuedConnection);
143147

0 commit comments

Comments
 (0)