diff --git a/ImGuiToolkit.cpp b/ImGuiToolkit.cpp index ba16459..4912bd7 100644 --- a/ImGuiToolkit.cpp +++ b/ImGuiToolkit.cpp @@ -64,22 +64,29 @@ void ImGuiToolkit::ButtonToggle( const char* label, bool* toggle ) } -void ImGuiToolkit::ButtonSwitch(const char* label, bool* toggle) +void ImGuiToolkit::ButtonSwitch(const char* label, bool* toggle, const char* help) { + // utility style ImVec4* colors = ImGui::GetStyle().Colors; - ImVec2 p = ImGui::GetCursorScreenPos(); ImDrawList* draw_list = ImGui::GetWindowDrawList(); + // draw position when entering + ImVec2 draw_pos = ImGui::GetCursorScreenPos(); + + // layout + float frame_height = ImGui::GetFrameHeight(); + float frame_width = ImGui::GetContentRegionAvail().x; float height = ImGui::GetFrameHeight() * 0.75f; float width = height * 1.6f; float radius = height * 0.50f; - ImGui::InvisibleButton(label, ImVec2(width, height)); + // toggle action : operate on the whole area + ImGui::InvisibleButton(label, ImVec2(frame_width, frame_height)); if (ImGui::IsItemClicked()) *toggle = !*toggle; - float t = *toggle ? 1.0f : 0.0f; + // animation ImGuiContext& g = *GImGui; float ANIM_SPEED = 0.1f; if (g.LastActiveId == g.CurrentWindow->GetID(label))// && g.LastActiveIdTimer < ANIM_SPEED) @@ -88,16 +95,30 @@ void ImGuiToolkit::ButtonSwitch(const char* label, bool* toggle) t = *toggle ? (t_anim) : (1.0f - t_anim); } + // hover ImU32 col_bg; if (ImGui::IsItemHovered()) col_bg = ImGui::GetColorU32(ImLerp(colors[ImGuiCol_FrameBgHovered], colors[ImGuiCol_TabHovered], t)); else col_bg = ImGui::GetColorU32(ImLerp(colors[ImGuiCol_FrameBg], colors[ImGuiCol_TabActive], t)); + // draw help text if present + if (help) { + ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(0.6, 0.6, 0.6, 1.f)); + ImGui::RenderText(draw_pos, help); + ImGui::PopStyleColor(1); + } + + // draw the label right aligned + const ImVec2 label_size = ImGui::CalcTextSize(label, NULL, true); + ImVec2 text_pos = draw_pos + ImVec2(frame_width -120.f -label_size.x, 0.f); + ImGui::RenderText(text_pos, label); + + // draw switch after the text + ImVec2 p = draw_pos + ImVec2(frame_width - 100.f, 0.f); draw_list->AddRectFilled(p, ImVec2(p.x + width, p.y + height), col_bg, height * 0.5f); draw_list->AddCircleFilled(ImVec2(p.x + radius + t * (width - radius * 2.0f), p.y + radius), radius - 1.5f, IM_COL32(255, 255, 255, 250)); - ImGui::SameLine(0,22); - ImGui::Text(label); + } diff --git a/ImGuiToolkit.h b/ImGuiToolkit.h index 7ddeaee..d05e7e5 100644 --- a/ImGuiToolkit.h +++ b/ImGuiToolkit.h @@ -20,7 +20,7 @@ namespace ImGuiToolkit bool ButtonIconToggle(int i, int j, int i_toggle, int j_toggle, bool* toggle); bool ButtonIconMultistate(std::vector > icons, int* state); void ButtonToggle( const char* label, bool* toggle ); - void ButtonSwitch( const char* label, bool* toggle ); + void ButtonSwitch(const char* label, bool* toggle , const char *help = nullptr); void ButtonOpenWebpage( const char* url ); void HelpMarker(const char* desc); diff --git a/Mixer.cpp b/Mixer.cpp index ab7dcc5..2d54df1 100644 --- a/Mixer.cpp +++ b/Mixer.cpp @@ -112,6 +112,7 @@ void Mixer::setCurrentSource(SourceList::iterator it) unsetCurrentSource(); if ( it != session_->end() ) { current_source_ = it; + current_source_index_ = session_->index(it); (*current_source_)->setOverlayVisible(true); } } @@ -141,8 +142,15 @@ void Mixer::unsetCurrentSource() // discard overlay for previously current source if ( current_source_ != session_->end() ) (*current_source_)->setOverlayVisible(false); + // deselect current source current_source_ = session_->end(); + current_source_index_ = -1; +} + +int Mixer::indexCurrentSource() +{ + return current_source_index_; } Source *Mixer::currentSource() @@ -295,6 +303,7 @@ void Mixer::newSession(Session *newsession) // no current source current_source_ = session_->end(); + current_source_index_ = -1; // reset timer update_time_ = GST_CLOCK_TIME_NONE; diff --git a/Mixer.h b/Mixer.h index a45a753..6fd4d81 100644 --- a/Mixer.h +++ b/Mixer.h @@ -46,8 +46,7 @@ public: void setCurrentSource(Source *s); void unsetCurrentSource(); Source *currentSource(); - - + int indexCurrentSource(); // management of view View *getView(View::Mode m); @@ -70,6 +69,7 @@ protected: Session *session_; SourceList::iterator current_source_; + int current_source_index_; MixingView mixing_; GeometryView geometry_; diff --git a/Session.cpp b/Session.cpp index 7af7d68..b652f01 100644 --- a/Session.cpp +++ b/Session.cpp @@ -76,6 +76,9 @@ SourceList::iterator Session::end() SourceList::iterator Session::find(int index) { + if (index<0) + return sources_.end(); + int i = 0; SourceList::iterator it = sources_.begin(); while ( i < index && it != sources_.end() ){ @@ -105,5 +108,16 @@ uint Session::numSource() const return sources_.size(); } - +int Session::index(SourceList::iterator it) const +{ + int index = -1; + int count = 0; + for(auto i = sources_.begin(); i != sources_.end(); i++, count++) { + if ( i == it ) { + index = count; + break; + } + } + return index; +} diff --git a/Session.h b/Session.h index 8529473..06bcaf3 100644 --- a/Session.h +++ b/Session.h @@ -22,7 +22,9 @@ public: SourceList::iterator find(Source *s); SourceList::iterator find(std::string name); SourceList::iterator find(Node *node); + uint numSource() const; + int index(SourceList::iterator it) const; // update all sources void update(float dt); diff --git a/UserInterfaceManager.cpp b/UserInterfaceManager.cpp index e993ee9..6cdb603 100644 --- a/UserInterfaceManager.cpp +++ b/UserInterfaceManager.cpp @@ -903,6 +903,7 @@ void UserInterface::RenderShaderEditor() SourceNavigator::SourceNavigator() { clearSelection(); + selected_source_index = -1; } void SourceNavigator::toggle(int index) @@ -911,16 +912,15 @@ void SourceNavigator::toggle(int index) clearSelection(); selected_button[index] = s; if (s) - selected_source_index = index - 1; + selected_source_index = index; else selected_source_index = -1; } void SourceNavigator::clearSelection() { - for(int i=0; ibegin(); iter != Mixer::manager().session()->end(); iter++, index++) { + // draw an indicator for current source + if ( Mixer::manager().indexCurrentSource() == index ){ + + ImDrawList* draw_list = ImGui::GetWindowDrawList(); + const ImVec2 p = ImGui::GetCursorScreenPos() + ImVec2(icon_width,0); + const ImU32 color = ImGui::GetColorU32( style.Colors[ImGuiCol_Text] ); + + draw_list->AddRect(p, ImVec2(p.x + 2.f, p.y + icon_width), color, 0.0f, 0, 3.f); + + } + // draw select box if (ImGui::Selectable( (*iter)->initials(), &selected_button[index], 0, iconsize)) { toggle(index); + Mixer::manager().setCurrentSource(selected_source_index); } } // the "+" icon for action of creating new source if (ImGui::Selectable( ICON_FA_PLUS, &selected_button[NAV_NEW], 0, iconsize)) { + Mixer::manager().unsetCurrentSource(); toggle(NAV_NEW); } ImGui::PopStyleVar(); @@ -975,8 +988,6 @@ void SourceNavigator::Render() // window menu if (selected_button[NAV_MENU]) { - Mixer::manager().unsetCurrentSource(); - // Next window is a side pannel ImGui::SetNextWindowPos( ImVec2(window_width, 0), ImGuiCond_Always ); ImGui::SetNextWindowSize(ImVec2( 5.f * window_width, io.DisplaySize.y), ImGuiCond_Always ); @@ -993,7 +1004,7 @@ void SourceNavigator::Render() ImGuiToolkit::ButtonSwitch( IMGUI_TITLE_MEDIAPLAYER, &Settings::application.media_player); ImGuiToolkit::ButtonSwitch( IMGUI_TITLE_SHADEREDITOR, &Settings::application.shader_editor); ImGuiToolkit::ButtonSwitch( ICON_FA_TACHOMETER_ALT " Metrics", &Settings::application.stats); - ImGuiToolkit::ButtonSwitch( ICON_FA_LIST " Logs", &Settings::application.logs); + ImGuiToolkit::ButtonSwitch( ICON_FA_LIST " Logs", &Settings::application.logs, "Ctrl + L"); ImGui::Text("Appearance"); ImGui::SetNextItemWidth(IMGUI_RIGHT_ALIGN); @@ -1010,8 +1021,6 @@ void SourceNavigator::Render() // window to create a source else if (selected_button[NAV_NEW]) { - Mixer::manager().unsetCurrentSource(); - // Next window is a side pannel ImGui::SetNextWindowPos( ImVec2(window_width, 0), ImGuiCond_Always ); ImGui::SetNextWindowSize(ImVec2( 5.f * window_width, io.DisplaySize.y), ImGuiCond_Always ); @@ -1060,9 +1069,11 @@ void SourceNavigator::Render() // window to configure a selected source else if (selected_source_index > -1) { - static ImGuiVisitor v; - Mixer::manager().setCurrentSource(selected_source_index); + // manipulate current source, and activate corresponding button Source *s = Mixer::manager().currentSource(); + clearSelection(); + selected_button[Mixer::manager().indexCurrentSource()] = true; + if (s) { // Next window is a side pannel @@ -1083,6 +1094,7 @@ void SourceNavigator::Render() Mixer::manager().renameSource(s, buf5); } // blending pannel + static ImGuiVisitor v; s->blendingShader()->accept(v); // preview float width = ImGui::GetContentRegionAvail().x IMGUI_RIGHT_ALIGN; diff --git a/UserInterfaceManager.h b/UserInterfaceManager.h index e4c08b6..81c33b0 100644 --- a/UserInterfaceManager.h +++ b/UserInterfaceManager.h @@ -5,14 +5,15 @@ #include using namespace std; -#define NAV_MENU 0 -#define NAV_NEW 63 +#define NAV_COUNT 67 #define NAV_MAX 64 +#define NAV_NEW 65 +#define NAV_MENU 66 class SourceNavigator { int selected_source_index; - bool selected_button[NAV_MAX]; + bool selected_button[NAV_COUNT]; void clearSelection(); void toggle(int index);