forked from Green-Sky/tomato
refactor big contact
This commit is contained in:
parent
858b9dfcfa
commit
b88fffd959
@ -52,12 +52,14 @@ add_executable(tomato
|
||||
./sdl_clipboard_utils.hpp
|
||||
./sdl_clipboard_utils.cpp
|
||||
|
||||
./chat_gui/theme.hpp
|
||||
./chat_gui/theme.cpp
|
||||
./chat_gui/contact_list.hpp
|
||||
./chat_gui/contact_list.cpp
|
||||
./chat_gui/file_selector.hpp
|
||||
./chat_gui/file_selector.cpp
|
||||
|
||||
./chat_gui/send_image_popup.hpp
|
||||
./chat_gui/send_image_popup.cpp
|
||||
|
||||
./chat_gui/settings_window.hpp
|
||||
./chat_gui/settings_window.cpp
|
||||
|
||||
|
145
src/chat_gui/contact_list.cpp
Normal file
145
src/chat_gui/contact_list.cpp
Normal file
@ -0,0 +1,145 @@
|
||||
#include "./contact_list.hpp"
|
||||
|
||||
#include <solanaceae/contact/components.hpp>
|
||||
|
||||
#include <imgui/imgui.h>
|
||||
//#include <imgui/imgui_internal.h>
|
||||
|
||||
bool renderContactBig(
|
||||
const Theme& th,
|
||||
ContactTextureCache& contact_tc,
|
||||
const Contact3Handle c,
|
||||
const bool unread,
|
||||
const bool selectable,
|
||||
const bool selected
|
||||
) {
|
||||
// we dont need ### bc there is no named prefix
|
||||
auto label = "##" + std::to_string(entt::to_integral(c.entity()));
|
||||
|
||||
const bool request_incoming = c.all_of<Contact::Components::RequestIncoming>();
|
||||
const bool request_outgoing = c.all_of<Contact::Components::TagRequestOutgoing>();
|
||||
|
||||
ImVec2 orig_curser_pos = ImGui::GetCursorPos();
|
||||
// HACK: fake selected to make it draw a box for us
|
||||
const bool show_selected = request_incoming || request_outgoing || selected;
|
||||
if (request_incoming) {
|
||||
ImGui::PushStyleColor(
|
||||
ImGuiCol_Header,
|
||||
th.getColor<ThemeCol_Contact::request_incoming>()
|
||||
);
|
||||
} else if (request_outgoing) {
|
||||
ImGui::PushStyleColor(
|
||||
ImGuiCol_Header,
|
||||
th.getColor<ThemeCol_Contact::request_outgoing>()
|
||||
);
|
||||
}
|
||||
|
||||
const float TEXT_BASE_HEIGHT = ImGui::GetTextLineHeightWithSpacing();
|
||||
|
||||
bool got_selected = false;
|
||||
if (selectable) {
|
||||
got_selected = ImGui::Selectable(label.c_str(), show_selected, ImGuiSelectableFlags_None, {0, 3*TEXT_BASE_HEIGHT});
|
||||
} else {
|
||||
got_selected = ImGui::InvisibleButton(label.c_str(), {-FLT_MIN, 3*TEXT_BASE_HEIGHT});
|
||||
}
|
||||
|
||||
if (request_incoming || request_outgoing) {
|
||||
ImGui::PopStyleColor();
|
||||
}
|
||||
|
||||
if (ImGui::BeginItemTooltip()) {
|
||||
if (c.all_of<Contact::Components::ConnectionState>()) {
|
||||
const auto cstate = c.get<Contact::Components::ConnectionState>().state;
|
||||
ImGui::Text("Connection state: %s",
|
||||
(cstate == Contact::Components::ConnectionState::disconnected)
|
||||
? "offline"
|
||||
: (cstate == Contact::Components::ConnectionState::direct)
|
||||
? "online (direct)"
|
||||
: "online (cloud)"
|
||||
);
|
||||
} else {
|
||||
ImGui::TextUnformatted("Connection state: unknown");
|
||||
}
|
||||
|
||||
ImGui::EndTooltip();
|
||||
}
|
||||
|
||||
ImVec2 post_curser_pos = ImGui::GetCursorPos();
|
||||
|
||||
ImVec2 img_curser {
|
||||
orig_curser_pos.x + ImGui::GetStyle().FramePadding.x,
|
||||
orig_curser_pos.y + ImGui::GetStyle().FramePadding.y
|
||||
};
|
||||
|
||||
float img_y {
|
||||
//(post_curser_pos.y - orig_curser_pos.y) - ImGui::GetStyle().FramePadding.y*2
|
||||
TEXT_BASE_HEIGHT*3 - ImGui::GetStyle().FramePadding.y*2
|
||||
};
|
||||
|
||||
ImGui::SetCursorPos(img_curser);
|
||||
|
||||
// TODO: refactor out avatar (with online state overlay)
|
||||
|
||||
ImVec4 color_current = th.getColor<ThemeCol_Contact::avatar_offline>();
|
||||
if (c.all_of<Contact::Components::ConnectionState>()) {
|
||||
const auto c_state = c.get<Contact::Components::ConnectionState>().state;
|
||||
if (c_state == Contact::Components::ConnectionState::State::direct) {
|
||||
color_current = th.getColor<ThemeCol_Contact::avatar_online_direct>();
|
||||
} else if (c_state == Contact::Components::ConnectionState::State::cloud) {
|
||||
color_current = th.getColor<ThemeCol_Contact::avatar_online_cloud>();
|
||||
}
|
||||
}
|
||||
|
||||
// avatar
|
||||
const auto [id, width, height] = contact_tc.get(c);
|
||||
ImGui::Image(
|
||||
id,
|
||||
ImVec2{img_y, img_y},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{1, 1, 1, 1},
|
||||
color_current
|
||||
);
|
||||
|
||||
ImGui::SameLine();
|
||||
ImGui::BeginGroup();
|
||||
{
|
||||
// TODO: is there a better way?
|
||||
// maybe cache mm?
|
||||
//bool has_unread = false;
|
||||
#if 0
|
||||
if (const auto* mm = _rmm.get(c); mm != nullptr) {
|
||||
if (const auto* unread_storage = mm->storage<Message::Components::TagUnread>(); unread_storage != nullptr && !unread_storage->empty()) {
|
||||
#if 0
|
||||
assert(unread_storage.size() == 0);
|
||||
assert(unread_storage.cbegin() == unread_storage.cend());
|
||||
std::cout << "UNREAD ";
|
||||
for (const auto e : mm->view<Message::Components::TagUnread>()) {
|
||||
std::cout << entt::to_integral(e) << " ";
|
||||
}
|
||||
std::cout << "\n";
|
||||
#endif
|
||||
has_unread = true;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
ImGui::Text("%s%s", unread?"* ":"", (c.all_of<Contact::Components::Name>() ? c.get<Contact::Components::Name>().name.c_str() : "<unk>"));
|
||||
|
||||
if (request_incoming) {
|
||||
ImGui::TextUnformatted("Incoming request/invite");
|
||||
} else if (request_outgoing) {
|
||||
ImGui::TextUnformatted("Outgoing request/invite");
|
||||
} else {
|
||||
//ImGui::Text("status message...");
|
||||
}
|
||||
//constexpr std::string_view test_text{"text"};
|
||||
//ImGui::RenderTextEllipsis(ImGui::GetWindowDrawList(), ImVec2{}, ImVec2{}, 1.f, 1.f, test_text.data(), test_text.data()+test_text.size(), nullptr);
|
||||
}
|
||||
ImGui::EndGroup();
|
||||
|
||||
ImGui::SetCursorPos(post_curser_pos);
|
||||
|
||||
return got_selected;
|
||||
}
|
||||
|
33
src/chat_gui/contact_list.hpp
Normal file
33
src/chat_gui/contact_list.hpp
Normal file
@ -0,0 +1,33 @@
|
||||
#pragma once
|
||||
|
||||
#include "./texture_cache_defs.hpp"
|
||||
|
||||
#include "./theme.hpp"
|
||||
|
||||
#include <solanaceae/contact/contact_model3.hpp>
|
||||
|
||||
enum class ThemeCol_Contact {
|
||||
request_incoming,
|
||||
request_outgoing,
|
||||
|
||||
avatar_online_direct,
|
||||
avatar_online_cloud,
|
||||
avatar_offline,
|
||||
};
|
||||
|
||||
// returns true if clicked, if selectable, will highlight on hover and respect selected
|
||||
// TODO: refine
|
||||
// +------+
|
||||
// | | *Name (Alias?)
|
||||
// |Avatar| Satus Message <-- richpresence interface?
|
||||
// | | user status (online/away/busy)-direct/relayed / offline <-- last text?
|
||||
// +------+
|
||||
bool renderContactBig(
|
||||
const Theme& th,
|
||||
ContactTextureCache& contact_tc,
|
||||
const Contact3Handle c,
|
||||
const bool unread = false,
|
||||
const bool selectable = false,
|
||||
const bool selected = false
|
||||
);
|
||||
|
12
src/chat_gui/texture_cache_defs.hpp
Normal file
12
src/chat_gui/texture_cache_defs.hpp
Normal file
@ -0,0 +1,12 @@
|
||||
#pragma once
|
||||
|
||||
#include <solanaceae/message3/registry_message_model.hpp>
|
||||
|
||||
#include "../texture_cache.hpp"
|
||||
#include "../tox_avatar_loader.hpp"
|
||||
#include "../message_image_loader.hpp"
|
||||
|
||||
|
||||
using ContactTextureCache = TextureCache<void*, Contact3, ToxAvatarLoader>;
|
||||
using MessageTextureCache = TextureCache<void*, Message3Handle, MessageImageLoader>;
|
||||
|
60
src/chat_gui/theme.cpp
Normal file
60
src/chat_gui/theme.cpp
Normal file
@ -0,0 +1,60 @@
|
||||
#include "./theme.hpp"
|
||||
|
||||
// HACK: includes everything and sets theme defaults
|
||||
#include "./contact_list.hpp"
|
||||
|
||||
//#include <iostream>
|
||||
|
||||
//enum class TestThemeSet {
|
||||
//Value1,
|
||||
//};
|
||||
|
||||
//// specialization
|
||||
////template<>
|
||||
////std::string typeValueName(TestThemeSet v) {
|
||||
////switch (v) {
|
||||
////case TestThemeSet::Value1: return "Value1";
|
||||
////default: return "unk";
|
||||
////}
|
||||
////}
|
||||
|
||||
Theme::Theme(void) {
|
||||
load();
|
||||
}
|
||||
|
||||
void Theme::update(void) {
|
||||
}
|
||||
|
||||
bool Theme::load(void) {
|
||||
name = "Default";
|
||||
|
||||
//setColor<TestThemeSet::Value1>(ImVec4{});
|
||||
//std::cout << "test value name: " << getColorName<TestThemeSet::Value1>() << "\n";
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Theme::store(void) {
|
||||
return true;
|
||||
}
|
||||
|
||||
Theme getDefaultThemeDark(void) {
|
||||
Theme t;
|
||||
|
||||
t.setColor<ThemeCol_Contact::request_incoming>({0.98f, 0.41f, 0.26f, 0.52f});
|
||||
t.setColor<ThemeCol_Contact::request_outgoing>({0.98f, 0.26f, 0.41f, 0.52f});
|
||||
|
||||
t.setColor<ThemeCol_Contact::avatar_online_direct>({0.3, 1, 0, 1});
|
||||
t.setColor<ThemeCol_Contact::avatar_online_cloud>({0, 1, 0.8, 1});
|
||||
t.setColor<ThemeCol_Contact::avatar_offline>({0.4, 0.4, 0.4, 1});
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
Theme getDefaultThemeLight(void) {
|
||||
// HACK: inherit dark and only diff
|
||||
Theme t = getDefaultThemeDark();
|
||||
|
||||
return t;
|
||||
}
|
||||
|
76
src/chat_gui/theme.hpp
Normal file
76
src/chat_gui/theme.hpp
Normal file
@ -0,0 +1,76 @@
|
||||
#pragma once
|
||||
|
||||
#include <imgui/imgui.h>
|
||||
|
||||
#include <entt/container/dense_map.hpp>
|
||||
#include <entt/core/type_info.hpp>
|
||||
|
||||
#include <string>
|
||||
#include <type_traits>
|
||||
|
||||
// default is resolving to its value
|
||||
template<typename T>
|
||||
std::string typeValueName(T V) {
|
||||
return std::to_string(static_cast<std::underlying_type_t<T>>(V));
|
||||
}
|
||||
|
||||
// stores theming values and colors not expressed by imgui directly
|
||||
struct Theme {
|
||||
using key_type = entt::id_type;
|
||||
|
||||
entt::dense_map<key_type, ImVec4> colors;
|
||||
entt::dense_map<key_type, std::string> colors_name;
|
||||
|
||||
// TODO: spec out dependencies
|
||||
|
||||
// TODO: what for
|
||||
entt::dense_map<key_type, float> single_values;
|
||||
|
||||
std::string name; // theme name
|
||||
|
||||
Theme(void);
|
||||
|
||||
// call when any color changed, so dependencies can be resolved
|
||||
void update(void);
|
||||
|
||||
template<auto V>
|
||||
void setColor(ImVec4 color) {
|
||||
constexpr auto key = entt::type_hash<entt::tag<V>>::value();
|
||||
colors[key] = color;
|
||||
|
||||
if (!colors_name.contains(key)) {
|
||||
std::string key_name = static_cast<std::string>(
|
||||
entt::type_name<decltype(V)>::value()
|
||||
) + ":" + typeValueName(V);
|
||||
colors_name[key] = key_name;
|
||||
}
|
||||
}
|
||||
template<auto V>
|
||||
ImVec4 getColor(void) const {
|
||||
constexpr auto key = entt::type_hash<entt::tag<V>>::value();
|
||||
const auto it = colors.find(key);
|
||||
if (it != colors.end()) {
|
||||
return it->second;
|
||||
} else {
|
||||
return {}; // TODO: pink as default?
|
||||
}
|
||||
}
|
||||
|
||||
template<auto V>
|
||||
std::string_view getColorName(void) const {
|
||||
constexpr auto key = entt::type_hash<entt::tag<V>>::value();
|
||||
if (colors_name.contains(key)) {
|
||||
return colors_name.at(key);
|
||||
} else {
|
||||
return "unk";
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: actually serialize from config?
|
||||
bool load(void);
|
||||
bool store(void);
|
||||
};
|
||||
|
||||
Theme getDefaultThemeDark(void);
|
||||
Theme getDefaultThemeLight(void);
|
||||
|
@ -13,6 +13,8 @@
|
||||
|
||||
#include <SDL3/SDL.h>
|
||||
|
||||
#include "./chat_gui/contact_list.hpp"
|
||||
|
||||
#include "./media_meta_info_loader.hpp"
|
||||
#include "./sdl_clipboard_utils.hpp"
|
||||
|
||||
@ -143,8 +145,9 @@ ChatGui4::ChatGui4(
|
||||
Contact3Registry& cr,
|
||||
TextureUploaderI& tu,
|
||||
ContactTextureCache& contact_tc,
|
||||
MessageTextureCache& msg_tc
|
||||
) : _conf(conf), _rmm(rmm), _cr(cr), _contact_tc(contact_tc), _msg_tc(msg_tc), _sip(tu) {
|
||||
MessageTextureCache& msg_tc,
|
||||
Theme& theme
|
||||
) : _conf(conf), _rmm(rmm), _cr(cr), _contact_tc(contact_tc), _msg_tc(msg_tc), _theme(theme), _sip(tu) {
|
||||
}
|
||||
|
||||
ChatGui4::~ChatGui4(void) {
|
||||
@ -197,7 +200,31 @@ float ChatGui4::render(float time_delta) {
|
||||
|
||||
const bool highlight_private {!_cr.all_of<Contact::Components::TagPrivate>(*_selected_contact)};
|
||||
|
||||
if (ImGui::BeginChild(chat_label.c_str(), {0, 0}, true)) {
|
||||
if (ImGui::BeginChild(chat_label.c_str(), {0, 0}, ImGuiChildFlags_Border, ImGuiWindowFlags_MenuBar)) {
|
||||
if (ImGui::BeginMenuBar()) {
|
||||
if (ImGui::BeginMenu("debug")) {
|
||||
ImGui::Checkbox("show extra info", &_show_chat_extra_info);
|
||||
ImGui::Checkbox("show avatar transfers", &_show_chat_avatar_tf);
|
||||
|
||||
ImGui::SeparatorText("tox");
|
||||
|
||||
// TODO: cheese it and rename to copy id?
|
||||
if (_cr.all_of<Contact::Components::ToxGroupPersistent>(*_selected_contact)) {
|
||||
if (ImGui::MenuItem("copy ngc chatid")) {
|
||||
const auto& chat_id = _cr.get<Contact::Components::ToxGroupPersistent>(*_selected_contact).chat_id.data;
|
||||
const auto chat_id_str = bin2hex(std::vector<uint8_t>{chat_id.begin(), chat_id.end()});
|
||||
ImGui::SetClipboardText(chat_id_str.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
ImGui::EndMenuBar();
|
||||
}
|
||||
|
||||
renderContactBig(_theme, _contact_tc, {_cr, *_selected_contact}, false, false, false);
|
||||
ImGui::Separator();
|
||||
|
||||
if (sub_contacts != nullptr && !_cr.all_of<Contact::Components::TagPrivate>(*_selected_contact) && _cr.all_of<Contact::Components::TagGroup>(*_selected_contact)) {
|
||||
if (!sub_contacts->empty()) {
|
||||
if (ImGui::BeginChild("subcontacts", {150, -100}, true)) {
|
||||
@ -256,27 +283,11 @@ float ChatGui4::render(float time_delta) {
|
||||
ImGui::EndChild();
|
||||
}
|
||||
|
||||
if (ImGui::BeginChild("message_log", {0, -100}, false, ImGuiWindowFlags_MenuBar)) {
|
||||
if (ImGui::BeginMenuBar()) {
|
||||
if (ImGui::BeginMenu("debug")) {
|
||||
ImGui::Checkbox("show extra info", &_show_chat_extra_info);
|
||||
ImGui::Checkbox("show avatar transfers", &_show_chat_avatar_tf);
|
||||
|
||||
ImGui::SeparatorText("tox");
|
||||
|
||||
// TODO: cheese it and rename to copy id?
|
||||
if (_cr.all_of<Contact::Components::ToxGroupPersistent>(*_selected_contact)) {
|
||||
if (ImGui::MenuItem("copy ngc chatid")) {
|
||||
const auto& chat_id = _cr.get<Contact::Components::ToxGroupPersistent>(*_selected_contact).chat_id.data;
|
||||
const auto chat_id_str = bin2hex(std::vector<uint8_t>{chat_id.begin(), chat_id.end()});
|
||||
ImGui::SetClipboardText(chat_id_str.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
ImGui::EndMenuBar();
|
||||
}
|
||||
if (ImGui::BeginChild("message_log", {0, -100}, ImGuiChildFlags_None)) {
|
||||
// TODO: background image?
|
||||
//auto p_min = ImGui::GetCursorScreenPos();
|
||||
//auto a_max = ImGui::GetContentRegionAvail();
|
||||
//ImGui::GetWindowDrawList()->AddImage(0, p_min, {p_min.x+a_max.x, p_min.y+a_max.y});
|
||||
|
||||
auto* msg_reg_ptr = _rmm.get(*_selected_contact);
|
||||
|
||||
@ -1075,7 +1086,18 @@ void ChatGui4::renderContactList(void) {
|
||||
if (ImGui::BeginChild("contacts", {TEXT_BASE_WIDTH*35, 0})) {
|
||||
//for (const auto& c : _cm.getBigContacts()) {
|
||||
for (const auto& c : _cr.view<Contact::Components::TagBig>()) {
|
||||
if (renderContactListContactBig(c, _selected_contact.has_value() && *_selected_contact == c)) {
|
||||
const bool selected = _selected_contact.has_value() && *_selected_contact == c;
|
||||
|
||||
// TODO: is there a better way?
|
||||
// maybe cache mm?
|
||||
bool has_unread = false;
|
||||
if (const auto* mm = _rmm.get(c); mm != nullptr) {
|
||||
if (const auto* unread_storage = mm->storage<Message::Components::TagUnread>(); unread_storage != nullptr && !unread_storage->empty()) {
|
||||
has_unread = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (renderContactBig(_theme, _contact_tc, {_cr, c}, has_unread, true, selected)) {
|
||||
_selected_contact = c;
|
||||
}
|
||||
}
|
||||
@ -1083,139 +1105,6 @@ void ChatGui4::renderContactList(void) {
|
||||
ImGui::EndChild();
|
||||
}
|
||||
|
||||
bool ChatGui4::renderContactListContactBig(const Contact3 c, const bool selected) {
|
||||
// TODO:
|
||||
// - unread message
|
||||
// - connection status
|
||||
// - user status
|
||||
// - status message
|
||||
// - context menu n shit?
|
||||
|
||||
// +------+
|
||||
// | | *Name (Alias?)
|
||||
// |Avatar| Satus Message
|
||||
// | | user status (online/away/busy)-direct/relayed / offline
|
||||
// +------+
|
||||
|
||||
auto label = "###" + std::to_string(entt::to_integral(c));
|
||||
|
||||
const bool request_incoming = _cr.all_of<Contact::Components::RequestIncoming>(c);
|
||||
const bool request_outgoing = _cr.all_of<Contact::Components::TagRequestOutgoing>(c);
|
||||
|
||||
ImVec2 orig_curser_pos = ImGui::GetCursorPos();
|
||||
// HACK: fake selected to make it draw a box for us
|
||||
const bool show_selected = request_incoming || request_outgoing || selected;
|
||||
if (request_incoming) {
|
||||
// TODO: theming
|
||||
ImGui::PushStyleColor(ImGuiCol_Header, {0.98f, 0.41f, 0.26f, 0.52f});
|
||||
} else if (request_outgoing) {
|
||||
// TODO: theming
|
||||
ImGui::PushStyleColor(ImGuiCol_Header, {0.98f, 0.26f, 0.41f, 0.52f});
|
||||
}
|
||||
|
||||
const bool got_selected = ImGui::Selectable(label.c_str(), show_selected, 0, {0,3*TEXT_BASE_HEIGHT});
|
||||
if (request_incoming || request_outgoing) {
|
||||
ImGui::PopStyleColor();
|
||||
}
|
||||
|
||||
if (ImGui::BeginItemTooltip()) {
|
||||
if (_cr.all_of<Contact::Components::ConnectionState>(c)) {
|
||||
const auto cstate = _cr.get<Contact::Components::ConnectionState>(c).state;
|
||||
ImGui::Text("Connection state: %s",
|
||||
(cstate == Contact::Components::ConnectionState::disconnected)
|
||||
? "offline"
|
||||
: (cstate == Contact::Components::ConnectionState::direct)
|
||||
? "online (direct)"
|
||||
: "online (cloud)"
|
||||
);
|
||||
} else {
|
||||
ImGui::TextUnformatted("Connection state: unknown");
|
||||
}
|
||||
|
||||
ImGui::EndTooltip();
|
||||
}
|
||||
|
||||
ImVec2 post_curser_pos = ImGui::GetCursorPos();
|
||||
|
||||
ImVec2 img_curser {
|
||||
orig_curser_pos.x + ImGui::GetStyle().FramePadding.x,
|
||||
orig_curser_pos.y + ImGui::GetStyle().FramePadding.y
|
||||
};
|
||||
|
||||
float img_y {
|
||||
//(post_curser_pos.y - orig_curser_pos.y) - ImGui::GetStyle().FramePadding.y*2
|
||||
TEXT_BASE_HEIGHT*3 - ImGui::GetStyle().FramePadding.y*2
|
||||
};
|
||||
|
||||
ImGui::SetCursorPos(img_curser);
|
||||
const ImVec4 color_online_direct{0.3, 1, 0, 1};
|
||||
const ImVec4 color_online_cloud{0, 1, 0.8, 1};
|
||||
const ImVec4 color_offline{0.4, 0.4, 0.4, 1};
|
||||
|
||||
ImVec4 color_current = color_offline;
|
||||
if (_cr.all_of<Contact::Components::ConnectionState>(c)) {
|
||||
const auto c_state = _cr.get<Contact::Components::ConnectionState>(c).state;
|
||||
if (c_state == Contact::Components::ConnectionState::State::direct) {
|
||||
color_current = color_online_direct;
|
||||
} else if (c_state == Contact::Components::ConnectionState::State::cloud) {
|
||||
color_current = color_online_cloud;
|
||||
}
|
||||
}
|
||||
|
||||
// avatar
|
||||
const auto [id, width, height] = _contact_tc.get(c);
|
||||
ImGui::Image(
|
||||
id,
|
||||
ImVec2{img_y, img_y},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{1, 1, 1, 1},
|
||||
color_current
|
||||
);
|
||||
|
||||
// TODO: move this out of chat gui
|
||||
any_unread = false;
|
||||
|
||||
ImGui::SameLine();
|
||||
ImGui::BeginGroup();
|
||||
{
|
||||
// TODO: is there a better way?
|
||||
// maybe cache mm?
|
||||
bool has_unread = false;
|
||||
if (const auto* mm = _rmm.get(c); mm != nullptr) {
|
||||
if (const auto* unread_storage = mm->storage<Message::Components::TagUnread>(); unread_storage != nullptr && !unread_storage->empty()) {
|
||||
#if 0
|
||||
assert(unread_storage.size() == 0);
|
||||
assert(unread_storage.cbegin() == unread_storage.cend());
|
||||
std::cout << "UNREAD ";
|
||||
for (const auto e : mm->view<Message::Components::TagUnread>()) {
|
||||
std::cout << entt::to_integral(e) << " ";
|
||||
}
|
||||
std::cout << "\n";
|
||||
#endif
|
||||
has_unread = true;
|
||||
any_unread = true;
|
||||
}
|
||||
}
|
||||
|
||||
ImGui::Text("%s%s", has_unread?"* ":"", (_cr.all_of<Contact::Components::Name>(c) ? _cr.get<Contact::Components::Name>(c).name.c_str() : "<unk>"));
|
||||
if (request_incoming) {
|
||||
ImGui::TextUnformatted("Incoming request/invite");
|
||||
} else if (request_outgoing) {
|
||||
ImGui::TextUnformatted("Outgoing request/invite");
|
||||
} else {
|
||||
//ImGui::Text("status message...");
|
||||
}
|
||||
//ImGui::TextDisabled("hi");
|
||||
//ImGui::RenderTextEllipsis
|
||||
}
|
||||
ImGui::EndGroup();
|
||||
|
||||
ImGui::SetCursorPos(post_curser_pos);
|
||||
|
||||
return got_selected;
|
||||
}
|
||||
|
||||
bool ChatGui4::renderContactListContactSmall(const Contact3 c, const bool selected) const {
|
||||
std::string label;
|
||||
|
||||
|
@ -3,6 +3,8 @@
|
||||
#include <solanaceae/message3/registry_message_model.hpp>
|
||||
#include <solanaceae/util/config_model.hpp>
|
||||
|
||||
#include "./chat_gui/theme.hpp"
|
||||
|
||||
#include "./texture_uploader.hpp"
|
||||
#include "./texture_cache.hpp"
|
||||
#include "./tox_avatar_loader.hpp"
|
||||
@ -29,6 +31,8 @@ class ChatGui4 {
|
||||
ContactTextureCache& _contact_tc;
|
||||
MessageTextureCache& _msg_tc;
|
||||
|
||||
Theme& _theme;
|
||||
|
||||
FileSelector _fss;
|
||||
SendImagePopup _sip;
|
||||
|
||||
@ -57,7 +61,8 @@ class ChatGui4 {
|
||||
Contact3Registry& cr,
|
||||
TextureUploaderI& tu,
|
||||
ContactTextureCache& contact_tc,
|
||||
MessageTextureCache& msg_tc
|
||||
MessageTextureCache& msg_tc,
|
||||
Theme& theme
|
||||
);
|
||||
~ChatGui4(void);
|
||||
|
||||
@ -65,8 +70,6 @@ class ChatGui4 {
|
||||
float render(float time_delta);
|
||||
|
||||
public:
|
||||
bool any_unread {false};
|
||||
|
||||
void sendFilePath(const char* file_path);
|
||||
|
||||
private:
|
||||
@ -75,7 +78,6 @@ class ChatGui4 {
|
||||
void renderMessageExtra(Message3Registry& reg, const Message3 e);
|
||||
|
||||
void renderContactList(void);
|
||||
bool renderContactListContactBig(const Contact3 c, const bool selected);
|
||||
bool renderContactListContactSmall(const Contact3 c, const bool selected) const;
|
||||
bool renderSubContactListContact(const Contact3 c, const bool selected) const;
|
||||
|
||||
|
@ -6,6 +6,7 @@
|
||||
#include <imgui/backends/imgui_impl_sdlrenderer3.h>
|
||||
|
||||
#include "./theme.hpp"
|
||||
#include "./chat_gui/theme.hpp"
|
||||
|
||||
#include "./start_screen.hpp"
|
||||
|
||||
@ -58,11 +59,14 @@ int main(int argc, char** argv) {
|
||||
IMGUI_CHECKVERSION();
|
||||
ImGui::CreateContext();
|
||||
|
||||
Theme theme;
|
||||
if (SDL_GetSystemTheme() == SDL_SYSTEM_THEME_LIGHT) {
|
||||
ImGui::StyleColorsLight();
|
||||
theme = getDefaultThemeLight();
|
||||
} else {
|
||||
//ImGui::StyleColorsDark();
|
||||
setThemeGreen();
|
||||
theme = getDefaultThemeDark();
|
||||
}
|
||||
|
||||
{
|
||||
@ -85,7 +89,7 @@ int main(int argc, char** argv) {
|
||||
ImGui_ImplSDL3_InitForSDLRenderer(window.get(), renderer.get());
|
||||
ImGui_ImplSDLRenderer3_Init(renderer.get());
|
||||
|
||||
std::unique_ptr<Screen> screen = std::make_unique<StartScreen>(renderer.get());
|
||||
std::unique_ptr<Screen> screen = std::make_unique<StartScreen>(renderer.get(), theme);
|
||||
|
||||
|
||||
bool quit = false;
|
||||
|
@ -12,7 +12,7 @@
|
||||
#include <memory>
|
||||
#include <cmath>
|
||||
|
||||
MainScreen::MainScreen(SDL_Renderer* renderer_, std::string save_path, std::string save_password, std::string new_username, std::vector<std::string> plugins) :
|
||||
MainScreen::MainScreen(SDL_Renderer* renderer_, Theme& theme_, std::string save_path, std::string save_password, std::string new_username, std::vector<std::string> plugins) :
|
||||
renderer(renderer_),
|
||||
rmm(cr),
|
||||
msnj{cr, {}, {}},
|
||||
@ -24,6 +24,7 @@ MainScreen::MainScreen(SDL_Renderer* renderer_, std::string save_path, std::stri
|
||||
tmm(rmm, cr, tcm, tc, tc),
|
||||
ttm(rmm, cr, tcm, tc, tc),
|
||||
tffom(cr, rmm, tcm, tc, tc),
|
||||
theme(theme_),
|
||||
mmil(rmm),
|
||||
tam(rmm, cr, conf),
|
||||
sdlrtu(renderer_),
|
||||
@ -31,7 +32,7 @@ MainScreen::MainScreen(SDL_Renderer* renderer_, std::string save_path, std::stri
|
||||
contact_tc(tal, sdlrtu),
|
||||
mil(),
|
||||
msg_tc(mil, sdlrtu),
|
||||
cg(conf, rmm, cr, sdlrtu, contact_tc, msg_tc),
|
||||
cg(conf, rmm, cr, sdlrtu, contact_tc, msg_tc, theme),
|
||||
sw(conf),
|
||||
tuiu(tc, conf),
|
||||
tdch(tpi)
|
||||
|
@ -62,6 +62,8 @@ struct MainScreen final : public Screen {
|
||||
ToxTransferManager ttm;
|
||||
ToxFriendFauxOfflineMessaging tffom;
|
||||
|
||||
Theme& theme;
|
||||
|
||||
MediaMetaInfoLoader mmil;
|
||||
ToxAvatarManager tam;
|
||||
|
||||
@ -89,7 +91,7 @@ struct MainScreen final : public Screen {
|
||||
uint64_t _window_hidden_ts {0};
|
||||
float _time_since_event {0.f};
|
||||
|
||||
MainScreen(SDL_Renderer* renderer_, std::string save_path, std::string save_password, std::string new_username, std::vector<std::string> plugins);
|
||||
MainScreen(SDL_Renderer* renderer_, Theme& theme_, std::string save_path, std::string save_password, std::string new_username, std::vector<std::string> plugins);
|
||||
~MainScreen(void);
|
||||
|
||||
bool handleEvent(SDL_Event& e) override;
|
||||
|
@ -9,7 +9,7 @@
|
||||
#include <memory>
|
||||
#include <filesystem>
|
||||
|
||||
StartScreen::StartScreen(SDL_Renderer* renderer) : _renderer(renderer) {
|
||||
StartScreen::StartScreen(SDL_Renderer* renderer, Theme& theme) : _renderer(renderer), _theme(theme) {
|
||||
}
|
||||
|
||||
Screen* StartScreen::render(float, bool&) {
|
||||
@ -143,7 +143,7 @@ Screen* StartScreen::render(float, bool&) {
|
||||
}
|
||||
} else {
|
||||
if (ImGui::Button("load", {60, 25})) {
|
||||
auto new_screen = std::make_unique<MainScreen>(_renderer, _tox_profile_path, _password, _user_name, queued_plugin_paths);
|
||||
auto new_screen = std::make_unique<MainScreen>(_renderer, _theme, _tox_profile_path, _password, _user_name, queued_plugin_paths);
|
||||
return new_screen.release();
|
||||
}
|
||||
}
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
#include "./screen.hpp"
|
||||
|
||||
#include "./chat_gui/theme.hpp"
|
||||
#include "./chat_gui/file_selector.hpp"
|
||||
|
||||
#include <vector>
|
||||
@ -14,6 +15,7 @@ extern "C" {
|
||||
|
||||
struct StartScreen final : public Screen {
|
||||
SDL_Renderer* _renderer;
|
||||
Theme& _theme;
|
||||
FileSelector _fss;
|
||||
|
||||
bool _new_save {false};
|
||||
@ -26,7 +28,7 @@ struct StartScreen final : public Screen {
|
||||
std::vector<std::string> queued_plugin_paths;
|
||||
|
||||
StartScreen(void) = delete;
|
||||
StartScreen(SDL_Renderer* renderer);
|
||||
StartScreen(SDL_Renderer* renderer, Theme& theme);
|
||||
~StartScreen(void) = default;
|
||||
|
||||
// return nullptr if not next
|
||||
|
Loading…
Reference in New Issue
Block a user