Skip to content

Commit 89ffc25

Browse files
author
Gin
committed
trying to get box draw on label program
1 parent 5f8adea commit 89ffc25

File tree

20 files changed

+232
-80
lines changed

20 files changed

+232
-80
lines changed

Common/Cpp/Options/ConfigOption.h

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -32,18 +32,33 @@ enum class ConfigOptionState{
3232
};
3333

3434

35-
// An option of a program, like the number of boxes of eggs to hatch,
36-
// the number of frames to skip, or what type of pokeballs to throw.
37-
// It is responsible for setting the UI (by calling make_ui()) of this option.
35+
// Abstract base class for An option of a program, like the number of boxes of
36+
// eggs to hatch, the number of frames to skip, or what type of pokeballs to throw.
37+
// It is responsible for setting the UI (by calling make_QtWidget()) of this option.
3838
// It also uses load_json() and to_json() to load and save the option to
3939
// a json file, so that the program can remember what user has selected.
4040
class ConfigOption{
4141
public:
42+
// the objects that listen to changes on the ConfigOption should inherit
43+
// this Listener struct and call ConfigOption::add_listener() to add themselves
44+
// to the listener set.
45+
// Afterwards, whenever the config state is changed, all added listeners'
46+
// corresponding member functions (e.g. value_changed()) will get called by
47+
// the config option.
4248
struct Listener{
43-
// Pass the object that initiated the change. This is mainly used to
44-
// identify yourself as the initiater to avoid infinite loops.
49+
// When the config option value is changed, all added listeners'
50+
// value_changed() will get called.
51+
// object: the object that initiated the change. e.g. If the user changes
52+
// a UI content, object would be the UI option that is changed. This is
53+
// mainly used to avoid infinite loops. So if the initial change triggers
54+
// the original UI option's value_changed() get called, it will know that
55+
// object == this and therefore a loop is formed.
4556
virtual void on_config_value_changed(void* object){}
57+
// When the config UI visibility is changed, all added listeners'
58+
// visibility_changed() will get called.
4659
virtual void on_config_visibility_changed(){}
60+
// When the program state is changed, all added listeners'
61+
// program_state_changed() will get called.
4762
virtual void on_program_state_changed(bool program_is_running){}
4863
};
4964
void add_listener(Listener& listener);

SerialPrograms/Source/CommonFramework/Panels/PanelList.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,11 @@ class PanelListDescriptor{
2727
const std::string& name() const{ return m_name; }
2828
bool enabled() const{ return m_enabled; }
2929

30-
virtual std::vector<PanelEntry> make_panels() const = 0;
31-
32-
public:
3330
PanelListWidget* make_QWidget(QWidget& parent, PanelHolder& holder) const;
3431

32+
protected:
33+
virtual std::vector<PanelEntry> make_panels() const = 0;
34+
3535
protected:
3636
std::string m_name;
3737
bool m_enabled;

SerialPrograms/Source/CommonFramework/VideoPipeline/Backends/CameraWidgetQt6.5.h

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -52,9 +52,6 @@ class CameraBackend : public PokemonAutomation::CameraBackend{
5252
};
5353

5454

55-
56-
57-
5855
class StaticQGraphicsView : public QGraphicsView{
5956
public:
6057
StaticQGraphicsView(QWidget* parent)
@@ -90,16 +87,6 @@ class StaticQGraphicsView : public QGraphicsView{
9087
};
9188

9289

93-
94-
95-
96-
97-
98-
99-
100-
101-
102-
10390
class CameraVideoSource : public QObject, public VideoSource{
10491
public:
10592
virtual ~CameraVideoSource();
@@ -147,7 +134,6 @@ class CameraVideoSource : public QObject, public VideoSource{
147134

148135
PeriodicStatsReporterI32 m_stats_conversion;
149136

150-
151137
private:
152138
// Last Frame: All accesses must be under this lock.
153139
// These will be updated very rapidly by the main thread.

SerialPrograms/Source/CommonFramework/VideoPipeline/VideoOverlayScopes.h

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -107,14 +107,6 @@ class OverlayLogTextScope{
107107
};
108108

109109

110-
111-
112-
113-
114-
115-
116-
117-
118110
// Used by video inference sessions to manage inference boxes.
119111
// VideoOverlaySet will be passed to the inference callbacks in a session
120112
// to store inference boxes. When the session ends, VideoOverlaySet::clear()

SerialPrograms/Source/ML/ML_Panels.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,8 @@ namespace ML{
1717
class PanelListFactory : public PanelListDescriptor{
1818
public:
1919
PanelListFactory();
20-
virtual std::vector<PanelEntry> make_panels() const;
20+
private:
21+
virtual std::vector<PanelEntry> make_panels() const override;
2122
};
2223

2324

SerialPrograms/Source/ML/Programs/ML_LabelImages.cpp

Lines changed: 121 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,99 @@
44
*
55
*/
66

7+
#include <QLabel>
8+
#include <QDir>
79
#include <QVBoxLayout>
10+
#include <QGraphicsView>
11+
#include <QGraphicsScene>
12+
#include <QGraphicsPixmapItem>
813
#include <QScrollArea>
14+
#include <QPushButton>
15+
#include <QResizeEvent>
16+
#include <iostream>
17+
#include "Common/Cpp/Json/JsonObject.h"
918
#include "Common/Cpp/Json/JsonValue.h"
1019
#include "Common/Qt/CollapsibleGroupBox.h"
20+
#include "CommonFramework/VideoPipeline/VideoOverlayScopes.h"
21+
#include "NintendoSwitch/Framework/UI/NintendoSwitch_SwitchSystemWidget.h"
22+
#include "CommonFramework/VideoPipeline/Backends/CameraWidgetQt6.5.h"
1123
#include "ML_LabelImages.h"
1224
#include "Pokemon/Pokemon_Strings.h"
25+
#include "Common/Qt/Options/ConfigWidget.h"
26+
27+
28+
using std::cout;
29+
using std::endl;
1330

1431
namespace PokemonAutomation{
1532
namespace ML{
1633

34+
35+
DrawnBoundingBox::DrawnBoundingBox(LabelImages& parent, VideoOverlay& overlay)
36+
: m_parent(parent)
37+
, m_overlay(overlay)
38+
, m_overlay_set(overlay)
39+
{
40+
m_parent.X.add_listener(*this);
41+
m_parent.Y.add_listener(*this);
42+
m_parent.WIDTH.add_listener(*this);
43+
m_parent.HEIGHT.add_listener(*this);
44+
overlay.add_listener(*this);
45+
}
46+
47+
DrawnBoundingBox::~DrawnBoundingBox(){
48+
detach();
49+
}
50+
51+
void DrawnBoundingBox::on_config_value_changed(void* object){
52+
std::lock_guard<std::mutex> lg(m_lock);
53+
m_overlay_set.clear();
54+
m_overlay_set.add(COLOR_RED, {m_parent.X, m_parent.Y, m_parent.WIDTH, m_parent.HEIGHT});
55+
}
56+
void DrawnBoundingBox::on_mouse_press(double x, double y){
57+
m_parent.WIDTH.set(0);
58+
m_parent.HEIGHT.set(0);
59+
m_parent.X.set(x);
60+
m_parent.Y.set(y);
61+
m_mouse_start.emplace();
62+
m_mouse_start->first = x;
63+
m_mouse_start->second = y;
64+
}
65+
void DrawnBoundingBox::on_mouse_release(double x, double y){
66+
m_mouse_start.reset();
67+
}
68+
void DrawnBoundingBox::on_mouse_move(double x, double y){
69+
if (!m_mouse_start){
70+
return;
71+
}
72+
73+
double xl = m_mouse_start->first;
74+
double xh = x;
75+
double yl = m_mouse_start->second;
76+
double yh = y;
77+
78+
if (xl > xh){
79+
std::swap(xl, xh);
80+
}
81+
if (yl > yh){
82+
std::swap(yl, yh);
83+
}
84+
85+
m_parent.X.set(xl);
86+
m_parent.Y.set(yl);
87+
m_parent.WIDTH.set(xh - xl);
88+
m_parent.HEIGHT.set(yh - yl);
89+
}
90+
91+
void DrawnBoundingBox::detach(){
92+
m_overlay.remove_listener(*this);
93+
m_parent.X.remove_listener(*this);
94+
m_parent.Y.remove_listener(*this);
95+
m_parent.WIDTH.remove_listener(*this);
96+
m_parent.HEIGHT.remove_listener(*this);
97+
}
98+
99+
17100
LabelImages_Descriptor::LabelImages_Descriptor()
18101
: PanelDescriptor(
19102
Color(),
@@ -25,45 +108,55 @@ LabelImages_Descriptor::LabelImages_Descriptor()
25108
{}
26109

27110

111+
#define ADD_OPTION(x) m_options.add_option(x, #x)
28112

29113
LabelImages::LabelImages(const LabelImages_Descriptor& descriptor)
30114
: PanelInstance(descriptor)
31-
// , m_switch({}, false)
32-
{}
115+
, m_switch_control_option({}, false)
116+
, m_options(LockMode::UNLOCK_WHILE_RUNNING)
117+
, X("<b>X Coordinate:</b>", LockMode::UNLOCK_WHILE_RUNNING, 0.3, 0.0, 1.0)
118+
, Y("<b>Y Coordinate:</b>", LockMode::UNLOCK_WHILE_RUNNING, 0.3, 0.0, 1.0)
119+
, WIDTH("<b>Width:</b>", LockMode::UNLOCK_WHILE_RUNNING, 0.4, 0.0, 1.0)
120+
, HEIGHT("<b>Height:</b>", LockMode::UNLOCK_WHILE_RUNNING, 0.4, 0.0, 1.0)
121+
{
122+
ADD_OPTION(X);
123+
ADD_OPTION(Y);
124+
ADD_OPTION(WIDTH);
125+
ADD_OPTION(HEIGHT);
126+
}
33127
void LabelImages::from_json(const JsonValue& json){
34-
// m_switch.load_json(json);
128+
const JsonObject* obj = json.to_object();
129+
if (obj == nullptr){
130+
return;
131+
}
132+
const JsonValue* value = obj->get_value("SwitchSetup");
133+
if (value){
134+
m_switch_control_option.load_json(*value);
135+
}
136+
m_options.load_json(json);
35137
}
36138
JsonValue LabelImages::to_json() const{
37-
return {};
38-
// return m_switch.to_json();
139+
JsonObject obj = std::move(*m_options.to_json().to_object());
140+
obj["SwitchSetup"] = m_switch_control_option.to_json();
141+
return obj;
39142
}
40143
QWidget* LabelImages::make_widget(QWidget& parent, PanelHolder& holder){
41-
return LabelImages_Widget::make(parent, *this, holder);
144+
return new LabelImages_Widget(parent, *this, holder);
42145
}
43146

44147

45-
46-
LabelImages_Widget* LabelImages_Widget::make(
47-
QWidget& parent,
48-
LabelImages& instance,
49-
PanelHolder& holder
50-
){
51-
LabelImages_Widget* widget = new LabelImages_Widget(parent, instance, holder);
52-
widget->construct();
53-
return widget;
54-
}
55148
LabelImages_Widget::~LabelImages_Widget(){
56-
// delete m_switch;
149+
delete m_switch_widget;
57150
}
58151
LabelImages_Widget::LabelImages_Widget(
59152
QWidget& parent,
60153
LabelImages& instance,
61154
PanelHolder& holder
62155
)
63156
: PanelWidget(parent, instance, holder)
64-
// , m_session(instance.m_switch, 0, 0)
65-
{}
66-
void LabelImages_Widget::construct(){
157+
, m_session(instance.m_switch_control_option, 0, 0)
158+
, m_drawn_box(instance, m_session.overlay())
159+
{
67160
QVBoxLayout* layout = new QVBoxLayout(this);
68161
layout->setContentsMargins(0, 0, 0, 0);
69162
layout->addWidget(make_header(*this));
@@ -77,10 +170,15 @@ void LabelImages_Widget::construct(){
77170
QVBoxLayout* scroll_layout = new QVBoxLayout(scroll_inner);
78171
scroll_layout->setAlignment(Qt::AlignTop);
79172

80-
// m_switch = new SwitchSystemWidget(*this, m_session, 0);
81-
// scroll_layout->addWidget(m_switch);
82-
}
173+
m_switch_widget = new NintendoSwitch::SwitchSystemWidget(*this, m_session, 0);
174+
scroll_layout->addWidget(m_switch_widget);
175+
176+
QPushButton* button = new QPushButton("This is a button", scroll_inner);
177+
scroll_layout->addWidget(button);
83178

179+
m_option_widget = instance.m_options.make_QtWidget(*scroll_inner);
180+
scroll_layout->addWidget(&m_option_widget->widget());
181+
}
84182

85183

86184

0 commit comments

Comments
 (0)