diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index d4c908bb..97bb038b 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -73,6 +73,10 @@ target_sources(tomato PUBLIC ./chat_gui/icons/cloud.cpp ./chat_gui/icons/mail.hpp ./chat_gui/icons/mail.cpp + ./chat_gui/icons/person.hpp + ./chat_gui/icons/person.cpp + ./chat_gui/icons/group.hpp + ./chat_gui/icons/group.cpp ./chat_gui/contact_list.hpp ./chat_gui/contact_list.cpp ./chat_gui/file_selector.hpp diff --git a/src/chat_gui/contact_list.cpp b/src/chat_gui/contact_list.cpp index 62b017fb..5ab4eab3 100644 --- a/src/chat_gui/contact_list.cpp +++ b/src/chat_gui/contact_list.cpp @@ -8,6 +8,8 @@ #include "./icons/direct.hpp" #include "./icons/cloud.hpp" #include "./icons/mail.hpp" +#include "./icons/person.hpp" +#include "./icons/group.hpp" void renderAvatar( const Theme& th, @@ -138,6 +140,9 @@ bool renderContactBig( ImGui::SameLine(0.f, same_line_spacing); ImGui::BeginGroup(); { + const bool is_group = c.all_of(); + const bool is_private = c.all_of(); + { // line 1 if (line_height == 1 && cstate != nullptr) { // icon pos @@ -145,23 +150,52 @@ bool renderContactBig( p0.y += ImGui::GetStyle().FramePadding.y; ImVec2 p1_o = {img_y, img_y}; // img_y is 1 line_height in this case - const ImU32 col_back = ImGui::GetColorU32(th.getColor()); - if (cstate->state == Contact::Components::ConnectionState::direct) { // direct icon - drawIconDirect( - p0, - p1_o, - ImGui::GetColorU32(th.getColor()), - col_back - ); - } else if (cstate->state == Contact::Components::ConnectionState::cloud) { // cloud icon - drawIconCloud( - p0, - p1_o, - ImGui::GetColorU32(th.getColor()), - col_back - ); - } ImGui::Dummy(p1_o); + if (ImGui::IsItemVisible()) { + const ImU32 col_back = ImGui::GetColorU32(th.getColor()); + if (cstate->state == Contact::Components::ConnectionState::direct) { // direct icon + drawIconDirect( + p0, + p1_o, + ImGui::GetColorU32(th.getColor()), + col_back + ); + } else if (cstate->state == Contact::Components::ConnectionState::cloud) { // cloud icon + drawIconCloud( + p0, + p1_o, + ImGui::GetColorU32(th.getColor()), + col_back + ); + } + } + ImGui::SameLine(0.f, same_line_spacing); + } + + // we dont render group/private in 1lh mode + if (line_height != 1 && (is_private || is_group)) { + // icon pos + auto p0 = ImGui::GetCursorScreenPos(); + p0.y += ImGui::GetStyle().FramePadding.y; + const float box_hight = TEXT_BASE_HEIGHT - ImGui::GetStyle().FramePadding.y*2; + ImVec2 p1_o = {box_hight, box_hight}; + + ImGui::Dummy(p1_o); + if (ImGui::IsItemVisible()) { + if (is_private) { + drawIconPerson( + p0, + p1_o, + ImGui::GetColorU32(ImGui::GetStyleColorVec4(ImGuiCol_Text)) + ); + } else if (is_group) { + drawIconGroup( + p0, + p1_o, + ImGui::GetColorU32(ImGui::GetStyleColorVec4(ImGuiCol_Text)) + ); + } + } ImGui::SameLine(0.f, same_line_spacing); } @@ -201,23 +235,25 @@ bool renderContactBig( const float box_hight = TEXT_BASE_HEIGHT - ImGui::GetStyle().FramePadding.y*2; ImVec2 p1_o = {box_hight, box_hight}; - const ImU32 col_back = ImGui::GetColorU32(th.getColor()); - if (cstate->state == Contact::Components::ConnectionState::direct) { // direct icon - drawIconDirect( - p0, - p1_o, - ImGui::GetColorU32(th.getColor()), - col_back - ); - } else if (cstate->state == Contact::Components::ConnectionState::cloud) { // cloud icon - drawIconCloud( - p0, - p1_o, - ImGui::GetColorU32(th.getColor()), - col_back - ); - } ImGui::Dummy(p1_o); + if (ImGui::IsItemVisible()) { + const ImU32 col_back = ImGui::GetColorU32(th.getColor()); + if (cstate->state == Contact::Components::ConnectionState::direct) { // direct icon + drawIconDirect( + p0, + p1_o, + ImGui::GetColorU32(th.getColor()), + col_back + ); + } else if (cstate->state == Contact::Components::ConnectionState::cloud) { // cloud icon + drawIconCloud( + p0, + p1_o, + ImGui::GetColorU32(th.getColor()), + col_back + ); + } + } ImGui::SameLine(0.f, same_line_spacing); } diff --git a/src/chat_gui/icons/group.cpp b/src/chat_gui/icons/group.cpp new file mode 100644 index 00000000..86f2f08e --- /dev/null +++ b/src/chat_gui/icons/group.cpp @@ -0,0 +1,139 @@ +#include "./group.hpp" + +#include + +static void drawIconGroupLines( + const ImVec2 p0, + const ImVec2 p1_o, + const ImU32 col, + const float thickness +) { +#define PLINE(x0, y0, x1, y1) \ + ImGui::GetWindowDrawList()->AddLine( \ + {p0.x + p1_o.x*(x0), p0.y + p1_o.y*(y0)}, \ + {p0.x + p1_o.x*(x1), p0.y + p1_o.y*(y1)}, \ + col, \ + thickness \ + ); + + // person front + // x y + PLINE( + 0.1f, 0.9f, + 0.6f, 0.9f + ) + PLINE( + 0.6f, 0.9f, + 0.6f, 0.7f + ) + PLINE( + 0.6f, 0.7f, + 0.5f, 0.6f + ) + PLINE( + 0.5f, 0.6f, + 0.4f, 0.6f + ) + PLINE( + 0.4f, 0.6f, + 0.5f, 0.5f + ) + PLINE( + 0.5f, 0.5f, + 0.5f, 0.4f + ) + PLINE( + 0.5f, 0.4f, + 0.4f, 0.3f + ) + PLINE( + 0.4f, 0.3f, + 0.3f, 0.3f + ) + PLINE( + 0.3f, 0.3f, + 0.2f, 0.4f + ) + PLINE( + 0.2f, 0.4f, + 0.2f, 0.5f + ) + PLINE( + 0.2f, 0.5f, + 0.3f, 0.6f + ) + PLINE( + 0.3f, 0.6f, + 0.2f, 0.6f + ) + PLINE( + 0.2f, 0.6f, + 0.1f, 0.7f + ) + PLINE( + 0.1f, 0.7f, + 0.1f, 0.9f + ) + + // person back + // x y + PLINE( + 0.7f, 0.7f, + 0.9f, 0.7f + ) + PLINE( + 0.9f, 0.7f, + 0.9f, 0.5f + ) + PLINE( + 0.9f, 0.5f, + 0.8f, 0.4f + ) + PLINE( + 0.8f, 0.4f, + 0.7f, 0.4f + ) + PLINE( + 0.7f, 0.4f, + 0.8f, 0.3f + ) + PLINE( + 0.8f, 0.3f, + 0.8f, 0.2f + ) + PLINE( + 0.8f, 0.2f, + 0.7f, 0.1f + ) + PLINE( + 0.7f, 0.1f, + 0.6f, 0.1f + ) + PLINE( + 0.6f, 0.1f, + 0.5f, 0.2f + ) + PLINE( + 0.5f, 0.2f, + 0.5f, 0.3f + ) + PLINE( + 0.5f, 0.3f, + 0.6f, 0.4f + ) + +#undef PLINE +} + +void drawIconGroup( + const ImVec2 p0, + const ImVec2 p1_o, + const ImU32 col_main +) { + // dark background + // the circle looks bad in light mode + //ImGui::GetWindowDrawList()->AddCircleFilled({p0.x + p1_o.x*0.5f, p0.y + p1_o.y*0.5f}, p1_o.x*0.5f, col_back); + //drawIconGroupLines(p0, p1_o, col_back, 3.5f); + drawIconGroupLines(p0, p1_o, col_main, 1.0f); +} + diff --git a/src/chat_gui/icons/group.hpp b/src/chat_gui/icons/group.hpp new file mode 100644 index 00000000..ed90928c --- /dev/null +++ b/src/chat_gui/icons/group.hpp @@ -0,0 +1,10 @@ +#pragma once + +#include + +void drawIconGroup( + const ImVec2 p0, + const ImVec2 p1_o, + const ImU32 col_main +); + diff --git a/src/chat_gui/icons/person.cpp b/src/chat_gui/icons/person.cpp new file mode 100644 index 00000000..8fe1df8c --- /dev/null +++ b/src/chat_gui/icons/person.cpp @@ -0,0 +1,101 @@ +#include "./person.hpp" + +#include + +static void drawIconPersonLines( + const ImVec2 p0, + const ImVec2 p1_o, + const ImU32 col, + const float thickness +) { +#define PLINE(x0, y0, x1, y1) \ + ImGui::GetWindowDrawList()->AddLine( \ + {p0.x + p1_o.x*(x0), p0.y + p1_o.y*(y0)}, \ + {p0.x + p1_o.x*(x1), p0.y + p1_o.y*(y1)}, \ + col, \ + thickness \ + ); + + //// quad + //// (1,2) -> (1,8) + //PLINE(0.1f, 0.2f, 0.1f, 0.8f) + //// (1,8) -> (9,8) + //PLINE(0.1f, 0.8f, 0.9f, 0.8f) + //// (9,8) -> (9,2) + //PLINE(0.9f, 0.8f, 0.9f, 0.2f) + //// (9,2) -> (1,2) + //PLINE(0.9f, 0.2f, 0.1f, 0.2f) + + // x y + PLINE( + 0.2f, 0.8f, + 0.8f, 0.8f + ) + PLINE( + 0.8f, 0.8f, + 0.8f, 0.6f + ) + PLINE( + 0.8f, 0.6f, + 0.7f, 0.5f + ) + PLINE( + 0.7f, 0.5f, + 0.6f, 0.5f + ) + PLINE( + 0.6f, 0.5f, + 0.7f, 0.4f + ) + PLINE( + 0.7f, 0.4f, + 0.7f, 0.2f + ) + PLINE( + 0.7f, 0.2f, + 0.6f, 0.1f + ) + PLINE( + 0.6f, 0.1f, + 0.4f, 0.1f + ) + PLINE( + 0.4f, 0.1f, + 0.3f, 0.2f + ) + PLINE( + 0.3f, 0.2f, + 0.3f, 0.4f + ) + PLINE( + 0.3f, 0.4f, + 0.4f, 0.5f + ) + PLINE( + 0.4f, 0.5f, + 0.3f, 0.5f + ) + PLINE( + 0.3f, 0.5f, + 0.2f, 0.6f + ) + PLINE( + 0.2f, 0.6f, + 0.2f, 0.8f + ) + +#undef PLINE +} + +void drawIconPerson( + const ImVec2 p0, + const ImVec2 p1_o, + const ImU32 col_main +) { + // dark background + // the circle looks bad in light mode + //ImGui::GetWindowDrawList()->AddCircleFilled({p0.x + p1_o.x*0.5f, p0.y + p1_o.y*0.5f}, p1_o.x*0.5f, col_back); + //drawIconPersonLines(p0, p1_o, col_back, 3.5f); + drawIconPersonLines(p0, p1_o, col_main, 1.0f); +} + diff --git a/src/chat_gui/icons/person.hpp b/src/chat_gui/icons/person.hpp new file mode 100644 index 00000000..1a754b98 --- /dev/null +++ b/src/chat_gui/icons/person.hpp @@ -0,0 +1,10 @@ +#pragma once + +#include + +void drawIconPerson( + const ImVec2 p0, + const ImVec2 p1_o, + const ImU32 col_main +); +