diff --git a/GstToolkit.cpp b/GstToolkit.cpp index 8d75fcd..4d77836 100644 --- a/GstToolkit.cpp +++ b/GstToolkit.cpp @@ -4,7 +4,7 @@ using namespace std; #include "GstToolkit.h" -string GstToolkit::time_to_string(guint64 t) +string GstToolkit::time_to_string(guint64 t, bool stripped) { if (t == GST_CLOCK_TIME_NONE) return "00:00:00.00"; @@ -13,14 +13,37 @@ string GstToolkit::time_to_string(guint64 t) guint s = ms / 1000; ostringstream oss; - if (s / 3600) - oss << setw(2) << setfill('0') << s / 3600 << ':'; - if ((s % 3600) / 60) - oss << setw(2) << setfill('0') << (s % 3600) / 60 << ':'; - oss << setw(2) << setfill('0') << (s % 3600) % 60 << '.'; - oss << setw(2) << setfill('0') << (ms % 1000) / 10; - // fixed length string (11 chars) HH:mm:ss.ii" + if (stripped) { + int count = 0; + + if (s / 3600) { + oss << s / 3600 << ':'; + count++; + } + if ((s % 3600) / 60) { + oss << (s % 3600) / 60 << ':'; + count++; + } + if (count < 2) { + oss << setw(count > 0 ? 2 : 1) << setfill('0') << (s % 3600) % 60; + count++; + } + if (count < 2 ) + oss << '.'<< setw(1) << setfill('0') << (ms % 1000) / 10; + + } + else { + if (s / 3600) + oss << setw(2) << setfill('0') << s / 3600 << ':'; + if ((s % 3600) / 60) + oss << setw(2) << setfill('0') << (s % 3600) / 60 << ':'; + oss << setw(2) << setfill('0') << (s % 3600) % 60 << '.'; + oss << setw(2) << setfill('0') << (ms % 1000) / 10; + } + + // non-stripped : fixed length string (11 chars) HH:mm:ss.ii" + // stripped : adapted to precision return oss.str(); } diff --git a/GstToolkit.h b/GstToolkit.h index a15517c..b72c3c5 100644 --- a/GstToolkit.h +++ b/GstToolkit.h @@ -9,7 +9,7 @@ namespace GstToolkit { - std::string time_to_string(guint64 t); + std::string time_to_string(guint64 t, bool stripped = false); std::string gst_version(); std::list all_plugins(); diff --git a/ImGuiToolkit.cpp b/ImGuiToolkit.cpp index b260228..ee4a182 100644 --- a/ImGuiToolkit.cpp +++ b/ImGuiToolkit.cpp @@ -283,9 +283,12 @@ void ImGuiToolkit::HelpMarker(const char* desc) // a) Returns TRUE if the left mouse button LMB is pressed over the timeline // b) the value of *time is changed to the position of the slider handle from user input (LMB) -bool ImGuiToolkit::TimelineSlider(const char* label, guint64 *time, guint64 duration, guint64 step) +#define NUM_MARKS 10 +#define LARGE_TICK_INCREMENT 1 +#define LABEL_TICK_INCREMENT 3 +bool ImGuiToolkit::TimelineSlider(const char* label, guint64 *time, guint64 duration, guint64 step, float scale) { - static guint64 optimal_tick_marks[12] = { 100 * MILISECOND, 500 * MILISECOND, 1 * SECOND, 2 * SECOND, 5 * SECOND, 10 * SECOND, 20 * SECOND, 1 * MINUTE, 2 * MINUTE, 5 * MINUTE, 10 * MINUTE, 60 * MINUTE }; + static guint64 optimal_tick_marks[NUM_MARKS + LABEL_TICK_INCREMENT] = { 100 * MILISECOND, 500 * MILISECOND, 1 * SECOND, 2 * SECOND, 5 * SECOND, 10 * SECOND, 20 * SECOND, 1 * MINUTE, 2 * MINUTE, 5 * MINUTE, 10 * MINUTE, 60 * MINUTE, 60 * MINUTE }; // get window ImGuiWindow* window = ImGui::GetCurrentWindow(); @@ -306,6 +309,7 @@ bool ImGuiToolkit::TimelineSlider(const char* label, guint64 *time, guint64 dura const float height = 2.f * (fontsize + style.FramePadding.y); ImVec2 pos = window->DC.CursorPos; ImVec2 size = ImGui::CalcItemSize(ImVec2(-FLT_MIN, 0.0f), ImGui::CalcItemWidth(), height); + size.x *= scale; ImRect bbox(pos, pos + size); ImGui::ItemSize(size, style.FramePadding.y); if (!ImGui::ItemAdd(bbox, id)) @@ -371,15 +375,17 @@ bool ImGuiToolkit::TimelineSlider(const char* label, guint64 *time, guint64 dura // by default, put a tick mark at every frame step and a large mark every second guint64 tick_step = step; guint64 large_tick_step = SECOND; + guint64 label_tick_step = 5 * SECOND; // how many pixels to represent one frame step? float tick_step_pixels = timeline_bbox.GetWidth() * step_; - // while there is less than 3 pixels between two tick marks (or at last optimal tick mark) + // while there is less than 5 pixels between two tick marks (or at last optimal tick mark) for ( int i=0; i<10 && tick_step_pixels < 5.f; ++i ) { // try to use the optimal tick marks pre-defined tick_step = optimal_tick_marks[i]; - large_tick_step = optimal_tick_marks[i+1]; + large_tick_step = optimal_tick_marks[i+LARGE_TICK_INCREMENT]; + label_tick_step = optimal_tick_marks[i+LABEL_TICK_INCREMENT]; tick_step_pixels = timeline_bbox.GetWidth() * static_cast ( static_cast(tick_step) / static_cast(duration) ); } @@ -388,10 +394,35 @@ bool ImGuiToolkit::TimelineSlider(const char* label, guint64 *time, guint64 dura pos = timeline_bbox.GetTL(); guint64 tick = 0; float tick_percent = 0.f; + char overlay_buf[24]; + ImVec2 overlay_size = ImVec2(0.f, 0.f); + ImVec2 mini = ImVec2(0.f, 0.f); + ImVec2 maxi = ImVec2(0.f, 0.f); + + // render text duration + ImFormatString(overlay_buf, IM_ARRAYSIZE(overlay_buf), "%s", GstToolkit::time_to_string(duration).c_str()); + overlay_size = ImGui::CalcTextSize(overlay_buf, NULL); + ImVec2 duration_label = bbox.GetBR() - overlay_size - ImVec2(3.f, 3.f); + if (overlay_size.x > 0.0f) + ImGui::RenderTextClipped( duration_label, bbox.Max, overlay_buf, NULL, &overlay_size); + + while ( tick < duration) { // large tick mark every large tick - float tick_length = !(tick%large_tick_step) ? fontsize : style.FramePadding.y; + float tick_length = !(tick%large_tick_step) ? fontsize - style.FramePadding.y : style.FramePadding.y; + + if ( !(tick%label_tick_step) ) { + tick_length = fontsize; + + ImFormatString(overlay_buf, IM_ARRAYSIZE(overlay_buf), "%s", GstToolkit::time_to_string(tick, true).c_str()); + overlay_size = ImGui::CalcTextSize(overlay_buf, NULL); + mini = ImVec2( pos.x - overlay_size.x / 2.f, pos.y + tick_length ); + maxi = ImVec2( pos.x + overlay_size.x / 2.f, pos.y + tick_length + overlay_size.y ); + // do not overlap with label for duration + if (maxi.x < duration_label.x) + ImGui::RenderTextClipped(mini, maxi, overlay_buf, NULL, &overlay_size); + } // draw a tick mark each step window->DrawList->AddLine( pos, pos + ImVec2(0.f, tick_length), color); @@ -405,20 +436,12 @@ bool ImGuiToolkit::TimelineSlider(const char* label, guint64 *time, guint64 dura // tick EOF window->DrawList->AddLine( timeline_bbox.GetTR(), timeline_bbox.GetTR() + ImVec2(0.f, fontsize), color); - // render text : duration and current time - char overlay_buf[24]; - ImVec2 overlay_size = ImVec2(0.f, 0.f); - ImFormatString(overlay_buf, IM_ARRAYSIZE(overlay_buf), "%s", GstToolkit::time_to_string(duration).c_str()); - overlay_size = ImGui::CalcTextSize(overlay_buf, NULL); - overlay_size += ImVec2(3.f, 3.f); - if (overlay_size.x > 0.0f) - ImGui::RenderTextClipped( bbox.GetBR() - overlay_size, bbox.Max, overlay_buf, NULL, &overlay_size); - - ImFormatString(overlay_buf, IM_ARRAYSIZE(overlay_buf), "%s", GstToolkit::time_to_string(*time).c_str()); - overlay_size = ImGui::CalcTextSize(overlay_buf, NULL); - overlay_size = ImVec2(3.f, -3.f - overlay_size.y); - if (overlay_size.x > 0.0f) - ImGui::RenderTextClipped( bbox.GetBL() + overlay_size, bbox.Max, overlay_buf, NULL, &overlay_size); +// disabled: render position +// ImFormatString(overlay_buf, IM_ARRAYSIZE(overlay_buf), "%s", GstToolkit::time_to_string(*time).c_str()); +// overlay_size = ImGui::CalcTextSize(overlay_buf, NULL); +// overlay_size = ImVec2(3.f, -3.f - overlay_size.y); +// if (overlay_size.x > 0.0f) +// ImGui::RenderTextClipped( bbox.GetBL() + overlay_size, bbox.Max, overlay_buf, NULL, &overlay_size); // draw slider grab handle if (grab_slider_bb.Max.x > grab_slider_bb.Min.x) { @@ -924,10 +947,10 @@ void ImGuiToolkit::SetAccentColor(accent_color color) colors[ImGuiCol_TabActive] = ImVec4(0.80f, 0.49f, 0.25f, 1.00f); colors[ImGuiCol_TabUnfocused] = ImVec4(0.15f, 0.10f, 0.07f, 0.97f); colors[ImGuiCol_TabUnfocusedActive] = ImVec4(0.42f, 0.26f, 0.14f, 1.00f); - colors[ImGuiCol_PlotLines] = ImVec4(0.61f, 0.61f, 0.61f, 1.00f); - colors[ImGuiCol_PlotLinesHovered] = ImVec4(1.00f, 0.43f, 0.35f, 1.00f); - colors[ImGuiCol_PlotHistogram] = ImVec4(0.94f, 0.57f, 0.01f, 1.00f); - colors[ImGuiCol_PlotHistogramHovered] = ImVec4(1.00f, 0.82f, 0.00f, 1.00f); + colors[ImGuiCol_PlotLines] = ImVec4(0.26f, 0.59f, 0.98f, 1.00f); + colors[ImGuiCol_PlotLinesHovered] = ImVec4(0.59f, 0.73f, 0.90f, 1.00f); + colors[ImGuiCol_PlotHistogram] = ImVec4(0.26f, 0.59f, 0.98f, 1.00f); + colors[ImGuiCol_PlotHistogramHovered] = ImVec4(0.59f, 0.73f, 0.90f, 1.00f); colors[ImGuiCol_TextSelectedBg] = ImVec4(0.98f, 0.59f, 0.26f, 0.64f); colors[ImGuiCol_DragDropTarget] = ImVec4(1.00f, 1.00f, 0.00f, 0.90f); colors[ImGuiCol_NavHighlight] = ImVec4(0.98f, 0.59f, 0.26f, 1.00f); @@ -976,9 +999,9 @@ void ImGuiToolkit::SetAccentColor(accent_color color) colors[ImGuiCol_TabUnfocused] = ImVec4(0.10f, 0.10f, 0.10f, 0.97f); colors[ImGuiCol_TabUnfocusedActive] = ImVec4(0.14f, 0.14f, 0.14f, 1.00f); colors[ImGuiCol_PlotLines] = ImVec4(0.61f, 0.61f, 0.61f, 1.00f); - colors[ImGuiCol_PlotLinesHovered] = ImVec4(1.00f, 0.43f, 0.35f, 1.00f); - colors[ImGuiCol_PlotHistogram] = ImVec4(0.94f, 0.57f, 0.01f, 1.00f); - colors[ImGuiCol_PlotHistogramHovered] = ImVec4(1.00f, 0.82f, 0.00f, 1.00f); + colors[ImGuiCol_PlotLinesHovered] = ImVec4(1.00f, 1.00f, 1.00f, 1.00f); + colors[ImGuiCol_PlotHistogram] = ImVec4(0.61f, 0.61f, 0.61f, 1.00f); + colors[ImGuiCol_PlotHistogramHovered] = ImVec4(1.00f, 1.00f, 1.00f, 1.00f); colors[ImGuiCol_TextSelectedBg] = ImVec4(0.26f, 0.59f, 0.98f, 0.64f); colors[ImGuiCol_DragDropTarget] = ImVec4(1.00f, 1.00f, 0.00f, 0.90f); colors[ImGuiCol_NavHighlight] = ImVec4(0.26f, 0.59f, 0.98f, 1.00f); @@ -1026,8 +1049,8 @@ void ImGuiToolkit::SetAccentColor(accent_color color) colors[ImGuiCol_TabActive] = ImVec4(0.25f, 0.49f, 0.80f, 1.00f); colors[ImGuiCol_TabUnfocused] = ImVec4(0.07f, 0.10f, 0.15f, 0.97f); colors[ImGuiCol_TabUnfocusedActive] = ImVec4(0.14f, 0.26f, 0.42f, 1.00f); - colors[ImGuiCol_PlotLines] = ImVec4(0.61f, 0.61f, 0.61f, 1.00f); - colors[ImGuiCol_PlotLinesHovered] = ImVec4(1.00f, 0.43f, 0.35f, 1.00f); + colors[ImGuiCol_PlotLines] = ImVec4(0.94f, 0.57f, 0.01f, 1.00f); + colors[ImGuiCol_PlotLinesHovered] = ImVec4(1.00f, 0.82f, 0.00f, 1.00f); colors[ImGuiCol_PlotHistogram] = ImVec4(0.94f, 0.57f, 0.01f, 1.00f); colors[ImGuiCol_PlotHistogramHovered] = ImVec4(1.00f, 0.82f, 0.00f, 1.00f); colors[ImGuiCol_TextSelectedBg] = ImVec4(0.26f, 0.59f, 0.98f, 0.64f); diff --git a/ImGuiToolkit.h b/ImGuiToolkit.h index b37709e..7529617 100644 --- a/ImGuiToolkit.h +++ b/ImGuiToolkit.h @@ -27,7 +27,7 @@ namespace ImGuiToolkit // utility sliders void Bar (float value, float in, float out, float min, float max, const char* title, bool expand); - bool TimelineSlider (const char* label, guint64 *time, guint64 duration, guint64 step); + bool TimelineSlider (const char* label, guint64 *time, guint64 duration, guint64 step, float scale = 1.f); bool TimelineSliderEdit (const char* label, guint64 *time, guint64 duration, guint64 step, std::list >& segments); diff --git a/ImGuiVisitor.cpp b/ImGuiVisitor.cpp index 53051b3..c21e710 100644 --- a/ImGuiVisitor.cpp +++ b/ImGuiVisitor.cpp @@ -93,7 +93,7 @@ void ImGuiVisitor::visit(Group &n) // } // spacing - ImGui::SetCursorPosY(ImGui::GetCursorPosY() + ImGui::GetTextLineHeight() / 2.f); + ImGui::Spacing(); } void ImGuiVisitor::visit(Switch &n) @@ -262,7 +262,7 @@ void ImGuiVisitor::visit(ImageProcessingShader &n) ImGui::PopID(); - ImGui::SetCursorPosY(ImGui::GetCursorPosY() + ImGui::GetTextLineHeight() / 2.f); + ImGui::Spacing(); } diff --git a/UserInterfaceManager.cpp b/UserInterfaceManager.cpp index 9b211d1..21a00aa 100644 --- a/UserInterfaceManager.cpp +++ b/UserInterfaceManager.cpp @@ -62,6 +62,7 @@ static TextEditor editor; void ShowAboutGStreamer(bool* p_open); void ShowAboutOpengl(bool* p_open); void ShowConfig(bool* p_open); +void ShowSandbox(bool* p_open); // static objects for multithreaded file dialog static std::atomic fileDialogPending_ = false; @@ -716,6 +717,7 @@ ToolBox::ToolBox() { show_demo_window = false; show_icons_window = false; + show_sandbox = false; } void UserInterface::StartScreenshot() @@ -782,6 +784,7 @@ void ToolBox::Render() } if (ImGui::BeginMenu("Gui")) { + ImGui::MenuItem("Sandbox", nullptr, &show_sandbox); ImGui::MenuItem("Icons", nullptr, &show_icons_window); ImGui::MenuItem("Demo ImGui", nullptr, &show_demo_window); @@ -850,7 +853,9 @@ void ToolBox::Render() // About and other utility windows if (show_icons_window) - ImGuiToolkit::ShowIconsWindow(&show_icons_window); + ImGuiToolkit::ShowIconsWindow(&show_icons_window); + if (show_sandbox) + ShowSandbox(&show_sandbox); if (show_demo_window) ImGui::ShowDemoWindow(&show_demo_window); @@ -1119,13 +1124,20 @@ void MediaController::Render() // Something to show ? if (mp_ && mp_->isOpen()) { - float width = ImGui::GetContentRegionAvail().x; + static float timeline_zoom = 1.f; + const float width = ImGui::GetContentRegionAvail().x; + const float timeline_height = 2.f * (ImGui::GetFontSize() + ImGui::GetStyle().FramePadding.y); - if (Settings::application.widget.media_player_view) { + if (Settings::application.widget.media_player_view) + { // set an image height to fill the vertical space, minus the height of control bar float image_height = ImGui::GetContentRegionAvail().y; - if (mp_->duration() != GST_CLOCK_TIME_NONE) - image_height -= 3.f * ImGui::GetFrameHeight(); + if (mp_->duration() != GST_CLOCK_TIME_NONE) { + // leave space for buttons, spacing and timeline + image_height -= ImGui::GetFrameHeight() + timeline_height + 3.f * ImGui::GetStyle().ItemSpacing.y; + // leave space for scrollbar + image_height -= ImGui::GetStyle().ScrollbarSize; + } // display media ImVec2 imagesize ( image_height * mp_->aspectRatio(), image_height); @@ -1133,6 +1145,8 @@ void MediaController::Render() ImGui::SetCursorPosX(ImGui::GetCursorPos().x + (ImGui::GetContentRegionAvail().x - imagesize.x) / 2.0); ImGui::Image((void*)(uintptr_t)mp_->texture(), imagesize); ImVec2 return_to_pos = ImGui::GetCursorPos(); + + // display media information if (ImGui::IsItemHovered()) { float tooltip_height = (follow_active_source_? 3.f:2.f)* ImGui::GetTextLineHeightWithSpacing(); @@ -1150,6 +1164,13 @@ void MediaController::Render() ImGui::Text(" %d x %d px", mp_->width(), mp_->height()); } + + // display time + ImGuiToolkit::PushFont(ImGuiToolkit::FONT_LARGE); + ImGui::SetCursorPos( ImVec2(return_to_pos.x + 5, return_to_pos.y - ImGui::GetTextLineHeightWithSpacing()) ); + ImGui::Text("%s", GstToolkit::time_to_string(mp_->position()).c_str()); + ImGui::PopFont(); + ImGui::SetCursorPos(return_to_pos); } @@ -1211,11 +1232,26 @@ void MediaController::Render() mp_->setLoop( MediaPlayer::LOOP_REWIND ); } + ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(3, 3)); + + // scrolling sub-window + ImGui::BeginChild("##scrolling", + ImVec2(ImGui::GetContentRegionAvail().x - 20.0, + timeline_height + ImGui::GetStyle().ScrollbarSize ), + false, ImGuiWindowFlags_HorizontalScrollbar); + // custom timeline slider guint64 current_t = mp_->position(); guint64 seek_t = current_t; - slider_pressed_ = ImGuiToolkit::TimelineSlider( "simpletimeline", &seek_t, - mp_->duration(), mp_->frameDuration()); + slider_pressed_ = ImGuiToolkit::TimelineSlider("##timeline", &seek_t, + mp_->duration(), mp_->frameDuration(), timeline_zoom); + ImGui::EndChild(); + + // zoom slider + ImGui::SameLine(); + ImGui::VSliderFloat("##zoom", ImVec2(17, timeline_height), &timeline_zoom, 1.0, 5.f, ""); + ImGui::PopStyleVar(); + // if the seek target time is different from the current position time // (i.e. the difference is less than one frame) if ( ABS_DIFF (current_t, seek_t) > mp_->frameDuration() ) { @@ -1823,7 +1859,7 @@ void Navigator::RenderTransitionPannel() ImGuiToolkit::ButtonSwitch( ICON_FA_CLOUD_SUN " Clear view", &Settings::application.transition.hide_windows); // Transition options - ImGui::SetCursorPosY(ImGui::GetCursorPosY() + ImGui::GetTextLineHeight() / 2.f); + ImGui::Spacing(); ImGui::Text("Animation"); if (ImGuiToolkit::ButtonIcon(4, 13)) Settings::application.transition.duration = 1.f; ImGui::SameLine(0, 10); @@ -1834,7 +1870,7 @@ void Navigator::RenderTransitionPannel() ImGui::SetNextItemWidth(IMGUI_RIGHT_ALIGN); ImGui::Combo("Curve", &Settings::application.transition.profile, "Linear\0Quadratic\0"); - ImGui::SetCursorPosY(ImGui::GetCursorPosY() + ImGui::GetTextLineHeight() / 2.f); + ImGui::Spacing(); if ( ImGui::Button( ICON_FA_SIGN_IN_ALT " Play ", ImVec2(IMGUI_RIGHT_ALIGN, 0)) ){ TransitionView *tv = static_cast(Mixer::manager().view(View::TRANSITION)); if (tv) tv->play(true); @@ -2025,14 +2061,14 @@ void Navigator::RenderMainPannel() } // options session - ImGui::SetCursorPosY(ImGui::GetCursorPosY() + ImGui::GetTextLineHeight() / 2.f); + ImGui::Spacing(); ImGui::Text("Options"); ImGuiToolkit::ButtonSwitch( ICON_FA_ARROW_CIRCLE_RIGHT " Smooth transition", &Settings::application.smooth_transition); // Continue Main pannel // WINDOWS - ImGui::SetCursorPosY(ImGui::GetCursorPosY() + ImGui::GetTextLineHeight() / 2.f); + ImGui::Spacing(); ImGui::Text("Windows"); ImGuiToolkit::ButtonSwitch( IMGUI_TITLE_PREVIEW, &Settings::application.widget.preview, CTRL_MOD "D"); ImGuiToolkit::ButtonSwitch( IMGUI_TITLE_MEDIAPLAYER, &Settings::application.widget.media_player, CTRL_MOD "P"); @@ -2044,7 +2080,7 @@ void Navigator::RenderMainPannel() ImGuiToolkit::ButtonSwitch( ICON_FA_TACHOMETER_ALT " Metrics", &Settings::application.widget.stats); // Settings application appearance - ImGui::SetCursorPosY(ImGui::GetCursorPosY() + ImGui::GetTextLineHeight() / 2.f); + ImGui::Spacing(); ImGui::Text("Appearance"); ImGui::SetNextItemWidth(IMGUI_RIGHT_ALIGN); if ( ImGui::DragFloat("Scale", &Settings::application.scale, 0.01, 0.8f, 1.2f, "%.1f")) @@ -2086,6 +2122,184 @@ void Navigator::RenderMainPannel() } +namespace ImGui +{ + +int hover(const char *label) +{ + const ImGuiStyle& Style = GetStyle(); + const ImGuiIO& IO = GetIO(); + ImDrawList* DrawList = GetWindowDrawList(); + ImGuiWindow* Window = GetCurrentWindow(); + if (Window->SkipItems) + return 0; + + int hovered = IsItemActive() || IsItemHovered(); + Dummy(ImVec2(0,3)); + + // prepare canvas + const float avail = GetContentRegionAvailWidth(); + const float dim = ImMin(avail, 128.f); + ImVec2 Canvas(dim, dim); + + ImRect bb(Window->DC.CursorPos, Window->DC.CursorPos + Canvas); + const ImGuiID id = Window->GetID(label); + ItemSize(bb); + if (!ItemAdd(bb, id)) + return 0; + + hovered |= 0 != IsItemClicked(); + + RenderFrame(bb.Min, bb.Max, GetColorU32(ImGuiCol_FrameBg, 1), true, Style.FrameRounding); + + + return 1; +} + +} + +bool hoverer(const char* label, uint *index, int min, int max, ImVec2 size) +{ + // get window + ImGuiWindow* window = ImGui::GetCurrentWindow(); + if (window->SkipItems) + return false; + + // get id +// ImGuiContext& g = *GImGui; + const ImGuiID id = window->GetID(label); + + ImVec2 pos = window->DC.CursorPos; + ImRect bbox(pos, pos + size); + ImGui::ItemSize(size); + if (!ImGui::ItemAdd(bbox, id)) + return false; + + // read user input from system + bool left_mouse_press = false; + const bool hovered = ImGui::ItemHoverable(bbox, id); + bool temp_input_is_active = ImGui::TempInputIsActive(id); + if (!temp_input_is_active) + { + const bool focus_requested = ImGui::FocusableItemRegister(window, id); + left_mouse_press = hovered && ImGui::IsMouseDown(ImGuiMouseButton_Left); + if (focus_requested || left_mouse_press) + { + ImGui::SetActiveID(id, window); + ImGui::SetFocusID(id, window); + ImGui::FocusWindow(window); + } + } + + // time Slider behavior + ImRect grab_slider_bb; + uint _zero = min; + uint _end = max; + bool pressed = ImGui::SliderBehavior(bbox, id, ImGuiDataType_U32, index, &_zero, + &_end, "%d", 1.f, ImGuiSliderFlags_None, &grab_slider_bb); + +// bbox = ImRect(pos, pos + ImVec2(size.x, size.y / 2.f)); +// if (ImGui::IsMouseHoveringRect(bbox.GetTL(), bbox.GetBR())) +// *val = 1.f; +// else +// *val = 0.f; + + return pressed; + +} + + +void ShowSandbox(bool* p_open) +{ + ImGui::SetNextWindowPos(ImVec2(100, 100), ImGuiCond_FirstUseEver); + ImGui::SetNextWindowSize(ImVec2(400, 260), ImGuiCond_FirstUseEver); + if (!ImGui::Begin( ICON_FA_BABY_CARRIAGE " Sandbox", p_open)) + { + ImGui::End(); + return; + } + + ImGui::Text("Testing sandox"); + + std::list< std::pair > segments; + segments.push_back( std::make_pair(GST_SECOND*1, GST_SECOND*2) ); + guint64 duration = GST_SECOND * 4; + guint64 step = GST_MSECOND * 20; + static guint64 t = 0; + + bool slider_pressed = ImGuiToolkit::TimelineSliderEdit("timeline", &t, duration, step, segments); + + + + static float arr[] = { 0.6f, 0.1f, 1.0f, 0.5f, 0.92f, 0.1f, 0.2f, 0.f, 1.f, 0.4f, + 0.6f, 0.1f, 1.0f, 0.5f, 0.92f, 0.1f, 0.2f, 0.f, 1.f, 0.4f, + 0.6f, 0.1f, 1.0f, 0.5f, 0.92f, 0.1f, 0.2f, 0.f, 1.f, 0.4f, + 0.6f, 0.1f, 1.0f, 0.5f, 0.92f, 0.1f, 0.2f, 0.f, 1.f, 0.4f, + 0.6f, 0.1f, 1.0f, 0.5f, 0.92f, 0.1f, 0.2f, 0.f, 1.f, 0.4f, + 0.6f, 0.1f, 1.0f, 0.5f, 0.92f, 0.1f, 0.2f, 0.f, 1.f, 0.4f, + 0.6f, 0.1f, 1.0f, 0.5f, 0.92f, 0.1f, 0.2f, 0.f, 1.f, 0.4f, + 0.6f, 0.1f, 1.0f, 0.5f, 0.92f, 0.1f, 0.2f, 0.f, 1.f, 0.4f, + 0.6f, 0.1f, 1.0f, 0.5f, 0.92f, 0.1f, 0.2f, 0.f, 1.f, 0.4f, + 0.6f, 0.1f, 1.0f, 0.5f, 0.92f, 0.1f, 0.2f, 0.f, 1.f, 0.4f, + 0.6f, 0.1f, 1.0f, 0.5f, 0.92f, 0.1f, 0.2f, 0.f, 1.f, 0.4f, + 0.6f, 0.1f, 1.0f, 0.5f, 0.92f, 0.1f, 0.2f, 0.f, 1.f, 0.4f, + 0.6f, 0.1f, 1.0f, 0.5f, 0.92f, 0.1f, 0.2f, 0.f, 1.f, 0.4f, + 0.6f, 0.1f, 1.0f, 0.5f, 0.92f, 0.1f, 0.2f, 0.f, 1.f, 0.4f, + 0.6f, 0.1f, 1.0f, 0.5f, 0.92f, 0.1f, 0.2f, 0.f, 1.f, 0.4f, + 0.6f, 0.1f, 1.0f, 0.5f, 0.92f, 0.1f, 0.2f, 0.f, 1.f, 0.4f, + 0.6f, 0.1f, 1.0f, 0.5f, 0.92f, 0.1f, 0.2f, 0.f, 1.f, 0.4f, + 0.6f, 0.1f, 1.0f, 0.5f, 0.92f, 0.1f, 0.2f, 0.f, 1.f, 0.4f, + 0.6f, 0.1f, 1.0f, 0.5f, 0.92f, 0.1f, 0.2f, 0.f, 1.f, 0.4f, + 0.6f, 0.1f, 1.0f, 0.5f, 0.92f, 0.1f, 0.2f, 0.f, 1.f, 0.4f, + 0.6f, 0.1f, 1.0f, 0.5f, 0.92f, 0.1f, 0.2f, 0.f, 1.f, 0.4f }; + + ImVec2 size = ImGui::CalcItemSize(ImVec2(-FLT_MIN, 0.0f), ImGui::CalcItemWidth(), 20); + + // draw position when entering + ImVec2 draw_pos = ImGui::GetCursorPos(); + // plot the histogram + uint press_index = IM_ARRAYSIZE(arr); + bool pressed = hoverer("test", &press_index, 0, IM_ARRAYSIZE(arr)-1, size); + + static bool active = false; + static float target_value = 0.f; + static uint starting_index = IM_ARRAYSIZE(arr); + + if (pressed != active) { + active = pressed; + starting_index = press_index; + target_value = arr[starting_index] > 0.f ? 0.f : 1.f; + } + + if (active) { + for (int i = MIN(starting_index, press_index); i < MAX(starting_index, press_index); ++i) + arr[i] = target_value; + } + + + + // back to + ImGui::SetCursorPos(draw_pos); +// ImGui::PlotLines("Lines", arr, IM_ARRAYSIZE(arr), 0, NULL, 0.0f, 1.0f, size); + +// ImVec4* colors = ImGui::GetStyle().Colors; +// ImGui::PushStyleColor(ImGuiCol_PlotHistogram, colors[ImGuiCol_Tab]); + + ImGui::PlotHistogram("Histogram", arr, IM_ARRAYSIZE(arr)-1, 0, NULL, 0.0f, 1.0f, size); + +// ImGui::PopStyleColor(1); + + ImGui::Text("Timeline t %" GST_STIME_FORMAT "\n", GST_STIME_ARGS(t)); + ImGui::Text("Timeline Pressed %s", slider_pressed ? "on" : "off"); + ImGui::Text("Hover Pressed %s v = %d", pressed ? "on" : "off", press_index); + + static int w = 0; + ImGui::SetNextItemWidth(size.x); + ImGui::SliderInt("##int", &w, 0, IM_ARRAYSIZE(arr)-1); + + ImGui::End(); +} + void ShowConfig(bool* p_open) { ImGui::SetNextWindowPos(ImVec2(1000, 20), ImGuiCond_FirstUseEver); diff --git a/UserInterfaceManager.h b/UserInterfaceManager.h index 2695ade..dbe6c54 100644 --- a/UserInterfaceManager.h +++ b/UserInterfaceManager.h @@ -71,6 +71,7 @@ class ToolBox { bool show_demo_window; bool show_icons_window; + bool show_sandbox; public: ToolBox(); diff --git a/docs/index.md b/docs/index.md index c5125f1..84f035d 100644 --- a/docs/index.md +++ b/docs/index.md @@ -25,7 +25,7 @@ Download package from [Github Release](https://github.com/brunoherbelin/vimix/re ### Windows -*Please consider helping by compiling vimix providing packages for Windows.* +*Please consider helping by compiling & providing packages for Windows.*