blob: 32c7a2104da7eb910acab63660278dd49b2e2603 [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/Window.h"
6
James Kuszmaulcf324122023-01-14 14:07:17 -08007#include <imgui.h>
Austin Schuh812d0d12021-11-04 20:16:48 -07008#include <imgui_internal.h>
9#include <wpi/StringExtras.h>
10
11#include "glass/Context.h"
Austin Schuh75263e32022-02-22 18:05:32 -080012#include "glass/Storage.h"
James Kuszmaulcf324122023-01-14 14:07:17 -080013#include "glass/support/ExtraGuiWidgets.h"
Austin Schuh812d0d12021-11-04 20:16:48 -070014
15using namespace glass;
16
Austin Schuh75263e32022-02-22 18:05:32 -080017Window::Window(Storage& storage, std::string_view id,
18 Visibility defaultVisibility)
19 : m_id{id},
20 m_name{storage.GetString("name")},
21 m_defaultName{id},
22 m_visible{storage.GetBool("visible", defaultVisibility != kHide)},
23 m_enabled{storage.GetBool("enabled", defaultVisibility != kDisabled)},
24 m_defaultVisible{storage.GetValue("visible").boolDefault},
25 m_defaultEnabled{storage.GetValue("enabled").boolDefault} {}
26
Austin Schuh812d0d12021-11-04 20:16:48 -070027void Window::SetVisibility(Visibility visibility) {
Austin Schuh75263e32022-02-22 18:05:32 -080028 m_visible = visibility != kHide;
29 m_enabled = visibility != kDisabled;
30}
31
32void Window::SetDefaultVisibility(Visibility visibility) {
33 m_defaultVisible = visibility != kHide;
34 m_defaultEnabled = visibility != kDisabled;
Austin Schuh812d0d12021-11-04 20:16:48 -070035}
36
37void Window::Display() {
38 if (!m_view) {
39 return;
40 }
41 if (!m_visible || !m_enabled) {
42 PushID(m_id);
43 m_view->Hidden();
44 PopID();
45 return;
46 }
47
48 if (m_posCond != 0) {
49 ImGui::SetNextWindowPos(m_pos, m_posCond);
50 }
51 if (m_sizeCond != 0) {
52 ImGui::SetNextWindowSize(m_size, m_sizeCond);
53 }
54 if (m_setPadding) {
55 ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, m_padding);
56 }
57
58 char label[128];
James Kuszmaulb13e13f2023-11-22 20:44:04 -080059 if (m_name.empty()) {
60 wpi::format_to_n_c_str(label, sizeof(label), "{}###{}", m_defaultName,
61 m_id);
62 } else {
63 wpi::format_to_n_c_str(label, sizeof(label), "{}###{}", m_name, m_id);
64 }
Austin Schuh812d0d12021-11-04 20:16:48 -070065
66 if (Begin(label, &m_visible, m_flags)) {
James Kuszmaulcf324122023-01-14 14:07:17 -080067 if (m_renamePopupEnabled || m_view->HasSettings()) {
68 bool isClicked = (ImGui::IsMouseReleased(ImGuiMouseButton_Right) &&
69 ImGui::IsItemHovered());
70 ImGuiWindow* window = ImGui::GetCurrentWindow();
71
72 bool settingsButtonClicked = false;
73 // Not docked, and window has just enough for the circles not to be
74 // touching
75 if (!ImGui::IsWindowDocked() &&
76 ImGui::GetWindowWidth() > (ImGui::GetFontSize() + 2) * 3 +
77 ImGui::GetStyle().FramePadding.x * 2) {
78 const ImGuiItemFlags itemFlagsRestore =
79 ImGui::GetCurrentContext()->CurrentItemFlags;
80
81 ImGui::GetCurrentContext()->CurrentItemFlags |=
82 ImGuiItemFlags_NoNavDefaultFocus;
83 window->DC.NavLayerCurrent = ImGuiNavLayer_Menu;
84
85 // Allow to draw outside of normal window
86 ImGui::PushClipRect(window->OuterRectClipped.Min,
87 window->OuterRectClipped.Max, false);
88
89 const ImRect titleBarRect = ImGui::GetCurrentWindow()->TitleBarRect();
90 const ImVec2 position = {titleBarRect.Max.x -
91 (ImGui::GetStyle().FramePadding.x * 3) -
92 (ImGui::GetFontSize() * 2),
93 titleBarRect.Min.y};
94 settingsButtonClicked =
95 HamburgerButton(ImGui::GetID("#SETTINGS"), position);
96
97 ImGui::PopClipRect();
98
99 ImGui::GetCurrentContext()->CurrentItemFlags = itemFlagsRestore;
100 }
101 if (settingsButtonClicked || isClicked) {
102 ImGui::OpenPopup(window->ID);
103 }
104
105 if (ImGui::BeginPopupEx(window->ID,
106 ImGuiWindowFlags_AlwaysAutoResize |
107 ImGuiWindowFlags_NoTitleBar |
108 ImGuiWindowFlags_NoSavedSettings)) {
109 if (m_renamePopupEnabled) {
110 ItemEditName(&m_name);
111 }
112 m_view->Settings();
113
114 ImGui::EndPopup();
115 }
Austin Schuh812d0d12021-11-04 20:16:48 -0700116 }
James Kuszmaulcf324122023-01-14 14:07:17 -0800117
Austin Schuh812d0d12021-11-04 20:16:48 -0700118 m_view->Display();
119 } else {
120 m_view->Hidden();
121 }
122 End();
123 if (m_setPadding) {
124 ImGui::PopStyleVar();
125 }
126}
127
128bool Window::DisplayMenuItem(const char* label) {
129 bool wasVisible = m_visible;
130 ImGui::MenuItem(
131 label ? label : (m_name.empty() ? m_id.c_str() : m_name.c_str()), nullptr,
132 &m_visible, m_enabled);
133 return !wasVisible && m_visible;
134}
135
136void Window::ScaleDefault(float scale) {
137 if ((m_posCond & ImGuiCond_FirstUseEver) != 0) {
138 m_pos.x *= scale;
139 m_pos.y *= scale;
140 }
141 if ((m_sizeCond & ImGuiCond_FirstUseEver) != 0) {
142 m_size.x *= scale;
143 m_size.y *= scale;
144 }
145}