work-in progress Helper and keyboard shortcuts

This commit is contained in:
Bruno
2021-08-26 15:51:07 +02:00
parent 7fb6e57829
commit 06187b9a1a
9 changed files with 350 additions and 52 deletions

View File

@@ -291,6 +291,7 @@ set(VMIX_SRCS
SessionVisitor.cpp
Interpolator.cpp
SessionCreator.cpp
SessionParser.cpp
Mixer.cpp
FrameGrabber.cpp
Recorder.cpp

View File

@@ -297,7 +297,7 @@ struct Sum
int sum{0};
};
bool ImGuiToolkit::ButtonIconMultistate(std::vector<std::pair<int, int> > icons, int* state)
bool ImGuiToolkit::ButtonIconMultistate(std::vector<std::pair<int, int> > icons, int* state, const char* tooltip)
{
bool ret = false;
Sum id = std::for_each(icons.begin(), icons.end(), Sum());
@@ -305,7 +305,7 @@ bool ImGuiToolkit::ButtonIconMultistate(std::vector<std::pair<int, int> > icons,
int num_button = static_cast<int>(icons.size()) -1;
int s = CLAMP(*state, 0, num_button);
if ( ButtonIcon( icons[s].first, icons[s].second ) ){
if ( ButtonIcon( icons[s].first, icons[s].second, tooltip ) ){
++s;
if (s > num_button)
*state = 0;

View File

@@ -20,7 +20,7 @@ namespace ImGuiToolkit
// buttons and gui items with icon
bool ButtonIcon (int i, int j, const char* tooltip = nullptr);
bool ButtonIconToggle (int i, int j, int i_toggle, int j_toggle, bool* toggle);
bool ButtonIconMultistate (std::vector<std::pair<int, int> > icons, int* state);
bool ButtonIconMultistate (std::vector<std::pair<int, int> > icons, int* state, const char* tooltip = nullptr);
bool MenuItemIcon (int i, int j, const char* label, bool selected = false, bool enabled = true);
bool SelectableIcon(const char* label, int i, int j, bool selected = false);
bool ComboIcon (std::vector<std::pair<int, int> > icons, std::vector<std::string> labels, int* state);

111
SessionParser.cpp Normal file
View File

@@ -0,0 +1,111 @@
#include "SessionParser.h"
using namespace tinyxml2;
#include "SystemToolkit.h"
#include "tinyxml2Toolkit.h"
SessionParser::SessionParser()
{
}
bool SessionParser::open(const std::string &filename)
{
// if the file exists
if (filename.empty() || !SystemToolkit::file_exists(filename))
return false;
// try to load the file
xmlDoc_.Clear();
XMLError eResult = xmlDoc_.LoadFile(filename.c_str());
// error
if ( XMLResultError(eResult, false) )
return false;
filename_ = filename;
return true;
}
bool SessionParser::save()
{
if (filename_.empty())
return false;
// save file to disk
return ( XMLSaveDoc(&xmlDoc_, filename_) );
}
std::map< uint64_t, std::pair<std::string, bool> > SessionParser::pathList() const
{
std::map< uint64_t, std::pair<std::string, bool> > paths;
// fill path list
const XMLElement *session = xmlDoc_.FirstChildElement("Session");
if (session != nullptr ) {
const XMLElement *sourceNode = session->FirstChildElement("Source");
for( ; sourceNode ; sourceNode = sourceNode->NextSiblingElement())
{
// get id
uint64_t sid = 0;
sourceNode->QueryUnsigned64Attribute("id", &sid);
// get path
const XMLElement* pathNode = nullptr;
pathNode = sourceNode->FirstChildElement("uri");
if (!pathNode)
pathNode = sourceNode->FirstChildElement("path");
if (!pathNode)
pathNode = sourceNode->FirstChildElement("Sequence");
if (pathNode) {
const char *text = pathNode->GetText();
if (text) {
bool exists = SystemToolkit::file_exists(text);
paths[sid] = std::pair<std::string, bool>(std::string(text), exists);
}
}
}
}
// return path list
return paths;
}
void SessionParser::replacePath(uint64_t id, const std::string &path)
{
XMLElement *session = xmlDoc_.FirstChildElement("Session");
if (session != nullptr ) {
XMLElement *sourceNode = session->FirstChildElement("Source");
for( ; sourceNode ; sourceNode = sourceNode->NextSiblingElement())
{
// get id
uint64_t sid = 0;
sourceNode->QueryUnsigned64Attribute("id", &sid);
if (sid == id) {
// get path
XMLElement* pathNode = nullptr;
pathNode = sourceNode->FirstChildElement("uri");
if (!pathNode)
pathNode = sourceNode->FirstChildElement("path");
if (!pathNode)
pathNode = sourceNode->FirstChildElement("Sequence");
if (pathNode) {
XMLText *text = xmlDoc_.NewText( path.c_str() );
pathNode->InsertEndChild( text );
}
break;
}
}
}
}

40
SessionParser.h Normal file
View File

@@ -0,0 +1,40 @@
#ifndef SESSIONPARSER_H
#define SESSIONPARSER_H
#include <map>
#include <string>
#include <tinyxml2.h>
class Session;
//struct SessionInformation {
// std::string description;
// FrameBufferImage *thumbnail;
// bool user_thumbnail_;
// SessionInformation() {
// description = "";
// thumbnail = nullptr;
// user_thumbnail_ = false;
// }
//};
class SessionParser
{
public:
SessionParser();
bool open(const std::string& filename);
bool save();
std::map<uint64_t, std::pair<std::string, bool> > pathList() const;
void replacePath(uint64_t id, const std::string &path);
// static SessionInformation info(const std::string& filename);
private:
tinyxml2::XMLDocument xmlDoc_;
std::string filename_;
};
#endif // SESSIONPARSER_H

View File

@@ -29,6 +29,7 @@ struct WidgetsConfig
bool shader_editor;
bool toolbox;
bool history;
bool help;
WidgetsConfig() {
stats = false;
@@ -43,6 +44,7 @@ struct WidgetsConfig
timeline_editmode = false;
shader_editor = false;
toolbox = false;
help = false;
}
};

View File

@@ -72,7 +72,7 @@ TextEditor editor;
#define PLOT_ARRAY_SIZE 180
#define LABEL_AUTO_MEDIA_PLAYER ICON_FA_CARET_SQUARE_RIGHT " Dynamic selection"
#define LABEL_STORE_SELECTION " Store selection"
#define LABEL_EDIT_FADING ICON_FA_RANDOM " Edit timeline fading"
#define LABEL_EDIT_FADING ICON_FA_RANDOM " Fade in & out"
// utility functions
void ShowAboutGStreamer(bool* p_open);
@@ -222,7 +222,7 @@ void UserInterface::handleKeyboard()
Mixer::manager().close();
}
else if (ImGui::IsKeyPressed( GLFW_KEY_SPACE )) {
// New Session
// Suspend / unsuspend session
Mixer::manager().session()->setActive( !Mixer::manager().session()->active() );
}
else if (ImGui::IsKeyPressed( GLFW_KEY_L )) {
@@ -230,15 +230,19 @@ void UserInterface::handleKeyboard()
Settings::application.widget.logs = !Settings::application.widget.logs;
}
else if (ImGui::IsKeyPressed( GLFW_KEY_T )) {
// Logs
// Developer toolbox
Settings::application.widget.toolbox = !Settings::application.widget.toolbox;
}
else if (ImGui::IsKeyPressed( GLFW_KEY_H )) {
// Session toolbox
// Settings::application.widget.help = !Settings::application.widget.help;
}
else if (ImGui::IsKeyPressed( GLFW_KEY_E )) {
// Shader Editor
Settings::application.widget.shader_editor = !Settings::application.widget.shader_editor;
}
else if (ImGui::IsKeyPressed( GLFW_KEY_D )) {
// Logs
// Display output
Settings::application.widget.preview = !Settings::application.widget.preview;
if (Settings::application.widget.preview_view != Settings::application.current_view) {
Settings::application.widget.preview_view = -1;
@@ -246,7 +250,7 @@ void UserInterface::handleKeyboard()
}
}
else if (ImGui::IsKeyPressed( GLFW_KEY_P )) {
// Logs
// Media player
Settings::application.widget.media_player = !Settings::application.widget.media_player;
if (Settings::application.widget.media_player_view != Settings::application.current_view) {
Settings::application.widget.media_player_view = -1;
@@ -317,7 +321,7 @@ void UserInterface::handleKeyboard()
// No CTRL modifier
else {
ctrl_modifier_active = false;
Source *_cs = Mixer::manager().currentSource();
// Source *_cs = Mixer::manager().currentSource();
// Application F-Keys
if (ImGui::IsKeyPressed( GLFW_KEY_F1 ))
@@ -361,28 +365,38 @@ void UserInterface::handleKeyboard()
}
}
// keys to control the current source if media player is not focused
if (_cs != nullptr && _cs->active() && (!ImGui::IsAnyWindowFocused() || sourcecontrol.Active()) )
{
// Space bar to toggle play / pause
if (ImGui::IsKeyPressed( GLFW_KEY_SPACE )) {
_cs->play( !_cs->playing() );
}
if (ImGui::IsKeyPressed( GLFW_KEY_SPACE ))
sourcecontrol.Play();
// B to rewind to Beginning
else if (ImGui::IsKeyPressed( GLFW_KEY_B )) {
_cs->replay();
}
else if (ImGui::IsKeyPressed( GLFW_KEY_B ))
sourcecontrol.Replay();
// N for Next frame or fast forward
else if (ImGui::IsKeyPressed( GLFW_KEY_N )) {
MediaSource *ms = dynamic_cast<MediaSource *>(_cs);
if ( ms != nullptr ) {
if (ms->playing())
ms->mediaplayer()->jump();
else
ms->mediaplayer()->step();
}
}
}
else if (ImGui::IsKeyPressed( GLFW_KEY_N ))
sourcecontrol.Next();
// // keys to control the current source if media player is not focused
// if (_cs != nullptr && _cs->active() && (!ImGui::IsAnyWindowFocused() || sourcecontrol.Active()) )
// {
// // Space bar to toggle play / pause
// if (ImGui::IsKeyPressed( GLFW_KEY_SPACE )) {
// _cs->play( !_cs->playing() );
// }
// // B to rewind to Beginning
// else if (ImGui::IsKeyPressed( GLFW_KEY_B )) {
// _cs->replay();
// }
// // N for Next frame or fast forward
// else if (ImGui::IsKeyPressed( GLFW_KEY_N )) {
// MediaSource *ms = dynamic_cast<MediaSource *>(_cs);
// if ( ms != nullptr ) {
// if (ms->playing())
// ms->mediaplayer()->jump();
// else
// ms->mediaplayer()->step();
// }
// }
// }
// normal keys in workspace // make sure no entry / window box is active
if ( !ImGui::IsAnyWindowFocused() )
@@ -759,13 +773,20 @@ void UserInterface::Render()
RenderPreview();
if (Settings::application.widget.history)
RenderHistory();
if (Settings::application.widget.media_player && ( Settings::application.widget.media_player_view < 0 ||
Settings::application.widget.media_player_view == Settings::application.current_view ))
sourcecontrol.Render();
if (Settings::application.widget.shader_editor)
RenderShaderEditor();
if (Settings::application.widget.logs)
Log::ShowLogWindow(&Settings::application.widget.logs);
if (Settings::application.widget.help)
sessiontoolbox.Render();
// Source controller
sourcecontrol.Update();
if (Settings::application.widget.media_player && ( Settings::application.widget.media_player_view < 0 ||
Settings::application.widget.media_player_view == Settings::application.current_view ))
sourcecontrol.Render();
// Notes
RenderNotes();
// dialogs
@@ -1955,11 +1976,67 @@ void ToolBox::Render()
}
///
/// SESSION REPAIR WINDOW
///
HelperToolbox::HelperToolbox()
{
}
void HelperToolbox::Render()
{
// first run
ImGui::SetNextWindowPos(ImVec2(40, 40), ImGuiCond_FirstUseEver);
ImGui::SetNextWindowSize(ImVec2(400, 300), ImGuiCond_FirstUseEver);
ImGui::SetNextWindowSizeConstraints(ImVec2(350, 300), ImVec2(FLT_MAX, FLT_MAX));
if ( !ImGui::Begin(IMGUI_TITLE_HELP, &Settings::application.widget.help) )
{
ImGui::End();
return;
}
if (ImGui::CollapsingHeader("File repair"))
{
}
if (ImGui::CollapsingHeader("Keyboard shortcuts"))
{
ImGui::Columns(2, "mycolumns"); // 4-ways, with border
ImGui::Text("HOME"); ImGui::NextColumn();
ImGui::Text("Main menu"); ImGui::NextColumn();
ImGui::Text("INS"); ImGui::NextColumn();
ImGui::Text("New source"); ImGui::NextColumn();
ImGui::Text("F1"); ImGui::NextColumn();
ImGui::Text("Mixing view"); ImGui::NextColumn();
ImGui::Text("F2"); ImGui::NextColumn();
ImGui::Text("Geometry view"); ImGui::NextColumn();
ImGui::Text("F3"); ImGui::NextColumn();
ImGui::Text("Layers view"); ImGui::NextColumn();
ImGui::Text("F4"); ImGui::NextColumn();
ImGui::Text("Texturing view"); ImGui::NextColumn();
ImGui::Text(CTRL_MOD "TAB"); ImGui::NextColumn();
ImGui::Text("Change view"); ImGui::NextColumn();
ImGui::Separator();
ImGui::Text("Ctrl + O"); ImGui::NextColumn();
ImGui::Text("Open Session file"); ImGui::NextColumn();
ImGui::Separator();
ImGui::Columns(1);
}
ImGui::End();
}
///
/// SOURCE CONTROLLER
///
SourceController::SourceController() : focused_(false), min_width_(0.f), h_space_(0.f), v_space_(0.f), buttons_height_(0.f),
timeline_height_(0.f), scrollbar_(0.f), mediaplayer_height_(0.f), buttons_width_(0.f),
play_request_(false), replay_request_(false), next_request_(false),
active_label_(LABEL_AUTO_MEDIA_PLAYER), active_selection_(-1),
selection_context_menu_(false), selection_mediaplayer_(nullptr), selection_target_slower_(0), selection_target_faster_(0),
mediaplayer_active_(nullptr), mediaplayer_edit_fading_(false), mediaplayer_mode_(false), mediaplayer_slider_pressed_(false), mediaplayer_timeline_zoom_(1.f)
@@ -1983,7 +2060,7 @@ bool SourceController::Active()
&& focused_);
}
void SourceController::Render()
void SourceController::Update()
{
// reset on session change
static Session *__session = nullptr;
@@ -1992,6 +2069,39 @@ void SourceController::Render()
resetActiveSelection();
}
// Play button or keyboard [space] was pressed
if ( play_request_ ) {
// active selection
if (active_selection_ > -1){
}
// selected sources
else {
}
play_request_ = false;
}
// Replay / rewind button or keyboard [B] was pressed
if ( replay_request_ ) {
replay_request_ = false;
}
// Next frame / FFwrd button or keyboard [N] was pressed
if ( next_request_ ) {
next_request_ = false;
}
}
void SourceController::Render()
{
ImGui::SetNextWindowPos(ImVec2(1180, 400), ImGuiCond_FirstUseEver);
ImGui::SetNextWindowSize(ImVec2(400, 400), ImGuiCond_FirstUseEver);
@@ -2032,6 +2142,19 @@ void SourceController::Render()
}
if (ImGui::BeginMenu(IMGUI_TITLE_MEDIAPLAYER))
{
// Menu section for play control
if (ImGui::MenuItem( ICON_FA_FAST_BACKWARD " Back", "B")) {
}
if (ImGui::MenuItem( ICON_FA_PLAY " Play | Pause", "Space")) {
}
if (ImGui::MenuItem( ICON_FA_STEP_FORWARD " Next frame | forward", "N")) {
}
// Menu section for list
ImGui::Separator();
if (ImGui::MenuItem( ICON_FA_TH " List all")) {
selection_.clear();
resetActiveSelection();
@@ -2045,7 +2168,7 @@ void SourceController::Render()
Mixer::manager().unsetCurrentSource();
Mixer::selection().clear();
}
// Menu section for window management
ImGui::Separator();
bool pinned = Settings::application.widget.media_player_view == Settings::application.current_view;
if ( ImGui::MenuItem( ICON_FA_MAP_PIN " Pin window to view", nullptr, &pinned) ){
@@ -2114,9 +2237,16 @@ void SourceController::Render()
if (ImGui::MenuItem(LABEL_EDIT_FADING))
mediaplayer_edit_fading_ = true;
bool option = mediaplayer_active_->rewindOnDisabled();
if (ImGui::MenuItem(ICON_FA_FAST_BACKWARD " " ICON_FA_SNOWFLAKE " Rewind when Inactive" , NULL, &option))
mediaplayer_active_->setRewindOnDisabled(option);
if (ImGui::BeginMenu(ICON_FA_SNOWFLAKE " Inactive"))
{
bool option = !mediaplayer_active_->rewindOnDisabled();
if (ImGui::MenuItem(ICON_FA_STOP " Stop", "", &option ))
mediaplayer_active_->setRewindOnDisabled(false);
option = mediaplayer_active_->rewindOnDisabled();
if (ImGui::MenuItem(ICON_FA_FAST_BACKWARD " Rewind & Stop", "", &option ))
mediaplayer_active_->setRewindOnDisabled(true);
ImGui::EndMenu();
}
// if (ImGui::BeginMenu(ICON_FA_CUT " Auto cut" ))
// {
@@ -2819,15 +2949,6 @@ void SourceController::RenderSingleSource(Source *s)
ImGui::Text("%s %s", SourcePlayIcon(s), GstToolkit::time_to_string(s->playtime()).c_str() );
ImGui::PopFont();
// if ( ms != nullptr ) {
// // ok, get the media player of the media source
// MediaPlayer *mp = ms->mediaplayer();
// const double width_ratio = static_cast<double>(rendersize.x) / static_cast<double>(mp->timeline()->sectionsDuration());
// DrawTimeline("##timeline_mediaplayers", mp->timeline(), mp->position(), width_ratio, 60);
// }
///
/// Play button bar
///
@@ -3066,7 +3187,7 @@ void SourceController::RenderMediaPlayer(MediaPlayer *mp)
static int current_loop = 0;
static std::vector< std::pair<int, int> > iconsloop = { {0,15}, {1,15}, {19,14} };
current_loop = (int) mediaplayer_active_->loop();
if ( ImGuiToolkit::ButtonIconMultistate(iconsloop, &current_loop) )
if ( ImGuiToolkit::ButtonIconMultistate(iconsloop, &current_loop, "Loop mode") )
mediaplayer_active_->setLoop( (MediaPlayer::LoopMode) current_loop );
// speed slider (if enough space)
@@ -4143,6 +4264,9 @@ void Navigator::RenderMainPannelVimix()
{
// Show info text bloc (dark background)
ImGuiTextBuffer info;
if (sessionfilename.empty())
info.appendf("<unsaved>");
else
info.appendf("%s", SystemToolkit::filename(sessionfilename).c_str());
ImGui::PushStyleColor(ImGuiCol_FrameBg, ImVec4(0.14f, 0.14f, 0.14f, 0.9f));
ImGui::SetNextItemWidth(IMGUI_RIGHT_ALIGN);

View File

@@ -13,6 +13,8 @@
#include "SourceList.h"
#include "InfoVisitor.h"
#include "DialogToolkit.h"
#include "SessionParser.h"
struct ImVec2;
class MediaPlayer;
@@ -105,6 +107,16 @@ public:
void Render();
};
class HelperToolbox
{
SessionParser parser_;
public:
HelperToolbox();
void Render();
};
class SourceController
{
@@ -118,6 +130,7 @@ class SourceController
float scrollbar_;
float mediaplayer_height_;
bool play_request_, replay_request_, next_request_;
std::string active_label_;
int active_selection_;
InfoVisitor info_;
@@ -153,6 +166,11 @@ class SourceController
public:
SourceController();
inline void Play() { play_request_=true; }
inline void Replay() { replay_request_=true;}
inline void Next() { next_request_=true; }
void Update();
void resetActiveSelection();
void Render();
bool Active();
@@ -165,6 +183,7 @@ class UserInterface
Navigator navigator;
ToolBox toolbox;
SourceController sourcecontrol;
HelperToolbox sessiontoolbox;
bool ctrl_modifier_active;
bool alt_modifier_active;

View File

@@ -66,6 +66,7 @@
#define IMGUI_TITLE_MEDIAPLAYER ICON_FA_PLAY_CIRCLE " Player"
#define IMGUI_TITLE_HISTORY ICON_FA_HISTORY " History"
#define IMGUI_TITLE_LOGS ICON_FA_LIST " Logs"
#define IMGUI_TITLE_HELP ICON_FA_LIFE_RING " Help"
#define IMGUI_TITLE_TOOLBOX ICON_FA_WRENCH " Development Toolbox"
#define IMGUI_TITLE_SHADEREDITOR ICON_FA_CODE " Code Editor"
#define IMGUI_TITLE_PREVIEW ICON_FA_DESKTOP " Ouput"