Streaming into an FTextView() object
This commit is contained in:
parent
8c67f64db4
commit
6b9336d6c1
|
@ -1,3 +1,10 @@
|
|||
2019-09-29 Markus Gans <guru.mail@muenster.de>
|
||||
* Streaming into an FTextView() object
|
||||
* Fixes the streaming of empty FString objects into a stream with
|
||||
a width > 0
|
||||
* The FString operator [] now returns a null character ('\0')
|
||||
if the position is equal to the string length
|
||||
|
||||
2019-09-28 Markus Gans <guru.mail@muenster.de>
|
||||
* Support for displaying full-width characters (2 columns wide)
|
||||
on the terminal. This is particularly important for the correct
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
examples/.libs/* usr/share/doc/libfinal-examples/examples
|
||||
examples/*.cpp usr/share/doc/libfinal-examples/examples
|
||||
examples/Makefile.clang usr/share/doc/libfinal-examples/examples
|
||||
examples/Makefile.gcc usr/share/doc/libfinal-examples/examples
|
||||
doc/readme.txt usr/lib/libfinal/examples
|
||||
examples/.libs/* usr/lib/libfinal/examples
|
||||
examples/*.cpp usr/lib/libfinal/examples
|
||||
examples/Makefile.clang usr/lib/libfinal/examples
|
||||
examples/Makefile.gcc usr/lib/libfinal/examples
|
||||
|
|
|
@ -1 +1,2 @@
|
|||
usr/share/doc/libfinal-examples/examples/Makefile.gcc usr/share/doc/libfinal-examples/examples/Makefile
|
||||
usr/lib/libfinal/examples usr/share/doc/libfinal-examples/examples
|
||||
usr/lib/libfinal/examples/Makefile.gcc usr/lib/libfinal/examples/Makefile
|
||||
|
|
|
@ -19,6 +19,7 @@ include /usr/share/dpkg/default.mk
|
|||
|
||||
# main packaging script based on dh7 syntax
|
||||
%:
|
||||
sed -i 's/doc\///g' README.md
|
||||
dh $@ --with autotools-dev
|
||||
|
||||
# debmake generated override targets
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
----------------------------------------------------------------------
|
||||
The Final Cut
|
||||
FINAL CUT
|
||||
----------------------------------------------------------------------
|
||||
|
||||
The Final Cut is a C++ class library and widget toolkit with full mouse
|
||||
The FINAL CUT is a C++ class library and widget toolkit with full mouse
|
||||
support for creating a text-based user interface. The library supports
|
||||
the programmer to develop an application for the text console. It allows
|
||||
the simultaneous handling of multiple text windows on the screen.
|
||||
|
|
|
@ -898,9 +898,7 @@ lDouble& Calc::getValue()
|
|||
//----------------------------------------------------------------------
|
||||
void Calc::setDisplay (lDouble d)
|
||||
{
|
||||
char buffer[33]{};
|
||||
snprintf (buffer, sizeof(buffer), "%32.11Lg", d);
|
||||
input = buffer;
|
||||
input.sprintf("%32.11Lg", d);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
|
|
@ -74,9 +74,9 @@ int main (int argc, char* argv[])
|
|||
scroll_text.setGeometry (FPoint(2, 8), FSize(32, 3));
|
||||
finalcut::FString text_line{"FINAL CUT supports "
|
||||
"full-width characters."};
|
||||
scroll_text << full(text_line);
|
||||
scroll_text.setStatusbarMessage ("You can scroll right and "
|
||||
"left with the arrow keys");
|
||||
scroll_text.append(full(text_line));
|
||||
|
||||
// Create a OK button
|
||||
finalcut::FButton btn("&OK", &dgl);
|
||||
|
|
|
@ -87,8 +87,7 @@ void term_boundaries (int& x, int& y)
|
|||
void move (int xold, int yold, int xnew, int ynew)
|
||||
{
|
||||
// prints the cursor move escape sequence
|
||||
std::string sequence{};
|
||||
char from[26]{}, to[26]{}, byte[20]{};
|
||||
finalcut::FString buffer{}, sequence{}, from{}, to{}, byte{};
|
||||
const std::string ctrl_character[] =
|
||||
{
|
||||
"NUL", "SOH", "STX", "ETX", "EOT", "ENQ", "ACK", "BEL",
|
||||
|
@ -100,36 +99,33 @@ void move (int xold, int yold, int xnew, int ynew)
|
|||
|
||||
term_boundaries(xold, yold);
|
||||
term_boundaries(xnew, ynew);
|
||||
snprintf (from, sizeof(from), "(%3d;%3d)", xold, yold);
|
||||
snprintf (to, sizeof(to), "(%3d;%3d)", xnew, ynew);
|
||||
std::cout << std::right << std::setw(10) << from
|
||||
<< " -> "
|
||||
<< std::left << std::setw(10) << to
|
||||
<< " ";
|
||||
|
||||
// get the move string
|
||||
char* buffer = finalcut::FTerm::moveCursorString (xold, yold, xnew, ynew);
|
||||
uInt len = uInt(std::strlen(buffer));
|
||||
buffer = finalcut::FTerm::moveCursorString (xold, yold, xnew, ynew);
|
||||
|
||||
for (uInt i = 0; i < len; i++)
|
||||
for (auto&& ch : buffer)
|
||||
{
|
||||
char ch = buffer[i];
|
||||
|
||||
if ( ch < 0x21 )
|
||||
sequence += ctrl_character[uInt(ch)];
|
||||
sequence += ctrl_character[std::size_t(ch)];
|
||||
else
|
||||
sequence += ch;
|
||||
|
||||
sequence += ' ';
|
||||
}
|
||||
|
||||
std::cout << std::setw(21) << sequence << " ";
|
||||
from.sprintf ("(%3d;%3d)", xold, yold);
|
||||
to.sprintf ("(%3d;%3d)", xnew, ynew);
|
||||
std::size_t len = buffer.getLength();
|
||||
|
||||
if ( len <= 1 )
|
||||
snprintf (byte, sizeof(byte), "%d byte ", len);
|
||||
byte.sprintf ("%d byte ", len);
|
||||
else
|
||||
snprintf (byte, sizeof(byte), "%d bytes", len);
|
||||
byte.sprintf ("%d bytes", len);
|
||||
|
||||
std::cout << std::right << std::setw(10) << byte << "\r\n";
|
||||
std::cout << std::right << std::setw(10) << from << " -> "
|
||||
<< std::left << std::setw(10) << to << " "
|
||||
<< std::setw(21) << sequence << " "
|
||||
<< std::right << std::setw(10) << byte << "\r\n";
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -425,7 +425,7 @@ void FApplication::cmd_options (const int& argc, char* argv[])
|
|||
{C_STR("no-esc-for-alt-meta"), no_argument, 0, 0 },
|
||||
#endif
|
||||
|
||||
{0, 0, 0, 0 }
|
||||
{nullptr, 0, nullptr, 0 }
|
||||
};
|
||||
|
||||
opterr = 0;
|
||||
|
|
|
@ -144,8 +144,7 @@ uInt character[][fc::NUM_OF_ENCODINGS] =
|
|||
{0x1af4, 0, 0xf4, 0}, // ] - NF_rev_menu_button3 (2)
|
||||
{0x1af5, 0, 0xf5, 0}, // ] - NF_shadow_box_right (2)
|
||||
{0x1afb, 0, 0xfb, 0}, // ✓ - NF_check_mark (2)
|
||||
{0x221a, 0, 0xfb, 'x'}, // √ - square root
|
||||
{0x25cf, '`', 0x04, '*'} // ● - black circle
|
||||
{0x221a, 0, 0xfb, 'x'} // √ - square root
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -204,7 +203,7 @@ const std::size_t lastKeyItem = \
|
|||
std::size_t((sizeof(vt100_key_to_utf8) / sizeof(vt100_key_to_utf8[0])) - 1);
|
||||
|
||||
|
||||
wchar_t cp437_to_ucs[][2] =
|
||||
wchar_t cp437_ucs[][2] =
|
||||
{
|
||||
{0x00, 0x0000}, // null
|
||||
{0x01, 0x263a}, // white smiling face
|
||||
|
@ -465,7 +464,7 @@ wchar_t cp437_to_ucs[][2] =
|
|||
};
|
||||
|
||||
const std::size_t lastCP437Item = \
|
||||
std::size_t((sizeof(cp437_to_ucs) / sizeof(cp437_to_ucs[0])) - 1);
|
||||
std::size_t((sizeof(cp437_ucs) / sizeof(cp437_ucs[0])) - 1);
|
||||
|
||||
// Based on http://www.unicode.org/charts/PDF/UFF00.pdf
|
||||
wchar_t halfWidth_fullWidth[][2] =
|
||||
|
|
|
@ -825,7 +825,7 @@ inline FLineEdit::offsetPair FLineEdit::endPosToOffset (std::size_t pos)
|
|||
{
|
||||
if ( char_width == 1 )
|
||||
{
|
||||
if ( pos > 0 && getColumnWidth(text[pos - 1]) == 2 )
|
||||
if ( getColumnWidth(text[pos - 1]) == 2 ) // pos is always > 0
|
||||
{
|
||||
fullwidth_char_offset = 1;
|
||||
break;
|
||||
|
|
|
@ -1648,11 +1648,8 @@ void FListView::drawListLine ( const FListViewItem* item
|
|||
width -= (indent + 1);
|
||||
|
||||
if ( item->isCheckable() )
|
||||
{
|
||||
static constexpr std::size_t checkbox_space = 4;
|
||||
width -= checkbox_space;
|
||||
}
|
||||
}
|
||||
|
||||
// Insert alignment spaces
|
||||
if ( align_offset > 0 )
|
||||
|
@ -1999,7 +1996,6 @@ void FListView::updateDrawing (bool draw_vbar, bool draw_hbar)
|
|||
std::size_t FListView::determineLineWidth (FListViewItem* item)
|
||||
{
|
||||
static constexpr std::size_t padding_space = 1;
|
||||
static constexpr std::size_t checkbox_space = 4;
|
||||
std::size_t line_width = padding_space; // leading space
|
||||
std::size_t column_idx{0};
|
||||
std::size_t entries = std::size_t(item->column_list.size());
|
||||
|
@ -2109,7 +2105,7 @@ void FListView::recalculateVerticalBar (std::size_t element_count)
|
|||
void FListView::mouseHeaderClicked()
|
||||
{
|
||||
int column{1};
|
||||
int checkbox_offset = ( hasCheckableItems() ) ? 4 : 0;
|
||||
int checkbox_offset = ( hasCheckableItems() ) ? checkbox_space : 0;
|
||||
int header_start = 2 + checkbox_offset;
|
||||
int header_pos = clicked_header_pos.getX() + xoffset;
|
||||
|
||||
|
|
|
@ -534,7 +534,6 @@ inline void FMenuBar::drawItem (FMenuItem* menuitem, std::size_t& x)
|
|||
|
||||
if ( hotkeypos != NOT_SET )
|
||||
{
|
||||
txt_length--;
|
||||
column_width--;
|
||||
to_char--;
|
||||
}
|
||||
|
|
|
@ -30,6 +30,10 @@
|
|||
namespace finalcut
|
||||
{
|
||||
|
||||
// static class attributes
|
||||
wchar_t FString::null_char{L'\0'};
|
||||
const wchar_t FString::const_null_char{L'\0'};
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// class FString
|
||||
//----------------------------------------------------------------------
|
||||
|
@ -1710,8 +1714,17 @@ const FString operator + (const FString& s, const char c)
|
|||
//----------------------------------------------------------------------
|
||||
std::ostream& operator << (std::ostream& outstr, const FString& s)
|
||||
{
|
||||
const std::size_t width = std::size_t(outstr.width());
|
||||
|
||||
if ( s.length > 0 )
|
||||
{
|
||||
outstr << s.wc_to_c_str(s.string);
|
||||
}
|
||||
else if ( width > 0 )
|
||||
{
|
||||
FString fill_str(width, outstr.fill());
|
||||
outstr << s.wc_to_c_str(fill_str.string);
|
||||
}
|
||||
|
||||
return outstr;
|
||||
}
|
||||
|
@ -1735,8 +1748,17 @@ std::istream& operator >> (std::istream& instr, FString& s)
|
|||
//----------------------------------------------------------------------
|
||||
std::wostream& operator << (std::wostream& outstr, const FString& s)
|
||||
{
|
||||
const std::size_t width = std::size_t(outstr.width());
|
||||
|
||||
if ( s.length > 0 )
|
||||
{
|
||||
outstr << s.string;
|
||||
}
|
||||
else if ( width > 0 )
|
||||
{
|
||||
FString fill_str(width, outstr.fill());
|
||||
outstr << fill_str.string;
|
||||
}
|
||||
|
||||
return outstr;
|
||||
}
|
||||
|
|
|
@ -835,7 +835,9 @@ int FTerm::closeConsole()
|
|||
if ( fd < 0 ) // console is already closed
|
||||
return 0;
|
||||
|
||||
if ( fsys )
|
||||
if ( ! fsys )
|
||||
getFSystem();
|
||||
|
||||
ret = fsys->close(fd); // close console
|
||||
|
||||
data->setTTYFileDescriptor(-1);
|
||||
|
@ -900,10 +902,10 @@ void FTerm::detectTermSize()
|
|||
|
||||
do
|
||||
{
|
||||
if ( fsys )
|
||||
if ( ! fsys )
|
||||
getFSystem();
|
||||
|
||||
ret = fsys->ioctl (FTermios::getStdOut(), TIOCGWINSZ, &win_size);
|
||||
else
|
||||
ret = -1;
|
||||
}
|
||||
while (errno == EINTR);
|
||||
|
||||
|
@ -1199,12 +1201,18 @@ bool FTerm::scrollTermReverse()
|
|||
//----------------------------------------------------------------------
|
||||
void FTerm::putstring (const char str[], int affcnt)
|
||||
{
|
||||
if ( ! fsys )
|
||||
getFSystem();
|
||||
|
||||
fsys->tputs (str, affcnt, FTerm::putchar_ASCII);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
int FTerm::putchar_ASCII (int c)
|
||||
{
|
||||
if ( ! fsys )
|
||||
getFSystem();
|
||||
|
||||
if ( fsys->putchar(char(c)) == EOF )
|
||||
return 0;
|
||||
else
|
||||
|
@ -1214,6 +1222,9 @@ int FTerm::putchar_ASCII (int c)
|
|||
//----------------------------------------------------------------------
|
||||
int FTerm::putchar_UTF8 (int c)
|
||||
{
|
||||
if ( ! fsys )
|
||||
getFSystem();
|
||||
|
||||
if ( c < 0x80 )
|
||||
{
|
||||
// 1 Byte (7-bit): 0xxxxxxx
|
||||
|
@ -1752,6 +1763,9 @@ void FTerm::init_term_encoding()
|
|||
int stdout_no = FTermios::getStdOut();
|
||||
const char* termtype = data->getTermType();
|
||||
|
||||
if ( ! fsys )
|
||||
getFSystem();
|
||||
|
||||
if ( fsys->isTTY(stdout_no)
|
||||
&& ! std::strcmp(nl_langinfo(CODESET), "UTF-8") )
|
||||
{
|
||||
|
@ -2357,6 +2371,9 @@ void FTerm::initBaudRate()
|
|||
uInt baud = FTermios::getBaudRate();
|
||||
data->setBaudrate(baud);
|
||||
|
||||
if ( ! fsys )
|
||||
getFSystem();
|
||||
|
||||
if ( fsys->isTTY(stdout_no) )
|
||||
opti_move->setBaudRate(int(baud));
|
||||
}
|
||||
|
@ -2501,10 +2518,9 @@ void FTerm::signal_handler (int signum)
|
|||
init_term_object->finish();
|
||||
std::fflush (stderr);
|
||||
std::fflush (stdout);
|
||||
std::fprintf ( stderr
|
||||
, "\nProgram stopped: signal %d (%s)\n"
|
||||
, signum
|
||||
, strsignal(signum) );
|
||||
std::cerr << "\nProgram stopped: signal "
|
||||
<< signum
|
||||
<< " (" << strsignal(signum) << ")" << std::endl;
|
||||
std::terminate();
|
||||
}
|
||||
}
|
||||
|
@ -2537,9 +2553,9 @@ wchar_t cp437_to_unicode (uChar c)
|
|||
|
||||
for (std::size_t i{0}; i <= fc::lastCP437Item; i++)
|
||||
{
|
||||
if ( fc::cp437_to_ucs[i][CP437] == c ) // found
|
||||
if ( fc::cp437_ucs[i][CP437] == c ) // found
|
||||
{
|
||||
ucs = fc::cp437_to_ucs[i][UNICODE];
|
||||
ucs = fc::cp437_ucs[i][UNICODE];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -2556,9 +2572,9 @@ uChar unicode_to_cp437 (wchar_t ucs)
|
|||
|
||||
for (std::size_t i{0}; i <= fc::lastCP437Item; i++)
|
||||
{
|
||||
if ( fc::cp437_to_ucs[i][UNICODE] == ucs ) // found
|
||||
if ( fc::cp437_ucs[i][UNICODE] == ucs ) // found
|
||||
{
|
||||
c = uChar(fc::cp437_to_ucs[i][CP437]);
|
||||
c = uChar(fc::cp437_ucs[i][CP437]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -546,10 +546,11 @@ const FString FTermDetection::getXTermColorName (FColor color)
|
|||
struct timeval tv{};
|
||||
int stdin_no = FTermios::getStdIn();
|
||||
|
||||
char temp[512]{};
|
||||
std::fprintf (stdout, OSC "4;%hu;?" BEL, color); // get color
|
||||
// get color
|
||||
std::fprintf (stdout, OSC "4;%hu;?" BEL, color);
|
||||
std::fflush (stdout);
|
||||
|
||||
char temp[512]{};
|
||||
FD_ZERO(&ifds);
|
||||
FD_SET(stdin_no, &ifds);
|
||||
tv.tv_sec = 0;
|
||||
|
|
|
@ -241,7 +241,7 @@ void FTextView::insert (const FString& str, int pos)
|
|||
hbar->setPageSize (int(maxLineWidth), int(getTextWidth()));
|
||||
hbar->calculateSliderValues();
|
||||
|
||||
if ( isShown() && ! hbar->isShown() )
|
||||
if ( isShown() && isHorizontallyScrollable() )
|
||||
hbar->show();
|
||||
}
|
||||
}
|
||||
|
@ -256,10 +256,10 @@ void FTextView::insert (const FString& str, int pos)
|
|||
vbar->setPageSize (int(getRows()), int(getTextHeight()));
|
||||
vbar->calculateSliderValues();
|
||||
|
||||
if ( isShown() && ! vbar->isShown() && getRows() > getTextHeight() )
|
||||
if ( isShown() && ! vbar->isShown() && isVerticallyScrollable() )
|
||||
vbar->show();
|
||||
|
||||
if ( isShown() && vbar->isShown() && getRows() <= getTextHeight() )
|
||||
if ( isShown() && vbar->isShown() && ! isVerticallyScrollable() )
|
||||
vbar->hide();
|
||||
|
||||
processChanged();
|
||||
|
@ -566,15 +566,15 @@ void FTextView::adjustSize()
|
|||
|
||||
if ( isShown() )
|
||||
{
|
||||
if ( last_line < int(height) + nf_offset - 1 )
|
||||
vbar->hide();
|
||||
else
|
||||
vbar->show();
|
||||
|
||||
if ( max_width < int(width) - nf_offset - 1 )
|
||||
hbar->hide();
|
||||
else
|
||||
if ( isHorizontallyScrollable() )
|
||||
hbar->show();
|
||||
else
|
||||
hbar->hide();
|
||||
|
||||
if ( isVerticallyScrollable() )
|
||||
vbar->show();
|
||||
else
|
||||
vbar->hide();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -662,18 +662,7 @@ void FTextView::draw()
|
|||
if ( isMonochron() )
|
||||
setReverse(false);
|
||||
|
||||
if ( ! isShown() ) // first drawing
|
||||
{
|
||||
vbar->show();
|
||||
hbar->show();
|
||||
}
|
||||
|
||||
if ( vbar->isShown() )
|
||||
vbar->redraw();
|
||||
|
||||
if ( hbar->isShown() )
|
||||
hbar->redraw();
|
||||
|
||||
drawScrollbars();
|
||||
drawText();
|
||||
|
||||
if ( hasFocus() && getStatusBar() )
|
||||
|
@ -693,6 +682,20 @@ void FTextView::draw()
|
|||
flush_out();
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
void FTextView::drawScrollbars()
|
||||
{
|
||||
if ( ! hbar->isShown() && isHorizontallyScrollable() )
|
||||
hbar->show();
|
||||
else
|
||||
vbar->redraw();
|
||||
|
||||
if ( ! vbar->isShown() && isVerticallyScrollable() )
|
||||
vbar->show();
|
||||
else
|
||||
hbar->redraw();
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
void FTextView::drawText()
|
||||
{
|
||||
|
|
|
@ -860,11 +860,12 @@ FVTerm::covered_state FVTerm::isCovered ( const FPoint& pos
|
|||
if ( ! area )
|
||||
return non_covered;
|
||||
|
||||
bool found( area == vdesktop );
|
||||
auto is_covered = non_covered;
|
||||
|
||||
if ( FWidget::getWindowList() && ! FWidget::getWindowList()->empty() )
|
||||
{
|
||||
bool found( area == vdesktop );
|
||||
|
||||
for (auto& win_obj : *FWidget::getWindowList())
|
||||
{
|
||||
auto win = win_obj->getVWin();
|
||||
|
|
|
@ -42,7 +42,7 @@ extern const std::size_t lastCharItem;
|
|||
extern int vt100_key_to_utf8[][2];
|
||||
extern const std::size_t lastKeyItem;
|
||||
|
||||
extern wchar_t cp437_to_ucs[][2];
|
||||
extern wchar_t cp437_ucs[][2];
|
||||
extern const std::size_t lastCP437Item;
|
||||
|
||||
extern wchar_t halfWidth_fullWidth[][2];
|
||||
|
|
|
@ -358,6 +358,9 @@ class FListView : public FWidget
|
|||
void adjustSize() override;
|
||||
|
||||
private:
|
||||
// Constants
|
||||
static constexpr std::size_t checkbox_space = 4;
|
||||
|
||||
// Typedef
|
||||
struct Header; // forward declaration
|
||||
typedef std::vector<Header> headerItems;
|
||||
|
|
|
@ -58,7 +58,6 @@
|
|||
|
||||
#include <cctype>
|
||||
#include <climits>
|
||||
#include <cstdio> // need for printf
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <iostream>
|
||||
|
|
|
@ -280,6 +280,8 @@ class FString
|
|||
std::size_t length{0};
|
||||
std::size_t bufsize{0};
|
||||
mutable char* c_string{nullptr};
|
||||
static wchar_t null_char;
|
||||
static const wchar_t const_null_char;
|
||||
};
|
||||
|
||||
|
||||
|
@ -292,9 +294,12 @@ inline const char* FString::getClassName()
|
|||
template <typename IndexT>
|
||||
inline wchar_t& FString::operator [] (const IndexT pos)
|
||||
{
|
||||
if ( isNegative(pos) || pos >= IndexT(length) )
|
||||
if ( isNegative(pos) || pos > IndexT(length) )
|
||||
throw std::out_of_range(""); // Invalid index position
|
||||
|
||||
if ( std::size_t(pos) == length )
|
||||
return null_char;
|
||||
|
||||
return string[std::size_t(pos)];
|
||||
}
|
||||
|
||||
|
@ -302,9 +307,12 @@ inline wchar_t& FString::operator [] (const IndexT pos)
|
|||
template <typename IndexT>
|
||||
inline const wchar_t& FString::operator [] (const IndexT pos) const
|
||||
{
|
||||
if ( isNegative(pos) || pos >= IndexT(length) )
|
||||
if ( isNegative(pos) || pos > IndexT(length) )
|
||||
throw std::out_of_range(""); // Invalid index position
|
||||
|
||||
if ( std::size_t(pos) == length )
|
||||
return const_null_char;
|
||||
|
||||
return string[std::size_t(pos)];
|
||||
}
|
||||
|
||||
|
@ -407,17 +415,17 @@ template<typename... Args>
|
|||
inline FString& FString::sprintf (const FString format, Args&&... args)
|
||||
{
|
||||
static constexpr int BUFSIZE = 4096;
|
||||
wchar_t buffer[BUFSIZE]{};
|
||||
wchar_t buf[BUFSIZE]{};
|
||||
|
||||
if ( ! format )
|
||||
if ( format.isEmpty() )
|
||||
{
|
||||
clear();
|
||||
return *this;
|
||||
}
|
||||
|
||||
std::swprintf ( buffer, BUFSIZE
|
||||
, format.wc_str(), std::forward<Args>(args)... );
|
||||
_assign(buffer);
|
||||
std::swprintf ( buf, BUFSIZE, format.wc_str()
|
||||
, std::forward<Args>(args)... );
|
||||
_assign(buf);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
|
|
@ -418,10 +418,18 @@ inline bool FTerm::unsetUTF8()
|
|||
template<typename... Args>
|
||||
inline void FTerm::putstringf (const char format[], Args&&... args)
|
||||
{
|
||||
char buf[512]{};
|
||||
char* str = buf;
|
||||
std::snprintf (str, sizeof(buf), format, std::forward<Args>(args)...);
|
||||
fsys->tputs (str, 1, FTerm::putchar_ASCII);
|
||||
int size = std::snprintf ( nullptr, 0, format
|
||||
, std::forward<Args>(args)... ) + 1;
|
||||
|
||||
if ( size == -1 )
|
||||
return;
|
||||
|
||||
if ( ! fsys )
|
||||
getFSystem();
|
||||
|
||||
std::vector<char> buf(size);
|
||||
std::snprintf (&buf[0], size, format, std::forward<Args>(args)...);
|
||||
fsys->tputs (&buf[0], 1, FTerm::putchar_ASCII);
|
||||
}
|
||||
|
||||
} // namespace finalcut
|
||||
|
|
|
@ -208,15 +208,8 @@ inline void FTermBuffer::clear()
|
|||
template<typename... Args>
|
||||
inline int FTermBuffer::writef (const FString format, Args&&... args)
|
||||
{
|
||||
static constexpr int BUFSIZE = 4096;
|
||||
wchar_t buffer[BUFSIZE]{};
|
||||
|
||||
if ( format.isEmpty() )
|
||||
return 0;
|
||||
|
||||
std::swprintf ( buffer, BUFSIZE
|
||||
, format.wc_str(), std::forward<Args>(args)... );
|
||||
FString str(buffer);
|
||||
FString str{};
|
||||
str.sprintf (format, std::forward<Args>(args)...);
|
||||
return write(str);
|
||||
}
|
||||
|
||||
|
|
|
@ -85,6 +85,13 @@ class FTextView : public FWidget
|
|||
// Disable assignment operator (=)
|
||||
FTextView& operator = (const FTextView&) = delete;
|
||||
|
||||
// Overloaded operators
|
||||
FTextView& operator = (const FString&);
|
||||
template <typename typeT>
|
||||
FTextView& operator << (const typeT&);
|
||||
FTextView& operator << (fc::SpecialCharacter);
|
||||
FTextView& operator << (const std::string&);
|
||||
|
||||
// Accessors
|
||||
const char* getClassName() const override;
|
||||
std::size_t getColumns() const;
|
||||
|
@ -147,6 +154,7 @@ class FTextView : public FWidget
|
|||
, fc::orientation
|
||||
, FTextViewCallback );
|
||||
void draw() override;
|
||||
void drawScrollbars();
|
||||
void drawText();
|
||||
bool isPrintable (wchar_t);
|
||||
void processChanged();
|
||||
|
@ -167,6 +175,40 @@ class FTextView : public FWidget
|
|||
};
|
||||
|
||||
// FListBox inline functions
|
||||
//----------------------------------------------------------------------
|
||||
FTextView& FTextView::operator = (const FString& s)
|
||||
{
|
||||
setText(s);
|
||||
return *this;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
template <typename typeT>
|
||||
inline FTextView& FTextView::operator << (const typeT& s)
|
||||
{
|
||||
std::wostringstream outstream;
|
||||
outstream << s;
|
||||
|
||||
if ( ! outstream.str().empty() )
|
||||
append (outstream.str());
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
inline FTextView& FTextView::operator << (fc::SpecialCharacter c)
|
||||
{
|
||||
append (static_cast<wchar_t>(c)); // Required under Solaris
|
||||
return *this;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
inline FTextView& FTextView::operator << (const std::string& string)
|
||||
{
|
||||
append (string);
|
||||
return *this;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
inline const char* FTextView::getClassName() const
|
||||
{ return "FTextView"; }
|
||||
|
|
|
@ -1047,15 +1047,8 @@ inline bool FVTerm::hasUTF8()
|
|||
template<typename... Args>
|
||||
inline int FVTerm::printf (const FString format, Args&&... args)
|
||||
{
|
||||
static constexpr int BUFSIZE = 4096;
|
||||
wchar_t buffer[BUFSIZE]{};
|
||||
|
||||
if ( format.isEmpty() )
|
||||
return 0;
|
||||
|
||||
std::swprintf ( buffer, BUFSIZE
|
||||
, format.wc_str(), std::forward<Args>(args)... );
|
||||
FString str(buffer);
|
||||
FString str{};
|
||||
str.sprintf (format, std::forward<Args>(args)...);
|
||||
return print(str);
|
||||
}
|
||||
|
||||
|
|
|
@ -558,6 +558,7 @@ void FStringTest::equalTest()
|
|||
constexpr wchar_t wch = L'a';
|
||||
CPPUNIT_ASSERT ( one_char == wch );
|
||||
CPPUNIT_ASSERT ( wch == one_char.wc_str()[0] );
|
||||
CPPUNIT_ASSERT ( L'\0' == one_char.wc_str()[1] ); // pos == size
|
||||
|
||||
const finalcut::FString str(L"abc");
|
||||
const finalcut::FString str2(L"abc");
|
||||
|
@ -875,14 +876,27 @@ void FStringTest::streamInsertionTest()
|
|||
out << lDouble(3.141592653589793238L);
|
||||
CPPUNIT_ASSERT ( out == L"3.14159265358979324" );
|
||||
|
||||
out = "abc";
|
||||
out.clear();
|
||||
std::ostringstream ostream;
|
||||
ostream << out;
|
||||
CPPUNIT_ASSERT ( ostream.str() == "" );
|
||||
ostream << std::setfill('*') << std::setw(5) << out;
|
||||
CPPUNIT_ASSERT ( ostream.str() == "*****" );
|
||||
out = "abc";
|
||||
ostream.str("");
|
||||
ostream << out;
|
||||
CPPUNIT_ASSERT ( ostream.str() == "abc" );
|
||||
|
||||
out.clear();
|
||||
std::wostringstream wostream;
|
||||
wostream << out;
|
||||
CPPUNIT_ASSERT ( wostream.str() == L"abc" );
|
||||
CPPUNIT_ASSERT ( wostream.str() == L"" );
|
||||
wostream << std::setfill(L'+') << std::setw(7) << out;
|
||||
CPPUNIT_ASSERT ( wostream.str() == L"+++++++" );
|
||||
out = L"def";
|
||||
wostream.str(L"");
|
||||
wostream << out;
|
||||
CPPUNIT_ASSERT ( wostream.str() == L"def" );
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
@ -957,12 +971,14 @@ void FStringTest::subscriptOperatorTest()
|
|||
CPPUNIT_ASSERT ( s[0] == L'\0' );
|
||||
CPPUNIT_ASSERT ( s[1] == L'\0' );
|
||||
CPPUNIT_ASSERT ( s[2] == L'\0' );
|
||||
CPPUNIT_ASSERT ( s[3] == L'\0' ); // pos == size
|
||||
s[0] = L'A';
|
||||
s[1] = L'B';
|
||||
s[2] = L'C';
|
||||
CPPUNIT_ASSERT ( s[0] == L'A' );
|
||||
CPPUNIT_ASSERT ( s[1] == L'B' );
|
||||
CPPUNIT_ASSERT ( s[2] == L'C' );
|
||||
CPPUNIT_ASSERT ( s[3] == L'\0' ); // pos == size
|
||||
CPPUNIT_ASSERT ( s == L"ABC" );
|
||||
}
|
||||
|
||||
|
@ -1202,7 +1218,7 @@ void FStringTest::exceptionTest()
|
|||
CPPUNIT_ASSERT_THROW ( finalcut::FString("abc").toULong()
|
||||
, std::invalid_argument );
|
||||
|
||||
CPPUNIT_ASSERT_THROW ( finalcut::FString("abc")[3]
|
||||
CPPUNIT_ASSERT_THROW ( finalcut::FString("abc")[4]
|
||||
, std::out_of_range );
|
||||
|
||||
CPPUNIT_ASSERT_THROW ( finalcut::FString("abc")[-1]
|
||||
|
|
|
@ -600,6 +600,7 @@ class ftermfreebsdTest : public CPPUNIT_NS::TestFixture, test::ConEmu
|
|||
|
||||
// End of test suite definition
|
||||
CPPUNIT_TEST_SUITE_END();
|
||||
wchar_t charEncode (wchar_t);
|
||||
};
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
@ -697,46 +698,60 @@ void ftermfreebsdTest::freebsdConsoleTest()
|
|||
freebsd.setCursorStyle(freebsd.getCursorStyle());
|
||||
CPPUNIT_ASSERT ( freebsd.getCursorStyle() == finalcut::fc::blink_cursor );
|
||||
|
||||
finalcut::fc::encoding enc = finalcut::fc::PC;
|
||||
CPPUNIT_ASSERT ( finalcut::fc::character[2][enc] == 21 );
|
||||
CPPUNIT_ASSERT ( finalcut::fc::character[3][enc] == 8 );
|
||||
CPPUNIT_ASSERT ( finalcut::fc::character[4][enc] == 10 );
|
||||
CPPUNIT_ASSERT ( finalcut::fc::character[5][enc] == 19 );
|
||||
CPPUNIT_ASSERT ( finalcut::fc::character[6][enc] == 18 );
|
||||
CPPUNIT_ASSERT ( finalcut::fc::character[8][enc] == 22 );
|
||||
CPPUNIT_ASSERT ( finalcut::fc::character[9][enc] == 24 );
|
||||
CPPUNIT_ASSERT ( finalcut::fc::character[10][enc] == 25 );
|
||||
CPPUNIT_ASSERT ( finalcut::fc::character[11][enc] == 26 );
|
||||
CPPUNIT_ASSERT ( finalcut::fc::character[12][enc] == 27 );
|
||||
CPPUNIT_ASSERT ( finalcut::fc::character[23][enc] == 4 );
|
||||
CPPUNIT_ASSERT ( finalcut::fc::character[25][enc] == 4 );
|
||||
CPPUNIT_ASSERT ( finalcut::fc::character[26][enc] == 4 );
|
||||
CPPUNIT_ASSERT ( finalcut::fc::character[57][enc] == 16 );
|
||||
CPPUNIT_ASSERT ( finalcut::fc::character[58][enc] == 17 );
|
||||
CPPUNIT_ASSERT ( finalcut::fc::character[59][enc] == 16 );
|
||||
CPPUNIT_ASSERT ( finalcut::fc::character[60][enc] == 17 );
|
||||
CPPUNIT_ASSERT ( finalcut::fc::character[105][enc] == 4 );
|
||||
const auto c1 = finalcut::fc::Section; // §
|
||||
const auto c2 = finalcut::fc::InverseBullet; // ◘
|
||||
const auto c3 = finalcut::fc::InverseWhiteCircle; // ◙
|
||||
const auto c4 = finalcut::fc::DoubleExclamationMark; // ‼
|
||||
const auto c5 = finalcut::fc::UpDownArrow; // ↕
|
||||
const auto c6 = finalcut::fc::BlackRectangle; // ▬
|
||||
const auto c7 = finalcut::fc::UpwardsArrow; // ↑
|
||||
const auto c8 = finalcut::fc::DownwardsArrow; // ↓
|
||||
const auto c9 = finalcut::fc::RightwardsArrow; // →
|
||||
const auto c10 = finalcut::fc::LeftwardsArrow; // ←
|
||||
const auto c11 = finalcut::fc::Bullet; // •
|
||||
const auto c12 = finalcut::fc::BlackCircle; // ●
|
||||
const auto c13 = finalcut::fc::BlackDiamondSuit; // ◆
|
||||
const auto c14 = finalcut::fc::BlackRightPointingTriangle; // ▶
|
||||
const auto c15 = finalcut::fc::BlackLeftPointingTriangle; // ◀
|
||||
const auto c16 = finalcut::fc::BlackRightPointingPointer; // ►
|
||||
const auto c17 = finalcut::fc::BlackLeftPointingPointer; // ◄
|
||||
CPPUNIT_ASSERT ( charEncode(c1) == 21 ); // §
|
||||
CPPUNIT_ASSERT ( charEncode(c2) == 8 ); // ◘
|
||||
CPPUNIT_ASSERT ( charEncode(c3) == 10 ); // ◙
|
||||
CPPUNIT_ASSERT ( charEncode(c4) == 19 ); // ‼
|
||||
CPPUNIT_ASSERT ( charEncode(c5) == 18 ); // ↕
|
||||
CPPUNIT_ASSERT ( charEncode(c6) == 22 ); // ▬
|
||||
CPPUNIT_ASSERT ( charEncode(c7) == 24 ); // ↑
|
||||
CPPUNIT_ASSERT ( charEncode(c8) == 25 ); // ↓
|
||||
CPPUNIT_ASSERT ( charEncode(c9) == 26 ); // →
|
||||
CPPUNIT_ASSERT ( charEncode(c10) == 27 ); // ←
|
||||
CPPUNIT_ASSERT ( charEncode(c11) == 4 ); // •
|
||||
CPPUNIT_ASSERT ( charEncode(c12) == 4 ); // ●
|
||||
CPPUNIT_ASSERT ( charEncode(c13) == 4 ); // ◆
|
||||
CPPUNIT_ASSERT ( charEncode(c14) == 16 ); // ▶
|
||||
CPPUNIT_ASSERT ( charEncode(c15) == 17 ); // ◀
|
||||
CPPUNIT_ASSERT ( charEncode(c16) == 16 ); // ►
|
||||
CPPUNIT_ASSERT ( charEncode(c17) == 17 ); // ◄
|
||||
|
||||
freebsd.initCharMap();
|
||||
|
||||
CPPUNIT_ASSERT ( finalcut::fc::character[2][enc] == 36 );
|
||||
CPPUNIT_ASSERT ( finalcut::fc::character[3][enc] == 42 );
|
||||
CPPUNIT_ASSERT ( finalcut::fc::character[4][enc] == 42 );
|
||||
CPPUNIT_ASSERT ( finalcut::fc::character[5][enc] == 33 );
|
||||
CPPUNIT_ASSERT ( finalcut::fc::character[6][enc] == 73 );
|
||||
CPPUNIT_ASSERT ( finalcut::fc::character[8][enc] == 95 );
|
||||
CPPUNIT_ASSERT ( finalcut::fc::character[9][enc] == 94 );
|
||||
CPPUNIT_ASSERT ( finalcut::fc::character[10][enc] == 118 );
|
||||
CPPUNIT_ASSERT ( finalcut::fc::character[11][enc] == 62 );
|
||||
CPPUNIT_ASSERT ( finalcut::fc::character[12][enc] == 60 );
|
||||
CPPUNIT_ASSERT ( finalcut::fc::character[23][enc] == 42 );
|
||||
CPPUNIT_ASSERT ( finalcut::fc::character[25][enc] == 42 );
|
||||
CPPUNIT_ASSERT ( finalcut::fc::character[26][enc] == 42 );
|
||||
CPPUNIT_ASSERT ( finalcut::fc::character[57][enc] == 62 );
|
||||
CPPUNIT_ASSERT ( finalcut::fc::character[58][enc] == 60 );
|
||||
CPPUNIT_ASSERT ( finalcut::fc::character[59][enc] == 62 );
|
||||
CPPUNIT_ASSERT ( finalcut::fc::character[60][enc] == 60 );
|
||||
CPPUNIT_ASSERT ( finalcut::fc::character[105][enc] == 42 );
|
||||
CPPUNIT_ASSERT ( charEncode(c1) == 36 ); // $
|
||||
CPPUNIT_ASSERT ( charEncode(c2) == 42 ); // *
|
||||
CPPUNIT_ASSERT ( charEncode(c3) == 42 ); // *
|
||||
CPPUNIT_ASSERT ( charEncode(c4) == 33 ); // !
|
||||
CPPUNIT_ASSERT ( charEncode(c5) == 73 ); // I
|
||||
CPPUNIT_ASSERT ( charEncode(c6) == 95 ); // _
|
||||
CPPUNIT_ASSERT ( charEncode(c7) == 94 ); // ^
|
||||
CPPUNIT_ASSERT ( charEncode(c8) == 118 ); // v
|
||||
CPPUNIT_ASSERT ( charEncode(c9) == 62 ); // >
|
||||
CPPUNIT_ASSERT ( charEncode(c10) == 60 ); // <
|
||||
CPPUNIT_ASSERT ( charEncode(c11) == 42 ); // *
|
||||
CPPUNIT_ASSERT ( charEncode(c12) == 42 ); // *
|
||||
CPPUNIT_ASSERT ( charEncode(c13) == 42 ); // *
|
||||
CPPUNIT_ASSERT ( charEncode(c14) == 62 ); // >
|
||||
CPPUNIT_ASSERT ( charEncode(c15) == 60 ); // <
|
||||
CPPUNIT_ASSERT ( charEncode(c16) == 62 ); // >
|
||||
CPPUNIT_ASSERT ( charEncode(c17) == 60 ); // <
|
||||
|
||||
term_detection->detect();
|
||||
|
||||
|
@ -798,6 +813,22 @@ void ftermfreebsdTest::freebsdConsoleTest()
|
|||
delete fsys;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
wchar_t ftermfreebsdTest::charEncode (wchar_t c)
|
||||
{
|
||||
wchar_t ch_enc{L'\0'};
|
||||
|
||||
for (std::size_t i{0}; i <= finalcut::fc::lastCharItem; i++)
|
||||
{
|
||||
if ( finalcut::fc::character[i][finalcut::fc::UTF8] == uInt(c) )
|
||||
{
|
||||
ch_enc = wchar_t(finalcut::fc::character[i][finalcut::fc::PC]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return ch_enc;
|
||||
}
|
||||
|
||||
// Put the test suite in the registry
|
||||
CPPUNIT_TEST_SUITE_REGISTRATION (ftermfreebsdTest);
|
||||
|
|
Loading…
Reference in New Issue