Commit 6139551d authored by Bastien Penavayre's avatar Bastien Penavayre Committed by Hugo Beauzée-Luyssen

Ports the new vlc3.0 dialog module in Libvlcpp

-New class Dialog (see Dialog.hpp) that wraps the internal type libvlc_dialog_id and associated functions
-Alter the Instance class (Instance.hpp), so that it holds the callbacks relative to the dialog module:
        -Inherits from CallbackOwner<8> instead of CallbackOwner<2>
        -Holder a std::shared_ptr<libvlc_dialog_cbs>
        -public usings for the prototype of the new callbacks
        -setDialogHandlers/unsetDialogHandlers
        -update the default constructor
Signed-off-by: 's avatarHugo Beauzée-Luyssen <hugo@beauzee.fr>
parent d8d466e0
/*****************************************************************************
* Dialog.hpp: libvlcpp dialog API
*****************************************************************************
* Copyright © 2016 VLC authors and VideoLAN
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#ifndef LIBVLC_CXX_DIALOG_H
#define LIBVLC_CXX_DIALOG_H
#include <string>
namespace VLC
{
///
/// \brief The Dialog class exposes libvlc_dialog_id functionalities
///
class Dialog
{
private:
libvlc_dialog_id *m_id;
Dialog() = delete;
Dialog(const Dialog &) = delete;
Dialog &operator=(const Dialog &) = delete;
template <size_t, typename ...>
friend class CallbackWrapper;
/**
* The standard constructor.
*
* Used only by CallbackWrapper when setting up the callbacks.
* \param id identifier for the current real dialog
*/
Dialog(libvlc_dialog_id *id) : m_id(id)
{
if (!m_id)
throw std::runtime_error("The required id is NULL, Dialog inoperable");
}
public:
/**
* Move constructor, steals the id of the instance given in parameter
* \param other rvalue reference instance of this class
*/
Dialog(Dialog &&other) : m_id(other.m_id)
{
other.m_id = nullptr;
}
~Dialog()
{
if (m_id)
dismiss();
}
/**
* Post a login answer.
*
* After this call, the instance won't be valid anymore
*
* \param username valid non-empty string
* \param password valid string
* \param store if true stores the credentials
* \return true if success, false otherwise
*/
bool postLogin(const std::string &username, const std::string &password, bool store)
{
if (!m_id)
throw std::runtime_error("Calling method on dismissed Dialog instance");
bool ret = libvlc_dialog_post_login(m_id, username.c_str(), password.c_str(), store) == 0;
m_id = nullptr;
return ret;
}
/**
* Post a question answer.
*
* After this call, this instance won't be valid anymore
*
* \see QuestionCb
* \param actionIndex 1 for action1, 2 for action2
* \return true on success, false otherwise
*/
bool postAction(int actionIndex)
{
if (!m_id)
throw std::runtime_error("Calling method on dismissed Dialog instance");
bool ret = libvlc_dialog_post_action(m_id, actionIndex) == 0;
m_id = nullptr;
return ret;
}
/**
* Dismiss a dialog.
*
* After this call, this instance won't be valid anymore
*
* \see CancelCb
*/
bool dismiss()
{
if (!m_id)
throw std::runtime_error("Calling method on dismissed Dialog instance");
bool ret = libvlc_dialog_dismiss(m_id) == 0;
m_id = nullptr;
return ret;
}
};
} // namespace VLC
#endif /*LIBVLC_CXX_DIALOG_H*/
......@@ -5,6 +5,7 @@
*
* Authors: Alexey Sokolov <alexey+vlc@asokolov.org>
* Hugo Beauzée-Luyssen <hugo@beauzee.fr>
* Bastien Penavayre <bastien.penavayre@epitech.eu>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
......@@ -27,21 +28,39 @@
#include "common.hpp"
#include "Internal.hpp"
#include "structures.hpp"
#include "Dialog.hpp"
#include <string>
#include <vector>
#include <cstring>
namespace VLC
{
using Question = libvlc_dialog_question_type;
class Instance : protected CallbackOwner<2>, public Internal<libvlc_instance_t>
namespace DialogType
{
static constexpr Question normal = LIBVLC_DIALOG_QUESTION_NORMAL;
static constexpr Question warning = LIBVLC_DIALOG_QUESTION_WARNING;
static constexpr Question critical = LIBVLC_DIALOG_QUESTION_CRITICAL;
}
class Instance : protected CallbackOwner<8>, public Internal<libvlc_instance_t>
{
private:
enum class CallbackIdx : unsigned int
{
Exit,
Log
Exit = 0,
Log,
ErrorDisplay,
LoginDisplay,
QuestionDisplay,
ProgressDisplay,
CancelDialog,
ProgressUpdate
};
std::shared_ptr<libvlc_dialog_cbs> m_callbacks_pointers;
public:
/**
* Create and initialize a libvlc instance. This functions accept a list
......@@ -66,7 +85,8 @@ public:
* \param argv list of arguments (should be NULL)
*/
Instance(int argc, const char *const * argv)
: Internal{ libvlc_new( argc, argv ), libvlc_release }
: Internal{ libvlc_new( argc, argv ), libvlc_release },
m_callbacks_pointers { std::make_shared<libvlc_dialog_cbs>() }
{
}
......@@ -336,6 +356,124 @@ public:
res.emplace_back( p );
return res;
}
/**
* Called when an error message needs to be displayed.
*
* \param title title of the dialog
* \param text text of the dialog
*/
using ErrorCb = void(std::string &&title, std::string &&text);
/**
*Called when a login dialog needs to be displayed.
*
*You can interact with this dialog by using the postLogin method on dialog to post an answer or the dismiss method to cancel this dialog.
*
*\note to receive this callack, CancelCb should not be NULL.
*\param dialog used to interact with the dialog
*\param title title of the dialog
*\param text text of the dialog
*\param defaultUserName user name that should be set on the user form
*\param askToStore if true, ask the user if he wants to save the credentials
*/
using LoginCb = void(Dialog &&dialog, std::string &&title, std::string &&text, std::string &&defaultUserName, bool askToStore);
/**
* Called when a question dialog needs to be displayed
*
* You can interact with this dialog by using the postAction method on dialog
* to post an answer or dismiss method to cancel this dialog.
*
* \note to receive this callack, CancelCb should not be
* NULL.
*
* \param dialog used to interact with the dialog
* \param title title of the diaog
* \param text text of the dialog
* \param qtype question type (or severity) of the dialog
* \param cancel text of the cancel button
* \param action1 text of the first button, if NULL, don't display this
* button
* \param action2 text of the second button, if NULL, don't display
* this button
*/
using QuestionCb = void(Dialog &&dialog, std::string &&title, std::string &&text, Question qType, std::string &&cancel, std::string &&action1, std::string &&action2);
/**
* Called when a progress dialog needs to be displayed
*
* If cancellable (cancel != NULL), you can cancel this dialog by
* calling the dismiss method on dialog
*
* \note to receive this callack, CancelCb and
* UpdtProgressCb should not be NULL.
*
* \param dialog used to interact with the dialog
* \param title title of the diaog
* \param text text of the dialog
* \param indeterminate true if the progress dialog is indeterminate
* \param position initial position of the progress bar (between 0.0 and
* 1.0)
* \param cancel text of the cancel button, if NULL the dialog is not
* cancellable
*/
using DspProgressCb = void(Dialog &&dialog, std::string &&title, std::string &&text, bool intermediate, float position, std::string &&cancel);
/**
* Called when a displayed dialog needs to be cancelled
*
* The implementation must call the method dismiss on dialog to really release
* the dialog.
*
* \param dialog used to interact with the dialog
*/
using CancelCb = void(Dialog &&dialog);
/**
* Called when a progress dialog needs to be updated
*
* \param dialog used to interact with the dialog
* \param position osition of the progress bar (between 0.0 and 1.0)
* \param text new text of the progress dialog
*/
using UpdtProgressCb = void(Dialog &&dialog, float position, std::string &&text);
/**
* Replaces all the dialog callbacks for this Instance instance
*
* \param error lambda callback that will get called when an error message needs to be displayed. \see ErrorCb
* \param login lambda callback that will get called when a login dialog needs to be displayed. \see LoginCb
* \param question lambda callback that will get called when a question dialog needs to be displayed. \see QuestionCb
* \param dspProgress lambda callback that will get called when a progress dialog needs to be displayed. \see DspProgressCb
* \param cancel lambda callback that will get called when a displayed dialog needs to be cancelled. \see CancelCb
* \param updtProgress lambda callback that will get called when a progress dialog needs to be updated. \see UpdtProgressCb
*/
template <class Error, class Login, class Question, class DspProgress, class Cancel, class UpdtProgress>
void setDialogHandlers(Error&& error, Login&& login, Question&& question, DspProgress&& dspProgress, Cancel &&cancel, UpdtProgress &&updtProgress)
{
static_assert(signature_match_or_nullptr<Error, ErrorCb>::value, "Mismatched error display callback prototype");
static_assert(signature_match_or_nullptr<Login, LoginCb>::value, "Mismatched login display callback prototype");
static_assert(signature_match_or_nullptr<Question, QuestionCb>::value, "Mismatched question display callback prototype");
static_assert(signature_match_or_nullptr<DspProgress, DspProgressCb>::value, "Mismatched progress display callback prototype");
static_assert(signature_match_or_nullptr<Cancel, CancelCb>::value, "Mismatched cancel callback prototype");
static_assert(signature_match_or_nullptr<UpdtProgress, UpdtProgressCb>::value, "Mismatched update progress callback prototype");
m_callbacks_pointers = std::make_shared<libvlc_dialog_cbs>((libvlc_dialog_cbs){
CallbackWrapper<(unsigned)CallbackIdx::ErrorDisplay, decltype(libvlc_dialog_cbs::pf_display_error)>::wrap(*m_callbacks, std::forward<Error>(error)),
CallbackWrapper<(unsigned)CallbackIdx::LoginDisplay, decltype(libvlc_dialog_cbs::pf_display_login)>::wrap(*m_callbacks, std::forward<Login>(login)),
CallbackWrapper<(unsigned)CallbackIdx::QuestionDisplay, decltype(libvlc_dialog_cbs::pf_display_question)>::wrap(*m_callbacks, std::forward<Question>(question)),
CallbackWrapper<(unsigned)CallbackIdx::ProgressDisplay, decltype(libvlc_dialog_cbs::pf_display_progress)>::wrap(*m_callbacks, std::forward<DspProgress>(dspProgress)),
CallbackWrapper<(unsigned)CallbackIdx::CancelDialog, decltype(libvlc_dialog_cbs::pf_cancel)>::wrap(*m_callbacks, std::forward<Cancel>(cancel)),
CallbackWrapper<(unsigned)CallbackIdx::ProgressUpdate, decltype(libvlc_dialog_cbs::pf_update_progress)>::wrap(*m_callbacks, std::forward<UpdtProgress>(updtProgress))
});
libvlc_dialog_set_callbacks(*this, m_callbacks_pointers.get(), m_callbacks.get());
}
/**
* Unset all callbacks
*/
void unsetDialogHandlers()
{
memset(m_callbacks_pointers.get(), 0, sizeof(libvlc_dialog_cbs));
std::fill(m_callbacks->begin() + 2, m_callbacks->end(), nullptr);
libvlc_dialog_set_callbacks(*this, nullptr, nullptr);
}
};
} // namespace VLC
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment