blob: adab6e75a32a0ae822047230fd54acaec248dea9 [file] [log] [blame]
Austin Schuh812d0d12021-11-04 20:16:48 -07001// Copyright (c) FIRST and other WPILib contributors.
2// Open Source Software; you can modify and/or share it under the terms of
3// the WPILib BSD license file in the root directory of this project.
4
5#include "glass/DataSource.h"
6
7#include <fmt/format.h>
8
9#include "glass/ContextInternal.h"
10
11using namespace glass;
12
13wpi::sig::Signal<const char*, DataSource*> DataSource::sourceCreated;
14
15DataSource::DataSource(std::string_view id) : m_id{id} {
16 auto it = gContext->sources.try_emplace(m_id, this);
17 auto& srcName = it.first->getValue();
18 m_name = srcName.name.get();
19 if (!srcName.source) {
20 srcName.source = this;
21 }
22 sourceCreated(m_id.c_str(), this);
23}
24
25DataSource::DataSource(std::string_view id, int index)
26 : DataSource{fmt::format("{}[{}]", id, index)} {}
27
28DataSource::DataSource(std::string_view id, int index, int index2)
29 : DataSource{fmt::format("{}[{},{}]", id, index, index2)} {}
30
31DataSource::~DataSource() {
32 if (!gContext) {
33 return;
34 }
35 auto it = gContext->sources.find(m_id);
36 if (it == gContext->sources.end()) {
37 return;
38 }
39 auto& srcName = it->getValue();
40 if (srcName.source == this) {
41 srcName.source = nullptr;
42 }
43}
44
45void DataSource::SetName(std::string_view name) {
46 m_name->SetName(name);
47}
48
49const char* DataSource::GetName() const {
50 return m_name->GetName();
51}
52
53void DataSource::PushEditNameId(int index) {
54 m_name->PushEditNameId(index);
55}
56
57void DataSource::PushEditNameId(const char* name) {
58 m_name->PushEditNameId(name);
59}
60
61bool DataSource::PopupEditName(int index) {
62 return m_name->PopupEditName(index);
63}
64
65bool DataSource::PopupEditName(const char* name) {
66 return m_name->PopupEditName(name);
67}
68
69bool DataSource::InputTextName(const char* label_id,
70 ImGuiInputTextFlags flags) {
71 return m_name->InputTextName(label_id, flags);
72}
73
74void DataSource::LabelText(const char* label, const char* fmt, ...) const {
75 va_list args;
76 va_start(args, fmt);
77 LabelTextV(label, fmt, args);
78 va_end(args);
79}
80
81// Add a label+text combo aligned to other label+value widgets
82void DataSource::LabelTextV(const char* label, const char* fmt,
83 va_list args) const {
84 ImGui::PushID(label);
85 ImGui::LabelTextV("##input", fmt, args);
86 ImGui::SameLine(0, ImGui::GetStyle().ItemInnerSpacing.x);
87 ImGui::Selectable(label);
88 ImGui::PopID();
89 EmitDrag();
90}
91
92bool DataSource::Combo(const char* label, int* current_item,
93 const char* const items[], int items_count,
94 int popup_max_height_in_items) const {
95 ImGui::PushID(label);
96 bool rv = ImGui::Combo("##input", current_item, items, items_count,
97 popup_max_height_in_items);
98 ImGui::SameLine(0, ImGui::GetStyle().ItemInnerSpacing.x);
99 ImGui::Selectable(label);
100 EmitDrag();
101 ImGui::PopID();
102 return rv;
103}
104
105bool DataSource::SliderFloat(const char* label, float* v, float v_min,
106 float v_max, const char* format,
107 float power) const {
108 ImGui::PushID(label);
109 bool rv = ImGui::SliderFloat("##input", v, v_min, v_max, format, power);
110 ImGui::SameLine(0, ImGui::GetStyle().ItemInnerSpacing.x);
111 ImGui::Selectable(label);
112 EmitDrag();
113 ImGui::PopID();
114 return rv;
115}
116
117bool DataSource::InputDouble(const char* label, double* v, double step,
118 double step_fast, const char* format,
119 ImGuiInputTextFlags flags) const {
120 ImGui::PushID(label);
121 bool rv = ImGui::InputDouble("##input", v, step, step_fast, format, flags);
122 ImGui::SameLine(0, ImGui::GetStyle().ItemInnerSpacing.x);
123 ImGui::Selectable(label);
124 EmitDrag();
125 ImGui::PopID();
126 return rv;
127}
128
129bool DataSource::InputInt(const char* label, int* v, int step, int step_fast,
130 ImGuiInputTextFlags flags) const {
131 ImGui::PushID(label);
132 bool rv = ImGui::InputInt("##input", v, step, step_fast, flags);
133 ImGui::SameLine(0, ImGui::GetStyle().ItemInnerSpacing.x);
134 ImGui::Selectable(label);
135 EmitDrag();
136 ImGui::PopID();
137 return rv;
138}
139
140void DataSource::EmitDrag(ImGuiDragDropFlags flags) const {
141 if (ImGui::BeginDragDropSource(flags)) {
142 auto self = this;
143 ImGui::SetDragDropPayload("DataSource", &self, sizeof(self)); // NOLINT
144 const char* name = GetName();
145 ImGui::TextUnformatted(name[0] == '\0' ? m_id.c_str() : name);
146 ImGui::EndDragDropSource();
147 }
148}
149
150DataSource* DataSource::Find(std::string_view id) {
151 auto it = gContext->sources.find(id);
152 if (it == gContext->sources.end()) {
153 return nullptr;
154 }
155 return it->getValue().source;
156}