Initial commit
This commit is contained in:
35
src/Insight/UserInterfaces/InsightWindow/AboutWindow.cpp
Normal file
35
src/Insight/UserInterfaces/InsightWindow/AboutWindow.cpp
Normal file
@@ -0,0 +1,35 @@
|
||||
#include <QtUiTools>
|
||||
#include <src/Exceptions/Exception.hpp>
|
||||
|
||||
#include "AboutWindow.hpp"
|
||||
#include "TargetWidgets/DIP/DualInlinePackageWidget.hpp"
|
||||
#include "src/Logger/Logger.hpp"
|
||||
#include "src/Application.hpp"
|
||||
|
||||
using namespace Bloom;
|
||||
using namespace InsightTargetWidgets;
|
||||
using namespace Exceptions;
|
||||
|
||||
AboutWindow::AboutWindow(QWidget* parent): QObject(parent) {
|
||||
auto aboutWindowUiFile = QFile(":/compiled/Insight/UserInterfaces/InsightWindow/UiFiles/AboutWindow.ui");
|
||||
auto aboutWindowStylesheet = QFile(":/compiled/Insight/UserInterfaces/InsightWindow/Stylesheets/AboutWindow.qss");
|
||||
|
||||
if (!aboutWindowUiFile.open(QFile::ReadOnly)) {
|
||||
throw Exception("Failed to open AboutWindow UI file");
|
||||
}
|
||||
|
||||
if (!aboutWindowStylesheet.open(QFile::ReadOnly)) {
|
||||
throw Exception("Failed to open AboutWindow QSS file");
|
||||
}
|
||||
|
||||
auto uiLoader = QUiLoader();
|
||||
this->windowWidget = uiLoader.load(&aboutWindowUiFile, parent);
|
||||
this->windowWidget->setStyleSheet(aboutWindowStylesheet.readAll());
|
||||
this->windowWidget->setFixedSize(400, 300);
|
||||
|
||||
auto versionLabel = this->windowWidget->findChild<QLabel*>("version-label");
|
||||
|
||||
if (versionLabel != nullptr) {
|
||||
versionLabel->setText("Bloom v" + QString::fromStdString(Application::VERSION_STR));
|
||||
}
|
||||
}
|
||||
28
src/Insight/UserInterfaces/InsightWindow/AboutWindow.hpp
Normal file
28
src/Insight/UserInterfaces/InsightWindow/AboutWindow.hpp
Normal file
@@ -0,0 +1,28 @@
|
||||
#pragma once
|
||||
|
||||
#include <QtCore>
|
||||
#include <QMainWindow>
|
||||
#include <QtUiTools/QtUiTools>
|
||||
#include <memory>
|
||||
|
||||
namespace Bloom
|
||||
{
|
||||
class AboutWindow: public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
private:
|
||||
QWidget* windowWidget = nullptr;
|
||||
|
||||
public:
|
||||
AboutWindow(QWidget* parent);
|
||||
|
||||
void show() {
|
||||
if (this->windowWidget != nullptr) {
|
||||
this->windowWidget->move(
|
||||
this->windowWidget->parentWidget()->geometry().center() - this->windowWidget->rect().center()
|
||||
);
|
||||
this->windowWidget->show();
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
494
src/Insight/UserInterfaces/InsightWindow/Images/BloomIcon.svg
Normal file
494
src/Insight/UserInterfaces/InsightWindow/Images/BloomIcon.svg
Normal file
@@ -0,0 +1,494 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="100"
|
||||
height="100"
|
||||
viewBox="0 0 26.458333 26.458334"
|
||||
version="1.1"
|
||||
id="svg8"
|
||||
inkscape:version="1.0.1 (1.0.1+r75)"
|
||||
sodipodi:docname="BloomIconv1.svg"
|
||||
inkscape:export-filename="/home/nav/Projects/Bloom/src/Insight/UserInterfaces/InsightWindow/Images/BloomIconv1.png"
|
||||
inkscape:export-xdpi="96"
|
||||
inkscape:export-ydpi="96">
|
||||
<defs
|
||||
id="defs2">
|
||||
<inkscape:path-effect
|
||||
effect="powerstroke"
|
||||
id="path-effect2043"
|
||||
is_visible="true"
|
||||
lpeversion="1"
|
||||
offset_points="4,0.087850891"
|
||||
sort_points="true"
|
||||
interpolator_type="CubicBezierJohan"
|
||||
interpolator_beta="0.2"
|
||||
start_linecap_type="zerowidth"
|
||||
linejoin_type="extrp_arc"
|
||||
miter_limit="4"
|
||||
scale_width="1"
|
||||
end_linecap_type="zerowidth" />
|
||||
<inkscape:path-effect
|
||||
effect="spiro"
|
||||
id="path-effect2041"
|
||||
is_visible="true"
|
||||
lpeversion="1" />
|
||||
<inkscape:path-effect
|
||||
effect="powerstroke"
|
||||
id="path-effect2037"
|
||||
is_visible="true"
|
||||
lpeversion="1"
|
||||
offset_points="0,0.1322915"
|
||||
sort_points="true"
|
||||
interpolator_type="CubicBezierJohan"
|
||||
interpolator_beta="0.2"
|
||||
start_linecap_type="zerowidth"
|
||||
linejoin_type="extrp_arc"
|
||||
miter_limit="4"
|
||||
scale_width="1"
|
||||
end_linecap_type="zerowidth" />
|
||||
<inkscape:path-effect
|
||||
effect="spiro"
|
||||
id="path-effect2035"
|
||||
is_visible="true"
|
||||
lpeversion="1" />
|
||||
<inkscape:path-effect
|
||||
effect="powerstroke"
|
||||
id="path-effect2031"
|
||||
is_visible="true"
|
||||
lpeversion="1"
|
||||
offset_points="0,0.1322915"
|
||||
sort_points="true"
|
||||
interpolator_type="CubicBezierJohan"
|
||||
interpolator_beta="0.2"
|
||||
start_linecap_type="zerowidth"
|
||||
linejoin_type="extrp_arc"
|
||||
miter_limit="4"
|
||||
scale_width="1"
|
||||
end_linecap_type="zerowidth" />
|
||||
<inkscape:path-effect
|
||||
effect="spiro"
|
||||
id="path-effect2029"
|
||||
is_visible="true"
|
||||
lpeversion="1" />
|
||||
<inkscape:path-effect
|
||||
effect="simplify"
|
||||
id="path-effect2027"
|
||||
is_visible="true"
|
||||
lpeversion="1"
|
||||
steps="1"
|
||||
threshold="0.075"
|
||||
smooth_angles="360"
|
||||
helper_size="0"
|
||||
simplify_individual_paths="false"
|
||||
simplify_just_coalesce="false" />
|
||||
<inkscape:path-effect
|
||||
effect="powerstroke"
|
||||
id="path-effect2023"
|
||||
is_visible="true"
|
||||
lpeversion="1"
|
||||
offset_points="0,0.1322915"
|
||||
sort_points="true"
|
||||
interpolator_type="CubicBezierJohan"
|
||||
interpolator_beta="0.2"
|
||||
start_linecap_type="zerowidth"
|
||||
linejoin_type="extrp_arc"
|
||||
miter_limit="4"
|
||||
scale_width="1"
|
||||
end_linecap_type="zerowidth" />
|
||||
<inkscape:path-effect
|
||||
effect="spiro"
|
||||
id="path-effect2021"
|
||||
is_visible="true"
|
||||
lpeversion="1" />
|
||||
<inkscape:path-effect
|
||||
effect="simplify"
|
||||
id="path-effect2019"
|
||||
is_visible="true"
|
||||
lpeversion="1"
|
||||
steps="1"
|
||||
threshold="0.075"
|
||||
smooth_angles="360"
|
||||
helper_size="0"
|
||||
simplify_individual_paths="false"
|
||||
simplify_just_coalesce="false" />
|
||||
<inkscape:path-effect
|
||||
effect="powerstroke"
|
||||
id="path-effect2015"
|
||||
is_visible="true"
|
||||
lpeversion="1"
|
||||
offset_points="0,0.1322915"
|
||||
sort_points="true"
|
||||
interpolator_type="CubicBezierJohan"
|
||||
interpolator_beta="0.2"
|
||||
start_linecap_type="zerowidth"
|
||||
linejoin_type="extrp_arc"
|
||||
miter_limit="4"
|
||||
scale_width="1"
|
||||
end_linecap_type="zerowidth" />
|
||||
<inkscape:path-effect
|
||||
effect="spiro"
|
||||
id="path-effect2013"
|
||||
is_visible="true"
|
||||
lpeversion="1" />
|
||||
<inkscape:path-effect
|
||||
effect="simplify"
|
||||
id="path-effect2011"
|
||||
is_visible="true"
|
||||
lpeversion="1"
|
||||
steps="1"
|
||||
threshold="0.075"
|
||||
smooth_angles="360"
|
||||
helper_size="0"
|
||||
simplify_individual_paths="false"
|
||||
simplify_just_coalesce="false" />
|
||||
<inkscape:path-effect
|
||||
effect="powerstroke"
|
||||
id="path-effect2007"
|
||||
is_visible="true"
|
||||
lpeversion="1"
|
||||
offset_points="0,0.1322915"
|
||||
sort_points="true"
|
||||
interpolator_type="CubicBezierJohan"
|
||||
interpolator_beta="0.2"
|
||||
start_linecap_type="zerowidth"
|
||||
linejoin_type="extrp_arc"
|
||||
miter_limit="4"
|
||||
scale_width="1"
|
||||
end_linecap_type="zerowidth" />
|
||||
<inkscape:path-effect
|
||||
effect="spiro"
|
||||
id="path-effect2005"
|
||||
is_visible="true"
|
||||
lpeversion="1" />
|
||||
<inkscape:path-effect
|
||||
effect="simplify"
|
||||
id="path-effect2003"
|
||||
is_visible="true"
|
||||
lpeversion="1"
|
||||
steps="1"
|
||||
threshold="0.0142857"
|
||||
smooth_angles="360"
|
||||
helper_size="0"
|
||||
simplify_individual_paths="false"
|
||||
simplify_just_coalesce="false" />
|
||||
<inkscape:path-effect
|
||||
effect="powerstroke"
|
||||
id="path-effect1999"
|
||||
is_visible="true"
|
||||
lpeversion="1"
|
||||
offset_points="0,0.1322915"
|
||||
sort_points="true"
|
||||
interpolator_type="CubicBezierJohan"
|
||||
interpolator_beta="0.2"
|
||||
start_linecap_type="zerowidth"
|
||||
linejoin_type="extrp_arc"
|
||||
miter_limit="4"
|
||||
scale_width="1"
|
||||
end_linecap_type="zerowidth" />
|
||||
<inkscape:path-effect
|
||||
effect="spiro"
|
||||
id="path-effect1997"
|
||||
is_visible="true"
|
||||
lpeversion="1" />
|
||||
<inkscape:path-effect
|
||||
effect="simplify"
|
||||
id="path-effect1995"
|
||||
is_visible="true"
|
||||
lpeversion="1"
|
||||
steps="1"
|
||||
threshold="0.0142857"
|
||||
smooth_angles="360"
|
||||
helper_size="0"
|
||||
simplify_individual_paths="false"
|
||||
simplify_just_coalesce="false" />
|
||||
<inkscape:path-effect
|
||||
effect="powerstroke"
|
||||
id="path-effect1991"
|
||||
is_visible="true"
|
||||
lpeversion="1"
|
||||
offset_points="0,0.1322915"
|
||||
sort_points="true"
|
||||
interpolator_type="CubicBezierJohan"
|
||||
interpolator_beta="0.2"
|
||||
start_linecap_type="zerowidth"
|
||||
linejoin_type="extrp_arc"
|
||||
miter_limit="4"
|
||||
scale_width="1"
|
||||
end_linecap_type="zerowidth" />
|
||||
<inkscape:path-effect
|
||||
effect="spiro"
|
||||
id="path-effect1989"
|
||||
is_visible="true"
|
||||
lpeversion="1" />
|
||||
<inkscape:path-effect
|
||||
effect="simplify"
|
||||
id="path-effect1987"
|
||||
is_visible="true"
|
||||
lpeversion="1"
|
||||
steps="1"
|
||||
threshold="0.5"
|
||||
smooth_angles="360"
|
||||
helper_size="0"
|
||||
simplify_individual_paths="false"
|
||||
simplify_just_coalesce="false" />
|
||||
<inkscape:path-effect
|
||||
effect="powerstroke"
|
||||
id="path-effect1983"
|
||||
is_visible="true"
|
||||
lpeversion="1"
|
||||
offset_points="0,0.1322915"
|
||||
sort_points="true"
|
||||
interpolator_type="CubicBezierJohan"
|
||||
interpolator_beta="0.2"
|
||||
start_linecap_type="zerowidth"
|
||||
linejoin_type="extrp_arc"
|
||||
miter_limit="4"
|
||||
scale_width="1"
|
||||
end_linecap_type="zerowidth" />
|
||||
<inkscape:path-effect
|
||||
effect="spiro"
|
||||
id="path-effect1981"
|
||||
is_visible="true"
|
||||
lpeversion="1" />
|
||||
<inkscape:path-effect
|
||||
effect="powerstroke"
|
||||
id="path-effect1977"
|
||||
is_visible="true"
|
||||
lpeversion="1"
|
||||
offset_points="0,0.1322915"
|
||||
sort_points="true"
|
||||
interpolator_type="CubicBezierJohan"
|
||||
interpolator_beta="0.2"
|
||||
start_linecap_type="zerowidth"
|
||||
linejoin_type="extrp_arc"
|
||||
miter_limit="4"
|
||||
scale_width="1"
|
||||
end_linecap_type="zerowidth" />
|
||||
<inkscape:path-effect
|
||||
effect="spiro"
|
||||
id="path-effect1975"
|
||||
is_visible="true"
|
||||
lpeversion="1" />
|
||||
<inkscape:path-effect
|
||||
effect="spiro"
|
||||
id="path-effect1971"
|
||||
is_visible="true"
|
||||
lpeversion="1" />
|
||||
<inkscape:path-effect
|
||||
effect="spiro"
|
||||
id="path-effect1965"
|
||||
is_visible="true"
|
||||
lpeversion="1" />
|
||||
<inkscape:path-effect
|
||||
effect="spiro"
|
||||
id="path-effect1943"
|
||||
is_visible="true"
|
||||
lpeversion="1" />
|
||||
<rect
|
||||
x="2.2588253"
|
||||
y="4.4681918"
|
||||
width="22.286396"
|
||||
height="20.035455"
|
||||
id="rect1929" />
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#3c3f41"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="2.8284271"
|
||||
inkscape:cx="103.76972"
|
||||
inkscape:cy="19.358205"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="layer6"
|
||||
inkscape:document-rotation="0"
|
||||
showgrid="false"
|
||||
units="px"
|
||||
inkscape:window-width="3440"
|
||||
inkscape:window-height="1353"
|
||||
inkscape:window-x="2560"
|
||||
inkscape:window-y="34"
|
||||
inkscape:window-maximized="1" />
|
||||
<metadata
|
||||
id="metadata5">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title />
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:groupmode="layer"
|
||||
id="layer6"
|
||||
inkscape:label="Layer 5"
|
||||
style="display:inline">
|
||||
<rect
|
||||
style="display:inline;fill:#3c3f41;fill-opacity:1;stroke:none;stroke-width:1.22116;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.611015"
|
||||
id="rect1934"
|
||||
width="26.458334"
|
||||
height="26.458334"
|
||||
x="-2.220446e-16"
|
||||
y="-2.220446e-16" />
|
||||
</g>
|
||||
<g
|
||||
inkscape:groupmode="layer"
|
||||
id="layer2"
|
||||
inkscape:label="Layer 2"
|
||||
style="display:inline"
|
||||
sodipodi:insensitive="true">
|
||||
<path
|
||||
style="opacity:1;fill:#a8a9a9;fill-opacity:1;stroke:none;stroke-width:0.214532;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="m 11.688069,17.233636 h -1.287196 v 1.287197 h 1.287196 z"
|
||||
id="path3020" />
|
||||
<path
|
||||
style="opacity:1;fill:#46484a;fill-opacity:1;stroke:none;stroke-width:0.214532;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="m 13.872785,17.233636 h -1.287197 v 1.287197 h 1.287197 z"
|
||||
id="path3018" />
|
||||
<path
|
||||
style="opacity:1;fill:#883e42;fill-opacity:1;stroke:none;stroke-width:0.214532;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="m 16.057499,17.233636 h -1.287196 v 1.287197 h 1.287196 z"
|
||||
id="rect3462-6-0-7" />
|
||||
<rect
|
||||
style="display:inline;fill:#1e1e1e;fill-opacity:1;stroke:none;stroke-width:0.214532;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="rect3447"
|
||||
width="6.292676"
|
||||
height="6.2926764"
|
||||
x="10.082829"
|
||||
y="10.082828" />
|
||||
<path
|
||||
style="opacity:1;fill:#a8a9a9;fill-opacity:1;stroke:none;stroke-width:0.214532;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="m 11.688069,7.9375 h -1.287196 v 1.2871968 h 1.287196 z"
|
||||
id="path3014" />
|
||||
<path
|
||||
style="opacity:1;fill:#98763f;fill-opacity:1;stroke:none;stroke-width:0.214532;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="m 13.872784,7.9375 h -1.287197 v 1.2871968 h 1.287197 z"
|
||||
id="path3012" />
|
||||
<path
|
||||
style="opacity:1;fill:#a8a9a9;fill-opacity:1;stroke:none;stroke-width:0.214532;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="m 16.057499,7.9375 h -1.287197 v 1.2871968 h 1.287197 z"
|
||||
id="rect3462-6-0-7-3" />
|
||||
<path
|
||||
style="display:inline;fill:none;stroke:#883e42;stroke-width:0.529167;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="m 15.413699,18.520833 v 2.188773 l 1.828342,1.700558"
|
||||
id="path2868-1" />
|
||||
<path
|
||||
style="display:inline;fill:none;stroke:#a8a9a9;stroke-width:0.529167;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="m 11.044456,18.520833 v 2.188773 l -1.8283422,1.700558"
|
||||
id="path2868-4-96" />
|
||||
<path
|
||||
style="display:inline;fill:none;stroke:#46484a;stroke-width:0.529167;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="M 13.229121,18.520833 V 23.30264"
|
||||
id="path2885-2" />
|
||||
<path
|
||||
style="display:inline;fill:none;stroke:#a8a9a9;stroke-width:0.529167;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="M 11.044456,7.9375 V 5.748727 L 9.2161138,4.048169"
|
||||
id="path2868-1-1" />
|
||||
<path
|
||||
style="display:inline;fill:none;stroke:#a8a9a9;stroke-width:0.529167;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="M 15.413699,7.9375 V 5.748727 l 1.828342,-1.700558"
|
||||
id="path2868-4-96-2" />
|
||||
<path
|
||||
style="display:inline;fill:none;stroke:#98763f;stroke-width:0.529167;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="M 13.229034,7.9375 V 3.155693"
|
||||
id="path2885-2-0" />
|
||||
<path
|
||||
style="display:inline;fill:none;stroke:#a8a9a9;stroke-width:0.529167;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="m 18.520834,11.044456 h 2.188773 l 1.700558,-1.8283422"
|
||||
id="path2868" />
|
||||
<path
|
||||
style="display:inline;fill:none;stroke:#3d778c;stroke-width:0.529167;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="m 18.520834,15.413699 h 2.188773 l 1.700558,1.828342"
|
||||
id="path2868-4" />
|
||||
<path
|
||||
style="display:inline;fill:none;stroke:#3d778c;stroke-width:0.529167;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="m 18.520834,13.229034 h 4.781807"
|
||||
id="path2885" />
|
||||
<path
|
||||
style="display:inline;fill:none;stroke:#98763f;stroke-width:0.529167;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="M 7.9375005,11.044456 H 5.7487275 L 4.0481695,9.2161142"
|
||||
id="path2868-9" />
|
||||
<path
|
||||
style="display:inline;fill:none;stroke:#98763f;stroke-width:0.529167;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="m 7.9375005,15.413699 h -2.188773 l -1.700558,1.828342"
|
||||
id="path2868-4-9" />
|
||||
<path
|
||||
style="display:inline;fill:none;stroke:#a8a9a9;stroke-width:0.529167;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="M 7.9375005,13.229034 H 3.1556935"
|
||||
id="path2885-4" />
|
||||
<rect
|
||||
style="display:inline;opacity:1;fill:#98763f;fill-opacity:1;stroke:none;stroke-width:0.214532;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="rect3462-2-5"
|
||||
width="1.2871968"
|
||||
height="1.2871968"
|
||||
x="-9.2246971"
|
||||
y="10.400837"
|
||||
transform="scale(-0.99999999,0.99999999)" />
|
||||
<rect
|
||||
style="display:inline;opacity:1;fill:#a8a9a9;fill-opacity:1;stroke:none;stroke-width:0.214532;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="rect3462-3-7-9"
|
||||
width="1.2871968"
|
||||
height="1.2871968"
|
||||
x="-9.2246971"
|
||||
y="12.585534"
|
||||
transform="scale(-0.99999999,0.99999999)" />
|
||||
<rect
|
||||
style="display:inline;opacity:1;fill:#98763f;fill-opacity:1;stroke:none;stroke-width:0.214532;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="rect3462-6-0-3"
|
||||
width="1.2871968"
|
||||
height="1.2871968"
|
||||
x="-9.2246971"
|
||||
y="14.77023"
|
||||
transform="scale(-0.99999999,0.99999999)" />
|
||||
<rect
|
||||
style="display:inline;opacity:1;fill:#a8a9a9;fill-opacity:1;stroke:none;stroke-width:0.214532;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="rect3462-2"
|
||||
width="1.2871968"
|
||||
height="1.2871968"
|
||||
x="17.233637"
|
||||
y="10.400837" />
|
||||
<rect
|
||||
style="display:inline;opacity:1;fill:#3d778c;fill-opacity:1;stroke:none;stroke-width:0.214532;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="rect3462-3-7"
|
||||
width="1.2871968"
|
||||
height="1.2871968"
|
||||
x="17.233637"
|
||||
y="12.585535" />
|
||||
<rect
|
||||
style="display:inline;opacity:1;fill:#3d778c;fill-opacity:1;stroke:none;stroke-width:0.214532;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="rect3462-6-0"
|
||||
width="1.2871968"
|
||||
height="1.2871968"
|
||||
x="17.233637"
|
||||
y="14.770231" />
|
||||
<circle
|
||||
style="fill:#a8a9a9;fill-opacity:0.81374;stroke:#0f0f0f;stroke-width:0.0661458;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="path3034"
|
||||
cx="10.7442"
|
||||
cy="10.7442"
|
||||
r="0.26458335" />
|
||||
</g>
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
style="display:inline">
|
||||
<circle
|
||||
style="fill:none;fill-opacity:1;stroke:#3c3f41;stroke-width:1.5875;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="path900"
|
||||
cx="13.229166"
|
||||
cy="13.229166"
|
||||
r="10.583333" />
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 17 KiB |
127
src/Insight/UserInterfaces/InsightWindow/Images/RAM.svg
Normal file
127
src/Insight/UserInterfaces/InsightWindow/Images/RAM.svg
Normal file
@@ -0,0 +1,127 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="25"
|
||||
height="25"
|
||||
viewBox="0 0 6.6145832 6.6145832"
|
||||
version="1.1"
|
||||
id="svg1576"
|
||||
inkscape:version="1.0.1 (1.0.1+r75)"
|
||||
sodipodi:docname="RAM.svg">
|
||||
<defs
|
||||
id="defs1570" />
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#3c3f41"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="1"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="32"
|
||||
inkscape:cx="9.8214382"
|
||||
inkscape:cy="11.928771"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="layer3"
|
||||
inkscape:document-rotation="0"
|
||||
showgrid="false"
|
||||
units="px"
|
||||
inkscape:window-width="3440"
|
||||
inkscape:window-height="1353"
|
||||
inkscape:window-x="2560"
|
||||
inkscape:window-y="34"
|
||||
inkscape:window-maximized="1" />
|
||||
<metadata
|
||||
id="metadata1573">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:groupmode="layer"
|
||||
id="layer3"
|
||||
inkscape:label="Pins"
|
||||
style="opacity:1;mix-blend-mode:normal">
|
||||
<rect
|
||||
style="opacity:1;fill:#afb1b3;fill-opacity:1;stroke:#3c3f41;stroke-width:0.17704;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="rect2148"
|
||||
width="0.64708883"
|
||||
height="0.780729"
|
||||
x="2.1040154"
|
||||
y="4.4343238" />
|
||||
<rect
|
||||
style="opacity:1;mix-blend-mode:normal;fill:#afb1b3;fill-opacity:1;stroke:#3c3f41;stroke-width:0.17704;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="rect2148-5"
|
||||
width="0.64708883"
|
||||
height="0.780729"
|
||||
x="2.9944377"
|
||||
y="4.4343238" />
|
||||
<rect
|
||||
style="opacity:1;mix-blend-mode:normal;fill:#afb1b3;fill-opacity:1;stroke:#3c3f41;stroke-width:0.17704;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="rect2148-5-4"
|
||||
width="0.64708883"
|
||||
height="0.780729"
|
||||
x="3.8850529"
|
||||
y="4.4343238" />
|
||||
<rect
|
||||
style="opacity:1;mix-blend-mode:normal;fill:#afb1b3;fill-opacity:1;stroke:#3c3f41;stroke-width:0.17704;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="rect2148-6"
|
||||
width="0.64708883"
|
||||
height="0.78059679"
|
||||
x="2.1040154"
|
||||
y="1.5483496" />
|
||||
<rect
|
||||
style="opacity:1;mix-blend-mode:normal;fill:#afb1b3;fill-opacity:1;stroke:#3c3f41;stroke-width:0.17704;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="rect2148-5-9"
|
||||
width="0.64708883"
|
||||
height="0.78059679"
|
||||
x="2.9944377"
|
||||
y="1.5484595" />
|
||||
<rect
|
||||
style="opacity:1;mix-blend-mode:normal;fill:#afb1b3;fill-opacity:1;stroke:#3c3f41;stroke-width:0.17704;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="rect2148-5-4-3"
|
||||
width="0.64708883"
|
||||
height="0.78059679"
|
||||
x="3.8850529"
|
||||
y="1.5484595" />
|
||||
</g>
|
||||
<g
|
||||
inkscape:label="Body"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
style="display:inline;opacity:1">
|
||||
<rect
|
||||
style="opacity:1;fill:#cccccc;fill-opacity:0;stroke:none;stroke-width:0.033241;stroke-opacity:0.462745"
|
||||
id="rect1580"
|
||||
width="3.31515"
|
||||
height="3.8507297"
|
||||
x="1.3077724"
|
||||
y="1.3337646" />
|
||||
<rect
|
||||
style="opacity:1;fill:#cccccc;fill-opacity:0;stroke:none;stroke-width:0.033241;stroke-opacity:0.462745"
|
||||
id="rect1582"
|
||||
width="1.9564158"
|
||||
height="2.2731953"
|
||||
x="2.4013965"
|
||||
y="1.82679" />
|
||||
<rect
|
||||
style="opacity:1;fill:#afb1b3;fill-opacity:1;stroke:#3c3f41;stroke-width:0.246372;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;image-rendering:auto"
|
||||
id="rect1584"
|
||||
width="1.9841725"
|
||||
height="3.8165693"
|
||||
x="2.3896153"
|
||||
y="-5.2069626"
|
||||
transform="rotate(90)" />
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 4.2 KiB |
@@ -0,0 +1,63 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="30"
|
||||
height="30"
|
||||
viewBox="0 0 30 30"
|
||||
version="1.1"
|
||||
id="svg2664"
|
||||
sodipodi:docname="refresh-disabled.svg"
|
||||
inkscape:version="1.0.1 (1.0.1+r75)"
|
||||
style="opacity:1">
|
||||
<metadata
|
||||
id="metadata2670">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title />
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<defs
|
||||
id="defs2668" />
|
||||
<sodipodi:namedview
|
||||
pagecolor="#3c3f41"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1"
|
||||
objecttolerance="10"
|
||||
gridtolerance="10"
|
||||
guidetolerance="10"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:window-width="3440"
|
||||
inkscape:window-height="1353"
|
||||
id="namedview2666"
|
||||
showgrid="false"
|
||||
inkscape:zoom="29.698485"
|
||||
inkscape:cx="21.658431"
|
||||
inkscape:cy="16.320612"
|
||||
inkscape:window-x="2560"
|
||||
inkscape:window-y="34"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="layer4"
|
||||
inkscape:document-rotation="0" />
|
||||
<g
|
||||
inkscape:groupmode="layer"
|
||||
id="layer4"
|
||||
inkscape:label="Layer 1"
|
||||
style="opacity:0.35">
|
||||
<path
|
||||
d="M 12,15 7.537,19.969 3,15 h 3 c 0,-4.97 4.03,-9 9,-9 2.395,0 4.565,0.942 6.179,2.468 l -2.004,2.231 C 18.094,9.649 16.622,9 15,9 11.691,9 9,11.691 9,15 Z M 22.463,10.031 18,15 h 3 c 0,3.309 -2.691,6 -6,6 -1.623,0 -3.094,-0.65 -4.175,-1.699 L 8.821,21.532 C 10.434,23.058 12.605,24 15,24 c 4.97,0 9,-4.03 9,-9 h 3 z"
|
||||
id="path2662"
|
||||
style="opacity:1;fill:#a6a8ab;fill-opacity:1" />
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.0 KiB |
56
src/Insight/UserInterfaces/InsightWindow/Images/refresh.svg
Normal file
56
src/Insight/UserInterfaces/InsightWindow/Images/refresh.svg
Normal file
@@ -0,0 +1,56 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="30"
|
||||
height="30"
|
||||
viewBox="0 0 30 30"
|
||||
version="1.1"
|
||||
id="svg2664"
|
||||
sodipodi:docname="refresh.svg"
|
||||
inkscape:version="1.0.1 (1.0.1+r75)">
|
||||
<metadata
|
||||
id="metadata2670">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title />
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<defs
|
||||
id="defs2668" />
|
||||
<sodipodi:namedview
|
||||
pagecolor="#3c3f41"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1"
|
||||
objecttolerance="10"
|
||||
gridtolerance="10"
|
||||
guidetolerance="10"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:window-width="2560"
|
||||
inkscape:window-height="1353"
|
||||
id="namedview2666"
|
||||
showgrid="false"
|
||||
inkscape:zoom="29.698485"
|
||||
inkscape:cx="21.843683"
|
||||
inkscape:cy="16.338347"
|
||||
inkscape:window-x="6000"
|
||||
inkscape:window-y="24"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="svg2664"
|
||||
inkscape:document-rotation="0" />
|
||||
<path
|
||||
d="M 12,15 7.537,19.969 3,15 h 3 c 0,-4.97 4.03,-9 9,-9 2.395,0 4.565,0.942 6.179,2.468 l -2.004,2.231 C 18.094,9.649 16.622,9 15,9 11.691,9 9,11.691 9,15 Z M 22.463,10.031 18,15 h 3 c 0,3.309 -2.691,6 -6,6 -1.623,0 -3.094,-0.65 -4.175,-1.699 L 8.821,21.532 C 10.434,23.058 12.605,24 15,24 c 4.97,0 9,-4.03 9,-9 h 3 z"
|
||||
id="path2662"
|
||||
style="fill:#a6a8ab;fill-opacity:1" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.9 KiB |
264
src/Insight/UserInterfaces/InsightWindow/InsightWindow.cpp
Normal file
264
src/Insight/UserInterfaces/InsightWindow/InsightWindow.cpp
Normal file
@@ -0,0 +1,264 @@
|
||||
#include <QtUiTools>
|
||||
#include <QtSvg/QtSvg>
|
||||
|
||||
#include "InsightWindow.hpp"
|
||||
#include "AboutWindow.hpp"
|
||||
#include "TargetWidgets/DIP/DualInlinePackageWidget.hpp"
|
||||
#include "TargetWidgets/QFP/QuadFlatPackageWidget.hpp"
|
||||
#include "src/Logger/Logger.hpp"
|
||||
#include "src/Exceptions/Exception.hpp"
|
||||
#include "src/Targets/TargetDescriptor.hpp"
|
||||
|
||||
using namespace Bloom;
|
||||
using namespace Exceptions;
|
||||
using Targets::TargetDescriptor;
|
||||
using Targets::TargetVariant;
|
||||
using Targets::TargetPackage;
|
||||
|
||||
|
||||
void InsightWindow::init(QApplication& application, TargetDescriptor targetDescriptor) {
|
||||
this->targetDescriptor = targetDescriptor;
|
||||
|
||||
auto mainWindowUiFile = QFile(":/compiled/Insight/UserInterfaces/InsightWindow/UiFiles/InsightWindow.ui");
|
||||
auto mainWindowStylesheet = QFile(":/compiled/Insight/UserInterfaces/InsightWindow/Stylesheets/InsightWindow.qss");
|
||||
|
||||
if (!mainWindowUiFile.open(QFile::ReadOnly)) {
|
||||
throw Exception("Failed to open InsightWindow UI file");
|
||||
}
|
||||
|
||||
if (!mainWindowStylesheet.open(QFile::ReadOnly)) {
|
||||
throw Exception("Failed to open InsightWindow stylesheet file");
|
||||
}
|
||||
|
||||
auto uiLoader = QUiLoader(this);
|
||||
this->mainWindowWidget = uiLoader.load(&mainWindowUiFile);
|
||||
this->mainWindowWidget->setStyleSheet(mainWindowStylesheet.readAll());
|
||||
|
||||
application.setWindowIcon(QIcon(":/compiled/Insight/UserInterfaces/InsightWindow/Images/BloomIcon.svg"));
|
||||
this->ioContainerWidget = this->mainWindowWidget->findChild<QWidget*>("io-container");
|
||||
this->ioUnavailableWidget = this->mainWindowWidget->findChild<QWidget*>("io-inspection-unavailable");
|
||||
this->mainMenuBar = this->mainWindowWidget->findChild<QMenuBar*>("menu-bar");
|
||||
|
||||
auto fileMenu = this->mainMenuBar->findChild<QMenu*>("file-menu");
|
||||
auto helpMenu = this->mainMenuBar->findChild<QMenu*>("help-menu");
|
||||
auto quitAction = fileMenu->findChild<QAction*>("close-insight");
|
||||
auto openReportIssuesUrlAction = helpMenu->findChild<QAction*>("open-report-issues-url");
|
||||
auto openAboutWindowAction = helpMenu->findChild<QAction*>("open-about-dialogue");
|
||||
|
||||
connect(quitAction, &QAction::triggered, this, &InsightWindow::close);
|
||||
connect(openReportIssuesUrlAction, &QAction::triggered, this, &InsightWindow::openReportIssuesUrl);
|
||||
connect(openAboutWindowAction, &QAction::triggered, this, &InsightWindow::openAboutWindow);
|
||||
|
||||
this->header = this->mainWindowWidget->findChild<QWidget*>("header");
|
||||
this->refreshIoInspectionButton = this->header->findChild<QToolButton*>("refresh-io-inspection-btn");
|
||||
|
||||
connect(this->refreshIoInspectionButton, &QToolButton::clicked, this, [this] {
|
||||
if (this->targetState == TargetState::STOPPED && this->selectedVariant != nullptr) {
|
||||
this->toggleUi(true);
|
||||
emit this->refreshTargetPinStates(this->selectedVariant->id);
|
||||
}
|
||||
});
|
||||
|
||||
this->footer = this->mainWindowWidget->findChild<QWidget*>("footer");
|
||||
auto targetNameLabel = this->footer->findChild<QLabel*>("target-name");
|
||||
auto targetIdLabel = this->footer->findChild<QLabel*>("target-id");
|
||||
this->targetStatusLabel = this->footer->findChild<QLabel*>("target-state");
|
||||
this->programCounterValueLabel = this->footer->findChild<QLabel*>("target-program-counter-value");
|
||||
targetNameLabel->setText(QString::fromStdString(this->targetDescriptor.name));
|
||||
targetIdLabel->setText("0x" + QString::fromStdString(this->targetDescriptor.id).remove("0x").toUpper());
|
||||
|
||||
this->variantMenu = this->footer->findChild<QMenu*>("target-variant-menu");
|
||||
|
||||
for (const auto& targetVariant: this->targetDescriptor.variants) {
|
||||
auto variantAction = new QAction(this->variantMenu);
|
||||
variantAction->setText(
|
||||
QString::fromStdString(targetVariant.name + " (" + targetVariant.packageName + ")")
|
||||
);
|
||||
|
||||
if (this->isVariantSupported(targetVariant)) {
|
||||
connect(
|
||||
variantAction,
|
||||
&QAction::triggered,
|
||||
this,
|
||||
[this, &targetVariant] {
|
||||
this->selectVariant(&targetVariant);
|
||||
}
|
||||
);
|
||||
|
||||
} else {
|
||||
variantAction->setEnabled(false);
|
||||
variantAction->setText(variantAction->text() + " (unsupported)");
|
||||
|
||||
};
|
||||
|
||||
this->variantMenu->addAction(variantAction);
|
||||
}
|
||||
|
||||
std::copy_if(
|
||||
this->targetDescriptor.variants.begin(),
|
||||
this->targetDescriptor.variants.end(),
|
||||
std::back_inserter(this->supportedVariants),
|
||||
[this](auto variant) {
|
||||
return this->isVariantSupported(variant);
|
||||
}
|
||||
);
|
||||
|
||||
Logger::debug("Number of target variants supported by Insight: " + std::to_string(supportedVariants.size()));
|
||||
|
||||
if (!supportedVariants.empty()) {
|
||||
this->selectVariant(&supportedVariants.front());
|
||||
|
||||
} else {
|
||||
if (this->targetDescriptor.variants.empty()) {
|
||||
this->variantMenu->parentWidget()->hide();
|
||||
}
|
||||
|
||||
this->ioUnavailableWidget->show();
|
||||
}
|
||||
}
|
||||
|
||||
void InsightWindow::selectVariant(const TargetVariant* variant) {
|
||||
if (!this->isVariantSupported(*variant)) {
|
||||
Logger::error("Attempted to select unsupported target variant.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (this->selectedVariant != nullptr && this->selectedVariant->id == variant->id) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (this->targetPackageWidget != nullptr) {
|
||||
this->targetPackageWidget->hide();
|
||||
this->targetPackageWidget->deleteLater();
|
||||
}
|
||||
|
||||
this->selectedVariant = variant;
|
||||
this->variantMenu->setTitle(QString::fromStdString(variant->name + " (" + variant->packageName + ")"));
|
||||
|
||||
if (variant->package == TargetPackage::DIP) {
|
||||
this->targetPackageWidget = new InsightTargetWidgets::Dip::DualInlinePackageWidget(
|
||||
*variant,
|
||||
this,
|
||||
this->ioContainerWidget
|
||||
);
|
||||
|
||||
} else if (variant->package == TargetPackage::QFP) {
|
||||
this->targetPackageWidget = new InsightTargetWidgets::Qfp::QuadFlatPackageWidget(
|
||||
*variant,
|
||||
this,
|
||||
this->ioContainerWidget
|
||||
);
|
||||
}
|
||||
|
||||
if (this->targetPackageWidget != nullptr) {
|
||||
if (this->targetState == TargetState::STOPPED) {
|
||||
this->toggleUi(true);
|
||||
emit this->refreshTargetPinStates(variant->id);
|
||||
}
|
||||
|
||||
this->targetPackageWidget->show();
|
||||
}
|
||||
}
|
||||
|
||||
void InsightWindow::show() {
|
||||
this->mainWindowWidget->activateWindow();
|
||||
this->mainWindowWidget->show();
|
||||
}
|
||||
|
||||
void InsightWindow::close() {
|
||||
if (this->mainWindowWidget != nullptr) {
|
||||
this->mainWindowWidget->close();
|
||||
}
|
||||
}
|
||||
|
||||
bool InsightWindow::isVariantSupported(const TargetVariant& variant) {
|
||||
if (variant.package == TargetPackage::DIP) {
|
||||
// All DIP variants must have a pin count that is a multiple of two
|
||||
if (variant.pinDescriptorsByNumber.size() % 2 == 0) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (variant.package == TargetPackage::QFP) {
|
||||
// All QFP variants must have a pin count that is a multiple of four
|
||||
if (variant.pinDescriptorsByNumber.size() % 4 == 0) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void InsightWindow::openReportIssuesUrl() {
|
||||
QDesktopServices::openUrl(QUrl("https://bloom.oscillate.io/report-issue"));
|
||||
}
|
||||
|
||||
void InsightWindow::openAboutWindow() {
|
||||
if (this->aboutWindowWidget == nullptr) {
|
||||
this->aboutWindowWidget = new AboutWindow(this->mainWindowWidget);
|
||||
}
|
||||
|
||||
this->aboutWindowWidget->show();
|
||||
}
|
||||
|
||||
void InsightWindow::onTargetStateUpdate(TargetState newState) {
|
||||
this->targetState = newState;
|
||||
|
||||
if (newState == TargetState::RUNNING) {
|
||||
this->targetStatusLabel->setText("Running");
|
||||
this->programCounterValueLabel->setText("-");
|
||||
this->toggleUi(true);
|
||||
|
||||
} else if (newState == TargetState::STOPPED) {
|
||||
this->targetStatusLabel->setText("Stopped");
|
||||
|
||||
if (this->selectedVariant != nullptr) {
|
||||
emit this->refreshTargetPinStates(this->selectedVariant->id);
|
||||
}
|
||||
|
||||
} else {
|
||||
this->targetStatusLabel->setText("Unknown");
|
||||
}
|
||||
}
|
||||
|
||||
void InsightWindow::onTargetProgramCounterUpdate(quint32 programCounter) {
|
||||
this->programCounterValueLabel->setText(
|
||||
"0x" + QString::number(programCounter, 16).toUpper() + " (" + QString::number(programCounter) + ")"
|
||||
);
|
||||
}
|
||||
|
||||
void InsightWindow::onTargetIoPortsUpdate() {
|
||||
if (this->targetState == TargetState::STOPPED && this->selectedVariant != nullptr) {
|
||||
emit this->refreshTargetPinStates(this->selectedVariant->id);
|
||||
}
|
||||
}
|
||||
|
||||
void InsightWindow::onTargetPinStatesUpdate(int variantId, Bloom::Targets::TargetPinStateMappingType pinStatesByNumber) {
|
||||
if (this->targetPackageWidget != nullptr
|
||||
&& this->selectedVariant != nullptr
|
||||
&& this->selectedVariant->id == variantId
|
||||
) {
|
||||
this->targetPackageWidget->updatePinStates(pinStatesByNumber);
|
||||
if (this->uiDisabled) {
|
||||
this->toggleUi(false);
|
||||
|
||||
} else {
|
||||
this->targetPackageWidget->repaint();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void InsightWindow::togglePinIoState(TargetPinWidget* pinWidget) {
|
||||
auto pinState = pinWidget->getPinState();
|
||||
|
||||
// Currently, we only allow users to toggle the IO state of output pins
|
||||
if (pinState.has_value()
|
||||
&& pinState.value().ioDirection == TargetPinState::IoDirection::OUTPUT
|
||||
&& this->selectedVariant != nullptr
|
||||
) {
|
||||
auto& pinDescriptor = pinWidget->getPinDescriptor();
|
||||
pinState.value().ioState = (pinState.value().ioState == TargetPinState::IoState::HIGH) ?
|
||||
TargetPinState::IoState::LOW : TargetPinState::IoState::HIGH;
|
||||
emit this->setTargetPinState(this->selectedVariant->id, pinDescriptor, pinState.value());
|
||||
}
|
||||
}
|
||||
97
src/Insight/UserInterfaces/InsightWindow/InsightWindow.hpp
Normal file
97
src/Insight/UserInterfaces/InsightWindow/InsightWindow.hpp
Normal file
@@ -0,0 +1,97 @@
|
||||
#pragma once
|
||||
|
||||
#include <QtCore>
|
||||
#include <QMainWindow>
|
||||
#include <QtUiTools/QtUiTools>
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
#include <src/Logger/Logger.hpp>
|
||||
|
||||
#include "AboutWindow.hpp"
|
||||
#include "TargetWidgets/TargetPackageWidget.hpp"
|
||||
#include "src/Targets/TargetState.hpp"
|
||||
#include "src/Targets/TargetDescriptor.hpp"
|
||||
#include "src/Targets/TargetVariant.hpp"
|
||||
|
||||
namespace Bloom
|
||||
{
|
||||
using InsightTargetWidgets::TargetPackageWidget;
|
||||
using InsightTargetWidgets::TargetPinWidget;
|
||||
|
||||
using Targets::TargetDescriptor;
|
||||
using Targets::TargetVariant;
|
||||
using Targets::TargetPackage;
|
||||
using Targets::TargetState;
|
||||
using Targets::TargetPinState;
|
||||
|
||||
class InsightWindow: public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
private:
|
||||
TargetDescriptor targetDescriptor;
|
||||
TargetState targetState = TargetState::UNKNOWN;
|
||||
|
||||
QWidget* mainWindowWidget = nullptr;
|
||||
AboutWindow* aboutWindowWidget = nullptr;
|
||||
QMenuBar* mainMenuBar = nullptr;
|
||||
QMenu* variantMenu = nullptr;
|
||||
|
||||
QWidget* header = nullptr;
|
||||
QToolButton* refreshIoInspectionButton = nullptr;
|
||||
|
||||
QWidget* ioContainerWidget = nullptr;
|
||||
QWidget* ioUnavailableWidget = nullptr;
|
||||
TargetPackageWidget* targetPackageWidget = nullptr;
|
||||
|
||||
QWidget* footer = nullptr;
|
||||
QLabel* targetStatusLabel = nullptr;
|
||||
QLabel* programCounterValueLabel = nullptr;
|
||||
|
||||
std::vector<TargetVariant> supportedVariants;
|
||||
const TargetVariant* selectedVariant = nullptr;
|
||||
bool uiDisabled = false;
|
||||
|
||||
bool isVariantSupported(const TargetVariant& variant);
|
||||
|
||||
void selectVariant(const TargetVariant* variant);
|
||||
|
||||
void toggleUi(bool disable) {
|
||||
this->uiDisabled = disable;
|
||||
|
||||
if (this->refreshIoInspectionButton != nullptr) {
|
||||
this->refreshIoInspectionButton->setDisabled(disable);
|
||||
this->refreshIoInspectionButton->repaint();
|
||||
}
|
||||
|
||||
if (this->ioContainerWidget != nullptr) {
|
||||
this->ioContainerWidget->setDisabled(disable);
|
||||
this->ioContainerWidget->repaint();
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
InsightWindow() = default;
|
||||
|
||||
void init(QApplication& application, Targets::TargetDescriptor targetDescriptor);
|
||||
|
||||
void show();
|
||||
|
||||
public slots:
|
||||
void onTargetPinStatesUpdate(int variantId, Bloom::Targets::TargetPinStateMappingType pinStatesByNumber);
|
||||
void onTargetStateUpdate(TargetState newState);
|
||||
void onTargetProgramCounterUpdate(quint32 programCounter);
|
||||
void onTargetIoPortsUpdate();
|
||||
void close();
|
||||
void openReportIssuesUrl();
|
||||
void openAboutWindow();
|
||||
void togglePinIoState(TargetPinWidget* pinWidget);
|
||||
|
||||
signals:
|
||||
void refreshTargetPinStates(int variantId);
|
||||
void setTargetPinState(
|
||||
int variantId,
|
||||
Bloom::Targets::TargetPinDescriptor pinDescriptor,
|
||||
Bloom::Targets::TargetPinState pinState
|
||||
);
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
* {
|
||||
color: #c2c4c6;
|
||||
font-family: 'Ubuntu', sans-serif;
|
||||
}
|
||||
|
||||
QMainWindow {
|
||||
background-color: #3C3F41;
|
||||
}
|
||||
|
||||
|
||||
#bloom-icon {
|
||||
min-height: 150px;
|
||||
min-width: 150px;
|
||||
max-height: 150px;
|
||||
max-width: 150px;
|
||||
image: url(":/compiled/Insight/UserInterfaces/InsightWindow/Images/BloomIcon.svg");
|
||||
image-position: center;
|
||||
}
|
||||
|
||||
#author-label {
|
||||
font-size: 14px;
|
||||
color: #adadb1;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,190 @@
|
||||
* {
|
||||
color: #c2c4c6;
|
||||
font-family: 'Ubuntu', sans-serif;
|
||||
}
|
||||
|
||||
QMainWindow {
|
||||
background-color: #3C3F41;
|
||||
}
|
||||
|
||||
#header {
|
||||
position: relative;
|
||||
background-color: transparent;
|
||||
max-height: 25px;
|
||||
width: auto;
|
||||
border-top: 1px solid #515151;
|
||||
border-bottom: 1px solid #515151;
|
||||
}
|
||||
|
||||
QMenuBar::item {
|
||||
position: relative;
|
||||
margin: 0;
|
||||
top: 0;
|
||||
padding-top: 0;
|
||||
padding-bottom: 1px;
|
||||
padding-right: 4px;
|
||||
padding-left: 4px;
|
||||
background-color: transparent;
|
||||
float: left;
|
||||
font-size: 14px;
|
||||
border: none;
|
||||
}
|
||||
|
||||
QMenuBar::item:pressed {
|
||||
background-color: #2F65CA;
|
||||
}
|
||||
|
||||
QMenuBar {
|
||||
border: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
min-height: 24px;
|
||||
background-color: transparent;
|
||||
spacing: 0;
|
||||
color: #c2c4c6;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
QMenu {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
background-color: #3C3F41;
|
||||
color: #c2c4c6;
|
||||
border: 1px solid #515151;
|
||||
min-width: 200px;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
QMenu::item {
|
||||
padding: 4px 5px 4px 25px;
|
||||
min-width: 200px;
|
||||
}
|
||||
|
||||
QMenu::item:selected {
|
||||
background-color: #2F65CA;
|
||||
}
|
||||
|
||||
QMenu::item:disabled {
|
||||
color: #808484;
|
||||
}
|
||||
|
||||
QMenu#help-menu::separator {
|
||||
border-top: 1px solid #515151;
|
||||
height: 1px;
|
||||
margin: 1px 0;
|
||||
}
|
||||
|
||||
#rhSideBar {
|
||||
max-width: 25px;
|
||||
background-color: transparent;
|
||||
height: auto;
|
||||
border-left: 1px solid #515151;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
#rhSideBar #inspectRamBtn {
|
||||
position: relative;
|
||||
max-width: 25px;
|
||||
height: 25px;
|
||||
color: #000;
|
||||
border: none;
|
||||
qproperty-icon: url(":/compiled/Insight/UserInterfaces/InsightWindow/Images/RAM.svg");
|
||||
icon-size: 25px;
|
||||
}
|
||||
|
||||
#rhSideBar #inspectRamBtn:hover {
|
||||
background-color: #343536;
|
||||
border: none;
|
||||
|
||||
}
|
||||
|
||||
#header-tool-bar {
|
||||
min-height: 25px;
|
||||
min-width: 100%;
|
||||
}
|
||||
|
||||
#header-tool-bar QToolButton {
|
||||
background-color: transparent;
|
||||
max-width: 25px;
|
||||
max-height: 21px;
|
||||
border: none;
|
||||
padding: 0;
|
||||
margin-top: 3px;
|
||||
margin-bottom: 3px;
|
||||
margin-left: 2px;
|
||||
}
|
||||
|
||||
#header-tool-bar QToolButton:hover {
|
||||
background-color: #505353;
|
||||
border: none;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
QToolTip {
|
||||
background-color: #474949;
|
||||
border: 1px solid #616365;
|
||||
color: #c2c4c6;
|
||||
padding: 1px 2px;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
|
||||
#footer {
|
||||
position: relative;
|
||||
background-color: transparent;
|
||||
padding: 0 3px 0 30px;
|
||||
max-height: 25px;
|
||||
width: auto;
|
||||
border-top: 1px solid #515151;
|
||||
|
||||
}
|
||||
|
||||
#footer QLabel,
|
||||
#target-variant-menu-bar,
|
||||
#footer QMenu::item {
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
#target-variant-menu-bar::item {
|
||||
padding: 0 10px 0 4px;
|
||||
border-left: 1px solid #515151;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
#target-variant-menu-bar::item:selected {
|
||||
background-color: #4d4e50;
|
||||
}
|
||||
|
||||
#footer QLabel {
|
||||
margin-left: 3px;
|
||||
}
|
||||
|
||||
#target-program-counter-value {
|
||||
border-color: #515151;
|
||||
border-style: solid;
|
||||
border-width: 0 1px 0 0;
|
||||
padding-right: 5px;
|
||||
margin-right: 3px;
|
||||
}
|
||||
|
||||
#target-name {
|
||||
max-width: 200px;
|
||||
padding-right: 0;
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
#target-id {
|
||||
margin-right: 6px;
|
||||
}
|
||||
|
||||
#target-variant-menu-bar {
|
||||
min-height: 25px;
|
||||
}
|
||||
|
||||
#footer QLayoutItem {
|
||||
max-width: 100px;
|
||||
}
|
||||
|
||||
#target-variant-menu::item {
|
||||
padding: 4px 10px 4px 10px;
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
#include <QPainter>
|
||||
#include <cmath>
|
||||
|
||||
#include "BodyWidget.hpp"
|
||||
#include "src/Logger/Logger.hpp"
|
||||
#include "src/Exceptions/Exception.hpp"
|
||||
|
||||
using namespace Bloom::InsightTargetWidgets::Dip;
|
||||
using namespace Bloom::Exceptions;
|
||||
|
||||
void BodyWidget::paintEvent(QPaintEvent* event) {
|
||||
auto painter = QPainter(this);
|
||||
this->drawWidget(painter);
|
||||
}
|
||||
|
||||
void BodyWidget::drawWidget(QPainter& painter) {
|
||||
auto parentWidget = this->parentWidget();
|
||||
|
||||
if (parentWidget == nullptr) {
|
||||
throw Exception("BodyWidget requires a parent widget");
|
||||
}
|
||||
|
||||
painter.setRenderHints(QPainter::RenderHint::Antialiasing | QPainter::RenderHint::SmoothPixmapTransform, true);
|
||||
|
||||
// Draw target body
|
||||
// auto targetBodyColor = QColor("#AFB1B3");
|
||||
auto targetBodyColor = this->getBodyColor();
|
||||
auto backgroundColor = QColor("#3C3F41");
|
||||
|
||||
if (!this->isEnabled()) {
|
||||
targetBodyColor.setAlpha(this->getDisableAlphaLevel());
|
||||
}
|
||||
|
||||
painter.setPen(Qt::PenStyle::NoPen);
|
||||
painter.setBrush(targetBodyColor);
|
||||
auto parentContainerWidth = parentWidget->width();
|
||||
// this->setFixedSize(parentContainerWidth, parentContainerHeight);
|
||||
auto targetBodyHeight = 150;
|
||||
auto targetBodyWidth = parentContainerWidth;
|
||||
|
||||
this->setFixedSize(targetBodyWidth, targetBodyHeight);
|
||||
auto targetBodyPoint = QPoint(
|
||||
0,
|
||||
0
|
||||
);
|
||||
|
||||
painter.drawRect(
|
||||
targetBodyPoint.x(),
|
||||
targetBodyPoint.y(),
|
||||
targetBodyWidth,
|
||||
targetBodyHeight
|
||||
);
|
||||
|
||||
painter.setPen(Qt::PenStyle::NoPen);
|
||||
painter.setBrush(backgroundColor);
|
||||
painter.drawEllipse(QRectF(
|
||||
targetBodyPoint.x() + 10,
|
||||
targetBodyPoint.y() + (targetBodyHeight - 30),
|
||||
20,
|
||||
20
|
||||
));
|
||||
|
||||
painter.drawEllipse(QRectF(
|
||||
targetBodyPoint.x() - 15,
|
||||
targetBodyPoint.y() + (targetBodyHeight / 2) - 15,
|
||||
30,
|
||||
30
|
||||
));
|
||||
}
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
#pragma once
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
namespace Bloom::InsightTargetWidgets::Dip
|
||||
{
|
||||
class BodyWidget: public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(QColor bodyColor READ getBodyColor WRITE setBodyColor DESIGNABLE true)
|
||||
Q_PROPERTY(int disableAlphaLevel READ getDisableAlphaLevel WRITE setDisableAlphaLevel DESIGNABLE true)
|
||||
|
||||
private:
|
||||
QColor bodyColor = QColor("#AFB1B3");
|
||||
int disableAlphaLevel = 100;
|
||||
|
||||
protected:
|
||||
void paintEvent(QPaintEvent* event);
|
||||
void drawWidget(QPainter& painter);
|
||||
|
||||
public:
|
||||
BodyWidget(QWidget* parent): QWidget(parent) {
|
||||
this->setObjectName("target-body");
|
||||
}
|
||||
|
||||
QColor getBodyColor() const {
|
||||
return this->bodyColor;
|
||||
}
|
||||
|
||||
void setBodyColor(QColor color) {
|
||||
this->bodyColor = color;
|
||||
}
|
||||
|
||||
int getDisableAlphaLevel() const {
|
||||
return this->disableAlphaLevel;
|
||||
}
|
||||
|
||||
void setDisableAlphaLevel(int level) {
|
||||
this->disableAlphaLevel = level;
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,119 @@
|
||||
#include <QPainter>
|
||||
#include <QVBoxLayout>
|
||||
#include <QHBoxLayout>
|
||||
#include <vector>
|
||||
#include <QEvent>
|
||||
#include <QFile>
|
||||
|
||||
#include "../../InsightWindow.hpp"
|
||||
#include "DualInlinePackageWidget.hpp"
|
||||
#include "src/Logger/Logger.hpp"
|
||||
#include "src/Exceptions/Exception.hpp"
|
||||
#include "PinWidget.hpp"
|
||||
#include "BodyWidget.hpp"
|
||||
|
||||
using namespace Bloom::InsightTargetWidgets::Dip;
|
||||
using namespace Bloom::Exceptions;
|
||||
|
||||
DualInlinePackageWidget::DualInlinePackageWidget(const TargetVariant& targetVariant, QObject* insightWindowObj, QWidget* parent):
|
||||
TargetPackageWidget(targetVariant, insightWindowObj, parent) {
|
||||
auto stylesheetFile = QFile("/home/nav/Projects/Bloom/src/Insight/UserInterfaces/InsightWindow/TargetWidgets/DIP/Stylesheets/DualInlinePackage.qss");
|
||||
stylesheetFile.open(QFile::ReadOnly);
|
||||
this->setStyleSheet(stylesheetFile.readAll());
|
||||
|
||||
this->pinWidgets.reserve(targetVariant.pinDescriptorsByNumber.size());
|
||||
this->layout = new QVBoxLayout();
|
||||
this->layout->setSpacing(8);
|
||||
this->layout->setMargin(0);
|
||||
|
||||
this->topPinLayout = new QHBoxLayout();
|
||||
this->topPinLayout->setSpacing(8);
|
||||
this->topPinLayout->setDirection(QBoxLayout::Direction::RightToLeft);
|
||||
this->bottomPinLayout = new QHBoxLayout();
|
||||
this->bottomPinLayout->setSpacing(8);
|
||||
|
||||
auto insightWindow = qobject_cast<InsightWindow*>(insightWindowObj);
|
||||
assert(insightWindow != nullptr);
|
||||
|
||||
for (const auto& [targetPinNumber, targetPinDescriptor]: targetVariant.pinDescriptorsByNumber) {
|
||||
auto pinWidget = new PinWidget(this, targetPinDescriptor, targetVariant);
|
||||
this->pinWidgets.push_back(pinWidget);
|
||||
|
||||
if (targetPinNumber <= (targetVariant.pinDescriptorsByNumber.size() / 2)) {
|
||||
this->bottomPinLayout->addWidget(pinWidget, 0, Qt::AlignmentFlag::AlignHCenter);
|
||||
} else {
|
||||
this->topPinLayout->addWidget(pinWidget, 0, Qt::AlignmentFlag::AlignRight);
|
||||
}
|
||||
|
||||
connect(pinWidget, &TargetPinWidget::toggleIoState, insightWindow, &InsightWindow::togglePinIoState);
|
||||
}
|
||||
|
||||
this->layout->addLayout(this->topPinLayout);
|
||||
this->bodyWidget = new BodyWidget(this);
|
||||
this->layout->addWidget(this->bodyWidget);
|
||||
this->layout->addLayout(this->bottomPinLayout);
|
||||
this->setLayout(this->layout);
|
||||
|
||||
auto insightWindowWidget = this->window();
|
||||
assert(insightWindowWidget != nullptr);
|
||||
|
||||
insightWindowWidget->setMinimumHeight(500);
|
||||
insightWindowWidget->setMinimumWidth(1000);
|
||||
}
|
||||
|
||||
void DualInlinePackageWidget::paintEvent(QPaintEvent* event) {
|
||||
// Logger::debug("Drawing main package widget");
|
||||
|
||||
auto painter = QPainter(this);
|
||||
this->drawWidget(painter);
|
||||
}
|
||||
|
||||
void DualInlinePackageWidget::resizeEvent(QResizeEvent* event) {
|
||||
// Logger::debug("RESIZE EVENT");
|
||||
}
|
||||
|
||||
void DualInlinePackageWidget::drawWidget(QPainter& painter) {
|
||||
auto parentWidget = this->parentWidget();
|
||||
|
||||
if (parentWidget == nullptr) {
|
||||
throw Exception("DualInlinePackageWidget requires a parent widget");
|
||||
}
|
||||
|
||||
auto parentContainerHeight = parentWidget->height();
|
||||
auto parentContainerWidth = parentWidget->width();
|
||||
|
||||
auto width = ((PinWidget::MINIMUM_WIDTH + 8) * static_cast<int>(this->pinWidgets.size() / 2)) + 46;
|
||||
|
||||
this->topPinLayout->setGeometry(QRect(0, 0, width, PinWidget::MAXIMUM_HEIGHT));
|
||||
auto bodyGeometry = QRect(0, this->topPinLayout->geometry().height() + 8, width, this->bodyWidget->height());
|
||||
this->bodyWidget->setGeometry(bodyGeometry);
|
||||
this->bottomPinLayout->setGeometry(
|
||||
QRect(
|
||||
0,
|
||||
bodyGeometry.top() + bodyGeometry.height() + 8,
|
||||
width,
|
||||
PinWidget::MAXIMUM_HEIGHT
|
||||
)
|
||||
);
|
||||
this->topPinLayout->setContentsMargins(
|
||||
static_cast<int>(width * 0.04),
|
||||
0,
|
||||
static_cast<int>(width * 0.04),
|
||||
0
|
||||
);
|
||||
this->bottomPinLayout->setContentsMargins(
|
||||
static_cast<int>(width * 0.04),
|
||||
0,
|
||||
static_cast<int>(width * 0.04),
|
||||
0
|
||||
);
|
||||
|
||||
auto height = (PinWidget::MAXIMUM_HEIGHT * 2) + bodyGeometry.height() + (8 * 3);
|
||||
this->setGeometry(
|
||||
(parentContainerWidth / 2) - (width / 2),
|
||||
(parentContainerHeight / 2) - (height / 2),
|
||||
width,
|
||||
height
|
||||
);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
#pragma once
|
||||
|
||||
#include <QWidget>
|
||||
#include <vector>
|
||||
#include <QHBoxLayout>
|
||||
#include <QVBoxLayout>
|
||||
|
||||
#include "../TargetPackageWidget.hpp"
|
||||
#include "PinWidget.hpp"
|
||||
#include "BodyWidget.hpp"
|
||||
#include "src/Targets/TargetVariant.hpp"
|
||||
|
||||
namespace Bloom::InsightTargetWidgets::Dip
|
||||
{
|
||||
using Targets::TargetVariant;
|
||||
|
||||
/**
|
||||
* The DualInlinePackageWidget implements a custom Qt widget for the Dual-inline package target variants.
|
||||
*/
|
||||
class DualInlinePackageWidget: public TargetPackageWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
private:
|
||||
QVBoxLayout* layout = nullptr;
|
||||
QHBoxLayout* topPinLayout = nullptr;
|
||||
QHBoxLayout* bottomPinLayout = nullptr;
|
||||
BodyWidget* bodyWidget = nullptr;
|
||||
|
||||
protected:
|
||||
void paintEvent(QPaintEvent* event);
|
||||
void resizeEvent(QResizeEvent* event);
|
||||
void drawWidget(QPainter& painter);
|
||||
|
||||
public:
|
||||
DualInlinePackageWidget(const TargetVariant& targetVariant, QObject* insightWindowObj, QWidget* parent);
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
#include <QPainter>
|
||||
#include <QLayout>
|
||||
#include <cmath>
|
||||
#include <QEvent>
|
||||
#include <QMenu>
|
||||
#include <QContextMenuEvent>
|
||||
|
||||
#include "PinBodyWidget.hpp"
|
||||
#include "src/Logger/Logger.hpp"
|
||||
#include "src/Exceptions/Exception.hpp"
|
||||
|
||||
using namespace Bloom::InsightTargetWidgets::Dip;
|
||||
using namespace Bloom::Exceptions;
|
||||
|
||||
void PinBodyWidget::paintEvent(QPaintEvent* event) {
|
||||
auto painter = QPainter(this);
|
||||
this->drawWidget(painter);
|
||||
}
|
||||
|
||||
bool PinBodyWidget::event(QEvent* event)
|
||||
{
|
||||
if (this->isEnabled() && this->pinState.has_value() && this->pinState->ioDirection == TargetPinState::IoDirection::OUTPUT) {
|
||||
switch (event->type()) {
|
||||
case QEvent::Enter: {
|
||||
this->hoverActive = true;
|
||||
this->repaint();
|
||||
break;
|
||||
}
|
||||
case QEvent::Leave: {
|
||||
this->hoverActive = false;
|
||||
this->repaint();
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return QWidget::event(event);
|
||||
}
|
||||
|
||||
void PinBodyWidget::drawWidget(QPainter& painter) {
|
||||
auto parentWidget = this->parentWidget();
|
||||
|
||||
if (parentWidget == nullptr) {
|
||||
Logger::error("PinBodyWidget requires a parent widget");
|
||||
}
|
||||
|
||||
painter.setRenderHints(QPainter::RenderHint::Antialiasing | QPainter::RenderHint::SmoothPixmapTransform, true);
|
||||
auto pinWidth = PinBodyWidget::WIDTH;
|
||||
auto pinHeight = PinBodyWidget::HEIGHT;
|
||||
this->setFixedSize(pinWidth, pinHeight);
|
||||
|
||||
auto pinColor = this->getBodyColor();
|
||||
|
||||
if (this->pinDescriptor.type == TargetPinType::VCC) {
|
||||
pinColor = QColor("#ff3d43");
|
||||
|
||||
} else if (this->pinDescriptor.type == TargetPinType::GND) {
|
||||
pinColor = QColor("#575757");
|
||||
}
|
||||
|
||||
if (this->pinState.has_value()) {
|
||||
if (this->pinState->ioState.has_value()
|
||||
&& this->pinState->ioDirection.has_value()
|
||||
&& this->pinState->ioState.value() == TargetPinState::IoState::HIGH
|
||||
) {
|
||||
pinColor = this->pinState->ioDirection.value() == TargetPinState::IoDirection::OUTPUT ?
|
||||
QColor("#3D7F96") : QColor("#A47E3E");
|
||||
}
|
||||
}
|
||||
|
||||
if (!this->hoverActive) {
|
||||
pinColor.setAlpha(225);
|
||||
}
|
||||
|
||||
if (!this->isEnabled()) {
|
||||
pinColor.setAlpha(this->getDisableAlphaLevel());
|
||||
}
|
||||
|
||||
painter.setPen(Qt::PenStyle::NoPen);
|
||||
painter.setBrush(pinColor);
|
||||
|
||||
painter.drawRect(
|
||||
0,
|
||||
0,
|
||||
pinWidth,
|
||||
pinHeight
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
#pragma once
|
||||
|
||||
#include <QWidget>
|
||||
#include <QMouseEvent>
|
||||
|
||||
#include "src/Targets/TargetPinDescriptor.hpp"
|
||||
|
||||
namespace Bloom::InsightTargetWidgets::Dip
|
||||
{
|
||||
using Targets::TargetPinDescriptor;
|
||||
using Targets::TargetPinType;
|
||||
using Targets::TargetPinState;
|
||||
|
||||
class PinBodyWidget: public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(QColor bodyColor READ getBodyColor WRITE setBodyColor DESIGNABLE true)
|
||||
Q_PROPERTY(int disableAlphaLevel READ getDisableAlphaLevel WRITE setDisableAlphaLevel DESIGNABLE true)
|
||||
|
||||
private:
|
||||
TargetPinDescriptor pinDescriptor;
|
||||
std::optional<TargetPinState> pinState;
|
||||
QColor bodyColor = QColor("#AFB1B3");
|
||||
int disableAlphaLevel = 100;
|
||||
|
||||
protected:
|
||||
bool hoverActive = false;
|
||||
void paintEvent(QPaintEvent* event) override;
|
||||
void drawWidget(QPainter& painter);
|
||||
bool event(QEvent* event) override;
|
||||
|
||||
void mouseReleaseEvent(QMouseEvent* event) override {
|
||||
if (event->button() == Qt::MouseButton::LeftButton) {
|
||||
emit this->clicked();
|
||||
}
|
||||
QWidget::mouseReleaseEvent(event);
|
||||
}
|
||||
|
||||
public:
|
||||
static const int WIDTH = 30;
|
||||
static const int HEIGHT = 40;
|
||||
|
||||
PinBodyWidget(QWidget* parent, const TargetPinDescriptor& pinDescriptor): QWidget(parent), pinDescriptor(pinDescriptor) {
|
||||
this->setFixedSize(PinBodyWidget::WIDTH, PinBodyWidget::HEIGHT);
|
||||
this->setObjectName("target-pin-body");
|
||||
}
|
||||
|
||||
void setPinState(const TargetPinState& pinState) {
|
||||
this->pinState = pinState;
|
||||
}
|
||||
|
||||
QColor getBodyColor() const {
|
||||
return this->bodyColor;
|
||||
}
|
||||
|
||||
void setBodyColor(QColor color) {
|
||||
this->bodyColor = color;
|
||||
}
|
||||
|
||||
int getDisableAlphaLevel() const {
|
||||
return this->disableAlphaLevel;
|
||||
}
|
||||
|
||||
void setDisableAlphaLevel(int level) {
|
||||
this->disableAlphaLevel = level;
|
||||
}
|
||||
|
||||
signals:
|
||||
void clicked();
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
#include <QWidget>
|
||||
#include <QPainter>
|
||||
#include <QLayout>
|
||||
#include <cmath>
|
||||
#include <QEvent>
|
||||
|
||||
#include "PinWidget.hpp"
|
||||
#include "PinBodyWidget.hpp"
|
||||
#include "src/Logger/Logger.hpp"
|
||||
|
||||
using namespace Bloom::InsightTargetWidgets::Dip;
|
||||
|
||||
PinWidget::PinWidget(QWidget* parent, const TargetPinDescriptor& pinDescriptor, const TargetVariant& targetVariant):
|
||||
TargetPinWidget(parent, pinDescriptor, targetVariant) {
|
||||
this->layout = new QVBoxLayout();
|
||||
this->layout->setMargin(0);
|
||||
this->layout->setSpacing(0);
|
||||
|
||||
this->bodyWidget = new PinBodyWidget(this, this->pinDescriptor);
|
||||
bool isTopWidget = pinDescriptor.number > (targetVariant.pinDescriptorsByNumber.size() / 2);
|
||||
|
||||
this->layout->setAlignment(isTopWidget ? (Qt::AlignmentFlag::AlignHCenter | Qt::AlignmentFlag::AlignBottom)
|
||||
: (Qt::AlignmentFlag::AlignHCenter | Qt::AlignmentFlag::AlignTop));
|
||||
|
||||
this->pinDirectionLabel = new QLabel(this);
|
||||
this->pinDirectionLabel->setObjectName("target-pin-direction");
|
||||
this->pinDirectionLabel->setAlignment(Qt::AlignmentFlag::AlignCenter);
|
||||
|
||||
this->pinNameLabel = new QLabel(this);
|
||||
this->pinNameLabel->setObjectName("target-pin-name");
|
||||
this->pinNameLabel->setText(QString::fromStdString(pinDescriptor.name).toUpper());
|
||||
this->pinNameLabel->setAlignment(Qt::AlignmentFlag::AlignCenter);
|
||||
|
||||
this->pinNumberLabel = new QLabel(this);
|
||||
this->pinNumberLabel->setObjectName("target-pin-number");
|
||||
this->pinNumberLabel->setText(QString::number(pinDescriptor.number));
|
||||
this->pinNumberLabel->setAlignment(Qt::AlignmentFlag::AlignCenter);
|
||||
|
||||
if (isTopWidget) {
|
||||
this->layout->setDirection(QBoxLayout::Direction::BottomToTop);
|
||||
}
|
||||
|
||||
this->layout->addWidget(this->bodyWidget);
|
||||
this->layout->insertSpacing(1, 3);
|
||||
this->layout->addWidget(this->pinNumberLabel);
|
||||
this->layout->insertSpacing(3, 2);
|
||||
this->layout->addWidget(this->pinNameLabel);
|
||||
this->layout->insertSpacing(5, 2);
|
||||
this->layout->addWidget(this->pinDirectionLabel);
|
||||
this->pinNameLabel->setFixedSize(PinBodyWidget::WIDTH, PinWidget::LABEL_HEIGHT - 2);
|
||||
this->pinNumberLabel->setFixedSize(PinBodyWidget::WIDTH, PinWidget::LABEL_HEIGHT - 2);
|
||||
|
||||
this->setFixedSize(PinWidget::MINIMUM_WIDTH, PinWidget::MAXIMUM_HEIGHT);
|
||||
this->setLayout(this->layout);
|
||||
|
||||
connect(this->bodyWidget, &PinBodyWidget::clicked, this, &TargetPinWidget::onWidgetBodyClicked);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
#pragma once
|
||||
|
||||
#include <QWidget>
|
||||
#include <QLabel>
|
||||
|
||||
#include "../TargetPinWidget.hpp"
|
||||
#include "PinBodyWidget.hpp"
|
||||
#include "src/Targets/TargetVariant.hpp"
|
||||
|
||||
namespace Bloom::InsightTargetWidgets::Dip
|
||||
{
|
||||
class PinWidget: public TargetPinWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
private:
|
||||
QVBoxLayout* layout = nullptr;
|
||||
QLabel* pinNumberLabel = nullptr;
|
||||
QLabel* pinNameLabel = nullptr;
|
||||
QLabel* pinDirectionLabel = nullptr;
|
||||
PinBodyWidget* bodyWidget = nullptr;
|
||||
|
||||
void setLabelColor(QString hexColor) {
|
||||
auto style = QString("QLabel { color: " + hexColor + "; }");
|
||||
if (this->pinNumberLabel != nullptr) {
|
||||
// this->pinNumberLabel->setStyleSheet(style);
|
||||
}
|
||||
|
||||
if (this->pinNameLabel != nullptr) {
|
||||
this->pinNameLabel->setStyleSheet(style);
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
static const int MINIMUM_WIDTH = 30;
|
||||
static const int MAXIMUM_LABEL_COUNT = 3;
|
||||
static const int LABEL_HEIGHT = 20;
|
||||
static const int MAXIMUM_HEIGHT = PinBodyWidget::HEIGHT + (PinWidget::LABEL_HEIGHT * PinWidget::MAXIMUM_LABEL_COUNT);
|
||||
|
||||
PinWidget(QWidget* parent, const TargetPinDescriptor& pinDescriptor, const TargetVariant& targetVariant);
|
||||
|
||||
virtual void updatePinState(const TargetPinState& pinState) override {
|
||||
TargetPinWidget::updatePinState(pinState);
|
||||
|
||||
if (pinState.ioDirection.has_value()) {
|
||||
this->pinDirectionLabel->setText(pinState.ioDirection.value() == TargetPinState::IoDirection::INPUT ?
|
||||
"IN" : "OUT");
|
||||
|
||||
} else {
|
||||
this->pinDirectionLabel->setText("");
|
||||
}
|
||||
|
||||
if (this->bodyWidget != nullptr) {
|
||||
this->bodyWidget->setPinState(pinState);
|
||||
}
|
||||
|
||||
this->setLabelColor(this->pinStateChanged ? "#6FA0FF" : "#a6a7aa");
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
#target-pin-number,
|
||||
#target-pin-number {
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
#target-pin-name,
|
||||
#target-pin-direction {
|
||||
font-size: 11px;
|
||||
}
|
||||
|
||||
#target-pin-name {
|
||||
color: #a6a7aa;
|
||||
}
|
||||
|
||||
#target-pin-direction {
|
||||
color: #8a8a8d;
|
||||
}
|
||||
|
||||
#target-pin-number-top {
|
||||
}
|
||||
|
||||
#target-body {
|
||||
qproperty-bodyColor: #A6A8AB;
|
||||
qproperty-disableAlphaLevel: 100;
|
||||
}
|
||||
|
||||
#target-pin-body {
|
||||
qproperty-bodyColor: #A6A8AB;
|
||||
qproperty-disableAlphaLevel: 100;
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
#include <QPainter>
|
||||
#include <cmath>
|
||||
|
||||
#include "BodyWidget.hpp"
|
||||
#include "src/Logger/Logger.hpp"
|
||||
|
||||
using namespace Bloom::InsightTargetWidgets::Qfp;
|
||||
|
||||
void BodyWidget::paintEvent(QPaintEvent* event) {
|
||||
auto painter = QPainter(this);
|
||||
this->drawWidget(painter);
|
||||
}
|
||||
|
||||
void BodyWidget::drawWidget(QPainter& painter) {
|
||||
painter.setRenderHints(QPainter::RenderHint::Antialiasing | QPainter::RenderHint::SmoothPixmapTransform, true);
|
||||
|
||||
auto targetBodyColor = this->getBodyColor();
|
||||
auto backgroundColor = QColor("#3C3F41");
|
||||
|
||||
if (!this->isEnabled()) {
|
||||
targetBodyColor.setAlpha(this->getDisableAlphaLevel());
|
||||
}
|
||||
|
||||
painter.setPen(Qt::PenStyle::NoPen);
|
||||
painter.setBrush(targetBodyColor);
|
||||
|
||||
auto containerGeometry = this->geometry();
|
||||
auto targetBodyWidth = containerGeometry.width() - 16;
|
||||
auto targetBodyHeight = containerGeometry.height() - 16;
|
||||
|
||||
auto targetBodyPoint = QPoint(
|
||||
(containerGeometry.width() / 2) - (targetBodyWidth / 2),
|
||||
(containerGeometry.height() / 2) - (targetBodyHeight / 2)
|
||||
);
|
||||
|
||||
painter.drawRect(
|
||||
targetBodyPoint.x(),
|
||||
targetBodyPoint.y(),
|
||||
targetBodyWidth,
|
||||
targetBodyHeight
|
||||
);
|
||||
|
||||
painter.setBrush(backgroundColor);
|
||||
painter.drawEllipse(QRectF(
|
||||
targetBodyPoint.x() + 10,
|
||||
targetBodyPoint.y() + 10,
|
||||
15,
|
||||
15
|
||||
));
|
||||
}
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
#pragma once
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
namespace Bloom::InsightTargetWidgets::Qfp
|
||||
{
|
||||
class BodyWidget: public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(QColor bodyColor READ getBodyColor WRITE setBodyColor DESIGNABLE true)
|
||||
Q_PROPERTY(int disableAlphaLevel READ getDisableAlphaLevel WRITE setDisableAlphaLevel DESIGNABLE true)
|
||||
|
||||
private:
|
||||
QColor bodyColor = QColor("#AFB1B3");
|
||||
int disableAlphaLevel = 100;
|
||||
|
||||
protected:
|
||||
void paintEvent(QPaintEvent* event);
|
||||
void drawWidget(QPainter& painter);
|
||||
|
||||
public:
|
||||
BodyWidget(QWidget* parent): QWidget(parent) {
|
||||
this->setObjectName("target-body");
|
||||
}
|
||||
|
||||
QColor getBodyColor() const {
|
||||
return this->bodyColor;
|
||||
}
|
||||
|
||||
void setBodyColor(QColor color) {
|
||||
this->bodyColor = color;
|
||||
}
|
||||
|
||||
int getDisableAlphaLevel() const {
|
||||
return this->disableAlphaLevel;
|
||||
}
|
||||
|
||||
void setDisableAlphaLevel(int level) {
|
||||
this->disableAlphaLevel = level;
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
#include <QPainter>
|
||||
#include <QLayout>
|
||||
#include <cmath>
|
||||
#include <QEvent>
|
||||
#include <QMenu>
|
||||
#include <QContextMenuEvent>
|
||||
|
||||
#include "PinBodyWidget.hpp"
|
||||
#include "src/Logger/Logger.hpp"
|
||||
#include "src/Exceptions/Exception.hpp"
|
||||
|
||||
using namespace Bloom::InsightTargetWidgets::Qfp;
|
||||
using namespace Bloom::Exceptions;
|
||||
|
||||
void PinBodyWidget::paintEvent(QPaintEvent* event) {
|
||||
auto painter = QPainter(this);
|
||||
this->drawWidget(painter);
|
||||
}
|
||||
|
||||
bool PinBodyWidget::event(QEvent* event)
|
||||
{
|
||||
if (this->isEnabled() && this->pinState.has_value() && this->pinState->ioDirection == TargetPinState::IoDirection::OUTPUT) {
|
||||
switch (event->type()) {
|
||||
case QEvent::Enter: {
|
||||
this->hoverActive = true;
|
||||
this->repaint();
|
||||
break;
|
||||
}
|
||||
case QEvent::Leave: {
|
||||
this->hoverActive = false;
|
||||
this->repaint();
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return QWidget::event(event);
|
||||
}
|
||||
|
||||
void PinBodyWidget::drawWidget(QPainter& painter) {
|
||||
auto parentWidget = this->parentWidget();
|
||||
|
||||
if (parentWidget == nullptr) {
|
||||
Logger::error("PinBodyWidget requires a parent widget");
|
||||
}
|
||||
|
||||
painter.setRenderHints(QPainter::RenderHint::Antialiasing | QPainter::RenderHint::SmoothPixmapTransform, true);
|
||||
auto pinWidth = this->isVertical ? PinBodyWidget::WIDTH : PinBodyWidget::HEIGHT;
|
||||
auto pinHeight = this->isVertical ? PinBodyWidget::HEIGHT : PinBodyWidget::WIDTH;
|
||||
this->setFixedSize(pinWidth, pinHeight);
|
||||
|
||||
auto pinColor = this->getBodyColor();
|
||||
|
||||
if (this->pinDescriptor.type == TargetPinType::VCC) {
|
||||
pinColor = QColor("#ff3d43");
|
||||
|
||||
} else if (this->pinDescriptor.type == TargetPinType::GND) {
|
||||
pinColor = QColor("#575757");
|
||||
}
|
||||
|
||||
if (this->pinState.has_value()) {
|
||||
if (this->pinState->ioState.has_value()
|
||||
&& this->pinState->ioDirection.has_value()
|
||||
&& this->pinState->ioState.value() == TargetPinState::IoState::HIGH
|
||||
) {
|
||||
pinColor = this->pinState->ioDirection.value() == TargetPinState::IoDirection::OUTPUT ?
|
||||
QColor("#3D7F96") : QColor("#A47E3E");
|
||||
}
|
||||
}
|
||||
|
||||
if (!this->hoverActive) {
|
||||
pinColor.setAlpha(225);
|
||||
}
|
||||
|
||||
if (!this->isEnabled()) {
|
||||
pinColor.setAlpha(this->getDisableAlphaLevel());
|
||||
}
|
||||
|
||||
painter.setPen(Qt::PenStyle::NoPen);
|
||||
painter.setBrush(pinColor);
|
||||
|
||||
painter.drawRect(
|
||||
0,
|
||||
0,
|
||||
pinWidth,
|
||||
pinHeight
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
#pragma once
|
||||
|
||||
#include <QWidget>
|
||||
#include <QMouseEvent>
|
||||
|
||||
#include "src/Targets/TargetPinDescriptor.hpp"
|
||||
|
||||
namespace Bloom::InsightTargetWidgets::Qfp
|
||||
{
|
||||
using Targets::TargetPinDescriptor;
|
||||
using Targets::TargetPinType;
|
||||
using Targets::TargetPinState;
|
||||
|
||||
class PinBodyWidget: public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(QColor bodyColor READ getBodyColor WRITE setBodyColor DESIGNABLE true)
|
||||
Q_PROPERTY(int disableAlphaLevel READ getDisableAlphaLevel WRITE setDisableAlphaLevel DESIGNABLE true)
|
||||
|
||||
private:
|
||||
TargetPinDescriptor pinDescriptor;
|
||||
std::optional<TargetPinState> pinState;
|
||||
QColor bodyColor = QColor("#AFB1B3");
|
||||
int disableAlphaLevel = 100;
|
||||
bool isVertical = false;
|
||||
|
||||
protected:
|
||||
bool hoverActive = false;
|
||||
void paintEvent(QPaintEvent* event) override;
|
||||
void drawWidget(QPainter& painter);
|
||||
bool event(QEvent* event) override;
|
||||
|
||||
void mouseReleaseEvent(QMouseEvent* event) override {
|
||||
if (event->button() == Qt::MouseButton::LeftButton) {
|
||||
emit this->clicked();
|
||||
}
|
||||
|
||||
QWidget::mouseReleaseEvent(event);
|
||||
}
|
||||
|
||||
public:
|
||||
static const int WIDTH = 30;
|
||||
static const int HEIGHT = 40;
|
||||
|
||||
PinBodyWidget(QWidget* parent, const TargetPinDescriptor& pinDescriptor, bool isVertical):
|
||||
QWidget(parent), pinDescriptor(pinDescriptor), isVertical(isVertical) {
|
||||
this->setObjectName("target-pin-body");
|
||||
|
||||
if (isVertical) {
|
||||
this->setFixedSize(PinBodyWidget::WIDTH, PinBodyWidget::HEIGHT);
|
||||
|
||||
} else {
|
||||
this->setFixedSize(PinBodyWidget::HEIGHT, PinBodyWidget::WIDTH);
|
||||
}
|
||||
}
|
||||
|
||||
void setPinState(const TargetPinState& pinState) {
|
||||
this->pinState = pinState;
|
||||
}
|
||||
|
||||
QColor getBodyColor() const {
|
||||
return this->bodyColor;
|
||||
}
|
||||
|
||||
void setBodyColor(QColor color) {
|
||||
this->bodyColor = color;
|
||||
}
|
||||
|
||||
int getDisableAlphaLevel() const {
|
||||
return this->disableAlphaLevel;
|
||||
}
|
||||
|
||||
void setDisableAlphaLevel(int level) {
|
||||
this->disableAlphaLevel = level;
|
||||
}
|
||||
|
||||
signals:
|
||||
void clicked();
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,97 @@
|
||||
#include <QWidget>
|
||||
#include <QPainter>
|
||||
#include <QLayout>
|
||||
#include <cmath>
|
||||
#include <QEvent>
|
||||
|
||||
#include "PinWidget.hpp"
|
||||
#include "PinBodyWidget.hpp"
|
||||
#include "src/Logger/Logger.hpp"
|
||||
|
||||
using namespace Bloom::InsightTargetWidgets::Qfp;
|
||||
|
||||
PinWidget::PinWidget(QWidget* parent, const TargetPinDescriptor& pinDescriptor, const TargetVariant& targetVariant):
|
||||
TargetPinWidget(parent, pinDescriptor, targetVariant) {
|
||||
this->layout = new QVBoxLayout();
|
||||
this->layout->setMargin(0);
|
||||
this->layout->setSpacing(0);
|
||||
|
||||
auto pinCountPerLayout = (targetVariant.pinDescriptorsByNumber.size() / 4);
|
||||
this->isLeftLayout = pinDescriptor.number <= pinCountPerLayout;
|
||||
this->isBottomLayout = pinDescriptor.number > pinCountPerLayout && pinDescriptor.number <= (pinCountPerLayout * 2);
|
||||
this->isRightLayout = pinDescriptor.number > (pinCountPerLayout * 2) && pinDescriptor.number <= (pinCountPerLayout * 3);
|
||||
this->isTopLayout = pinDescriptor.number > (pinCountPerLayout * 3) && pinDescriptor.number <= (pinCountPerLayout * 4);
|
||||
|
||||
this->bodyWidget = new PinBodyWidget(this, this->pinDescriptor, (this->isTopLayout || this->isBottomLayout));
|
||||
|
||||
this->pinDirectionLabel = new QLabel(this);
|
||||
this->pinDirectionLabel->setObjectName("target-pin-direction");
|
||||
this->pinDirectionLabel->setAlignment(Qt::AlignmentFlag::AlignCenter);
|
||||
|
||||
this->pinNameLabel = new QLabel(this);
|
||||
this->pinNameLabel->setObjectName("target-pin-name");
|
||||
auto pinName = QString::fromStdString(pinDescriptor.name).toUpper();
|
||||
pinName.truncate(5);
|
||||
this->pinNameLabel->setText(pinName);
|
||||
this->pinNameLabel->setAlignment(Qt::AlignmentFlag::AlignCenter);
|
||||
|
||||
this->pinNumberLabel = new QLabel(this);
|
||||
this->pinNumberLabel->setObjectName("target-pin-number");
|
||||
auto pinNumberText = QString::number(pinDescriptor.number);
|
||||
pinNumberText.truncate(5);
|
||||
this->pinNumberLabel->setText(QString::number(pinDescriptor.number));
|
||||
this->pinNumberLabel->setAlignment(Qt::AlignmentFlag::AlignCenter);
|
||||
|
||||
if (this->isLeftLayout) {
|
||||
this->layout->setAlignment((Qt::AlignmentFlag::AlignVCenter | Qt::AlignmentFlag::AlignRight));
|
||||
this->layout->setDirection(QBoxLayout::Direction::RightToLeft);
|
||||
this->setFixedSize(PinWidget::MAXIMUM_HORIZONTAL_WIDTH, PinWidget::MAXIMUM_HORIZONTAL_HEIGHT);
|
||||
|
||||
} else if (this->isBottomLayout) {
|
||||
this->layout->setAlignment(Qt::AlignmentFlag::AlignHCenter | Qt::AlignmentFlag::AlignTop);
|
||||
this->layout->setDirection(QBoxLayout::Direction::TopToBottom);
|
||||
this->setFixedSize(PinWidget::MAXIMUM_VERTICAL_WIDTH, PinWidget::MAXIMUM_VERTICAL_HEIGHT);
|
||||
|
||||
} else if (this->isRightLayout) {
|
||||
this->layout->setAlignment((Qt::AlignmentFlag::AlignVCenter | Qt::AlignmentFlag::AlignLeft));
|
||||
this->layout->setDirection(QBoxLayout::Direction::LeftToRight);
|
||||
this->setFixedSize(PinWidget::MAXIMUM_HORIZONTAL_WIDTH, PinWidget::MAXIMUM_HORIZONTAL_HEIGHT);
|
||||
|
||||
} else if (this->isTopLayout) {
|
||||
this->layout->setAlignment((Qt::AlignmentFlag::AlignHCenter | Qt::AlignmentFlag::AlignBottom));
|
||||
this->layout->setDirection(QBoxLayout::Direction::BottomToTop);
|
||||
this->setFixedSize(PinWidget::MAXIMUM_VERTICAL_WIDTH, PinWidget::MAXIMUM_VERTICAL_HEIGHT);
|
||||
}
|
||||
|
||||
this->layout->addWidget(this->bodyWidget);
|
||||
this->layout->insertSpacing(1, 3);
|
||||
|
||||
if (this->isLeftLayout || this->isRightLayout) {
|
||||
auto stackedLabelLayout = new QVBoxLayout();
|
||||
stackedLabelLayout->addWidget(this->pinNameLabel);
|
||||
stackedLabelLayout->insertSpacing(3, 2);
|
||||
stackedLabelLayout->addWidget(this->pinNumberLabel);
|
||||
this->layout->insertSpacing(2, 4);
|
||||
this->layout->addLayout(stackedLabelLayout);
|
||||
|
||||
// Adjust the pin name label width for horizontal pins to accommodate for pin names up to 5 characters in length
|
||||
this->pinNameLabel->setFixedSize(PinWidget::MAXIMUM_LABEL_WIDTH + 5, PinWidget::MAXIMUM_HORIZONTAL_HEIGHT / 2);
|
||||
this->pinNumberLabel->setFixedSize(PinWidget::MAXIMUM_LABEL_WIDTH + 5, PinWidget::MAXIMUM_HORIZONTAL_HEIGHT / 2);
|
||||
|
||||
} else if (this-isTopLayout || this->isBottomLayout) {
|
||||
this->layout->addWidget(this->pinNumberLabel);
|
||||
this->layout->insertSpacing(3, 2);
|
||||
this->layout->addWidget(this->pinNameLabel);
|
||||
|
||||
this->pinNameLabel->setFixedSize(PinBodyWidget::WIDTH, PinWidget::LABEL_HEIGHT - 2);
|
||||
this->pinNumberLabel->setFixedSize(PinBodyWidget::WIDTH, PinWidget::LABEL_HEIGHT - 2);
|
||||
}
|
||||
|
||||
this->layout->insertSpacing(5, 2);
|
||||
this->layout->addWidget(this->pinDirectionLabel);
|
||||
|
||||
this->setLayout(this->layout);
|
||||
|
||||
connect(this->bodyWidget, &PinBodyWidget::clicked, this, &TargetPinWidget::onWidgetBodyClicked);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
#pragma once
|
||||
|
||||
#include <QWidget>
|
||||
#include <QLabel>
|
||||
|
||||
#include "../TargetPinWidget.hpp"
|
||||
#include "PinBodyWidget.hpp"
|
||||
#include "src/Targets/TargetVariant.hpp"
|
||||
|
||||
namespace Bloom::InsightTargetWidgets::Qfp
|
||||
{
|
||||
class PinWidget: public TargetPinWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
private:
|
||||
QVBoxLayout* layout = nullptr;
|
||||
QLabel* pinNumberLabel = nullptr;
|
||||
QLabel* pinNameLabel = nullptr;
|
||||
QLabel* pinDirectionLabel = nullptr;
|
||||
PinBodyWidget* bodyWidget = nullptr;
|
||||
|
||||
bool isLeftLayout = false;
|
||||
bool isBottomLayout = false;
|
||||
bool isRightLayout = false;
|
||||
bool isTopLayout = false;
|
||||
|
||||
void setLabelColor(QString hexColor) {
|
||||
auto style = QString("QLabel { color: " + hexColor + "; }");
|
||||
if (this->pinNumberLabel != nullptr) {
|
||||
// this->pinNumberLabel->setStyleSheet(style);
|
||||
}
|
||||
|
||||
if (this->pinNameLabel != nullptr) {
|
||||
this->pinNameLabel->setStyleSheet(style);
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
static const int MAXIMUM_SPACING = 8;
|
||||
static const int MAXIMUM_LABEL_COUNT = 3;
|
||||
static const int LABEL_HEIGHT = 20;
|
||||
static const int MAXIMUM_LABEL_WIDTH = PinBodyWidget::WIDTH;
|
||||
static const int MAXIMUM_LABEL_HEIGHT = 20;
|
||||
static const int MAXIMUM_HORIZONTAL_WIDTH = PinBodyWidget::HEIGHT + (PinWidget::MAXIMUM_LABEL_WIDTH * PinWidget::MAXIMUM_LABEL_COUNT);
|
||||
static const int MAXIMUM_HORIZONTAL_HEIGHT = PinBodyWidget::WIDTH;
|
||||
static const int MAXIMUM_VERTICAL_HEIGHT = PinBodyWidget::HEIGHT + (PinWidget::MAXIMUM_LABEL_HEIGHT * PinWidget::MAXIMUM_LABEL_COUNT);
|
||||
static const int MAXIMUM_VERTICAL_WIDTH = PinBodyWidget::WIDTH;
|
||||
|
||||
PinWidget(QWidget* parent, const TargetPinDescriptor& pinDescriptor, const TargetVariant& targetVariant);
|
||||
|
||||
virtual void updatePinState(const TargetPinState& pinState) override {
|
||||
TargetPinWidget::updatePinState(pinState);
|
||||
|
||||
if (pinState.ioDirection.has_value()) {
|
||||
this->pinDirectionLabel->setText(pinState.ioDirection.value() == TargetPinState::IoDirection::INPUT ?
|
||||
"IN" : "OUT");
|
||||
|
||||
} else {
|
||||
this->pinDirectionLabel->setText("");
|
||||
}
|
||||
|
||||
if (this->bodyWidget != nullptr) {
|
||||
this->bodyWidget->setPinState(pinState);
|
||||
}
|
||||
|
||||
this->setLabelColor(this->pinStateChanged ? "#6FA0FF" : "#a6a7aa");
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,213 @@
|
||||
#include <QPainter>
|
||||
#include <QVBoxLayout>
|
||||
#include <QHBoxLayout>
|
||||
#include <vector>
|
||||
#include <QEvent>
|
||||
#include <QFile>
|
||||
|
||||
#include "../../InsightWindow.hpp"
|
||||
#include "QuadFlatPackageWidget.hpp"
|
||||
#include "src/Logger/Logger.hpp"
|
||||
#include "src/Exceptions/Exception.hpp"
|
||||
#include "PinWidget.hpp"
|
||||
#include "BodyWidget.hpp"
|
||||
|
||||
using namespace Bloom::InsightTargetWidgets::Qfp;
|
||||
using namespace Bloom::Exceptions;
|
||||
|
||||
QuadFlatPackageWidget::QuadFlatPackageWidget(const TargetVariant& targetVariant, QObject* insightWindowObj, QWidget* parent):
|
||||
TargetPackageWidget(targetVariant, insightWindowObj, parent) {
|
||||
assert((targetVariant.pinDescriptorsByNumber.size() % 4) == 0);
|
||||
|
||||
auto stylesheetFile = QFile("/home/nav/Projects/Bloom/src/Insight/UserInterfaces/InsightWindow/TargetWidgets/QFP/Stylesheets/QuadFlatPackage.qss");
|
||||
stylesheetFile.open(QFile::ReadOnly);
|
||||
this->setStyleSheet(stylesheetFile.readAll());
|
||||
|
||||
this->pinWidgets.reserve(targetVariant.pinDescriptorsByNumber.size());
|
||||
this->layout = new QVBoxLayout();
|
||||
this->layout->setSpacing(0);
|
||||
this->layout->setMargin(0);
|
||||
|
||||
this->horizontalLayout = new QHBoxLayout();
|
||||
this->horizontalLayout->setSpacing(0);
|
||||
this->horizontalLayout->setDirection(QBoxLayout::Direction::LeftToRight);
|
||||
|
||||
this->topPinLayout = new QHBoxLayout();
|
||||
this->topPinLayout->setSpacing(QuadFlatPackageWidget::PIN_WIDGET_SPACING);
|
||||
this->topPinLayout->setDirection(QBoxLayout::Direction::RightToLeft);
|
||||
|
||||
this->rightPinLayout = new QVBoxLayout();
|
||||
this->rightPinLayout->setSpacing(QuadFlatPackageWidget::PIN_WIDGET_SPACING);
|
||||
this->rightPinLayout->setDirection(QBoxLayout::Direction::BottomToTop);
|
||||
|
||||
this->bottomPinLayout = new QHBoxLayout();
|
||||
this->bottomPinLayout->setSpacing(QuadFlatPackageWidget::PIN_WIDGET_SPACING);
|
||||
this->bottomPinLayout->setDirection(QBoxLayout::Direction::LeftToRight);
|
||||
|
||||
this->leftPinLayout = new QVBoxLayout();
|
||||
this->leftPinLayout->setSpacing(QuadFlatPackageWidget::PIN_WIDGET_SPACING);
|
||||
this->leftPinLayout->setDirection(QBoxLayout::Direction::TopToBottom);
|
||||
|
||||
auto insightWindow = qobject_cast<InsightWindow*>(insightWindowObj);
|
||||
assert(insightWindow != nullptr);
|
||||
|
||||
auto pinCountPerLayout = (targetVariant.pinDescriptorsByNumber.size() / 4);
|
||||
for (const auto& [targetPinNumber, targetPinDescriptor]: targetVariant.pinDescriptorsByNumber) {
|
||||
auto pinWidget = new PinWidget(this, targetPinDescriptor, targetVariant);
|
||||
this->pinWidgets.push_back(pinWidget);
|
||||
|
||||
if (targetPinNumber <= pinCountPerLayout) {
|
||||
this->leftPinLayout->addWidget(pinWidget, 0, Qt::AlignmentFlag::AlignRight);
|
||||
|
||||
} else if (targetPinNumber > pinCountPerLayout && targetPinNumber <= (pinCountPerLayout * 2)) {
|
||||
this->bottomPinLayout->addWidget(pinWidget, 0, Qt::AlignmentFlag::AlignTop);
|
||||
|
||||
} else if (targetPinNumber > (pinCountPerLayout * 2) && targetPinNumber <= (pinCountPerLayout * 3)) {
|
||||
this->rightPinLayout->addWidget(pinWidget, 0, Qt::AlignmentFlag::AlignLeft);
|
||||
|
||||
} else if (targetPinNumber > (pinCountPerLayout * 3) && targetPinNumber <= (pinCountPerLayout * 4)) {
|
||||
this->topPinLayout->addWidget(pinWidget, 0, Qt::AlignmentFlag::AlignBottom);
|
||||
}
|
||||
|
||||
connect(pinWidget, &TargetPinWidget::toggleIoState, insightWindow, &InsightWindow::togglePinIoState);
|
||||
}
|
||||
|
||||
this->bodyWidget = new BodyWidget(this);
|
||||
this->layout->addLayout(this->topPinLayout);
|
||||
this->horizontalLayout->addLayout(this->leftPinLayout);
|
||||
this->horizontalLayout->addWidget(this->bodyWidget);
|
||||
this->horizontalLayout->addLayout(this->rightPinLayout);
|
||||
this->layout->addLayout(this->horizontalLayout);
|
||||
this->layout->addLayout(this->bottomPinLayout);
|
||||
this->setLayout(this->layout);
|
||||
|
||||
auto insightWindowWidget = this->window();
|
||||
assert(insightWindowWidget != nullptr);
|
||||
|
||||
insightWindowWidget->setMinimumHeight(
|
||||
std::max(
|
||||
500,
|
||||
static_cast<int>((PinWidget::MAXIMUM_HORIZONTAL_HEIGHT * pinCountPerLayout)
|
||||
+ (PinWidget::MAXIMUM_VERTICAL_HEIGHT * 2)) + 300
|
||||
)
|
||||
);
|
||||
|
||||
insightWindowWidget->setMinimumWidth(
|
||||
std::max(
|
||||
1000,
|
||||
static_cast<int>((PinWidget::MAXIMUM_VERTICAL_WIDTH * pinCountPerLayout)
|
||||
+ (PinWidget::MAXIMUM_VERTICAL_WIDTH * 2)) + 300
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
void QuadFlatPackageWidget::paintEvent(QPaintEvent* event) {
|
||||
auto painter = QPainter(this);
|
||||
this->drawWidget(painter);
|
||||
}
|
||||
|
||||
void QuadFlatPackageWidget::drawWidget(QPainter& painter) {
|
||||
auto parentWidget = this->parentWidget();
|
||||
assert(parentWidget != nullptr);
|
||||
|
||||
auto parentContainerHeight = parentWidget->height();
|
||||
auto parentContainerWidth = parentWidget->width();
|
||||
|
||||
// auto verticalPinWidgetHeight = this->topPinLayout->findChildren<PinWidget*>().front()->height();
|
||||
// auto verticalPinWidgetWidth = this->topPinLayout->findChildren<PinWidget*>().front()->width();
|
||||
// auto horizontalPinWidgetHeight = this->leftPinLayout->findChildren<PinWidget*>().front()->height();
|
||||
// auto horizontalPinWidgetWidth = this->leftPinLayout->findChildren<PinWidget*>().front()->width();
|
||||
|
||||
auto verticalPinWidgetHeight = PinWidget::MAXIMUM_VERTICAL_HEIGHT;
|
||||
auto verticalPinWidgetWidth = PinWidget::MAXIMUM_VERTICAL_WIDTH;
|
||||
auto horizontalPinWidgetHeight = PinWidget::MAXIMUM_HORIZONTAL_HEIGHT;
|
||||
auto horizontalPinWidgetWidth = PinWidget::MAXIMUM_HORIZONTAL_WIDTH;
|
||||
|
||||
auto pinCountPerLayout = static_cast<int>(this->pinWidgets.size() / 4);
|
||||
|
||||
auto width = ((horizontalPinWidgetHeight + QuadFlatPackageWidget::PIN_WIDGET_SPACING) * pinCountPerLayout
|
||||
+ QuadFlatPackageWidget::PIN_WIDGET_LAYOUT_PADDING);
|
||||
|
||||
auto containerWidth = width + (horizontalPinWidgetWidth * 2);
|
||||
|
||||
this->topPinLayout->setGeometry(QRect(
|
||||
horizontalPinWidgetWidth,
|
||||
0,
|
||||
width,
|
||||
verticalPinWidgetHeight
|
||||
));
|
||||
|
||||
this->horizontalLayout->setGeometry(QRect(
|
||||
0,
|
||||
verticalPinWidgetHeight,
|
||||
containerWidth,
|
||||
width
|
||||
));
|
||||
|
||||
this->leftPinLayout->setGeometry(QRect(
|
||||
0,
|
||||
verticalPinWidgetHeight,
|
||||
horizontalPinWidgetWidth,
|
||||
width
|
||||
));
|
||||
|
||||
this->bodyWidget->setGeometry(QRect(
|
||||
horizontalPinWidgetWidth,
|
||||
verticalPinWidgetHeight,
|
||||
width,
|
||||
width
|
||||
));
|
||||
|
||||
this->rightPinLayout->setGeometry(QRect(
|
||||
width + horizontalPinWidgetWidth,
|
||||
verticalPinWidgetHeight,
|
||||
horizontalPinWidgetWidth,
|
||||
width
|
||||
));
|
||||
|
||||
this->bottomPinLayout->setGeometry(QRect(
|
||||
horizontalPinWidgetWidth,
|
||||
verticalPinWidgetHeight + width,
|
||||
width,
|
||||
verticalPinWidgetHeight
|
||||
));
|
||||
|
||||
auto pinWidgetLayoutMargin = QuadFlatPackageWidget::PIN_WIDGET_LAYOUT_PADDING / 2;
|
||||
|
||||
this->topPinLayout->setContentsMargins(
|
||||
pinWidgetLayoutMargin,
|
||||
0,
|
||||
pinWidgetLayoutMargin,
|
||||
0
|
||||
);
|
||||
|
||||
this->bottomPinLayout->setContentsMargins(
|
||||
pinWidgetLayoutMargin,
|
||||
0,
|
||||
pinWidgetLayoutMargin,
|
||||
0
|
||||
);
|
||||
|
||||
this->leftPinLayout->setContentsMargins(
|
||||
0,
|
||||
pinWidgetLayoutMargin,
|
||||
0,
|
||||
pinWidgetLayoutMargin
|
||||
);
|
||||
|
||||
this->rightPinLayout->setContentsMargins(
|
||||
0,
|
||||
pinWidgetLayoutMargin,
|
||||
0,
|
||||
pinWidgetLayoutMargin
|
||||
);
|
||||
|
||||
auto containerHeight = width + (verticalPinWidgetHeight * 2);
|
||||
this->setGeometry(
|
||||
(parentContainerWidth / 2) - (containerWidth / 2),
|
||||
(parentContainerHeight / 2) - (containerHeight / 2),
|
||||
containerWidth,
|
||||
containerHeight
|
||||
);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
#pragma once
|
||||
|
||||
#include <QWidget>
|
||||
#include <vector>
|
||||
#include <QHBoxLayout>
|
||||
#include <QVBoxLayout>
|
||||
|
||||
#include "../TargetPackageWidget.hpp"
|
||||
#include "PinWidget.hpp"
|
||||
#include "BodyWidget.hpp"
|
||||
#include "src/Targets/TargetVariant.hpp"
|
||||
|
||||
namespace Bloom::InsightTargetWidgets::Qfp
|
||||
{
|
||||
using Targets::TargetVariant;
|
||||
|
||||
/**
|
||||
* QuadFlatPackageWidget implements a custom Qt widget for Quad-flat package variants.
|
||||
*/
|
||||
class QuadFlatPackageWidget: public TargetPackageWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
private:
|
||||
QVBoxLayout* layout = nullptr;
|
||||
QHBoxLayout* horizontalLayout = nullptr;
|
||||
QHBoxLayout* topPinLayout = nullptr;
|
||||
QVBoxLayout* rightPinLayout = nullptr;
|
||||
QHBoxLayout* bottomPinLayout = nullptr;
|
||||
QVBoxLayout* leftPinLayout = nullptr;
|
||||
BodyWidget* bodyWidget = nullptr;
|
||||
|
||||
protected:
|
||||
void paintEvent(QPaintEvent* event);
|
||||
void drawWidget(QPainter& painter);
|
||||
|
||||
public:
|
||||
static const int PIN_WIDGET_LAYOUT_PADDING = 46;
|
||||
static const int PIN_WIDGET_SPACING = 8;
|
||||
QuadFlatPackageWidget(const TargetVariant& targetVariant, QObject* insightWindowObj, QWidget* parent);
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
#target-pin-number,
|
||||
#target-pin-number {
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
#target-pin-name,
|
||||
#target-pin-direction {
|
||||
font-size: 11px;
|
||||
}
|
||||
|
||||
#target-pin-name {
|
||||
color: #a6a7aa;
|
||||
}
|
||||
|
||||
#target-pin-direction {
|
||||
color: #8a8a8d;
|
||||
}
|
||||
|
||||
#target-pin-number {
|
||||
}
|
||||
|
||||
#target-body {
|
||||
qproperty-bodyColor: #A6A8AB;
|
||||
qproperty-disableAlphaLevel: 100;
|
||||
}
|
||||
|
||||
#target-pin-body {
|
||||
qproperty-bodyColor: #A6A8AB;
|
||||
qproperty-disableAlphaLevel: 100;
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
#pragma once
|
||||
|
||||
#include <QWidget>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
|
||||
#include "TargetPinWidget.hpp"
|
||||
#include "src/Targets/TargetVariant.hpp"
|
||||
#include "src/Targets/TargetDescriptor.hpp"
|
||||
|
||||
namespace Bloom::InsightTargetWidgets
|
||||
{
|
||||
using Targets::TargetVariant;
|
||||
using Targets::TargetPinState;
|
||||
|
||||
/**
|
||||
* Each custom target package widget should be derived from this class.
|
||||
*/
|
||||
class TargetPackageWidget: public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
protected:
|
||||
TargetVariant targetVariant;
|
||||
std::vector<TargetPinWidget*> pinWidgets;
|
||||
|
||||
public:
|
||||
TargetPackageWidget(const TargetVariant& targetVariant, QObject* insightWindowObj, QWidget* parent):
|
||||
QWidget(parent), targetVariant(targetVariant) {};
|
||||
|
||||
virtual void updatePinStates(std::map<int, TargetPinState> pinStatesByNumber) {
|
||||
for (auto& pinWidget : this->pinWidgets) {
|
||||
auto pinNumber = pinWidget->getPinNumber();
|
||||
if (pinStatesByNumber.contains(pinNumber)) {
|
||||
pinWidget->updatePinState(pinStatesByNumber.at(pinNumber));
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
#pragma once
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
#include "src/Targets/TargetVariant.hpp"
|
||||
#include "src/Targets/TargetPinDescriptor.hpp"
|
||||
|
||||
namespace Bloom::InsightTargetWidgets
|
||||
{
|
||||
using Targets::TargetVariant;
|
||||
using Targets::TargetPinDescriptor;
|
||||
using Targets::TargetPinType;
|
||||
using Targets::TargetPinState;
|
||||
|
||||
class TargetPinWidget: public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
protected:
|
||||
TargetVariant targetVariant;
|
||||
TargetPinDescriptor pinDescriptor;
|
||||
std::optional<TargetPinState> pinState;
|
||||
bool pinStateChanged = false;
|
||||
|
||||
public:
|
||||
TargetPinWidget(QWidget* parent, const TargetPinDescriptor& pinDescriptor, const TargetVariant& targetVariant):
|
||||
QWidget(parent), targetVariant(targetVariant), pinDescriptor(pinDescriptor) {
|
||||
this->setDisabled(false);
|
||||
};
|
||||
|
||||
int getPinNumber() const {
|
||||
return this->pinDescriptor.number;
|
||||
}
|
||||
|
||||
const TargetPinDescriptor& getPinDescriptor() const {
|
||||
return this->pinDescriptor;
|
||||
}
|
||||
|
||||
std::optional<TargetPinState> getPinState() const {
|
||||
return this->pinState;
|
||||
}
|
||||
|
||||
virtual void updatePinState(const TargetPinState& pinState) {
|
||||
this->pinStateChanged = !this->pinState.has_value()
|
||||
|| this->pinState->ioState != pinState.ioState
|
||||
|| this->pinState->ioDirection != pinState.ioDirection;
|
||||
|
||||
this->pinState = pinState;
|
||||
}
|
||||
|
||||
void setDisabled(bool disabled) {
|
||||
if (pinDescriptor.type != TargetPinType::GND
|
||||
&& pinDescriptor.type != TargetPinType::VCC
|
||||
&& pinDescriptor.type != TargetPinType::UNKNOWN
|
||||
) {
|
||||
QWidget::setDisabled(disabled);
|
||||
|
||||
} else {
|
||||
QWidget::setDisabled(true);
|
||||
}
|
||||
}
|
||||
|
||||
public slots:
|
||||
void onWidgetBodyClicked() {
|
||||
emit this->toggleIoState(this);
|
||||
}
|
||||
|
||||
signals:
|
||||
void toggleIoState(TargetPinWidget* pinWidget);
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<widget class="QMainWindow" name="about-window">
|
||||
<property name="windowTitle"><string>About</string></property>
|
||||
<property name="maximized"><bool>false</bool></property>
|
||||
|
||||
<widget class="QWidget" name="container">
|
||||
<layout class="QVBoxLayout">
|
||||
<item alignment="Qt::AlignHCenter">
|
||||
<widget class="QWidget" name="bloom-icon">
|
||||
|
||||
</widget>
|
||||
</item>
|
||||
<item alignment="Qt::AlignHCenter">
|
||||
<widget class="QLabel" name="version-label">
|
||||
<property name="text">
|
||||
<string>Bloom</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item alignment="Qt::AlignHCenter">
|
||||
<widget class="QLabel" name="link-label">
|
||||
<property name="text">
|
||||
<string><![CDATA[
|
||||
<a style="color: #3F86A0;" href="https://bloom.oscillate.io/">https://bloom.oscillate.io/</a>
|
||||
]]></string>
|
||||
</property>
|
||||
<property name="openExternalLinks">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item alignment="Qt::AlignHCenter">
|
||||
<widget class="QLabel" name="author-label">
|
||||
<property name="text">
|
||||
<string>Nav Mohammed</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item alignment="Qt::AlignHCenter">
|
||||
<spacer name="vSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item alignment="Qt::AlignHCenter">
|
||||
<widget class="QLabel" name="os-link-label">
|
||||
<property name="text">
|
||||
<string><![CDATA[
|
||||
<span>Powered by <a style="color: #3F86A0;" href="https://bloom.oscillate.io/">open-source software</a></span>
|
||||
]]></string>
|
||||
</property>
|
||||
<property name="openExternalLinks">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
</ui>
|
||||
@@ -0,0 +1,189 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<widget class="QMainWindow" name="main-window">
|
||||
<property name="minimumHeight"><number>500</number></property>
|
||||
<property name="minimumWidth"><number>1000</number></property>
|
||||
<property name="windowTitle"><string>Bloom</string></property>
|
||||
<property name="maximized"><bool>false</bool></property>
|
||||
|
||||
<widget class="QMenuBar" name="menu-bar">
|
||||
<property name="nativeMenuBar">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
|
||||
<widget class="QMenu" name="file-menu">
|
||||
<property name="title"><string>File</string></property>
|
||||
<addaction name="close-insight"/>
|
||||
<action name="close-insight">
|
||||
<property name="text">
|
||||
<string>Exit</string>
|
||||
</property>
|
||||
</action>
|
||||
</widget>
|
||||
|
||||
<widget class="QMenu" name="help-menu">
|
||||
<property name="title"><string>Help</string></property>
|
||||
<addaction name="open-getting-started-url"/>
|
||||
<addaction name="open-report-issues-url"/>
|
||||
<addaction name="separator"/>
|
||||
<addaction name="open-about-dialogue"/>
|
||||
<action name="open-getting-started-url">
|
||||
<property name="text">
|
||||
<string>Getting Started</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="open-report-issues-url">
|
||||
<property name="text">
|
||||
<string>Report An Issue</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="open-about-dialogue">
|
||||
<property name="text">
|
||||
<string>About</string>
|
||||
</property>
|
||||
</action>
|
||||
</widget>
|
||||
|
||||
<addaction name="file-menu"/>
|
||||
<addaction name="help-menu"/>
|
||||
</widget>
|
||||
|
||||
<widget class="QWidget">
|
||||
<layout class="QVBoxLayout">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="margin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QWidget" name="header">
|
||||
<widget class="QToolBar" name="header-tool-bar">
|
||||
<widget class="QToolButton" name="refresh-io-inspection-btn">
|
||||
<property name="icon">
|
||||
<iconset>
|
||||
<disabledoff>:/compiled/Insight/UserInterfaces/InsightWindow/Images/refresh-disabled.svg</disabledoff>
|
||||
<normalon>:/compiled/Insight/UserInterfaces/InsightWindow/Images/refresh.svg</normalon>
|
||||
</iconset>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Refresh GPIO Pin States</string>
|
||||
</property>
|
||||
</widget>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QWidget" name="container">
|
||||
<layout class="QHBoxLayout">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="margin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QWidget" name="io-container">
|
||||
<layout class="QHBoxLayout">
|
||||
<item alignment="Qt::AlignHCenter">
|
||||
<widget class="QLabel" name="io-inspection-unavailable">
|
||||
<property name="visible"><bool>false</bool></property>
|
||||
<property name="text">
|
||||
<string>IO inspection is not available for this target. Please report this to Bloom developers by clicking Help -> Report An Issue</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<!-- Target RAM inspection will be introduced in a later version -->
|
||||
<!-- <item>-->
|
||||
<!-- <widget class="QWidget" name="rhSideBar">-->
|
||||
<!-- <property name="layoutDirection">-->
|
||||
<!-- <enum>Qt::RightToLeft</enum>-->
|
||||
<!-- </property>-->
|
||||
<!-- <layout class="QVBoxLayout">-->
|
||||
<!-- <property name="spacing">-->
|
||||
<!-- <number>0</number>-->
|
||||
<!-- </property>-->
|
||||
<!-- <property name="margin">-->
|
||||
<!-- <number>0</number>-->
|
||||
<!-- </property>-->
|
||||
|
||||
<!-- <item alignment="Qt::AlignTop">-->
|
||||
<!-- <widget class="QToolButton" name="inspectRamBtn">-->
|
||||
<!-- <property name="toolTip">-->
|
||||
<!-- <string>Inspect Target RAM</string>-->
|
||||
<!-- </property>-->
|
||||
<!-- </widget>-->
|
||||
<!-- </item>-->
|
||||
<!-- </layout>-->
|
||||
<!-- </widget>-->
|
||||
<!-- </item>-->
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QWidget" name="footer">
|
||||
<layout class="QHBoxLayout" stretch="100,0,0">
|
||||
<property name="spacing"><number>0</number></property>
|
||||
<property name="margin"><number>0</number></property>
|
||||
<item alignment="Qt::AlignLeft">
|
||||
<widget class="QLabel" name="target-state">
|
||||
<property name="toolTip">
|
||||
<string>Target State</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
|
||||
<item alignment="Qt::AlignRight">
|
||||
<widget class="QLabel" name="target-program-counter-value">
|
||||
<property name="text">
|
||||
<string>-</string>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Program Counter Value</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
|
||||
<item alignment="Qt::AlignRight">
|
||||
<widget class="QLabel" name="target-name">
|
||||
<property name="toolTip">
|
||||
<string>Target Name</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
|
||||
<item alignment="Qt::AlignRight">
|
||||
<widget class="QLabel" name="target-id">
|
||||
<property name="toolTip">
|
||||
<string>Target ID</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
|
||||
<item alignment="Qt::AlignRight">
|
||||
<widget class="QMenuBar" name="target-variant-menu-bar">
|
||||
<property name="nativeMenuBar">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="defaultUp">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
|
||||
<widget class="QMenu" name="target-variant-menu">
|
||||
<property name="title">
|
||||
<string>No supported variants available</string>
|
||||
</property>
|
||||
</widget>
|
||||
<addaction name="target-variant-menu"/>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
</ui>
|
||||
Reference in New Issue
Block a user