Linux Dialogs in GTK for SNAP compatibility

Discarding use of ZENITY under linux (previously used with the tinyfiledialog) because snapcraft makes  it impossible to use :(. Reimplementation of GTK+ dialogs directly inside vimix code. Note: no changes for OSX. Complete cleanup of cmake file.
This commit is contained in:
Bruno
2021-03-27 13:03:22 +01:00
parent 43d44634f7
commit ee2ce3802f
12 changed files with 650 additions and 178 deletions

View File

@@ -1,5 +1,5 @@
cmake_minimum_required(VERSION 3.8.0)
cmake_minimum_required(VERSION 3.8.2)
project(vimix VERSION 0.0.1 LANGUAGES CXX C)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
@@ -46,6 +46,9 @@ if(UNIX)
set(OpenGL_GL_PREFERENCE "GLVND")
find_package(GTK 3.0 REQUIRED)
macro_log_feature(GTK_FOUND "GTK" "GTK cross-platform widget toolkit" "http://www.gtk.org" TRUE)
endif()
add_definitions(-DUNIX)
elseif(WIN32)
@@ -54,9 +57,21 @@ elseif(WIN32)
endif()
# Include the CMake RC module
include(CMakeRC)
# Basics
set(CMAKE_THREAD_PREFER_PTHREAD TRUE)
find_package(Threads REQUIRED)
find_package(GLIB2)
macro_log_feature(GLIB2_FOUND "GLib" "GTK general-purpose utility library" "http://www.gtk.org" TRUE)
find_package(GObject)
macro_log_feature(GOBJECT_FOUND "GObject" "GTK object-oriented framework" "http://www.gtk.org" TRUE)
find_package(PNG REQUIRED)
macro_log_feature(PNG_FOUND "PNG" "Portable Network Graphics" "http://www.libpng.org" TRUE)
find_package(ICU REQUIRED COMPONENTS i18n io uc)
macro_log_feature(ICU_FOUND "ICU" "International Components for Unicode" "http://site.icu-project.org" TRUE)
#
# GSTREAMER
@@ -91,7 +106,6 @@ macro_log_feature(GSTREAMER_GL_LIBRARY_FOUND "GStreamer opengl library"
"${GSTREAMER_GL_LIBRARY}"
"http://gstreamer.freedesktop.org/" TRUE "1.0.0")
#find_package(GStreamerPluginsBad 1.0.0 COMPONENTS player)
#macro_log_feature(GSTREAMER_PLAYER_LIBRARY_FOUND "GStreamer player library"
#"${GSTREAMER_PLAYER_LIBRARY}"
@@ -101,22 +115,6 @@ macro_log_feature(GSTREAMER_GL_LIBRARY_FOUND "GStreamer opengl library"
# Various preprocessor definitions for GST
add_definitions(-DGST_DISABLE_XML -DGST_DISABLE_LOADSAVE)
# Basics
find_package(GLIB2)
macro_log_feature(GLIB2_FOUND "GLib" "GTK general-purpose utility library" "http://www.gtk.org/" TRUE)
find_package(GObject)
macro_log_feature(GOBJECT_FOUND "GObject" "GTK object-oriented framework" "http://www.gtk.org/" TRUE)
set(CMAKE_THREAD_PREFER_PTHREAD TRUE)
find_package(Threads REQUIRED)
set(THREAD_LIBRARY Threads::Threads)
find_package(PNG REQUIRED)
set(PNG_LIBRARY PNG::PNG)
find_package(ICU REQUIRED COMPONENTS i18n io uc)
macro_log_feature(ICU_FOUND "ICU" "International Components for Unicode" "http://site.icu-project.org" TRUE)
#
@@ -124,10 +122,10 @@ macro_log_feature(ICU_FOUND "ICU" "International Components for Unicode" "http:/
# NB: set glfw3_PATH to /usr/local/Cellar/glfw/3.3.2/lib/cmake/glfw3
#
find_package(glfw3 3.2 REQUIRED)
macro_log_feature(glfw3_FOUND "GLFW3" "Open Source multi-platform library for OpenGL" "http://www.glfw.org/" TRUE)
macro_log_feature(glfw3_FOUND "GLFW3" "Open Source multi-platform library for OpenGL" "http://www.glfw.org" TRUE)
set(GLFW_LIBRARY glfw)
#find_package(OpenGL REQUIRED)
macro_display_feature_log()
# static sub packages in ext
set(BUILD_STATIC_LIBS ON)
@@ -136,14 +134,14 @@ set(BUILD_STATIC_LIBS ON)
# GLM
#
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/ext/glm)
message(STATUS "Compiling 'GLM' OpenGL mathematics https://glm.g-truc.net.")
message(STATUS "Compiling 'GLM' OpenGL mathematics https://glm.g-truc.net")
#
# GLAD
#
set(GLAD_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/ext/glad/include)
add_library(GLAD "${CMAKE_CURRENT_SOURCE_DIR}/ext/glad/src/glad.c")
message(STATUS "Compiling 'GLAD' Open source multi-language OpenGL loader https://glad.dav1d.de/ -- ${GLAD_INCLUDE_DIR}.")
message(STATUS "Compiling 'GLAD' Open source multi-language OpenGL loader https://glad.dav1d.de -- ${GLAD_INCLUDE_DIR}.")
#
# DEAR IMGUI
@@ -198,7 +196,6 @@ set(OSCPACK_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/ext/OSCPack)
add_library(OSCPACK "${OSCPACK_SRCS}")
message(STATUS "Compiling 'OSCPack' from http://www.rossbencina.com/code/oscpack -- ${OSCPACK_INCLUDE_DIR}.")
#
# STB
#
@@ -215,22 +212,29 @@ if(WIN32)
endif( WIN32 )
#
# TINY FILE DIALOG
# FILE DIALOG: use tinyfiledialog for all except Linux
#
set(TINYFD_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/ext/tfd)
add_library(TINYFD "${CMAKE_CURRENT_SOURCE_DIR}/ext/tfd/tinyfiledialogs.c")
message(STATUS "Compiling 'TinyFileDialog' from https://github.com/native-toolkit/tinyfiledialogs.git -- ${TINYFD_INCLUDE_DIR}.")
if(UNIX)
if (APPLE)
set(TINYFD_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/ext/tfd)
add_library(TINYFD "${CMAKE_CURRENT_SOURCE_DIR}/ext/tfd/tinyfiledialogs.c")
message(STATUS "Compiling 'TinyFileDialog' from https://github.com/native-toolkit/tinyfiledialogs.git -- ${TINYFD_INCLUDE_DIR}.")
set(TINYFD_LIBRARY TINYFD)
endif()
else()
set(TINYFD_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/ext/tfd)
add_library(TINYFD "${CMAKE_CURRENT_SOURCE_DIR}/ext/tfd/tinyfiledialogs.c")
message(STATUS "Compiling 'TinyFileDialog' from https://github.com/native-toolkit/tinyfiledialogs.git -- ${TINYFD_INCLUDE_DIR}.")
set(TINYFD_LIBRARY TINYFD)
endif()
#
# OBJ LOADER
# OBJ LOADER - not used
#
#set(OBJLOADER_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/ext/obj)
#add_library(OBJLOADER "${CMAKE_CURRENT_SOURCE_DIR}/ext/obj/ObjLoader.cpp")
#message(STATUS "Compiling 'ObjLoader' from https://github.com/mortennobel/OpenGL_3_2_Utils -- ${OBJLOADER_INCLUDE_DIR}.")
# find_package(PkgConfig REQUIRED)
# pkg_check_modules(GTK3 REQUIRED gtk+-3.0)
#
# Application
#
@@ -316,6 +320,7 @@ set(VMIX_SRCS
GstToolkit.cpp
GlmToolkit.cpp
SystemToolkit.cpp
DialogToolkit.cpp
tinyxml2Toolkit.cpp
NetworkToolkit.cpp
Connection.cpp
@@ -426,6 +431,11 @@ set(VMIX_RSC_FILES
./rsc/mesh/h_mark.ply
)
# Include the CMake RC module
include(CMakeRC)
cmrc_add_resource_library(vmix-resources ALIAS vmix::rc NAMESPACE vmix WHENCE rsc ${VMIX_RSC_FILES})
message(STATUS "Using 'CMakeRC ' from https://github.com/vector-of-bool/cmrc.git -- ${CMAKE_MODULE_PATH}.")
### DEFINE THE TARGET (OS specific)
IF(APPLE)
@@ -455,17 +465,19 @@ IF(APPLE)
ELSE(APPLE)
link_directories (${GTK3_LIBRARY_DIRS})
add_executable(${VMIX_BINARY}
${VMIX_SRCS}
${IMGUITEXTEDIT_SRC}
)
set(PLATFORM_LIBS ""
set(PLATFORM_LIBS
GTK::GTK
)
ENDIF(APPLE)
### COMPILE THE TARGET (all OS)
set_property(TARGET ${VMIX_BINARY} PROPERTY CXX_STANDARD 17)
@@ -473,14 +485,12 @@ set_property(TARGET ${VMIX_BINARY} PROPERTY C_STANDARD 11)
target_compile_definitions(${VMIX_BINARY} PUBLIC "IMGUI_IMPL_OPENGL_LOADER_GLAD")
cmrc_add_resource_library(vmix-resources ALIAS vmix::rc NAMESPACE vmix WHENCE rsc ${VMIX_RSC_FILES})
message(STATUS "Using 'CMakeRC ' from https://github.com/vector-of-bool/cmrc.git -- ${CMAKE_MODULE_PATH}.")
target_link_libraries(${VMIX_BINARY} LINK_PRIVATE
${GLFW_LIBRARY}
GLAD
glm::glm
TINYXML2
IMGUI
OSCPACK
${GLFW_LIBRARY}
${CMAKE_DL_LIBS}
${GOBJECT_LIBRARIES}
${GSTREAMER_LIBRARY}
@@ -491,21 +501,17 @@ target_link_libraries(${VMIX_BINARY} LINK_PRIVATE
${GSTREAMER_PBUTILS_LIBRARY}
${GSTREAMER_GL_LIBRARY}
${GSTREAMER_PLAYER_LIBRARY}
${NFD_LIBRARY}
${PNG_LIBRARY}
${THREAD_LIBRARY}
TINYXML2
TINYFD
IMGUI
OSCPACK
vmix::rc
${TINYFD_LIBRARY}
Threads::Threads
PNG::PNG
glm::glm
ICU::i18n
ICU::io
ICU::uc
vmix::rc
${PLATFORM_LIBS}
)
macro_display_feature_log()
### DEFINE THE PACKAGING (all OS)

326
DialogToolkit.cpp Normal file
View File

@@ -0,0 +1,326 @@
// multiplatform implementation of system dialogs
//
// 'TinyFileDialog' from https://github.com/native-toolkit/tinyfiledialogs.git
// is the prefered solution, but it is not compatible with linux snap packaging
// because of 'zenity' access rights nightmare :(
// Thus this re-implementation of native GTK+ dialogs for linux
#if defined(LINUX)
#define USE_TINYFILEDIALOG 0
#else
#define USE_TINYFILEDIALOG 1
#endif
#if USE_TINYFILEDIALOG
#include <tinyfiledialogs.h>
#else
#include <stdio.h>
#include <gtk/gtk.h>
#endif
#include "defines.h"
#include "SystemToolkit.h"
#include "DialogToolkit.h"
bool gtk_init_ok = false;
void add_filter_any_file_dialog( GtkWidget *dialog)
{
/* append a wildcard option */
GtkFileFilter *filter;
filter = gtk_file_filter_new();
gtk_file_filter_set_name( filter, "Any file" );
gtk_file_filter_add_pattern( filter, "*" );
gtk_file_chooser_add_filter( GTK_FILE_CHOOSER(dialog), filter );
}
void add_filter_file_dialog( GtkWidget *dialog, int const countfilterPatterns, char const * const * const filterPatterns, char const * const filterDescription)
{
GtkFileFilter *filter;
filter = gtk_file_filter_new();
gtk_file_filter_set_name( filter, filterDescription );
for (int i = 0; i < countfilterPatterns; i++ )
gtk_file_filter_add_pattern( filter, filterPatterns[i] );
gtk_file_chooser_add_filter( GTK_FILE_CHOOSER(dialog), filter );
}
void wait_for_event(void)
{
while ( gtk_events_pending() )
gtk_main_iteration();
}
bool gtk_init()
{
if (!gtk_init_ok) {
if ( gtk_init_check( NULL, NULL ) )
gtk_init_ok = true;
}
return gtk_init_ok;
}
std::string DialogToolkit::saveSessionFileDialog(const std::string &path)
{
std::string filename = "";
char const * save_pattern[1] = { "*.mix" };
#if USE_TINYFILEDIALOG
char const * save_file_name;
save_file_name = tinyfd_saveFileDialog( "Save a session file", path.c_str(), 1, save_pattern, "vimix session");
if (save_file_name) {
filename = std::string(save_file_name);
std::string extension = filename.substr(filename.find_last_of(".") + 1);
if (extension != "mix")
filename += ".mix";
}
#else
if (!gtk_init()) {
ErrorDialog("Could not initialize GTK+ for dialog");
return filename;
}
GtkWidget *dialog = gtk_file_chooser_dialog_new( "Save Session File", NULL,
GTK_FILE_CHOOSER_ACTION_SAVE,
"_Cancel", GTK_RESPONSE_CANCEL,
"_Save", GTK_RESPONSE_ACCEPT, NULL );
gtk_file_chooser_set_do_overwrite_confirmation( GTK_FILE_CHOOSER(dialog), TRUE );
// set file filters
add_filter_file_dialog(dialog, 1, save_pattern, "vimix session");
add_filter_any_file_dialog(dialog);
// Set the default path
gtk_file_chooser_set_current_folder( GTK_FILE_CHOOSER(dialog), path.c_str() );
// ensure front and centered
gtk_window_set_keep_above( GTK_WINDOW(dialog), TRUE );
static int x = 0, y = 0;
if (x != 0)
gtk_window_move( GTK_WINDOW(dialog), x, y);
// display and get filename
if ( gtk_dialog_run( GTK_DIALOG(dialog) ) == GTK_RESPONSE_ACCEPT ) {
char *save_file_name = gtk_file_chooser_get_filename( GTK_FILE_CHOOSER(dialog) );
if (save_file_name)
filename = std::string(save_file_name);
g_free( save_file_name );
}
// remember position
gtk_window_get_position( GTK_WINDOW(dialog), &x, &y);
// done
gtk_widget_destroy(dialog);
// wait_for_event();
#endif
return filename;
}
std::string DialogToolkit::openSessionFileDialog(const std::string &path)
{
std::string filename = "";
std::string startpath = SystemToolkit::file_exists(path) ? path : SystemToolkit::home_path();
char const * open_pattern[1] = { "*.mix" };
#if USE_TINYFILEDIALOG
char const * open_file_name;
open_file_name = tinyfd_openFileDialog( "Import a file", startpath.c_str(), 1, open_pattern, "vimix session", 0);
if (open_file_name)
filename = std::string(open_file_name);
#else
if (!gtk_init()) {
ErrorDialog("Could not initialize GTK+ for dialog");
return filename;
}
GtkWidget *dialog = gtk_file_chooser_dialog_new( "Open Session File", NULL,
GTK_FILE_CHOOSER_ACTION_OPEN,
"_Cancel", GTK_RESPONSE_CANCEL,
"_Open", GTK_RESPONSE_ACCEPT, NULL );
// set file filters
add_filter_file_dialog(dialog, 1, open_pattern, "vimix session");
add_filter_any_file_dialog(dialog);
// Set the default path
gtk_file_chooser_set_current_folder( GTK_FILE_CHOOSER(dialog), startpath.c_str() );
// ensure front and centered
gtk_window_set_keep_above( GTK_WINDOW(dialog), TRUE );
static int x = 0, y = 0;
if (x != 0)
gtk_window_move( GTK_WINDOW(dialog), x, y);
// display and get filename
if ( gtk_dialog_run( GTK_DIALOG(dialog) ) == GTK_RESPONSE_ACCEPT ) {
char *open_file_name = gtk_file_chooser_get_filename( GTK_FILE_CHOOSER(dialog) );
if (open_file_name)
filename = std::string(open_file_name);
g_free( open_file_name );
}
// remember position
gtk_window_get_position( GTK_WINDOW(dialog), &x, &y);
// done
gtk_widget_destroy(dialog);
// wait_for_event();
#endif
return filename;
}
std::string DialogToolkit::ImportFileDialog(const std::string &path)
{
std::string filename = "";
std::string startpath = SystemToolkit::file_exists(path) ? path : SystemToolkit::home_path();
char const * open_pattern[18] = { "*.mix", "*.mp4", "*.mpg",
"*.avi", "*.mov", "*.mkv",
"*.webm", "*.mod", "*.wmv",
"*.mxf", "*.ogg", "*.flv",
"*.asf", "*.jpg", "*.png",
"*.gif", "*.tif", "*.svg" };
#if USE_TINYFILEDIALOG
char const * open_file_name;
open_file_name = tinyfd_openFileDialog( "Import a file", startpath.c_str(), 18, open_pattern, "All supported formats", 0);
if (open_file_name)
filename = std::string(open_file_name);
#else
if (!gtk_init()) {
ErrorDialog("Could not initialize GTK+ for dialog");
return filename;
}
GtkWidget *dialog = gtk_file_chooser_dialog_new( "Import Media File", NULL,
GTK_FILE_CHOOSER_ACTION_OPEN,
"_Cancel", GTK_RESPONSE_CANCEL,
"_Open", GTK_RESPONSE_ACCEPT, NULL );
// set file filters
add_filter_file_dialog(dialog, 18, open_pattern, "All supported formats");
add_filter_any_file_dialog(dialog);
// Set the default path
gtk_file_chooser_set_current_folder( GTK_FILE_CHOOSER(dialog), startpath.c_str() );
// ensure front and centered
gtk_window_set_keep_above( GTK_WINDOW(dialog), TRUE );
static int x = 0, y = 0;
if (x != 0)
gtk_window_move( GTK_WINDOW(dialog), x, y);
// display and get filename
if ( gtk_dialog_run( GTK_DIALOG(dialog) ) == GTK_RESPONSE_ACCEPT ) {
char *open_file_name = gtk_file_chooser_get_filename( GTK_FILE_CHOOSER(dialog) );
if (open_file_name)
filename = std::string(open_file_name);
g_free( open_file_name );
}
// remember position
gtk_window_get_position( GTK_WINDOW(dialog), &x, &y);
// done
gtk_widget_destroy(dialog);
// wait_for_event();
#endif
return filename;
}
std::string DialogToolkit::FolderDialog(const std::string &path)
{
std::string foldername = "";
std::string startpath = SystemToolkit::file_exists(path) ? path : SystemToolkit::home_path();
#if USE_TINYFILEDIALOG
char const * open_folder_name;
open_folder_name = tinyfd_selectFolderDialog("Select folder", startpath.c_str());
if (open_folder_name)
foldername = std::string(open_folder_name);
#else
if (!gtk_init()) {
ErrorDialog("Could not initialize GTK+ for dialog");
return foldername;
}
GtkWidget *dialog = gtk_file_chooser_dialog_new( "Select folder", NULL,
GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER,
"_Cancel", GTK_RESPONSE_CANCEL,
"_Select", GTK_RESPONSE_ACCEPT, NULL );
gtk_file_chooser_set_do_overwrite_confirmation( GTK_FILE_CHOOSER(dialog), TRUE );
// Set the default path
gtk_file_chooser_set_current_folder( GTK_FILE_CHOOSER(dialog), startpath.c_str() );
// ensure front and centered
gtk_window_set_keep_above( GTK_WINDOW(dialog), TRUE );
static int x = 0, y = 0;
if (x != 0)
gtk_window_move( GTK_WINDOW(dialog), x, y);
// display and get filename
if ( gtk_dialog_run( GTK_DIALOG(dialog) ) == GTK_RESPONSE_ACCEPT ) {
char *open_folder_name = gtk_file_chooser_get_filename( GTK_FILE_CHOOSER(dialog) );
if (open_folder_name)
foldername = std::string(open_folder_name);
g_free( open_folder_name );
}
// remember position
gtk_window_get_position( GTK_WINDOW(dialog), &x, &y);
// done
gtk_widget_destroy(dialog);
// wait_for_event();
#endif
return foldername;
}
void DialogToolkit::ErrorDialog(const char* message)
{
#if USE_TINYFILEDIALOG
tinyfd_messageBox( APP_TITLE, message, "ok", "error", 0);
#else
if (!gtk_init()) {
return;
}
GtkWidget *dialog = gtk_message_dialog_new( NULL, GTK_DIALOG_DESTROY_WITH_PARENT,
GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE,
"Error: %s", message);
gtk_window_set_keep_above( GTK_WINDOW(dialog), TRUE );
static int x = 0, y = 0;
if (x != 0)
gtk_window_move( GTK_WINDOW(dialog), x, y);
// show
gtk_dialog_run( GTK_DIALOG(dialog) );
// remember position
gtk_window_get_position( GTK_WINDOW(dialog), &x, &y);
// done
gtk_widget_destroy( dialog );
// wait_for_event();
#endif
}

24
DialogToolkit.h Normal file
View File

@@ -0,0 +1,24 @@
#ifndef DIALOGTOOLKIT_H
#define DIALOGTOOLKIT_H
#include <string>
namespace DialogToolkit
{
std::string saveSessionFileDialog(const std::string &path);
std::string openSessionFileDialog(const std::string &path);
std::string ImportFileDialog(const std::string &path);
std::string FolderDialog(const std::string &path);
void ErrorDialog(const char* message);
}
#endif // DIALOGTOOLKIT_H

19
Log.cpp
View File

@@ -1,4 +1,7 @@
#include "Log.h"
#include <string>
#include <list>
#include <mutex>
using namespace std;
#include "imgui.h"
#ifndef IMGUI_DEFINE_MATH_OPERATORS
@@ -6,16 +9,11 @@
#endif
#include "imgui_internal.h"
#include "ImGuiToolkit.h"
#include "defines.h"
#include "ImGuiToolkit.h"
#include "DialogToolkit.h"
#include "Log.h"
// multiplatform
#include <tinyfiledialogs.h>
#include <string>
#include <list>
#include <mutex>
using namespace std;
static std::mutex mtx;
@@ -296,7 +294,8 @@ void Log::Error(const char* fmt, ...)
buf.appendfv(fmt, args);
va_end(args);
tinyfd_messageBox( APP_TITLE, buf.c_str(), "ok", "error", 0);
DialogToolkit::ErrorDialog(buf.c_str());
Log::Info("Error - %s\n", buf.c_str());
}

View File

@@ -63,3 +63,11 @@ and (recursively) clone all the internal git Dependencies.
**OSX with Brew**
brew install cmake libpng glfw gstreamer gst-libav gst-plugins-bad gst-plugins-base gst-plugins-good gst-plugins-ugly icu4c
#### Generate snap
From vimix root directory
snapcraft --debug
snap install --dangerous vimix_0.5_amd64.snap

View File

@@ -10,9 +10,6 @@
// Desktop OpenGL function loader
#include <glad/glad.h>
// multiplatform message box
#include <tinyfiledialogs.h>
// standalone image loader
#include "stb_image.h"

View File

@@ -20,9 +20,6 @@ using namespace std;
// Include glfw3.h after our OpenGL definitions
#include <GLFW/glfw3.h>
// multiplatform
#include <tinyfiledialogs.h>
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtx/string_cast.hpp>
@@ -38,17 +35,17 @@ using namespace std;
#include "defines.h"
#include "Log.h"
#include "SystemToolkit.h"
#include "DialogToolkit.h"
#include "GlmToolkit.h"
#include "GstToolkit.h"
#include "ImGuiToolkit.h"
#include "ImGuiVisitor.h"
#include "RenderingManager.h"
#include "Connection.h"
#include "ActionManager.h"
#include "Resource.h"
#include "FileDialog.h"
#include "Settings.h"
#include "SessionCreator.h"
#include "ImGuiToolkit.h"
#include "ImGuiVisitor.h"
#include "GlmToolkit.h"
#include "GstToolkit.h"
#include "Mixer.h"
#include "Recorder.h"
#include "Streamer.h"
@@ -78,79 +75,12 @@ void ShowSandbox(bool* p_open);
const std::chrono::milliseconds timeout = std::chrono::milliseconds(4);
static std::atomic<bool> fileDialogPending_ = false;
static std::vector< std::future<std::string> > saveSessionFileDialogs;
static std::string saveSessionFileDialog(const std::string &path)
{
std::string filename = "";
char const * save_file_name;
char const * save_pattern[1] = { "*.mix" };
save_file_name = tinyfd_saveFileDialog( "Save a session file", path.c_str(), 1, save_pattern, "vimix session");
if (save_file_name) {
filename = std::string(save_file_name);
std::string extension = filename.substr(filename.find_last_of(".") + 1);
if (extension != "mix")
filename += ".mix";
}
return filename;
}
static std::vector< std::future<std::string> > openSessionFileDialogs;
static std::vector< std::future<std::string> > importSessionFileDialogs;
static std::string openSessionFileDialog(const std::string &path)
{
std::string filename = "";
std::string startpath = SystemToolkit::file_exists(path) ? path : SystemToolkit::home_path();
char const * open_pattern[18] = { "*.mix" };
char const * open_file_name;
open_file_name = tinyfd_openFileDialog( "Import a file", startpath.c_str(), 1, open_pattern, "vimix session", 0);
if (open_file_name)
filename = std::string(open_file_name);
return filename;
}
static std::vector< std::future<std::string> > fileImportFileDialogs;
static std::string ImportFileDialog(const std::string &path)
{
std::string filename = "";
std::string startpath = SystemToolkit::file_exists(path) ? path : SystemToolkit::home_path();
char const * open_pattern[18] = { "*.mix", "*.mp4", "*.mpg",
"*.avi", "*.mov", "*.mkv",
"*.webm", "*.mod", "*.wmv",
"*.mxf", "*.ogg", "*.flv",
"*.asf", "*.jpg", "*.png",
"*.gif", "*.tif", "*.svg" };
char const * open_file_name;
open_file_name = tinyfd_openFileDialog( "Import a file", startpath.c_str(), 18, open_pattern, "All supported formats", 0);
if (open_file_name)
filename = std::string(open_file_name);
return filename;
}
static std::vector< std::future<std::string> > recentFolderFileDialogs;
static std::vector< std::future<std::string> > recordFolderFileDialogs;
static std::string FolderDialog(const std::string &path)
{
std::string foldername = "";
std::string startpath = SystemToolkit::file_exists(path) ? path : SystemToolkit::home_path();
char const * open_folder_name;
open_folder_name = tinyfd_selectFolderDialog("Select a folder", startpath.c_str());
if (open_folder_name)
foldername = std::string(open_folder_name);
return foldername;
}
UserInterface::UserInterface()
@@ -700,7 +630,7 @@ void UserInterface::selectSaveFilename()
{
// launch file dialog to select a session filename to save
if ( saveSessionFileDialogs.empty()) {
saveSessionFileDialogs.emplace_back( std::async(std::launch::async, saveSessionFileDialog, Settings::application.recentSessions.path) );
saveSessionFileDialogs.emplace_back( std::async(std::launch::async, DialogToolkit::saveSessionFileDialog, Settings::application.recentSessions.path) );
fileDialogPending_ = true;
}
navigator.hidePannel();
@@ -710,7 +640,7 @@ void UserInterface::selectOpenFilename()
{
// launch file dialog to select a session filename to open
if ( openSessionFileDialogs.empty()) {
openSessionFileDialogs.emplace_back( std::async(std::launch::async, openSessionFileDialog, Settings::application.recentSessions.path) );
openSessionFileDialogs.emplace_back( std::async(std::launch::async, DialogToolkit::openSessionFileDialog, Settings::application.recentSessions.path) );
fileDialogPending_ = true;
}
navigator.hidePannel();
@@ -906,7 +836,7 @@ void UserInterface::showMenuFile()
if (ImGui::MenuItem( ICON_FA_FILE_EXPORT " Import")) {
// launch file dialog to open a session file
if ( importSessionFileDialogs.empty()) {
importSessionFileDialogs.emplace_back( std::async(std::launch::async, openSessionFileDialog, Settings::application.recentSessions.path) );
importSessionFileDialogs.emplace_back( std::async(std::launch::async, DialogToolkit::openSessionFileDialog, Settings::application.recentSessions.path) );
fileDialogPending_ = true;
}
navigator.hidePannel();
@@ -1288,7 +1218,7 @@ void UserInterface::RenderPreview()
ImGui::Combo("Path", &selected_path, name_path, 4);
if (selected_path > 2) {
if (recordFolderFileDialogs.empty()) {
recordFolderFileDialogs.emplace_back( std::async(std::launch::async, FolderDialog, Settings::application.record.path) );
recordFolderFileDialogs.emplace_back( std::async(std::launch::async, DialogToolkit::FolderDialog, Settings::application.record.path) );
fileDialogPending_ = true;
}
}
@@ -2490,7 +2420,7 @@ void Navigator::RenderNewPannel()
if ( ImGui::Button( ICON_FA_FILE_EXPORT " Open file", ImVec2(ImGui::GetContentRegionAvail().x IMGUI_RIGHT_ALIGN, 0)) ) {
// launch async call to file dialog and get its future.
if (fileImportFileDialogs.empty()) {
fileImportFileDialogs.emplace_back( std::async(std::launch::async, ImportFileDialog, Settings::application.recentImport.path) );
fileImportFileDialogs.emplace_back( std::async(std::launch::async, DialogToolkit::ImportFileDialog, Settings::application.recentImport.path) );
fileDialogPending_ = true;
}
}
@@ -2776,7 +2706,7 @@ void Navigator::RenderMainPannel()
// Option 2 : add a folder
if (ImGui::Selectable( ICON_FA_FOLDER_PLUS " Add Folder") ){
if (recentFolderFileDialogs.empty()) {
recentFolderFileDialogs.emplace_back( std::async(std::launch::async, FolderDialog, Settings::application.recentFolders.path) );
recentFolderFileDialogs.emplace_back( std::async(std::launch::async, DialogToolkit::FolderDialog, Settings::application.recentFolders.path) );
fileDialogPending_ = true;
}
}
@@ -3023,6 +2953,8 @@ int hover(const char *label)
#define SEGMENT_ARRAY_MAX 1000
#define MAXSIZE 65535
void ShowSandbox(bool* p_open)
{
@@ -3036,6 +2968,16 @@ void ShowSandbox(bool* p_open)
ImGui::Text("Testing sandox");
if (ImGui::Button("Message test")) {
Log::Error("Testing dialog");
}
static char str[128] = "";
ImGui::InputText("Command", str, IM_ARRAYSIZE(str));
if ( ImGui::Button("Execute") )
SystemToolkit::execute(str);
// const guint64 duration = GST_SECOND * 6;
// const guint64 step = GST_MSECOND * 20;
// static guint64 t = 0;
@@ -3121,8 +3063,9 @@ void ShowSandbox(bool* p_open)
// ImGui::EndChild();
static char str0[128] = "àöäüèáû вторая строчка";
ImGui::InputText("input text", str0, IM_ARRAYSIZE(str0));
ImGui::InputText("##inputtext", str0, IM_ARRAYSIZE(str0));
std::string tra = SystemToolkit::transliterate(std::string(str0));
ImGui::Text("Transliteration: '%s'", tra.c_str());
@@ -3159,8 +3102,8 @@ void UserInterface::RenderAbout(bool* p_open)
ImGui::Spacing();
ImGui::Text("\nvimix is built using the following libraries:");
tinyfd_inputBox("tinyfd_query", NULL, NULL);
ImGui::Text("- Tinyfiledialogs v%s mode '%s'", tinyfd_version, tinyfd_response);
// tinyfd_inputBox("tinyfd_query", NULL, NULL);
// ImGui::Text("- Tinyfiledialogs v%s mode '%s'", tinyfd_version, tinyfd_response);
ImGui::Columns(3, "abouts");
ImGui::Separator();

147
cmake/modules/FindGTK.cmake Normal file
View File

@@ -0,0 +1,147 @@
# - Try to find GTK+ 3.x or 4.x
#
# Copyright (C) 2012 Raphael Kubo da Costa <rakuco@webkit.org>
# Copyright (C) 2013, 2015, 2020 Igalia S.L.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND ITS CONTRIBUTORS ``AS
# IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR ITS
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#[=======================================================================[.rst:
FindGTK
-------
Find GTK headers and libraries.
Optional Components
^^^^^^^^^^^^^^^^^^^
The ``COMPONENTS`` (or ``OPTIONAL_COMPONENTS``) keyword can be passed to
``find_package()``, the following GTK components can be searched for:
- ``unix-print``
Imported Targets
^^^^^^^^^^^^^^^^
``GTK::GTK``
The GTK library, if found.
``GTK::UnixPrint``
The GTK unix-print library, if found.
Result Variables
^^^^^^^^^^^^^^^^
This will define the following variables in your project:
``GTK_FOUND``
true if (the requested version of) GTK is available.
``GTK_UNIX_PRINT_FOUND``
true if the ``unix-print`` component is available.
``GTK_4``
whether GTK 4 was detected
``GTK_3``
whether GTK 3 was detected
``GTK_VERSION``
the version of GTK.
``GTK_SUPPORTS_BROADWAY``
true if the Broadway target is built into GTK.
``GTK_SUPPORTS_QUARTZ``
true if the Quartz target is built into GTK.
``GTK_SUPPORTS_WAYLAND``
true if the Wayland target is built into GTK.
``GTK_SUPPORTS_WIN32``
true if the Windows target is built into GTK.
``GTK_SUPPORTS_X11``
true if the X11 target is built into GTK.
#]=======================================================================]
if (GTK_FIND_VERSION VERSION_LESS 3.90)
set(GTK_PC_MODULE "gtk+-3.0")
set(GTK_PC_UNIX_PRINT_MODULE "gtk+-unix-print-3.0")
set(GTK_4 FALSE)
set(GTK_3 TRUE)
else ()
set(GTK_PC_MODULE "gtk4")
set(GTK_PC_UNIX_PRINT_MODULE "gtk4-unix-print")
set(GTK_4 TRUE)
set(GTK_3 FALSE)
endif ()
find_package(PkgConfig QUIET)
pkg_check_modules(GTK IMPORTED_TARGET ${GTK_PC_MODULE})
set(GTK_VERSION_OK TRUE)
if (GTK_VERSION)
if (GTK_FIND_VERSION_EXACT)
if (NOT("${GTK_FIND_VERSION}" VERSION_EQUAL "${GTK_VERSION}"))
set(GTK_VERSION_OK FALSE)
endif ()
else ()
if ("${GTK_VERSION}" VERSION_LESS "${GTK_FIND_VERSION}")
set(GTK_VERSION_OK FALSE)
endif ()
endif ()
endif ()
# Set all the GTK_SUPPORTS_<target> variables to FALSE initially.
foreach (gtk_target broadway quartz wayland win32 x11)
string(TOUPPER "GTK_SUPPORTS_${gtk_target}" gtk_target)
set(${gtk_target} FALSE)
endforeach ()
if (GTK_VERSION AND GTK_VERSION_OK)
# Fetch the "targets" variable and set GTK_SUPPORTS_<target>.
pkg_get_variable(GTK_TARGETS ${GTK_PC_MODULE} targets)
separate_arguments(GTK_TARGETS)
foreach (gtk_target ${GTK_TARGETS})
string(TOUPPER "GTK_SUPPORTS_${gtk_target}" gtk_target)
set(${gtk_target} TRUE)
endforeach ()
endif ()
if (TARGET PkgConfig::GTK AND NOT TARGET GTK::GTK)
add_library(GTK::GTK INTERFACE IMPORTED GLOBAL)
set_property(TARGET GTK::GTK PROPERTY
INTERFACE_LINK_LIBRARIES PkgConfig::GTK
)
endif ()
# Try to find additional components
foreach (gtk_component ${GTK_FIND_COMPONENTS})
if (NOT "${gtk_component}" STREQUAL unix-print)
message(FATAL_ERROR "Invalid component name: ${gtk_component}")
endif ()
pkg_check_modules(GTK_UNIX_PRINT IMPORTED_TARGET "${GTK_PC_UNIX_PRINT_MODULE}")
if (GTK_FIND_REQUIRED_unix-print AND NOT GTK_UNIX_PRINT_FOUND)
message(FATAL_ERROR "Component unix-print not found")
endif ()
if (TARGET PkgConfig::GTK_UNIX_PRINT AND NOT TARGET GTK::UnixPrint)
add_library(GTK::UnixPrint INTERFACE IMPORTED GLOBAL)
set_property(TARGET GTK::UnixPrint PROPERTY
INTERFACE_LINK_LIBRARIES PkgConfig::GTK_UNIX_PRINT)
endif ()
endforeach ()
include(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(GTK DEFAULT_MSG GTK_VERSION GTK_VERSION_OK)

View File

@@ -479,7 +479,7 @@ public:
if( FD_ISSET( breakPipe_[0], &tempfds ) ){
// clear pending data from the asynchronous break pipe
char c;
read( breakPipe_[0], &c, 1 );
size_t n = read( breakPipe_[0], &c, 1 );
}
if( break_ )
@@ -534,7 +534,8 @@ public:
break_ = true;
// Send a termination message to the asynchronous break pipe, so select() will return
write( breakPipe_[1], "!", 1 );
if (write( breakPipe_[1], "!", 1 ) < 1)
throw std::runtime_error("AsynchronousBreak failed\n");
}
};

View File

@@ -5,5 +5,4 @@ Comment=Live video mixing.
Categories=AudioVideo;Video;Graphics;Utility;
Icon=${SNAP}/meta/gui/vimix.svg
Exec=vimix
TryExec=vimix
Terminal=false

View File

@@ -1,6 +1,4 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:osb="http://www.openswatchbook.org/uri/2009/osb"
xmlns:dc="http://purl.org/dc/elements/1.1/"
@@ -15,11 +13,11 @@
height="64"
id="svg3744"
sodipodi:version="0.32"
inkscape:version="0.92.4 (5da689c313, 2019-01-14)"
inkscape:version="1.0.1 (3bc2e813f5, 2020-09-07)"
version="1.0"
sodipodi:docname="v-mix.svg"
sodipodi:docname="vimix.svg"
inkscape:output_extension="org.inkscape.output.svg.inkscape"
inkscape:export-filename="/home/bhbn/Developments/v-mix/rsc/images/v-mix_256x256.png"
inkscape:export-filename="/home/bhbn/Developments/v-mix/rsc/images/vimix_256x256.png"
inkscape:export-xdpi="405.16815"
inkscape:export-ydpi="405.16815">
<sodipodi:namedview
@@ -29,9 +27,9 @@
borderopacity="1.0"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:zoom="24.671299"
inkscape:cx="36.638352"
inkscape:cy="31.887987"
inkscape:zoom="22.627417"
inkscape:cx="35.082716"
inkscape:cy="31.811389"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:document-units="px"
@@ -41,16 +39,17 @@
showborder="true"
objecttolerance="1"
guidetolerance="10000"
inkscape:window-width="2618"
inkscape:window-width="2890"
inkscape:window-height="1885"
inkscape:window-x="920"
inkscape:window-y="160"
inkscape:window-x="817"
inkscape:window-y="89"
inkscape:window-maximized="0"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0"
inkscape:showpageshadow="false">
inkscape:showpageshadow="false"
inkscape:document-rotation="0">
<inkscape:grid
type="xygrid"
id="grid3754"
@@ -169,7 +168,7 @@
xlink:href="#linearGradient3237-580"
id="radialGradient855"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(4.0147937,-0.11912026,0.11328765,3.8182126,-0.22461479,-46.392657)"
gradientTransform="matrix(4.0147937,-0.11912026,0.11328765,3.8182126,-0.22443818,-46.542095)"
cx="8"
cy="8"
fx="8"
@@ -192,16 +191,42 @@
id="layer1"
inkscape:label="Layer 1"
inkscape:groupmode="layer"
transform="translate(-0.8,48.8)">
transform="translate(-0.8,48.8)"
style="opacity:0.89674699">
<ellipse
style="fill:#0c0c0c;fill-opacity:0.477137;stroke:none;stroke-width:0.862179;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke fill markers"
id="path854"
cx="32.799999"
cy="-16.91748"
rx="27.470198"
ry="27.375973" />
<path
id="path4090"
d="m 32.8,-48.060406 c -17.255744,0 -31.2604062,14.004662 -31.2604062,31.260406 0,17.25574444 14.0046622,31.260406 31.2604062,31.260406 17.255744,0 31.260406,-14.00466156 31.260406,-31.260406 0,-17.255744 -14.004662,-31.260406 -31.260406,-31.260406 z m 0,3.907551 c 15.098776,0 27.352855,12.254079 27.352855,27.352855 0,15.0987764 -12.254079,27.352856 -27.352855,27.352856 -15.098776,0 -27.3528555,-12.2540796 -27.3528555,-27.352856 0,-15.098776 12.2540795,-27.352855 27.3528555,-27.352855 z"
style="display:inline;overflow:visible;visibility:visible;opacity:0.2;fill:#848484;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:4.34172344;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:3.5999999;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
inkscape:connector-curvature="0" />
d="m 32.8,-48.060406 c -17.255744,0 -31.2604061,14.004662 -31.2604061,31.260406 0,17.25574393 14.0046621,31.260406 31.2604061,31.260406 17.255744,0 31.260406,-14.00466207 31.260406,-31.260406 0,-17.255744 -14.004662,-31.260406 -31.260406,-31.260406 z m 0,3.907551 c 15.098776,0 27.352855,12.254079 27.352855,27.352855 0,15.0987763 -12.254079,27.352856 -27.352855,27.352856 -15.098776,0 -27.3528552,-12.2540797 -27.3528552,-27.352856 0,-15.098776 12.2540792,-27.352855 27.3528552,-27.352855 z"
style="display:inline;overflow:visible;visibility:visible;opacity:0.2;fill:#848484;fill-opacity:0.654019;fill-rule:nonzero;stroke:none;stroke-width:4.34172;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:3.6;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
inkscape:connector-curvature="0"
inkscape:export-xdpi="405"
inkscape:export-ydpi="405" />
<g
id="g858">
<path
id="path4096"
style="display:inline;overflow:visible;visibility:visible;opacity:0.801;fill:url(#radialGradient855);fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:stroke fill markers;enable-background:accumulate"
d="m 36.688849,-42.590063 c -0.303933,2.108537 -2.081796,3.675579 -4.183594,3.6875 -2.080492,0.0106 -3.863017,-1.50665 -4.21289,-3.585937 -12.672805,2.236616 -21.7888326,13.427755 -21.4160161,26.291015 0.1430268,4.836336 1.636139,9.5362214 4.3105471,13.5683594 L 33.725958,-20.359594 v -1.535156 c 0,-3.229159 2.616539,-5.847657 5.845703,-5.847657 1.906945,0 3.585217,0.927726 4.652344,2.339844 h 1.195313 c 3.875281,0 7.017578,2.093968 7.017578,4.677734 l -7.017578,1.167969 v 5.847656 c 0,6.3779194 -4.259861,11.7530414 -10.085938,13.45898538 l 3.015625,8.15429682 c 0.05432,0.149079 0.106204,0.243515 0.205076,0.378518 C 50.521949,5.6477954 58.834499,-4.9395226 58.733771,-17.193579 58.61364,-29.921919 49.273879,-40.681635 36.688849,-42.590063 Z m 2.769317,19.244586 c -0.764292,0 -1.38415,0.619286 -1.38415,1.384151 0,0.764288 0.619858,1.385691 1.38415,1.385691 0.764291,0 1.385692,-0.621403 1.385692,-1.385691 0,-0.764865 -0.621402,-1.384151 -1.385692,-1.384151 z M 31.800177,0.30446838 c -0.138877,0.0044 -0.274456,0.01953 -0.414062,0.01953 h -2.855469 l 2.800781,7.58007782 c 0.138751,0.380792 0.336318,0.7630677 0.493205,1.0479047 0.763561,0.0573 0.707955,0.03676 1.473592,0.02631 0.559417,-0.01186 1.118303,-0.04182 1.675781,-0.08984 z m -14.0625,0.01953 -2.873047,1.43554602 c 3.582287,3.433627 8.074429,5.76748 12.943359,6.7246095 L 24.788458,0.32399838 Z"
sodipodi:nodetypes="ccccccsscsccscccccssssscsccccccccccc" />
</g>
<path
style="display:inline;overflow:visible;visibility:visible;opacity:0.80100002;fill:url(#radialGradient855);fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:2.09425879;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.64077669;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:stroke fill markers;enable-background:accumulate"
d="m 32.810524,-42.734828 -1.015246,0.02097 A 25.934385,25.934385 0 0 0 6.8756139,-16.048973 25.934385,25.934385 0 0 0 11.186212,-2.4795029 L 33.725083,-20.21064 v -1.535455 c 0,-3.229159 2.61689,-5.846052 5.846054,-5.846052 1.906945,0 3.585382,0.926722 4.652509,2.33884 h 1.19564 c 3.875281,0 7.016522,2.093915 7.016522,4.677681 l -7.016522,1.168373 v 5.848149 c 0,6.3779185 -4.259255,11.7523532 -10.085332,13.45829656 l 3.014273,8.15342884 c 0.05432,0.1490791 0.05251,0.2989217 0.02726,0.444695 A 25.934385,25.934385 0 0 0 58.732847,-17.043242 25.934385,25.934385 0 0 0 32.810524,-42.734828 Z m 6.760613,19.235127 c -0.968462,0 -1.753607,0.78442 -1.753607,1.753606 0,0.968457 0.785146,1.755704 1.753607,1.755704 0.96846,0 1.755703,-0.787247 1.755703,-1.755704 0,-0.969186 -0.787244,-1.753606 -1.755703,-1.753606 z M 31.799473,0.45296287 c -0.138877,0.004393 -0.273623,0.0209759 -0.413229,0.0209759 h -2.854855 l 2.800315,7.57868263 c 0.138751,0.3807921 -0.01302,0.7823496 -0.329324,1.0047577 a 25.934385,25.934385 0 0 0 2.294791,0.071319 25.934385,25.934385 0 0 0 1.675994,-0.090197 z M 17.737064,0.47393875 14.865429,1.9087078 A 25.934385,25.934385 0 0 0 27.807711,8.6336612 L 24.789245,0.47393875 Z"
id="path4096"
inkscape:connector-curvature="0" />
style="opacity:0.809083;fill:#888888;fill-opacity:1;stroke:#ffffff;stroke-width:0.5;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:normal"
id="path859"
sodipodi:type="arc"
sodipodi:cx="32.47654"
sodipodi:cy="-43.181934"
sodipodi:rx="2.0615652"
sodipodi:ry="2.0901108"
sodipodi:start="0"
sodipodi:end="6.2616827"
sodipodi:arc-type="chord"
d="m 34.538105,-43.181934 a 2.0615652,2.0901108 0 0 1 -2.050483,2.09008 2.0615652,2.0901108 0 0 1 -2.072528,-2.067609 2.0615652,2.0901108 0 0 1 2.0282,-2.11231 2.0615652,2.0901108 0 0 1 2.094334,2.044899 z"
sodipodi:open="true" />
</g>
</svg>

Before

Width:  |  Height:  |  Size: 322 KiB

After

Width:  |  Height:  |  Size: 324 KiB

View File

@@ -37,15 +37,18 @@ apps:
GST_PLUGIN_SYSTEM_PATH : $SNAP/usr/lib/x86_64-linux-gnu/gstreamer-1.0
GST_PLUGIN_SCANNER: $SNAP/usr/lib/x86_64-linux-gnu/gstreamer1.0/gstreamer-1.0/gst-plugin-scanner
parts:
vimix-binary:
plugin: cmake
source: .
configflags:
- -DCMAKE_BUILD_TYPE=RelWithDebInfo
- -DCMAKE_INSTALL_PREFIX=/
- -DCMAKE_BUILD_TYPE=RelWithDebInfo
build-packages:
- g++
- make
- git
- libpng-dev
- libxrandr-dev
- libglfw3-dev
@@ -53,7 +56,6 @@ parts:
- libgstreamer-plugins-base1.0-dev
- libicu-dev
stage-packages:
- zenity
- libpng16-16
- libglu1-mesa
- freeglut3
@@ -69,11 +71,6 @@ parts:
- gstreamer1.0-plugins-ugly
- libgpm2
- libslang2
stage-snaps:
- zenity-integration