2015-01-06 14:37:26 +01:00
|
|
|
/*
|
2018-04-07 01:00:25 +02:00
|
|
|
ELEMENT-ACCESS.hpp - access to generic elements in the UI
|
2015-01-06 14:37:26 +01:00
|
|
|
|
|
|
|
|
Copyright (C) Lumiera.org
|
|
|
|
|
2015, Hermann Vosseler <Ichthyostega@web.de>
|
|
|
|
|
|
|
|
|
|
This program is free software; you can redistribute it and/or
|
|
|
|
|
modify it under the terms of the GNU General Public License as
|
|
|
|
|
published by the Free Software Foundation; either version 2 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 General Public License for more details.
|
|
|
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
|
|
|
along with this program; if not, write to the Free Software
|
|
|
|
|
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
2018-04-07 01:00:25 +02:00
|
|
|
/** @file element-access.hpp
|
2018-04-07 02:28:29 +02:00
|
|
|
** Interface to discover and access raw UI elements in a cross cutting way.
|
|
|
|
|
** We have several orthogonal identification and access schemes within the UI.
|
|
|
|
|
** A naively written UI application just attaches the core logic below some widgets and
|
|
|
|
|
** controllers -- not only does this lead to a hard to maintain codebase, this approach
|
|
|
|
|
** is even outright impossible for Lumiera, since the core is able to run standalone and
|
|
|
|
|
** the UI is loaded as plug-in, which places us into the situation to connect a self
|
|
|
|
|
** contained core with a self contained UI. This is a binding, which, as a sideline, also
|
|
|
|
|
** generates a control structure of its own. An another kind of generic access happens
|
|
|
|
|
** when we _navigate_ the topological UI structure for focus management.
|
2015-01-06 14:37:26 +01:00
|
|
|
**
|
2018-04-07 02:28:29 +02:00
|
|
|
** This interface defines an abstract service to translate a generic element designation
|
|
|
|
|
** into a (language level) access to internal structures of the UI toolkit (GTK in our case).
|
|
|
|
|
** This access to low-level structure proceeds in two stages:
|
|
|
|
|
** - navigate down the UI topology. Optionally, this may involve a mutation (create element)
|
|
|
|
|
** - evaluate the result (found, not found, element created) and access the target,
|
|
|
|
|
** possibly with conversion (which might fail)
|
|
|
|
|
**
|
|
|
|
|
** @note as of 4/2018 this is a first draft and WIP-WIP-WIP
|
2018-04-07 01:00:25 +02:00
|
|
|
** @todo WIP ///////////////////////TICKET #1134
|
2015-01-06 14:37:26 +01:00
|
|
|
**
|
2018-04-07 02:28:29 +02:00
|
|
|
** @see ElementAccess_test
|
|
|
|
|
** @see elem-access-dir.hpp implementation
|
2015-01-06 14:37:26 +01:00
|
|
|
**
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
2018-04-07 01:00:25 +02:00
|
|
|
#ifndef GUI_MODEL_ELEMENT_ACCESS_H
|
|
|
|
|
#define GUI_MODEL_ELEMENT_ACCESS_H
|
2015-01-06 14:37:26 +01:00
|
|
|
|
|
|
|
|
|
|
|
|
|
#include "lib/error.hpp"
|
2018-03-24 05:35:13 +01:00
|
|
|
#include "lib/nocopy.hpp"
|
2018-04-07 02:28:29 +02:00
|
|
|
#include "lib/result.hpp"
|
2018-04-09 00:51:24 +02:00
|
|
|
#include "include/limits.h"
|
|
|
|
|
#include "lib/access-casted.hpp"
|
2018-04-07 02:28:29 +02:00
|
|
|
#include "gui/interact/ui-coord.hpp"
|
2018-04-09 00:51:24 +02:00
|
|
|
//#include "lib/format-string.hpp"
|
2015-01-06 14:37:26 +01:00
|
|
|
//#include "lib/symbol.hpp"
|
2018-04-07 02:28:29 +02:00
|
|
|
//#include "lib/util.hpp"
|
2015-01-06 14:37:26 +01:00
|
|
|
|
2018-04-09 00:51:24 +02:00
|
|
|
#include <string>
|
2015-01-06 14:37:26 +01:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
namespace gui {
|
|
|
|
|
namespace model {
|
2018-04-09 00:51:24 +02:00
|
|
|
namespace error = lumiera::error;
|
2015-01-06 14:37:26 +01:00
|
|
|
|
2018-04-07 02:28:29 +02:00
|
|
|
using interact::UICoord;
|
|
|
|
|
// using util::isnil;
|
2018-04-09 00:51:24 +02:00
|
|
|
using std::string;
|
2015-01-06 14:37:26 +01:00
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
2018-04-07 02:28:29 +02:00
|
|
|
* Interface: access UI elements by navigating the UI topology.
|
2015-01-06 14:37:26 +01:00
|
|
|
*
|
2018-04-07 02:28:29 +02:00
|
|
|
* @see gui::interact::Navigator
|
|
|
|
|
* @see ElementAccess_test
|
2015-01-06 14:37:26 +01:00
|
|
|
*/
|
2018-04-07 01:00:25 +02:00
|
|
|
class ElementAccess
|
2018-04-07 02:28:29 +02:00
|
|
|
: util::NonCopyable
|
2015-01-06 14:37:26 +01:00
|
|
|
{
|
|
|
|
|
|
|
|
|
|
public:
|
2018-04-07 02:28:29 +02:00
|
|
|
virtual ~ElementAccess () { } ///< this is an interface
|
|
|
|
|
|
2015-01-06 14:37:26 +01:00
|
|
|
|
2018-04-07 02:28:29 +02:00
|
|
|
template<class TAR>
|
|
|
|
|
using Result = lib::Result<TAR>;
|
2015-01-06 14:37:26 +01:00
|
|
|
|
2018-04-07 02:28:29 +02:00
|
|
|
/* == Access by Location == */
|
2015-01-06 14:37:26 +01:00
|
|
|
|
2018-04-07 02:28:29 +02:00
|
|
|
template<class TAR>
|
|
|
|
|
Result<TAR&> access (UICoord destination);
|
2015-01-06 14:37:26 +01:00
|
|
|
|
2018-04-07 02:28:29 +02:00
|
|
|
template<class TAR>
|
2018-04-09 00:51:24 +02:00
|
|
|
Result<TAR&> access_or_create (UICoord destination, size_t limitCreation = LUMIERA_MAX_ORDINAL_NUMBER);
|
2015-01-06 14:37:26 +01:00
|
|
|
|
2018-04-07 02:28:29 +02:00
|
|
|
|
|
|
|
|
protected:
|
2018-04-09 00:51:24 +02:00
|
|
|
/** @internal drill down according to coordinates, maybe create element */
|
|
|
|
|
virtual void* performAccessTo (UICoord, size_t limitCreation) =0;
|
2015-01-06 14:37:26 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2018-04-09 00:51:24 +02:00
|
|
|
/** Navigate the UI topology to access the designated component.
|
|
|
|
|
* @tparam TAR type of result element expected at the designated location
|
2018-04-07 02:28:29 +02:00
|
|
|
* @return suitably converted direct (language) reference to the desired element
|
|
|
|
|
* wrapped as _result proxy_
|
2018-04-09 00:51:24 +02:00
|
|
|
* @throw error::Invalid when the designated element exists, but is not
|
|
|
|
|
* type or conversion compatible to the expected result type
|
2018-04-07 02:28:29 +02:00
|
|
|
* @note when access was not possible because the element does not exist,
|
|
|
|
|
* the result proxy is empty and convertible to `bool(false)`
|
|
|
|
|
*/
|
|
|
|
|
template<class TAR>
|
|
|
|
|
inline ElementAccess::Result<TAR&>
|
|
|
|
|
ElementAccess::access (UICoord destination)
|
|
|
|
|
{
|
2018-04-09 00:51:24 +02:00
|
|
|
void* targetElm = performAccessTo (destination, 0);
|
|
|
|
|
if (targetElm)
|
|
|
|
|
return *util::AccessCasted<TAR*>::access (targetElm);
|
|
|
|
|
else
|
|
|
|
|
return "In current UI, there is no element at location "+string(destination);
|
2018-04-07 02:28:29 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** Navigate to the designated component, possibly create the element and parents
|
|
|
|
|
* @return suitably converted direct (language) reference to the desired element
|
|
|
|
|
* wrapped as _result proxy_
|
|
|
|
|
* @note when access was not possible because the element could not been created,
|
|
|
|
|
* the result proxy is empty and convertible to `bool(false)`
|
2015-01-06 14:37:26 +01:00
|
|
|
*/
|
2018-04-07 02:28:29 +02:00
|
|
|
template<class TAR>
|
|
|
|
|
inline ElementAccess::Result<TAR&>
|
2018-04-09 00:51:24 +02:00
|
|
|
ElementAccess::access_or_create (UICoord destination, size_t limitCreation)
|
2015-01-06 14:37:26 +01:00
|
|
|
{
|
2018-04-07 02:28:29 +02:00
|
|
|
UNIMPLEMENTED ("delegate to a suitable polymorphic navigation/creation function");
|
2015-01-06 14:37:26 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}} // namespace gui::model
|
2018-04-07 01:00:25 +02:00
|
|
|
#endif /*GUI_MODEL_ELEMENT_ACCESS_H*/
|