FDataPtr was replaced by the template class FData

This commit is contained in:
Markus Gans 2020-09-18 17:13:52 +02:00
parent ff555baf3b
commit 5092244b81
45 changed files with 679 additions and 416 deletions

View File

@ -1,3 +1,7 @@
2020-09-18 Markus Gans <guru.mail@muenster.de>
* The generic data type FDataPtr is now deprecated and was
completely replaced by the template class FData
2020-09-11 Markus Gans <guru.mail@muenster.de>
* Fixes a problem with mouse input in Cygwin in non-blocking read mode

View File

@ -431,7 +431,7 @@ class extendedApplication : public FApplication
|| last_avg[2] != load_avg[2] )
{
FUserEvent user_event(fc::User_Event, 0);
user_event.setData (FDataPtr(&load_avg));
user_event.setData (load_avg);
FApplication::sendEvent (getMainWidget(), &user_event);
}
@ -458,8 +458,7 @@ class dialogWidget final : public FDialog
private:
void onUserEvent (FUserEvent* ev) override
{
FDataPtr dataPtr = ev->getData();
auto& lavg = *(reinterpret_cast<LoadAvg*>(dataPtr));
const auto& lavg = ev->getData<LoadAvg>();
std::setlocale(LC_NUMERIC, "C");
loadavg_label.clear();
loadavg_label << "Load average: " << lavg[0] << ", "

View File

@ -108,8 +108,7 @@ Background::Background (finalcut::FWidget* parent)
for (auto& c : color_list)
{
FDataPtr data_ptr = reinterpret_cast<FDataPtr>(&c.second);
finalcut::FListBoxItem item (c.first, data_ptr);
finalcut::FListBoxItem item (c.first, c.second);
color_choice.insert(item);
}
@ -199,9 +198,8 @@ void Background::cb_choice()
uChar r{};
uChar g{};
uChar b{};
const FDataPtr data_ptr = color_choice.getItemData();
const RGB* rgb = reinterpret_cast<RGB*>(data_ptr);
std::tie(r, g, b) = *rgb;
const RGB rgb = color_choice.getItemData<RGB>();
std::tie(r, g, b) = rgb;
red.setValue(r);
green.setValue(g);
blue.setValue(b);

View File

@ -38,8 +38,8 @@ static std::weak_ptr<FString> temp_str;
// Function prototypes
void doubleToItem ( FListBoxItem&
, FDataPtr container
, int index);
, FDataAccess* container
, std::size_t index);
FString& doubleToString (std::list<double>::const_iterator iter);
FString& mapToString ( std::map<FString
, FString>::const_iterator iter );
@ -47,14 +47,15 @@ FString& mapToString ( std::map<FString
// Lazy conversion insert function
void doubleToItem ( FListBoxItem& item
, FDataPtr container, int index)
, FDataAccess* container
, std::size_t index )
{
typedef std::list<double>* double_list_ptr;
double_list_ptr dbllist = static_cast<double_list_ptr>(container);
std::list<double>::iterator iter = dbllist->begin();
typedef std::list<double> DblList;
DblList& dbl_list = FListBoxHelper::getContainer<DblList>(container);
std::list<double>::iterator iter = dbl_list.begin();
std::advance (iter, index);
item.setText (FString() << *iter);
item.setData (FDataPtr(&(*iter)));
item.setData (*iter);
}
// Insert converter functions
@ -129,7 +130,7 @@ Listbox::Listbox (FWidget* parent)
//
// Insert via lazy conversion on print
//
list2.insert (&double_list, doubleToItem);
list2.insert (double_list, doubleToItem); // (container, converter)
//
// Direct insert of the complete list

View File

@ -199,7 +199,9 @@ class Window final : public finalcut::FDialog
void configureDialogButtons();
void activateWindow (finalcut::FDialog*) const;
void adjustSize() override;
template<typename InstanceT, typename CallbackT, typename... Args>
template <typename InstanceT
, typename CallbackT
, typename... Args>
void addClickedCallback ( finalcut::FWidget*
, InstanceT&&, CallbackT&&, Args&&... );
template <typename IteratorT>
@ -378,7 +380,9 @@ void Window::adjustSize()
}
//----------------------------------------------------------------------
template<typename InstanceT, typename CallbackT, typename... Args>
template <typename InstanceT
, typename CallbackT
, typename... Args>
void Window::addClickedCallback ( finalcut::FWidget* widget
, InstanceT&& instance
, CallbackT&& callback

View File

@ -10,7 +10,7 @@ function create_code_file ()
echo -e "#define ${INCLUDE_GUARD}\\n"
echo -e "namespace finalcut\\n{\\n"
echo -e "namespace fc\\n{\\n"
echo -e "static unsigned char ${NAME}[] =\\n{"
echo -e "constexpr unsigned char ${NAME}[] =\\n{"
grep -A"${HEIGHT}" "^BITMAP" "$NEWFONTFILE" \
| tr '\n' ',' \

View File

@ -9,7 +9,7 @@ namespace finalcut
namespace fc
{
static unsigned char __8x16graph[] =
constexpr unsigned char __8x16graph[] =
{
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0 */
0x00, 0x00, 0x7e, 0x81, 0xa5, 0x81, 0x81, 0xbd, 0x99, 0x81, 0x81, 0x7e, 0x00, 0x00, 0x00, 0x00, /* 1 */

View File

@ -9,7 +9,7 @@ namespace finalcut
namespace fc
{
static unsigned char __9x16graph[] =
constexpr unsigned char __9x16graph[] =
{
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0 */
0x00, 0x00, 0x7e, 0x81, 0xa5, 0x81, 0x81, 0xbd, 0x99, 0x81, 0x81, 0x7e, 0x00, 0x00, 0x00, 0x00, /* 1 */

View File

@ -17,7 +17,7 @@ namespace finalcut
namespace fc
{
static struct unipair unicode_cp437_pairs[] =
constexpr struct unipair unicode_cp437_pairs[] =
{
// .----------- unicode
// | .---- fontpos
@ -306,7 +306,7 @@ static struct unipair unicode_cp437_pairs[] =
{0x266c, 0x0e}
};
static struct unipair unicode_newfont_pairs[] =
constexpr struct unipair unicode_newfont_pairs[] =
{
// .----------- unicode
// | .---- fontpos

View File

@ -9,7 +9,7 @@ namespace finalcut
namespace fc
{
static unsigned char __8x16std[] =
constexpr unsigned char __8x16std[] =
{
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0 */
0x00, 0x00, 0x7e, 0x81, 0xa5, 0x81, 0x81, 0xbd, 0x99, 0x81, 0x81, 0x7e, 0x00, 0x00, 0x00, 0x00, /* 1 */

View File

@ -121,6 +121,12 @@ FApplication* FApplication::getApplicationObject()
return app_object;
}
//----------------------------------------------------------------------
FWidget* FApplication::getKeyboardWidget()
{
return keyboard_widget;
}
//----------------------------------------------------------------------
FApplication::FLogPtr& FApplication::getLog()
{
@ -306,6 +312,12 @@ void FApplication::setDarkTheme()
setColorTheme<default16ColorDarkTheme>();
}
//----------------------------------------------------------------------
void FApplication::setKeyboardWidget (FWidget* widget)
{
keyboard_widget = widget;
}
//----------------------------------------------------------------------
void FApplication::closeConfirmationDialog (FWidget* w, FCloseEvent* ev)
{

View File

@ -3,7 +3,7 @@
* *
* This file is part of the FINAL CUT widget toolkit *
* *
* Copyright 2015-2019 Markus Gans *
* Copyright 2015-2020 Markus Gans *
* *
* FINAL CUT is free software; you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License as *
@ -163,7 +163,7 @@ const std::size_t lastCharItem = \
std::size_t((sizeof(character) / sizeof(character[0])) - 1);
int vt100_key_to_utf8[][2] =
constexpr int vt100_key_to_utf8[][2] =
{
{fc::vt100_key_rarrow , fc::BlackRightPointingPointer}, // ►
{fc::vt100_key_larrow , fc::BlackLeftPointingPointer}, // ◄
@ -210,7 +210,7 @@ const std::size_t lastKeyItem = \
std::size_t((sizeof(vt100_key_to_utf8) / sizeof(vt100_key_to_utf8[0])) - 1);
wchar_t cp437_ucs[][2] =
constexpr wchar_t cp437_ucs[][2] =
{
{0x00, 0x0000}, // null
{0x01, 0x263a}, // white smiling face
@ -474,7 +474,7 @@ const std::size_t lastCP437Item = \
std::size_t((sizeof(cp437_ucs) / sizeof(cp437_ucs[0])) - 1);
// Based on http://www.unicode.org/charts/PDF/UFF00.pdf
const wchar_t halfWidth_fullWidth[][2] =
constexpr wchar_t halfWidth_fullWidth[][2] =
{
// Fullwidth ASCII variants
{0x0020, 0x3000}, // ' ' -> ' '

View File

@ -366,18 +366,13 @@ FUserEvent::FUserEvent (fc::events ev_type, int user_event_id) // constructor
//----------------------------------------------------------------------
FUserEvent::~FUserEvent() // destructor
{ }
{
if ( ! external_data_pointer && data_pointer )
delete data_pointer;
}
//----------------------------------------------------------------------
int FUserEvent::getUserId() const
{ return uid; }
//----------------------------------------------------------------------
FDataPtr FUserEvent::getData() const
{ return data_pointer; }
//----------------------------------------------------------------------
void FUserEvent::setData (FDataPtr data)
{ data_pointer = data; }
} // namespace finalcut

View File

@ -214,7 +214,7 @@ FKeyMap fkey[] =
{ 0 , nullptr, "\0" }
};
FMetakeyMap fmetakey[] =
constexpr FMetakeyMap fmetakey[] =
{
{ fc::Fmkey_ic , "\033[2;3~" }, // M-insert
{ fc::Fmkey_ic , "\033\033[2~" }, // M-insert
@ -447,7 +447,7 @@ FMetakeyMap fmetakey[] =
{ 0 , "\0" }
};
FKeyName fkeyname[] =
constexpr FKeyName fkeyname[] =
{
{ fc::Fckey_a , "Ctrl+A" },
{ fc::Fckey_b , "Ctrl+B" },

View File

@ -51,12 +51,6 @@ FListBoxItem::FListBoxItem (const FListBoxItem& item)
, selected{item.selected}
{ }
//----------------------------------------------------------------------
FListBoxItem::FListBoxItem (const FString& txt, FDataPtr data)
: text{txt}
, data_pointer{data}
{ }
//----------------------------------------------------------------------
FListBoxItem::~FListBoxItem() // destructor
{ }
@ -95,6 +89,9 @@ FListBox::FListBox (FWidget* parent)
//----------------------------------------------------------------------
FListBox::~FListBox() // destructor
{
if ( source_container )
delete source_container; // for lazy conversion
delOwnTimers();
}
@ -1729,12 +1726,12 @@ void FListBox::changeOnResize() const
}
//----------------------------------------------------------------------
void FListBox::lazyConvert(listBoxItems::iterator iter, int y)
void FListBox::lazyConvert(listBoxItems::iterator iter, std::size_t y)
{
if ( conv_type != lazy_convert || ! iter->getText().isNull() )
return;
lazy_inserter (*iter, source_container, y + yoffset);
lazy_inserter (*iter, source_container, y + std::size_t(yoffset));
const auto column_width = getColumnWidth(iter->text);
recalculateHorizontalBar (column_width, hasBrackets(iter));

View File

@ -198,21 +198,6 @@ FListViewItem::FListViewItem (iterator parent_iter)
insert (this, parent_iter);
}
//----------------------------------------------------------------------
FListViewItem::FListViewItem ( const FStringList& cols
, FDataPtr data
, iterator parent_iter )
: FObject{nullptr}
, column_list{cols}
, data_pointer{data}
{
if ( cols.empty() )
return;
replaceControlCodes();
insert (this, parent_iter);
}
//----------------------------------------------------------------------
FListViewItem::~FListViewItem() // destructor
{
@ -895,33 +880,6 @@ FObject::iterator FListView::insert ( FListViewItem* item
return item_iter;
}
//----------------------------------------------------------------------
FObject::iterator FListView::insert ( const FStringList& cols
, FDataPtr d
, iterator parent_iter )
{
FListViewItem* item;
if ( cols.empty() || parent_iter == getNullIterator() )
return getNullIterator();
if ( ! *parent_iter )
parent_iter = root;
try
{
item = new FListViewItem (cols, d, getNullIterator());
}
catch (const std::bad_alloc&)
{
badAllocOutput ("FListViewItem");
return getNullIterator();
}
item->replaceControlCodes();
return insert(item, parent_iter);
}
//----------------------------------------------------------------------
void FListView::remove (FListViewItem* item)
{

View File

@ -605,9 +605,6 @@ void FMenuItem::createDialogList (FMenu* winmenu) const
while ( iter != getDialogList()->end() && *iter )
{
auto win = static_cast<FDialog*>(*iter);
if ( win )
{
FMenuItem* win_item{};
const uInt32 n = uInt32(std::distance(first, iter));
// get the dialog title
@ -644,8 +641,6 @@ void FMenuItem::createDialogList (FMenu* winmenu) const
);
win_item->associated_window = win;
}
++iter;
}
}

View File

@ -1212,7 +1212,7 @@ inline void FString::_initLength (std::size_t len)
try
{
string = new wchar_t[bufsize]();
string = new wchar_t[bufsize];
std::wmemset (string, L'\0', bufsize);
}
catch (const std::bad_alloc&)
@ -1244,7 +1244,7 @@ void FString::_assign (const wchar_t s[])
try
{
string = new wchar_t[bufsize]();
string = new wchar_t[bufsize];
}
catch (const std::bad_alloc&)
{
@ -1272,7 +1272,7 @@ void FString::_insert (std::size_t len, const wchar_t s[])
try
{
string = new wchar_t[bufsize]();
string = new wchar_t[bufsize];
}
catch (const std::bad_alloc&)
{
@ -1319,7 +1319,7 @@ void FString::_insert ( std::size_t pos
try
{
sptr = new wchar_t[bufsize](); // generate new string
sptr = new wchar_t[bufsize]; // generate new string
}
catch (const std::bad_alloc&)
{
@ -1363,7 +1363,7 @@ void FString::_remove (std::size_t pos, std::size_t len)
try
{
sptr = new wchar_t[bufsize](); // generate new string
sptr = new wchar_t[bufsize]; // generate new string
}
catch (const std::bad_alloc&)
{
@ -1417,7 +1417,7 @@ inline const char* FString::_to_cstring (const wchar_t s[]) const
try
{
c_string = new char[size]();
c_string = new char[size];
// pre-initialiaze the whole string with '\0'
std::memset (c_string, '\0', size);
@ -1467,7 +1467,7 @@ inline const wchar_t* FString::_to_wcstring (const char s[]) const
try
{
dest = new wchar_t[size]();
dest = new wchar_t[size];
// pre-initialiaze the whole string with '\0'
std::wmemset (dest, L'\0', size);
}

View File

@ -141,15 +141,15 @@ void FSwitch::drawCheckButton()
//----------------------------------------------------------------------
inline void FSwitch::drawChecked()
{
wchar_t on[6]{L" On "};
const wchar_t off[6]{L" Off "};
FString on{L" On "};
const FString off{L" Off "};
const auto& wc = getColorTheme();
if ( hasFocus() && ! button_pressed )
{
if ( FTerm::isMonochron() )
{
std::wcsncpy (on, L" <On>", 6);
on.setString(L" <On>");
setBold(true);
}
else if ( FTerm::getMaxColor() < 16 )
@ -191,8 +191,8 @@ inline void FSwitch::drawChecked()
//----------------------------------------------------------------------
inline void FSwitch::drawUnchecked()
{
const wchar_t on[6]{L" On "};
wchar_t off[6]{L" Off "};
const FString on{L" On "};
FString off{L" Off "};
const auto& wc = getColorTheme();
setColor (wc->button_inactive_fg, wc->button_inactive_bg);
@ -206,7 +206,7 @@ inline void FSwitch::drawUnchecked()
{
if ( FTerm::isMonochron() )
{
std::wcsncpy (off, L"<Off>", 6);
off.setString(L"<Off>");
setBold(true);
}
else if ( FTerm::getMaxColor() < 16 )

View File

@ -278,7 +278,7 @@ bool FTermLinux::loadVGAFont()
struct unimapdesc unimap;
unimap.entry_ct = uInt16 ( sizeof(fc::unicode_cp437_pairs)
/ sizeof(unipair) );
unimap.entries = &fc::unicode_cp437_pairs[0];
unimap.entries = const_cast<unipair*>(&fc::unicode_cp437_pairs[0]);
setUnicodeMap(&unimap);
}
else
@ -327,7 +327,7 @@ bool FTermLinux::loadNewFont()
struct unimapdesc unimap;
unimap.entry_ct = uInt16 ( sizeof(fc::unicode_newfont_pairs)
/ sizeof(unipair) );
unimap.entries = &fc::unicode_newfont_pairs[0];
unimap.entries = const_cast<unipair*>(&fc::unicode_newfont_pairs[0]);
setUnicodeMap(&unimap);
}
else
@ -660,7 +660,7 @@ FTermLinux::modifier_key& FTermLinux::getModifierKey()
}
//----------------------------------------------------------------------
int FTermLinux::setScreenFont ( uChar fontdata[], uInt count
int FTermLinux::setScreenFont ( const uChar fontdata[], uInt count
, uInt fontwidth, uInt fontheight
, bool direct)
{
@ -681,7 +681,7 @@ int FTermLinux::setScreenFont ( uChar fontdata[], uInt count
font.charcount = count;
if ( direct )
font.data = fontdata;
font.data = const_cast<uChar*>(fontdata);
else
{
const std::size_t bytes_per_line = font.width / 8;

View File

@ -1471,20 +1471,17 @@ FVTerm::covered_state FVTerm::isCovered ( const FPoint& pos
if ( FWidget::getWindowList() && ! FWidget::getWindowList()->empty() )
{
bool found( area == vdesktop );
bool found{ area == vdesktop };
for (auto& win_obj : *FWidget::getWindowList())
{
const auto& win = win_obj->getVWin();
if ( ! win )
if ( ! (win && win->visible) )
continue;
if ( ! win->visible )
continue;
const int win_x = win->offset_left;
const int win_y = win->offset_top;
const int& win_x = win->offset_left;
const int& win_y = win->offset_top;
const FRect geometry { win_x , win_y
, std::size_t(win->width) + std::size_t(win->right_shadow)
, std::size_t(win->height) + std::size_t(win->bottom_shadow) };
@ -1492,9 +1489,9 @@ FVTerm::covered_state FVTerm::isCovered ( const FPoint& pos
if ( found && geometry.contains(pos) )
{
const int width = win->width + win->right_shadow;
const int x = pos.getX();
const int y = pos.getY();
auto tmp = &win->data[(y - win_y) * width + (x - win_x)];
const int& x = pos.getX();
const int& y = pos.getY();
const auto& tmp = &win->data[(y - win_y) * width + (x - win_x)];
if ( tmp->attr.bit.color_overlay )
{

View File

@ -109,6 +109,10 @@ FWidget::~FWidget() // destructor
if ( this == getClickedWidget() )
setClickedWidget(nullptr);
// unset keyboard widget
if ( this == FApplication::getKeyboardWidget() )
FApplication::setKeyboardWidget(nullptr);
// unset the local window widget focus
if ( flags.focus )
{

View File

@ -114,6 +114,7 @@ class FApplication : public FWidget
int getArgc() const;
char** getArgv() const;
static FApplication* getApplicationObject();
static FWidget* getKeyboardWidget();
static FLogPtr& getLog();
// Mutator
@ -136,6 +137,7 @@ class FApplication : public FWidget
void initTerminal() override;
static void setDefaultTheme();
static void setDarkTheme();
static void setKeyboardWidget (FWidget*);
static void closeConfirmationDialog (FWidget*, FCloseEvent*);
// Callback method

View File

@ -3,7 +3,7 @@
* *
* This file is part of the FINAL CUT widget toolkit *
* *
* Copyright 2015-2019 Markus Gans *
* Copyright 2015-2020 Markus Gans *
* *
* FINAL CUT is free software; you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License as *
@ -39,10 +39,10 @@ namespace fc
extern uInt character[][fc::NUM_OF_ENCODINGS];
extern const std::size_t lastCharItem;
extern int vt100_key_to_utf8[][2];
extern const int vt100_key_to_utf8[][2];
extern const std::size_t lastKeyItem;
extern wchar_t cp437_ucs[][2];
extern const wchar_t cp437_ucs[][2];
extern const std::size_t lastCP437Item;
extern const wchar_t halfWidth_fullWidth[][2];

View File

@ -150,7 +150,8 @@ class FComboBox : public FWidget
const FString getClassName() const override;
std::size_t getCount() const;
FString getText() const;
FDataPtr getItemData();
template <typename DT>
clean_fdata_t<DT>& getItemData();
FLineEdit::label_o getLabelOrientation() const;
// Mutators
@ -182,11 +183,13 @@ class FComboBox : public FWidget
// Methods
void insert (const FListBoxItem&);
template <typename T>
template <typename T
, typename DT = std::nullptr_t>
void insert ( const std::initializer_list<T>& list
, FDataPtr = nullptr );
template <typename ItemT>
void insert (const ItemT&, FDataPtr = nullptr);
, DT&& = DT() );
template <typename ItemT
, typename DT = std::nullptr_t>
void insert (const ItemT&, DT&& = DT());
void remove (std::size_t);
void reserve (std::size_t);
void clear();
@ -247,10 +250,11 @@ inline FString FComboBox::getText() const
{ return input_field.getText(); }
//----------------------------------------------------------------------
inline FDataPtr FComboBox::getItemData()
template <typename DT>
inline clean_fdata_t<DT>& FComboBox::getItemData()
{
const std::size_t index = list_window.list.currentItem();
return list_window.list.getItem(index).getData();
return list_window.list.getItem(index).getData<DT>();
}
//----------------------------------------------------------------------
@ -298,21 +302,23 @@ inline bool FComboBox::hasShadow() const
{ return getFlags().shadow; }
//----------------------------------------------------------------------
template <typename T>
void FComboBox::insert (const std::initializer_list<T>& list, FDataPtr d)
template <typename T
, typename DT>
void FComboBox::insert (const std::initializer_list<T>& list, DT&& d)
{
for (auto& item : list)
{
FListBoxItem listItem (FString() << item, d);
FListBoxItem listItem (FString() << item, std::forward<DT>(d));
insert (listItem);
}
}
//----------------------------------------------------------------------
template <typename ItemT>
void FComboBox::insert (const ItemT& item, FDataPtr d)
template <typename ItemT
, typename DT>
void FComboBox::insert (const ItemT& item, DT&& d)
{
FListBoxItem listItem (FString() << item, d);
FListBoxItem listItem (FString() << item, std::forward<DT>(d));
insert (listItem);
}

View File

@ -20,6 +20,19 @@
* <http://www.gnu.org/licenses/>. *
***********************************************************************/
/* Inheritance diagram
*
*
*
* FDataAccess
*
*
*
*
* FData
*
*/
#ifndef FDATA_H
#define FDATA_H
@ -29,11 +42,55 @@
#include <utility>
template<typename T>
struct FData
namespace finalcut
{
explicit FData (T v) // constructor
//----------------------------------------------------------------------
// struct FDataAccess
//----------------------------------------------------------------------
template <typename T>
struct FData; // Class forward declaration
struct FDataAccess
{
public:
virtual ~FDataAccess();
template <typename T>
const T& get() const
{
return static_cast<const FData<T>&>(*this).get();
}
template <typename T
, typename V>
void set (const V& v)
{
static_cast<FData<T>&>(*this).set(v);
}
};
//----------------------------------------------------------------------
inline FDataAccess::~FDataAccess()
{ }
//----------------------------------------------------------------------
// struct FData
//----------------------------------------------------------------------
template <typename T>
struct FData : public FDataAccess
{
explicit FData (T& v) // constructor
: value_ref{v}
{ }
explicit FData (T&& v) // constructor
: value{v}
, value_ref{value}
{ }
~FData() // destructor
@ -41,64 +98,131 @@ struct FData
FData (const FData& d) // Copy constructor
: value{d.value}
, value_ref{d.value_ref}
{ }
FData& operator = (const FData& d) // Copy assignment operator (=)
{
value = d.value;
return *this;
}
FData (FData&& d) noexcept // Move constructor
: value{std::move(d.value)}
{ }
FData& operator = (FData&& d) noexcept // Move assignment operator (=)
{
value = std::move(d.value);
value_ref = d.value_ref;
return *this;
}
T operator () () const
{
return value;
return value_ref;
}
template <typename... Args>
T operator () (Args... args) const
{
return value(args...);
return value_ref(args...);
}
explicit operator T () const
{
return value;
return value_ref;
}
T& get()
{
return value;
return value_ref;
}
void set (const T& v)
{
value = v;
value_ref = v;
}
bool isInitializedCopy()
{
return bool(value);
}
bool isInitializedReference()
{
return ! isInitializedCopy();
}
FData& operator << (const T& v)
{
value = v;
value_ref = v;
return *this;
}
friend std::ostream& operator << (std::ostream &os, const FData& data)
{
os << data.value;
os << data.value_ref;
return os;
}
T value;
private:
T value{};
public:
T& value_ref;
};
#endif // FDATA_H
// non-member functions
//----------------------------------------------------------------------
namespace internal
{
template <typename T
, bool isArray = std::is_array<T>::value
, bool isFunction = std::is_function<T>::value>
struct cleanCondition;
//----------------------------------------------------------------------
template <typename T>
struct cleanCondition<T, false, false>
{
// Leave the type untouched
typedef T type;
};
//----------------------------------------------------------------------
template <typename T>
struct cleanCondition<T, true, false>
{
// Array to pointer
typedef typename std::remove_extent<T>::type* type;
};
//----------------------------------------------------------------------
template <typename T>
struct cleanCondition<T, false, true>
{
// Add pointer to function
typedef typename std::add_pointer<T>::type type;
};
} // namespace internal
//----------------------------------------------------------------------
template <typename T>
class cleanFData
{
private:
typedef typename std::remove_reference<T>::type remove_ref;
public:
// Similar to std::decay, but keeps const and volatile
typedef typename internal::cleanCondition<remove_ref>::type type;
};
//----------------------------------------------------------------------
template <typename T>
using clean_fdata_t = typename cleanFData<T>::type;
//----------------------------------------------------------------------
template <typename T>
constexpr FData<clean_fdata_t<T>>* makeFData (T&& data)
{
return new FData<clean_fdata_t<T>>(std::forward<T>(data));
}
} // namespace finalcut
#endif // FDATA_H

View File

@ -343,14 +343,50 @@ class FUserEvent : public FEvent // user event
FUserEvent& operator = (const FUserEvent&) = delete;
int getUserId() const;
FDataPtr getData() const;
void setData (FDataPtr);
template <typename T>
FData<T>&& getFDataObject() const;
template <typename T>
clean_fdata_t<T>& getData() const;
template <typename T>
void setFDataObject (T&&);
template <typename T>
void setData (T&&);
private:
int uid{0};
FDataPtr data_pointer{nullptr};
FDataAccess* data_pointer{nullptr};
bool external_data_pointer{false};
};
//----------------------------------------------------------------------
template <typename T>
inline FData<T>&& FUserEvent::getFDataObject() const
{
return static_cast<FData<T>&&>(*data_pointer);
}
//----------------------------------------------------------------------
template <typename T>
inline clean_fdata_t<T>& FUserEvent::getData() const
{
return static_cast<FData<clean_fdata_t<T>>&>(*data_pointer).get();
}
//----------------------------------------------------------------------
template <typename T>
inline void FUserEvent::setFDataObject (T&& fdata)
{
external_data_pointer = true;
data_pointer = &(std::forward<T>(fdata));
}
//----------------------------------------------------------------------
template <typename T>
inline void FUserEvent::setData (T&& data)
{
external_data_pointer = false;
data_pointer = makeFData(std::forward<T>(data));
}
} // namespace finalcut
#endif // FEVENT_H

View File

@ -3,7 +3,7 @@
* *
* This file is part of the FINAL CUT widget toolkit *
* *
* Copyright 2015-2019 Markus Gans *
* Copyright 2015-2020 Markus Gans *
* *
* FINAL CUT is free software; you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License as *
@ -34,8 +34,8 @@ namespace fc
{
extern FKeyMap fkey[];
extern FMetakeyMap fmetakey[];
extern FKeyName fkeyname[];
extern const FMetakeyMap fmetakey[];
extern const FKeyName fkeyname[];
} // namespace fc

View File

@ -72,7 +72,8 @@ class FListBoxItem
// Constructors
FListBoxItem ();
FListBoxItem (const FListBoxItem&); // copy constructor
explicit FListBoxItem (const FString&, FDataPtr = nullptr);
template <typename DT = std::nullptr_t>
explicit FListBoxItem (const FString&, DT&& = DT() );
// Destructor
virtual ~FListBoxItem();
@ -83,11 +84,13 @@ class FListBoxItem
// Accessors
virtual const FString getClassName() const;
virtual FString getText() const;
virtual FDataPtr getData() const;
template <typename DT>
clean_fdata_t<DT>& getData() const;
// Mutators
void setText (const FString&);
void setData (FDataPtr);
template <typename DT>
void setData (DT&&);
// Methods
void clear();
@ -95,7 +98,7 @@ class FListBoxItem
private:
// Data members
FString text{};
FDataPtr data_pointer{nullptr};
FDataAccess* data_pointer{nullptr};
fc::brackets_type brackets{fc::NoBrackets};
bool selected{false};
@ -105,6 +108,13 @@ class FListBoxItem
// FListBoxItem inline functions
//----------------------------------------------------------------------
template <typename DT>
inline FListBoxItem::FListBoxItem (const FString& txt, DT&& data)
: text{txt}
, data_pointer{makeFData(std::forward<DT>(data))}
{ }
//----------------------------------------------------------------------
inline const FString FListBoxItem::getClassName() const
{ return "FListBoxItem"; }
@ -114,16 +124,22 @@ inline FString FListBoxItem::getText() const
{ return text; }
//----------------------------------------------------------------------
inline FDataPtr FListBoxItem::getData() const
{ return data_pointer; }
template <typename DT>
inline clean_fdata_t<DT>& FListBoxItem::getData() const
{
return static_cast<FData<clean_fdata_t<DT>>&>(*data_pointer).get();
}
//----------------------------------------------------------------------
inline void FListBoxItem::setText (const FString& txt)
{ text.setString(txt); }
//----------------------------------------------------------------------
inline void FListBoxItem::setData (FDataPtr data)
{ data_pointer = data; }
template <typename DT>
inline void FListBoxItem::setData (DT&& data)
{
data_pointer = makeFData(std::forward<DT>(data));
}
//----------------------------------------------------------------------
inline void FListBoxItem::clear()
@ -145,9 +161,11 @@ class FListBox : public FWidget
// Constructor
explicit FListBox (FWidget* = nullptr);
template <typename Iterator, typename InsertConverter>
template <typename Iterator
, typename InsertConverter>
FListBox (Iterator, Iterator, InsertConverter, FWidget* = nullptr);
template <typename Container, typename LazyConverter>
template <typename Container
, typename LazyConverter>
FListBox (Container, LazyConverter, FWidget* = nullptr);
// Disable copy constructor
@ -197,21 +215,30 @@ class FListBox : public FWidget
// Methods
void hide() override;
template <typename Iterator, typename InsertConverter>
void insert (Iterator, Iterator, InsertConverter);
template <typename Container, typename LazyConverter>
void insert (Container, LazyConverter);
template <typename Iterator
, typename InsertConverter>
void insert ( Iterator, Iterator
, const InsertConverter& );
template <typename Container
, typename LazyConverter>
void insert ( const Container&
, const LazyConverter& );
template <typename Container
, typename LazyConverter>
void insert (Container*, const LazyConverter&);
void insert (const FListBoxItem&);
template <typename T>
template <typename T
, typename DT = std::nullptr_t>
void insert ( const std::initializer_list<T>& list
, fc::brackets_type = fc::NoBrackets
, bool = false
, FDataPtr = nullptr );
template <typename ItemT>
, DT&& = DT() );
template <typename ItemT
, typename DT = std::nullptr_t>
void insert ( const ItemT&
, fc::brackets_type = fc::NoBrackets
, bool = false
, FDataPtr = nullptr );
, DT&& = DT() );
void remove (std::size_t);
void reserve (std::size_t);
void clear();
@ -236,7 +263,7 @@ class FListBox : public FWidget
// Typedefs
typedef std::unordered_map<int, std::function<void()>> keyMap;
typedef std::unordered_map<int, std::function<bool()>> keyMapResult;
typedef std::function<void(FListBoxItem&, FDataPtr, int)> lazyInsert;
typedef std::function<void(FListBoxItem&, FDataAccess*, std::size_t)> lazyInsert;
// Enumeration
enum convert_type
@ -305,7 +332,7 @@ class FListBox : public FWidget
void processSelect() const;
void processChanged() const;
void changeOnResize() const;
void lazyConvert (listBoxItems::iterator, int);
void lazyConvert (listBoxItems::iterator, std::size_t);
listBoxItems::iterator index2iterator (std::size_t);
listBoxItems::const_iterator index2iterator (std::size_t index) const;
// Callback methods
@ -317,7 +344,7 @@ class FListBox : public FWidget
// Data members
listBoxItems itemlist{};
FDataPtr source_container{nullptr};
FDataAccess* source_container{nullptr};
FScrollbarPtr vbar{nullptr};
FScrollbarPtr hbar{nullptr};
FString text{};
@ -342,10 +369,23 @@ class FListBox : public FWidget
bool click_on_list{false};
};
// non-member function
//----------------------------------------------------------------------
namespace FListBoxHelper
{
template <typename Container>
constexpr clean_fdata_t<Container>& getContainer(FDataAccess* container)
{
return static_cast<FData<clean_fdata_t<Container>>&>(*container).get();
}
} // namespace FListBoxHelper
// FListBox inline functions
//----------------------------------------------------------------------
template <typename Iterator, typename InsertConverter>
template <typename Iterator
, typename InsertConverter>
inline FListBox::FListBox ( Iterator first
, Iterator last
, InsertConverter convert
@ -362,7 +402,8 @@ inline FListBox::FListBox ( Iterator first
}
//----------------------------------------------------------------------
template <typename Container, typename LazyConverter>
template <typename Container
, typename LazyConverter>
inline FListBox::FListBox ( Container container
, LazyConverter convert
, FWidget* parent )
@ -475,10 +516,11 @@ inline void FListBox::reserve (std::size_t new_cap)
{ itemlist.reserve(new_cap); }
//----------------------------------------------------------------------
template <typename Iterator, typename InsertConverter>
template <typename Iterator
, typename InsertConverter>
inline void FListBox::insert ( Iterator first
, Iterator last
, InsertConverter convert )
, const InsertConverter& convert )
{
conv_type = direct_convert;
@ -490,13 +532,14 @@ inline void FListBox::insert ( Iterator first
}
//----------------------------------------------------------------------
template <typename Container, typename LazyConverter>
void FListBox::insert (Container container, LazyConverter convert)
template <typename Container
, typename LazyConverter>
void FListBox::insert (const Container& container, const LazyConverter& converter)
{
conv_type = lazy_convert;
source_container = container;
lazy_inserter = convert;
const std::size_t size = container->size();
source_container = makeFData(container);
lazy_inserter = converter;
const std::size_t size = container.size();
if ( size > 0 )
itemlist.resize(size);
@ -505,15 +548,24 @@ void FListBox::insert (Container container, LazyConverter convert)
}
//----------------------------------------------------------------------
template <typename T>
template <typename Container
, typename LazyConverter>
void FListBox::insert (Container* container, const LazyConverter& converter)
{
insert (*container, converter);
}
//----------------------------------------------------------------------
template <typename T
, typename DT>
void FListBox::insert ( const std::initializer_list<T>& list
, fc::brackets_type b
, bool s
, FDataPtr d )
, DT&& d )
{
for (auto& item : list)
{
FListBoxItem listItem (FString() << item, d);
FListBoxItem listItem (FString() << item, std::forward<DT>(d));
listItem.brackets = b;
listItem.selected = s;
insert (listItem);
@ -521,13 +573,14 @@ void FListBox::insert ( const std::initializer_list<T>& list
}
//----------------------------------------------------------------------
template <typename ItemT>
template <typename ItemT
, typename DT>
void FListBox::insert ( const ItemT& item
, fc::brackets_type b
, bool s
, FDataPtr d )
, DT&& d )
{
FListBoxItem listItem (FString() << item, d);
FListBoxItem listItem (FString() << item, std::forward<DT>(d));
listItem.brackets = b;
listItem.selected = s;
insert (listItem);

View File

@ -54,6 +54,7 @@
#include "final/fscrollbar.h"
#include "final/ftermbuffer.h"
#include "final/ftypes.h"
#include "final/fwidget.h"
namespace finalcut
@ -74,9 +75,8 @@ class FListViewItem : public FObject
// Constructor
FListViewItem (const FListViewItem&); // copy constructor
explicit FListViewItem (iterator);
FListViewItem ( const FStringList&
, FDataPtr
, iterator );
template <typename DT>
FListViewItem (const FStringList&, DT&&, iterator);
// Destructor
~FListViewItem() override;
@ -89,12 +89,14 @@ class FListViewItem : public FObject
uInt getColumnCount() const;
int getSortColumn() const;
FString getText (int) const;
FDataPtr getData() const;
template <typename DT>
clean_fdata_t<DT>& getData() const;
uInt getDepth() const;
// Mutators
void setText (int, const FString&);
void setData (FDataPtr);
template <typename DT>
void setData (DT&&);
void setCheckable (bool);
void setChecked (bool);
@ -124,7 +126,7 @@ class FListViewItem : public FObject
// Data members
FStringList column_list{};
FDataPtr data_pointer{nullptr};
FDataAccess* data_pointer{nullptr};
iterator root{};
std::size_t visible_lines{1};
bool expandable{false};
@ -139,6 +141,22 @@ class FListViewItem : public FObject
// FListViewItem inline functions
//----------------------------------------------------------------------
template <typename DT>
inline FListViewItem::FListViewItem ( const FStringList& cols
, DT&& data
, iterator parent_iter )
: FObject{nullptr}
, column_list{cols}
, data_pointer{makeFData(std::forward<DT>(data))}
{
if ( cols.empty() )
return;
replaceControlCodes();
insert (this, parent_iter);
}
//----------------------------------------------------------------------
inline const FString FListViewItem::getClassName() const
{ return "FListViewItem"; }
@ -148,12 +166,18 @@ inline uInt FListViewItem::getColumnCount() const
{ return uInt(column_list.size()); }
//----------------------------------------------------------------------
inline FDataPtr FListViewItem::getData() const
{ return data_pointer; }
template <typename DT>
inline clean_fdata_t<DT>& FListViewItem::getData() const
{
return static_cast<FData<clean_fdata_t<DT>>&>(*data_pointer).get();
}
//----------------------------------------------------------------------
inline void FListViewItem::setData (FDataPtr data)
{ data_pointer = data; }
template <typename DT>
inline void FListViewItem::setData (DT&& data)
{
data_pointer = makeFData(std::forward<DT>(data));
}
//----------------------------------------------------------------------
inline void FListViewItem::setChecked (bool checked)
@ -312,32 +336,38 @@ class FListView : public FWidget
void hide() override;
iterator insert (FListViewItem*);
iterator insert (FListViewItem*, iterator);
template <typename DT = std::nullptr_t>
iterator insert ( const FStringList&
, FDataPtr = nullptr );
, DT&& = DT() );
iterator insert ( const FStringList&
, iterator );
template <typename DT>
iterator insert ( const FStringList&
, FDataPtr
, DT&&
, iterator );
template <typename T>
template <typename T
, typename DT = std::nullptr_t>
iterator insert ( const std::initializer_list<T>&
, FDataPtr = nullptr );
, DT&& = DT() );
template <typename T>
iterator insert ( const std::initializer_list<T>&
, iterator );
template <typename T>
template <typename T
, typename DT>
iterator insert ( const std::initializer_list<T>&
, FDataPtr
, DT&&
, iterator );
template <typename ColT>
template <typename ColT
, typename DT = std::nullptr_t>
iterator insert ( const std::vector<ColT>&
, FDataPtr = nullptr );
, DT&& = DT() );
template <typename ColT>
iterator insert ( const std::vector<ColT>&
, iterator );
template <typename ColT>
template <typename ColT
, typename DT>
iterator insert ( const std::vector<ColT>&
, FDataPtr
, DT&&
, iterator );
void remove (FListViewItem*);
void clear();
@ -560,9 +590,10 @@ inline FObject::iterator FListView::insert (FListViewItem* item)
{ return insert (item, root); }
//----------------------------------------------------------------------
template <typename DT>
inline FObject::iterator
FListView::insert (const FStringList& cols, FDataPtr d)
{ return insert (cols, d, root); }
FListView::insert (const FStringList& cols, DT&& d)
{ return insert (cols, std::forward<DT>(d), root); }
//----------------------------------------------------------------------
inline FObject::iterator
@ -571,10 +602,39 @@ inline FObject::iterator
{ return insert (cols, nullptr, parent_iter); }
//----------------------------------------------------------------------
template<typename T>
template <typename DT>
inline FObject::iterator FListView::insert ( const FStringList& cols
, DT&& d
, iterator parent_iter )
{
FListViewItem* item;
if ( cols.empty() || parent_iter == getNullIterator() )
return getNullIterator();
if ( ! *parent_iter )
parent_iter = root;
try
{
item = new FListViewItem (cols, std::forward<DT>(d), getNullIterator());
}
catch (const std::bad_alloc&)
{
badAllocOutput ("FListViewItem");
return getNullIterator();
}
item->replaceControlCodes();
return insert(item, parent_iter);
}
//----------------------------------------------------------------------
template <typename T
, typename DT>
inline FObject::iterator
FListView::insert (const std::initializer_list<T>& list, FDataPtr d)
{ return insert (list, d, root); }
FListView::insert (const std::initializer_list<T>& list, DT&& d)
{ return insert (list, std::forward<DT>(d), root); }
//----------------------------------------------------------------------
template <typename T>
@ -584,10 +644,11 @@ inline FObject::iterator
{ return insert (list, 0, parent_iter); }
//----------------------------------------------------------------------
template<typename T>
template <typename T
, typename DT>
FObject::iterator
FListView::insert ( const std::initializer_list<T>& list
, FDataPtr d
, DT&& d
, iterator parent_iter )
{
FStringList str_cols;
@ -602,15 +663,16 @@ FObject::iterator
}
);
auto item_iter = insert (str_cols, d, parent_iter);
auto item_iter = insert (str_cols, std::forward<DT>(d), parent_iter);
return item_iter;
}
//----------------------------------------------------------------------
template <typename ColT>
template <typename ColT
, typename DT>
inline FObject::iterator
FListView::insert (const std::vector<ColT>& cols, FDataPtr d)
{ return insert (cols, d, root); }
FListView::insert (const std::vector<ColT>& cols, DT&& d)
{ return insert (cols, std::forward<DT>(d), root); }
//----------------------------------------------------------------------
template <typename ColT>
@ -620,10 +682,11 @@ inline FObject::iterator
{ return insert (cols, 0, parent_iter); }
//----------------------------------------------------------------------
template <typename ColT>
template <typename ColT
, typename DT>
FObject::iterator
FListView::insert ( const std::vector<ColT>& cols
, FDataPtr d
, DT&& d
, iterator parent_iter )
{
FStringList str_cols;
@ -638,7 +701,7 @@ FObject::iterator
}
);
auto item_iter = insert (str_cols, d, parent_iter);
auto item_iter = insert (str_cols, std::forward<DT>(d), parent_iter);
return item_iter;
}

View File

@ -170,9 +170,10 @@ class FScrollbar : public FWidget
};
// non-member function forward declarations
// non-member function
//----------------------------------------------------------------------
template<typename Instance, typename Callback>
template <typename Instance
, typename Callback>
void initScrollbar ( FScrollbarPtr& bar
, fc::orientation o
, Instance cb_instance

View File

@ -104,7 +104,8 @@ class FTermcap final
static char* getString (const CharT&);
template <typename CharT>
static char* encodeMotionParameter (const CharT&, int, int);
template<typename CharT, typename... Args>
template <typename CharT
, typename... Args>
static char* encodeParameter (const CharT&, Args&&...);
template <typename CharT>
static int paddingPrint (const CharT&, int, fn_putc);
@ -187,7 +188,8 @@ char* FTermcap::encodeMotionParameter (const CharT& cap, int col, int row)
}
//----------------------------------------------------------------------
template<typename CharT, typename... Args>
template <typename CharT
, typename... Args>
inline char* FTermcap::encodeParameter (const CharT& cap, Args&&... args)
{
return ::tparm (C_STR(cap), std::forward<Args>(args)...);

View File

@ -152,7 +152,7 @@ class FTermLinux final
modifier_key& getModifierKey();
// Mutators
int setScreenFont ( uChar[], uInt, uInt, uInt
int setScreenFont ( const uChar[], uInt, uInt, uInt
, bool = false );
int setUnicodeMap (struct unimapdesc*);
void setLinuxCursorStyle (fc::linuxConsoleCursorStyle) const;

View File

@ -75,7 +75,11 @@ typedef std::function<void()> FCall;
namespace finalcut
{
template <typename T, bool is_signed>
namespace internal
{
template <typename T
, bool is_signed>
struct is_negative
{
inline bool operator () (const T& x) const
@ -93,10 +97,12 @@ struct is_negative<T, false>
}
};
} // namespace internal
template <typename T>
inline bool isNegative (const T& x)
constexpr bool isNegative (const T& x)
{
return is_negative<T, std::numeric_limits<T>::is_signed>()(x);
return internal::is_negative<T, std::numeric_limits<T>::is_signed>()(x);
}
template <typename T>

View File

@ -122,7 +122,12 @@ class FObject_userEvent : public finalcut::FObject
virtual void onUserEvent (finalcut::FUserEvent* ev)
{
if ( ev->getUserId() == 42 )
value = *(static_cast<int*>(ev->getData()));
{
value = ev->getData<int>();
if ( ev->getFDataObject<int>().isInitializedReference() )
ev->getData<int>()++; // this has external effects
}
}
private:
@ -625,9 +630,10 @@ void FObjectTest::userEventTest()
int n = 9;
finalcut::FUserEvent user_ev (finalcut::fc::User_Event, 42);
user_ev.setData( (void*)(&n) );
user_ev.setData(n);
finalcut::FApplication::sendEvent (&user, &user_ev);
CPPUNIT_ASSERT ( user.getValue() == 9 );
CPPUNIT_ASSERT ( n == 10 );
}
// Put the test suite in the registry