Decoupling the FWidget and FWindow classes from FVTerm

This commit is contained in:
Markus Gans 2021-04-18 15:05:55 +02:00
parent 8a7ce330a3
commit 4c3b5b6737
14 changed files with 229 additions and 194 deletions

View File

@ -1,3 +1,8 @@
2021-04-18 Markus Gans <guru.mail@muenster.de>
* Decoupling the FWidget and FWindow classes from FVTerm
* Avoid redrawing widgets when show() is called multiple times
* Readjustment of the root widget when the terminal size is changed
2021-04-11 Markus Gans <guru.mail@muenster.de>
* Better support for kitty terminals

View File

@ -766,8 +766,11 @@ void FDialog::onWindowLowered (FEvent*)
if ( getWindowList()->empty() )
return;
for (auto&& win : *getWindowList())
for (auto&& window : *getWindowList())
{
const auto win = static_cast<FWidget*>(window);
putArea (win->getTermPos(), win->getVWin());
}
}
@ -1216,8 +1219,10 @@ void FDialog::restoreOverlaidWindows()
bool overlaid{false};
for (auto&& win : *getWindowList())
for (auto&& window : *getWindowList())
{
const auto win = static_cast<FWidget*>(window);
if ( overlaid )
putArea (win->getTermPos(), win->getVWin());

View File

@ -599,18 +599,15 @@ void FListBox::adjustSize()
hbar->setWidth (width, false);
hbar->resize();
if ( isShown() )
{
if ( isHorizontallyScrollable() )
hbar->show();
else
hbar->hide();
if ( isHorizontallyScrollable() )
hbar->show();
else
hbar->hide();
if ( isVerticallyScrollable() )
vbar->show();
else
vbar->hide();
}
if ( isVerticallyScrollable() )
vbar->show();
else
vbar->hide();
}

View File

@ -1368,18 +1368,15 @@ void FListView::adjustScrollbars (const std::size_t element_count) const
hbar->setWidth (width, false);
hbar->resize();
if ( isShown() )
{
if ( isHorizontallyScrollable() )
hbar->show();
else
hbar->hide();
if ( isHorizontallyScrollable() )
hbar->show();
else
hbar->hide();
if ( isVerticallyScrollable() )
vbar->show();
else
vbar->hide();
}
if ( isVerticallyScrollable() )
vbar->show();
else
vbar->hide();
}
//----------------------------------------------------------------------

View File

@ -638,11 +638,8 @@ void FScrollView::adjustSize()
vbar->setValue (yoffset);
vbar->resize();
if ( isShown() )
{
setHorizontalScrollBarVisibility();
setVerticalScrollBarVisibility();
}
setHorizontalScrollBarVisibility();
setVerticalScrollBarVisibility();
}
//----------------------------------------------------------------------

View File

@ -457,28 +457,14 @@ bool FTermDetection::get256colorEnvString()
color_env.string7 = std::getenv("COLORFGBG");
color_env.string7 = std::getenv("KITTY_WINDOW_ID");
if ( color_env.string1 != nullptr )
return true;
if ( color_env.string2 != nullptr )
return true;
if ( color_env.string3 != nullptr )
return true;
if ( color_env.string4 != nullptr )
return true;
if ( color_env.string5 != nullptr )
return true;
if ( color_env.string6 != nullptr )
return true;
if ( color_env.string7 != nullptr )
return true;
if ( color_env.string8 != nullptr )
if ( color_env.string1 != nullptr
|| color_env.string2 != nullptr
|| color_env.string3 != nullptr
|| color_env.string4 != nullptr
|| color_env.string5 != nullptr
|| color_env.string6 != nullptr
|| color_env.string7 != nullptr
|| color_env.string8 != nullptr )
return true;
return false;

View File

@ -526,18 +526,15 @@ void FTextView::adjustSize()
hbar->setValue (xoffset);
hbar->resize();
if ( isShown() )
{
if ( isHorizontallyScrollable() )
hbar->show();
else
hbar->hide();
if ( isHorizontallyScrollable() )
hbar->show();
else
hbar->hide();
if ( isVerticallyScrollable() )
vbar->show();
else
vbar->hide();
}
if ( isVerticallyScrollable() )
vbar->show();
else
vbar->hide();
}

View File

@ -48,8 +48,6 @@
#include "final/ftermcap.h"
#include "final/ftypes.h"
#include "final/fvterm.h"
#include "final/fwidget.h"
#include "final/fwindow.h"
namespace finalcut
{
@ -96,6 +94,7 @@ FVTerm::FVTerm()
fterm = std::shared_ptr<FTerm>(init_object->fterm);
term_pos = std::shared_ptr<FPoint>(init_object->term_pos);
output_buffer = std::shared_ptr<OutputBuffer>(init_object->output_buffer);
window_list = std::shared_ptr<FVTermList>(init_object->window_list);
}
}
@ -651,7 +650,7 @@ void FVTerm::createArea ( const FRect& box
return;
}
area->widget = reinterpret_cast<FWidget*>(this);
area->setOwner<FVTerm*>(this);
resizeArea (box, shadow, area);
}
@ -1082,6 +1081,28 @@ void FVTerm::putArea (const FPoint& pos, const FTermArea* area)
vterm->has_changes = true;
}
//----------------------------------------------------------------------
int FVTerm::getLayer (FVTerm* obj)
{
// returns the layer from the FVTerm object
if ( ! getWindowList() || getWindowList()->empty() )
return -1;
auto iter = getWindowList()->begin();
const auto end = getWindowList()->end();
while ( iter != end )
{
if ( *iter == obj )
break;
++iter;
}
return int(std::distance(getWindowList()->begin(), iter) + 1);
}
//----------------------------------------------------------------------
void FVTerm::scrollAreaForward (FTermArea* area) const
{
@ -1389,11 +1410,11 @@ FVTerm::CoveredState FVTerm::isCovered ( const FPoint& pos
auto is_covered = CoveredState::None;
if ( FWidget::getWindowList() && ! FWidget::getWindowList()->empty() )
if ( getWindowList() && ! getWindowList()->empty() )
{
bool found{ area == vdesktop };
for (auto& win_obj : *FWidget::getWindowList())
for (auto& win_obj : *getWindowList())
{
const auto& win = win_obj->getVWin();
@ -1590,13 +1611,10 @@ void FVTerm::updateVTerm() const
vdesktop->has_changes = false;
}
const FWidget* widget = vterm->widget;
if ( ! widget || ! widget->getWindowList()
|| widget->getWindowList()->empty() )
if ( ! getWindowList() || getWindowList()->empty() )
return;
for (auto&& window : *(widget->getWindowList()))
for (auto&& window : *getWindowList())
{
auto v_win = window->getVWin();
@ -1686,10 +1704,10 @@ FChar FVTerm::generateCharacter (const FPoint& pos)
const int y = pos.getY();
auto sc = &vdesktop->data[y * vdesktop->width + x]; // shown character
if ( ! FWidget::getWindowList() || FWidget::getWindowList()->empty() )
if ( ! getWindowList() || getWindowList()->empty() )
return *sc;
for (auto& win_obj : *FWidget::getWindowList())
for (auto& win_obj : *getWindowList())
{
const auto& win = win_obj->getVWin();
@ -1767,24 +1785,26 @@ FChar FVTerm::getCharacter ( CharacterType char_type
auto cc = &vdesktop->data[yy * vdesktop->width + xx]; // covered character
if ( ! area || ! FWidget::getWindowList() || FWidget::getWindowList()->empty() )
if ( ! area || ! getWindowList() || getWindowList()->empty() )
return *cc;
// Get the window layer of this widget object
const int layer = FWindow::getWindowLayer(area->widget);
const auto has_an_owner = area->hasOwner();
const auto area_owner = area->getOwner<FVTerm*>();
const int layer = has_an_owner ? getLayer(area_owner) : 0;
for (auto&& win_obj : *FWidget::getWindowList())
for (auto&& win_obj : *getWindowList())
{
bool significant_char{false};
// char_type can be "overlapped_character"
// or "covered_character"
if ( char_type == CharacterType::Covered )
significant_char = bool(layer >= FWindow::getWindowLayer(win_obj));
significant_char = bool(layer >= getLayer(win_obj));
else
significant_char = bool(layer < FWindow::getWindowLayer(win_obj));
significant_char = bool(layer < getLayer(win_obj));
if ( area->widget && area->widget != win_obj && significant_char )
if ( has_an_owner && area_owner != win_obj && significant_char )
{
const auto& win = win_obj->getVWin();
@ -1832,6 +1852,7 @@ void FVTerm::init()
fterm = std::make_shared<FTerm>();
term_pos = std::make_shared<FPoint>(-1, -1);
output_buffer = std::make_shared<OutputBuffer>();
window_list = std::make_shared<FVTermList>();
}
catch (const std::bad_alloc&)
{

View File

@ -54,7 +54,6 @@ FStatusBar* FWidget::statusbar{nullptr};
FMenuBar* FWidget::menubar{nullptr};
FWidget* FWidget::show_root_widget{nullptr};
FWidget* FWidget::redraw_root_widget{nullptr};
FWidget::FWidgetList* FWidget::window_list{nullptr};
FWidget::FWidgetList* FWidget::dialog_list{nullptr};
FWidget::FWidgetList* FWidget::always_on_top_list{nullptr};
FWidget::FWidgetList* FWidget::close_widget{nullptr};
@ -665,15 +664,16 @@ bool FWidget::setCursorPos (const FPoint& pos)
const auto& area = getPrintArea();
if ( area->widget )
if ( area->hasOwner() )
{
int woffsetX = getTermX() - area->widget->getTermX();
int woffsetY = getTermY() - area->widget->getTermY();
const auto object = area->getOwner<FWidget*>();
int woffsetX = getTermX() - object->getTermX();
int woffsetY = getTermY() - object->getTermY();
if ( isChildPrintArea() )
{
woffsetX += (1 - area->widget->getLeftPadding());
woffsetY += (1 - area->widget->getTopPadding());
woffsetX += (1 - object->getLeftPadding());
woffsetY += (1 - object->getTopPadding());
}
bool visible = ! isCursorHideable() || flags.visible_cursor;
@ -959,7 +959,7 @@ void FWidget::show()
{
// Make the widget visible and draw it
if ( ! isVisible() || FApplication::isQuit() )
if ( ! isVisible() || isShown() || FApplication::isQuit() )
return;
// Initialize desktop on first call
@ -1352,10 +1352,12 @@ void FWidget::adjustSizeGlobal()
return;
}
if ( window_list && ! window_list->empty() )
adjustSize(); // Root widget / FApplication object
if ( getWindowList() && ! getWindowList()->empty() )
{
for (auto&& window : *window_list)
window->adjustSize();
for (auto&& window : *getWindowList())
static_cast<FWidget*>(window)->adjustSize();
}
}
@ -1749,7 +1751,6 @@ void FWidget::initRootWidget()
try
{
// Initialize widget lists
window_list = new FWidgetList();
dialog_list = new FWidgetList();
always_on_top_list = new FWidgetList();
close_widget = new FWidgetList();
@ -1813,12 +1814,6 @@ void FWidget::finish()
delete always_on_top_list;
always_on_top_list = nullptr;
}
if ( window_list )
{
delete window_list;
window_list = nullptr;
}
}
//----------------------------------------------------------------------
@ -1946,7 +1941,7 @@ void FWidget::setWindowFocus (bool enable)
if ( ! window->isWindowActive() )
{
bool has_raised = window->raiseWindow();
FWindow::setActiveWindow(window);
window->setActiveWindow(window);
if ( has_raised && window->isVisible() && window->isShown() )
window->redraw();
@ -2012,18 +2007,20 @@ void FWidget::drawWindows() const
default_char.attr.byte[0] = 0;
default_char.attr.byte[1] = 0;
if ( ! window_list || window_list->empty() )
if ( ! getWindowList() || getWindowList()->empty() )
return;
for (auto&& window : *window_list)
for (auto&& window : *getWindowList())
{
if ( window->isShown() )
const auto win = static_cast<FWidget*>(window);
if ( win->isShown() )
{
auto v_win = window->getVWin();
auto v_win = win->getVWin();
const int w = v_win->width + v_win->right_shadow;
const int h = v_win->height + v_win->bottom_shadow;
std::fill_n (v_win->data, w * h, default_char);
window->redraw();
win->redraw();
}
}
}

View File

@ -3,7 +3,7 @@
* *
* This file is part of the FINAL CUT widget toolkit *
* *
* Copyright 2015-2020 Markus Gans *
* Copyright 2015-2021 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 *
@ -129,7 +129,7 @@ void FWindow::setActiveWindow (FWindow* window)
{
w->deactivateWindow();
FEvent ev(Event::WindowInactive);
FApplication::sendEvent(win, &ev);
FApplication::sendEvent(static_cast<FWidget*>(win), &ev);
}
}
}
@ -365,12 +365,10 @@ void FWindow::setHeight (std::size_t h, bool adjust)
//----------------------------------------------------------------------
void FWindow::setSize (const FSize& size, bool adjust)
{
const std::size_t old_width = getWidth();
const std::size_t old_height = getHeight();
const FSize old_size{getSize()};
FWidget::setSize (size, adjust);
if ( isVirtualWindow()
&& (getWidth() != old_width || getHeight() != old_height) )
if ( isVirtualWindow() && getSize() != old_size )
{
FRect geometry {getTermGeometry()};
geometry.move(-1, -1);
@ -429,6 +427,7 @@ void FWindow::move (const FPoint& pos)
FWindow* FWindow::getWindowWidgetAt (int x, int y)
{
// returns the window object to the corresponding coordinates
if ( getWindowList() && ! getWindowList()->empty() )
{
auto iter = getWindowList()->end();
@ -482,56 +481,6 @@ void FWindow::delWindow (const FWidget* obj)
}
}
//----------------------------------------------------------------------
FWindow* FWindow::getWindowWidget (FWidget* obj)
{
// returns the window object to the given widget obj
auto p_obj = obj->getParentWidget();
while ( ! obj->isWindowWidget() && p_obj )
{
obj = p_obj;
p_obj = p_obj->getParentWidget();
}
if ( obj->isWindowWidget() )
return static_cast<FWindow*>(obj);
else
return nullptr;
}
//----------------------------------------------------------------------
int FWindow::getWindowLayer (FWidget* obj)
{
// returns the window layer from the widget obj
const FWidget* window;
if ( ! getWindowList() || getWindowList()->empty() )
return -1;
if ( ! obj->isWindowWidget() )
{
if ( (window = getWindowWidget(obj)) == nullptr )
return -1;
}
else
window = obj;
auto iter = getWindowList()->begin();
const auto end = getWindowList()->end();
while ( iter != end )
{
if ( *iter == window )
break;
++iter;
}
return int(std::distance(getWindowList()->begin(), iter) + 1);
}
//----------------------------------------------------------------------
void FWindow::swapWindow (const FWidget* obj1, const FWidget* obj2)
{
@ -582,18 +531,19 @@ bool FWindow::raiseWindow (FWidget* obj)
if ( ! obj->isWindowWidget() )
return false;
if ( getWindowList()->back() == obj )
const auto last = static_cast<FWidget*>(getWindowList()->back());
if ( last == obj )
return false;
if ( getWindowList()->back()->getFlags().modal
&& ! obj->isMenuWidget() )
if ( last->getFlags().modal && ! obj->isMenuWidget() )
return false;
auto iter = getWindowList()->begin();
while ( iter != getWindowList()->end() )
{
if ( *iter == obj )
if ( static_cast<FWidget*>(*iter) == obj )
{
getWindowList()->erase (iter);
getWindowList()->push_back (obj);
@ -686,8 +636,7 @@ void FWindow::switchToPrevWindow (const FWidget* widget)
const bool is_activated = activatePrevWindow();
auto active_win = static_cast<FWindow*>(getActiveWindow());
if ( ! is_activated
&& getWindowList() && getWindowList()->size() > 1 )
if ( ! is_activated && getWindowList() && getWindowList()->size() > 1 )
{
// no previous window -> looking for another window
auto iter = getWindowList()->end();
@ -716,7 +665,7 @@ void FWindow::switchToPrevWindow (const FWidget* widget)
auto focus = active_win->getWindowFocusWidget();
if ( ! active_win->isWindowActive() )
setActiveWindow(active_win);
active_win->setActiveWindow(active_win);
if ( focus )
{
@ -745,7 +694,7 @@ bool FWindow::activatePrevWindow()
if ( ! w->isWindowHidden() )
{
setActiveWindow(w);
w->setActiveWindow(w);
return true;
}
}
@ -885,6 +834,42 @@ void FWindow::processAlwaysOnTop()
}
}
//----------------------------------------------------------------------
FWindow* FWindow::getWindowWidgetImpl (FWidget* obj)
{
// returns the window object to the given widget obj
auto p_obj = obj->getParentWidget();
while ( ! obj->isWindowWidget() && p_obj )
{
obj = p_obj;
p_obj = p_obj->getParentWidget();
}
if ( obj->isWindowWidget() )
return static_cast<FWindow*>(obj);
else
return nullptr;
}
//----------------------------------------------------------------------
int FWindow::getWindowLayerImpl (FWidget* obj)
{
// returns the window layer from the widget obj
FWidget* window;
if ( ! obj->isWindowWidget() )
{
if ( (window = getWindowWidget(obj)) == nullptr )
return -1;
}
else
window = obj;
return FVTerm::getLayer(window);
}
// non-member functions
//----------------------------------------------------------------------
void closeDropDown (const FWidget* widget, const FPoint& mouse_position)

View File

@ -165,6 +165,8 @@ class FData : public FDataAccess
, value_ref{value}
{ }
~FData() noexcept override = default; // Destructor
FData (const FData& d) // Copy constructor
: value{d.value}
, value_ref{d.isInitializedCopy() ? std::ref(value) : d.value_ref}

View File

@ -58,6 +58,7 @@
#include <vector>
#include "final/fc.h"
#include "final/fdata.h"
#include "final/fstringstream.h"
#include "final/fterm.h"
@ -79,7 +80,7 @@ class FTerm;
class FTermBuffer;
class FTermDebugData;
class FStyle;
class FWidget;
//----------------------------------------------------------------------
// class FVTerm
@ -102,6 +103,7 @@ class FVTerm
using FPreprocessingHandler = void (FVTerm::*)();
using FPreprocessingFunction = std::function<void()>;
using FPreprocessing = std::vector<std::unique_ptr<FVTermPreprocessing>>;
using FVTermList = std::vector<FVTerm*>;
// Enumerations
enum class CoveredState
@ -149,6 +151,7 @@ class FVTerm
const FTermArea* getVWin() const;
FPoint getPrintCursor();
static FChar getAttribute();
static FVTermList* getWindowList();
FTerm& getFTerm() const;
// Mutators
@ -278,6 +281,7 @@ class FVTerm
static void getArea (const FRect&, const FTermArea*);
void putArea (const FTermArea*) const;
static void putArea (const FPoint&, const FTermArea*);
static int getLayer (FVTerm*);
void scrollAreaForward (FTermArea*) const;
void scrollAreaReverse (FTermArea*) const;
void clearArea (FTermArea*, wchar_t = L' ') const;
@ -438,16 +442,17 @@ class FVTerm
FTermArea* child_print_area{nullptr}; // print area for children
FTermArea* vwin{nullptr}; // virtual window
std::shared_ptr<FTerm> fterm{};
std::shared_ptr<FPoint> term_pos{}; // terminal cursor position
std::shared_ptr<FPoint> term_pos{}; // terminal cursor position
std::shared_ptr<OutputBuffer> output_buffer{};
static const FVTerm* init_object; // Global FVTerm object
static FTermArea* vterm; // virtual terminal
static FTermArea* vdesktop; // virtual desktop
static FTermArea* active_area; // active area
std::shared_ptr<FVTermList> window_list{}; // List of all window owner
static const FVTerm* init_object; // Global FVTerm object
static FTermArea* vterm; // virtual terminal
static FTermArea* vdesktop; // virtual desktop
static FTermArea* active_area; // active area
static FChar term_attribute;
static FChar next_attribute;
static FChar s_ch; // shadow character
static FChar i_ch; // inherit background character
static FChar s_ch; // shadow character
static FChar i_ch; // inherit background character
static timeval time_last_flush;
static timeval last_term_size_check;
static bool draw_completed;
@ -473,6 +478,9 @@ class FVTerm
struct FVTerm::FTermArea // define virtual terminal character properties
{
// Using-declaration
using FDataAccessPtr = std::shared_ptr<FDataAccess>;
// Constructor
FTermArea() = default;
@ -485,18 +493,35 @@ struct FVTerm::FTermArea // define virtual terminal character properties
// Disable copy assignment operator (=)
FTermArea& operator = (const FTermArea&) = delete;
template <typename T>
clean_fdata_t<T>& getOwner() const
{
return static_cast<FData<clean_fdata_t<T>>&>(*owner).get();
}
template <typename T>
void setOwner (T&& obj)
{
owner.reset(makeFData(std::forward<T>(obj)));
}
bool hasOwner() const
{
return owner.get() != nullptr;
}
// Data members
int offset_left{0}; // Distance from left terminal side
int offset_top{0}; // Distance from top of the terminal
int width{-1}; // Window width
int height{-1}; // Window height
int right_shadow{0}; // Right window shadow
int bottom_shadow{0}; // Bottom window shadow
int cursor_x{0}; // X-position for the next write operation
int cursor_y{0}; // Y-position for the next write operation
int input_cursor_x{-1}; // X-position input cursor
int input_cursor_y{-1}; // Y-position input cursor
FWidget* widget{nullptr}; // Widget that owns this FTermArea
int offset_left{0}; // Distance from left terminal side
int offset_top{0}; // Distance from top of the terminal
int width{-1}; // Window width
int height{-1}; // Window height
int right_shadow{0}; // Right window shadow
int bottom_shadow{0}; // Bottom window shadow
int cursor_x{0}; // X-position for the next write operation
int cursor_y{0}; // Y-position for the next write operation
int input_cursor_x{-1}; // X-position input cursor
int input_cursor_y{-1}; // Y-position input cursor
FDataAccessPtr owner{nullptr}; // Object that owns this FTermArea
FPreprocessing preproc_list{};
FLineChanges* changes{nullptr};
FChar* data{nullptr}; // FChar data of the drawing area
@ -617,6 +642,14 @@ inline const FVTerm::FTermArea* FVTerm::getVWin() const
inline FChar FVTerm::getAttribute()
{ return next_attribute; }
//----------------------------------------------------------------------
inline FVTerm::FVTermList* FVTerm::getWindowList()
{
return (init_object && init_object->window_list)
? init_object->window_list.get()
: nullptr;
}
//----------------------------------------------------------------------
inline FTerm& FVTerm::getFTerm() const
{ return *fterm; }

View File

@ -183,7 +183,6 @@ class FWidget : public FVTerm, public FObject
static FWidget*& getClickedWidget();
static FWidget*& getOpenMenu();
static FWidget*& getMoveSizeWidget();
static FWidgetList*& getWindowList();
static FMenuBar* getMenuBar();
static FStatusBar* getStatusBar();
static auto getColorTheme() -> std::shared_ptr<FWidgetColors>&;
@ -480,7 +479,6 @@ class FWidget : public FVTerm, public FObject
static FWidget* move_size_widget;
static FWidget* show_root_widget;
static FWidget* redraw_root_widget;
static FWidgetList* window_list;
static FWidgetList* dialog_list;
static FWidgetList* always_on_top_list;
static FWidgetList* close_widget;
@ -555,10 +553,6 @@ inline FWidget*& FWidget::getOpenMenu()
inline FWidget*& FWidget::getMoveSizeWidget()
{ return move_size_widget; }
//----------------------------------------------------------------------
inline FWidget::FWidgetList*& FWidget::getWindowList()
{ return window_list; }
//----------------------------------------------------------------------
inline FMenuBar* FWidget::getMenuBar()
{ return menubar; }

View File

@ -84,8 +84,10 @@ class FWindow : public FWidget
// Accessors
FString getClassName() const override;
static FWindow* getWindowWidget (FWidget*);
static int getWindowLayer (FWidget*);
template<typename WidgetT>
static FWindow* getWindowWidget (WidgetT*);
template<typename WidgetT>
static int getWindowLayer (WidgetT*);
FWidget* getWindowFocusWidget() const;
// Mutators
@ -159,6 +161,8 @@ class FWindow : public FWidget
// Methods
static void deleteFromAlwaysOnTopList (const FWidget*);
static void processAlwaysOnTop();
static FWindow* getWindowWidgetImpl (FWidget*);
static int getWindowLayerImpl (FWidget*);
// Data members
FWidget* win_focus_widget{nullptr};
@ -178,6 +182,21 @@ void closeDropDown (const FWidget*, const FPoint&);
inline FString FWindow::getClassName() const
{ return "FWindow"; }
//----------------------------------------------------------------------
template<typename WidgetT>
inline FWindow* FWindow::getWindowWidget (WidgetT* obj)
{
return getWindowWidgetImpl (static_cast<FWidget*>(obj));
}
//----------------------------------------------------------------------
template<typename WidgetT>
inline int FWindow::getWindowLayer (WidgetT* obj)
{
return getWindowLayerImpl (static_cast<FWidget*>(obj));
}
//----------------------------------------------------------------------
inline bool FWindow::unsetWindowWidget()
{ return setWindowWidget(false); }