2019-10-08 04:37:19 +02:00
|
|
|
/***********************************************************************
|
|
|
|
* fwidget_functions.cpp - FWidget helper functions *
|
|
|
|
* *
|
2020-07-08 21:32:47 +02:00
|
|
|
* This file is part of the FINAL CUT widget toolkit *
|
2019-10-08 04:37:19 +02:00
|
|
|
* *
|
2020-02-02 22:34:27 +01:00
|
|
|
* Copyright 2019-2020 Markus Gans *
|
2019-10-08 04:37:19 +02:00
|
|
|
* *
|
2020-07-08 21:32:47 +02:00
|
|
|
* FINAL CUT 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 3 of *
|
2019-10-08 04:37:19 +02:00
|
|
|
* the License, or (at your option) any later version. *
|
|
|
|
* *
|
2020-07-08 21:32:47 +02:00
|
|
|
* FINAL CUT is distributed in the hope that it will be useful, but *
|
|
|
|
* WITHOUT ANY WARRANTY; without even the implied warranty of *
|
2019-10-08 04:37:19 +02:00
|
|
|
* 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, see *
|
|
|
|
* <http://www.gnu.org/licenses/>. *
|
|
|
|
***********************************************************************/
|
|
|
|
|
2020-08-11 23:04:46 +02:00
|
|
|
#include "final/fapplication.h"
|
2020-02-16 00:01:36 +01:00
|
|
|
#include "final/fcolorpair.h"
|
|
|
|
#include "final/fstyle.h"
|
2019-10-08 04:37:19 +02:00
|
|
|
#include "final/fwidget.h"
|
|
|
|
#include "final/fwidgetcolors.h"
|
|
|
|
|
|
|
|
namespace finalcut
|
|
|
|
{
|
|
|
|
|
|
|
|
// FWidget non-member functions
|
2019-11-16 15:16:44 +01:00
|
|
|
//----------------------------------------------------------------------
|
2020-02-02 22:34:27 +01:00
|
|
|
bool isFocusNextKey (const FKey key)
|
2019-11-16 15:16:44 +01:00
|
|
|
{
|
|
|
|
if ( key == fc::Fkey_tab
|
|
|
|
|| key == fc::Fkey_right
|
|
|
|
|| key == fc::Fkey_down )
|
2020-04-13 12:40:11 +02:00
|
|
|
return true;
|
2019-11-16 15:16:44 +01:00
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
2020-02-02 22:34:27 +01:00
|
|
|
bool isFocusPrevKey (const FKey key)
|
2019-11-16 15:16:44 +01:00
|
|
|
{
|
|
|
|
if ( key == fc::Fkey_btab
|
|
|
|
|| key == fc::Fkey_left
|
|
|
|
|| key == fc::Fkey_up )
|
2020-04-13 12:40:11 +02:00
|
|
|
return true;
|
2019-11-16 15:16:44 +01:00
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2019-10-08 04:37:19 +02:00
|
|
|
//----------------------------------------------------------------------
|
2020-08-11 23:04:46 +02:00
|
|
|
FApplication* getFApplication()
|
|
|
|
{
|
|
|
|
return FApplication::getApplicationObject();
|
|
|
|
}
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
2019-10-08 04:37:19 +02:00
|
|
|
FKey getHotkey (const FString& text)
|
|
|
|
{
|
|
|
|
// Returns the hotkey character from a string
|
|
|
|
// e.g. "E&xit" returns 'x'
|
|
|
|
|
|
|
|
if ( text.isEmpty() )
|
|
|
|
return 0;
|
|
|
|
|
2020-04-14 23:46:42 +02:00
|
|
|
std::size_t i{0};
|
2020-02-02 22:34:27 +01:00
|
|
|
const std::size_t length = text.getLength();
|
2019-10-08 04:37:19 +02:00
|
|
|
|
2020-04-14 23:46:42 +02:00
|
|
|
while ( i < length )
|
2019-10-08 04:37:19 +02:00
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
|
|
|
if ( i + 1 < length && text[i] == '&' )
|
2020-04-13 12:40:11 +02:00
|
|
|
{
|
|
|
|
i++;
|
|
|
|
return FKey(text[i]);
|
|
|
|
}
|
2019-10-08 04:37:19 +02:00
|
|
|
}
|
|
|
|
catch (const std::out_of_range&)
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
2020-04-14 23:46:42 +02:00
|
|
|
|
|
|
|
i++;
|
2019-10-08 04:37:19 +02:00
|
|
|
}
|
2020-04-14 23:46:42 +02:00
|
|
|
|
2019-10-08 04:37:19 +02:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
std::size_t getHotkeyPos (const FString& src, FString& dest)
|
|
|
|
{
|
|
|
|
// Find hotkey position in string
|
|
|
|
// + generate a new string without the '&'-sign
|
|
|
|
|
2020-10-04 00:59:21 +02:00
|
|
|
constexpr auto NOT_SET = static_cast<std::size_t>(-1);
|
2019-10-08 04:37:19 +02:00
|
|
|
std::size_t hotkeypos{NOT_SET};
|
|
|
|
std::size_t i{0};
|
|
|
|
|
|
|
|
for (auto&& ch : src)
|
|
|
|
{
|
|
|
|
if ( ch == L'&' && hotkeypos == NOT_SET && src.getLength() != i + 1 )
|
|
|
|
hotkeypos = i;
|
|
|
|
else
|
|
|
|
dest += ch;
|
|
|
|
|
|
|
|
i++;
|
|
|
|
}
|
|
|
|
|
|
|
|
return hotkeypos;
|
|
|
|
}
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
void setHotkeyViaString (FWidget* w, const FString& text)
|
|
|
|
{
|
|
|
|
// Set hotkey accelerator via string
|
|
|
|
|
|
|
|
if ( ! w )
|
|
|
|
return;
|
|
|
|
|
|
|
|
FKey hotkey = getHotkey(text);
|
|
|
|
|
|
|
|
if ( hotkey > 0xff00 && hotkey < 0xff5f ) // full-width character
|
|
|
|
hotkey -= 0xfee0;
|
|
|
|
|
|
|
|
if ( hotkey )
|
|
|
|
{
|
|
|
|
if ( std::isalpha(int(hotkey)) || std::isdigit(int(hotkey)) )
|
|
|
|
{
|
|
|
|
w->addAccelerator (FKey(std::tolower(int(hotkey))));
|
|
|
|
w->addAccelerator (FKey(std::toupper(int(hotkey))));
|
|
|
|
// Meta + hotkey
|
|
|
|
w->addAccelerator (fc::Fmkey_meta + FKey(std::tolower(int(hotkey))));
|
|
|
|
}
|
|
|
|
else
|
|
|
|
w->addAccelerator (hotkey);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
w->delAccelerator();
|
|
|
|
}
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
void drawShadow (FWidget* w)
|
|
|
|
{
|
2020-05-16 22:24:36 +02:00
|
|
|
if ( FTerm::isMonochron() && ! w->flags.trans_shadow )
|
2019-10-08 04:37:19 +02:00
|
|
|
return;
|
|
|
|
|
2020-05-16 22:24:36 +02:00
|
|
|
if ( (FTerm::getEncoding() == fc::VT100 && ! w->flags.trans_shadow)
|
|
|
|
|| (FTerm::getEncoding() == fc::ASCII && ! w->flags.trans_shadow) )
|
2019-10-08 04:37:19 +02:00
|
|
|
{
|
|
|
|
clearShadow(w);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( w->flags.trans_shadow )
|
|
|
|
drawTransparentShadow (w); // transparent shadow
|
2020-07-06 19:32:01 +02:00
|
|
|
else if ( w->flags.shadow )
|
2019-10-08 04:37:19 +02:00
|
|
|
drawBlockShadow (w); // non-transparent shadow
|
|
|
|
}
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
void drawTransparentShadow (FWidget* w)
|
|
|
|
{
|
|
|
|
// transparent shadow
|
|
|
|
|
2020-02-02 22:34:27 +01:00
|
|
|
const std::size_t width = w->getWidth();
|
|
|
|
const std::size_t height = w->getHeight();
|
2020-05-26 21:37:39 +02:00
|
|
|
const auto& wc = FWidget::getColorTheme();
|
2020-05-02 00:07:35 +02:00
|
|
|
w->print() << FStyle {fc::Transparent}
|
|
|
|
<< FPoint {int(width) + 1, 1}
|
2020-02-16 00:01:36 +01:00
|
|
|
<< " "
|
2020-05-02 00:07:35 +02:00
|
|
|
<< FStyle {fc::Reset}
|
2020-05-26 21:37:39 +02:00
|
|
|
<< FColorPair {wc->shadow_bg, wc->shadow_fg}
|
2020-05-02 00:07:35 +02:00
|
|
|
<< FStyle {fc::ColorOverlay};
|
2019-10-08 04:37:19 +02:00
|
|
|
|
|
|
|
for (std::size_t y{1}; y < height; y++)
|
|
|
|
{
|
2020-05-02 00:07:35 +02:00
|
|
|
w->print() << FPoint{int(width) + 1, int(y) + 1} << " ";
|
2019-10-08 04:37:19 +02:00
|
|
|
}
|
|
|
|
|
2020-05-02 00:07:35 +02:00
|
|
|
w->print() << FStyle {fc::Reset} << FStyle {fc::Transparent}
|
|
|
|
<< FPoint {1, int(height) + 1}
|
2020-02-16 00:01:36 +01:00
|
|
|
<< " "
|
2020-05-02 00:07:35 +02:00
|
|
|
<< FStyle {fc::Reset}
|
2020-05-26 21:37:39 +02:00
|
|
|
<< FColorPair {wc->shadow_bg, wc->shadow_fg}
|
2020-05-02 00:07:35 +02:00
|
|
|
<< FStyle {fc::ColorOverlay}
|
|
|
|
<< FString {width, L' '}
|
|
|
|
<< FStyle {fc::Reset};
|
2019-10-08 04:37:19 +02:00
|
|
|
|
2020-05-16 22:24:36 +02:00
|
|
|
if ( FTerm::isMonochron() )
|
2019-10-08 04:37:19 +02:00
|
|
|
w->setReverse(false);
|
|
|
|
}
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
void drawBlockShadow (FWidget* w)
|
|
|
|
{
|
|
|
|
// non-transparent shadow
|
|
|
|
|
2020-05-16 22:24:36 +02:00
|
|
|
if ( ! FTerm::hasShadowCharacter() )
|
2019-10-08 04:37:19 +02:00
|
|
|
return;
|
|
|
|
|
2020-02-02 22:34:27 +01:00
|
|
|
const std::size_t width = w->getWidth();
|
|
|
|
const std::size_t height = w->getHeight();
|
2020-05-26 21:37:39 +02:00
|
|
|
const auto& wc = FWidget::getColorTheme();
|
2020-05-02 00:07:35 +02:00
|
|
|
w->print() << FPoint {int(width) + 1, 1};
|
2019-10-08 04:37:19 +02:00
|
|
|
|
|
|
|
if ( w->isWindowWidget() )
|
|
|
|
{
|
2020-05-26 21:37:39 +02:00
|
|
|
w->print() << FColorPair {wc->shadow_fg, wc->shadow_bg}
|
2020-05-02 00:07:35 +02:00
|
|
|
<< FStyle {fc::InheritBackground}; // current background color will be ignored
|
2019-10-08 04:37:19 +02:00
|
|
|
}
|
|
|
|
else if ( auto p = w->getParentWidget() )
|
2020-05-26 21:37:39 +02:00
|
|
|
w->print() << FColorPair {wc->shadow_fg, p->getBackgroundColor()};
|
2019-10-08 04:37:19 +02:00
|
|
|
|
|
|
|
w->print (fc::LowerHalfBlock); // ▄
|
|
|
|
|
|
|
|
if ( w->isWindowWidget() )
|
2020-05-02 00:07:35 +02:00
|
|
|
w->print() << FStyle {fc::InheritBackground};
|
2019-10-08 04:37:19 +02:00
|
|
|
|
|
|
|
for (std::size_t y{1}; y < height; y++)
|
|
|
|
{
|
2020-05-02 00:07:35 +02:00
|
|
|
w->print() << FPoint {int(width) + 1, int(y) + 1}
|
2020-02-16 00:01:36 +01:00
|
|
|
<< fc::FullBlock; // █
|
2019-10-08 04:37:19 +02:00
|
|
|
}
|
|
|
|
|
2020-05-02 00:07:35 +02:00
|
|
|
w->print() << FPoint {2, int(height) + 1};
|
2019-10-08 04:37:19 +02:00
|
|
|
|
|
|
|
if ( w->isWindowWidget() )
|
2020-05-02 00:07:35 +02:00
|
|
|
w->print() << FStyle {fc::InheritBackground};
|
2019-10-08 04:37:19 +02:00
|
|
|
|
2020-05-02 00:07:35 +02:00
|
|
|
w->print() << FString{width, fc::UpperHalfBlock}; // ▀
|
2019-10-08 04:37:19 +02:00
|
|
|
|
|
|
|
if ( w->isWindowWidget() )
|
2020-05-02 00:07:35 +02:00
|
|
|
w->print() << FStyle {fc::Reset};
|
2019-10-08 04:37:19 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
void clearShadow (FWidget* w)
|
|
|
|
{
|
2020-05-16 22:24:36 +02:00
|
|
|
if ( FTerm::isMonochron() )
|
2019-10-08 04:37:19 +02:00
|
|
|
return;
|
|
|
|
|
2020-02-02 22:34:27 +01:00
|
|
|
const std::size_t width = w->getWidth();
|
|
|
|
const std::size_t height = w->getHeight();
|
2020-05-26 21:37:39 +02:00
|
|
|
const auto& wc = FWidget::getColorTheme();
|
2019-10-08 04:37:19 +02:00
|
|
|
|
|
|
|
if ( w->isWindowWidget() )
|
|
|
|
{
|
2020-05-26 21:37:39 +02:00
|
|
|
w->print() << FColorPair {wc->shadow_fg, wc->shadow_bg}
|
2020-05-02 00:07:35 +02:00
|
|
|
<< FStyle {fc::InheritBackground}; // current background color will be ignored
|
2019-10-08 04:37:19 +02:00
|
|
|
}
|
|
|
|
else if ( auto p = w->getParentWidget() )
|
2020-05-26 21:37:39 +02:00
|
|
|
w->print() << FColorPair {wc->shadow_fg, p->getBackgroundColor()};
|
2019-10-08 04:37:19 +02:00
|
|
|
|
|
|
|
if ( int(width) <= w->woffset.getX2() )
|
|
|
|
{
|
|
|
|
for (std::size_t y{1}; y <= height; y++)
|
|
|
|
{
|
2020-05-02 00:07:35 +02:00
|
|
|
w->print() << FPoint {int(width) + 1, int(y)}
|
2020-02-16 00:01:36 +01:00
|
|
|
<< ' '; // clear █
|
2019-10-08 04:37:19 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( int(height) <= w->woffset.getY2() )
|
|
|
|
{
|
2020-05-02 00:07:35 +02:00
|
|
|
w->print() << FPoint{2, int(height) + 1}
|
|
|
|
<< FString{width, L' '}; // clear ▀
|
2019-10-08 04:37:19 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
if ( w->isWindowWidget() )
|
2020-05-02 00:07:35 +02:00
|
|
|
w->print() << FStyle {fc::Reset};
|
2019-10-08 04:37:19 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
void drawFlatBorder (FWidget* w)
|
|
|
|
{
|
2020-05-16 22:24:36 +02:00
|
|
|
if ( ! FTerm::isNewFont() )
|
2019-10-08 04:37:19 +02:00
|
|
|
return;
|
|
|
|
|
2020-02-02 22:34:27 +01:00
|
|
|
const std::size_t width = w->getWidth();
|
|
|
|
const std::size_t height = w->getHeight();
|
2020-05-26 21:37:39 +02:00
|
|
|
const auto& wc = FWidget::getColorTheme();
|
2020-04-13 12:40:11 +02:00
|
|
|
|
|
|
|
if ( auto p = w->getParentWidget() )
|
2020-05-26 21:37:39 +02:00
|
|
|
w->setColor (wc->dialog_fg, p->getBackgroundColor());
|
2020-04-13 12:40:11 +02:00
|
|
|
else
|
2020-05-26 21:37:39 +02:00
|
|
|
w->setColor (wc->dialog_fg, wc->dialog_bg);
|
2019-10-08 04:37:19 +02:00
|
|
|
|
|
|
|
for (std::size_t y{0}; y < height; y++)
|
|
|
|
{
|
2020-05-02 00:07:35 +02:00
|
|
|
w->print() << FPoint {0, int(y) + 1};
|
2019-10-08 04:37:19 +02:00
|
|
|
|
|
|
|
if ( w->double_flatline_mask.left[uLong(y)] )
|
|
|
|
// left+right line (on left side)
|
|
|
|
w->print (fc::NF_rev_border_line_right_and_left);
|
|
|
|
else
|
|
|
|
// right line (on left side)
|
|
|
|
w->print (fc::NF_rev_border_line_right);
|
|
|
|
|
2020-05-02 00:07:35 +02:00
|
|
|
w->print() << FPoint {int(width) + 1, int(y) + 1};
|
2019-10-08 04:37:19 +02:00
|
|
|
|
|
|
|
if ( w->double_flatline_mask.right[y] )
|
|
|
|
// left+right line (on right side)
|
|
|
|
w->print (fc::NF_rev_border_line_right_and_left);
|
|
|
|
else
|
|
|
|
// left line (on right side)
|
|
|
|
w->print (fc::NF_border_line_left);
|
|
|
|
}
|
|
|
|
|
2020-05-02 00:07:35 +02:00
|
|
|
w->print() << FPoint {1, 0};
|
2019-10-08 04:37:19 +02:00
|
|
|
|
|
|
|
for (std::size_t x{0}; x < width; x++)
|
|
|
|
{
|
|
|
|
if ( w->double_flatline_mask.top[x] )
|
|
|
|
// top+bottom line (at top)
|
|
|
|
w->print (fc::NF_border_line_up_and_down);
|
|
|
|
else
|
|
|
|
// bottom line (at top)
|
|
|
|
w->print (fc::NF_border_line_bottom);
|
|
|
|
}
|
|
|
|
|
2020-05-02 00:07:35 +02:00
|
|
|
w->print() << FPoint {1, int(height) + 1};
|
2019-10-08 04:37:19 +02:00
|
|
|
|
|
|
|
for (std::size_t x{0}; x < width; x++)
|
|
|
|
{
|
|
|
|
if ( w->double_flatline_mask.bottom[x] )
|
|
|
|
// top+bottom line (at bottom)
|
|
|
|
w->print (fc::NF_border_line_up_and_down);
|
|
|
|
else
|
|
|
|
// top line (at bottom)
|
|
|
|
w->print (fc::NF_border_line_upper);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
void clearFlatBorder (FWidget* w)
|
|
|
|
{
|
2020-05-16 22:24:36 +02:00
|
|
|
if ( ! FTerm::isNewFont() )
|
2019-10-08 04:37:19 +02:00
|
|
|
return;
|
|
|
|
|
2020-02-02 22:34:27 +01:00
|
|
|
const std::size_t width = w->getWidth();
|
|
|
|
const std::size_t height = w->getHeight();
|
2020-05-26 21:37:39 +02:00
|
|
|
const auto& wc = FWidget::getColorTheme();
|
2020-04-13 12:40:11 +02:00
|
|
|
|
|
|
|
if ( auto p = w->getParentWidget() )
|
2020-05-26 21:37:39 +02:00
|
|
|
w->setColor (wc->dialog_fg, p->getBackgroundColor());
|
2020-04-13 12:40:11 +02:00
|
|
|
else
|
2020-05-26 21:37:39 +02:00
|
|
|
w->setColor (wc->dialog_fg, wc->dialog_bg);
|
2019-10-08 04:37:19 +02:00
|
|
|
|
|
|
|
for (std::size_t y{0}; y < height; y++)
|
|
|
|
{
|
|
|
|
// clear on left side
|
2020-05-02 00:07:35 +02:00
|
|
|
w->print() << FPoint {0, int(y) + 1};
|
2019-10-08 04:37:19 +02:00
|
|
|
|
|
|
|
if ( w->double_flatline_mask.left[y] )
|
|
|
|
w->print (fc::NF_border_line_left);
|
|
|
|
else
|
|
|
|
w->print (' ');
|
|
|
|
|
|
|
|
// clear on right side
|
2020-05-02 00:07:35 +02:00
|
|
|
w->print() << FPoint {int(width) + 1, int(y) + 1};
|
2019-10-08 04:37:19 +02:00
|
|
|
|
|
|
|
if ( w->double_flatline_mask.right[y] )
|
|
|
|
w->print (fc::NF_rev_border_line_right);
|
|
|
|
else
|
|
|
|
w->print (' ');
|
|
|
|
}
|
|
|
|
|
|
|
|
// clear at top
|
2020-05-02 00:07:35 +02:00
|
|
|
w->print() << FPoint {1, 0};
|
2019-10-08 04:37:19 +02:00
|
|
|
|
|
|
|
for (std::size_t x{0}; x < width; x++)
|
|
|
|
{
|
|
|
|
if ( w->double_flatline_mask.top[x] )
|
|
|
|
w->print (fc::NF_border_line_upper);
|
|
|
|
else
|
|
|
|
w->print (' ');
|
|
|
|
}
|
|
|
|
|
|
|
|
// clear at bottom
|
2020-05-02 00:07:35 +02:00
|
|
|
w->print() << FPoint {1, int(height) + 1};
|
2019-10-08 04:37:19 +02:00
|
|
|
|
|
|
|
for (std::size_t x{0}; x < width; x++)
|
|
|
|
{
|
|
|
|
if ( w->double_flatline_mask.bottom[x] )
|
|
|
|
w->print (fc::NF_border_line_bottom);
|
|
|
|
else
|
|
|
|
w->print (' ');
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
2020-04-13 12:40:11 +02:00
|
|
|
inline void checkBorder (const FWidget* w, FRect& r)
|
2019-10-08 04:37:19 +02:00
|
|
|
{
|
|
|
|
if ( r.x1_ref() > r.x2_ref() )
|
|
|
|
std::swap (r.x1_ref(), r.x2_ref());
|
|
|
|
|
|
|
|
if ( r.y1_ref() > r.y2_ref() )
|
|
|
|
std::swap (r.y1_ref(), r.y2_ref());
|
|
|
|
|
|
|
|
if ( r.x1_ref() < 1 )
|
|
|
|
r.x1_ref() = 1;
|
|
|
|
|
|
|
|
if ( r.y1_ref() < 1 )
|
|
|
|
r.y1_ref() = 1;
|
|
|
|
|
|
|
|
if ( r.x2_ref() > int(w->getWidth()) )
|
|
|
|
r.x2_ref() = int(w->getWidth());
|
|
|
|
|
|
|
|
if ( r.y2_ref() > int(w->getHeight()) )
|
|
|
|
r.y2_ref() = int(w->getHeight());
|
2019-11-06 02:40:47 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
2020-04-13 12:40:11 +02:00
|
|
|
void drawBorder (FWidget* w, const FRect& r)
|
2019-11-06 02:40:47 +01:00
|
|
|
{
|
2020-04-13 12:40:11 +02:00
|
|
|
FRect rect = r;
|
|
|
|
checkBorder (w, rect);
|
2019-10-08 04:37:19 +02:00
|
|
|
|
2020-05-16 22:24:36 +02:00
|
|
|
if ( FTerm::isNewFont() )
|
2020-04-13 12:40:11 +02:00
|
|
|
drawNewFontBox (w, rect);
|
2019-10-08 04:37:19 +02:00
|
|
|
else
|
2020-04-13 12:40:11 +02:00
|
|
|
drawBox (w, rect);
|
2019-10-08 04:37:19 +02:00
|
|
|
}
|
|
|
|
|
2019-11-06 02:40:47 +01:00
|
|
|
//----------------------------------------------------------------------
|
2020-04-13 12:40:11 +02:00
|
|
|
void drawListBorder (FWidget* w, const FRect& r)
|
2019-11-06 02:40:47 +01:00
|
|
|
{
|
2020-04-13 12:40:11 +02:00
|
|
|
FRect rect = r;
|
|
|
|
checkBorder (w, rect);
|
2019-11-06 02:40:47 +01:00
|
|
|
|
2020-05-16 22:24:36 +02:00
|
|
|
if ( FTerm::isNewFont() )
|
2020-04-13 12:40:11 +02:00
|
|
|
drawNewFontListBox (w, rect);
|
2019-11-06 02:40:47 +01:00
|
|
|
else
|
2020-04-13 12:40:11 +02:00
|
|
|
drawBox (w, rect);
|
2019-11-06 02:40:47 +01:00
|
|
|
}
|
|
|
|
|
2019-10-08 04:37:19 +02:00
|
|
|
//----------------------------------------------------------------------
|
|
|
|
inline void drawBox (FWidget* w, const FRect& r)
|
|
|
|
{
|
|
|
|
// Use box-drawing characters to draw a border
|
|
|
|
|
|
|
|
if ( ! w )
|
|
|
|
return;
|
|
|
|
|
|
|
|
w->print() << r.getUpperLeftPos()
|
2019-11-06 02:40:47 +01:00
|
|
|
<< fc::BoxDrawingsDownAndRight // ┌
|
2020-05-02 00:07:35 +02:00
|
|
|
<< FString{r.getWidth() - 2, fc::BoxDrawingsHorizontal} // ─
|
2019-10-08 04:37:19 +02:00
|
|
|
<< fc::BoxDrawingsDownAndLeft; // ┐
|
|
|
|
|
|
|
|
for (int y = r.getY1() + 1; y < r.getY2(); y++)
|
|
|
|
{
|
2020-05-02 00:07:35 +02:00
|
|
|
w->print() << FPoint{r.getX1(), y}
|
2019-10-08 04:37:19 +02:00
|
|
|
<< fc::BoxDrawingsVertical // │
|
2020-05-02 00:07:35 +02:00
|
|
|
<< FPoint{r.getX2(), y}
|
2019-10-08 04:37:19 +02:00
|
|
|
<< fc::BoxDrawingsVertical; // │
|
|
|
|
}
|
|
|
|
|
|
|
|
w->print() << r.getLowerLeftPos()
|
2019-11-06 02:40:47 +01:00
|
|
|
<< fc::BoxDrawingsUpAndRight // └
|
2020-05-02 00:07:35 +02:00
|
|
|
<< FString{r.getWidth() - 2, fc::BoxDrawingsHorizontal} // ─
|
2019-10-08 04:37:19 +02:00
|
|
|
<< fc::BoxDrawingsUpAndLeft; // ┘
|
|
|
|
}
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
inline void drawNewFontBox (FWidget* w, const FRect& r)
|
|
|
|
{
|
|
|
|
// Use new graphical font characters to draw a border
|
|
|
|
|
|
|
|
w->print() << r.getUpperLeftPos()
|
|
|
|
<< fc::NF_border_corner_middle_upper_left // ┌
|
2020-05-02 00:07:35 +02:00
|
|
|
<< FString{r.getWidth() - 2, fc::NF_border_line_horizontal} // ─
|
2019-10-08 04:37:19 +02:00
|
|
|
<< fc::NF_border_corner_middle_upper_right; // ┐
|
|
|
|
|
|
|
|
for (int y = r.getY1() + 1; y < r.getY2(); y++)
|
|
|
|
{
|
2020-05-02 00:07:35 +02:00
|
|
|
w->print() << FPoint{r.getX1(), y}
|
2019-11-06 02:40:47 +01:00
|
|
|
<< fc::NF_border_line_vertical // │
|
2020-05-02 00:07:35 +02:00
|
|
|
<< FPoint{r.getX2(), y}
|
2019-11-06 02:40:47 +01:00
|
|
|
<< fc::NF_border_line_vertical; // │
|
2019-10-08 04:37:19 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
w->print() << r.getLowerLeftPos()
|
|
|
|
<< fc::NF_border_corner_middle_lower_left // └
|
2020-05-02 00:07:35 +02:00
|
|
|
<< FString{r.getWidth() - 2, fc::NF_border_line_horizontal} // ─
|
2019-10-08 04:37:19 +02:00
|
|
|
<< fc::NF_border_corner_middle_lower_right; // ┘
|
|
|
|
}
|
|
|
|
|
2019-11-06 02:40:47 +01:00
|
|
|
//----------------------------------------------------------------------
|
|
|
|
inline void drawNewFontListBox (FWidget* w, const FRect& r)
|
|
|
|
{
|
|
|
|
w->print() << r.getUpperLeftPos()
|
|
|
|
<< fc::NF_border_line_middle_left_down // ┌
|
2020-05-02 00:07:35 +02:00
|
|
|
<< FString{r.getWidth() - 2, fc::NF_border_line_horizontal} // ─
|
2019-11-06 02:40:47 +01:00
|
|
|
<< fc::NF_border_line_left_down; // ╷
|
|
|
|
|
|
|
|
for (int y = r.getY1() + 1; y < r.getY2(); y++)
|
|
|
|
{
|
2020-05-02 00:07:35 +02:00
|
|
|
w->print() << FPoint{r.getX1(), y}
|
2019-11-06 02:40:47 +01:00
|
|
|
<< fc::NF_border_line_left // border left ⎸
|
2020-05-02 00:07:35 +02:00
|
|
|
<< FPoint{r.getX2(), y}
|
2019-11-06 02:40:47 +01:00
|
|
|
<< fc::NF_border_line_left; // border left ⎸
|
|
|
|
}
|
|
|
|
|
|
|
|
w->print() << r.getLowerLeftPos()
|
|
|
|
<< fc::NF_border_line_middle_right_up // └
|
2020-05-02 00:07:35 +02:00
|
|
|
<< FString{r.getWidth() - 2, fc::NF_border_line_horizontal} // ─
|
2019-11-06 02:40:47 +01:00
|
|
|
<< fc::NF_border_line_left_up; // ╵
|
|
|
|
}
|
|
|
|
|
2019-10-08 04:37:19 +02:00
|
|
|
} // namespace finalcut
|