mirror of
https://github.com/brunoherbelin/vimix.git
synced 2025-12-11 18:34:58 +01:00
Player: move up timeline and adjust size
keep play button bar at the bottom for all configurations, avoid text and buttons overlay when Player is small. Fix cut timing in selection
This commit is contained in:
@@ -505,18 +505,6 @@ void ImGuiToolkit::RenderTimeline (ImGuiWindow* window, ImRect timeline_bbox, gu
|
|||||||
|
|
||||||
ImGuiToolkit::PushFont(ImGuiToolkit::FONT_BOLD);
|
ImGuiToolkit::PushFont(ImGuiToolkit::FONT_BOLD);
|
||||||
|
|
||||||
// render tick and text START
|
|
||||||
ImFormatString(text_buf, IM_ARRAYSIZE(text_buf), "%s",
|
|
||||||
GstToolkit::time_to_string(start, GstToolkit::TIME_STRING_MINIMAL).c_str());
|
|
||||||
ImVec2 beginning_label_size = ImGui::CalcTextSize(text_buf, NULL);
|
|
||||||
ImVec2 beginning_label_pos = timeline_bbox.GetTL() + ImVec2(3.f, fontsize);
|
|
||||||
if (verticalflip)
|
|
||||||
beginning_label_pos.y -= fontsize;
|
|
||||||
ImGui::RenderTextClipped( beginning_label_pos, beginning_label_pos + beginning_label_size,
|
|
||||||
text_buf, NULL, &beginning_label_size);
|
|
||||||
window->DrawList->AddLine( timeline_bbox.GetTL(), timeline_bbox.GetBL(), text_color, 1.5f);
|
|
||||||
|
|
||||||
|
|
||||||
// render tick and text END
|
// render tick and text END
|
||||||
ImFormatString(text_buf, IM_ARRAYSIZE(text_buf), "%s",
|
ImFormatString(text_buf, IM_ARRAYSIZE(text_buf), "%s",
|
||||||
GstToolkit::time_to_string(end, GstToolkit::TIME_STRING_MINIMAL).c_str());
|
GstToolkit::time_to_string(end, GstToolkit::TIME_STRING_MINIMAL).c_str());
|
||||||
@@ -528,6 +516,19 @@ void ImGuiToolkit::RenderTimeline (ImGuiWindow* window, ImRect timeline_bbox, gu
|
|||||||
text_buf, NULL, &duration_label_size);
|
text_buf, NULL, &duration_label_size);
|
||||||
window->DrawList->AddLine( timeline_bbox.GetTR(), timeline_bbox.GetBR(), text_color, 1.5f);
|
window->DrawList->AddLine( timeline_bbox.GetTR(), timeline_bbox.GetBR(), text_color, 1.5f);
|
||||||
|
|
||||||
|
// render tick and text START
|
||||||
|
ImFormatString(text_buf, IM_ARRAYSIZE(text_buf), "%s",
|
||||||
|
GstToolkit::time_to_string(start, GstToolkit::TIME_STRING_MINIMAL).c_str());
|
||||||
|
ImVec2 beginning_label_size = ImGui::CalcTextSize(text_buf, NULL);
|
||||||
|
ImVec2 beginning_label_pos = timeline_bbox.GetTL() + ImVec2(3.f, fontsize);
|
||||||
|
if (verticalflip)
|
||||||
|
beginning_label_pos.y -= fontsize;
|
||||||
|
if ( beginning_label_pos.x + beginning_label_size.x < duration_label_pos . x) {
|
||||||
|
ImGui::RenderTextClipped( beginning_label_pos, beginning_label_pos + beginning_label_size,
|
||||||
|
text_buf, NULL, &beginning_label_size);
|
||||||
|
}
|
||||||
|
window->DrawList->AddLine( timeline_bbox.GetTL(), timeline_bbox.GetBL(), text_color, 1.5f);
|
||||||
|
|
||||||
ImGui::PopFont();
|
ImGui::PopFont();
|
||||||
|
|
||||||
// render the tick marks along TIMELINE
|
// render the tick marks along TIMELINE
|
||||||
|
|||||||
22
Timeline.cpp
22
Timeline.cpp
@@ -268,6 +268,28 @@ GstClockTime Timeline::sectionsDuration() const
|
|||||||
return duration() - d;
|
return duration() - d;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
GstClockTime Timeline::sectionsTimeAt(GstClockTime t) const
|
||||||
|
{
|
||||||
|
// target time
|
||||||
|
GstClockTime d = t;
|
||||||
|
|
||||||
|
// loop over gaps
|
||||||
|
for (auto it = gaps_.begin(); it != gaps_.end(); ++it) {
|
||||||
|
// gap before target?
|
||||||
|
if ( (*it).end < d ) {
|
||||||
|
// increment target
|
||||||
|
d += (*it).end - (*it).begin;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
// done
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// return updated target
|
||||||
|
return d;
|
||||||
|
}
|
||||||
|
|
||||||
size_t Timeline::fillSectionsArrays( float* const gaps, float* const fading)
|
size_t Timeline::fillSectionsArrays( float* const gaps, float* const fading)
|
||||||
{
|
{
|
||||||
size_t arraysize = MAX_TIMELINE_ARRAY;
|
size_t arraysize = MAX_TIMELINE_ARRAY;
|
||||||
|
|||||||
11
Timeline.h
11
Timeline.h
@@ -120,10 +120,15 @@ public:
|
|||||||
bool addGap(GstClockTime begin, GstClockTime end);
|
bool addGap(GstClockTime begin, GstClockTime end);
|
||||||
bool cut(GstClockTime t, bool left, bool join_extremity);
|
bool cut(GstClockTime t, bool left, bool join_extremity);
|
||||||
bool removeGaptAt(GstClockTime t);
|
bool removeGaptAt(GstClockTime t);
|
||||||
|
|
||||||
bool gapAt(const GstClockTime t) const;
|
bool gapAt(const GstClockTime t) const;
|
||||||
bool getGapAt(const GstClockTime t, TimeInterval &gap) const;
|
bool getGapAt(const GstClockTime t, TimeInterval &gap) const;
|
||||||
|
|
||||||
|
// inverse of gaps: sections of play areas
|
||||||
|
TimeIntervalSet sections() const;
|
||||||
|
GstClockTime sectionsDuration() const;
|
||||||
|
GstClockTime sectionsTimeAt(GstClockTime t) const;
|
||||||
|
size_t fillSectionsArrays(float * const gaps, float * const fading);
|
||||||
|
|
||||||
// Manipulation of Fading
|
// Manipulation of Fading
|
||||||
float fadingAt(const GstClockTime t) const;
|
float fadingAt(const GstClockTime t) const;
|
||||||
size_t fadingIndexAt(const GstClockTime t) const;
|
size_t fadingIndexAt(const GstClockTime t) const;
|
||||||
@@ -134,10 +139,6 @@ public:
|
|||||||
void smoothFading(uint N = 1);
|
void smoothFading(uint N = 1);
|
||||||
void autoFading(uint milisecond = 100);
|
void autoFading(uint milisecond = 100);
|
||||||
bool autoCut();
|
bool autoCut();
|
||||||
TimeIntervalSet sections() const;
|
|
||||||
|
|
||||||
GstClockTime sectionsDuration() const;
|
|
||||||
size_t fillSectionsArrays(float * const gaps, float * const fading);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
|||||||
@@ -2015,7 +2015,7 @@ void SourceController::Render()
|
|||||||
_timeline_height = (g.FontSize + _v_space) * 2.0f ; // double line for each timeline
|
_timeline_height = (g.FontSize + _v_space) * 2.0f ; // double line for each timeline
|
||||||
_scrollbar = g.Style.ScrollbarSize;
|
_scrollbar = g.Style.ScrollbarSize;
|
||||||
// all together: 1 title bar + spacing + 1 toolbar + spacing + 2 timelines + scrollbar
|
// all together: 1 title bar + spacing + 1 toolbar + spacing + 2 timelines + scrollbar
|
||||||
_mediaplayer_height = _buttons_height + 2.f * _timeline_height + _scrollbar + 2.f * _v_space;
|
_mediaplayer_height = _buttons_height + 2.f * _timeline_height + 2.f * _scrollbar + _v_space;
|
||||||
|
|
||||||
// constraint position
|
// constraint position
|
||||||
static ImVec2 source_window_pos = ImVec2(1180, 20);
|
static ImVec2 source_window_pos = ImVec2(1180, 20);
|
||||||
@@ -2337,6 +2337,8 @@ void SourceController::RenderSelection(size_t i)
|
|||||||
// NB: use the same width/time ratio for all to ensure timing vertical correspondance
|
// NB: use the same width/time ratio for all to ensure timing vertical correspondance
|
||||||
DrawTimeline("##timeline_mediaplayer", mp->timeline(), mp->position(), width_ratio / fabs(mp->playSpeed()), framesize.y);
|
DrawTimeline("##timeline_mediaplayer", mp->timeline(), mp->position(), width_ratio / fabs(mp->playSpeed()), framesize.y);
|
||||||
|
|
||||||
|
if ( w > maxframewidth ) {
|
||||||
|
|
||||||
// next icon buttons are small
|
// next icon buttons are small
|
||||||
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(3.f, 3.f));
|
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(3.f, 3.f));
|
||||||
|
|
||||||
@@ -2359,6 +2361,7 @@ void SourceController::RenderSelection(size_t i)
|
|||||||
|
|
||||||
for (auto d = durations.crbegin(); d != durations.crend(); ++d) {
|
for (auto d = durations.crbegin(); d != durations.crend(); ++d) {
|
||||||
|
|
||||||
|
// next buttons sub id
|
||||||
ImGui::PushID( static_cast<int>(*d));
|
ImGui::PushID( static_cast<int>(*d));
|
||||||
|
|
||||||
// calculate position of icons
|
// calculate position of icons
|
||||||
@@ -2407,7 +2410,7 @@ void SourceController::RenderSelection(size_t i)
|
|||||||
// middle buttons : offer to cut at this position
|
// middle buttons : offer to cut at this position
|
||||||
else if ( playdur > (*d) ) {
|
else if ( playdur > (*d) ) {
|
||||||
char text_buf[256];
|
char text_buf[256];
|
||||||
GstClockTime cutposition = (*d) * fabs(mp->playSpeed());
|
GstClockTime cutposition = mp->timeline()->sectionsTimeAt( (*d) * fabs(mp->playSpeed()) );
|
||||||
ImFormatString(text_buf, IM_ARRAYSIZE(text_buf), "Cut at %s",
|
ImFormatString(text_buf, IM_ARRAYSIZE(text_buf), "Cut at %s",
|
||||||
GstToolkit::time_to_string(cutposition, GstToolkit::TIME_STRING_MINIMAL).c_str());
|
GstToolkit::time_to_string(cutposition, GstToolkit::TIME_STRING_MINIMAL).c_str());
|
||||||
|
|
||||||
@@ -2446,6 +2449,8 @@ void SourceController::RenderSelection(size_t i)
|
|||||||
ImGui::PopID();
|
ImGui::PopID();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
// next line position
|
// next line position
|
||||||
ImGui::SetCursorPos(image_top + ImVec2(0, 2.0f * _timeline_height + 2.f * _v_space));
|
ImGui::SetCursorPos(image_top + ImVec2(0, 2.0f * _timeline_height + 2.f * _v_space));
|
||||||
}
|
}
|
||||||
@@ -2523,20 +2528,20 @@ void SourceController::RenderSelectionContextMenu()
|
|||||||
std::ostringstream info;
|
std::ostringstream info;
|
||||||
info << SystemToolkit::base_filename( _selection_mediaplayer->filename() );
|
info << SystemToolkit::base_filename( _selection_mediaplayer->filename() );
|
||||||
|
|
||||||
if ( ImGuiToolkit::MenuItemIcon(14, 16, ICON_FA_CARET_LEFT " Accelerate", false, fabs(_selection_target_faster) > 0 )){
|
if ( ImGuiToolkit::MenuItemIcon(14, 16, ICON_FA_CARET_LEFT " Accelerate" , false, fabs(_selection_target_faster) > 0 )){
|
||||||
_selection_mediaplayer->setPlaySpeed( _selection_target_faster );
|
_selection_mediaplayer->setPlaySpeed( _selection_target_faster );
|
||||||
info << ": Speed x" << std::setprecision(3) << _selection_target_faster;
|
info << ": Speed x" << std::setprecision(3) << _selection_target_faster;
|
||||||
Action::manager().store(info.str());
|
Action::manager().store(info.str());
|
||||||
}
|
}
|
||||||
if ( ImGuiToolkit::MenuItemIcon(15, 16, ICON_FA_CARET_RIGHT " Slow down", false, fabs(_selection_target_slower) > 0 )){
|
if ( ImGuiToolkit::MenuItemIcon(15, 16, "Slow down " ICON_FA_CARET_RIGHT , false, fabs(_selection_target_slower) > 0 )){
|
||||||
_selection_mediaplayer->setPlaySpeed( _selection_target_slower );
|
_selection_mediaplayer->setPlaySpeed( _selection_target_slower );
|
||||||
info << ": Speed x" << std::setprecision(3) << _selection_target_slower;
|
info << ": Speed x" << std::setprecision(3) << _selection_target_slower;
|
||||||
Action::manager().store(info.str());
|
Action::manager().store(info.str());
|
||||||
}
|
}
|
||||||
if ( _selection_mediaplayer->timeline()->gapAt( _selection_mediaplayer->timeline()->end()) ) {
|
if ( _selection_mediaplayer->timeline()->gapAt( _selection_mediaplayer->timeline()->end()) ) {
|
||||||
|
|
||||||
if ( ImGuiToolkit::MenuItemIcon(7, 0, "Remove end gap" )){
|
if ( ImGuiToolkit::MenuItemIcon(7, 0, "Restore ending" )){
|
||||||
info << ": Remove end gap ";
|
info << ": Restore ending";
|
||||||
if ( _selection_mediaplayer->timeline()->removeGaptAt(_selection_mediaplayer->timeline()->end()) )
|
if ( _selection_mediaplayer->timeline()->removeGaptAt(_selection_mediaplayer->timeline()->end()) )
|
||||||
Action::manager().store(info.str());
|
Action::manager().store(info.str());
|
||||||
}
|
}
|
||||||
@@ -2763,12 +2768,17 @@ void SourceController::RenderSingleSource(Source *s)
|
|||||||
|
|
||||||
void SourceController::RenderMediaPlayer(MediaPlayer *mp)
|
void SourceController::RenderMediaPlayer(MediaPlayer *mp)
|
||||||
{
|
{
|
||||||
|
// for action manager
|
||||||
|
std::ostringstream oss;
|
||||||
|
oss << SystemToolkit::base_filename( mp->filename() );
|
||||||
|
|
||||||
|
// for draw
|
||||||
static float timeline_zoom = 1.f;
|
static float timeline_zoom = 1.f;
|
||||||
const float slider_zoom_width = _timeline_height / 2.f;
|
const float slider_zoom_width = _timeline_height / 2.f;
|
||||||
ImDrawList* draw_list = ImGui::GetWindowDrawList();
|
ImDrawList* draw_list = ImGui::GetWindowDrawList();
|
||||||
|
|
||||||
ImVec2 top = ImGui::GetCursorScreenPos();
|
const ImVec2 top = ImGui::GetCursorScreenPos();
|
||||||
ImVec2 rendersize = ImGui::GetContentRegionAvail() - ImVec2(0, _mediaplayer_height);
|
const ImVec2 rendersize = ImGui::GetContentRegionAvail() - ImVec2(0, _mediaplayer_height);
|
||||||
ImVec2 bottom = ImVec2(top.x, top.y + rendersize.y + _v_space);
|
ImVec2 bottom = ImVec2(top.x, top.y + rendersize.y + _v_space);
|
||||||
|
|
||||||
///
|
///
|
||||||
@@ -2789,32 +2799,32 @@ void SourceController::RenderMediaPlayer(MediaPlayer *mp)
|
|||||||
///
|
///
|
||||||
/// Image
|
/// Image
|
||||||
///
|
///
|
||||||
top += corner;
|
const ImVec2 top_image = top + corner;
|
||||||
ImGui::SetCursorScreenPos(top);
|
ImGui::SetCursorScreenPos(top_image);
|
||||||
ImGui::Image((void*)(uintptr_t) mp->texture(), framesize);
|
ImGui::Image((void*)(uintptr_t) mp->texture(), framesize);
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Info overlays
|
/// Info overlays
|
||||||
///
|
///
|
||||||
ImGui::SetCursorScreenPos(top + ImVec2(framesize.x - ImGui::GetTextLineHeightWithSpacing(), _v_space));
|
ImGui::SetCursorScreenPos(top_image + ImVec2(framesize.x - ImGui::GetTextLineHeightWithSpacing(), _v_space));
|
||||||
ImGui::Text(ICON_FA_INFO_CIRCLE);
|
ImGui::Text(ICON_FA_INFO_CIRCLE);
|
||||||
if (ImGui::IsItemHovered()){
|
if (ImGui::IsItemHovered()){
|
||||||
// information visitor
|
// information visitor
|
||||||
mp->accept(info_);
|
mp->accept(info_);
|
||||||
float tooltip_height = 3.f * ImGui::GetTextLineHeightWithSpacing();
|
float tooltip_height = 3.f * ImGui::GetTextLineHeightWithSpacing();
|
||||||
draw_list->AddRectFilled(top, top + ImVec2(framesize.x, tooltip_height), IMGUI_COLOR_OVERLAY);
|
draw_list->AddRectFilled(top_image, top_image + ImVec2(framesize.x, tooltip_height), IMGUI_COLOR_OVERLAY);
|
||||||
ImGui::SetCursorScreenPos(top + ImVec2(_h_space, _v_space));
|
ImGui::SetCursorScreenPos(top_image + ImVec2(_h_space, _v_space));
|
||||||
ImGui::Text("%s", info_.str().c_str());
|
ImGui::Text("%s", info_.str().c_str());
|
||||||
|
|
||||||
// Icon to inform hardware decoding
|
// Icon to inform hardware decoding
|
||||||
if ( !mp->hardwareDecoderName().empty()) {
|
if ( !mp->hardwareDecoderName().empty()) {
|
||||||
ImGui::SetCursorScreenPos(top + ImVec2( framesize.x - ImGui::GetTextLineHeightWithSpacing(), 0.35f * tooltip_height));
|
ImGui::SetCursorScreenPos(top_image + ImVec2( framesize.x - ImGui::GetTextLineHeightWithSpacing(), 0.35f * tooltip_height));
|
||||||
ImGui::Text(ICON_FA_MICROCHIP);
|
ImGui::Text(ICON_FA_MICROCHIP);
|
||||||
}
|
}
|
||||||
|
|
||||||
// refresh frequency
|
// refresh frequency
|
||||||
if ( mp->isPlaying()) {
|
if ( mp->isPlaying()) {
|
||||||
ImGui::SetCursorScreenPos(top + ImVec2( framesize.x - 1.5f * _buttons_height, 0.667f * tooltip_height));
|
ImGui::SetCursorScreenPos(top_image + ImVec2( framesize.x - 1.5f * _buttons_height, 0.667f * tooltip_height));
|
||||||
ImGui::Text("%.1f Hz", mp->updateFrameRate());
|
ImGui::Text("%.1f Hz", mp->updateFrameRate());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2828,143 +2838,14 @@ void SourceController::RenderMediaPlayer(MediaPlayer *mp)
|
|||||||
ImGui::Text( ICON_FA_SNOWFLAKE " %s", GstToolkit::time_to_string(mp->position()).c_str() );
|
ImGui::Text( ICON_FA_SNOWFLAKE " %s", GstToolkit::time_to_string(mp->position()).c_str() );
|
||||||
ImGui::PopFont();
|
ImGui::PopFont();
|
||||||
|
|
||||||
///
|
|
||||||
/// media player buttons bar (custom)
|
|
||||||
///
|
|
||||||
draw_list->AddRectFilled(bottom, bottom + ImVec2(rendersize.x, _buttons_height), ImGui::GetColorU32(ImGuiCol_FrameBg), _h_space);
|
|
||||||
|
|
||||||
// buttons style
|
|
||||||
ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(1.f, 1.f, 1.f, 1.0f));
|
|
||||||
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0.00f, 0.00f, 0.00f, 0.00f));
|
|
||||||
ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImVec4(0.14f, 0.14f, 0.14f, 0.5f));
|
|
||||||
ImGui::PushStyleColor(ImGuiCol_FrameBg, ImVec4(0.24f, 0.24f, 0.24f, 0.2f));
|
|
||||||
ImGui::PushStyleColor(ImGuiCol_FrameBgHovered, ImVec4(0.14f, 0.14f, 0.14f, 0.5f));
|
|
||||||
|
|
||||||
ImGui::SetCursorScreenPos(bottom + ImVec2(_h_space, _v_space) );
|
|
||||||
if (ImGui::Button(mp->playSpeed() > 0 ? ICON_FA_FAST_BACKWARD :ICON_FA_FAST_FORWARD))
|
|
||||||
mp->rewind();
|
|
||||||
|
|
||||||
// ignore actual play status of mediaplayer when slider is pressed
|
|
||||||
if (!slider_pressed_)
|
|
||||||
media_playing_mode_ = mp->isPlaying();
|
|
||||||
|
|
||||||
// display buttons Play/Stop depending on current playing mode
|
|
||||||
ImGui::SameLine(0, _h_space);
|
|
||||||
if (media_playing_mode_) {
|
|
||||||
if (ImGui::Button(ICON_FA_PAUSE))
|
|
||||||
media_playing_mode_ = false;
|
|
||||||
ImGui::SameLine(0, _h_space);
|
|
||||||
|
|
||||||
ImGui::PushButtonRepeat(true);
|
|
||||||
if (ImGui::Button( mp->playSpeed() < 0 ? ICON_FA_BACKWARD :ICON_FA_FORWARD))
|
|
||||||
mp->jump ();
|
|
||||||
ImGui::PopButtonRepeat();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if (ImGui::Button(ICON_FA_PLAY))
|
|
||||||
media_playing_mode_ = true;
|
|
||||||
ImGui::SameLine(0, _h_space);
|
|
||||||
|
|
||||||
ImGui::PushButtonRepeat(true);
|
|
||||||
if (ImGui::Button( mp->playSpeed() < 0 ? ICON_FA_STEP_BACKWARD : ICON_FA_STEP_FORWARD))
|
|
||||||
mp->step();
|
|
||||||
ImGui::PopButtonRepeat();
|
|
||||||
}
|
|
||||||
|
|
||||||
// loop modes button
|
|
||||||
ImGui::SameLine(0, _h_space);
|
|
||||||
static int current_loop = 0;
|
|
||||||
static std::vector< std::pair<int, int> > iconsloop = { {0,15}, {1,15}, {19,14} };
|
|
||||||
current_loop = (int) mp->loop();
|
|
||||||
if ( ImGuiToolkit::ButtonIconMultistate(iconsloop, ¤t_loop) )
|
|
||||||
mp->setLoop( (MediaPlayer::LoopMode) current_loop );
|
|
||||||
|
|
||||||
|
|
||||||
std::ostringstream oss;
|
|
||||||
oss << SystemToolkit::base_filename( mp->filename() );
|
|
||||||
|
|
||||||
// speed slider (if enough space)
|
|
||||||
float speed = static_cast<float>(mp->playSpeed());
|
|
||||||
if ( rendersize.x > _min_width * 1.4f ) {
|
|
||||||
ImGui::SameLine(0, MAX(_h_space * 2.f, rendersize.x - _min_width * 1.6f) );
|
|
||||||
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x - _buttons_height );
|
|
||||||
if (ImGui::DragFloat( "##Speed", &speed, 0.01f, -10.f, 10.f, "Speed " UNICODE_MULTIPLY " %.1f", 2.f))
|
|
||||||
mp->setPlaySpeed( static_cast<double>(speed) );
|
|
||||||
|
|
||||||
if (ImGui::IsItemDeactivatedAfterEdit()){
|
|
||||||
oss << ": Speed x" << std::setprecision(3) << speed;
|
|
||||||
Action::manager().store(oss.str());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
///
|
|
||||||
/// Media Player context menu
|
|
||||||
///
|
|
||||||
ImGui::SameLine();
|
|
||||||
ImGui::SetCursorPosX(rendersize.x - _buttons_height / 1.5f);
|
|
||||||
|
|
||||||
// Timeline popup menu
|
|
||||||
if (ImGuiToolkit::IconButton(5,8) )
|
|
||||||
ImGui::OpenPopup( "MenuTimeline" );
|
|
||||||
if (ImGui::BeginPopup( "MenuTimeline" ))
|
|
||||||
{
|
|
||||||
if (ImGuiToolkit::MenuItemIcon(19,15,"Reset speed" )){
|
|
||||||
speed = 1.f;
|
|
||||||
mp->setPlaySpeed( static_cast<double>(speed) );
|
|
||||||
oss << ": Speed x1";
|
|
||||||
Action::manager().store(oss.str());
|
|
||||||
}
|
|
||||||
if (ImGui::MenuItem(ICON_FA_WINDOW_CLOSE " Reset timeline" )){
|
|
||||||
timeline_zoom = 1.f;
|
|
||||||
mp->timeline()->clearFading();
|
|
||||||
mp->timeline()->clearGaps();
|
|
||||||
oss << ": Reset timeline";
|
|
||||||
Action::manager().store(oss.str());
|
|
||||||
}
|
|
||||||
if (ImGui::BeginMenu(ICON_FA_RANDOM " Auto fading"))
|
|
||||||
{
|
|
||||||
const char* names[] = { "250 ms", "500 ms", "1 second", "2 seconds"};
|
|
||||||
for (int i = 0; i < IM_ARRAYSIZE(names); ++i) {
|
|
||||||
if (ImGui::MenuItem(names[i])) {
|
|
||||||
mp->timeline()->autoFading( 250 * (int ) pow(2, i) );
|
|
||||||
mp->timeline()->smoothFading( 2 * (i + 1) );
|
|
||||||
oss << ": Timeline Auto fading " << 250 * (int ) pow(2, i);
|
|
||||||
Action::manager().store(oss.str());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ImGui::EndMenu();
|
|
||||||
}
|
|
||||||
if (ImGui::BeginMenu(ICON_FA_CUT " Auto cut" )){
|
|
||||||
|
|
||||||
if (ImGuiToolkit::MenuItemIcon(14, 12, "Cut faded areas" ))
|
|
||||||
if (mp->timeline()->autoCut()){
|
|
||||||
oss << ": Cut faded areas";
|
|
||||||
Action::manager().store(oss.str());
|
|
||||||
}
|
|
||||||
|
|
||||||
ImGui::EndMenu();
|
|
||||||
}
|
|
||||||
if (Settings::application.render.gpu_decoding && ImGui::BeginMenu(ICON_FA_MICROCHIP " Hardware decoding"))
|
|
||||||
{
|
|
||||||
bool hwdec = !mp->softwareDecodingForced();
|
|
||||||
if (ImGui::MenuItem("Auto", "", &hwdec ))
|
|
||||||
mp->setSoftwareDecodingForced(false);
|
|
||||||
hwdec = mp->softwareDecodingForced();
|
|
||||||
if (ImGui::MenuItem("Disabled", "", &hwdec ))
|
|
||||||
mp->setSoftwareDecodingForced(true);
|
|
||||||
ImGui::EndMenu();
|
|
||||||
}
|
|
||||||
ImGui::EndPopup();
|
|
||||||
}
|
|
||||||
|
|
||||||
// restore buttons style
|
|
||||||
ImGui::PopStyleColor(5);
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// media player timelines
|
/// media player timelines
|
||||||
///
|
///
|
||||||
bottom += ImVec2(0, _buttons_height + _v_space);
|
|
||||||
ImGui::SetCursorScreenPos(bottom);
|
// ignore actual play status of mediaplayer when slider is pressed
|
||||||
|
if (!slider_pressed_)
|
||||||
|
media_playing_mode_ = mp->isPlaying();
|
||||||
|
|
||||||
// seek position
|
// seek position
|
||||||
guint64 seek_t = mp->position();
|
guint64 seek_t = mp->position();
|
||||||
@@ -2972,6 +2853,7 @@ void SourceController::RenderMediaPlayer(MediaPlayer *mp)
|
|||||||
// scrolling sub-window
|
// scrolling sub-window
|
||||||
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(1.f, 1.f));
|
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(1.f, 1.f));
|
||||||
ImGui::PushStyleVar(ImGuiStyleVar_FrameRounding, 1.f);
|
ImGui::PushStyleVar(ImGuiStyleVar_FrameRounding, 1.f);
|
||||||
|
ImGui::PushStyleColor(ImGuiCol_ScrollbarBg, ImVec4(0.f, 0.f, 0.f, 0.0f));
|
||||||
|
|
||||||
ImVec2 scrollwindow = ImVec2(ImGui::GetContentRegionAvail().x - slider_zoom_width - 3.0,
|
ImVec2 scrollwindow = ImVec2(ImGui::GetContentRegionAvail().x - slider_zoom_width - 3.0,
|
||||||
2.f * _timeline_height + _scrollbar );
|
2.f * _timeline_height + _scrollbar );
|
||||||
@@ -3063,6 +2945,135 @@ void SourceController::RenderMediaPlayer(MediaPlayer *mp)
|
|||||||
ImGui::VSliderFloat("##TimelineZoom", ImVec2(slider_zoom_width, _timeline_height), &timeline_zoom, 1.0, 5.f, "");
|
ImGui::VSliderFloat("##TimelineZoom", ImVec2(slider_zoom_width, _timeline_height), &timeline_zoom, 1.0, 5.f, "");
|
||||||
|
|
||||||
ImGui::PopStyleVar(2);
|
ImGui::PopStyleVar(2);
|
||||||
|
ImGui::PopStyleColor(1);
|
||||||
|
|
||||||
|
|
||||||
|
///
|
||||||
|
/// media player buttons bar (custom)
|
||||||
|
///
|
||||||
|
|
||||||
|
bottom.x = top.x;
|
||||||
|
bottom.y += 2.f * _timeline_height + _scrollbar;
|
||||||
|
|
||||||
|
draw_list->AddRectFilled(bottom, bottom + ImVec2(rendersize.x, _buttons_height), ImGui::GetColorU32(ImGuiCol_FrameBg), _h_space);
|
||||||
|
|
||||||
|
// buttons style
|
||||||
|
ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(1.f, 1.f, 1.f, 1.0f));
|
||||||
|
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0.00f, 0.00f, 0.00f, 0.00f));
|
||||||
|
ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImVec4(0.14f, 0.14f, 0.14f, 0.5f));
|
||||||
|
ImGui::PushStyleColor(ImGuiCol_FrameBg, ImVec4(0.24f, 0.24f, 0.24f, 0.2f));
|
||||||
|
ImGui::PushStyleColor(ImGuiCol_FrameBgHovered, ImVec4(0.14f, 0.14f, 0.14f, 0.5f));
|
||||||
|
|
||||||
|
ImGui::SetCursorScreenPos(bottom + ImVec2(_h_space, _v_space) );
|
||||||
|
if (ImGui::Button(mp->playSpeed() > 0 ? ICON_FA_FAST_BACKWARD :ICON_FA_FAST_FORWARD))
|
||||||
|
mp->rewind();
|
||||||
|
|
||||||
|
// display buttons Play/Stop depending on current playing mode
|
||||||
|
ImGui::SameLine(0, _h_space);
|
||||||
|
if (media_playing_mode_) {
|
||||||
|
if (ImGui::Button(ICON_FA_PAUSE))
|
||||||
|
media_playing_mode_ = false;
|
||||||
|
ImGui::SameLine(0, _h_space);
|
||||||
|
|
||||||
|
ImGui::PushButtonRepeat(true);
|
||||||
|
if (ImGui::Button( mp->playSpeed() < 0 ? ICON_FA_BACKWARD :ICON_FA_FORWARD))
|
||||||
|
mp->jump ();
|
||||||
|
ImGui::PopButtonRepeat();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (ImGui::Button(ICON_FA_PLAY))
|
||||||
|
media_playing_mode_ = true;
|
||||||
|
ImGui::SameLine(0, _h_space);
|
||||||
|
|
||||||
|
ImGui::PushButtonRepeat(true);
|
||||||
|
if (ImGui::Button( mp->playSpeed() < 0 ? ICON_FA_STEP_BACKWARD : ICON_FA_STEP_FORWARD))
|
||||||
|
mp->step();
|
||||||
|
ImGui::PopButtonRepeat();
|
||||||
|
}
|
||||||
|
|
||||||
|
// loop modes button
|
||||||
|
ImGui::SameLine(0, _h_space);
|
||||||
|
static int current_loop = 0;
|
||||||
|
static std::vector< std::pair<int, int> > iconsloop = { {0,15}, {1,15}, {19,14} };
|
||||||
|
current_loop = (int) mp->loop();
|
||||||
|
if ( ImGuiToolkit::ButtonIconMultistate(iconsloop, ¤t_loop) )
|
||||||
|
mp->setLoop( (MediaPlayer::LoopMode) current_loop );
|
||||||
|
|
||||||
|
// speed slider (if enough space)
|
||||||
|
float speed = static_cast<float>(mp->playSpeed());
|
||||||
|
if ( rendersize.x > _min_width * 1.4f ) {
|
||||||
|
ImGui::SameLine(0, MAX(_h_space * 2.f, rendersize.x - _min_width * 1.6f) );
|
||||||
|
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x - _buttons_height );
|
||||||
|
if (ImGui::DragFloat( "##Speed", &speed, 0.01f, -10.f, 10.f, "Speed " UNICODE_MULTIPLY " %.1f", 2.f))
|
||||||
|
mp->setPlaySpeed( static_cast<double>(speed) );
|
||||||
|
|
||||||
|
if (ImGui::IsItemDeactivatedAfterEdit()){
|
||||||
|
oss << ": Speed x" << std::setprecision(3) << speed;
|
||||||
|
Action::manager().store(oss.str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Media Player context menu
|
||||||
|
///
|
||||||
|
ImGui::SameLine();
|
||||||
|
ImGui::SetCursorPosX(rendersize.x - _buttons_height / 1.5f);
|
||||||
|
|
||||||
|
// Timeline popup menu
|
||||||
|
if (ImGuiToolkit::IconButton(5,8) )
|
||||||
|
ImGui::OpenPopup( "MenuTimeline" );
|
||||||
|
if (ImGui::BeginPopup( "MenuTimeline" ))
|
||||||
|
{
|
||||||
|
if (ImGuiToolkit::MenuItemIcon(19,15,"Reset speed" )){
|
||||||
|
speed = 1.f;
|
||||||
|
mp->setPlaySpeed( static_cast<double>(speed) );
|
||||||
|
oss << ": Speed x1";
|
||||||
|
Action::manager().store(oss.str());
|
||||||
|
}
|
||||||
|
if (ImGui::MenuItem(ICON_FA_WINDOW_CLOSE " Reset timeline" )){
|
||||||
|
timeline_zoom = 1.f;
|
||||||
|
mp->timeline()->clearFading();
|
||||||
|
mp->timeline()->clearGaps();
|
||||||
|
oss << ": Reset timeline";
|
||||||
|
Action::manager().store(oss.str());
|
||||||
|
}
|
||||||
|
if (ImGui::BeginMenu(ICON_FA_RANDOM " Auto fading"))
|
||||||
|
{
|
||||||
|
const char* names[] = { "250 ms", "500 ms", "1 second", "2 seconds"};
|
||||||
|
for (int i = 0; i < IM_ARRAYSIZE(names); ++i) {
|
||||||
|
if (ImGui::MenuItem(names[i])) {
|
||||||
|
mp->timeline()->autoFading( 250 * (int ) pow(2, i) );
|
||||||
|
mp->timeline()->smoothFading( 2 * (i + 1) );
|
||||||
|
oss << ": Timeline Auto fading " << 250 * (int ) pow(2, i);
|
||||||
|
Action::manager().store(oss.str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ImGui::EndMenu();
|
||||||
|
}
|
||||||
|
if (ImGui::BeginMenu(ICON_FA_CUT " Auto cut" ))
|
||||||
|
{
|
||||||
|
if (ImGuiToolkit::MenuItemIcon(14, 12, "Cut faded areas" ))
|
||||||
|
if (mp->timeline()->autoCut()){
|
||||||
|
oss << ": Cut faded areas";
|
||||||
|
Action::manager().store(oss.str());
|
||||||
|
}
|
||||||
|
ImGui::EndMenu();
|
||||||
|
}
|
||||||
|
if (Settings::application.render.gpu_decoding && ImGui::BeginMenu(ICON_FA_MICROCHIP " Hardware decoding"))
|
||||||
|
{
|
||||||
|
bool hwdec = !mp->softwareDecodingForced();
|
||||||
|
if (ImGui::MenuItem("Auto", "", &hwdec ))
|
||||||
|
mp->setSoftwareDecodingForced(false);
|
||||||
|
hwdec = mp->softwareDecodingForced();
|
||||||
|
if (ImGui::MenuItem("Disabled", "", &hwdec ))
|
||||||
|
mp->setSoftwareDecodingForced(true);
|
||||||
|
ImGui::EndMenu();
|
||||||
|
}
|
||||||
|
ImGui::EndPopup();
|
||||||
|
}
|
||||||
|
|
||||||
|
// restore buttons style
|
||||||
|
ImGui::PopStyleColor(5);
|
||||||
|
|
||||||
///
|
///
|
||||||
/// media player timeline actions
|
/// media player timeline actions
|
||||||
@@ -3080,6 +3091,7 @@ void SourceController::RenderMediaPlayer(MediaPlayer *mp)
|
|||||||
if ( mp->isPlaying() != media_play ) {
|
if ( mp->isPlaying() != media_play ) {
|
||||||
mp->play( media_play );
|
mp->play( media_play );
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *SourceController::SourcePlayIcon(Source *s)
|
const char *SourceController::SourcePlayIcon(Source *s)
|
||||||
|
|||||||
Reference in New Issue
Block a user