blob: 333dad4bc5127a4c69f85ea12f415f64ced1c3d7 [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/WindowManager.h"
6
7#include <algorithm>
8#include <cstdio>
9
10#include <fmt/format.h>
11#include <wpigui.h>
12
Austin Schuh75263e32022-02-22 18:05:32 -080013#include "glass/Context.h"
14#include "glass/Storage.h"
15
Austin Schuh812d0d12021-11-04 20:16:48 -070016using namespace glass;
17
Austin Schuh75263e32022-02-22 18:05:32 -080018WindowManager::WindowManager(Storage& storage) : m_storage{storage} {
19 storage.SetCustomApply([this] {
20 for (auto&& childIt : m_storage.GetChildren()) {
21 GetOrAddWindow(childIt.key(), true);
22 }
23 });
Austin Schuh812d0d12021-11-04 20:16:48 -070024}
25
26Window* WindowManager::AddWindow(std::string_view id,
Austin Schuh75263e32022-02-22 18:05:32 -080027 wpi::unique_function<void()> display,
28 Window::Visibility defaultVisibility) {
29 auto win = GetOrAddWindow(id, false, defaultVisibility);
Austin Schuh812d0d12021-11-04 20:16:48 -070030 if (!win) {
31 return nullptr;
32 }
33 if (win->HasView()) {
34 fmt::print(stderr, "GUI: ignoring duplicate window '{}'\n", id);
35 return nullptr;
36 }
37 win->SetView(MakeFunctionView(std::move(display)));
38 return win;
39}
40
41Window* WindowManager::AddWindow(std::string_view id,
Austin Schuh75263e32022-02-22 18:05:32 -080042 std::unique_ptr<View> view,
43 Window::Visibility defaultVisibility) {
44 auto win = GetOrAddWindow(id, false, defaultVisibility);
Austin Schuh812d0d12021-11-04 20:16:48 -070045 if (!win) {
46 return nullptr;
47 }
48 if (win->HasView()) {
49 fmt::print(stderr, "GUI: ignoring duplicate window '{}'\n", id);
50 return nullptr;
51 }
52 win->SetView(std::move(view));
53 return win;
54}
55
Austin Schuh75263e32022-02-22 18:05:32 -080056Window* WindowManager::GetOrAddWindow(std::string_view id, bool duplicateOk,
57 Window::Visibility defaultVisibility) {
Austin Schuh812d0d12021-11-04 20:16:48 -070058 // binary search
59 auto it = std::lower_bound(
60 m_windows.begin(), m_windows.end(), id,
61 [](const auto& elem, std::string_view s) { return elem->GetId() < s; });
62 if (it != m_windows.end() && (*it)->GetId() == id) {
63 if (!duplicateOk) {
64 fmt::print(stderr, "GUI: ignoring duplicate window '{}'\n", id);
65 return nullptr;
66 }
67 return it->get();
68 }
69 // insert before (keeps sort)
Austin Schuh75263e32022-02-22 18:05:32 -080070 return m_windows
71 .emplace(it, std::make_unique<Window>(
72 m_storage.GetChild(id).GetChild("window"), id,
73 defaultVisibility))
74 ->get();
Austin Schuh812d0d12021-11-04 20:16:48 -070075}
76
77Window* WindowManager::GetWindow(std::string_view id) {
78 // binary search
79 auto it = std::lower_bound(
80 m_windows.begin(), m_windows.end(), id,
81 [](const auto& elem, std::string_view s) { return elem->GetId() < s; });
82 if (it == m_windows.end() || (*it)->GetId() != id) {
83 return nullptr;
84 }
85 return it->get();
86}
87
Austin Schuh75263e32022-02-22 18:05:32 -080088void WindowManager::RemoveWindow(size_t index) {
89 m_storage.Erase(m_windows[index]->GetId());
90 m_windows.erase(m_windows.begin() + index);
91}
92
Austin Schuh812d0d12021-11-04 20:16:48 -070093void WindowManager::GlobalInit() {
Austin Schuh812d0d12021-11-04 20:16:48 -070094 wpi::gui::AddWindowScaler([this](float scale) {
95 // scale default window positions
96 for (auto&& window : m_windows) {
97 window->ScaleDefault(scale);
98 }
99 });
100 wpi::gui::AddLateExecute([this] { DisplayWindows(); });
101}
102
103void WindowManager::DisplayMenu() {
104 for (auto&& window : m_windows) {
105 window->DisplayMenuItem();
106 }
107}
108
109void WindowManager::DisplayWindows() {
Austin Schuh75263e32022-02-22 18:05:32 -0800110 PushStorageStack(m_storage);
Austin Schuh812d0d12021-11-04 20:16:48 -0700111 for (auto&& window : m_windows) {
112 window->Display();
113 }
Austin Schuh75263e32022-02-22 18:05:32 -0800114 PopStorageStack();
Austin Schuh812d0d12021-11-04 20:16:48 -0700115}