Support for displaying full-width characters

This commit is contained in:
Markus Gans 2019-09-28 03:13:06 +02:00
parent e15f1a344a
commit 8c67f64db4
86 changed files with 2612 additions and 1379 deletions

1
.gitignore vendored
View File

@ -49,6 +49,7 @@ examples/windows
examples/term-attributes examples/term-attributes
examples/transparent examples/transparent
examples/input-dialog examples/input-dialog
examples/fullwidth-character
examples/7segment examples/7segment
examples/choice examples/choice
examples/listbox examples/listbox

View File

@ -1,3 +1,11 @@
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
display of CJK characters
2019-09-16 Markus Gans <guru.mail@muenster.de>
* Improve FStartOptions implementation
2019-09-08 Markus Gans <guru.mail@muenster.de> 2019-09-08 Markus Gans <guru.mail@muenster.de>
* Remove the lines of the #pragma pack() directive from the code * Remove the lines of the #pragma pack() directive from the code
because they caused a misaligned address because they caused a misaligned address

View File

@ -1,7 +1,12 @@
![FINAL CUT](logo/svg/finalcut-logo.svg) ![FINAL CUT](logo/svg/finalcut-logo.svg)
============================================ ============================================
### Building and code analysis # Library for creating terminal applications with text-based widgets
The FINAL CUT is a C++ class library and widget toolkit with full mouse support for creating a [text-based user interface](https://en.wikipedia.org/wiki/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.
The structure of the Qt framework was originally the inspiration for the C++ class design of FINAL CUT. It provides common controls like dialog boxes, push buttons, check boxes, radio buttons, input lines, list boxes, status bars and so on.
## Building and code analysis
*Latest release:*<br /> *Latest release:*<br />
&#160;&#160;&#160;&#160;&#160;[![Latest Release](https://img.shields.io/github/release/gansm/finalcut.svg)](https://github.com/gansm/finalcut/releases) <br /> &#160;&#160;&#160;&#160;&#160;[![Latest Release](https://img.shields.io/github/release/gansm/finalcut.svg)](https://github.com/gansm/finalcut/releases) <br />
*License:*<br /> *License:*<br />
@ -15,12 +20,7 @@
*Class Reference:*<br /> *Class Reference:*<br />
&#160;&#160;&#160;&#160;&#160;[![documented](https://codedocs.xyz/gansm/finalcut.svg)](https://codedocs.xyz/gansm/finalcut/hierarchy.html) &#160;&#160;&#160;&#160;&#160;[![documented](https://codedocs.xyz/gansm/finalcut.svg)](https://codedocs.xyz/gansm/finalcut/hierarchy.html)
### Description ## Installation
The FINAL CUT is a C++ class library and widget toolkit with full mouse support for creating a [text-based user interface](https://en.wikipedia.org/wiki/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.
The structure of the Qt framework was originally the inspiration for the C++ class design of FINAL CUT. It provides common controls like dialog boxes, push buttons, check boxes, radio buttons, input lines, list boxes, status bars and so on.
### Installation
```bash ```bash
> git clone git://github.com/gansm/finalcut.git > git clone git://github.com/gansm/finalcut.git
> cd finalcut > cd finalcut
@ -30,7 +30,7 @@ The structure of the Qt framework was originally the inspiration for the C++ cla
> su -c "make install" > su -c "make install"
``` ```
### Supported platforms ## Supported platforms
* Linux * Linux
* FreeBSD * FreeBSD
* NetBSD * NetBSD
@ -39,13 +39,12 @@ The structure of the Qt framework was originally the inspiration for the C++ cla
* Cygwin * Cygwin
* Solaris * Solaris
### First steps ## First steps
Read here [how to use the library](doc/first-steps.md#first-steps-with-the-final-cut-widget-toolkit)
[How to use the library](doc/first-steps.md#first-steps-with-the-final-cut-widget-toolkit) ## Some screenshots
### Screenshots The FFileDialog widget with incremental file name search:
The FFileDialog widget:
![FFileDialog](doc/fileopen-dialog.png) ![FFileDialog](doc/fileopen-dialog.png)

View File

@ -59,7 +59,7 @@ case "$1" in
;; ;;
"--fulldebug"|"fulldebug") "--fulldebug"|"fulldebug")
if ! ./configure --prefix="$PREFIX" CPPFLAGS="-DDEBUG" CXXFLAGS="-g -O0 -DDEBUG -W -Wall -Weffc++ -pedantic -pedantic-errors -Wextra -Wformat-nonliteral -Wformat-security -Wformat-y2k -Wimport -Winit-self -Winvalid-pch -Wlong-long -Wmissing-braces -Wmissing-field-initializers -Wmissing-format-attribute -Wmissing-include-dirs -Wmissing-noreturn -Wpacked -Wparentheses -Wpointer-arith -Wredundant-decls -Wreturn-type -Wsequence-point -Wshadow -Wsign-compare -fstack-protector -Wstrict-aliasing -Wstrict-aliasing=3 -Wswitch -Wswitch-enum -Wtrigraphs -Wuninitialized -Wunknown-pragmas -Wunreachable-code -Wunused -Wunused-function -Wunused-label -Wunused-parameter -Wunused-value -Wunused-variable -Wvariadic-macros -Wvolatile-register-var -Wwrite-strings -Wsign-promo -Woverloaded-virtual -Wstrict-null-sentinel -fext-numeric-literals -Wreorder -Wnoexcept -Wnarrowing -Wliteral-suffix -Wctor-dtor-privacy -ftree-loop-distribute-patterns -Wmemset-transposed-args" if ! ./configure --prefix="$PREFIX" CPPFLAGS="-DDEBUG" CXXFLAGS="-g -O0 -DDEBUG -W -Wall -Weffc++ -pedantic -pedantic-errors -Wextra -Wformat-nonliteral -Wformat-security -Wformat-y2k -Wimport -Winit-self -Winvalid-pch -Wlong-long -Wmissing-braces -Wmissing-field-initializers -Wmissing-format-attribute -Wmissing-include-dirs -Wmissing-noreturn -Wpacked -Wparentheses -Wpointer-arith -Wredundant-decls -Wreturn-type -Wsequence-point -Wshadow -Wsign-compare -fstack-protector -Wstrict-aliasing -Wstrict-aliasing=3 -Wswitch -Wswitch-enum -Wtrigraphs -Wuninitialized -Wunknown-pragmas -Wunreachable-code -Wunused -Wunused-function -Wunused-label -Wunused-parameter -Wunused-value -Wunused-variable -Wvariadic-macros -Wvolatile-register-var -Wwrite-strings -Wsign-promo -Woverloaded-virtual -Wstrict-null-sentinel -fext-numeric-literals -Wreorder -Wnoexcept -Wnarrowing -Wliteral-suffix -Wctor-dtor-privacy -ftree-loop-distribute-patterns -Wmemset-transposed-args -Wno-format-nonliteral"
then then
echo "${RED}Configure failed!${NORMAL}" 1>&2 echo "${RED}Configure failed!${NORMAL}" 1>&2
exit 255 exit 255

View File

@ -1,8 +1,20 @@
AUTHORS
COPYING
COPYING.LESSER
ChangeLog
README.md
doc/calendar-draft.png doc/calendar-draft.png
doc/calculator.png
doc/class-diagram.txt doc/class-diagram.txt
doc/class_template.cpp
doc/class_template.h
doc/console_codes-manual.sh doc/console_codes-manual.sh
doc/console_ioctl-manual.sh doc/console_ioctl-manual.sh
doc/faq.md
doc/fileopen-dialog.png doc/fileopen-dialog.png
doc/first-steps.md
doc/framebuffer.txt
doc/Mandelbrot.png
doc/ncurses.supp doc/ncurses.supp
doc/newfont1.png doc/newfont1.png
doc/newfont2.png doc/newfont2.png
@ -13,6 +25,8 @@ doc/terminfo-capabilities.sh
doc/terminfo-manual.sh doc/terminfo-manual.sh
doc/textview.png doc/textview.png
doc/TODO doc/TODO
doc/vga.txt
doc/vt100_line_drawing_graphics.png doc/vt100_line_drawing_graphics.png
doc/virtual-terminal.txt doc/virtual-terminal.txt
doc/xterm.txt
doc/xgraphics doc/xgraphics

View File

@ -6,12 +6,17 @@ docdir = ${datadir}/doc/${PACKAGE}
EXTRA_DIST = \ EXTRA_DIST = \
calendar-draft.png \ calendar-draft.png \
calculator.png \
class-diagram.txt \ class-diagram.txt \
class_template.cpp \
class_template.h \
console_codes-manual.sh \ console_codes-manual.sh \
console_ioctl-manual.sh \ console_ioctl-manual.sh \
faq.md \ faq.md \
fileopen-dialog.png \ fileopen-dialog.png \
first-steps.md \ first-steps.md \
framebuffer.txt \
Mandelbrot.png \
ncurses.supp \ ncurses.supp \
newfont1.png \ newfont1.png \
newfont2.png \ newfont2.png \
@ -22,18 +27,25 @@ EXTRA_DIST = \
terminfo-manual.sh \ terminfo-manual.sh \
textview.png \ textview.png \
TODO \ TODO \
vga.txt \
vt100_line_drawing_graphics.png \ vt100_line_drawing_graphics.png \
virtual-terminal.txt \ virtual-terminal.txt \
xterm.txt \
xgraphics xgraphics
doc_DATA = \ doc_DATA = \
calendar-draft.png \ calendar-draft.png \
calculator.png \
class-diagram.txt \ class-diagram.txt \
class_template.cpp \
class_template.h \
console_codes-manual.sh \ console_codes-manual.sh \
console_ioctl-manual.sh \ console_ioctl-manual.sh \
faq.md \ faq.md \
fileopen-dialog.png \ fileopen-dialog.png \
first-steps.md \ first-steps.md \
framebuffer.txt \
Mandelbrot.png \
ncurses.supp \ ncurses.supp \
newfont1.png \ newfont1.png \
newfont2.png \ newfont2.png \
@ -44,6 +56,8 @@ doc_DATA = \
terminfo-manual.sh \ terminfo-manual.sh \
textview.png \ textview.png \
TODO \ TODO \
vga.txt \
vt100_line_drawing_graphics.png \ vt100_line_drawing_graphics.png \
virtual-terminal.txt \ virtual-terminal.txt \
xterm.txt \
xgraphics xgraphics

View File

@ -11,6 +11,7 @@ noinst_PROGRAMS = \
hello \ hello \
dialog \ dialog \
input-dialog \ input-dialog \
fullwidth-character \
7segment \ 7segment \
choice \ choice \
listbox \ listbox \
@ -36,6 +37,7 @@ noinst_PROGRAMS = \
hello_SOURCES = hello.cpp hello_SOURCES = hello.cpp
dialog_SOURCES = dialog.cpp dialog_SOURCES = dialog.cpp
input_dialog_SOURCES = input-dialog.cpp input_dialog_SOURCES = input-dialog.cpp
fullwidth_character_SOURCES = fullwidth-character.cpp
7segment_SOURCES = 7segment.cpp 7segment_SOURCES = 7segment.cpp
choice_SOURCES = choice.cpp choice_SOURCES = choice.cpp
listbox_SOURCES = listbox.cpp listbox_SOURCES = listbox.cpp

View File

@ -73,14 +73,14 @@ CheckList::CheckList (finalcut::FWidget* parent)
{ {
setText (L"Shopping list"); setText (L"Shopping list");
setShadow(); setShadow();
setGeometry ( FPoint(int(1 + (parent->getWidth() - 30) / 2), 5) setGeometry ( FPoint(int(1 + (parent->getWidth() - 28) / 2), 5)
, FSize(30, 13) ); , FSize(28, 13) );
listView.ignorePadding(); listView.ignorePadding();
listView.setGeometry (FPoint(1, 2), FSize(getWidth(), getHeight() - 1)); listView.setGeometry (FPoint(1, 2), FSize(getWidth(), getHeight() - 1));
// Add columns to the view // Add columns to the view
listView.addColumn ("Item"); listView.addColumn ("Item");
listView.addColumn ("Priority", 12); listView.addColumn ("Priority", 9);
// Set the type of sorting // Set the type of sorting
listView.setColumnSortType (1, fc::by_name); listView.setColumnSortType (1, fc::by_name);

View File

@ -0,0 +1,137 @@
/***********************************************************************
* fullwidth-letter.cpp - Demonstrates use of full-width characters *
* *
* This file is part of the Final Cut widget toolkit *
* *
* Copyright 2019 Markus Gans *
* *
* The 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 *
* the License, or (at your option) any later version. *
* *
* The Final Cut is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU 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/>. *
***********************************************************************/
#include <final/final.h>
#define full(...) finalcut::getFullWidth(__VA_ARGS__)
using finalcut::FPoint;
using finalcut::FSize;
//----------------------------------------------------------------------
// main part
//----------------------------------------------------------------------
int main (int argc, char* argv[])
{
// Create the application object
finalcut::FApplication app(argc, argv);
// Create a simple dialog box
finalcut::FDialog dgl(&app);
dgl.setText (full("Dialog"));
dgl.setSize (FSize(37, 16));
dgl.setPos (FPoint( int(app.getDesktopWidth() - dgl.getWidth()) / 2
, int(app.getDesktopHeight() - dgl.getHeight()) / 2));
dgl.setShadow();
// Create input fields
finalcut::FLineEdit field1 (&dgl);
field1.setLabelText (full("Input"));
field1.setText (L"你好"); // Nǐ hǎo (chinese)
field1.setStatusbarMessage (full("Type your text here"));
field1.setGeometry (FPoint(15, 1), FSize(19, 1));
finalcut::FLineEdit field2 (&dgl);
field2.setLabelText (L"Comment");
field2.setText (full(L"Hello"));
field2.setStatusbarMessage (full("Post a comment"));
field2.setGeometry (FPoint(15, 3), FSize(19, 1));
// Create the button group
finalcut::FButtonGroup group (full("Side"), &dgl);
group.setGeometry(FPoint(2, 5), FSize(32, 3));
// Create radio buttons
finalcut::FRadioButton left ("&" + full("Left"), &group);
finalcut::FRadioButton right ("&" + full("Right"), &group);
left.setStatusbarMessage (full("Prefer the left side"));
right.setStatusbarMessage (full("Prefer the right side"));
left.setGeometry (FPoint(1, 1), FSize(8, 1));
right.setGeometry (FPoint(15, 1), FSize(10, 1));
// Create a scrollable text field
finalcut::FTextView scroll_text (&dgl);
scroll_text.setGeometry (FPoint(2, 8), FSize(32, 3));
finalcut::FString text_line{"FINAL CUT supports "
"full-width characters."};
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("&", &dgl);
btn.setStatusbarMessage (full("Press Enter to exit the dialog"));
btn.setGeometry (FPoint(24, 12), FSize(10, 1));
// Create the status bar
finalcut::FStatusBar sbar(&dgl);
finalcut::FStatusKey key_F1 (finalcut::fc::Fkey_f1, "Info", &sbar);
// Create the menu bar
finalcut::FMenuBar Menubar(&dgl);
// Create menu bar items
finalcut::FMenu File{L"&", &Menubar};
finalcut::FMenuItem Edit{L"&", &Menubar};
finalcut::FMenuItem Exit{L"&", &Menubar};
// Create file menu items
finalcut::FMenuItem Open{"&", &File};
finalcut::FMenuItem Print{"&", &File};
finalcut::FMenuItem Line{&File};
Line.setSeparator();
finalcut::FMenuItem Quit{"&", &File};
Quit.addAccelerator (finalcut::fc::Fckey_q); // Ctrl + Q
// Callback lambda expressions
auto cb_exit = \
[] (finalcut::FWidget*, FDataPtr data)
{
auto a = static_cast<finalcut::FApplication*>(data);
a->quit();
};
auto cb_tooltip = \
[] (finalcut::FWidget*, FDataPtr data)
{
auto a = static_cast<finalcut::FApplication*>(data);
finalcut::FToolTip tooltip(a);
tooltip.setText (full("A tooltip with\ncharacters\n"
"in full-width\nfor 3 seconds"));
tooltip.show();
sleep(3);
};
// Connect the signals with the callback lambda expressions
btn.addCallback ("clicked", cb_exit, &app);
Exit.addCallback ("clicked", cb_exit, &app);
Quit.addCallback ("clicked", cb_exit, &app);
key_F1.addCallback ("activate",cb_tooltip, &app);
// Set dialog object as main widget
app.setMainWidget(&dgl);
// Show and start the application
dgl.show();
return app.exec();
}

View File

@ -1,5 +1,5 @@
/*********************************************************************** /***********************************************************************
* input-dialog.cpp - an input field example * * input-dialog.cpp - An input field example *
* * * *
* This file is part of the Final Cut widget toolkit * * This file is part of the Final Cut widget toolkit *
* * * *

View File

@ -76,7 +76,7 @@ void Mandelbrot::draw()
int xoffset{2}; int xoffset{2};
int yoffset{2}; int yoffset{2};
int current_line{0}; int current_line{0};
int Cols = int(getClientWidth()); int Cols = int(getClientWidth());
int Lines = int(getClientHeight()); int Lines = int(getClientHeight());
double dX = (x_max - x_min) / (Cols - 1); double dX = (x_max - x_min) / (Cols - 1);

View File

@ -457,7 +457,7 @@ void MouseDraw::draw()
//---------------------------------------------------------------------- //----------------------------------------------------------------------
void MouseDraw::drawBrush (int x, int y, bool swap_color) void MouseDraw::drawBrush (int x, int y, bool swap_color)
{ {
int Cols = int(getWidth()); int Cols = int(getWidth());
int Lines = int(getHeight()); int Lines = int(getHeight());
if ( x > 10 && x < Cols && y > 2 && y < Lines ) if ( x > 10 && x < Cols && y > 2 && y < Lines )

View File

@ -108,7 +108,7 @@ void move (int xold, int yold, int xnew, int ynew)
<< " "; << " ";
// get the move string // get the move string
char* buffer = finalcut::FTerm::moveCursorString (xold, yold, xnew, ynew); char* buffer = finalcut::FTerm::moveCursorString (xold, yold, xnew, ynew);
uInt len = uInt(std::strlen(buffer)); uInt len = uInt(std::strlen(buffer));
for (uInt i = 0; i < len; i++) for (uInt i = 0; i < len; i++)
{ {

View File

@ -118,8 +118,8 @@ Scrollview::~Scrollview()
void Scrollview::setScrollSize (const FSize& size) void Scrollview::setScrollSize (const FSize& size)
{ {
FScrollView::setScrollSize (size); FScrollView::setScrollSize (size);
auto width = int(size.getWidth()); int width = int(size.getWidth());
auto height = int(size.getHeight()); int height = int(size.getHeight());
go_south.setPos (FPoint(width - 5, 1)); go_south.setPos (FPoint(width - 5, 1));
go_west.setPos (FPoint(width - 5, height - 1)); go_west.setPos (FPoint(width - 5, height - 1));
go_north.setPos (FPoint(1, height - 1)); go_north.setPos (FPoint(1, height - 1));
@ -141,6 +141,7 @@ void Scrollview::draw()
for (int x{0}; x < int(getScrollWidth()); x++) for (int x{0}; x < int(getScrollWidth()); x++)
print (32 + ((x + y) % 0x5f)); print (32 + ((x + y) % 0x5f));
} }
if ( isMonochron() ) if ( isMonochron() )

View File

@ -643,7 +643,7 @@ void iteratorExample()
{ {
// Test: character access with std::iterator // Test: character access with std::iterator
const finalcut::FString stringIterator{"iterator"}; const finalcut::FString stringIterator{"iterator"};
finalcut::FString::iterator iter; finalcut::FString::const_iterator iter;
iter = stringIterator.begin(); iter = stringIterator.begin();
std::cout << " " << stringIterator << ": "; std::cout << " " << stringIterator << ": ";

View File

@ -1,5 +1,5 @@
/*********************************************************************** /***********************************************************************
* 7segment.cpp - Seven-segment display example * * ui.cpp - Example of a user interface *
* * * *
* This file is part of the Final Cut widget toolkit * * This file is part of the Final Cut widget toolkit *
* * * *
@ -556,6 +556,7 @@ void MyDialog::initWidgets()
// A multiple selection listbox // A multiple selection listbox
myList.setGeometry(FPoint(38, 1), FSize(14, 17)); myList.setGeometry(FPoint(38, 1), FSize(14, 17));
myList.setText ("Items"); myList.setText ("Items");
myList.setStatusbarMessage ("99 items in a list"); myList.setStatusbarMessage ("99 items in a list");
myList.setMultiSelection(); myList.setMultiSelection();
myList.reserve(100); myList.reserve(100);
@ -737,7 +738,7 @@ void MyDialog::adjustSize()
{ {
auto h = getParentWidget()->getHeight() - 4; auto h = getParentWidget()->getHeight() - 4;
setHeight (h, false); setHeight (h, false);
auto X = int((getDesktopWidth() - getWidth()) / 2); int X = int((getDesktopWidth() - getWidth()) / 2);
if ( X < 1 ) if ( X < 1 )
X = 1; X = 1;

View File

@ -342,12 +342,12 @@ void Window::activateWindow (finalcut::FDialog* win)
//---------------------------------------------------------------------- //----------------------------------------------------------------------
void Window::adjustSize() void Window::adjustSize()
{ {
std::size_t w = getDesktopWidth(); std::size_t w = getDesktopWidth();
std::size_t h = getDesktopHeight(); std::size_t h = getDesktopHeight();
int X = int(1 + (w - 40) / 2) int X = int(1 + (w - 40) / 2);
, Y = int(1 + (h - 22) / 2) int Y = int(1 + (h - 22) / 2);
, dx = ( w > 80 ) ? int(w - 80) / 2 : 0 int dx = ( w > 80 ) ? int(w - 80) / 2 : 0;
, dy = ( h > 24 ) ? int(h - 24) / 2 : 0; int dy = ( h > 24 ) ? int(h - 24) / 2 : 0;
if ( Y < 2 ) if ( Y < 2 )
Y = 2; Y = 2;
@ -360,9 +360,9 @@ void Window::adjustSize()
{ {
if ( (*iter)->is_open ) if ( (*iter)->is_open )
{ {
int n = int(std::distance(first, iter)) int n = int(std::distance(first, iter));
, x = dx + 5 + (n % 3) * 25 + int(n / 3) * 3 int x = dx + 5 + (n % 3) * 25 + int(n / 3) * 3;
, y = dy + 11 + int(n / 3) * 3; int y = dy + 11 + int(n / 3) * 3;
(*iter)->dgl->setPos (FPoint(x, y)); (*iter)->dgl->setPos (FPoint(x, y));
} }

View File

@ -45,6 +45,7 @@ libfinal_la_SOURCES = \
fkey_map.cpp \ fkey_map.cpp \
fcharmap.cpp \ fcharmap.cpp \
ftextview.cpp \ ftextview.cpp \
fstartoptions.cpp \
fstatusbar.cpp \ fstatusbar.cpp \
ftermcap.cpp \ ftermcap.cpp \
ftermcapquirks.cpp \ ftermcapquirks.cpp \
@ -114,6 +115,7 @@ finalcutinclude_HEADERS = \
include/final/frect.h \ include/final/frect.h \
include/final/fscrollbar.h \ include/final/fscrollbar.h \
include/final/fscrollview.h \ include/final/fscrollview.h \
include/final/fstartoptions.h \
include/final/fstatusbar.h \ include/final/fstatusbar.h \
include/final/fstring.h \ include/final/fstring.h \
include/final/fsystem.h \ include/final/fsystem.h \

View File

@ -48,6 +48,7 @@ INCLUDE_HEADERS = \
fmouse.h \ fmouse.h \
fkeyboard.h \ fkeyboard.h \
ftermcap.h \ ftermcap.h \
fstartoptions.h \
fterm.h \ fterm.h \
ftermdata.h \ ftermdata.h \
ftermdebugdata.h \ ftermdebugdata.h \
@ -114,6 +115,7 @@ OBJS = \
fsystem.o \ fsystem.o \
fsystemimpl.o \ fsystemimpl.o \
fkeyboard.o \ fkeyboard.o \
fstartoptions.o \
ftermcap.o \ ftermcap.o \
fterm.o \ fterm.o \
ftermdebugdata.o \ ftermdebugdata.o \
@ -159,7 +161,10 @@ all: dep $(OBJS)
$(LIB): all $(LIB): all
debug: debug:
$(MAKE) $(MAKEFILE) DEBUG="-g -D DEBUG -Wall -Wextra -Wpedantic -Weverything -Wno-padded -Wno-c++98-compat -Wno-c++98-compat-pedantic -Wno-implicit-fallthrough -Wno-reserved-id-macro" $(MAKE) $(MAKEFILE) DEBUG="-g -D DEBUG -Wall -Wextra -Wpedantic -Weverything -Wno-padded -Wno-c++98-compat -Wno-c++98-compat-pedantic -Wno-implicit-fallthrough -Wno-reserved-id-macro -Wno-format-nonliteral"
unittest:
$(MAKE) $(MAKEFILE) DEBUG="-g -D DEBUG -DUNIT_TEST -Wall -Wextra -Wpedantic -Weverything -Wno-padded -Wno-c++98-compat -Wno-c++98-compat-pedantic -Wno-implicit-fallthrough -Wno-reserved-id-macro -Wno-format-nonliteral"
profile: profile:
$(MAKE) $(MAKEFILE) PROFILE="-pg" $(MAKE) $(MAKEFILE) PROFILE="-pg"

View File

@ -47,6 +47,7 @@ INCLUDE_HEADERS = \
fsystemimpl.h \ fsystemimpl.h \
fmouse.h \ fmouse.h \
fkeyboard.h \ fkeyboard.h \
fstartoptions.h \
ftermcap.h \ ftermcap.h \
fterm.h \ fterm.h \
ftermdata.h \ ftermdata.h \
@ -115,6 +116,7 @@ OBJS = \
fsystemimpl.o \ fsystemimpl.o \
fkeyboard.o \ fkeyboard.o \
ftermcap.o \ ftermcap.o \
fstartoptions.o \
fterm.o \ fterm.o \
ftermdebugdata.o \ ftermdebugdata.o \
ftermios.o \ ftermios.o \
@ -160,6 +162,9 @@ $(LIB): all
debug: debug:
$(MAKE) $(MAKEFILE) DEBUG="-g -D DEBUG -Wall -Wextra -Wpedantic" $(MAKE) $(MAKEFILE) DEBUG="-g -D DEBUG -Wall -Wextra -Wpedantic"
unittest:
$(MAKE) $(MAKEFILE) DEBUG="-g -D DEBUG -DUNIT_TEST -Wall -Wextra -Wpedantic"
profile: profile:
$(MAKE) $(MAKEFILE) PROFILE="-pg" $(MAKE) $(MAKEFILE) PROFILE="-pg"

View File

@ -489,6 +489,12 @@ void FApplication::cmd_options (const int& argc, char* argv[])
} }
} }
//----------------------------------------------------------------------
inline FStartOptions& FApplication::getStartOptions()
{
return FStartOptions::getFStartOptions();
}
//---------------------------------------------------------------------- //----------------------------------------------------------------------
inline void FApplication::findKeyboardWidget() inline void FApplication::findKeyboardWidget()
{ {

View File

@ -238,7 +238,7 @@ void FButton::hide()
} }
else else
{ {
const FWidgetColors& wc = getFWidgetColors(); const auto& wc = getFWidgetColors();
fg = wc.dialog_fg; fg = wc.dialog_fg;
bg = wc.dialog_bg; bg = wc.dialog_bg;
} }
@ -410,7 +410,7 @@ void FButton::onFocusOut (FFocusEvent*)
//---------------------------------------------------------------------- //----------------------------------------------------------------------
void FButton::init() void FButton::init()
{ {
const FWidgetColors& wc = getFWidgetColors(); const auto& wc = getFWidgetColors();
setForegroundColor (wc.button_active_fg); setForegroundColor (wc.button_active_fg);
setBackgroundColor (wc.button_active_bg); setBackgroundColor (wc.button_active_bg);
setShadow(); setShadow();
@ -424,6 +424,9 @@ void FButton::setHotkeyAccelerator()
{ {
FKey hotkey = getHotkey(text); FKey hotkey = getHotkey(text);
if ( hotkey > 0xff00 && hotkey < 0xff5f ) // full-width character
hotkey -= 0xfee0;
if ( hotkey ) if ( hotkey )
{ {
if ( std::isalpha(int(hotkey)) || std::isdigit(int(hotkey)) ) if ( std::isalpha(int(hotkey)) || std::isdigit(int(hotkey)) )
@ -466,9 +469,9 @@ inline std::size_t FButton::clickAnimationIndent (FWidget* parent_widget)
setColor ( parent_widget->getForegroundColor() setColor ( parent_widget->getForegroundColor()
, parent_widget->getBackgroundColor() ); , parent_widget->getBackgroundColor() );
for (std::size_t y{1}; y <= getHeight(); y++) for (int y{1}; y <= int(getHeight()); y++)
{ {
print() << FPoint(1, int(y)) << ' '; // clear one left █ print() << FPoint(1, y) << ' '; // clear one left █
} }
return 1; return 1;
@ -563,10 +566,10 @@ inline void FButton::drawButtonTextLine (wchar_t button_text[])
print() << FPoint(2 + int(indent), 1 + int(vcenter_offset)) print() << FPoint(2 + int(indent), 1 + int(vcenter_offset))
<< FColorPair (button_fg, button_bg); << FColorPair (button_fg, button_bg);
if ( getWidth() < txtlength + 1 ) if ( getWidth() < column_width + 1 )
center_offset = 0; center_offset = 0;
else else
center_offset = (getWidth() - txtlength - 1) / 2; center_offset = (getWidth() - column_width - 1) / 2;
// Print button text line // Print button text line
for (pos = 0; pos < center_offset; pos++) for (pos = 0; pos < center_offset; pos++)
@ -585,9 +588,9 @@ inline void FButton::drawButtonTextLine (wchar_t button_text[])
if ( active_focus && (isMonochron() || getMaxColor() < 16) ) if ( active_focus && (isMonochron() || getMaxColor() < 16) )
setBold(); setBold();
for ( std::size_t z{0} for ( std::size_t z{0}, columns{0}
; pos < center_offset + txtlength && z + 2 < getWidth() ; pos < center_offset + column_width && columns + 2 < getWidth()
; z++, pos++) ; z++)
{ {
if ( z == hotkeypos && getFlags().active ) if ( z == hotkeypos && getFlags().active )
{ {
@ -613,9 +616,13 @@ inline void FButton::drawButtonTextLine (wchar_t button_text[])
{ {
print (button_text[z]); print (button_text[z]);
} }
auto char_width = getColumnWidth (button_text[z]);
columns += char_width;
pos += char_width;
} }
if ( txtlength + 1 >= getWidth() ) if ( column_width + 1 >= getWidth() )
{ {
// Print ellipsis // Print ellipsis
print() << FPoint(int(getWidth() + indent) - 2, 1) << ".."; print() << FPoint(int(getWidth() + indent) - 2, 1) << "..";
@ -624,7 +631,7 @@ inline void FButton::drawButtonTextLine (wchar_t button_text[])
if ( active_focus && (isMonochron() || getMaxColor() < 16) ) if ( active_focus && (isMonochron() || getMaxColor() < 16) )
unsetBold(); unsetBold();
for (pos = center_offset + txtlength; pos < getWidth() - 2; pos++) for (pos = center_offset + column_width; pos < getWidth() - 2; pos++)
print (space_char); // █ print (space_char); // █
} }
@ -633,7 +640,8 @@ void FButton::draw()
{ {
wchar_t* button_text{}; wchar_t* button_text{};
auto parent_widget = getParentWidget(); auto parent_widget = getParentWidget();
txtlength = text.getLength(); auto txtlength = text.getLength();
column_width = getColumnWidth(text);
space_char = int(' '); space_char = int(' ');
active_focus = getFlags().active && getFlags().focus; active_focus = getFlags().active && getFlags().focus;
@ -668,7 +676,7 @@ void FButton::draw()
hotkeypos = finalcut::getHotkeyPos(text.wc_str(), button_text, uInt(txtlength)); hotkeypos = finalcut::getHotkeyPos(text.wc_str(), button_text, uInt(txtlength));
if ( hotkeypos != NOT_SET ) if ( hotkeypos != NOT_SET )
txtlength--; column_width--;
if ( getHeight() >= 2 ) if ( getHeight() >= 2 )
vcenter_offset = (getHeight() - 1) / 2; vcenter_offset = (getHeight() - 1) / 2;

View File

@ -23,6 +23,7 @@
#include "final/fapplication.h" #include "final/fapplication.h"
#include "final/fbuttongroup.h" #include "final/fbuttongroup.h"
#include "final/fcolorpair.h"
#include "final/fevent.h" #include "final/fevent.h"
#include "final/fsize.h" #include "final/fsize.h"
#include "final/fstatusbar.h" #include "final/fstatusbar.h"
@ -142,17 +143,12 @@ bool FButtonGroup::hasFocusedButton() const
if ( buttonlist.empty() ) if ( buttonlist.empty() )
return false; return false;
auto iter = buttonlist.begin(); for (auto&& item : buttonlist)
auto last = buttonlist.end();
while ( iter != last )
{ {
auto toggle_button = static_cast<FToggleButton*>(*iter); auto toggle_button = static_cast<FToggleButton*>(item);
if ( toggle_button->hasFocus() ) if ( toggle_button->hasFocus() )
return true; return true;
++iter;
} }
return false; return false;
@ -164,17 +160,12 @@ bool FButtonGroup::hasCheckedButton() const
if ( buttonlist.empty() ) if ( buttonlist.empty() )
return false; return false;
auto iter = buttonlist.begin(); for (auto&& item : buttonlist)
auto last = buttonlist.end();
while ( iter != last )
{ {
auto toggle_button = static_cast<FToggleButton*>(*iter); auto toggle_button = static_cast<FToggleButton*>(item);
if ( toggle_button->isChecked() ) if ( toggle_button->isChecked() )
return true; return true;
++iter;
} }
return false; return false;
@ -189,14 +180,10 @@ void FButtonGroup::hide()
if ( ! buttonlist.empty() ) if ( ! buttonlist.empty() )
{ {
auto iter = buttonlist.begin(); for (auto&& item : buttonlist)
auto last = buttonlist.end();
while ( iter != last )
{ {
auto toggle_button = static_cast<FToggleButton*>(*iter); auto toggle_button = static_cast<FToggleButton*>(item);
toggle_button->hide(); toggle_button->hide();
++iter;
} }
} }
@ -207,7 +194,7 @@ void FButtonGroup::hide()
} }
else else
{ {
const FWidgetColors& wc = getFWidgetColors(); const auto& wc = getFWidgetColors();
fg = wc.dialog_fg; fg = wc.dialog_fg;
bg = wc.dialog_bg; bg = wc.dialog_bg;
} }
@ -323,13 +310,11 @@ void FButtonGroup::onFocusIn (FFocusEvent* in_ev)
{ {
if ( hasCheckedButton() && ! buttonlist.empty() ) if ( hasCheckedButton() && ! buttonlist.empty() )
{ {
auto iter = buttonlist.begin();
auto last = buttonlist.end();
in_ev->ignore(); in_ev->ignore();
while ( iter != last ) for (auto&& item : buttonlist)
{ {
auto toggle_button = static_cast<FToggleButton*>(*iter); auto toggle_button = static_cast<FToggleButton*>(item);
if ( toggle_button->isChecked() ) if ( toggle_button->isChecked() )
{ {
@ -356,9 +341,7 @@ void FButtonGroup::onFocusIn (FFocusEvent* in_ev)
break; break;
} }
} // end of range-based for loop
++iter;
}
} }
if ( ! in_ev->isAccepted() ) if ( ! in_ev->isAccepted() )
@ -393,6 +376,9 @@ void FButtonGroup::setHotkeyAccelerator()
{ {
FKey hotkey = getHotkey(text); FKey hotkey = getHotkey(text);
if ( hotkey > 0xff00 && hotkey < 0xff5f ) // full-width character
hotkey -= 0xfee0;
if ( hotkey ) if ( hotkey )
{ {
if ( std::isalpha(int(hotkey)) || std::isdigit(int(hotkey)) ) if ( std::isalpha(int(hotkey)) || std::isdigit(int(hotkey)) )
@ -478,10 +464,10 @@ bool FButtonGroup::isRadioButton (const FToggleButton* button) const
//---------------------------------------------------------------------- //----------------------------------------------------------------------
void FButtonGroup::init() void FButtonGroup::init()
{ {
const FWidgetColors& wc = getFWidgetColors(); const auto& wc = getFWidgetColors();
setForegroundColor (wc.label_fg); setForegroundColor (wc.label_fg);
setBackgroundColor (wc.label_bg); setBackgroundColor (wc.label_bg);
setMinimumSize (FSize(7, 4)); setMinimumSize (FSize(7, 3));
buttonlist.clear(); // no buttons yet buttonlist.clear(); // no buttons yet
} }
@ -490,11 +476,21 @@ void FButtonGroup::drawText ( wchar_t LabelText[]
, std::size_t hotkeypos , std::size_t hotkeypos
, std::size_t length ) , std::size_t length )
{ {
const auto& wc = getFWidgetColors();
std::size_t column_width = getColumnWidth(LabelText);
bool ellipsis{false};
if ( column_width > getClientWidth() )
{
std::size_t len = getClientWidth() - 3;
FString s = finalcut::getColumnSubString (LabelText, 1, len);
length = s.getLength();
ellipsis = true;
}
if ( isMonochron() ) if ( isMonochron() )
setReverse(true); setReverse(true);
const FWidgetColors& wc = getFWidgetColors();
if ( isEnabled() ) if ( isEnabled() )
setColor(wc.label_emphasis_fg, wc.label_bg); setColor(wc.label_emphasis_fg, wc.label_bg);
else else
@ -520,6 +516,9 @@ void FButtonGroup::drawText ( wchar_t LabelText[]
print (LabelText[z]); print (LabelText[z]);
} }
if ( ellipsis ) // Print ellipsis
print() << FColorPair (wc.label_ellipsis_fg, wc.label_bg) << "..";
if ( isMonochron() ) if ( isMonochron() )
setReverse(true); setReverse(true);
} }
@ -533,12 +532,9 @@ void FButtonGroup::directFocus()
if ( hasCheckedButton() && ! buttonlist.empty() ) if ( hasCheckedButton() && ! buttonlist.empty() )
{ {
auto iter = buttonlist.begin(); for (auto&& item : buttonlist)
auto last = buttonlist.end();
while ( iter != last )
{ {
auto toggle_button = static_cast<FToggleButton*>(*iter); auto toggle_button = static_cast<FToggleButton*>(item);
if ( toggle_button->isChecked() ) if ( toggle_button->isChecked() )
{ {
@ -559,9 +555,7 @@ void FButtonGroup::directFocus()
break; break;
} }
} // end of range-based for loop
++iter;
}
} }
if ( ! found_checked ) if ( ! found_checked )
@ -598,12 +592,9 @@ void FButtonGroup::cb_buttonToggled (FWidget* widget, FDataPtr)
if ( buttonlist.empty() ) if ( buttonlist.empty() )
return; return;
auto iter = buttonlist.begin(); for (auto&& item : buttonlist)
auto last = buttonlist.end();
while ( iter != last )
{ {
auto toggle_button = static_cast<FToggleButton*>(*iter); auto toggle_button = static_cast<FToggleButton*>(item);
if ( toggle_button != button if ( toggle_button != button
&& toggle_button->isChecked() && toggle_button->isChecked()
@ -614,8 +605,6 @@ void FButtonGroup::cb_buttonToggled (FWidget* widget, FDataPtr)
if ( toggle_button->isShown() ) if ( toggle_button->isShown() )
toggle_button->redraw(); toggle_button->redraw();
} }
++iter;
} }
} }

View File

@ -50,6 +50,9 @@ uInt character[][fc::NUM_OF_ENCODINGS] =
{0x2193, 'v', 0x19, 'v'}, // ↓ - DownwardsArrow {0x2193, 'v', 0x19, 'v'}, // ↓ - DownwardsArrow
{0x2192, '>', 0x1a, '>'}, // → - RightwardsArrow {0x2192, '>', 0x1a, '>'}, // → - RightwardsArrow
{0x2190, '<', 0x1b, '<'}, // ← - LeftwardsArrow {0x2190, '<', 0x1b, '<'}, // ← - LeftwardsArrow
{0x203a, '>', 0xaf, '>'}, // - SingleRightAngleQuotationMark
{0x2039, '<', 0xae, '<'}, // - SingleLeftAngleQuotationMark
{0x2026, '.', '.', '.'}, // … - HorizontalEllipsis
{0x03c0, '{', 0xe3, 'n'}, // π - Pi {0x03c0, '{', 0xe3, 'n'}, // π - Pi
{0x207F, 'I', 0xfc, ' '}, // ⁿ - SuperscriptLatinSmallLetterN {0x207F, 'I', 0xfc, ' '}, // ⁿ - SuperscriptLatinSmallLetterN
{0x2265, 'z', 0xf2, '>'}, // ≥ - GreaterThanOrEqualTo {0x2265, 'z', 0xf2, '>'}, // ≥ - GreaterThanOrEqualTo
@ -464,6 +467,248 @@ wchar_t cp437_to_ucs[][2] =
const std::size_t lastCP437Item = \ const std::size_t lastCP437Item = \
std::size_t((sizeof(cp437_to_ucs) / sizeof(cp437_to_ucs[0])) - 1); std::size_t((sizeof(cp437_to_ucs) / sizeof(cp437_to_ucs[0])) - 1);
// Based on http://www.unicode.org/charts/PDF/UFF00.pdf
wchar_t halfWidth_fullWidth[][2] =
{
// Fullwidth ASCII variants
{0x0020, 0x3000}, // ' ' -> ' '
{0x0021, 0xff01}, // ! ->
{0x0022, 0xff02}, // " ->
{0x0023, 0xff03}, // # ->
{0x0024, 0xff04}, // $ ->
{0x0025, 0xff05}, // % ->
{0x0026, 0xff06}, // & ->
{0x0027, 0xff07}, // ' ->
{0x0028, 0xff08}, // ( ->
{0x0029, 0xff09}, // ) ->
{0x002a, 0xff0a}, // * ->
{0x002b, 0xff0b}, // + ->
{0x002c, 0xff0c}, // , ->
{0x002d, 0xff0d}, // - ->
{0x002e, 0xff0e}, // . ->
{0x002f, 0xff0f}, // / ->
{0x0030, 0xff10}, // 0 ->
{0x0031, 0xff11}, // 1 ->
{0x0032, 0xff12}, // 2 ->
{0x0033, 0xff13}, // 3 ->
{0x0034, 0xff14}, // 4 ->
{0x0035, 0xff15}, // 5 ->
{0x0036, 0xff16}, // 6 ->
{0x0037, 0xff17}, // 7 ->
{0x0038, 0xff18}, // 8 ->
{0x0039, 0xff19}, // 9 ->
{0x003a, 0xff1a}, // : ->
{0x003b, 0xff1b}, // ; ->
{0x003c, 0xff1c}, // < ->
{0x003d, 0xff1d}, // = ->
{0x003e, 0xff1e}, // > ->
{0x003f, 0xff1f}, // ? ->
{0x0040, 0xff20}, // @ ->
{0x0041, 0xff21}, // A ->
{0x0042, 0xff22}, // B ->
{0x0043, 0xff23}, // C ->
{0x0044, 0xff24}, // D ->
{0x0045, 0xff25}, // E ->
{0x0046, 0xff26}, // F ->
{0x0047, 0xff27}, // G ->
{0x0048, 0xff28}, // H ->
{0x0049, 0xff29}, // I ->
{0x004a, 0xff2a}, // J ->
{0x004b, 0xff2b}, // K ->
{0x004c, 0xff2c}, // L ->
{0x004d, 0xff2d}, // M ->
{0x004e, 0xff2e}, // N ->
{0x004f, 0xff2f}, // O ->
{0x0050, 0xff30}, // P ->
{0x0051, 0xff31}, // Q ->
{0x0052, 0xff32}, // R ->
{0x0053, 0xff33}, // S ->
{0x0054, 0xff34}, // T ->
{0x0055, 0xff35}, // U ->
{0x0056, 0xff36}, // V ->
{0x0057, 0xff37}, // W ->
{0x0058, 0xff38}, // X ->
{0x0059, 0xff39}, // Y ->
{0x005a, 0xff3a}, // Z ->
{0x005b, 0xff3b}, // [ ->
{0x005c, 0xff3c}, // \ ->
{0x005d, 0xff3c}, // ] ->
{0x005e, 0xff3e}, // ^ ->
{0x005f, 0xff3f}, // _ -> _
{0x0060, 0xff40}, // ` ->
{0x0061, 0xff41}, // a ->
{0x0062, 0xff42}, // b ->
{0x0063, 0xff43}, // c ->
{0x0064, 0xff44}, // d ->
{0x0065, 0xff45}, // e ->
{0x0066, 0xff46}, // f ->
{0x0067, 0xff47}, // g ->
{0x0068, 0xff48}, // h ->
{0x0069, 0xff49}, // i ->
{0x006a, 0xff4a}, // j ->
{0x006b, 0xff4b}, // k ->
{0x006c, 0xff4c}, // l ->
{0x006d, 0xff4d}, // m ->
{0x006e, 0xff4e}, // n ->
{0x006f, 0xff4f}, // o ->
{0x0070, 0xff50}, // p ->
{0x0071, 0xff51}, // q ->
{0x0072, 0xff52}, // r ->
{0x0073, 0xff53}, // s ->
{0x0074, 0xff54}, // t ->
{0x0075, 0xff55}, // u ->
{0x0076, 0xff56}, // v ->
{0x0077, 0xff57}, // w ->
{0x0078, 0xff58}, // x ->
{0x0079, 0xff59}, // y ->
{0x007a, 0xff5a}, // z ->
{0x007b, 0xff5b}, // { ->
{0x007c, 0xff5c}, // | ->
{0x007d, 0xff5d}, // } ->
{0x007e, 0xff5e}, // ~ ->
{0x007e, 0x0301}, // ~ -> 〜
// Fullwidth brackets
{0xff5f, 0x2e28}, // ⦅ -> ⸨
{0xff60, 0x2e29}, // ⦆ -> ⸩
// Halfwidth CJK punctuation
{0xff61, 0x3002}, // 。 -> 。
{0xff62, 0x300c}, // 「 -> 「
{0xff63, 0x300d}, // 」 -> 」
{0xff64, 0x3001}, // 、 -> 、
// Halfwidth Katakana variants
{0xff65, 0x30fb}, // ・ -> ・
{0xff66, 0x30f2}, // ヲ -> ヲ
{0xff67, 0x30a1}, // ァ -> ァ
{0xff68, 0x30a3}, // ィ -> ィ
{0xff69, 0x30a5}, // ゥ -> ゥ
{0xff6a, 0x30a7}, // ェ -> ェ
{0xff6b, 0x30a9}, // ォ -> ォ
{0xff6c, 0x30e3}, // ャ -> ャ
{0xff6d, 0x30e5}, // ュ -> ュ
{0xff6e, 0x30e7}, // ョ -> ョ
{0xff6f, 0x30c3}, // ッ -> ッ
{0xff70, 0x30fc}, // ー -> ー
{0xff71, 0x30a2}, // ア -> ア
{0xff72, 0x30a4}, // イ -> イ
{0xff73, 0x30a6}, // ウ -> ウ
{0xff74, 0x30a8}, // エ -> エ
{0xff75, 0x30aa}, // オ -> オ
{0xff76, 0x30ab}, // カ -> カ
{0xff77, 0x30ad}, // キ -> キ
{0xff78, 0x30af}, // ク -> ク
{0xff79, 0x30b1}, // ケ -> ケ
{0xff7a, 0x30b3}, // コ -> コ
{0xff7b, 0x30b5}, // サ -> サ
{0xff7c, 0x30b7}, // シ -> シ
{0xff7d, 0x30b9}, // ス -> ス
{0xff7e, 0x30bb}, // セ -> セ
{0xff7f, 0x30bd}, // ソ -> ソ
{0xff80, 0x30bf}, // タ -> タ
{0xff81, 0x30c1}, // チ -> チ
{0xff82, 0x30c4}, // ツ -> ツ
{0xff83, 0x30c6}, // テ -> テ
{0xff84, 0x30c8}, // ト -> ト
{0xff85, 0x30ca}, // ナ -> ナ
{0xff86, 0x30cb}, // ニ -> ニ
{0xff87, 0x30cc}, // ヌ -> ヌ
{0xff88, 0x30cd}, // ネ -> ネ
{0xff89, 0x30ce}, // ノ ->
{0xff8a, 0x30cf}, // ハ -> ハ
{0xff8b, 0x30d2}, // ヒ -> ヒ
{0xff8c, 0x30d5}, // フ -> フ
{0xff8d, 0x30d8}, // ヘ -> ヘ
{0xff8e, 0x30db}, // ホ -> ホ
{0xff8f, 0x30de}, // マ -> マ
{0xff90, 0x30df}, // ミ -> ミ
{0xff91, 0x30e0}, // ム -> ム
{0xff92, 0x30e1}, // メ -> メ
{0xff93, 0x30e2}, // モ -> モ
{0xff94, 0x30e4}, // ヤ -> ヤ
{0xff95, 0x30e6}, // ユ -> ユ
{0xff96, 0x30e8}, // ヨ -> ヨ
{0xff97, 0x30e9}, // ラ -> ラ
{0xff98, 0x30ea}, // リ -> リ
{0xff99, 0x30eb}, // ル -> ル
{0xff9a, 0x30ec}, // レ -> レ
{0xff9b, 0x30ed}, // ロ -> ロ
{0xff9c, 0x30ef}, // ワ -> ワ
{0xff9d, 0x30f3}, // ン -> ン
{0xff9e, 0x3099}, // ゙ -> ゙
{0xff9f, 0x309a}, // ゚ -> ゚
// Halfwidth Hangul variants
{0xffa0, 0x3164}, // ->
{0xffa1, 0x3131}, // ᄀ -> ㄱ
{0xffa2, 0x3132}, // ᄁ -> ㄲ
{0xffa3, 0x3133}, // ᆪ -> ㄳ
{0xffa4, 0x3134}, // ᄂ -> ㄴ
{0xffa5, 0x3135}, // ᆬ -> ㄵ
{0xffa6, 0x3136}, // ᆭ -> ㄶ
{0xffa7, 0x3137}, // ᄃ -> ㄷ
{0xffa8, 0x3138}, // ᄄ -> ㄸ
{0xffa9, 0x3139}, // ᄅ -> ㄹ
{0xffaa, 0x313a}, // ᆰ -> ㄺ
{0xffab, 0x313b}, // ᆱ -> ㄻ
{0xffac, 0x313c}, // ᆲ -> ㄼ
{0xffad, 0x313d}, // ᆳ -> ㄽ
{0xffae, 0x313e}, // ᆴ -> ㄾ
{0xffaf, 0x313f}, // ᆵ -> ㄿ
{0xffb0, 0x3140}, // ᄚ -> ㅀ
{0xffb1, 0x3141}, // ᄆ -> ㅁ
{0xffb2, 0x3142}, // ᄇ -> ㅂ
{0xffb3, 0x3143}, // ᄈ -> ㅃ
{0xffb4, 0x3144}, // ᄡ -> ㅄ
{0xffb5, 0x3145}, // ᄉ -> ㅅ
{0xffb6, 0x3146}, // ᄊ -> ㅆ
{0xffb7, 0x3147}, // ᄋ -> ㅇ
{0xffb8, 0x3148}, // ᄌ -> ㅈ
{0xffb9, 0x3149}, // ᄍ -> ㅉ
{0xffba, 0x314a}, // ᄎ -> ㅊ
{0xffbb, 0x314b}, // ᄏ -> ㅋ
{0xffbc, 0x314c}, // ᄐ -> ㅌ
{0xffbd, 0x314d}, // ᄑ -> ㅍ
{0xffbe, 0x314e}, // ᄒ -> ㅎ
{0xffc2, 0x314f}, // ᅡ -> ㅏ
{0xffc3, 0x3150}, // ᅢ -> ㅐ
{0xffc4, 0x3151}, // ᅣ -> ㅑ
{0xffc5, 0x3152}, // ᅤ -> ㅒ
{0xffc6, 0x3153}, // ᅥ -> ㅓ
{0xffc7, 0x3154}, // ᅦ -> ㅔ
{0xffca, 0x3155}, // ᅧ -> ㅕ
{0xffcb, 0x3156}, // ᅨ -> ㅖ
{0xffcc, 0x3157}, // ᅩ -> ㅗ
{0xffcd, 0x3158}, // ᅪ -> ㅘ
{0xffce, 0x3159}, // ᅫ -> ㅙ
{0xffcf, 0x315a}, // ᅬ -> ㅚ
{0xffd2, 0x315b}, // ᅭ -> ㅛ
{0xffd3, 0x315c}, // ᅮ -> ㅜ
{0xffd4, 0x315d}, // ᅯ -> ㅝ
{0xffd5, 0x315e}, // ᅰ -> ㅞ
{0xffd6, 0x315f}, // ᅱ -> ㅟ
{0xffd7, 0x3160}, // ᅲ -> ㅠ
{0xffda, 0x3161}, // ᅳ -> ㅡ
{0xffdb, 0x3162}, // ᅴ -> ㅢ
{0xffdc, 0x3163}, // ᅵ -> ㅣ
// Fullwidth symbol variants
{0x00a2, 0xffe0}, // ¢ -> ¢
{0x00a3, 0xffe1}, // £ -> £
{0x00ac, 0xffe2}, // ¬ -> ¬
{0x00af, 0xffe3}, // ¯ ->  ̄
{0x00a6, 0xffe4}, // ¦ -> ¦
{0x00a5, 0xffe5}, // ¥ -> ¥
{0x20a9, 0xffe6}, // ₩ -> ₩
// Halfwidth symbol variants
{0xffe8, 0x2502}, // -> │
{0xffe9, 0x2190}, // ← -> ←
{0xffea, 0x2191}, // ↑ -> ↑
{0xffeb, 0x2192}, // → -> →
{0xffec, 0x2193}, // ↓ -> ↓
{0xffed, 0x25a0}, // ■ -> ■
{0xffee, 0x25cb} // ○ -> ○
};
const std::size_t lastHalfWidthItem = \
std::size_t((sizeof(halfWidth_fullWidth) / sizeof(halfWidth_fullWidth[0])) - 1);
} // namespace fc } // namespace fc
} // namespace finalcut } // namespace finalcut

View File

@ -784,7 +784,7 @@ void FDialog::init()
addDialog(this); addDialog(this);
setActiveWindow(this); setActiveWindow(this);
setTransparentShadow(); setTransparentShadow();
const FWidgetColors& wc = getFWidgetColors(); const auto& wc = getFWidgetColors();
setForegroundColor (wc.dialog_fg); setForegroundColor (wc.dialog_fg);
setBackgroundColor (wc.dialog_bg); setBackgroundColor (wc.dialog_bg);
auto old_focus = FWidget::getFocusWidget(); auto old_focus = FWidget::getFocusWidget();
@ -908,7 +908,7 @@ void FDialog::drawBorder()
if ( (getMoveSizeWidget() == this || ! resize_click_pos.isOrigin() ) if ( (getMoveSizeWidget() == this || ! resize_click_pos.isOrigin() )
&& ! isZoomed() ) && ! isZoomed() )
{ {
const FWidgetColors& wc = getFWidgetColors(); const auto& wc = getFWidgetColors();
setColor (wc.dialog_resize_fg, getBackgroundColor()); setColor (wc.dialog_resize_fg, getBackgroundColor());
} }
else else
@ -971,7 +971,7 @@ void FDialog::drawBarButton()
{ {
// Print the title button // Print the title button
print() << FPoint(1, 1); print() << FPoint(1, 1);
const FWidgetColors& wc = getFWidgetColors(); const auto& wc = getFWidgetColors();
if ( dialog_menu && dialog_menu->isShown() ) if ( dialog_menu && dialog_menu->isShown() )
setColor (wc.titlebar_button_focus_fg, wc.titlebar_button_focus_bg); setColor (wc.titlebar_button_focus_fg, wc.titlebar_button_focus_bg);
@ -1024,7 +1024,7 @@ void FDialog::drawZoomButton()
if ( ! isResizeable() ) if ( ! isResizeable() )
return; return;
const FWidgetColors& wc = getFWidgetColors(); const auto& wc = getFWidgetColors();
if ( zoom_button_pressed ) if ( zoom_button_pressed )
setColor (wc.titlebar_button_focus_fg, wc.titlebar_button_focus_bg); setColor (wc.titlebar_button_focus_fg, wc.titlebar_button_focus_bg);
@ -1093,7 +1093,7 @@ void FDialog::drawTextBar()
// Fill with spaces (left of the title) // Fill with spaces (left of the title)
std::size_t center_offset{0}; std::size_t center_offset{0};
std::size_t x{1}; std::size_t x{1};
const FWidgetColors& wc = getFWidgetColors(); const auto& wc = getFWidgetColors();
if ( getMaxColor() < 16 ) if ( getMaxColor() < 16 )
setBold(); setBold();
@ -1103,9 +1103,9 @@ void FDialog::drawTextBar()
else else
setColor (wc.titlebar_inactive_fg, wc.titlebar_inactive_bg); setColor (wc.titlebar_inactive_fg, wc.titlebar_inactive_bg);
std::size_t width = getWidth(); auto width = getWidth();
std::size_t zoom_btn = getZoomButtonWidth(); auto zoom_btn = getZoomButtonWidth();
std::size_t length = tb_text.getLength(); auto length = getColumnWidth(tb_text);
if ( width > length + MENU_BTN + zoom_btn ) if ( width > length + MENU_BTN + zoom_btn )
center_offset = (width - length - MENU_BTN - zoom_btn) / 2; center_offset = (width - length - MENU_BTN - zoom_btn) / 2;

View File

@ -54,8 +54,8 @@ FDialogListMenu::~FDialogListMenu()
//---------------------------------------------------------------------- //----------------------------------------------------------------------
void FDialogListMenu::init() void FDialogListMenu::init()
{ {
auto menuitem = getItem(); auto m_item = getItem();
menuitem->dialog_index = true; m_item->dialog_index = true;
} }
} // namespace finalcut } // namespace finalcut

View File

@ -701,7 +701,7 @@ int FFileDialog::changeDir (const FString& dirname)
filename.setText('/'); filename.setText('/');
else else
{ {
auto baseName = basename(C_STR(lastdir.c_str())); auto baseName = basename(lastdir.c_str());
selectDirectoryEntry (baseName); selectDirectoryEntry (baseName);
} }
} }
@ -728,10 +728,16 @@ int FFileDialog::changeDir (const FString& dirname)
void FFileDialog::printPath (const FString& txt) void FFileDialog::printPath (const FString& txt)
{ {
const auto& path = txt; const auto& path = txt;
const uInt max_width = uInt(filebrowser.getWidth()) - 4; const std::size_t max_width = filebrowser.getWidth() - 4;
std::size_t column_width = getColumnWidth(path);
if ( path.getLength() > max_width ) if ( column_width > max_width )
filebrowser.setText(".." + path.right(max_width - 2)); {
const std::size_t width = max_width - 2;
std::size_t first = column_width + 1 - width;
FString sub_str(getColumnSubString (path, first, width));
filebrowser.setText(".." + sub_str);
}
else else
filebrowser.setText(path); filebrowser.setText(path);
} }

View File

@ -183,24 +183,6 @@ void FLabel::setAlignment (fc::text_alignment align)
alignment = align; alignment = align;
} }
//----------------------------------------------------------------------
bool FLabel::setEmphasis (bool enable)
{
if ( emphasis != enable )
emphasis = enable;
return enable;
}
//----------------------------------------------------------------------
bool FLabel::setReverseMode (bool enable)
{
if ( reverse_mode != enable )
reverse_mode = enable;
return enable;
}
//---------------------------------------------------------------------- //----------------------------------------------------------------------
bool FLabel::setEnable (bool enable) bool FLabel::setEnable (bool enable)
{ {
@ -342,7 +324,7 @@ void FLabel::init()
} }
else else
{ {
const FWidgetColors& wc = getFWidgetColors(); const auto& wc = getFWidgetColors();
setForegroundColor (wc.dialog_fg); setForegroundColor (wc.dialog_fg);
setBackgroundColor (wc.dialog_bg); setBackgroundColor (wc.dialog_bg);
} }
@ -353,6 +335,9 @@ void FLabel::setHotkeyAccelerator()
{ {
FKey hotkey = getHotkey(text); FKey hotkey = getHotkey(text);
if ( hotkey > 0xff00 && hotkey < 0xff5f ) // full-width character
hotkey -= 0xfee0;
if ( hotkey ) if ( hotkey )
{ {
if ( std::isalpha(int(hotkey)) || std::isdigit(int(hotkey)) ) if ( std::isalpha(int(hotkey)) || std::isdigit(int(hotkey)) )
@ -372,7 +357,7 @@ void FLabel::setHotkeyAccelerator()
//---------------------------------------------------------------------- //----------------------------------------------------------------------
std::size_t FLabel::getAlignOffset (std::size_t length) std::size_t FLabel::getAlignOffset (std::size_t length)
{ {
std::size_t width = std::size_t(getWidth()); std::size_t width(getWidth());
switch ( alignment ) switch ( alignment )
{ {
@ -398,6 +383,9 @@ std::size_t FLabel::getAlignOffset (std::size_t length)
//---------------------------------------------------------------------- //----------------------------------------------------------------------
void FLabel::draw() void FLabel::draw()
{ {
if ( text.isEmpty() )
return;
if ( isMonochron() ) if ( isMonochron() )
{ {
setReverse(true); setReverse(true);
@ -435,10 +423,11 @@ void FLabel::drawMultiLine()
while ( y < text_lines && y < std::size_t(getHeight()) ) while ( y < text_lines && y < std::size_t(getHeight()) )
{ {
wchar_t* label_text; wchar_t* label_text{};
std::size_t hotkeypos{NOT_SET}; std::size_t hotkeypos{NOT_SET};
std::size_t align_offset{}; std::size_t align_offset{};
std::size_t length = multiline_text[y].getLength(); auto length = multiline_text[y].getLength();
auto column_width = getColumnWidth(multiline_text[y]);
try try
{ {
@ -463,13 +452,13 @@ void FLabel::drawMultiLine()
if ( hotkeypos != NOT_SET ) if ( hotkeypos != NOT_SET )
{ {
align_offset = getAlignOffset(length - 1); align_offset = getAlignOffset(length - 1);
printLine (label_text, length - 1, hotkeypos, align_offset); printLine (label_text, length - 1, column_width, hotkeypos, align_offset);
hotkey_printed = true; hotkey_printed = true;
} }
else else
{ {
align_offset = getAlignOffset(length); align_offset = getAlignOffset(length);
printLine (label_text, length, NOT_SET, align_offset); printLine (label_text, length, column_width, NOT_SET, align_offset);
} }
y++; y++;
@ -480,9 +469,10 @@ void FLabel::drawMultiLine()
//---------------------------------------------------------------------- //----------------------------------------------------------------------
void FLabel::drawSingleLine() void FLabel::drawSingleLine()
{ {
wchar_t* label_text; wchar_t* label_text{};
std::size_t hotkeypos{NOT_SET}; std::size_t hotkeypos{NOT_SET};
std::size_t length = text.getLength(); auto length = text.getLength();
auto column_width = getColumnWidth(text);
try try
{ {
@ -497,37 +487,48 @@ void FLabel::drawSingleLine()
hotkeypos = finalcut::getHotkeyPos (text.wc_str(), label_text, length); hotkeypos = finalcut::getHotkeyPos (text.wc_str(), label_text, length);
if ( hotkeypos != NOT_SET ) if ( hotkeypos != NOT_SET )
{
length--; length--;
column_width--;
}
print() << FPoint(1, 1); print() << FPoint(1, 1);
std::size_t align_offset = getAlignOffset(length); auto align_offset = getAlignOffset(column_width);
printLine (label_text, length, hotkeypos, align_offset); printLine (label_text, length, column_width, hotkeypos, align_offset);
delete[] label_text; delete[] label_text;
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
void FLabel::printLine ( wchar_t line[] void FLabel::printLine ( wchar_t line[]
, std::size_t length , std::size_t length
, std::size_t column_width
, std::size_t hotkeypos , std::size_t hotkeypos
, std::size_t align_offset ) , std::size_t align_offset )
{ {
std::size_t to_char{}; std::size_t to_char{};
std::size_t width = std::size_t(getWidth()); std::size_t to_column{};
std::size_t width(getWidth());
if ( align_offset > 0 ) if ( align_offset > 0 )
print (FString(align_offset, ' ')); // leading spaces print (FString(align_offset, ' ')); // leading spaces
if ( length <= width ) if ( column_width <= width )
{
to_char = length; to_char = length;
to_column = column_width;
}
else else
to_char = width - 2; {
to_column = width - 2;
to_char = getColumnWidthToLength(line, to_column);
}
if ( hasReverseMode() ) if ( hasReverseMode() )
setReverse(true); setReverse(true);
for (std::size_t z{0}; z < to_char; z++) for (std::size_t z{0}; z < to_char; z++)
{ {
if ( ! std::iswprint(wint_t(line[z])) ) if ( ! std::iswprint(std::wint_t(line[z])) )
{ {
if ( ! isNewFont() && ( int(line[z]) < fc::NF_rev_left_arrow2 if ( ! isNewFont() && ( int(line[z]) < fc::NF_rev_left_arrow2
|| int(line[z]) > fc::NF_check_mark ) ) || int(line[z]) > fc::NF_check_mark ) )
@ -538,7 +539,7 @@ void FLabel::printLine ( wchar_t line[]
if ( z == hotkeypos && getFlags().active ) if ( z == hotkeypos && getFlags().active )
{ {
const FWidgetColors& wc = getFWidgetColors(); const auto& wc = getFWidgetColors();
setColor (wc.label_hotkey_fg, wc.label_hotkey_bg); setColor (wc.label_hotkey_fg, wc.label_hotkey_bg);
if ( ! getFlags().no_underline ) if ( ! getFlags().no_underline )
@ -558,16 +559,16 @@ void FLabel::printLine ( wchar_t line[]
print (line[z]); print (line[z]);
} }
if ( length > width ) if ( column_width > width )
{ {
// Print ellipsis // Print ellipsis
print() << FColorPair(ellipsis_color, getBackgroundColor()) << ".."; print() << FColorPair(ellipsis_color, getBackgroundColor()) << "..";
setColor(); setColor();
} }
else if ( align_offset + to_char < width ) else if ( align_offset + to_column < width )
{ {
// Print trailing spaces // Print trailing spaces
std::size_t len = width - align_offset - to_char; std::size_t len = width - align_offset - to_column;
print (FString(len, ' ')); print (FString(len, ' '));
} }

View File

@ -168,7 +168,7 @@ const FLineEdit& FLineEdit::operator >> (FString& s)
//---------------------------------------------------------------------- //----------------------------------------------------------------------
bool FLineEdit::setEnable (bool enable) bool FLineEdit::setEnable (bool enable)
{ {
const FWidgetColors& wc = getFWidgetColors(); const auto& wc = getFWidgetColors();
FWidget::setEnable(enable); FWidget::setEnable(enable);
if ( enable ) if ( enable )
@ -196,7 +196,7 @@ bool FLineEdit::setEnable (bool enable)
//---------------------------------------------------------------------- //----------------------------------------------------------------------
bool FLineEdit::setFocus (bool enable) bool FLineEdit::setFocus (bool enable)
{ {
const FWidgetColors& wc = getFWidgetColors(); const auto& wc = getFWidgetColors();
FWidget::setFocus(enable); FWidget::setFocus(enable);
if ( enable ) if ( enable )
@ -263,7 +263,11 @@ void FLineEdit::setText (const FString& txt)
else else
text.setString(""); text.setString("");
keyEnd(); if ( isShown() )
{
cursorEnd();
adjustTextOffset();
}
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
@ -274,20 +278,26 @@ void FLineEdit::setMaxLength (std::size_t max)
if ( text.getLength() > max_length ) if ( text.getLength() > max_length )
text.setString(text.left(max_length)); text.setString(text.left(max_length));
keyEnd(); if ( isShown() )
{
cursorEnd();
adjustTextOffset();
}
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
void FLineEdit::setCursorPosition (std::size_t pos) void FLineEdit::setCursorPosition (std::size_t pos)
{ {
cursor_pos = pos; if ( pos == 0 )
cursor_pos = 1;
else
cursor_pos = pos - 1;
if ( cursor_pos > text.getLength() ) if ( cursor_pos > text.getLength() )
keyEnd(); cursor_pos = text.getLength();
else if ( cursor_pos + 1 >= getWidth() )
text_offset = text.getLength() - getWidth() + 2; if ( isShown() )
else adjustTextOffset();
text_offset = 0;
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
@ -310,8 +320,11 @@ void FLineEdit::setGeometry ( const FPoint& pos, const FSize& size
, bool adjust ) , bool adjust )
{ {
FWidget::setGeometry(pos, size, adjust); FWidget::setGeometry(pos, size, adjust);
keyEnd();
if ( isShown() )
adjustTextOffset();
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
void FLineEdit::hide() void FLineEdit::hide()
{ {
@ -326,8 +339,9 @@ void FLineEdit::hide()
//---------------------------------------------------------------------- //----------------------------------------------------------------------
void FLineEdit::clear() void FLineEdit::clear()
{ {
text_offset = 0;
cursor_pos = 0; cursor_pos = 0;
text_offset = 0;
char_width_offset = 0;
text.clear(); text.clear();
} }
@ -339,44 +353,44 @@ void FLineEdit::onKeyPress (FKeyEvent* ev)
switch ( key ) switch ( key )
{ {
case fc::Fkey_left: case fc::Fkey_left:
keyLeft(); cursorLeft();
ev->accept(); ev->accept();
break; break;
case fc::Fkey_right: case fc::Fkey_right:
keyRight(); cursorRight();
ev->accept(); ev->accept();
break; break;
case fc::Fkey_home: case fc::Fkey_home:
keyHome(); cursorHome();
ev->accept(); ev->accept();
break; break;
case fc::Fkey_end: case fc::Fkey_end:
keyEnd(); cursorEnd();
ev->accept(); ev->accept();
break; break;
case fc::Fkey_dc: // del key case fc::Fkey_dc: // del key
keyDel(); deleteCurrentCharacter();
ev->accept(); ev->accept();
break; break;
case fc::Fkey_erase: case fc::Fkey_erase:
case fc::Fkey_backspace: case fc::Fkey_backspace:
keyBackspace(); deletePreviousCharacter();
ev->accept(); ev->accept();
break; break;
case fc::Fkey_ic: // insert key case fc::Fkey_ic: // insert key
keyInsert(); switchInsertMode();
ev->accept(); ev->accept();
break; break;
case fc::Fkey_return: case fc::Fkey_return:
case fc::Fkey_enter: case fc::Fkey_enter:
keyEnter(); acceptInput();
ev->accept(); ev->accept();
break; break;
@ -421,15 +435,19 @@ void FLineEdit::onMouseDown (FMouseEvent* ev)
int mouse_x = ev->getX(); int mouse_x = ev->getX();
int mouse_y = ev->getY(); int mouse_y = ev->getY();
int xmin = 2 + int(char_width_offset);
if ( mouse_x >= 2 && mouse_x <= int(getWidth()) && mouse_y == 1 ) if ( mouse_x >= xmin && mouse_x <= int(getWidth()) && mouse_y == 1 )
{ {
std::size_t len = text.getLength(); std::size_t len = text.getLength();
cursor_pos = text_offset + std::size_t(mouse_x) - 2; cursor_pos = clickPosToCursorPos (std::size_t(mouse_x) - 2);
if ( cursor_pos >= len ) if ( cursor_pos >= len )
cursor_pos = len; cursor_pos = len;
if ( mouse_x == int(getWidth()) )
adjustTextOffset();
drawInputField(); drawInputField();
updateTerminal(); updateTerminal();
} }
@ -458,11 +476,12 @@ void FLineEdit::onMouseMove (FMouseEvent* ev)
if ( mouse_x >= 2 && mouse_x <= int(getWidth()) && mouse_y == 1 ) if ( mouse_x >= 2 && mouse_x <= int(getWidth()) && mouse_y == 1 )
{ {
cursor_pos = text_offset + std::size_t(mouse_x) - 2; cursor_pos = clickPosToCursorPos (std::size_t(mouse_x) - 2);
if ( cursor_pos >= len ) if ( cursor_pos >= len )
cursor_pos = len; cursor_pos = len;
adjustTextOffset();
drawInputField(); drawInputField();
updateTerminal(); updateTerminal();
} }
@ -487,14 +506,14 @@ void FLineEdit::onMouseMove (FMouseEvent* ev)
else if ( mouse_x >= int(getWidth()) ) else if ( mouse_x >= int(getWidth()) )
{ {
// drag right // drag right
if ( ! scroll_timer && text_offset <= len - getWidth() + 1 ) if ( ! scroll_timer && cursor_pos < len )
{ {
scroll_timer = true; scroll_timer = true;
addTimer(scroll_repeat); addTimer(scroll_repeat);
drag_scroll = FLineEdit::scrollRight; drag_scroll = FLineEdit::scrollRight;
} }
if ( text_offset == len - getWidth() + 2 ) if ( cursor_pos == len )
{ {
delOwnTimer(); delOwnTimer();
drag_scroll = FLineEdit::noScroll; drag_scroll = FLineEdit::noScroll;
@ -512,7 +531,7 @@ void FLineEdit::onMouseMove (FMouseEvent* ev)
//---------------------------------------------------------------------- //----------------------------------------------------------------------
void FLineEdit::onTimer (FTimerEvent*) void FLineEdit::onTimer (FTimerEvent*)
{ {
std::size_t len = text.getLength(); auto len = text.getLength();
switch ( int(drag_scroll) ) switch ( int(drag_scroll) )
{ {
@ -534,14 +553,13 @@ void FLineEdit::onTimer (FTimerEvent*)
break; break;
case FLineEdit::scrollRight: case FLineEdit::scrollRight:
if ( len + 2 < getWidth() if ( text_offset == endPosToOffset(len).first )
|| text_offset == len - getWidth() + 2 )
{ {
drag_scroll = FLineEdit::noScroll; drag_scroll = FLineEdit::noScroll;
return; return;
} }
if ( text_offset <= len - getWidth() + 1 ) if ( text_offset < endPosToOffset(len).first )
text_offset++; text_offset++;
if ( cursor_pos < len ) if ( cursor_pos < len )
@ -553,6 +571,7 @@ void FLineEdit::onTimer (FTimerEvent*)
break; break;
} }
adjustTextOffset();
drawInputField(); drawInputField();
updateTerminal(); updateTerminal();
} }
@ -626,10 +645,10 @@ void FLineEdit::onFocusOut (FFocusEvent*)
//---------------------------------------------------------------------- //----------------------------------------------------------------------
void FLineEdit::adjustLabel() void FLineEdit::adjustLabel()
{ {
std::size_t label_length = label_text.getLength(); auto label_width = getColumnWidth(label_text);
if ( hasHotkey() ) if ( hasHotkey() )
label_length--; label_width--;
assert ( label_orientation == label_above assert ( label_orientation == label_above
|| label_orientation == label_left ); || label_orientation == label_left );
@ -638,12 +657,12 @@ void FLineEdit::adjustLabel()
{ {
case label_above: case label_above:
label->setGeometry ( FPoint(getX(), getY() - 1) label->setGeometry ( FPoint(getX(), getY() - 1)
, FSize(label_length, 1) ); , FSize(label_width, 1) );
break; break;
case label_left: case label_left:
label->setGeometry ( FPoint(getX() - int(label_length) - 1, getY()) label->setGeometry ( FPoint(getX() - int(label_width) - 1, getY())
, FSize(label_length, 1) ); , FSize(label_width, 1) );
break; break;
} }
} }
@ -653,6 +672,9 @@ void FLineEdit::adjustSize()
{ {
FWidget::adjustSize(); FWidget::adjustSize();
adjustLabel(); adjustLabel();
if ( isShown() )
adjustTextOffset();
} }
@ -660,7 +682,7 @@ void FLineEdit::adjustSize()
//---------------------------------------------------------------------- //----------------------------------------------------------------------
void FLineEdit::init() void FLineEdit::init()
{ {
const FWidgetColors& wc = getFWidgetColors(); const auto& wc = getFWidgetColors();
label->setAccelWidget(this); label->setAccelWidget(this);
setVisibleCursor(); setVisibleCursor();
setShadow(); setShadow();
@ -697,6 +719,12 @@ bool FLineEdit::hasHotkey()
//---------------------------------------------------------------------- //----------------------------------------------------------------------
void FLineEdit::draw() void FLineEdit::draw()
{ {
if ( cursor_pos == NOT_SET )
cursorEnd();
if ( ! isShown() )
adjustTextOffset();
drawInputField(); drawInputField();
if ( getFlags().focus && getStatusBar() ) if ( getFlags().focus && getStatusBar() )
@ -737,12 +765,15 @@ void FLineEdit::drawInputField()
if ( isActiveFocus && getMaxColor() < 16 ) if ( isActiveFocus && getMaxColor() < 16 )
setBold(); setBold();
FString show_text(text.mid(1 + text_offset, getWidth() - 2)); auto text_offset_column = getColumnWidth (text, text_offset);
std::size_t start_column = text_offset_column - char_width_offset + 1;
const FString& show_text = \
getColumnSubString(text, start_column, getWidth() - 2);
if ( show_text ) if ( show_text )
print (show_text); print (show_text);
std::size_t x = show_text.getLength(); std::size_t x = getColumnWidth(show_text);
while ( x + 1 < getWidth() ) while ( x + 1 < getWidth() )
{ {
@ -762,56 +793,174 @@ void FLineEdit::drawInputField()
if ( getFlags().shadow ) if ( getFlags().shadow )
drawShadow (); drawShadow ();
// set the cursor to the first pos. // set the cursor to the insert pos.
setCursorPos (FPoint(int(2 + cursor_pos - text_offset), 1)); auto cursor_pos_column = getColumnWidth (text, cursor_pos);
int xpos = int(2 + cursor_pos_column
- text_offset_column
+ char_width_offset);
setCursorPos (FPoint(xpos, 1));
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
inline void FLineEdit::keyLeft() inline FLineEdit::offsetPair FLineEdit::endPosToOffset (std::size_t pos)
{
std::size_t input_width = getWidth() - 2;
std::size_t fullwidth_char_offset{0};
std::size_t len = text.getLength();
if ( pos >= len )
pos = len - 1;
while ( pos > 0 && input_width > 0 )
{
std::size_t char_width = getColumnWidth(text[pos]);
if ( input_width >= char_width )
input_width -= char_width;
if ( input_width == 0 )
break;
if ( input_width == 1)
{
if ( char_width == 1 )
{
if ( pos > 0 && getColumnWidth(text[pos - 1]) == 2 )
{
fullwidth_char_offset = 1;
break;
}
}
if ( char_width == 2 )
{
fullwidth_char_offset = 1;
break;
}
}
pos--;
}
return offsetPair(pos, fullwidth_char_offset);
}
//----------------------------------------------------------------------
std::size_t FLineEdit::clickPosToCursorPos (std::size_t pos)
{
std::size_t click_width{0};
std::size_t idx = text_offset;
std::size_t len = text.getLength();
pos -= char_width_offset;
while ( click_width < pos && idx < len )
{
std::size_t char_width = getColumnWidth(text[idx]);
idx++;
click_width += char_width;
if ( char_width == 2 && click_width == pos + 1)
idx--;
}
return idx;
}
//----------------------------------------------------------------------
void FLineEdit::adjustTextOffset()
{
std::size_t input_width = getWidth() - 2;
std::size_t len = text.getLength();
std::size_t len_column = getColumnWidth (text);
std::size_t text_offset_column = getColumnWidth (text, text_offset);
std::size_t cursor_pos_column = getColumnWidth (text, cursor_pos);
std::size_t first_char_width{0};
std::size_t cursor_char_width{1};
char_width_offset = 0;
if ( cursor_pos < len )
cursor_char_width = getColumnWidth(text[cursor_pos]);
if ( len > 0 )
first_char_width = getColumnWidth(text[0]);
// Text alignment right for long lines
while ( text_offset > 0 && len_column - text_offset_column < input_width )
{
text_offset--;
text_offset_column = getColumnWidth (text, text_offset);
}
// Right cursor overflow
if ( cursor_pos_column + 1 > text_offset_column + input_width )
{
offsetPair offset_pair = endPosToOffset(cursor_pos);
text_offset = offset_pair.first;
char_width_offset = offset_pair.second;
text_offset_column = getColumnWidth (text, text_offset);
}
// Right full-width cursor overflow
if ( cursor_pos_column + 2 > text_offset_column + input_width
&& cursor_char_width == 2 )
{
text_offset++;
if ( first_char_width == 2 )
char_width_offset = 1; // Deletes a half character at the beginning
}
// Left cursor underflow
if ( text_offset > cursor_pos )
text_offset = cursor_pos;
}
//----------------------------------------------------------------------
inline void FLineEdit::cursorLeft()
{ {
if ( cursor_pos > 0 ) if ( cursor_pos > 0 )
cursor_pos--; cursor_pos--;
if ( cursor_pos < text_offset ) adjustTextOffset();
text_offset--;
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
inline void FLineEdit::keyRight() inline void FLineEdit::cursorRight()
{ {
std::size_t len = text.getLength(); auto len = text.getLength();
if ( cursor_pos < len ) if ( cursor_pos < len )
cursor_pos++; cursor_pos++;
if ( cursor_pos - text_offset + 2 >= getWidth() adjustTextOffset();
&& text_offset <= len - getWidth() + 1 )
text_offset++;
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
inline void FLineEdit::keyHome() inline void FLineEdit::cursorHome()
{ {
cursor_pos = 0; cursor_pos = 0;
text_offset = 0; text_offset = 0;
char_width_offset = 0;
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
inline void FLineEdit::keyEnd() inline void FLineEdit::cursorEnd()
{ {
std::size_t len = text.getLength(); auto len = text.getLength();
if ( cursor_pos == len )
return;
cursor_pos = len; cursor_pos = len;
adjustTextOffset();
if ( cursor_pos + 1 >= getWidth() )
text_offset = len - getWidth() + 2;
else
text_offset = 0;
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
inline void FLineEdit::keyDel() inline void FLineEdit::deleteCurrentCharacter()
{ {
std::size_t len = text.getLength(); // Delete key functionality
auto len = text.getLength();
if ( len > 0 && cursor_pos < len ) if ( len > 0 && cursor_pos < len )
{ {
@ -822,38 +971,34 @@ inline void FLineEdit::keyDel()
if ( cursor_pos >= len ) if ( cursor_pos >= len )
cursor_pos = len; cursor_pos = len;
if ( text_offset > 0 && len - text_offset + 1 < getWidth() ) adjustTextOffset();
text_offset--;
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
inline void FLineEdit::keyBackspace() inline void FLineEdit::deletePreviousCharacter()
{ {
if ( text.getLength() > 0 && cursor_pos > 0 ) // Backspace functionality
{
text.remove(cursor_pos - 1, 1);
cursor_pos--;
if ( text_offset > 0 ) if ( text.getLength() == 0 || cursor_pos == 0 )
text_offset--; return;
processChanged(); cursorLeft();
} deleteCurrentCharacter();
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
inline void FLineEdit::keyInsert() inline void FLineEdit::switchInsertMode()
{ {
insert_mode = ! insert_mode; insert_mode = ! insert_mode;
if ( insert_mode ) if ( insert_mode )
setInsertCursor(); setInsertCursor(); // Insert mode
else else
unsetInsertCursor(); unsetInsertCursor(); // Overtype mode
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
inline void FLineEdit::keyEnter() inline void FLineEdit::acceptInput()
{ {
processActivate(); processActivate();
} }
@ -869,28 +1014,28 @@ inline bool FLineEdit::keyInput (FKey key)
if ( key >= 0x20 && key <= 0x10fff ) if ( key >= 0x20 && key <= 0x10fff )
{ {
std::size_t len = text.getLength(); auto len = text.getLength();
wchar_t c = characterFilter(wchar_t(key)); auto ch = characterFilter(wchar_t(key));
if ( c == L'\0' ) if ( ch == L'\0' )
return false; return false;
else if ( cursor_pos == len ) else if ( cursor_pos == len )
text += c; text += ch;
else if ( len > 0 ) else if ( len > 0 )
{ {
if ( insert_mode ) if ( insert_mode )
text.insert(c, cursor_pos); {
text.insert(ch, cursor_pos);
len++;
}
else else
text.overwrite(c, cursor_pos); text.overwrite(ch, cursor_pos);
} }
else else
text.setString(c); text.setString(ch);
cursor_pos++; cursor_pos++;
adjustTextOffset();
if ( cursor_pos + 1 >= getWidth() )
text_offset++;
processChanged(); processChanged();
return true; return true;
} }

View File

@ -140,13 +140,13 @@ void FListBox::showInsideBrackets ( std::size_t index
if ( b == fc::NoBrackets ) if ( b == fc::NoBrackets )
return; return;
std::size_t len = iter->getText().getLength() + 2; std::size_t column_width = getColumnWidth(iter->getText()) + 2;
if ( len > max_line_width ) if ( column_width > max_line_width )
{ {
max_line_width = len; max_line_width = column_width;
if ( len >= getWidth() - nf_offset - 3 ) if ( column_width >= getWidth() - nf_offset - 3 )
{ {
int hmax = ( max_line_width > getWidth() - nf_offset - 4 ) int hmax = ( max_line_width > getWidth() - nf_offset - 4 )
? int(max_line_width - getWidth() + nf_offset + 4) ? int(max_line_width - getWidth() + nf_offset + 4)
@ -222,9 +222,9 @@ void FListBox::hide()
//---------------------------------------------------------------------- //----------------------------------------------------------------------
void FListBox::insert (FListBoxItem listItem) void FListBox::insert (FListBoxItem listItem)
{ {
std::size_t len = listItem.text.getLength(); std::size_t column_width = getColumnWidth(listItem.text);
bool has_brackets = bool(listItem.brackets); bool has_brackets(listItem.brackets);
recalculateHorizontalBar (len, has_brackets); recalculateHorizontalBar (column_width, has_brackets);
itemlist.push_back (listItem); itemlist.push_back (listItem);
@ -244,10 +244,10 @@ void FListBox::remove (std::size_t item)
for (auto&& listbox_item : itemlist) for (auto&& listbox_item : itemlist)
{ {
std::size_t len = listbox_item.getText().getLength(); std::size_t column_width = getColumnWidth(listbox_item.getText());
if ( len > max_line_width ) if ( column_width > max_line_width )
max_line_width = len; max_line_width = column_width;
} }
int hmax = ( max_line_width > getWidth() - nf_offset - 4 ) int hmax = ( max_line_width > getWidth() - nf_offset - 4 )
@ -284,7 +284,6 @@ void FListBox::remove (std::size_t item)
//---------------------------------------------------------------------- //----------------------------------------------------------------------
void FListBox::clear() void FListBox::clear()
{ {
std::size_t size;
itemlist.clear(); itemlist.clear();
itemlist.shrink_to_fit(); itemlist.shrink_to_fit();
current = 0; current = 0;
@ -303,9 +302,9 @@ void FListBox::clear()
hbar->hide(); hbar->hide();
// clear list from screen // clear list from screen
const FWidgetColors& wc = getFWidgetColors(); const auto& wc = getFWidgetColors();
setColor (wc.list_fg, wc.list_bg); setColor (wc.list_fg, wc.list_bg);
size = getWidth() - 2; std::size_t size = getWidth() - 2;
if ( size == 0 ) if ( size == 0 )
return; return;
@ -335,69 +334,69 @@ void FListBox::onKeyPress (FKeyEvent* ev)
{ {
case fc::Fkey_return: case fc::Fkey_return:
case fc::Fkey_enter: case fc::Fkey_enter:
keyEnter(); acceptSelection();
ev->accept(); ev->accept();
break; break;
case fc::Fkey_up: case fc::Fkey_up:
keyUp(); onePosUp();
ev->accept(); ev->accept();
break; break;
case fc::Fkey_down: case fc::Fkey_down:
keyDown(); onePosDown();
ev->accept(); ev->accept();
break; break;
case fc::Fkey_left: case fc::Fkey_left:
keyLeft(); scrollLeft();
ev->accept(); ev->accept();
break; break;
case fc::Fkey_right: case fc::Fkey_right:
keyRight(); scrollRight();
ev->accept(); ev->accept();
break; break;
case fc::Fkey_ppage: case fc::Fkey_ppage:
keyPgUp(); onePageUp();
ev->accept(); ev->accept();
break; break;
case fc::Fkey_npage: case fc::Fkey_npage:
keyPgDn(); onePageDown();
ev->accept(); ev->accept();
break; break;
case fc::Fkey_home: case fc::Fkey_home:
keyHome(); firstPos();
ev->accept(); ev->accept();
break; break;
case fc::Fkey_end: case fc::Fkey_end:
keyEnd(); lastPos();
ev->accept(); ev->accept();
break; break;
case fc::Fkey_ic: // insert key case fc::Fkey_ic: // insert key
if ( keyInsert() ) if ( changeSelectionAndPosition() )
ev->accept(); ev->accept();
break; break;
case fc::Fkey_space: case fc::Fkey_space:
if ( keySpace() ) if ( spacebarProcessing() )
ev->accept(); ev->accept();
break; break;
case fc::Fkey_erase: case fc::Fkey_erase:
case fc::Fkey_backspace: case fc::Fkey_backspace:
if ( keyBackspace() ) if ( deletePreviousCharacter() )
ev->accept(); ev->accept();
break; break;
case fc::Fkey_escape: case fc::Fkey_escape:
case fc::Fkey_escape_mintty: case fc::Fkey_escape_mintty:
if ( keyEsc() ) if ( skipIncrementalSearch() )
ev->accept(); ev->accept();
break; break;
@ -416,8 +415,8 @@ void FListBox::onKeyPress (FKeyEvent* ev)
if ( ev->isAccepted() ) if ( ev->isAccepted() )
{ {
bool draw_vbar = yoffset_before != yoffset; bool draw_vbar( yoffset_before != yoffset );
bool draw_hbar = xoffset_before != xoffset; bool draw_hbar( xoffset_before != xoffset );
updateDrawing (draw_vbar, draw_hbar); updateDrawing (draw_vbar, draw_hbar);
} }
} }
@ -758,7 +757,7 @@ void FListBox::init()
initScrollbar (vbar, fc::vertical, &FListBox::cb_VBarChange); initScrollbar (vbar, fc::vertical, &FListBox::cb_VBarChange);
initScrollbar (hbar, fc::horizontal, &FListBox::cb_HBarChange); initScrollbar (hbar, fc::horizontal, &FListBox::cb_HBarChange);
setGeometry (FPoint(1, 1), FSize(5, 4), false); // initialize geometry values setGeometry (FPoint(1, 1), FSize(5, 4), false); // initialize geometry values
const FWidgetColors& wc = getFWidgetColors(); const auto& wc = getFWidgetColors();
setForegroundColor (wc.dialog_fg); setForegroundColor (wc.dialog_fg);
setBackgroundColor (wc.dialog_bg); setBackgroundColor (wc.dialog_bg);
nf_offset = isNewFont() ? 1 : 0; nf_offset = isNewFont() ? 1 : 0;
@ -874,21 +873,21 @@ void FListBox::drawHeadline()
return; return;
FString txt(" " + text + " "); FString txt(" " + text + " ");
std::size_t length = txt.getLength(); auto column_width = getColumnWidth(txt);
print() << FPoint(2, 1); print() << FPoint(2, 1);
const FWidgetColors& wc = getFWidgetColors(); const auto& wc = getFWidgetColors();
if ( isEnabled() ) if ( isEnabled() )
setColor(wc.label_emphasis_fg, wc.label_bg); setColor(wc.label_emphasis_fg, wc.label_bg);
else else
setColor(wc.label_inactive_fg, wc.label_inactive_bg); setColor(wc.label_inactive_fg, wc.label_inactive_bg);
if ( length <= uInt(getClientWidth()) ) if ( column_width <= getClientWidth() )
print (txt); print (txt);
else else
{ {
// Print ellipsis // Print ellipsis
print() << text.left(uInt(getClientWidth() - 2)) print() << getColumnSubString (text, 1, getClientWidth() - 2)
<< FColorPair (wc.label_ellipsis_fg, wc.label_bg) << ".."; << FColorPair (wc.label_ellipsis_fg, wc.label_bg) << "..";
} }
} }
@ -900,7 +899,7 @@ void FListBox::drawList()
return; return;
std::size_t start{}; std::size_t start{};
std::size_t num = uInt(getHeight() - 2); std::size_t num(getHeight() - 2);
if ( num > getCount() ) if ( num > getCount() )
num = getCount(); num = getCount();
@ -954,12 +953,12 @@ inline void FListBox::drawListLine ( int y
, bool serach_mark ) , bool serach_mark )
{ {
std::size_t inc_len = inc_search.getLength(); std::size_t inc_len = inc_search.getLength();
const FWidgetColors& wc = getFWidgetColors(); const auto& wc = getFWidgetColors();
bool isCurrentLine = bool(y + yoffset + 1 == int(current)); bool isCurrentLine( y + yoffset + 1 == int(current) );
FString element (getString(iter).mid ( std::size_t(xoffset) + 1 std::size_t first = std::size_t(xoffset) + 1;
, getWidth() - nf_offset - 4 )); std::size_t max_width = getWidth() - nf_offset - 4;
const wchar_t* const& element_str = element.wc_str(); FString element(getColumnSubString (getString(iter), first, max_width));
std::size_t len = element.getLength(); std::size_t column_width = getColumnWidth(element);
if ( isMonochron() && isCurrentLine && getFlags().focus ) if ( isMonochron() && isCurrentLine && getFlags().focus )
print (fc::BlackRightPointingPointer); // ► print (fc::BlackRightPointingPointer); // ►
@ -970,24 +969,22 @@ inline void FListBox::drawListLine ( int y
setColor ( wc.current_inc_search_element_fg setColor ( wc.current_inc_search_element_fg
, wc.current_element_focus_bg ); , wc.current_element_focus_bg );
std::size_t i{}; for (std::size_t i{0}; i < element.getLength(); i++)
for (i = 0; i < len; i++)
{ {
if ( serach_mark && i == inc_len && getFlags().focus ) if ( serach_mark && i == inc_len && getFlags().focus )
setColor ( wc.current_element_focus_fg setColor ( wc.current_element_focus_fg
, wc.current_element_focus_bg ); , wc.current_element_focus_bg );
print (element_str[i]); print (element[i]);
} }
if ( isMonochron() && isCurrentLine && getFlags().focus ) if ( isMonochron() && isCurrentLine && getFlags().focus )
{ {
print (fc::BlackLeftPointingPointer); // ◄ print (fc::BlackLeftPointingPointer); // ◄
i++; column_width++;
} }
for (; i < getWidth() - nf_offset - 3; i++) for (; column_width < getWidth() - nf_offset - 3; column_width++)
print (' '); print (' ');
} }
@ -1010,10 +1007,9 @@ inline void FListBox::drawListBracketsLine ( int y
, listBoxItems::iterator iter , listBoxItems::iterator iter
, bool serach_mark ) , bool serach_mark )
{ {
FString element{};
std::size_t inc_len = inc_search.getLength() std::size_t inc_len = inc_search.getLength()
, b{0}; , b{0};
bool isCurrentLine = bool(y + yoffset + 1 == int(current)); bool isCurrentLine( y + yoffset + 1 == int(current) );
if ( isMonochron() && isCurrentLine && getFlags().focus ) if ( isMonochron() && isCurrentLine && getFlags().focus )
print (fc::BlackRightPointingPointer); // ► print (fc::BlackRightPointingPointer); // ►
@ -1022,23 +1018,19 @@ inline void FListBox::drawListBracketsLine ( int y
if ( xoffset == 0 ) if ( xoffset == 0 )
{ {
b = 1; b = 1; // Required bracket space
printLeftBracket (iter->brackets); printLeftBracket (iter->brackets);
element = getString(iter).mid ( std::size_t(xoffset) + 1
, getWidth() - nf_offset - 5 );
} }
else
element = getString(iter).mid ( std::size_t(xoffset)
, getWidth() - nf_offset - 4 );
const wchar_t* const& element_str = element.wc_str(); std::size_t first = std::size_t(xoffset);
std::size_t full_length = getString(iter).getLength() std::size_t max_width = getWidth() - nf_offset - 4 - b;
, len = element.getLength() FString element(getColumnSubString (getString(iter), first, max_width));
, i{0}; std::size_t column_width = getColumnWidth(element);
const FWidgetColors& wc = getFWidgetColors(); std::size_t text_width = getColumnWidth(getString(iter));
std::size_t i{0};
const auto& wc = getFWidgetColors();
for (; i < len; i++) for (; i < element.getLength(); i++)
{ {
if ( serach_mark && i == 0 ) if ( serach_mark && i == 0 )
setColor ( wc.current_inc_search_element_fg setColor ( wc.current_inc_search_element_fg
@ -1048,27 +1040,27 @@ inline void FListBox::drawListBracketsLine ( int y
setColor ( wc.current_element_focus_fg setColor ( wc.current_element_focus_fg
, wc.current_element_focus_bg ); , wc.current_element_focus_bg );
print (element_str[i]); print (element[i]);
} }
if ( b + i < getWidth() - nf_offset - 4 if ( b + column_width < getWidth() - nf_offset - 4
&& std::size_t(xoffset) <= full_length + 1 ) && std::size_t(xoffset) <= text_width )
{ {
if ( serach_mark && i == inc_len ) if ( serach_mark && i == inc_len )
setColor ( wc.current_element_focus_fg setColor ( wc.current_element_focus_fg
, wc.current_element_focus_bg ); , wc.current_element_focus_bg );
printRightBracket (iter->brackets); printRightBracket (iter->brackets);
i++; column_width++;
} }
if ( isMonochron() && isCurrentLine && getFlags().focus ) if ( isMonochron() && isCurrentLine && getFlags().focus )
{ {
print (fc::BlackLeftPointingPointer); // ◄ print (fc::BlackLeftPointingPointer); // ◄
i++; column_width++;
} }
for (; b + i < getWidth() - nf_offset - 3; i++) for (; b + column_width < getWidth() - nf_offset - 3; column_width++)
print (' '); print (' ');
} }
@ -1078,9 +1070,10 @@ inline void FListBox::setLineAttributes ( int y
, bool lineHasBrackets , bool lineHasBrackets
, bool& serach_mark ) , bool& serach_mark )
{ {
bool isCurrentLine = bool(y + yoffset + 1 == int(current)); bool isCurrentLine( y + yoffset + 1 == int(current) );
std::size_t inc_len = inc_search.getLength(); std::size_t inc_len = inc_search.getLength();
const FWidgetColors& wc = getFWidgetColors(); std::size_t inc_width = getColumnWidth(inc_search);
const auto& wc = getFWidgetColors();
print() << FPoint(2, 2 + int(y)); print() << FPoint(2, 2 + int(y));
if ( isLineSelected ) if ( isLineSelected )
@ -1131,7 +1124,7 @@ inline void FListBox::setLineAttributes ( int y
{ {
serach_mark = true; serach_mark = true;
// Place the cursor on the last found character // Place the cursor on the last found character
setCursorPos (FPoint(2 + b + int(inc_len), 2 + int(y))); setCursorPos (FPoint(2 + b + int(inc_width), 2 + int(y)));
} }
else // only highlighted else // only highlighted
setCursorPos (FPoint(3 + b, 2 + int(y))); // first character setCursorPos (FPoint(3 + b, 2 + int(y))); // first character
@ -1554,35 +1547,35 @@ void FListBox::scrollRight (int distance)
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
inline void FListBox::keyUp() inline void FListBox::scrollLeft()
{
prevListItem (1);
inc_search.clear();
}
//----------------------------------------------------------------------
inline void FListBox::keyDown()
{
nextListItem (1);
inc_search.clear();
}
//----------------------------------------------------------------------
inline void FListBox::keyLeft()
{ {
scrollLeft(1); scrollLeft(1);
inc_search.clear(); inc_search.clear();
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
inline void FListBox::keyRight() inline void FListBox::scrollRight()
{ {
scrollRight(1); scrollRight(1);
inc_search.clear(); inc_search.clear();
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
inline void FListBox::keyPgUp() inline void FListBox::onePosUp()
{
prevListItem (1);
inc_search.clear();
}
//----------------------------------------------------------------------
inline void FListBox::onePosDown()
{
nextListItem (1);
inc_search.clear();
}
//----------------------------------------------------------------------
inline void FListBox::onePageUp()
{ {
int pagesize = int(getClientHeight()) - 1; int pagesize = int(getClientHeight()) - 1;
prevListItem (pagesize); prevListItem (pagesize);
@ -1590,7 +1583,7 @@ inline void FListBox::keyPgUp()
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
inline void FListBox::keyPgDn() inline void FListBox::onePageDown()
{ {
int pagesize = int(getClientHeight()) - 1; int pagesize = int(getClientHeight()) - 1;
nextListItem (pagesize); nextListItem (pagesize);
@ -1598,7 +1591,7 @@ inline void FListBox::keyPgDn()
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
inline void FListBox::keyHome() inline void FListBox::firstPos()
{ {
current = 1; current = 1;
yoffset = 0; yoffset = 0;
@ -1606,7 +1599,7 @@ inline void FListBox::keyHome()
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
inline void FListBox::keyEnd() inline void FListBox::lastPos()
{ {
std::size_t element_count = getCount(); std::size_t element_count = getCount();
int yoffset_end = int(element_count - getClientHeight()); int yoffset_end = int(element_count - getClientHeight());
@ -1619,7 +1612,7 @@ inline void FListBox::keyEnd()
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
inline bool FListBox::keyEsc() inline bool FListBox::skipIncrementalSearch()
{ {
if ( inc_search.getLength() > 0 ) if ( inc_search.getLength() > 0 )
{ {
@ -1631,18 +1624,18 @@ inline bool FListBox::keyEsc()
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
inline void FListBox::keyEnter() inline void FListBox::acceptSelection()
{ {
processClick(); processClick();
inc_search.clear(); inc_search.clear();
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
inline bool FListBox::keySpace() inline bool FListBox::spacebarProcessing()
{ {
std::size_t inc_len = inc_search.getLength(); std::size_t inc_len = inc_search.getLength();
if ( inc_len > 0 ) if ( inc_len > 0 ) // Enter a spacebar for incremental search
{ {
inc_search += L' '; inc_search += L' ';
bool inc_found{false}; bool inc_found{false};
@ -1668,7 +1661,7 @@ inline bool FListBox::keySpace()
return false; return false;
} }
} }
else if ( isMultiSelection() ) else if ( isMultiSelection() ) // Change selection
{ {
if ( isSelected(current) ) if ( isSelected(current) )
unselectItem(current); unselectItem(current);
@ -1683,7 +1676,7 @@ inline bool FListBox::keySpace()
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
inline bool FListBox::keyInsert() inline bool FListBox::changeSelectionAndPosition()
{ {
if ( isMultiSelection() ) if ( isMultiSelection() )
{ {
@ -1711,7 +1704,7 @@ inline bool FListBox::keyInsert()
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
inline bool FListBox::keyBackspace() inline bool FListBox::deletePreviousCharacter()
{ {
std::size_t inc_len = inc_search.getLength(); std::size_t inc_len = inc_search.getLength();
@ -1810,8 +1803,8 @@ void FListBox::lazyConvert(listBoxItems::iterator iter, int y)
return; return;
convertToItem (*iter, source_container, y + yoffset); convertToItem (*iter, source_container, y + yoffset);
std::size_t len = iter->text.getLength(); std::size_t column_width = getColumnWidth(iter->text);
recalculateHorizontalBar (len, hasBrackets(iter)); recalculateHorizontalBar (column_width, hasBrackets(iter));
if ( hbar->isShown() ) if ( hbar->isShown() )
hbar->redraw(); hbar->redraw();

View File

@ -232,7 +232,7 @@ FString FListViewItem::getText (int column) const
return fc::emptyFString::get(); return fc::emptyFString::get();
// Convert column position to address offset (index) // Convert column position to address offset (index)
std::size_t index = uInt(column - 1); std::size_t index = std::size_t(column - 1);
return column_list[index]; return column_list[index];
} }
@ -259,7 +259,7 @@ void FListViewItem::setText (int column, const FString& text)
return; return;
// Convert column position to address offset (index) // Convert column position to address offset (index)
std::size_t index = uInt(column - 1); std::size_t index = std::size_t(column - 1);
auto parent = getParent(); auto parent = getParent();
if ( parent && parent->isInstanceOf("FListView") ) if ( parent && parent->isInstanceOf("FListView") )
@ -268,10 +268,10 @@ void FListViewItem::setText (int column, const FString& text)
if ( ! listview->header[index].fixed_width ) if ( ! listview->header[index].fixed_width )
{ {
int length = int(text.getLength()); int column_width = int(getColumnWidth(text));
if ( length > listview->header[index].width ) if ( column_width > listview->header[index].width )
listview->header[index].width = length; listview->header[index].width = column_width;
} }
} }
@ -596,13 +596,11 @@ FListView::~FListView() // destructor
std::size_t FListView::getCount() std::size_t FListView::getCount()
{ {
int n{0}; int n{0};
auto iter = itemlist.begin();
while ( iter != itemlist.end() ) for (auto&& item : itemlist)
{ {
auto item = static_cast<FListViewItem*>(*iter); auto listitem = static_cast<FListViewItem*>(item);
n += item->getVisibleLines(); n += listitem->getVisibleLines();
++iter;
} }
return std::size_t(n); return std::size_t(n);
@ -617,7 +615,7 @@ fc::text_alignment FListView::getColumnAlignment (int column) const
return fc::alignLeft; return fc::alignLeft;
// Convert column position to address offset (index) // Convert column position to address offset (index)
std::size_t index = uInt(column - 1); std::size_t index = std::size_t(column - 1);
return header[index].alignment; return header[index].alignment;
} }
@ -630,7 +628,7 @@ FString FListView::getColumnText (int column) const
return fc::emptyFString::get(); return fc::emptyFString::get();
// Convert column position to address offset (index) // Convert column position to address offset (index)
std::size_t index = uInt(column - 1); std::size_t index = std::size_t(column - 1);
return header[index].name; return header[index].name;
} }
@ -698,10 +696,10 @@ void FListView::setColumnText (int column, const FString& label)
if ( ! header[index].fixed_width ) if ( ! header[index].fixed_width )
{ {
int length = int(label.getLength()); int column_width = int(getColumnWidth(label));
if ( length > header[index].width ) if ( column_width > header[index].width )
header[index].width = length; header[index].width = column_width;
} }
header[index].name = label; header[index].name = label;
@ -715,7 +713,7 @@ void FListView::setColumnSortType (int column, fc::sorting_type type)
if ( column < 1 || header.empty() || column > int(header.size()) ) if ( column < 1 || header.empty() || column > int(header.size()) )
return; return;
std::size_t size = std::size_t(column) + 1; std::size_t size = std::size_t(column + 1);
if ( sort_type.empty() || sort_type.size() < size ) if ( sort_type.empty() || sort_type.size() < size )
sort_type.resize(size); sort_type.resize(size);
@ -745,7 +743,7 @@ int FListView::addColumn (const FString& label, int width)
if ( new_column.width == USE_MAX_SIZE ) if ( new_column.width == USE_MAX_SIZE )
{ {
new_column.fixed_width = false; new_column.fixed_width = false;
new_column.width = int(label.getLength()); new_column.width = int(getColumnWidth(label));
} }
else else
new_column.fixed_width = true; new_column.fixed_width = true;
@ -895,7 +893,7 @@ void FListView::onKeyPress (FKeyEvent* ev)
break; break;
case fc::Fkey_space: case fc::Fkey_space:
keySpace(); toggleCheckbox();
ev->accept(); ev->accept();
break; break;
@ -910,12 +908,12 @@ void FListView::onKeyPress (FKeyEvent* ev)
break; break;
case fc::Fkey_left: case fc::Fkey_left:
keyLeft (first_line_position_before); collapseAndScrollLeft (first_line_position_before);
ev->accept(); ev->accept();
break; break;
case fc::Fkey_right: case fc::Fkey_right:
keyRight(first_line_position_before); expandAndScrollRight (first_line_position_before);
ev->accept(); ev->accept();
break; break;
@ -930,22 +928,22 @@ void FListView::onKeyPress (FKeyEvent* ev)
break; break;
case fc::Fkey_home: case fc::Fkey_home:
keyHome(); firstPos();
ev->accept(); ev->accept();
break; break;
case fc::Fkey_end: case fc::Fkey_end:
keyEnd(); lastPos();
ev->accept(); ev->accept();
break; break;
case int('+'): case int('+'):
if ( keyPlus() ) if ( expandSubtree() )
ev->accept(); ev->accept();
break; break;
case int('-'): case int('-'):
if ( keyMinus() ) if ( collapseSubtree() )
ev->accept(); ev->accept();
break; break;
@ -958,9 +956,9 @@ void FListView::onKeyPress (FKeyEvent* ev)
if ( ev->isAccepted() ) if ( ev->isAccepted() )
{ {
bool draw_vbar = first_line_position_before bool draw_vbar( first_line_position_before
!= first_visible_line.getPosition(); != first_visible_line.getPosition() );
bool draw_hbar = xoffset_before != xoffset; bool draw_hbar(xoffset_before != xoffset);
updateDrawing (draw_vbar, draw_hbar); updateDrawing (draw_vbar, draw_hbar);
} }
} }
@ -1387,7 +1385,7 @@ void FListView::init()
root = selflist.begin(); root = selflist.begin();
null_iter = selflist.end(); null_iter = selflist.end();
setGeometry (FPoint(1, 1), FSize(5, 4), false); // initialize geometry values setGeometry (FPoint(1, 1), FSize(5, 4), false); // initialize geometry values
const FWidgetColors& wc = getFWidgetColors(); const auto& wc = getFWidgetColors();
setForegroundColor (wc.dialog_fg); setForegroundColor (wc.dialog_fg);
setBackgroundColor (wc.dialog_bg); setBackgroundColor (wc.dialog_bg);
nf_offset = isNewFont() ? 1 : 0; nf_offset = isNewFont() ? 1 : 0;
@ -1437,7 +1435,7 @@ void FListView::sort (Compare cmp)
//---------------------------------------------------------------------- //----------------------------------------------------------------------
std::size_t FListView::getAlignOffset ( fc::text_alignment align std::size_t FListView::getAlignOffset ( fc::text_alignment align
, std::size_t txt_length , std::size_t column_width
, std::size_t width ) , std::size_t width )
{ {
switch ( align ) switch ( align )
@ -1446,14 +1444,14 @@ std::size_t FListView::getAlignOffset ( fc::text_alignment align
return 0; return 0;
case fc::alignCenter: case fc::alignCenter:
if ( txt_length < width ) if ( column_width < width )
return (width - txt_length) / 2; return (width - column_width) / 2;
else else
return 0; return 0;
case fc::alignRight: case fc::alignRight:
if ( txt_length < width ) if ( column_width < width )
return width - txt_length; return width - column_width;
else else
return 0; return 0;
} }
@ -1536,8 +1534,6 @@ void FListView::drawScrollbars()
//---------------------------------------------------------------------- //----------------------------------------------------------------------
void FListView::drawHeadlines() void FListView::drawHeadlines()
{ {
std::vector<charData>::const_iterator first, last;
if ( header.empty() if ( header.empty()
|| getHeight() <= 2 || getHeight() <= 2
|| getWidth() <= 4 || getWidth() <= 4
@ -1548,7 +1544,7 @@ void FListView::drawHeadlines()
headerline.clear(); headerline.clear();
if ( hasCheckableItems() ) if ( hasCheckableItems() )
drawHeaderBorder(4); drawHeaderBorder(4); // Draw into FTermBuffer object
while ( iter != header.end() ) while ( iter != header.end() )
{ {
@ -1560,27 +1556,12 @@ void FListView::drawHeadlines()
continue; continue;
} }
drawHeadlineLabel(iter); drawHeadlineLabel(iter); // Draw into FTermBuffer object
++iter; ++iter;
} }
std::vector<charData> h; // Print the FTermBuffer object
h << headerline; drawBufferedHeadline();
first = h.begin() + xoffset;
if ( h.size() <= getClientWidth() )
last = h.end();
else
{
int len = int(getClientWidth()) + xoffset - 1;
if ( len > int(h.size()) )
len = int(h.size());
last = h.begin() + len;
}
print() << FPoint(2, 1) << std::vector<charData>(first, last);
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
@ -1590,12 +1571,12 @@ void FListView::drawList()
return; return;
uInt y{0}; uInt y{0};
uInt page_height = uInt(getHeight() - 2); uInt page_height = uInt(getHeight()) - 2;
auto iter = first_visible_line; auto iter = first_visible_line;
while ( iter != itemlist.end() && y < page_height ) while ( iter != itemlist.end() && y < page_height )
{ {
bool is_current_line = bool( iter == current_iter ); bool is_current_line( iter == current_iter );
const auto item = static_cast<FListViewItem*>(*iter); const auto item = static_cast<FListViewItem*>(*iter);
int tree_offset = ( tree_view ) ? int(item->getDepth() << 1) + 1 : 0; int tree_offset = ( tree_view ) ? int(item->getDepth() << 1) + 1 : 0;
int checkbox_offset = ( item->isCheckable() ) ? 1 : 0; int checkbox_offset = ( item->isCheckable() ) ? 1 : 0;
@ -1606,9 +1587,13 @@ void FListView::drawList()
if ( getFlags().focus && is_current_line ) if ( getFlags().focus && is_current_line )
{ {
int xpos = 3 + tree_offset + checkbox_offset - xoffset;
if ( xpos < 2 ) // Hide the cursor
xpos = -9999; // by moving it outside the visible area
setVisibleCursor (item->isCheckable()); setVisibleCursor (item->isCheckable());
setCursorPos (FPoint ( 3 + tree_offset + checkbox_offset - xoffset setCursorPos (FPoint(xpos, 2 + int(y))); // first character
, 2 + int(y) )); // first character
} }
last_visible_line = iter; last_visible_line = iter;
@ -1651,12 +1636,12 @@ void FListView::drawListLine ( const FListViewItem* item
static constexpr std::size_t ellipsis_length = 2; static constexpr std::size_t ellipsis_length = 2;
const auto& text = item->column_list[col]; const auto& text = item->column_list[col];
std::size_t width = std::size_t(header[col].width); std::size_t width = std::size_t(header[col].width);
std::size_t txt_length = text.getLength(); std::size_t column_width = getColumnWidth(text);
// Increment the value of i for the column position // Increment the value of col for the column position
// and the next iteration // and the next iteration
col++; col++;
fc::text_alignment align = getColumnAlignment(int(col)); fc::text_alignment align = getColumnAlignment(int(col));
std::size_t align_offset = getAlignOffset (align, txt_length, width); std::size_t align_offset = getAlignOffset (align, column_width, width);
if ( tree_view && col == 1 ) if ( tree_view && col == 1 )
{ {
@ -1673,40 +1658,43 @@ void FListView::drawListLine ( const FListViewItem* item
if ( align_offset > 0 ) if ( align_offset > 0 )
line += FString(align_offset, L' '); line += FString(align_offset, L' ');
if ( align_offset + txt_length <= width ) if ( align_offset + column_width <= width )
{ {
// Insert text and trailing space // Insert text and trailing space
static constexpr std::size_t leading_space = 1; static constexpr std::size_t leading_space = 1;
line += text.left(width); line += getColumnSubString (text, 1, width);
line += FString ( leading_space + width line += FString ( leading_space + width
- align_offset - txt_length, L' '); - align_offset - column_width, L' ');
} }
else if ( align == fc::alignRight ) else if ( align == fc::alignRight )
{ {
// Ellipse right align text // Ellipse right align text
std::size_t first = getColumnWidth(text) + 1 - width;
line += FString (L".."); line += FString (L"..");
line += text.right(width - ellipsis_length); line += getColumnSubString (text, first, width - ellipsis_length);
line += L' '; line += L' ';
} }
else else
{ {
// Ellipse left align text and center text // Ellipse left align text and center text
line += text.left(width - ellipsis_length); line += getColumnSubString (text, 1, width - ellipsis_length);
line += FString (L".. "); line += FString (L".. ");
} }
} }
} }
line = line.mid ( std::size_t(xoffset) + 1 std::size_t width = getWidth() - nf_offset - 2;
, getWidth() - nf_offset - 2); line = getColumnSubString ( line, std::size_t(xoffset) + 1, width );
const wchar_t* const& element_str = line.wc_str();
std::size_t len = line.getLength(); std::size_t len = line.getLength();
std::size_t i; std::size_t char_width{0};
for (i = 0; i < len; i++) for (std::size_t i{0}; i < len; i++)
print() << element_str[i]; {
char_width += getColumnWidth(line[i]);
print() << line[i];
}
for (; i < getWidth() - nf_offset - 2; i++) for (std::size_t i = char_width; i < width; i++)
print (' '); print (' ');
} }
@ -1714,7 +1702,7 @@ void FListView::drawListLine ( const FListViewItem* item
inline void FListView::setLineAttributes ( bool is_current inline void FListView::setLineAttributes ( bool is_current
, bool is_focus ) , bool is_focus )
{ {
const FWidgetColors& wc = getFWidgetColors(); const auto& wc = getFWidgetColors();
setColor (wc.list_fg, wc.list_bg); setColor (wc.list_fg, wc.list_bg);
if ( is_current ) if ( is_current )
@ -1805,9 +1793,9 @@ inline FString FListView::getLinePrefix ( const FListViewItem* item
//---------------------------------------------------------------------- //----------------------------------------------------------------------
inline void FListView::drawSortIndicator ( std::size_t& length inline void FListView::drawSortIndicator ( std::size_t& length
, std::size_t column_width ) , std::size_t column_max )
{ {
if ( length >= column_width ) if ( length >= column_max )
return; return;
setColor(); setColor();
@ -1818,7 +1806,7 @@ inline void FListView::drawSortIndicator ( std::size_t& length
else if ( sort_order == fc::descending ) else if ( sort_order == fc::descending )
headerline << fc::BlackDownPointingTriangle; // ▼ headerline << fc::BlackDownPointingTriangle; // ▼
if ( length < column_width ) if ( length < column_max )
{ {
length++; length++;
headerline << ' '; headerline << ' ';
@ -1833,65 +1821,153 @@ inline void FListView::drawHeaderBorder (std::size_t length)
headerline << line; // horizontal line headerline << line; // horizontal line
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
void FListView::drawHeadlineLabel (const headerItems::const_iterator& iter) void FListView::drawHeadlineLabel (const headerItems::const_iterator& iter)
{ {
// Print lable text // Print label text
static constexpr std::size_t leading_space = 1; static constexpr std::size_t leading_space = 1;
const auto& text = iter->name; const auto& text = iter->name;
FString txt(" " + text); FString txt(" " + text);
std::size_t width = std::size_t(iter->width); std::size_t width = std::size_t(iter->width);
std::size_t txt_length = txt.getLength(); std::size_t column_width = getColumnWidth(txt);
std::size_t column_width = leading_space + width; std::size_t column_max = leading_space + width;
headerItems::const_iterator first = header.begin(); headerItems::const_iterator first = header.begin();
int column = int(std::distance(first, iter)) + 1; int column = int(std::distance(first, iter)) + 1;
bool has_sort_indicator = bool ( sort_column == column bool has_sort_indicator( sort_column == column && ! hide_sort_indicator );
&& ! hide_sort_indicator ); const auto& wc = getFWidgetColors();
const FWidgetColors& wc = getFWidgetColors();
if ( isEnabled() ) if ( isEnabled() )
setColor (wc.label_emphasis_fg, wc.label_bg); setColor (wc.label_emphasis_fg, wc.label_bg);
else else
setColor (wc.label_inactive_fg, wc.label_inactive_bg); setColor (wc.label_inactive_fg, wc.label_inactive_bg);
if ( has_sort_indicator && txt_length >= column_width - 1 && txt_length > 1 ) if ( has_sort_indicator && column_width >= column_max - 1 && column_width > 1 )
{ {
txt_length = column_width - 2; column_width = column_max - 2;
txt = txt.left(txt_length); txt = getColumnSubString (txt, 1, column_width);
} }
if ( txt_length <= column_width ) if ( column_width <= column_max )
{ {
std::size_t length = txt_length;
headerline << txt; headerline << txt;
if ( length < column_width ) if ( column_width < column_max )
{ {
length++; column_width++;
headerline << ' '; // trailing space headerline << ' '; // trailing space
} }
if ( has_sort_indicator ) if ( has_sort_indicator )
drawSortIndicator (length, column_width ); drawSortIndicator (column_width, column_max );
if ( length < column_width ) if ( column_width < column_max )
drawHeaderBorder (column_width - length); drawHeaderBorder (column_max - column_width);
} }
else else
drawColumnEllipsis (iter, text); // Print ellipsis drawColumnEllipsis (iter, text); // Print ellipsis
} }
//----------------------------------------------------------------------
void FListView::drawBufferedHeadline()
{
// Print the FTermBuffer object
if ( headerline.isEmpty() )
return;
std::size_t column_offset{0};
std::size_t column_width{0};
std::size_t offset{0};
bool left_truncated_fullwidth{false};
bool right_truncated_fullwidth{false};
std::vector<charData>::const_iterator first{}, last{};
last = headerline.end();
// Search for the start position
for (auto&& tc : headerline)
{
if ( xoffset == 0 )
break;
column_offset += getColumnWidth(tc);
offset++;
if ( column_offset == std::size_t(xoffset) )
break;
if ( column_offset > std::size_t(xoffset) && column_offset >= 2 )
{
left_truncated_fullwidth = true;
break;
}
}
first = headerline.begin();
std::advance(first, offset);
// Search for the end position
if ( getColumnWidth(headerline) > getClientWidth() )
{
std::size_t character{0};
if ( left_truncated_fullwidth )
column_width++;
for (auto&& tc : FTermBuffer(first, last))
{
uInt8 char_width = tc.attr.bit.char_width;
if ( column_width + char_width > getClientWidth() )
{
column_width++;
right_truncated_fullwidth = true;
break;
}
column_width += char_width;
character++;
if ( column_width == getClientWidth() )
break;
}
last = first;
std::advance(last, character);
}
else
column_width = getColumnWidth(headerline);
// Print the header line
print() << FPoint(2, 1);
if ( left_truncated_fullwidth )
print (fc::SingleLeftAngleQuotationMark); //
print() << FTermBuffer(first, last);
if ( right_truncated_fullwidth )
print (fc::SingleRightAngleQuotationMark); //
while ( column_width < getClientWidth() )
{
setColor();
print(fc::BoxDrawingsHorizontal);
column_width++;
}
}
//---------------------------------------------------------------------- //----------------------------------------------------------------------
void FListView::drawColumnEllipsis ( const headerItems::const_iterator& iter void FListView::drawColumnEllipsis ( const headerItems::const_iterator& iter
, const FString& text ) , const FString& text )
{ {
// Print lable ellipsis // Print label ellipsis
static constexpr int ellipsis_length = 2; static constexpr int ellipsis_length = 2;
int width = iter->width; int width = iter->width;
const FWidgetColors& wc = getFWidgetColors(); const auto& wc = getFWidgetColors();
headerline << ' ' headerline << ' '
<< text.left(uInt(width - ellipsis_length)) << getColumnSubString (text, 1, uInt(width - ellipsis_length))
<< FColorPair (wc.label_ellipsis_fg, wc.label_bg) << FColorPair (wc.label_ellipsis_fg, wc.label_bg)
<< ".."; << "..";
@ -1923,33 +1999,36 @@ void FListView::updateDrawing (bool draw_vbar, bool draw_hbar)
std::size_t FListView::determineLineWidth (FListViewItem* item) std::size_t FListView::determineLineWidth (FListViewItem* item)
{ {
static constexpr std::size_t padding_space = 1; 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 line_width = padding_space; // leading space
uInt column_idx{0}; std::size_t column_idx{0};
uInt entries = uInt(item->column_list.size()); std::size_t entries = std::size_t(item->column_list.size());
headerItems::iterator header_iter = header.begin();
while ( header_iter != header.end() ) if ( hasCheckableItems() )
line_width += checkbox_space;
for (auto&& header_item : header)
{ {
std::size_t width = std::size_t(header_iter->width); std::size_t width = std::size_t(header_item.width);
bool fixed_width = header_iter->fixed_width; bool fixed_width = header_item.fixed_width;
if ( ! fixed_width ) if ( ! fixed_width )
{ {
std::size_t len; std::size_t len{};
if ( column_idx < entries ) if ( column_idx < entries )
len = item->column_list[column_idx].getLength(); len = getColumnWidth(item->column_list[column_idx]);
else else
len = 0; len = 0;
if ( len > width ) if ( len > width )
header_iter->width = int(len); header_item.width = int(len);
} }
line_width += std::size_t(header_iter->width) // width + trailing space
+ padding_space; // width + trailing space line_width += std::size_t(header_item.width) + padding_space;
column_idx++; column_idx++;
++header_iter;
} }
return line_width; return line_width;
@ -2033,19 +2112,18 @@ void FListView::mouseHeaderClicked()
int checkbox_offset = ( hasCheckableItems() ) ? 4 : 0; int checkbox_offset = ( hasCheckableItems() ) ? 4 : 0;
int header_start = 2 + checkbox_offset; int header_start = 2 + checkbox_offset;
int header_pos = clicked_header_pos.getX() + xoffset; int header_pos = clicked_header_pos.getX() + xoffset;
headerItems::const_iterator iter = header.begin();
while ( iter != header.end() ) for (auto&& item : header)
{ {
static constexpr int leading_space = 1; static constexpr int leading_space = 1;
bool has_sort_indicator = bool( column == sort_column ); bool has_sort_indicator( column == sort_column );
int click_width = int(iter->name.getLength()); int click_width = int(getColumnWidth(item.name));
if ( has_sort_indicator ) if ( has_sort_indicator )
click_width += 2; click_width += 2;
if ( click_width > iter->width ) if ( click_width > item.width )
click_width = iter->width; click_width = item.width;
if ( header_pos > header_start if ( header_pos > header_start
&& header_pos <= header_start + click_width ) && header_pos <= header_start + click_width )
@ -2063,9 +2141,8 @@ void FListView::mouseHeaderClicked()
break; break;
} }
header_start += leading_space + iter->width; header_start += leading_space + item.width;
column++; column++;
++iter;
} }
} }
@ -2234,7 +2311,7 @@ void FListView::processChanged()
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
inline void FListView::keySpace() inline void FListView::toggleCheckbox()
{ {
if ( itemlist.empty() ) if ( itemlist.empty() )
return; return;
@ -2246,7 +2323,7 @@ inline void FListView::keySpace()
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
inline void FListView::keyLeft (int& first_line_position_before) inline void FListView::collapseAndScrollLeft (int& first_line_position_before)
{ {
if ( itemlist.empty() ) if ( itemlist.empty() )
return; return;
@ -2303,7 +2380,7 @@ inline void FListView::keyLeft (int& first_line_position_before)
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
inline void FListView::keyRight (int& first_line_position_before) inline void FListView::expandAndScrollRight (int& first_line_position_before)
{ {
if ( itemlist.empty() ) if ( itemlist.empty() )
return; return;
@ -2331,7 +2408,7 @@ inline void FListView::keyRight (int& first_line_position_before)
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
inline void FListView::keyHome() inline void FListView::firstPos()
{ {
if ( itemlist.empty() ) if ( itemlist.empty() )
return; return;
@ -2343,7 +2420,7 @@ inline void FListView::keyHome()
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
inline void FListView::keyEnd() inline void FListView::lastPos()
{ {
if ( itemlist.empty() ) if ( itemlist.empty() )
return; return;
@ -2356,7 +2433,7 @@ inline void FListView::keyEnd()
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
inline bool FListView::keyPlus() inline bool FListView::expandSubtree()
{ {
if ( itemlist.empty() ) if ( itemlist.empty() )
return false; return false;
@ -2374,7 +2451,7 @@ inline bool FListView::keyPlus()
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
inline bool FListView::keyMinus() inline bool FListView::collapseSubtree()
{ {
if ( itemlist.empty() ) if ( itemlist.empty() )
return false; return false;

View File

@ -51,7 +51,7 @@ FMenu::FMenu(FWidget* parent)
//---------------------------------------------------------------------- //----------------------------------------------------------------------
FMenu::FMenu (const FString& txt, FWidget* parent) FMenu::FMenu (const FString& txt, FWidget* parent)
: FWindow(parent) : FWindow(parent)
, item(txt, parent) , menuitem(txt, parent)
{ {
init(parent); init(parent);
} }
@ -80,7 +80,7 @@ bool FMenu::setMenuWidget (bool enable)
void FMenu::setStatusbarMessage (const FString& msg) void FMenu::setStatusbarMessage (const FString& msg)
{ {
FWidget::setStatusbarMessage(msg); FWidget::setStatusbarMessage(msg);
item.setStatusbarMessage(msg); menuitem.setStatusbarMessage(msg);
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
@ -138,29 +138,29 @@ void FMenu::onKeyPress (FKeyEvent* ev)
switch ( ev->key() ) switch ( ev->key() )
{ {
case fc::Fkey_up: case fc::Fkey_up:
keyUp(); selectPrevItem();
break; break;
case fc::Fkey_down: case fc::Fkey_down:
keyDown(); selectNextItem();
break; break;
case fc::Fkey_left: case fc::Fkey_left:
keyLeft(ev); selectPrevMenu(ev);
break; break;
case fc::Fkey_right: case fc::Fkey_right:
keyRight(ev); selectNextMenu(ev);
break; break;
case fc::Fkey_return: case fc::Fkey_return:
case fc::Fkey_enter: case fc::Fkey_enter:
keyEnter(); acceptSelection();
break; break;
case fc::Fkey_escape: case fc::Fkey_escape:
case fc::Fkey_escape_mintty: case fc::Fkey_escape_mintty:
keyEscape(); closeMenu();
break; break;
case fc::Fmkey_1: case fc::Fmkey_1:
@ -320,12 +320,12 @@ void FMenu::onMouseMove (FMouseEvent* ev)
//---------------------------------------------------------------------- //----------------------------------------------------------------------
void FMenu::cb_menuitem_toggled (FWidget* widget, FDataPtr) void FMenu::cb_menuitem_toggled (FWidget* widget, FDataPtr)
{ {
auto menuitem = static_cast<FMenuItem*>(widget); auto m_item = static_cast<FMenuItem*>(widget);
if ( ! has_checkable_items ) if ( ! has_checkable_items )
return; return;
if ( ! menuitem->isChecked() ) if ( ! m_item->isChecked() )
return; return;
auto list = getItemList(); auto list = getItemList();
@ -333,19 +333,14 @@ void FMenu::cb_menuitem_toggled (FWidget* widget, FDataPtr)
if ( list.empty() ) if ( list.empty() )
return; return;
auto iter = list.begin(); for (auto&& item : list)
auto last = list.end();
while ( iter != last )
{ {
if ( (*iter) != menuitem if ( item != m_item
&& (*iter)->isChecked() && item->isChecked()
&& isRadioMenuItem(*iter) ) && isRadioMenuItem(item) )
{ {
(*iter)->unsetChecked(); item->unsetChecked();
} }
++iter;
} }
} }
@ -445,10 +440,10 @@ void FMenu::init(FWidget* parent)
setMenuWidget(); setMenuWidget();
hide(); hide();
const FWidgetColors& wc = getFWidgetColors(); const auto& wc = getFWidgetColors();
setForegroundColor (wc.menu_active_fg); setForegroundColor (wc.menu_active_fg);
setBackgroundColor (wc.menu_active_bg); setBackgroundColor (wc.menu_active_bg);
item.setMenu(this); menuitem.setMenu(this);
if ( parent ) if ( parent )
{ {
@ -472,17 +467,14 @@ void FMenu::init(FWidget* parent)
//---------------------------------------------------------------------- //----------------------------------------------------------------------
void FMenu::calculateDimensions() void FMenu::calculateDimensions()
{ {
auto list = getItemList();
auto iter = list.begin();
auto last = list.end();
max_item_width = 10; // minimum width max_item_width = 10; // minimum width
// find the maximum item width // find the maximum item width
while ( iter != last ) for (auto&& item : getItemList())
{ {
std::size_t item_width = (*iter)->getTextLength() + 2; std::size_t item_width = item->getTextWidth() + 2;
FKey accel_key = (*iter)->accel_key; FKey accel_key = item->accel_key;
bool has_menu = (*iter)->hasMenu(); bool has_menu = item->hasMenu();
if ( has_menu ) if ( has_menu )
{ {
@ -499,8 +491,6 @@ void FMenu::calculateDimensions()
if ( item_width > max_item_width ) if ( item_width > max_item_width )
max_item_width = item_width; max_item_width = item_width;
++iter;
} }
int adjust_X = adjustX(getX()); int adjust_X = adjustX(getX());
@ -510,42 +500,36 @@ void FMenu::calculateDimensions()
, FSize(max_item_width + 2, getCount() + 2) ); , FSize(max_item_width + 2, getCount() + 2) );
// set geometry of all items // set geometry of all items
iter = list.begin();
int item_X = 1; int item_X = 1;
int item_Y = 1; int item_Y = 1;
while ( iter != last ) for (auto&& item : getItemList())
{ {
(*iter)->setGeometry (FPoint(item_X, item_Y), FSize(max_item_width, 1)); item->setGeometry (FPoint(item_X, item_Y), FSize(max_item_width, 1));
if ( (*iter)->hasMenu() ) if ( item->hasMenu() )
{ {
int menu_X = getTermX() + int(max_item_width) + 1; int menu_X = getTermX() + int(max_item_width) + 1;
int menu_Y = (*iter)->getTermY() - 2; int menu_Y = item->getTermY() - 2;
// set sub-menu position // set sub-menu position
(*iter)->getMenu()->setPos (FPoint(menu_X, menu_Y), false); item->getMenu()->setPos (FPoint(menu_X, menu_Y), false);
} }
item_Y++; item_Y++;
++iter;
} }
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
void FMenu::adjustItems() void FMenu::adjustItems()
{ {
auto list = getItemList(); for (auto&& item : getItemList())
auto iter = list.begin();
auto last = list.end();
while ( iter != last )
{ {
if ( (*iter)->hasMenu() ) if ( item->hasMenu() )
{ {
auto menu = (*iter)->getMenu(); auto menu = item->getMenu();
int menu_X = getTermX() + int(max_item_width) + 1; int menu_X = getTermX() + int(max_item_width) + 1;
menu_X = menu->adjustX(menu_X); menu_X = menu->adjustX(menu_X);
int menu_Y = (*iter)->getTermY() - 2; int menu_Y = item->getTermY() - 2;
// set sub-menu position // set sub-menu position
menu->setPos (FPoint(menu_X, menu_Y)); menu->setPos (FPoint(menu_X, menu_Y));
@ -554,8 +538,6 @@ void FMenu::adjustItems()
if ( menu->getCount() > 0 ) if ( menu->getCount() > 0 )
menu->adjustItems(); menu->adjustItems();
} }
++iter;
} }
} }
@ -664,16 +646,13 @@ void FMenu::hideSuperMenus()
bool FMenu::mouseDownOverList (FPoint mouse_pos) bool FMenu::mouseDownOverList (FPoint mouse_pos)
{ {
bool focus_changed{false}; bool focus_changed{false};
auto list = getItemList();
auto iter = list.begin();
auto last = list.end();
mouse_pos -= FPoint(getRightPadding(), getTopPadding()); mouse_pos -= FPoint(getRightPadding(), getTopPadding());
while ( iter != last ) for (auto&& item : getItemList())
{ {
int x1 = (*iter)->getX() int x1 = item->getX()
, x2 = (*iter)->getX() + int((*iter)->getWidth()) , x2 = item->getX() + int(item->getWidth())
, y = (*iter)->getY() , y = item->getY()
, mouse_x = mouse_pos.getX() , mouse_x = mouse_pos.getX()
, mouse_y = mouse_pos.getY(); , mouse_y = mouse_pos.getY();
@ -682,11 +661,9 @@ bool FMenu::mouseDownOverList (FPoint mouse_pos)
&& mouse_y == y ) && mouse_y == y )
{ {
// Mouse pointer over item // Mouse pointer over item
mouseDownSubmenu (*iter); mouseDownSubmenu (item);
mouseDownSelection (*iter, focus_changed); mouseDownSelection (item, focus_changed);
} }
++iter;
} }
return focus_changed; return focus_changed;
@ -753,28 +730,25 @@ void FMenu::mouseDownSelection (FMenuItem* m_item, bool& focus_changed)
//---------------------------------------------------------------------- //----------------------------------------------------------------------
bool FMenu::mouseUpOverList (FPoint mouse_pos) bool FMenu::mouseUpOverList (FPoint mouse_pos)
{ {
auto list = getItemList();
auto iter = list.begin();
auto last = list.end();
mouse_pos -= FPoint(getRightPadding(), getTopPadding()); mouse_pos -= FPoint(getRightPadding(), getTopPadding());
while ( iter != last ) for (auto&& item : getItemList())
{ {
int x1 = (*iter)->getX() int x1 = item->getX()
, x2 = (*iter)->getX() + int((*iter)->getWidth()) , x2 = item->getX() + int(item->getWidth())
, y = (*iter)->getY() , y = item->getY()
, mouse_x = mouse_pos.getX() , mouse_x = mouse_pos.getX()
, mouse_y = mouse_pos.getY(); , mouse_y = mouse_pos.getY();
if ( (*iter)->isSelected() if ( item->isSelected()
&& mouse_x >= x1 && mouse_x >= x1
&& mouse_x < x2 && mouse_x < x2
&& mouse_y == y ) && mouse_y == y )
{ {
// Mouse pointer over item // Mouse pointer over item
if ( (*iter)->hasMenu() ) if ( item->hasMenu() )
{ {
auto sub_menu = (*iter)->getMenu(); auto sub_menu = item->getMenu();
if ( ! sub_menu->isShown() ) if ( ! sub_menu->isShown() )
openSubMenu (sub_menu, SELECT_ITEM); openSubMenu (sub_menu, SELECT_ITEM);
else if ( opened_sub_menu ) else if ( opened_sub_menu )
@ -800,11 +774,9 @@ bool FMenu::mouseUpOverList (FPoint mouse_pos)
unselectItem(); unselectItem();
hide(); hide();
hideSuperMenus(); hideSuperMenus();
(*iter)->processClicked(); item->processClicked();
} }
} }
++iter;
} }
return false; return false;
@ -813,25 +785,20 @@ bool FMenu::mouseUpOverList (FPoint mouse_pos)
//---------------------------------------------------------------------- //----------------------------------------------------------------------
void FMenu::mouseMoveOverList (FPoint mouse_pos, mouseStates& ms) void FMenu::mouseMoveOverList (FPoint mouse_pos, mouseStates& ms)
{ {
auto list = getItemList();
auto iter = list.begin();
auto last = list.end();
mouse_pos -= FPoint(getRightPadding(), getTopPadding()); mouse_pos -= FPoint(getRightPadding(), getTopPadding());
while ( iter != last ) for (auto&& item : getItemList())
{ {
int x1 = (*iter)->getX() int x1 = item->getX()
, x2 = (*iter)->getX() + int((*iter)->getWidth()) , x2 = item->getX() + int(item->getWidth())
, y = (*iter)->getY() , y = item->getY()
, mouse_x = mouse_pos.getX() , mouse_x = mouse_pos.getX()
, mouse_y = mouse_pos.getY(); , mouse_y = mouse_pos.getY();
if ( mouse_x >= x1 && mouse_x < x2 && mouse_y == y ) if ( mouse_x >= x1 && mouse_x < x2 && mouse_y == y )
mouseMoveSelection (*iter, ms); mouseMoveSelection (item, ms);
else else
mouseMoveDeselection (*iter, ms); mouseMoveDeselection (item, ms);
++iter;
} }
} }
@ -1001,7 +968,7 @@ bool FMenu::containsMenuStructure (int x, int y)
return true; return true;
else if ( si && si->hasMenu() && opened_sub_menu ) else if ( si && si->hasMenu() && opened_sub_menu )
return si->getMenu()->containsMenuStructure(x, y); return si->getMenu()->containsMenuStructure(x, y);
else if ( item.getTermGeometry().contains(x, y) ) else if ( menuitem.getTermGeometry().contains(x, y) )
return true; return true;
else else
return false; return false;
@ -1038,9 +1005,8 @@ bool FMenu::selectNextItem()
{ {
auto list = getItemList(); auto list = getItemList();
auto iter = list.begin(); auto iter = list.begin();
auto last = list.end();
while ( iter != last ) while ( iter != list.end() )
{ {
if ( (*iter)->isSelected() ) if ( (*iter)->isSelected() )
{ {
@ -1087,7 +1053,6 @@ bool FMenu::selectPrevItem()
{ {
auto list = getItemList(); auto list = getItemList();
auto iter = list.end(); auto iter = list.end();
auto first = list.begin();
do do
{ {
@ -1127,7 +1092,7 @@ bool FMenu::selectPrevItem()
break; break;
} }
} }
while ( iter != first ); while ( iter != list.begin() );
return true; return true;
} }
@ -1144,22 +1109,21 @@ void FMenu::keypressMenuBar (FKeyEvent* ev)
//---------------------------------------------------------------------- //----------------------------------------------------------------------
bool FMenu::hotkeyMenu (FKeyEvent* ev) bool FMenu::hotkeyMenu (FKeyEvent* ev)
{ {
auto list = getItemList(); for (auto&& item : getItemList())
auto iter = list.begin();
auto last = list.end();
while ( iter != last )
{ {
if ( (*iter)->hasHotkey() ) if ( item->hasHotkey() )
{ {
bool found{false}; bool found{false};
uChar hotkey = (*iter)->getHotkey(); FKey hotkey = item->getHotkey();
FKey key = ev->key(); FKey key = ev->key();
if ( std::isalpha(hotkey) || std::isdigit(hotkey) ) if ( hotkey > 0xff00 && hotkey < 0xff5f ) // full-width character
hotkey -= 0xfee0;
if ( std::isalpha(int(hotkey)) || std::isdigit(int(hotkey)) )
{ {
if ( FKey(std::tolower(hotkey)) == key if ( FKey(std::tolower(int(hotkey))) == key
|| FKey(std::toupper(hotkey)) == key ) || FKey(std::toupper(int(hotkey))) == key )
found = true; found = true;
} }
else if ( hotkey == key ) else if ( hotkey == key )
@ -1167,14 +1131,17 @@ bool FMenu::hotkeyMenu (FKeyEvent* ev)
if ( found ) if ( found )
{ {
if ( (*iter)->hasMenu() ) if ( item->hasMenu() )
{ {
auto sub_menu = (*iter)->getMenu(); auto sub_menu = item->getMenu();
unselectItem(); unselectItem();
(*iter)->setSelected(); item->setSelected();
setSelectedItem (*iter); setSelectedItem (item);
redraw(); redraw();
openSubMenu (sub_menu, SELECT_ITEM);
if ( ! sub_menu->isShown() )
openSubMenu (sub_menu, SELECT_ITEM);
sub_menu->redraw(); sub_menu->redraw();
} }
else else
@ -1186,14 +1153,13 @@ bool FMenu::hotkeyMenu (FKeyEvent* ev)
updateTerminal(); updateTerminal();
flush_out(); flush_out();
ev->accept(); ev->accept();
(*iter)->processClicked(); item->processClicked();
} }
ev->accept();
return true; return true;
} }
} }
++iter;
} }
return false; return false;
@ -1203,7 +1169,7 @@ bool FMenu::hotkeyMenu (FKeyEvent* ev)
void FMenu::draw() void FMenu::draw()
{ {
// Fill the background // Fill the background
const FWidgetColors& wc = getFWidgetColors(); const auto& wc = getFWidgetColors();
setColor (wc.menu_active_fg, wc.menu_active_bg); setColor (wc.menu_active_fg, wc.menu_active_bg);
if ( isMonochron() ) if ( isMonochron() )
@ -1222,18 +1188,14 @@ void FMenu::draw()
void FMenu::drawItems() void FMenu::drawItems()
{ {
int y = 0; int y = 0;
auto list = getItemList();
auto iter = list.begin();
auto last = list.end();
while ( iter != last ) for (auto&& item : getItemList())
{ {
if ( (*iter)->isSeparator() ) if ( item->isSeparator() )
drawSeparator (y); drawSeparator (y);
else else
drawMenuLine (*iter, y); drawMenuLine (item, y);
++iter;
y++; y++;
} }
} }
@ -1241,7 +1203,7 @@ void FMenu::drawItems()
//---------------------------------------------------------------------- //----------------------------------------------------------------------
inline void FMenu::drawSeparator (int y) inline void FMenu::drawSeparator (int y)
{ {
const FWidgetColors& wc = getFWidgetColors(); const auto& wc = getFWidgetColors();
print() << FPoint(1, 2 + y) print() << FPoint(1, 2 + y)
<< FColorPair(wc.menu_active_fg, wc.menu_active_bg); << FColorPair(wc.menu_active_fg, wc.menu_active_bg);
@ -1270,21 +1232,22 @@ inline void FMenu::drawSeparator (int y)
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
inline void FMenu::drawMenuLine (FMenuItem* menuitem, int y) inline void FMenu::drawMenuLine (FMenuItem* m_item, int y)
{ {
FString txt(menuitem->getText()); FString txt(m_item->getText());
menuText txtdata{}; menuText txtdata{};
std::size_t txt_length = txt.getLength(); std::size_t txt_length = txt.getLength();
std::size_t to_char = txt_length; std::size_t to_char = txt_length;
FKey accel_key = menuitem->accel_key; std::size_t column_width = getColumnWidth(txt);
bool is_enabled = menuitem->isEnabled(); FKey accel_key = m_item->accel_key;
bool is_selected = menuitem->isSelected(); bool is_enabled = m_item->isEnabled();
bool is_selected = m_item->isSelected();
// Set screen position and attributes // Set screen position and attributes
setLineAttributes (menuitem, y); setLineAttributes (m_item, y);
// Draw check mark prefix for checkable items // Draw check mark prefix for checkable items
drawCheckMarkPrefix (menuitem); drawCheckMarkPrefix (m_item);
// Print leading blank space // Print leading blank space
print (' '); print (' ');
@ -1302,11 +1265,14 @@ inline void FMenu::drawMenuLine (FMenuItem* menuitem, int y)
hotkeypos = finalcut::getHotkeyPos(txt.wc_str(), txtdata.text, txt_length); hotkeypos = finalcut::getHotkeyPos(txt.wc_str(), txtdata.text, txt_length);
if ( hotkeypos != NOT_SET ) if ( hotkeypos != NOT_SET )
{
to_char--; to_char--;
column_width--;
}
txtdata.length = to_char; txtdata.length = to_char;
txtdata.no_underline = menuitem->getFlags().no_underline; txtdata.no_underline = m_item->getFlags().no_underline;
setCursorToHotkeyPosition (menuitem); setCursorToHotkeyPosition (m_item);
if ( ! is_enabled || is_selected ) if ( ! is_enabled || is_selected )
txtdata.hotkeypos = NOT_SET; txtdata.hotkeypos = NOT_SET;
@ -1315,14 +1281,14 @@ inline void FMenu::drawMenuLine (FMenuItem* menuitem, int y)
drawMenuText (txtdata); drawMenuText (txtdata);
if ( menuitem->hasMenu() ) if ( m_item->hasMenu() )
drawSubMenuIndicator (to_char); drawSubMenuIndicator (column_width);
else if ( accel_key ) else if ( accel_key )
drawAcceleratorKey (to_char, accel_key); drawAcceleratorKey (column_width, accel_key);
// Draw the trailing spaces of the selected line // Draw the trailing spaces of the selected line
if ( is_selected ) if ( is_selected )
drawTrailingSpaces (to_char); drawTrailingSpaces (column_width);
if ( isMonochron() && is_enabled && is_selected ) if ( isMonochron() && is_enabled && is_selected )
setReverse(true); setReverse(true);
@ -1331,11 +1297,11 @@ inline void FMenu::drawMenuLine (FMenuItem* menuitem, int y)
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
inline void FMenu::drawCheckMarkPrefix (FMenuItem* menuitem) inline void FMenu::drawCheckMarkPrefix (FMenuItem* m_item)
{ {
bool is_checked = menuitem->isChecked(); bool is_checked = m_item->isChecked();
bool is_checkable = menuitem->checkable; bool is_checkable = m_item->checkable;
bool is_radio_btn = menuitem->radio_button; bool is_radio_btn = m_item->radio_button;
if ( ! has_checkable_items ) if ( ! has_checkable_items )
return; return;
@ -1361,7 +1327,7 @@ inline void FMenu::drawCheckMarkPrefix (FMenuItem* menuitem)
} }
else else
{ {
const FWidgetColors& wc = getFWidgetColors(); const auto& wc = getFWidgetColors();
setColor (wc.menu_inactive_fg, getBackgroundColor()); setColor (wc.menu_inactive_fg, getBackgroundColor());
if ( getEncoding() == fc::ASCII ) if ( getEncoding() == fc::ASCII )
@ -1383,7 +1349,7 @@ inline void FMenu::drawMenuText (menuText& data)
for (std::size_t z{0}; z < data.length; z++) for (std::size_t z{0}; z < data.length; z++)
{ {
if ( ! std::iswprint(wint_t(data.text[z])) ) if ( ! std::iswprint(std::wint_t(data.text[z])) )
{ {
if ( ! isNewFont() if ( ! isNewFont()
&& ( int(data.text[z]) < fc::NF_rev_left_arrow2 && ( int(data.text[z]) < fc::NF_rev_left_arrow2
@ -1396,7 +1362,7 @@ inline void FMenu::drawMenuText (menuText& data)
if ( z == data.hotkeypos ) if ( z == data.hotkeypos )
{ {
const FWidgetColors& wc = getFWidgetColors(); const auto& wc = getFWidgetColors();
setColor (wc.menu_hotkey_fg, wc.menu_hotkey_bg); setColor (wc.menu_hotkey_fg, wc.menu_hotkey_bg);
if ( ! data.no_underline ) if ( ! data.no_underline )
@ -1458,11 +1424,11 @@ inline void FMenu::drawTrailingSpaces (std::size_t startpos)
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
inline void FMenu::setLineAttributes (FMenuItem* menuitem, int y) inline void FMenu::setLineAttributes (FMenuItem* m_item, int y)
{ {
bool is_enabled = menuitem->isEnabled(); bool is_enabled = m_item->isEnabled();
bool is_selected = menuitem->isSelected(); bool is_selected = m_item->isSelected();
const FWidgetColors& wc = getFWidgetColors(); const auto& wc = getFWidgetColors();
if ( is_enabled ) if ( is_enabled )
{ {
@ -1497,10 +1463,10 @@ inline void FMenu::setLineAttributes (FMenuItem* menuitem, int y)
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
inline void FMenu::setCursorToHotkeyPosition (FMenuItem* menuitem) inline void FMenu::setCursorToHotkeyPosition (FMenuItem* m_item)
{ {
bool is_checkable = menuitem->checkable; bool is_checkable = m_item->checkable;
bool is_selected = menuitem->isSelected(); bool is_selected = m_item->isSelected();
if ( hotkeypos == NOT_SET ) if ( hotkeypos == NOT_SET )
{ {
@ -1508,9 +1474,9 @@ inline void FMenu::setCursorToHotkeyPosition (FMenuItem* menuitem)
if ( is_selected ) if ( is_selected )
{ {
if ( is_checkable ) if ( is_checkable )
menuitem->setCursorPos (FPoint(3, 1)); m_item->setCursorPos (FPoint(3, 1));
else else
menuitem->setCursorPos (FPoint(2, 1)); m_item->setCursorPos (FPoint(2, 1));
} }
} }
else else
@ -1518,28 +1484,18 @@ inline void FMenu::setCursorToHotkeyPosition (FMenuItem* menuitem)
if ( is_selected ) if ( is_selected )
{ {
// set cursor to the hotkey position // set cursor to the hotkey position
auto x = getColumnWidth (m_item->getText(), hotkeypos);
if ( is_checkable ) if ( is_checkable )
menuitem->setCursorPos (FPoint(3 + int(hotkeypos), 1)); m_item->setCursorPos (FPoint(3 + int(x), 1));
else else
menuitem->setCursorPos (FPoint(2 + int(hotkeypos), 1)); m_item->setCursorPos (FPoint(2 + int(x), 1));
} }
} }
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
inline void FMenu::keyUp() inline void FMenu::selectPrevMenu (FKeyEvent* ev)
{
selectPrevItem();
}
//----------------------------------------------------------------------
inline void FMenu::keyDown()
{
selectNextItem();
}
//----------------------------------------------------------------------
inline void FMenu::keyLeft (FKeyEvent* ev)
{ {
if ( isSubMenu() ) if ( isSubMenu() )
{ {
@ -1563,7 +1519,7 @@ inline void FMenu::keyLeft (FKeyEvent* ev)
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
inline void FMenu::keyRight (FKeyEvent* ev) inline void FMenu::selectNextMenu (FKeyEvent* ev)
{ {
if ( hasSelectedItem() && getSelectedItem()->hasMenu() ) if ( hasSelectedItem() && getSelectedItem()->hasMenu() )
{ {
@ -1579,7 +1535,7 @@ inline void FMenu::keyRight (FKeyEvent* ev)
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
inline void FMenu::keyEnter() inline void FMenu::acceptSelection()
{ {
if ( ! hasSelectedItem() ) if ( ! hasSelectedItem() )
return; return;
@ -1598,7 +1554,7 @@ inline void FMenu::keyEnter()
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
inline void FMenu::keyEscape() inline void FMenu::closeMenu()
{ {
unselectItem(); unselectItem();
hideSubMenus(); hideSubMenus();

View File

@ -65,7 +65,7 @@ void FMenuBar::resetMenu()
void FMenuBar::hide() void FMenuBar::hide()
{ {
FWindow::hide(); FWindow::hide();
const FWidgetColors& wc = getFWidgetColors(); const auto& wc = getFWidgetColors();
FColor fg = wc.term_fg; FColor fg = wc.term_fg;
FColor bg = wc.term_bg; FColor bg = wc.term_bg;
setColor (fg, bg); setColor (fg, bg);
@ -250,7 +250,7 @@ void FMenuBar::init()
addAccelerator (fc::Fkey_f10); addAccelerator (fc::Fkey_f10);
addAccelerator (fc::Fckey_space); addAccelerator (fc::Fckey_space);
const FWidgetColors& wc = getFWidgetColors(); const auto& wc = getFWidgetColors();
setForegroundColor (wc.menu_active_fg); setForegroundColor (wc.menu_active_fg);
setBackgroundColor (wc.menu_active_bg); setBackgroundColor (wc.menu_active_bg);
unsetFocusable(); unsetFocusable();
@ -260,26 +260,21 @@ void FMenuBar::init()
void FMenuBar::calculateDimensions() void FMenuBar::calculateDimensions()
{ {
FPoint item_pos (1, 1); FPoint item_pos (1, 1);
auto list = getItemList();
auto iter = list.begin();
auto last = list.end();
// find the maximum item width // find the maximum item width
while ( iter != last ) for (auto&& item : getItemList())
{ {
std::size_t len = (*iter)->getTextLength(); int len = int(item->getTextWidth());
int item_width = int(len) + 2; int item_width = len + 2;
// set item geometry // set item geometry
(*iter)->setGeometry (item_pos, FSize(std::size_t(item_width), 1), false); item->setGeometry (item_pos, FSize(std::size_t(item_width), 1), false);
// set menu position // set menu position
if ( (*iter)->hasMenu() ) if ( item->hasMenu() )
(*iter)->getMenu()->setPos (item_pos, false); item->getMenu()->setPos (item_pos, false);
item_pos.x_ref() += item_width; item_pos.x_ref() += item_width;
++iter;
} }
} }
@ -288,9 +283,8 @@ bool FMenuBar::selectNextItem()
{ {
auto list = getItemList(); auto list = getItemList();
auto iter = list.begin(); auto iter = list.begin();
auto last = list.end();
while ( iter != last ) while ( iter != list.end() )
{ {
if ( (*iter)->isSelected() ) if ( (*iter)->isSelected() )
{ {
@ -351,7 +345,6 @@ bool FMenuBar::selectPrevItem()
{ {
auto list = getItemList(); auto list = getItemList();
auto iter = list.end(); auto iter = list.end();
auto first = list.begin();
do do
{ {
@ -405,7 +398,7 @@ bool FMenuBar::selectPrevItem()
break; break;
} }
} }
while ( iter != first ); while ( iter != list.begin() );
return true; return true;
} }
@ -413,18 +406,17 @@ bool FMenuBar::selectPrevItem()
//---------------------------------------------------------------------- //----------------------------------------------------------------------
bool FMenuBar::hotkeyMenu (FKeyEvent*& ev) bool FMenuBar::hotkeyMenu (FKeyEvent*& ev)
{ {
auto list = getItemList(); for (auto&& item : getItemList())
auto iter = list.begin();
auto last = list.end();
while ( iter != last )
{ {
if ( (*iter)->isEnabled() ) if ( item->isEnabled() )
{ {
uChar hotkey = (*iter)->getHotkey(); FKey hotkey = item->getHotkey();
FKey key = ev->key(); FKey key = ev->key();
if ( fc::Fmkey_meta + FKey(std::tolower(hotkey)) == key ) if ( hotkey > 0xff00 && hotkey < 0xff5f ) // full-width character
hotkey -= 0xfee0;
if ( fc::Fmkey_meta + FKey(std::tolower(int(hotkey))) == key )
{ {
auto sel_item = getSelectedItem(); auto sel_item = getSelectedItem();
@ -433,13 +425,13 @@ bool FMenuBar::hotkeyMenu (FKeyEvent*& ev)
unselectItem(); unselectItem();
if ( (*iter)->hasMenu() ) if ( item->hasMenu() )
{ {
auto menu = (*iter)->getMenu(); auto menu = item->getMenu();
(*iter)->setSelected(); item->setSelected();
setSelectedItem(*iter); setSelectedItem(item);
(*iter)->setFocus(); item->setFocus();
(*iter)->openMenu(); item->openMenu();
menu->selectFirstItem(); menu->selectFirstItem();
auto first_item = menu->getSelectedItem(); auto first_item = menu->getSelectedItem();
@ -459,15 +451,13 @@ bool FMenuBar::hotkeyMenu (FKeyEvent*& ev)
setSelectedItem(nullptr); setSelectedItem(nullptr);
redraw(); redraw();
drop_down = false; drop_down = false;
(*iter)->processClicked(); item->processClicked();
} }
ev->accept(); ev->accept();
return true; return true;
} }
} }
++iter;
} }
return false; return false;
@ -493,15 +483,10 @@ void FMenuBar::drawItems()
setReverse(true); setReverse(true);
screenWidth = getDesktopWidth(); screenWidth = getDesktopWidth();
auto iter = list.begin();
auto last = list.end();
std::size_t x{1}; std::size_t x{1};
while ( iter != last ) for (auto&& item : list)
{ drawItem (item, x);
drawItem (*iter, x);
++iter;
}
// Print spaces to end of line // Print spaces to end of line
for (; x <= screenWidth; x++) for (; x <= screenWidth; x++)
@ -520,6 +505,7 @@ inline void FMenuBar::drawItem (FMenuItem* menuitem, std::size_t& x)
FString txt(menuitem->getText()); FString txt(menuitem->getText());
std::size_t to_char{}; std::size_t to_char{};
std::size_t txt_length = txt.getLength(); std::size_t txt_length = txt.getLength();
std::size_t column_width = getColumnWidth(txt);
bool is_enabled = menuitem->isEnabled(); bool is_enabled = menuitem->isEnabled();
bool is_selected = menuitem->isSelected(); bool is_selected = menuitem->isSelected();
@ -549,22 +535,24 @@ inline void FMenuBar::drawItem (FMenuItem* menuitem, std::size_t& x)
if ( hotkeypos != NOT_SET ) if ( hotkeypos != NOT_SET )
{ {
txt_length--; txt_length--;
column_width--;
to_char--; to_char--;
} }
txtdata.length = to_char; txtdata.length = to_char;
x += txt_length; x += column_width;
if ( ! is_enabled || is_selected ) if ( ! is_enabled || is_selected )
txtdata.hotkeypos = NOT_SET; txtdata.hotkeypos = NOT_SET;
else else
txtdata.hotkeypos = hotkeypos; txtdata.hotkeypos = hotkeypos;
setCursorToHotkeyPosition (menuitem, hotkeypos);
drawMenuText (txtdata); drawMenuText (txtdata);
drawEllipsis (txtdata, x); drawEllipsis (txtdata, x);
drawTrailingSpace (x); drawTrailingSpace (x);
const FWidgetColors& wc = getFWidgetColors(); const auto& wc = getFWidgetColors();
setColor (wc.menu_active_fg, wc.menu_active_bg); setColor (wc.menu_active_fg, wc.menu_active_bg);
if ( isMonochron() && is_enabled && is_selected ) if ( isMonochron() && is_enabled && is_selected )
@ -578,7 +566,7 @@ inline void FMenuBar::setLineAttributes (FMenuItem* menuitem)
{ {
bool is_enabled = menuitem->isEnabled(); bool is_enabled = menuitem->isEnabled();
bool is_selected = menuitem->isSelected(); bool is_selected = menuitem->isSelected();
const FWidgetColors& wc = getFWidgetColors(); const auto& wc = getFWidgetColors();
if ( is_enabled ) if ( is_enabled )
{ {
@ -605,6 +593,25 @@ inline void FMenuBar::setLineAttributes (FMenuItem* menuitem)
setColor(); setColor();
} }
//----------------------------------------------------------------------
inline void FMenuBar::setCursorToHotkeyPosition ( FMenuItem* menuitem
, std::size_t hotkeypos )
{
if ( ! menuitem->isSelected() )
return;
if ( hotkeypos == NOT_SET )
{
// set cursor to the first character
menuitem->setCursorPos (FPoint(2, 1));
return;
}
// set cursor to the hotkey position
std::size_t x = getColumnWidth (menuitem->getText(), hotkeypos);
menuitem->setCursorPos (FPoint(2 + int(x), 1));
}
//---------------------------------------------------------------------- //----------------------------------------------------------------------
inline void FMenuBar::drawMenuText (menuText& data) inline void FMenuBar::drawMenuText (menuText& data)
{ {
@ -615,7 +622,7 @@ inline void FMenuBar::drawMenuText (menuText& data)
if ( data.startpos > screenWidth - z ) if ( data.startpos > screenWidth - z )
break; break;
if ( ! std::iswprint(wint_t(data.text[z])) ) if ( ! std::iswprint(std::wint_t(data.text[z])) )
{ {
if ( ! isNewFont() if ( ! isNewFont()
&& ( int(data.text[z]) < fc::NF_rev_left_arrow2 && ( int(data.text[z]) < fc::NF_rev_left_arrow2
@ -627,7 +634,7 @@ inline void FMenuBar::drawMenuText (menuText& data)
if ( z == data.hotkeypos ) if ( z == data.hotkeypos )
{ {
const FWidgetColors& wc = getFWidgetColors(); const auto& wc = getFWidgetColors();
setColor (wc.menu_hotkey_fg, wc.menu_hotkey_bg); setColor (wc.menu_hotkey_fg, wc.menu_hotkey_bg);
if ( ! data.no_underline ) if ( ! data.no_underline )
@ -692,18 +699,15 @@ void FMenuBar::adjustItems()
{ {
int item_X = 1; int item_X = 1;
int item_Y = 1; int item_Y = 1;
auto list = getItemList();
auto iter = list.begin();
auto last = list.end();
while ( iter != last ) for (auto&& item : getItemList())
{ {
// get item width // get item width
int item_width = int((*iter)->getWidth()); int item_width = int(item->getWidth());
if ( (*iter)->hasMenu() ) if ( item->hasMenu() )
{ {
auto menu = (*iter)->getMenu(); auto menu = item->getMenu();
// set menu position // set menu position
menu->setPos (FPoint(menu->adjustX(item_X), item_Y)); menu->setPos (FPoint(menu->adjustX(item_X), item_Y));
@ -713,7 +717,6 @@ void FMenuBar::adjustItems()
} }
item_X += item_width; item_X += item_width;
++iter;
} }
} }
@ -817,30 +820,21 @@ void FMenuBar::mouseDownOverList (const FMouseEvent* ev)
return; return;
focus_changed = false; focus_changed = false;
auto iter = list.begin();
auto last = list.end();
int mouse_x = ev->getX(); int mouse_x = ev->getX();
int mouse_y = ev->getY(); int mouse_y = ev->getY();
while ( iter != last ) for (auto&& item : list)
{ {
int x1 = (*iter)->getX(); int x1 = item->getX();
int x2 = (*iter)->getX() + int((*iter)->getWidth()); int x2 = item->getX() + int(item->getWidth());
if ( mouse_y == 1 ) if ( mouse_y == 1 )
{ {
if ( mouse_x >= x1 && mouse_x < x2 ) if ( mouse_x >= x1 && mouse_x < x2 )
{ selectMenuItem (item); // Mouse pointer over item
// Mouse pointer over item
selectMenuItem (*iter);
}
else else
{ unselectMenuItem (item);
unselectMenuItem (*iter);
}
} }
++iter;
} }
if ( getStatusBar() ) if ( getStatusBar() )
@ -866,36 +860,32 @@ void FMenuBar::mouseUpOverList (const FMouseEvent* ev)
if ( list.empty() ) if ( list.empty() )
return; return;
auto iter = list.begin();
auto last = list.end();
int mouse_x = ev->getX(); int mouse_x = ev->getX();
int mouse_y = ev->getY(); int mouse_y = ev->getY();
while ( iter != last ) for (auto&& item : list)
{ {
int x1 = (*iter)->getX(); int x1 = item->getX();
int x2 = (*iter)->getX() + int((*iter)->getWidth()); int x2 = item->getX() + int(item->getWidth());
if ( mouse_y == 1 if ( mouse_y == 1
&& mouse_x >= x1 && mouse_x >= x1
&& mouse_x < x2 && mouse_x < x2
&& (*iter)->isEnabled() && item->isEnabled()
&& (*iter)->isSelected() ) && item->isSelected() )
{ {
// Mouse pointer over item // Mouse pointer over item
if ( ! activateMenu(*iter) ) if ( ! activateMenu(item) )
{ {
if ( clickItem(*iter) ) if ( clickItem(item) )
return; return;
} }
} }
else else
{ {
unselectMenuItem(*iter); unselectMenuItem(item);
redraw(); redraw();
} }
++iter;
} }
if ( ! hasSelectedItem() ) if ( ! hasSelectedItem() )
@ -912,32 +902,30 @@ void FMenuBar::mouseMoveOverList (const FMouseEvent* ev)
focus_changed = false; focus_changed = false;
bool mouse_over_menubar{false}; bool mouse_over_menubar{false};
auto iter = list.begin();
auto last = list.end();
int mouse_x = ev->getX(); int mouse_x = ev->getX();
int mouse_y = ev->getY(); int mouse_y = ev->getY();
if ( getTermGeometry().contains(ev->getTermPos()) ) if ( getTermGeometry().contains(ev->getTermPos()) )
mouse_over_menubar = true; mouse_over_menubar = true;
while ( iter != last ) for (auto&& item : list)
{ {
int x1 = (*iter)->getX(); int x1 = item->getX();
int x2 = (*iter)->getX() + int((*iter)->getWidth()); int x2 = item->getX() + int(item->getWidth());
if ( mouse_x >= x1 if ( mouse_x >= x1
&& mouse_x < x2 && mouse_x < x2
&& mouse_y == 1 ) && mouse_y == 1 )
{ {
// Mouse pointer over item // Mouse pointer over item
selectMenuItem(*iter); selectMenuItem(item);
} }
else else
{ {
if ( mouse_over_menubar ) if ( mouse_over_menubar )
{ {
// Unselect selected item without mouse focus // Unselect selected item without mouse focus
unselectMenuItem(*iter); unselectMenuItem(item);
} }
else else
{ {
@ -945,8 +933,6 @@ void FMenuBar::mouseMoveOverList (const FMouseEvent* ev)
passEventToMenu(ev); passEventToMenu(ev);
} }
} }
++iter;
} }
if ( getStatusBar() ) if ( getStatusBar() )

View File

@ -94,7 +94,7 @@ bool FMenuItem::setEnable (bool enable)
if ( super && isMenuBar(super) ) if ( super && isMenuBar(super) )
{ {
// Meta + hotkey // Meta + hotkey
super->addAccelerator ( fc::Fmkey_meta + FKey(std::tolower(hotkey)) super->addAccelerator ( fc::Fmkey_meta + FKey(std::tolower(int(hotkey)))
, this ); , this );
} }
} }
@ -190,10 +190,14 @@ void FMenuItem::setText (const FString& txt)
{ {
text.setString(txt); text.setString(txt);
text_length = text.getLength(); text_length = text.getLength();
hotkey = hotKey(); text_width = getColumnWidth(txt);
hotkey = finalcut::getHotkey(text);
if ( hotkey ) if ( hotkey )
{
text_length--; text_length--;
text_width--;
}
updateSuperMenuDimensions(); updateSuperMenuDimensions();
} }
@ -524,12 +528,19 @@ FMenuList* FMenuItem::getFMenuList (FWidget& widget)
void FMenuItem::init (FWidget* parent) void FMenuItem::init (FWidget* parent)
{ {
text_length = text.getLength(); text_length = text.getLength();
hotkey = hotKey(); text_width = getColumnWidth(text);
hotkey = finalcut::getHotkey(text);
if ( hotkey > 0xff00 && hotkey < 0xff5f ) // full-width character
hotkey -= 0xfee0;
if ( hotkey ) if ( hotkey )
{
text_length--; text_length--;
text_width--;
}
setGeometry (FPoint(1, 1), FSize(text_length + 2, 1), false); setGeometry (FPoint(1, 1), FSize(text_width + 2, 1), false);
if ( ! parent ) if ( ! parent )
return; return;
@ -550,7 +561,7 @@ void FMenuItem::init (FWidget* parent)
menubar_ptr->calculateDimensions(); menubar_ptr->calculateDimensions();
if ( hotkey ) // Meta + hotkey if ( hotkey ) // Meta + hotkey
menubar_ptr->addAccelerator ( fc::Fmkey_meta + FKey(std::tolower(hotkey)) menubar_ptr->addAccelerator ( fc::Fmkey_meta + FKey(std::tolower(int(hotkey)))
, this ); , this );
addCallback // for this element addCallback // for this element
@ -566,30 +577,6 @@ void FMenuItem::init (FWidget* parent)
} }
} }
//----------------------------------------------------------------------
uChar FMenuItem::hotKey()
{
if ( text.isEmpty() )
return 0;
std::size_t length = text.getLength();
for (std::size_t i{0}; i < length; i++)
{
try
{
if ( i + 1 < length && text[i] == '&' )
return uChar(text[++i]);
}
catch (const std::out_of_range&)
{
return 0;
}
}
return 0;
}
//---------------------------------------------------------------------- //----------------------------------------------------------------------
void FMenuItem::updateSuperMenuDimensions() void FMenuItem::updateSuperMenuDimensions()
{ {

View File

@ -61,7 +61,6 @@ FMessageBox::FMessageBox (const FMessageBox& mbox)
, headline_text(mbox.headline_text) , headline_text(mbox.headline_text)
, text(mbox.text) , text(mbox.text)
, text_components(mbox.text_components) , text_components(mbox.text_components)
, text_split(mbox.text_split)
, max_line_width(mbox.max_line_width) , max_line_width(mbox.max_line_width)
, emphasis_color(mbox.emphasis_color) , emphasis_color(mbox.emphasis_color)
, num_buttons(mbox.num_buttons) , num_buttons(mbox.num_buttons)
@ -114,7 +113,6 @@ FMessageBox& FMessageBox::operator = (const FMessageBox& mbox)
headline_text = mbox.headline_text; headline_text = mbox.headline_text;
text = mbox.text; text = mbox.text;
text_components = mbox.text_components; text_components = mbox.text_components;
text_split = mbox.text_split;
max_line_width = mbox.max_line_width; max_line_width = mbox.max_line_width;
center_text = mbox.center_text; center_text = mbox.center_text;
emphasis_color = mbox.emphasis_color; emphasis_color = mbox.emphasis_color;
@ -139,10 +137,10 @@ void FMessageBox::setHeadline (const FString& headline)
for (uInt n{0}; n < num_buttons; n++) for (uInt n{0}; n < num_buttons; n++)
button[n]->setY (int(getHeight()) - 4, false); button[n]->setY (int(getHeight()) - 4, false);
std::size_t len = headline_text.getLength(); std::size_t column_width = getColumnWidth(headline_text);
if ( len > max_line_width ) if ( column_width > max_line_width )
max_line_width = len; max_line_width = column_width;
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
@ -311,9 +309,9 @@ void FMessageBox::calculateDimensions()
{ {
FSize size{}; FSize size{};
std::size_t headline_height{0}; std::size_t headline_height{0};
text_split = text.split("\n"); text_components = text.split("\n");
max_line_width = 0; max_line_width = 0;
text_num_lines = uInt(text_split.size()); text_num_lines = std::size_t(text_components.size());
if ( text_num_lines == 0 ) if ( text_num_lines == 0 )
return; return;
@ -321,13 +319,12 @@ void FMessageBox::calculateDimensions()
if ( ! headline_text.isNull() ) if ( ! headline_text.isNull() )
headline_height = 2; headline_height = 2;
for (uInt i{0}; i < text_num_lines; i++) for (auto&& line : text_components)
{ {
text_components = &text_split[0]; std::size_t column_width = getColumnWidth(line);
std::size_t len = text_components[i].getLength();
if ( len > max_line_width ) if ( column_width > max_line_width )
max_line_width = len; max_line_width = column_width;
} }
size.setHeight (text_num_lines + 8 + headline_height); size.setHeight (text_num_lines + 8 + headline_height);
@ -344,21 +341,22 @@ void FMessageBox::draw()
{ {
FDialog::draw(); FDialog::draw();
int head_offset = 0; int y{0};
int center_x = 0; int head_offset{0};
int center_x{0};
// center the whole block // center the whole block
int msg_x = int((getWidth() - max_line_width) / 2); int msg_x = int((getWidth() - max_line_width) / 2);
if ( isMonochron() ) if ( isMonochron() )
setReverse(true); setReverse(true);
if ( ! headline_text.isNull() ) if ( ! headline_text.isEmpty() )
{ {
setColor(emphasis_color, getBackgroundColor()); setColor(emphasis_color, getBackgroundColor());
std::size_t headline_length = headline_text.getLength(); std::size_t headline_width = getColumnWidth(headline_text);
if ( center_text ) // center one line if ( center_text ) // center one line
center_x = int((max_line_width - headline_length) / 2); center_x = int((max_line_width - headline_width) / 2);
print() << FPoint(1 + msg_x + center_x, 4) << headline_text; print() << FPoint(1 + msg_x + center_x, 4) << headline_text;
head_offset = 2; head_offset = 2;
@ -366,15 +364,16 @@ void FMessageBox::draw()
setColor(); setColor();
for (int i{0}; i < int(text_num_lines); i++) for (auto&& line : text_components)
{ {
std::size_t line_length = text_components[i].getLength(); std::size_t line_width = getColumnWidth(line);
if ( center_text ) // center one line if ( center_text ) // center one line
center_x = int((max_line_width - line_length) / 2); center_x = int((max_line_width - line_width) / 2);
print() << FPoint(1 + msg_x + center_x, 4 + head_offset + i) print() << FPoint(1 + msg_x + center_x, 4 + head_offset + y)
<< text_components[i]; << line;
y++;
} }
if ( isMonochron() ) if ( isMonochron() )

View File

@ -1220,10 +1220,10 @@ inline bool FOptiAttr::hasColorChanged (charData*& term, charData*& next)
{ {
if ( term && next ) if ( term && next )
{ {
bool frev = ( on.attr.bit.reverse bool frev ( ( on.attr.bit.reverse
|| on.attr.bit.standout || on.attr.bit.standout
|| off.attr.bit.reverse || off.attr.bit.reverse
|| off.attr.bit.standout ) && fake_reverse; || off.attr.bit.standout ) && fake_reverse );
return bool ( frev return bool ( frev
|| term->fg_color != next->fg_color || term->fg_color != next->fg_color
|| term->bg_color != next->bg_color ); || term->bg_color != next->bg_color );
@ -1483,10 +1483,10 @@ inline void FOptiAttr::change_current_color ( charData*& term
auto& Sf = F_set_foreground.cap; auto& Sf = F_set_foreground.cap;
auto& Sb = F_set_background.cap; auto& Sb = F_set_background.cap;
auto& sp = F_set_color_pair.cap; auto& sp = F_set_color_pair.cap;
bool frev = ( off.attr.bit.reverse bool frev ( ( off.attr.bit.reverse
|| off.attr.bit.standout || off.attr.bit.standout
|| term->attr.bit.reverse || term->attr.bit.reverse
|| term->attr.bit.standout ) && fake_reverse; || term->attr.bit.standout ) && fake_reverse );
if ( AF && AB ) if ( AF && AB )
{ {

View File

@ -146,7 +146,7 @@ void FProgressbar::drawProgressLabel()
, parent_widget->getBackgroundColor() ); , parent_widget->getBackgroundColor() );
else else
{ {
const FWidgetColors& wc = getFWidgetColors(); const auto& wc = getFWidgetColors();
setColor ( wc.dialog_fg, wc.dialog_bg ); setColor ( wc.dialog_fg, wc.dialog_bg );
} }
@ -192,7 +192,7 @@ std::size_t FProgressbar::drawProgressIndicator()
double length = double(bar_length * percentage) / 100; double length = double(bar_length * percentage) / 100;
auto len = std::size_t(trunc(length)); auto len = std::size_t(trunc(length));
const FWidgetColors& wc = getFWidgetColors(); const auto& wc = getFWidgetColors();
print() << FColorPair (wc.progressbar_fg, wc.progressbar_fg) print() << FColorPair (wc.progressbar_fg, wc.progressbar_fg)
<< FString (len, fc::FullBlock); // █ << FString (len, fc::FullBlock); // █
@ -225,7 +225,7 @@ void FProgressbar::drawProgressBackground (std::size_t len)
// Draw the progress background // Draw the progress background
std::size_t bg_len = bar_length - len; std::size_t bg_len = bar_length - len;
const FWidgetColors& wc = getFWidgetColors(); const auto& wc = getFWidgetColors();
setColor (wc.progressbar_fg, wc.progressbar_bg); setColor (wc.progressbar_fg, wc.progressbar_bg);
if ( getMaxColor() < 16 ) if ( getMaxColor() < 16 )

View File

@ -472,7 +472,7 @@ void FScrollbar::draw()
//---------------------------------------------------------------------- //----------------------------------------------------------------------
void FScrollbar::drawVerticalBar() void FScrollbar::drawVerticalBar()
{ {
const FWidgetColors& wc = getFWidgetColors(); const auto& wc = getFWidgetColors();
setColor (wc.scrollbar_fg, wc.scrollbar_bg); setColor (wc.scrollbar_fg, wc.scrollbar_bg);
for (int z{1}; z <= slider_pos; z++) for (int z{1}; z <= slider_pos; z++)
@ -531,7 +531,7 @@ inline void FScrollbar::drawVerticalBackgroundLine()
//---------------------------------------------------------------------- //----------------------------------------------------------------------
void FScrollbar::drawHorizontalBar() void FScrollbar::drawHorizontalBar()
{ {
const FWidgetColors& wc = getFWidgetColors(); const auto& wc = getFWidgetColors();
setColor (wc.scrollbar_fg, wc.scrollbar_bg); setColor (wc.scrollbar_fg, wc.scrollbar_bg);
if ( isNewFont() ) if ( isNewFont() )
@ -577,7 +577,7 @@ inline void FScrollbar::drawHorizontalBackgroundColumn()
//---------------------------------------------------------------------- //----------------------------------------------------------------------
void FScrollbar::drawButtons() void FScrollbar::drawButtons()
{ {
const FWidgetColors& wc = getFWidgetColors(); const auto& wc = getFWidgetColors();
setColor (wc.scrollbar_button_fg, wc.scrollbar_button_bg); setColor (wc.scrollbar_button_fg, wc.scrollbar_button_bg);
if ( isNewFont() ) if ( isNewFont() )

View File

@ -373,8 +373,8 @@ void FScrollView::scrollTo (int x, int y)
if ( xoffset > xoffset_end ) if ( xoffset > xoffset_end )
xoffset = xoffset_end; xoffset = xoffset_end;
changeX = bool(xoffset_before != xoffset); changeX = bool( xoffset_before != xoffset );
changeY = bool(yoffset_before != yoffset); changeY = bool( yoffset_before != yoffset );
if ( ! isShown() || ! viewport || ! (changeX || changeY) ) if ( ! isShown() || ! viewport || ! (changeX || changeY) )
return; return;
@ -764,7 +764,7 @@ void FScrollView::init (FWidget* parent)
initScrollbar (vbar, fc::vertical, &FScrollView::cb_VBarChange); initScrollbar (vbar, fc::vertical, &FScrollView::cb_VBarChange);
initScrollbar (hbar, fc::horizontal, &FScrollView::cb_HBarChange); initScrollbar (hbar, fc::horizontal, &FScrollView::cb_HBarChange);
const FWidgetColors& wc = getFWidgetColors(); const auto& wc = getFWidgetColors();
setForegroundColor (wc.dialog_fg); setForegroundColor (wc.dialog_fg);
setBackgroundColor (wc.dialog_bg); setBackgroundColor (wc.dialog_bg);
setGeometry (FPoint(1, 1), FSize(4, 4)); setGeometry (FPoint(1, 1), FSize(4, 4));

100
src/fstartoptions.cpp Normal file
View File

@ -0,0 +1,100 @@
/***********************************************************************
* fstartoptions.cpp - Contains the start options for initialization *
* *
* This file is part of the Final Cut widget toolkit *
* *
* Copyright 2019 Markus Gans *
* *
* The 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 *
* the License, or (at your option) any later version. *
* *
* The Final Cut is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU 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/>. *
***********************************************************************/
#include "final/fstartoptions.h"
namespace finalcut
{
// static class attribute
FStartOptions* FStartOptions::start_options{};
//----------------------------------------------------------------------
// class FStartOptions
//----------------------------------------------------------------------
// constructors and destructor
//----------------------------------------------------------------------
FStartOptions::FStartOptions()
: cursor_optimisation{true}
, mouse_support{true}
, terminal_detection{true}
, color_change{true}
, vgafont{false}
, newfont{false}
, encoding{fc::UNKNOWN}
#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(UNIT_TEST)
, meta_sends_escape{true}
, change_cursorstyle{true}
#elif defined(__NetBSD__) || defined(__OpenBSD__)
, meta_sends_escape{true}
#endif
{ }
//----------------------------------------------------------------------
FStartOptions::~FStartOptions() // destructor
{
if ( start_options )
delete start_options;
}
// public methods of FStartOptions
//----------------------------------------------------------------------
FStartOptions& FStartOptions::getFStartOptions()
{
if ( start_options == 0 )
{
try
{
start_options = new FStartOptions;
}
catch (const std::bad_alloc& ex)
{
std::cerr << bad_alloc_str << ex.what() << std::endl;
std::abort();
}
}
return *start_options;
}
//----------------------------------------------------------------------
void FStartOptions::setDefault()
{
cursor_optimisation = true;
mouse_support = true;
terminal_detection = true;
color_change = true;
vgafont = false;
newfont = false;
encoding = fc::UNKNOWN;
#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(UNIT_TEST)
meta_sends_escape = true;
change_cursorstyle = true;
#elif defined(__NetBSD__) || defined(__OpenBSD__)
meta_sends_escape = true;
#endif
}
} // namespace finalcut

View File

@ -175,7 +175,7 @@ bool FStatusBar::hasActivatedKey()
void FStatusBar::hide() void FStatusBar::hide()
{ {
FWindow::hide(); FWindow::hide();
const FWidgetColors& wc = getFWidgetColors(); const auto& wc = getFWidgetColors();
FColor fg = wc.term_fg; FColor fg = wc.term_fg;
FColor bg = wc.term_bg; FColor bg = wc.term_bg;
setColor (fg, bg); setColor (fg, bg);
@ -196,7 +196,7 @@ void FStatusBar::drawMessage()
x = x_msg; x = x_msg;
int space_offset{1}; int space_offset{1};
bool hasKeys = bool(! key_list.empty()); bool hasKeys( ! key_list.empty() );
bool isLastActiveFocus{false}; bool isLastActiveFocus{false};
std::size_t termWidth = getDesktopWidth(); std::size_t termWidth = getDesktopWidth();
@ -212,7 +212,7 @@ void FStatusBar::drawMessage()
if ( isLastActiveFocus ) if ( isLastActiveFocus )
space_offset = 0; space_offset = 0;
const FWidgetColors& wc = getFWidgetColors(); const auto& wc = getFWidgetColors();
setColor (wc.statusbar_fg, wc.statusbar_bg); setColor (wc.statusbar_fg, wc.statusbar_bg);
setPrintPos (FPoint(x, 1)); setPrintPos (FPoint(x, 1));
@ -236,7 +236,7 @@ void FStatusBar::drawMessage()
print (' '); print (' ');
} }
std::size_t msg_length = getMessage().getLength(); auto msg_length = getColumnWidth(getMessage());
x += int(msg_length); x += int(msg_length);
if ( x - 1 <= int(termWidth) ) if ( x - 1 <= int(termWidth) )
@ -244,8 +244,9 @@ void FStatusBar::drawMessage()
else else
{ {
// Print ellipsis // Print ellipsis
print ( getMessage().left(msg_length + termWidth - uInt(x) - 1) ); std::size_t len = msg_length + termWidth - uInt(x) - 1;
print (".."); print() << getColumnSubString ( getMessage(), 1, len)
<< "..";
} }
} }
} }
@ -358,8 +359,8 @@ void FStatusBar::onMouseDown (FMouseEvent* ev)
while ( iter != last ) while ( iter != last )
{ {
int x1 = X int x1 = X
, kname_len = int(getKeyName((*iter)->getKey()).getLength()) , kname_len = getKeyNameWidth(*iter)
, txt_length = int((*iter)->getText().getLength()) , txt_length = getKeyTextWidth(*iter)
, x2 = x1 + kname_len + txt_length + 1 , x2 = x1 + kname_len + txt_length + 1
, mouse_x = ev->getX() , mouse_x = ev->getX()
, mouse_y = ev->getY(); , mouse_y = ev->getY();
@ -401,8 +402,8 @@ void FStatusBar::onMouseUp (FMouseEvent* ev)
while ( iter != last ) while ( iter != last )
{ {
int x1 = X int x1 = X
, kname_len = int(getKeyName((*iter)->getKey()).getLength()) , kname_len = getKeyNameWidth(*iter)
, txt_length = int((*iter)->getText().getLength()) , txt_length = getKeyTextWidth(*iter)
, x2 = x1 + kname_len + txt_length + 1; , x2 = x1 + kname_len + txt_length + 1;
if ( (*iter)->hasMouseFocus() ) if ( (*iter)->hasMouseFocus() )
@ -446,8 +447,8 @@ void FStatusBar::onMouseMove (FMouseEvent* ev)
while ( iter != last ) while ( iter != last )
{ {
int x1 = X int x1 = X
, kname_len = int(getKeyName((*iter)->getKey()).getLength()) , kname_len = getKeyNameWidth(*iter)
, txt_length = int((*iter)->getText().getLength()) , txt_length = getKeyTextWidth(*iter)
, x2 = x1 + kname_len + txt_length + 1 , x2 = x1 + kname_len + txt_length + 1
, mouse_x = ev->getX() , mouse_x = ev->getX()
, mouse_y = ev->getY(); , mouse_y = ev->getY();
@ -518,12 +519,26 @@ void FStatusBar::init()
if ( getRootWidget() ) if ( getRootWidget() )
getRootWidget()->setBottomPadding(1, true); getRootWidget()->setBottomPadding(1, true);
const FWidgetColors& wc = getFWidgetColors(); const auto& wc = getFWidgetColors();
setForegroundColor (wc.statusbar_fg); setForegroundColor (wc.statusbar_fg);
setBackgroundColor (wc.statusbar_bg); setBackgroundColor (wc.statusbar_bg);
unsetFocusable(); unsetFocusable();
} }
//----------------------------------------------------------------------
int FStatusBar::getKeyNameWidth (const FStatusKey* key)
{
const FString& key_name = getKeyName(key->getKey());
return int(getColumnWidth(key_name));
}
//----------------------------------------------------------------------
int FStatusBar::getKeyTextWidth (const FStatusKey* key)
{
const FString& key_text = key->getText();
return int(getColumnWidth(key_text));
}
//---------------------------------------------------------------------- //----------------------------------------------------------------------
void FStatusBar::draw() void FStatusBar::draw()
{ {
@ -549,22 +564,22 @@ void FStatusBar::drawKeys()
setReverse(true); setReverse(true);
auto iter = key_list.begin(); auto iter = key_list.begin();
auto last = key_list.end();
while ( iter != last ) while ( iter != key_list.end() )
{ {
keyname_len = int(getKeyName((*iter)->getKey()).getLength()); auto item = *iter;
keyname_len = getKeyNameWidth(item);
if ( x + keyname_len + 2 < int(screenWidth) ) if ( x + keyname_len + 2 < int(screenWidth) )
{ {
if ( (*iter)->isActivated() || (*iter)->hasMouseFocus() ) if ( item->isActivated() || item->hasMouseFocus() )
drawActiveKey (iter); drawActiveKey (iter);
else else
drawKey (iter); drawKey (iter);
} }
else else
{ {
const FWidgetColors& wc = getFWidgetColors(); const auto& wc = getFWidgetColors();
setColor (wc.statusbar_fg, wc.statusbar_bg); setColor (wc.statusbar_fg, wc.statusbar_bg);
for (; x <= int(screenWidth); x++) for (; x <= int(screenWidth); x++)
@ -586,7 +601,7 @@ void FStatusBar::drawKey (keyList::const_iterator iter)
// Draw not active key // Draw not active key
auto item = *iter; auto item = *iter;
const FWidgetColors& wc = getFWidgetColors(); const auto& wc = getFWidgetColors();
setColor (wc.statusbar_hotkey_fg, wc.statusbar_hotkey_bg); setColor (wc.statusbar_hotkey_fg, wc.statusbar_hotkey_bg);
x++; x++;
print (' '); print (' ');
@ -595,23 +610,22 @@ void FStatusBar::drawKey (keyList::const_iterator iter)
setColor (wc.statusbar_fg, wc.statusbar_bg); setColor (wc.statusbar_fg, wc.statusbar_bg);
x++; x++;
print ('-'); print ('-');
std::size_t txt_length = item->getText().getLength(); auto column_width = getColumnWidth (item->getText());
x += int(txt_length); x += int(column_width);
if ( x - 1 <= int(screenWidth) ) if ( x - 1 <= int(screenWidth) )
print (item->getText()); print (item->getText());
else else
{ {
// Print ellipsis // Print ellipsis
std::size_t len = txt_length + screenWidth - std::size_t(x) - 1; std::size_t len = column_width + screenWidth - std::size_t(x) - 1;
print (item->getText().left(len)); print() << getColumnSubString(item->getText(), 1, len)
print (".."); << "..";
} }
if ( iter + 1 != key_list.end() if ( iter + 1 != key_list.end()
&& ( (*(iter + 1))->isActivated() || (*(iter + 1))->hasMouseFocus() ) && ( (*(iter + 1))->isActivated() || (*(iter + 1))->hasMouseFocus() )
&& x + int(getKeyName((*(iter + 1))->getKey()).getLength()) + 3 && x + getKeyNameWidth(*(iter + 1)) + 3 < int(screenWidth) )
< int(screenWidth) )
{ {
// Next element is active // Next element is active
if ( isMonochron() ) if ( isMonochron() )
@ -649,7 +663,7 @@ void FStatusBar::drawActiveKey (keyList::const_iterator iter)
if ( isMonochron() ) if ( isMonochron() )
setReverse(false); setReverse(false);
const FWidgetColors& wc = getFWidgetColors(); const auto& wc = getFWidgetColors();
setColor ( wc.statusbar_active_hotkey_fg setColor ( wc.statusbar_active_hotkey_fg
, wc.statusbar_active_hotkey_bg ); , wc.statusbar_active_hotkey_bg );
x++; x++;
@ -659,8 +673,8 @@ void FStatusBar::drawActiveKey (keyList::const_iterator iter)
setColor (wc.statusbar_active_fg, wc.statusbar_active_bg); setColor (wc.statusbar_active_fg, wc.statusbar_active_bg);
x++; x++;
print ('-'); print ('-');
std::size_t txt_length = item->getText().getLength(); auto column_width = getColumnWidth (item->getText());
x += int(txt_length); x += int(column_width);
if ( x <= int(screenWidth) ) if ( x <= int(screenWidth) )
{ {
@ -671,9 +685,9 @@ void FStatusBar::drawActiveKey (keyList::const_iterator iter)
else else
{ {
// Print ellipsis // Print ellipsis
print ( item->getText() std::size_t len = column_width + screenWidth - std::size_t(x) - 1;
.left(txt_length + screenWidth - std::size_t(x) - 1) ); print() << getColumnSubString(item->getText(), 1, len)
print (".."); << "..";
} }
if ( isMonochron() ) if ( isMonochron() )

View File

@ -20,6 +20,7 @@
* <http://www.gnu.org/licenses/>. * * <http://www.gnu.org/licenses/>. *
***********************************************************************/ ***********************************************************************/
#include <algorithm>
#include <string> #include <string>
#include <utility> #include <utility>
#include <vector> #include <vector>
@ -417,7 +418,7 @@ std::size_t FString::getUTF8length() const
if ( ! string ) if ( ! string )
return 0; return 0;
std::size_t len = 0; std::size_t len{0};
const char* s = c_str(); const char* s = c_str();
while ( *s ) while ( *s )
@ -426,27 +427,6 @@ std::size_t FString::getUTF8length() const
return len; return len;
} }
//----------------------------------------------------------------------
FString& FString::sprintf (const FString format, ...)
{
static constexpr int BUFSIZE = 4096;
wchar_t buffer[BUFSIZE]{};
va_list args{};
if ( ! format )
{
clear();
return *this;
}
va_start (args, format);
std::vswprintf (buffer, BUFSIZE, format.wc_str(), args);
va_end (args);
_assign (buffer);
return *this;
}
//---------------------------------------------------------------------- //----------------------------------------------------------------------
FString FString::clear() FString FString::clear()
{ {
@ -511,17 +491,11 @@ const std::string FString::toString() const
FString FString::toLower() const FString FString::toLower() const
{ {
FString s(string); FString s(string);
wchar_t* p = s.string; auto to_lower = [] (wchar_t& c)
{
if ( p ) c = wchar_t(std::towlower(std::wint_t(c)));
{ };
while ( *p ) std::for_each (s.begin(), s.end(), to_lower);
{
*p = wchar_t(std::towlower(wint_t(*p)));
p++;
}
}
return s; return s;
} }
@ -529,17 +503,11 @@ FString FString::toLower() const
FString FString::toUpper() const FString FString::toUpper() const
{ {
FString s(string); FString s(string);
wchar_t* p = s.string; auto to_upper = [] (wchar_t& c)
{
if ( p ) c = wchar_t(std::towupper(std::wint_t(c)));
{ };
while ( *p ) std::for_each (s.begin(), s.end(), to_upper);
{
*p = wchar_t(std::towupper(wint_t(*p)));
p++;
}
}
return s; return s;
} }
@ -621,9 +589,9 @@ long FString::toLong() const
p++; p++;
} }
while ( std::iswdigit(wint_t(*p)) ) while ( std::iswdigit(std::wint_t(*p)) )
{ {
uChar d = uChar((*p) - L'0'); uChar d = uChar(*p - L'0');
if ( num > tenth_limit if ( num > tenth_limit
|| (num == tenth_limit && d > tenth_limit_digit) ) || (num == tenth_limit && d > tenth_limit_digit) )
@ -638,7 +606,7 @@ long FString::toLong() const
p++; p++;
} }
if ( *p != L'\0' && ! std::iswdigit(wint_t(*p)) ) if ( *p != L'\0' && ! std::iswdigit(std::wint_t(*p)) )
throw std::invalid_argument ("no valid number"); throw std::invalid_argument ("no valid number");
if ( neg ) if ( neg )
@ -671,9 +639,9 @@ uLong FString::toULong() const
p++; p++;
} }
while ( std::iswdigit(wint_t(*p)) ) while ( std::iswdigit(std::wint_t(*p)) )
{ {
uChar d = uChar((*p) - L'0'); uChar d = uChar(*p - L'0');
if ( num > tenth_limit if ( num > tenth_limit
|| (num == tenth_limit && d > tenth_limit_digit) ) || (num == tenth_limit && d > tenth_limit_digit) )
@ -685,7 +653,7 @@ uLong FString::toULong() const
p++; p++;
} }
if ( *p != L'\0' && ! std::iswdigit(wint_t(*p)) ) if ( *p != L'\0' && ! std::iswdigit(std::wint_t(*p)) )
throw std::invalid_argument ("no valid number"); throw std::invalid_argument ("no valid number");
return num; return num;
@ -743,7 +711,7 @@ FString FString::ltrim() const
const wchar_t* p = s.string; const wchar_t* p = s.string;
while ( std::iswspace(wint_t(*p)) ) while ( std::iswspace(std::wint_t(*p)) )
p++; p++;
return FString(p); return FString(p);
@ -761,10 +729,10 @@ FString FString::rtrim() const
wchar_t* p = s.string; wchar_t* p = s.string;
wchar_t* last = p + length; wchar_t* last = p + length;
while ( std::iswspace(wint_t(*--last)) && last > p ) while ( std::iswspace(std::wint_t(*--last)) && last > p )
s.length--; s.length--;
if ( last == p && std::iswspace(wint_t(*last)) ) if ( last == p && std::iswspace(std::wint_t(*last)) )
s = L""; s = L"";
else else
*(last + 1) = '\0'; *(last + 1) = '\0';
@ -1166,29 +1134,23 @@ FString FString::replace (const FString& from, const FString& to)
FString FString::replaceControlCodes() const FString FString::replaceControlCodes() const
{ {
FString s(string); FString s(string);
wchar_t* p = s.string;
if ( p ) for (auto&& c : s)
{ {
while ( *p ) if ( c <= L'\x1f' )
{ {
if ( *p <= L'\x1f' ) c += L'\x2400';
{
*p += L'\x2400';
}
else if ( *p == L'\x7f' )
{
*p = L'\x2421';
}
else if ( *p >= L'\x80' && *p <= L'\x9f' )
{
*p = L' ';
}
else if ( ! std::iswprint(wint_t(*p)) )
*p = L' ';
p++;
} }
else if ( c == L'\x7f' )
{
c = L'\x2421';
}
else if ( c >= L'\x80' && c <= L'\x9f' )
{
c = L' ';
}
else if ( ! std::iswprint(std::wint_t(c)) )
c = L' ';
} }
return s; return s;
@ -1224,36 +1186,28 @@ FString FString::expandTabs (int tabstop) const
FString FString::removeDel() const FString FString::removeDel() const
{ {
FString s(string); FString s(string);
const wchar_t* p = s.string; std::size_t i{0};
std::size_t count{0};
if ( p ) for (auto&& c : s)
{ {
uInt i{0}; if ( c == 0x7f )
uInt d{0};
while ( *p )
{ {
if ( *p == 0x7f ) count++;
{ }
d++; else if ( count > 0 )
} {
else if ( d > 0 ) count--;
{ }
d--; else // count == 0
} {
else s.string[i] = c;
{ i++;
s.string[i] = *p;
i++;
}
p++;
} }
s.string[i] = L'\0';
s.length = i;
} }
s.string[i] = L'\0';
s.length = i;
return s; return s;
} }
@ -1262,31 +1216,23 @@ FString FString::removeDel() const
FString FString::removeBackspaces() const FString FString::removeBackspaces() const
{ {
FString s(string); FString s(string);
const wchar_t* p = s.string; std::size_t i{0};
if ( p ) for (auto&& c : s)
{ {
uInt i = 0; if ( c != L'\b' )
while ( *p )
{ {
if ( *p != L'\b' ) s.string[i] = c;
{ i++;
s.string[i] = *p; }
i++; else if ( i > 0 )
} {
else if ( i > 0 ) i--;
{
i--;
}
p++;
} }
s.string[i] = L'\0';
s.length = i;
} }
s.string[i] = L'\0';
s.length = i;
return s; return s;
} }
@ -1367,7 +1313,7 @@ inline void FString::initLength (std::size_t len)
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
inline void FString::_assign (const wchar_t s[]) void FString::_assign (const wchar_t s[])
{ {
if ( ! s ) if ( ! s )
{ {
@ -1378,7 +1324,7 @@ inline void FString::_assign (const wchar_t s[])
if ( string && std::wcscmp(string, s) == 0 ) if ( string && std::wcscmp(string, s) == 0 )
return; // string == s return; // string == s
uInt new_length = uInt(std::wcslen(s)); uInt new_length= uInt(std::wcslen(s));
if ( ! string || new_length > capacity() ) if ( ! string || new_length > capacity() )
{ {
@ -1404,7 +1350,7 @@ inline void FString::_assign (const wchar_t s[])
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
inline void FString::_insert (std::size_t len, const wchar_t s[]) void FString::_insert (std::size_t len, const wchar_t s[])
{ {
if ( len == 0 ) // String s is a null or a empty string if ( len == 0 ) // String s is a null or a empty string
return; return;
@ -1430,9 +1376,9 @@ inline void FString::_insert (std::size_t len, const wchar_t s[])
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
inline void FString::_insert ( std::size_t pos void FString::_insert ( std::size_t pos
, std::size_t len , std::size_t len
, const wchar_t s[] ) , const wchar_t s[] )
{ {
if ( len == 0 ) // String s is a null or a empty string if ( len == 0 ) // String s is a null or a empty string
return; return;
@ -1491,7 +1437,7 @@ inline void FString::_insert ( std::size_t pos
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
inline void FString::_remove (std::size_t pos, std::size_t len) void FString::_remove (std::size_t pos, std::size_t len)
{ {
if ( capacity() - length + len <= FWDBUFFER ) if ( capacity() - length + len <= FWDBUFFER )
{ {
@ -1558,7 +1504,7 @@ inline char* FString::wc_to_c_str (const wchar_t s[]) const
int size = int(std::wcslen(s)) + 1; int size = int(std::wcslen(s)) + 1;
int dest_size = size * int(CHAR_SIZE); int dest_size = size * int(CHAR_SIZE);
const wchar_t* src = s; const wchar_t* src = s;
std::mbstate_t state; std::mbstate_t state{};
std::memset (&state, '\0', sizeof(mbstate_t)); std::memset (&state, '\0', sizeof(mbstate_t));
try try
@ -1611,7 +1557,7 @@ inline wchar_t* FString::c_to_wc_str (const char s[]) const
int dest_size = size * int(CHAR_SIZE); int dest_size = size * int(CHAR_SIZE);
const char* src = s; const char* src = s;
wchar_t* dest{}; wchar_t* dest{};
std::mbstate_t state; std::mbstate_t state{};
std::memset (&state, '\0', sizeof(mbstate_t)); std::memset (&state, '\0', sizeof(mbstate_t));
try try

View File

@ -143,7 +143,7 @@ inline void FSwitch::drawChecked()
{ {
wchar_t on[6]{L" On "}; wchar_t on[6]{L" On "};
wchar_t off[6]{L" Off "}; wchar_t off[6]{L" Off "};
const FWidgetColors& wc = getFWidgetColors(); const auto& wc = getFWidgetColors();
if ( hasFocus() && ! button_pressed ) if ( hasFocus() && ! button_pressed )
{ {
@ -194,7 +194,7 @@ inline void FSwitch::drawUnchecked()
wchar_t on[6]{L" On "}; wchar_t on[6]{L" On "};
wchar_t off[6]{L" Off "}; wchar_t off[6]{L" Off "};
const FWidgetColors& wc = getFWidgetColors(); const auto& wc = getFWidgetColors();
setColor (wc.button_inactive_fg, wc.button_inactive_bg); setColor (wc.button_inactive_fg, wc.button_inactive_bg);
if ( isMonochron() ) if ( isMonochron() )

View File

@ -35,9 +35,9 @@
#include "final/foptimove.h" #include "final/foptimove.h"
#include "final/fstartoptions.h" #include "final/fstartoptions.h"
#include "final/fstring.h" #include "final/fstring.h"
#include "final/fsystem.h"
#include "final/fsystemimpl.h" #include "final/fsystemimpl.h"
#include "final/fterm.h" #include "final/fterm.h"
#include "final/ftermbuffer.h"
#include "final/ftermcap.h" #include "final/ftermcap.h"
#include "final/ftermcapquirks.h" #include "final/ftermcapquirks.h"
#include "final/ftermdata.h" #include "final/ftermdata.h"
@ -1165,49 +1165,11 @@ wchar_t FTerm::charEncode (wchar_t c, fc::encoding enc)
} }
if ( enc == fc::PC && ch_enc == c ) if ( enc == fc::PC && ch_enc == c )
ch_enc = FTerm::unicode_to_cp437(c); ch_enc = finalcut::unicode_to_cp437(c);
return ch_enc; return ch_enc;
} }
//----------------------------------------------------------------------
wchar_t FTerm::cp437_to_unicode (uChar c)
{
constexpr std::size_t CP437 = 0;
constexpr std::size_t UNICODE = 1;
wchar_t ucs = wchar_t(c);
for (std::size_t i{0}; i <= fc::lastCP437Item; i++)
{
if ( fc::cp437_to_ucs[i][CP437] == c ) // found
{
ucs = fc::cp437_to_ucs[UNICODE][1];
break;
}
}
return ucs;
}
//----------------------------------------------------------------------
uChar FTerm::unicode_to_cp437 (wchar_t ucs)
{
constexpr std::size_t CP437 = 0;
constexpr std::size_t UNICODE = 1;
uChar c = '?';
for (std::size_t i{0}; i <= fc::lastCP437Item; i++)
{
if ( fc::cp437_to_ucs[i][UNICODE] == ucs ) // found
{
c = uChar(fc::cp437_to_ucs[i][CP437]);
break;
}
}
return c;
}
//---------------------------------------------------------------------- //----------------------------------------------------------------------
bool FTerm::scrollTermForward() bool FTerm::scrollTermForward()
{ {
@ -1234,21 +1196,6 @@ bool FTerm::scrollTermReverse()
return false; return false;
} }
//----------------------------------------------------------------------
void FTerm::putstringf (const char format[], ...)
{
assert ( format != 0 );
char buf[512]{};
va_list args{};
char* str = buf;
va_start (args, format);
vsnprintf (str, sizeof(buf), format, args);
va_end (args);
fsys->tputs (str, 1, FTerm::putchar_ASCII);
}
//---------------------------------------------------------------------- //----------------------------------------------------------------------
void FTerm::putstring (const char str[], int affcnt) void FTerm::putstring (const char str[], int affcnt)
{ {
@ -1352,6 +1299,12 @@ void FTerm::exitWithMessage (const FString& message)
// private methods of FTerm // private methods of FTerm
//----------------------------------------------------------------------
inline FStartOptions& FTerm::getStartOptions()
{
return FStartOptions::getFStartOptions();
}
//---------------------------------------------------------------------- //----------------------------------------------------------------------
void FTerm::init_global_values (bool disable_alt_screen) void FTerm::init_global_values (bool disable_alt_screen)
{ {
@ -1441,7 +1394,7 @@ void FTerm::init_alt_charset()
uChar keyChar = uChar(fc::vt100_key_to_utf8[n][vt100_key]); uChar keyChar = uChar(fc::vt100_key_to_utf8[n][vt100_key]);
uChar altChar = uChar(vt100_alt_char[keyChar]); uChar altChar = uChar(vt100_alt_char[keyChar]);
uInt utf8char = uInt(fc::vt100_key_to_utf8[n][utf8_char]); uInt utf8char = uInt(fc::vt100_key_to_utf8[n][utf8_char]);
fc::encoding num = fc::NUM_OF_ENCODINGS; fc::encoding num{fc::NUM_OF_ENCODINGS};
uInt* p = std::find ( fc::character[0] uInt* p = std::find ( fc::character[0]
, fc::character[fc::lastCharItem] + num , fc::character[fc::lastCharItem] + num
@ -2575,4 +2528,232 @@ uInt env2uint (const char* env)
} }
} }
//----------------------------------------------------------------------
wchar_t cp437_to_unicode (uChar c)
{
constexpr std::size_t CP437 = 0;
constexpr std::size_t UNICODE = 1;
wchar_t ucs(c);
for (std::size_t i{0}; i <= fc::lastCP437Item; i++)
{
if ( fc::cp437_to_ucs[i][CP437] == c ) // found
{
ucs = fc::cp437_to_ucs[i][UNICODE];
break;
}
}
return ucs;
}
//----------------------------------------------------------------------
uChar unicode_to_cp437 (wchar_t ucs)
{
constexpr std::size_t CP437 = 0;
constexpr std::size_t UNICODE = 1;
uChar c{'?'};
for (std::size_t i{0}; i <= fc::lastCP437Item; i++)
{
if ( fc::cp437_to_ucs[i][UNICODE] == ucs ) // found
{
c = uChar(fc::cp437_to_ucs[i][CP437]);
break;
}
}
return c;
}
//----------------------------------------------------------------------
FString getFullWidth (const FString& str)
{
// Converts half-width to full-width characters
FString s(str);
constexpr std::size_t HALF = 0;
constexpr std::size_t FULL = 1;
for (auto&& c : s)
{
if ( c > L'\x20' && c < L'\x7f' ) // half-width ASCII
{
c += 0xfee0;
}
else for (std::size_t i{0}; i <= fc::lastHalfWidthItem; i++)
{
if ( fc::halfWidth_fullWidth[i][HALF] == c ) // found
{
c = fc::halfWidth_fullWidth[i][FULL];
}
}
}
return s;
}
//----------------------------------------------------------------------
FString getHalfWidth (const FString& str)
{
// Converts full-width to half-width characters
FString s(str);
constexpr std::size_t HALF = 0;
constexpr std::size_t FULL = 1;
for (auto&& c : s)
{
if ( c > L'\xff00' && c < L'\xff5f' ) // full-width ASCII
{
c -= 0xfee0;
}
else for (std::size_t i{0}; i <= fc::lastHalfWidthItem; i++)
{
if ( fc::halfWidth_fullWidth[i][FULL] == c ) // found
{
c = fc::halfWidth_fullWidth[i][HALF];
}
}
}
return s;
}
//----------------------------------------------------------------------
std::size_t getColumnWidthToLength ( const FString& str
, std::size_t col_len )
{
std::size_t column_width{0}, length{0};
for (auto&& ch : str)
{
if ( column_width < col_len )
{
column_width += getColumnWidth(ch);
length++;
}
}
return length;
}
//----------------------------------------------------------------------
FString getColumnSubString ( const FString& str
, std::size_t col_pos, std::size_t col_len )
{
FString s(str);
std::size_t col_first{1}, col_num{0}, first{1}, num{0};
if ( col_len == 0 || s.isEmpty() )
return FString(L"");
if ( col_pos == 0 )
col_pos = 1;
for (auto&& ch : s)
{
std::size_t width = getColumnWidth(ch);
if ( col_first < col_pos )
{
if ( col_first + width <= col_pos )
{
col_first += width;
first++;
}
else
{
ch = fc::SingleLeftAngleQuotationMark; //
num = col_num = 1;
col_pos = col_first;
}
}
else
{
if ( col_num + width <= col_len )
{
col_num += width;
num++;
}
else if ( col_num < col_len )
{
ch = fc::SingleRightAngleQuotationMark; //
num++;
break;
}
}
}
if ( col_first < col_pos ) // String length < col_pos
return FString(L"");
return s.mid(first, num);
}
//----------------------------------------------------------------------
std::size_t getColumnWidth (const FString& s, std::size_t pos)
{
if ( s.isEmpty() )
return 0;
std::size_t column_width{0};
auto length = s.getLength();
if ( pos > length )
pos = length;
for (std::size_t i{0}; i < pos; i++)
column_width += getColumnWidth(s[i]);
return column_width;
}
//----------------------------------------------------------------------
std::size_t getColumnWidth (const FString& s)
{
if ( s.isEmpty() )
return 0;
const wchar_t* str = s.wc_str();
size_t len = std::wcslen(str);
int column_width = wcswidth (str, len);
return ( column_width == -1 ) ? 0 : std::size_t(column_width);
}
//----------------------------------------------------------------------
std::size_t getColumnWidth (const wchar_t wchar)
{
int column_width = wcwidth (wchar);
return ( column_width == -1 ) ? 0 : std::size_t(column_width);
}
//----------------------------------------------------------------------
std::size_t getColumnWidth (charData& term_char)
{
int column_width = wcwidth (term_char.code);
std::size_t char_width = ( column_width == -1 ) ? 0 : std::size_t(column_width);
if ( char_width == 2 && FTerm::getEncoding() != fc::UTF8 )
{
term_char.code = '.';
term_char.attr.bit.char_width = 1;
}
else
term_char.attr.bit.char_width = char_width & 0x03;
return char_width;
}
//----------------------------------------------------------------------
std::size_t getColumnWidth (const FTermBuffer& termbuffer)
{
std::size_t column_width{0};
for (auto&& tc : termbuffer)
column_width += tc.attr.bit.char_width;
return column_width;
}
} // namespace finalcut } // namespace finalcut

View File

@ -41,55 +41,43 @@ FTermBuffer::~FTermBuffer() // destructor
// public methods of FTermBuffer // public methods of FTermBuffer
//---------------------------------------------------------------------- //----------------------------------------------------------------------
int FTermBuffer::writef (const FString format, ...) const FString FTermBuffer::toString() const
{ {
static constexpr int BUFSIZE = 4096; std::wstring wide_string{};
wchar_t buffer[BUFSIZE]{}; wide_string.reserve(data.size());
va_list args{};
if ( format.isEmpty() ) for (auto&& tc : data)
return 0; wide_string.push_back(tc.code);
va_start (args, format); return FString(wide_string);
std::vswprintf (buffer, BUFSIZE, format.wc_str(), args);
va_end (args);
FString str(buffer);
return write(str);
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
int FTermBuffer::write (const FString& s) int FTermBuffer::write (const FString& string)
{ {
assert ( ! s.isNull() ); assert ( ! string.isNull() );
int len{0}; int len = int(string.getLength());
const wchar_t* p = s.wc_str();
if ( p ) for (auto&& c : string)
{ {
while ( *p ) charData nc; // next character
{ nc = FVTerm::getAttribute();
charData nc; // next character nc.code = c;
nc = FVTerm::getAttribute(); getColumnWidth(nc); // add column width
nc.code = *p; nc.attr.bit.no_changes = false;
nc.attr.bit.no_changes = false; nc.attr.bit.printed = false;
nc.attr.bit.printed = false; data.push_back(nc);
data.push_back(nc);
p++;
len++;
} // end of while
} }
return len; return len;
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
int FTermBuffer::write (wchar_t c) int FTermBuffer::write (wchar_t ch)
{ {
charData nc = FVTerm::getAttribute(); // next character charData nc = FVTerm::getAttribute(); // next character
nc.code = c; nc.code = ch;
getColumnWidth(nc); // add column width
nc.attr.bit.no_changes = false; nc.attr.bit.no_changes = false;
nc.attr.bit.printed = false; nc.attr.bit.printed = false;

View File

@ -193,7 +193,7 @@ bool FTermFreeBSD::saveFreeBSDAltKey()
return false; return false;
// Save current mapping // Save current mapping
bsd_alt_keymap = keymap.key[left_alt].map[0]; bsd_alt_keymap = uInt(keymap.key[left_alt].map[0]);
return true; return true;
} }
@ -213,7 +213,7 @@ bool FTermFreeBSD::setFreeBSDAltKey (uInt key)
return false; return false;
// Mapping "key" on the left alt key // Mapping "key" on the left alt key
keymap.key[left_alt].map[0] = key; keymap.key[left_alt].map[0] = int(key);
if ( (keymap.n_keys > 0) if ( (keymap.n_keys > 0)
&& fsystem && (fsystem->ioctl(0, PIO_KEYMAP, &keymap) < 0) ) && fsystem && (fsystem->ioctl(0, PIO_KEYMAP, &keymap) < 0) )

View File

@ -358,7 +358,7 @@ bool FTermLinux::loadNewFont()
//---------------------------------------------------------------------- //----------------------------------------------------------------------
bool FTermLinux::loadOldFont() bool FTermLinux::loadOldFont()
{ {
bool retval = false; bool retval{false};
if ( FTerm::openConsole() == 0 ) if ( FTerm::openConsole() == 0 )
{ {

View File

@ -104,8 +104,8 @@ bool FTermOpenBSD::setBeep (int Hz, int ms)
wskbd_bell_data bell; wskbd_bell_data bell;
bell.which = WSKBD_BELL_DOALL; bell.which = WSKBD_BELL_DOALL;
bell.pitch = Hz; bell.pitch = uInt(Hz);
bell.period = ms; bell.period = uInt(ms);
bell.volume = 50; // 50% volume bell.volume = 50; // 50% volume
if ( fsystem && fsystem->ioctl(0, WSKBDIO_SETBELL, &bell) < 0 ) if ( fsystem && fsystem->ioctl(0, WSKBDIO_SETBELL, &bell) < 0 )

View File

@ -398,6 +398,7 @@ void FTermXTerminal::setXTermCursorStyle()
if ( TCAP(fc::t_cursor_style) if ( TCAP(fc::t_cursor_style)
|| term_detection->isXTerminal() || term_detection->isXTerminal()
|| term_detection->isCygwinTerminal()
|| term_detection->isMinttyTerm() || term_detection->isMinttyTerm()
|| term_detection->hasSetCursorStyleSupport() ) || term_detection->hasSetCursorStyleSupport() )
{ {
@ -413,6 +414,7 @@ void FTermXTerminal::setXTermTitle()
if ( term_detection->isXTerminal() if ( term_detection->isXTerminal()
|| term_detection->isScreenTerm() || term_detection->isScreenTerm()
|| term_detection->isCygwinTerminal()
|| term_detection->isMinttyTerm() || term_detection->isMinttyTerm()
|| term_detection->isPuttyTerminal() || term_detection->isPuttyTerminal()
|| FTermcap::osc_support ) || FTermcap::osc_support )
@ -626,12 +628,12 @@ void FTermXTerminal::resetXTermColorMap()
if ( term_detection->isMinttyTerm() ) if ( term_detection->isMinttyTerm() )
{ {
FTerm::putstringf (ESC "c"); // Full Reset (RIS) FTerm::putstring (ESC "c"); // Full Reset (RIS)
} }
else if ( canResetColor() ) else if ( canResetColor() )
{ {
oscPrefix(); oscPrefix();
FTerm::putstringf (OSC "104" BEL); FTerm::putstring (OSC "104" BEL);
oscPostfix(); oscPostfix();
std::fflush(stdout); std::fflush(stdout);
} }
@ -715,7 +717,7 @@ void FTermXTerminal::resetXTermHighlightBackground()
if ( canResetColor() ) if ( canResetColor() )
{ {
oscPrefix(); oscPrefix();
FTerm::putstringf (OSC "117" BEL); FTerm::putstring (OSC "117" BEL);
oscPostfix(); oscPostfix();
std::fflush(stdout); std::fflush(stdout);
} }

View File

@ -145,8 +145,8 @@ void FTextView::scrollBy (int dx, int dy)
//---------------------------------------------------------------------- //----------------------------------------------------------------------
void FTextView::scrollTo (int x, int y) void FTextView::scrollTo (int x, int y)
{ {
bool changeX = bool(x != xoffset); bool changeX( x != xoffset );
bool changeY = bool(y != yoffset); bool changeY( y != yoffset );
if ( ! isShown() || ! (changeX || changeY) ) if ( ! isShown() || ! (changeX || changeY) )
return; return;
@ -207,7 +207,7 @@ void FTextView::append (const FString& str)
//---------------------------------------------------------------------- //----------------------------------------------------------------------
void FTextView::insert (const FString& str, int pos) void FTextView::insert (const FString& str, int pos)
{ {
FString s; FString s{};
if ( pos < 0 || pos >= int(getRows()) ) if ( pos < 0 || pos >= int(getRows()) )
pos = int(getRows()); pos = int(getRows());
@ -217,23 +217,22 @@ void FTextView::insert (const FString& str, int pos)
else else
s = FString(str).rtrim().expandTabs(getTabstop()); s = FString(str).rtrim().expandTabs(getTabstop());
auto iter = data.begin();
auto text_split = s.split("\r\n"); auto text_split = s.split("\r\n");
auto num = text_split.size();
for (std::size_t i{0}; i < num; i++) for (auto&& line : text_split) // Line loop
{ {
text_split[i] = text_split[i].removeBackspaces() line = line.removeBackspaces()
.removeDel() .removeDel()
.replaceControlCodes() .replaceControlCodes()
.rtrim(); .rtrim();
auto len = text_split[i].getLength(); auto column_width = getColumnWidth(line);
if ( len > maxLineWidth ) if ( column_width > maxLineWidth )
{ {
maxLineWidth = len; maxLineWidth = column_width;
if ( len > getTextWidth() ) if ( column_width > getTextWidth() )
{ {
int hmax = ( maxLineWidth > getTextWidth() ) int hmax = ( maxLineWidth > getTextWidth() )
? int(maxLineWidth) - int(getTextWidth()) ? int(maxLineWidth) - int(getTextWidth())
@ -242,12 +241,13 @@ void FTextView::insert (const FString& str, int pos)
hbar->setPageSize (int(maxLineWidth), int(getTextWidth())); hbar->setPageSize (int(maxLineWidth), int(getTextWidth()));
hbar->calculateSliderValues(); hbar->calculateSliderValues();
if ( ! hbar->isShown() ) if ( isShown() && ! hbar->isShown() )
hbar->show(); hbar->show();
} }
} }
} }
auto iter = data.begin();
data.insert (iter + pos, text_split.begin(), text_split.end()); data.insert (iter + pos, text_split.begin(), text_split.end());
int vmax = ( getRows() > getTextHeight() ) int vmax = ( getRows() > getTextHeight() )
? int(getRows()) - int(getTextHeight()) ? int(getRows()) - int(getTextHeight())
@ -256,10 +256,10 @@ void FTextView::insert (const FString& str, int pos)
vbar->setPageSize (int(getRows()), int(getTextHeight())); vbar->setPageSize (int(getRows()), int(getTextHeight()));
vbar->calculateSliderValues(); vbar->calculateSliderValues();
if ( ! vbar->isShown() && getRows() > getTextHeight() ) if ( isShown() && ! vbar->isShown() && getRows() > getTextHeight() )
vbar->show(); vbar->show();
if ( vbar->isShown() && getRows() <= getTextHeight() ) if ( isShown() && vbar->isShown() && getRows() <= getTextHeight() )
vbar->hide(); vbar->hide();
processChanged(); processChanged();
@ -597,7 +597,7 @@ void FTextView::init()
{ {
initScrollbar (vbar, fc::vertical, &FTextView::cb_VBarChange); initScrollbar (vbar, fc::vertical, &FTextView::cb_VBarChange);
initScrollbar (hbar, fc::horizontal, &FTextView::cb_HBarChange); initScrollbar (hbar, fc::horizontal, &FTextView::cb_HBarChange);
const FWidgetColors& wc = getFWidgetColors(); const auto& wc = getFWidgetColors();
setForegroundColor (wc.dialog_fg); setForegroundColor (wc.dialog_fg);
setBackgroundColor (wc.dialog_bg); setBackgroundColor (wc.dialog_bg);
nf_offset = isNewFont() ? 1 : 0; nf_offset = isNewFont() ? 1 : 0;
@ -662,6 +662,12 @@ void FTextView::draw()
if ( isMonochron() ) if ( isMonochron() )
setReverse(false); setReverse(false);
if ( ! isShown() ) // first drawing
{
vbar->show();
hbar->show();
}
if ( vbar->isShown() ) if ( vbar->isShown() )
vbar->redraw(); vbar->redraw();
@ -703,40 +709,48 @@ void FTextView::drawText()
if ( isMonochron() ) if ( isMonochron() )
setReverse(true); setReverse(true);
for (std::size_t y{0}; y < num; y++) for (std::size_t y{0}; y < num; y++) // Line loop
{ {
std::size_t i{}; std::size_t n = std::size_t(yoffset) + y;
std::size_t n = y + std::size_t(yoffset); std::size_t pos = std::size_t(xoffset) + 1;
std::size_t x = std::size_t(xoffset) + 1; std::size_t trailing_whitespace{0};
FString line(data[n].mid (x, getTextWidth())); auto text_width = getTextWidth();
const auto line_str = line.wc_str(); FString line(getColumnSubString(data[n], pos, text_width));
const auto len = line.getLength(); auto column_width = getColumnWidth(line);
print() << FPoint(2, 2 - nf_offset + int(y)); print() << FPoint(2, 2 - nf_offset + int(y));
for (i = 0; i < len; i++) for (auto&& ch : line) // Column loop
{ {
wchar_t ch = line_str[i]; if ( isPrintable(ch) )
bool utf8 = ( getEncoding() == fc::UTF8 ) ? true : false;
// only printable and 1 column per character
if ( ( (utf8 && std::iswprint(wint_t(ch)))
|| (!utf8 && std::isprint(ch)) )
&& wcwidth(ch) == 1 )
{
print (ch); print (ch);
}
else else
print ('.'); print ('.');
} }
for (; i < getTextWidth(); i++) if ( column_width <= text_width )
print (' '); trailing_whitespace = text_width - column_width;
print() << FString(trailing_whitespace, L' ');
} }
if ( isMonochron() ) if ( isMonochron() )
setReverse(false); setReverse(false);
} }
//----------------------------------------------------------------------
inline bool FTextView::isPrintable (wchar_t ch)
{
// Check for printable characters
bool utf8 = ( getEncoding() == fc::UTF8 ) ? true : false;
if ( (utf8 && std::iswprint(std::wint_t(ch)))
|| (!utf8 && std::isprint(ch)) )
return true;
return false;
}
//---------------------------------------------------------------------- //----------------------------------------------------------------------
void FTextView::processChanged() void FTextView::processChanged()
{ {

View File

@ -86,7 +86,8 @@ void FToggleButton::setGeometry ( const FPoint& pos, const FSize& s
FSize size(s); FSize size(s);
std::size_t hotkey_mark = ( getHotkey(text) ) ? 1 : 0; std::size_t hotkey_mark = ( getHotkey(text) ) ? 1 : 0;
std::size_t min_width = button_width + text.getLength() - hotkey_mark; std::size_t column_width = getColumnWidth(text);
std::size_t min_width = button_width + column_width - hotkey_mark;
if ( size.getWidth() < min_width ) if ( size.getWidth() < min_width )
size.setWidth(min_width); size.setWidth(min_width);
@ -109,7 +110,7 @@ bool FToggleButton::setNoUnderline (bool enable)
bool FToggleButton::setEnable (bool enable) bool FToggleButton::setEnable (bool enable)
{ {
FWidget::setEnable(enable); FWidget::setEnable(enable);
const FWidgetColors& wc = getFWidgetColors(); const auto& wc = getFWidgetColors();
if ( enable ) if ( enable )
{ {
@ -140,7 +141,7 @@ bool FToggleButton::setEnable (bool enable)
bool FToggleButton::setFocus (bool enable) bool FToggleButton::setFocus (bool enable)
{ {
FWidget::setFocus(enable); FWidget::setFocus(enable);
const FWidgetColors& wc = getFWidgetColors(); const auto& wc = getFWidgetColors();
if ( enable ) if ( enable )
{ {
@ -194,8 +195,8 @@ void FToggleButton::setText (const FString& txt)
{ {
text.setString(txt); text.setString(txt);
std::size_t hotkey_mark = ( getHotkey(text) ) ? 1 : 0; std::size_t hotkey_mark = ( getHotkey(text) ) ? 1 : 0;
std::size_t column_width = getColumnWidth(text);
setWidth(button_width + text.getLength() - hotkey_mark); setWidth(button_width + column_width - hotkey_mark);
if ( isEnabled() ) if ( isEnabled() )
{ {
@ -371,6 +372,9 @@ void FToggleButton::setHotkeyAccelerator()
{ {
FKey hotkey = getHotkey(text); FKey hotkey = getHotkey(text);
if ( hotkey > 0xff00 && hotkey < 0xff5f ) // full-width character
hotkey -= 0xfee0;
if ( hotkey ) if ( hotkey )
{ {
if ( std::isalpha(int(hotkey)) || std::isdigit(int(hotkey)) ) if ( std::isalpha(int(hotkey)) || std::isdigit(int(hotkey)) )
@ -534,7 +538,7 @@ void FToggleButton::setGroup (FButtonGroup* btngroup)
void FToggleButton::init() void FToggleButton::init()
{ {
setGeometry (FPoint(1, 1), FSize(4, 1), false); // initialize geometry values setGeometry (FPoint(1, 1), FSize(4, 1), false); // initialize geometry values
const FWidgetColors& wc = getFWidgetColors(); const auto& wc = getFWidgetColors();
if ( isEnabled() ) if ( isEnabled() )
{ {
@ -564,7 +568,7 @@ void FToggleButton::drawText ( wchar_t LabelText[]
if ( isMonochron() ) if ( isMonochron() )
setReverse(true); setReverse(true);
const FWidgetColors& wc = getFWidgetColors(); const auto& wc = getFWidgetColors();
if ( isEnabled() ) if ( isEnabled() )
setColor (wc.label_fg, wc.label_bg); setColor (wc.label_fg, wc.label_bg);

View File

@ -78,6 +78,7 @@ void FToolTip::setText (const FString& txt)
//---------------------------------------------------------------------- //----------------------------------------------------------------------
void FToolTip::draw() void FToolTip::draw()
{ {
int y{0};
setColor(); setColor();
if ( getMaxColor() < 16 ) if ( getMaxColor() < 16 )
@ -86,9 +87,10 @@ void FToolTip::draw()
clearArea(); clearArea();
drawBorder(); drawBorder();
for (std::size_t i{0}; i < text_num_lines; i++) for (auto&& line : text_components)
{ {
print() << FPoint(3, 2 + int(i)) << text_components[i]; print() << FPoint(3, 2 + y) << line;
y++;
} }
unsetBold(); unsetBold();
@ -126,7 +128,7 @@ void FToolTip::init()
// initialize geometry values // initialize geometry values
setGeometry (FPoint(1, 1), FSize(3, 3), false); setGeometry (FPoint(1, 1), FSize(3, 3), false);
setMinimumSize (FSize(3, 3)); setMinimumSize (FSize(3, 3));
const FWidgetColors& wc = getFWidgetColors(); const auto& wc = getFWidgetColors();
setForegroundColor (wc.tooltip_fg); setForegroundColor (wc.tooltip_fg);
setBackgroundColor (wc.tooltip_bg); setBackgroundColor (wc.tooltip_bg);
calculateDimensions(); calculateDimensions();
@ -138,19 +140,18 @@ void FToolTip::calculateDimensions()
int x{}, y{}; int x{}, y{};
auto r = getRootWidget(); auto r = getRootWidget();
max_line_width = 0; max_line_width = 0;
text_split = text.split("\n"); text_components = text.split("\n");
text_num_lines = uInt(text_split.size()); text_num_lines = std::size_t(text_components.size());
if ( text_num_lines == 0 ) if ( text_num_lines == 0 )
return; return;
for (std::size_t i{0}; i < text_num_lines; i++) for (auto&& line : text_components)
{ {
text_components = &text_split[0]; std::size_t column_width = getColumnWidth(line);
std::size_t len = text_components[i].getLength();
if ( len > max_line_width ) if ( column_width > max_line_width )
max_line_width = len; max_line_width = column_width;
} }
std::size_t h = text_num_lines + 2; std::size_t h = text_num_lines + 2;

View File

@ -323,24 +323,6 @@ void FVTerm::delPreprocessingHandler (FVTerm* instance)
} }
} }
//----------------------------------------------------------------------
int FVTerm::printf (const FString format, ...)
{
static constexpr int BUFSIZE = 4096;
wchar_t buffer[BUFSIZE]{};
va_list args{};
if ( format.isEmpty() )
return 0;
va_start (args, format);
std::vswprintf (buffer, BUFSIZE, format.wc_str(), args);
va_end (args);
FString str(buffer);
return print(str);
}
//---------------------------------------------------------------------- //----------------------------------------------------------------------
int FVTerm::print (const FString& s) int FVTerm::print (const FString& s)
{ {
@ -532,6 +514,10 @@ int FVTerm::print (term_area* area, charData& term_char)
int bsh = area->bottom_shadow; int bsh = area->bottom_shadow;
int ax = area->cursor_x - 1; int ax = area->cursor_x - 1;
int ay = area->cursor_y - 1; int ay = area->cursor_y - 1;
std::size_t char_width = getColumnWidth(nc); // add column width
if ( char_width == 0 && ! nc.attr.bit.fullwidth_padding )
return 0;
if ( area->cursor_x > 0 if ( area->cursor_x > 0
&& area->cursor_y > 0 && area->cursor_y > 0
@ -579,6 +565,8 @@ int FVTerm::print (term_area* area, charData& term_char)
area->cursor_x = 1; area->cursor_x = 1;
area->cursor_y++; area->cursor_y++;
} }
else if ( char_width == 2 )
printPaddingCharacter (area, nc);
// Prevent up scrolling // Prevent up scrolling
if ( area->cursor_y > height + bsh ) if ( area->cursor_y > height + bsh )
@ -658,10 +646,10 @@ void FVTerm::resizeArea ( const FRect& box
int offset_left = box.getX(); int offset_left = box.getX();
int offset_top = box.getY(); int offset_top = box.getY();
int width = int(box.getWidth()); int width = int(box.getWidth());
int height = int(box.getHeight()); int height = int(box.getHeight());
int rsw = int(shadow.getWidth()); int rsw = int(shadow.getWidth());
int bsh = int(shadow.getHeight()); int bsh = int(shadow.getHeight());
assert ( offset_top >= 0 ); assert ( offset_top >= 0 );
assert ( width > 0 && width + rsw > 0 ); assert ( width > 0 && width + rsw > 0 );
@ -872,7 +860,7 @@ FVTerm::covered_state FVTerm::isCovered ( const FPoint& pos
if ( ! area ) if ( ! area )
return non_covered; return non_covered;
bool found = bool(area == vdesktop); bool found( area == vdesktop );
auto is_covered = non_covered; auto is_covered = non_covered;
if ( FWidget::getWindowList() && ! FWidget::getWindowList()->empty() ) if ( FWidget::getWindowList() && ! FWidget::getWindowList()->empty() )
@ -1190,8 +1178,8 @@ void FVTerm::updateVTerm (term_area* area)
int ay = area->offset_top; int ay = area->offset_top;
int width = area->width + area->right_shadow; int width = area->width + area->right_shadow;
int height = area->height + area->bottom_shadow; int height = area->height + area->bottom_shadow;
int ol = 0; // Outside left int ol{0}; // Outside left
int y_end; int y_end{};
// Call the processing handler methods // Call the processing handler methods
callPreprocessingHandler(area); callPreprocessingHandler(area);
@ -1209,8 +1197,7 @@ void FVTerm::updateVTerm (term_area* area)
for (int y{0}; y < y_end; y++) // Line loop for (int y{0}; y < y_end; y++) // Line loop
{ {
int _xmin, _xmax; bool modified{false};
bool modified = false;
int line_xmin = int(area->changes[y].xmin); int line_xmin = int(area->changes[y].xmin);
int line_xmax = int(area->changes[y].xmax); int line_xmax = int(area->changes[y].xmax);
@ -1244,8 +1231,8 @@ void FVTerm::updateVTerm (term_area* area)
line_xmin++; // Don't update covered character line_xmin++; // Don't update covered character
} }
_xmin = ax + line_xmin - ol; int _xmin = ax + line_xmin - ol;
_xmax = ax + line_xmax; int _xmax = ax + line_xmax;
if ( _xmin < int(vterm->changes[ay + y].xmin) ) if ( _xmin < int(vterm->changes[ay + y].xmin) )
vterm->changes[ay + y].xmin = uInt(_xmin); vterm->changes[ay + y].xmin = uInt(_xmin);
@ -1340,10 +1327,9 @@ void FVTerm::getArea (const FPoint& pos, term_area* area)
if ( ! area ) if ( ! area )
return; return;
int y_end;
int length;
int ax = pos.getX() - 1; int ax = pos.getX() - 1;
int ay = pos.getY() - 1; int ay = pos.getY() - 1;
int y_end{}, length{};
if ( area->height + ay > vterm->height ) if ( area->height + ay > vterm->height )
y_end = area->height - ay; y_end = area->height - ay;
@ -1431,7 +1417,7 @@ void FVTerm::putArea (const FPoint& pos, term_area* area)
int ay = pos.getY() - 1; int ay = pos.getY() - 1;
int width = area->width + area->right_shadow; int width = area->width + area->right_shadow;
int height = area->height + area->bottom_shadow; int height = area->height + area->bottom_shadow;
int ol = 0; // outside left int ol{0}; // outside left
int y_end{}, length{}; int y_end{}, length{};
if ( ax < 0 ) if ( ax < 0 )
@ -2308,6 +2294,7 @@ void FVTerm::printRange ( uInt xmin, uInt xmax, uInt y
auto& rp = TCAP(fc::t_repeat_char); auto& rp = TCAP(fc::t_repeat_char);
auto print_char = &vt->text[y * uInt(vt->width) + x]; auto print_char = &vt->text[y * uInt(vt->width) + x];
print_char->attr.bit.printed = true; print_char->attr.bit.printed = true;
replaceNonPrintableFullwidth (x, print_char);
// skip character with no changes // skip character with no changes
if ( skipUnchangedCharacters(x, xmax, y) ) if ( skipUnchangedCharacters(x, xmax, y) )
@ -2326,14 +2313,193 @@ void FVTerm::printRange ( uInt xmin, uInt xmax, uInt y
{ {
repeatCharacter(x, xmax, y); repeatCharacter(x, xmax, y);
} }
else else // General character output
{ {
// General character output bool min_and_not_max( x == xmin && xmin != xmax );
appendCharacter (print_char); printCharacter (x, y, min_and_not_max, print_char);
}
}
}
//----------------------------------------------------------------------
inline void FVTerm::replaceNonPrintableFullwidth ( uInt x
, charData*& print_char )
{
// Replace non-printable full-width characters that are truncated
// from the right or left terminal side
if ( x == 0 && isFullWidthPaddingChar(print_char) )
{
print_char->code = fc::SingleLeftAngleQuotationMark; //
print_char->attr.bit.fullwidth_padding = false;
}
else if ( x == uInt(vterm->width - 1)
&& isFullWidthChar(print_char) )
{
print_char->code = fc::SingleRightAngleQuotationMark; //
print_char->attr.bit.char_width = 1;
}
}
//----------------------------------------------------------------------
void FVTerm::printCharacter ( uInt& x, uInt y, bool min_and_not_max
, charData*& print_char)
{
// General character output on terminal
if ( x < uInt(vterm->width - 1) && isFullWidthChar(print_char) )
{
printFullWidthCharacter (x, y, print_char);
}
else if ( x > 0 && x < uInt(vterm->width - 1)
&& isFullWidthPaddingChar(print_char) )
{
printFullWidthPaddingCharacter (x, y, print_char);
}
else if ( x > 0 && min_and_not_max )
{
printHalfCovertFullWidthCharacter (x, y, print_char);
}
else
{
// Print a half-width character
appendCharacter (print_char);
markAsPrinted (x, y);
}
}
//----------------------------------------------------------------------
void FVTerm::printFullWidthCharacter ( uInt& x, uInt y
, charData*& print_char )
{
auto vt = vterm;
auto next_char = &vt->text[y * uInt(vt->width) + x + 1];
if ( print_char->attr.byte[0] == next_char->attr.byte[0]
&& print_char->attr.byte[1] == next_char->attr.byte[1]
&& print_char->fg_color == next_char->fg_color
&& print_char->bg_color == next_char->bg_color
&& isFullWidthChar(print_char)
&& isFullWidthPaddingChar(next_char) )
{
// Print a full-width character
appendCharacter (print_char);
markAsPrinted (x, y);
skipPaddingCharacter (x, y, print_char);
}
else
{
// Print ellipses for the 1st full-width character column
appendAttributes (print_char);
appendOutputBuffer (fc::HorizontalEllipsis);
term_pos->x_ref()++;
markAsPrinted (x, y);
if ( isFullWidthPaddingChar(next_char) )
{
// Print ellipses for the 2nd full-width character column
x++;
appendAttributes (next_char);
appendOutputBuffer (fc::HorizontalEllipsis);
term_pos->x_ref()++;
markAsPrinted (x, y); markAsPrinted (x, y);
} }
} }
} }
//----------------------------------------------------------------------
void FVTerm::printFullWidthPaddingCharacter ( uInt& x, uInt y
, charData*& print_char)
{
auto vt = vterm;
auto prev_char = &vt->text[y * uInt(vt->width) + x - 1];
if ( print_char->attr.byte[0] == prev_char->attr.byte[0]
&& print_char->attr.byte[1] == prev_char->attr.byte[1]
&& print_char->fg_color == prev_char->fg_color
&& print_char->bg_color == prev_char->bg_color
&& isFullWidthChar(prev_char)
&& isFullWidthPaddingChar(print_char) )
{
// Move cursor one character to the left
auto& le = TCAP(fc::t_cursor_left);
auto& RI = TCAP(fc::t_parm_right_cursor);
if ( le )
appendOutputBuffer (le);
else if ( RI )
appendOutputBuffer (tparm(RI, 1, 0, 0, 0, 0, 0, 0, 0, 0));
else
{
skipPaddingCharacter (x, y, prev_char);
return;
}
// Print a full-width character
x--;
term_pos->x_ref()--;
appendCharacter (prev_char);
markAsPrinted (x, y);
skipPaddingCharacter (x, y, prev_char);
}
else
{
// Print ellipses for the 1st full-width character column
appendAttributes (print_char);
appendOutputBuffer (fc::HorizontalEllipsis);
term_pos->x_ref()++;
markAsPrinted (x, y);
}
}
//----------------------------------------------------------------------
void FVTerm::printHalfCovertFullWidthCharacter ( uInt& x, uInt y
, charData*& print_char )
{
auto vt = vterm;
auto prev_char = &vt->text[y * uInt(vt->width) + x - 1];
if ( isFullWidthChar(prev_char) && ! isFullWidthPaddingChar(print_char) )
{
// Move cursor one character to the left
auto& le = TCAP(fc::t_cursor_left);
auto& RI = TCAP(fc::t_parm_right_cursor);
if ( le )
appendOutputBuffer (le);
else if ( RI )
appendOutputBuffer (tparm(RI, 1, 0, 0, 0, 0, 0, 0, 0, 0));
if ( le || RI )
{
// Print ellipses for the 1st full-width character column
x--;
term_pos->x_ref()--;
appendAttributes (print_char);
appendOutputBuffer (fc::HorizontalEllipsis);
term_pos->x_ref()++;
markAsPrinted (x, y);
x++;
}
}
// Print a half-width character
appendCharacter (print_char);
markAsPrinted (x, y);
}
//----------------------------------------------------------------------
inline void FVTerm::skipPaddingCharacter ( uInt& x, uInt y
, charData*& print_char )
{
if ( isFullWidthChar(print_char) ) // full-width character
{
x++; // Skip the following padding character
term_pos->x_ref()++;
markAsPrinted (x, y);
}
}
//---------------------------------------------------------------------- //----------------------------------------------------------------------
FVTerm::exit_state FVTerm::eraseCharacters ( uInt& x, uInt xmax, uInt y FVTerm::exit_state FVTerm::eraseCharacters ( uInt& x, uInt xmax, uInt y
, bool draw_trailing_ws ) , bool draw_trailing_ws )
@ -2347,7 +2513,7 @@ FVTerm::exit_state FVTerm::eraseCharacters ( uInt& x, uInt xmax, uInt y
if ( ! ec || print_char->code != ' ' ) if ( ! ec || print_char->code != ' ' )
return not_used; return not_used;
uInt whitespace = 1; uInt whitespace{1};
bool normal = FTerm::isNormal(print_char); bool normal = FTerm::isNormal(print_char);
for (uInt i = x + 1; i <= xmax; i++) for (uInt i = x + 1; i <= xmax; i++)
@ -2358,6 +2524,7 @@ FVTerm::exit_state FVTerm::eraseCharacters ( uInt& x, uInt xmax, uInt y
whitespace++; whitespace++;
else else
break; break;
} }
if ( whitespace == 1 ) if ( whitespace == 1 )
@ -2454,6 +2621,18 @@ FVTerm::exit_state FVTerm::repeatCharacter (uInt& x, uInt xmax, uInt y)
return used; return used;
} }
//----------------------------------------------------------------------
inline bool FVTerm::isFullWidthChar (charData*& ch)
{
return bool(ch->attr.bit.char_width == 2);
}
//----------------------------------------------------------------------
inline bool FVTerm::isFullWidthPaddingChar (charData*& ch)
{
return ch->attr.bit.fullwidth_padding;
}
//---------------------------------------------------------------------- //----------------------------------------------------------------------
void FVTerm::cursorWrap() void FVTerm::cursorWrap()
{ {
@ -2507,6 +2686,34 @@ bool FVTerm::printWrap (term_area* area)
return end_of_area; return end_of_area;
} }
//----------------------------------------------------------------------
void FVTerm::printPaddingCharacter (term_area* area, charData& term_char)
{
// Creates a padding-character from the current character (term_char)
// and prints it. It is a placeholder for the column after
// a full-width character.
charData pc; // padding character
// Copy character to padding character
std::memcpy (&pc, &term_char, sizeof(pc));
if ( getEncoding() == fc::UTF8 )
{
pc.code = 0;
pc.attr.bit.fullwidth_padding = true;
pc.attr.bit.char_width = 0;
}
else
{
pc.code = '.';
pc.attr.bit.char_width = 1;
}
// Print the padding-character
print (area, pc);
}
//---------------------------------------------------------------------- //----------------------------------------------------------------------
void FVTerm::updateTerminalLine (uInt y) void FVTerm::updateTerminalLine (uInt y)
{ {

View File

@ -1250,10 +1250,10 @@ void FWidget::drawShadow()
return; return;
} }
int x1 = 1 int x1 = 1;
, x2 = int(getWidth()) int x2 = int(getWidth());
, y1 = 1 int y1 = 1;
, y2 = int(getHeight()); int y2 = int(getHeight());
if ( flags.trans_shadow ) if ( flags.trans_shadow )
{ {
@ -1310,10 +1310,10 @@ void FWidget::drawFlatBorder()
if ( ! isNewFont() ) if ( ! isNewFont() )
return; return;
int x1 = 1 int x1 = 1;
, x2 = int(getWidth()) + 1 int x2 = int(getWidth() + 1);
, y1 = 0 int y1 = 0;
, y2 = int(getHeight()) + 1; int y2 = int(getHeight() + 1);
if ( auto p = getParentWidget() ) if ( auto p = getParentWidget() )
setColor (wcolors.dialog_fg, p->getBackgroundColor()); setColor (wcolors.dialog_fg, p->getBackgroundColor());
@ -1377,10 +1377,10 @@ void FWidget::clearFlatBorder()
if ( ! isNewFont() ) if ( ! isNewFont() )
return; return;
int x1 = 1 int x1 = 1;
, x2 = int(getWidth()) + 1 int x2 = int(getWidth() + 1);
, y1 = 0 int y1 = 0;
, y2 = int(getHeight()) + 1; int y2 = int(getHeight() + 1);
if ( auto p = getParentWidget() ) if ( auto p = getParentWidget() )
setColor (wcolors.dialog_fg, p->getBackgroundColor()); setColor (wcolors.dialog_fg, p->getBackgroundColor());
@ -1548,9 +1548,9 @@ void FWidget::adjustSize()
else if ( ignore_padding && p ) else if ( ignore_padding && p )
{ {
woffset.setCoordinates ( p->getTermX() - 1 woffset.setCoordinates ( p->getTermX() - 1
, p->getTermY() - 1 , p->getTermY() - 1
, p->getTermX() + int(p->getWidth()) - 2 , p->getTermX() + int(p->getWidth()) - 2
, p->getTermY() + int(p->getHeight()) - 2 ); , p->getTermY() + int(p->getHeight()) - 2 );
} }
else if ( p ) else if ( p )
woffset = p->wclient_offset; woffset = p->wclient_offset;

View File

@ -782,18 +782,18 @@ void FWindow::setShadowSize (const FSize& size)
//---------------------------------------------------------------------- //----------------------------------------------------------------------
void FWindow::adjustSize() void FWindow::adjustSize()
{ {
int old_x = getX(); int old_x = getTermX();
int old_y = getY(); int old_y = getTermY();
FWidget::adjustSize(); FWidget::adjustSize();
if ( zoomed ) if ( zoomed )
setGeometry (FPoint(1, 1), FSize(getMaxWidth(), getMaxHeight()), false); setGeometry (FPoint(1, 1), FSize(getMaxWidth(), getMaxHeight()), false);
else if ( isVirtualWindow() ) else if ( isVirtualWindow() )
{ {
if ( getX() != old_x ) if ( getTermX() != old_x )
getVWin()->offset_left = getTermX() - 1; getVWin()->offset_left = getTermX() - 1;
if ( getY() != old_y ) if ( getTermY() != old_y )
getVWin()->offset_top = getTermY() - 1; getVWin()->offset_top = getTermY() - 1;
} }
} }

View File

@ -79,6 +79,7 @@ class FCloseEvent;
class FFocusEvent; class FFocusEvent;
class FKeyEvent; class FKeyEvent;
class FMouseEvent; class FMouseEvent;
class FStartOptions;
class FTimerEvent; class FTimerEvent;
class FWheelEvent; class FWheelEvent;
class FMouseControl; class FMouseControl;
@ -144,6 +145,7 @@ class FApplication : public FWidget
// Methods // Methods
void init (uInt64, uInt64); void init (uInt64, uInt64);
static void cmd_options (const int&, char*[]); static void cmd_options (const int&, char*[]);
static FStartOptions& getStartOptions();
void findKeyboardWidget(); void findKeyboardWidget();
bool isKeyPressed(); bool isKeyPressed();
void keyPressed(); void keyPressed();

View File

@ -173,7 +173,7 @@ class FButton : public FWidget
std::size_t indent{0}; std::size_t indent{0};
std::size_t center_offset{0}; std::size_t center_offset{0};
std::size_t vcenter_offset{0}; std::size_t vcenter_offset{0};
std::size_t txtlength{0}; std::size_t column_width{0};
}; };
// FButton inline functions // FButton inline functions

View File

@ -152,6 +152,9 @@ enum SpecialCharacter : wchar_t
DownwardsArrow = 0x2193, // ↓ DownwardsArrow = 0x2193, // ↓
RightwardsArrow = 0x2192, // → RightwardsArrow = 0x2192, // →
LeftwardsArrow = 0x2190, // ← LeftwardsArrow = 0x2190, // ←
SingleRightAngleQuotationMark = 0x203a, // (1)
SingleLeftAngleQuotationMark = 0x2039, // (1)
HorizontalEllipsis = 0x2026, // … (1)
DoubleExclamationMark = 0x203c, // ‼ DoubleExclamationMark = 0x203c, // ‼
SuperscriptLatinSmallLetterN = 0x207f, // ⁿ SuperscriptLatinSmallLetterN = 0x207f, // ⁿ
GreaterThanOrEqualTo = 0x2265, // ≥ GreaterThanOrEqualTo = 0x2265, // ≥

View File

@ -45,6 +45,9 @@ extern const std::size_t lastKeyItem;
extern wchar_t cp437_to_ucs[][2]; extern wchar_t cp437_to_ucs[][2];
extern const std::size_t lastCP437Item; extern const std::size_t lastCP437Item;
extern wchar_t halfWidth_fullWidth[][2];
extern const std::size_t lastHalfWidthItem;
} // namespace fc } // namespace fc
} // namespace finalcut } // namespace finalcut

View File

@ -105,11 +105,11 @@ class FLabel : public FWidget
// Mutators // Mutators
void setAccelWidget (FWidget* = nullptr); void setAccelWidget (FWidget* = nullptr);
void setAlignment(fc::text_alignment); void setAlignment (fc::text_alignment);
bool setEmphasis(bool); bool setEmphasis (bool);
bool setEmphasis(); bool setEmphasis();
bool unsetEmphasis(); bool unsetEmphasis();
bool setReverseMode(bool); bool setReverseMode (bool);
bool setReverseMode(); bool setReverseMode();
bool unsetReverseMode(); bool unsetReverseMode();
bool setEnable (bool) override; bool setEnable (bool) override;
@ -146,7 +146,7 @@ class FLabel : public FWidget
void draw() override; void draw() override;
void drawMultiLine(); void drawMultiLine();
void drawSingleLine(); void drawSingleLine();
void printLine ( wchar_t[], std::size_t void printLine ( wchar_t[], std::size_t, std::size_t
, std::size_t, std::size_t = 0 ); , std::size_t, std::size_t = 0 );
// Data members // Data members
@ -178,6 +178,10 @@ inline fc::text_alignment FLabel::getAlignment()
inline FString& FLabel::getText() inline FString& FLabel::getText()
{ return text; } { return text; }
//----------------------------------------------------------------------
inline bool FLabel::setEmphasis (bool enable)
{ return (emphasis = enable); }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
inline bool FLabel::setEmphasis() inline bool FLabel::setEmphasis()
{ return setEmphasis(true); } { return setEmphasis(true); }
@ -186,6 +190,10 @@ inline bool FLabel::setEmphasis()
inline bool FLabel::unsetEmphasis() inline bool FLabel::unsetEmphasis()
{ return setEmphasis(false); } { return setEmphasis(false); }
//----------------------------------------------------------------------
inline bool FLabel::setReverseMode (bool enable)
{ return (reverse_mode = enable); }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
inline bool FLabel::setReverseMode() inline bool FLabel::setReverseMode()
{ return setReverseMode(true); } { return setReverseMode(true); }

View File

@ -156,6 +156,9 @@ class FLineEdit : public FWidget
void adjustSize() override; void adjustSize() override;
private: private:
// Typedef
typedef std::pair<std::size_t, std::size_t> offsetPair;
// Enumeration // Enumeration
enum dragScroll enum dragScroll
{ {
@ -164,19 +167,25 @@ class FLineEdit : public FWidget
scrollRight = 2 scrollRight = 2
}; };
// Constants
static constexpr std::size_t NOT_SET = static_cast<std::size_t>(-1);
// Methods // Methods
void init(); void init();
bool hasHotkey(); bool hasHotkey();
void draw() override; void draw() override;
void drawInputField(); void drawInputField();
void keyLeft(); offsetPair endPosToOffset (std::size_t);
void keyRight(); std::size_t clickPosToCursorPos (std::size_t);
void keyHome(); void adjustTextOffset();
void keyEnd(); void cursorLeft();
void keyDel(); void cursorRight();
void keyBackspace(); void cursorHome();
void keyInsert(); void cursorEnd();
void keyEnter(); void deleteCurrentCharacter();
void deletePreviousCharacter();
void switchInsertMode();
void acceptInput();
bool keyInput (FKey); bool keyInput (FKey);
wchar_t characterFilter (const wchar_t); wchar_t characterFilter (const wchar_t);
void processActivate(); void processActivate();
@ -192,8 +201,9 @@ class FLineEdit : public FWidget
int scroll_repeat{100}; int scroll_repeat{100};
bool scroll_timer{false}; bool scroll_timer{false};
bool insert_mode{true}; bool insert_mode{true};
std::size_t cursor_pos{0}; std::size_t cursor_pos{NOT_SET};
std::size_t text_offset{0}; std::size_t text_offset{0};
std::size_t char_width_offset{0};
std::size_t max_length{std::numeric_limits<std::size_t>::max()}; std::size_t max_length{std::numeric_limits<std::size_t>::max()};
}; };

View File

@ -290,19 +290,19 @@ class FListBox : public FWidget
void scrollToY (int); void scrollToY (int);
void scrollLeft (int); void scrollLeft (int);
void scrollRight (int); void scrollRight (int);
void keyUp(); void scrollLeft();
void keyDown(); void scrollRight();
void keyLeft(); void onePosUp();
void keyRight(); void onePosDown();
void keyPgUp(); void onePageUp();
void keyPgDn(); void onePageDown();
void keyHome(); void firstPos();
void keyEnd(); void lastPos();
bool keyEsc(); bool skipIncrementalSearch();
void keyEnter(); void acceptSelection();
bool keySpace(); bool spacebarProcessing();
bool keyInsert(); bool changeSelectionAndPosition();
bool keyBackspace(); bool deletePreviousCharacter();
bool keyIncSearchInput (FKey); bool keyIncSearchInput (FKey);
void processClick(); void processClick();
void processSelect(); void processSelect();

View File

@ -394,6 +394,7 @@ class FListView : public FWidget
void drawSortIndicator (std::size_t&, std::size_t); void drawSortIndicator (std::size_t&, std::size_t);
void drawHeadlineLabel (const headerItems::const_iterator&); void drawHeadlineLabel (const headerItems::const_iterator&);
void drawHeaderBorder (std::size_t); void drawHeaderBorder (std::size_t);
void drawBufferedHeadline();
void drawColumnEllipsis ( const headerItems::const_iterator& void drawColumnEllipsis ( const headerItems::const_iterator&
, const FString& ); , const FString& );
void updateDrawing (bool, bool); void updateDrawing (bool, bool);
@ -413,13 +414,13 @@ class FListView : public FWidget
FObjectIterator appendItem (FListViewItem*); FObjectIterator appendItem (FListViewItem*);
void processClick(); void processClick();
void processChanged(); void processChanged();
void keySpace(); void toggleCheckbox();
void keyLeft (int&); void collapseAndScrollLeft (int&);
void keyRight (int&); void expandAndScrollRight (int&);
void keyHome(); void firstPos();
void keyEnd(); void lastPos();
bool keyPlus(); bool expandSubtree();
bool keyMinus(); bool collapseSubtree();
void setRelativePosition (int); void setRelativePosition (int);
void stepForward(); void stepForward();
void stepBackward(); void stepBackward();

View File

@ -210,12 +210,10 @@ class FMenu : public FWindow, public FMenuList
void drawTrailingSpaces (std::size_t); void drawTrailingSpaces (std::size_t);
void setLineAttributes (FMenuItem*, int); void setLineAttributes (FMenuItem*, int);
void setCursorToHotkeyPosition (FMenuItem*); void setCursorToHotkeyPosition (FMenuItem*);
void keyUp(); void selectPrevMenu (FKeyEvent*);
void keyDown(); void selectNextMenu (FKeyEvent*);
void keyLeft (FKeyEvent*); void acceptSelection();
void keyRight (FKeyEvent*); void closeMenu();
void keyEnter();
void keyEscape();
void processActivate(); void processActivate();
// Friend classes // Friend classes
@ -227,7 +225,7 @@ class FMenu : public FWindow, public FMenuList
friend class FRadioMenuItem; friend class FRadioMenuItem;
// Data members // Data members
FMenuItem item{}; FMenuItem menuitem{};
FWidget* super_menu{nullptr}; FWidget* super_menu{nullptr};
FMenu* opened_sub_menu{nullptr}; FMenu* opened_sub_menu{nullptr};
FMenu* shown_sub_menu{nullptr}; FMenu* shown_sub_menu{nullptr};
@ -245,35 +243,35 @@ inline const char* FMenu::getClassName() const
//---------------------------------------------------------------------- //----------------------------------------------------------------------
inline FString FMenu::getText() const inline FString FMenu::getText() const
{ return item.getText(); } { return menuitem.getText(); }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
inline FMenuItem* FMenu::getItem() inline FMenuItem* FMenu::getItem()
{ return &item; } { return &menuitem; }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
inline bool FMenu::setEnable (bool enable) inline bool FMenu::setEnable (bool enable)
{ return item.setEnable(enable); } { return menuitem.setEnable(enable); }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
inline bool FMenu::setEnable() inline bool FMenu::setEnable()
{ return item.setEnable(); } { return menuitem.setEnable(); }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
inline bool FMenu::unsetEnable() inline bool FMenu::unsetEnable()
{ return item.unsetEnable(); } { return menuitem.unsetEnable(); }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
inline bool FMenu::setDisable() inline bool FMenu::setDisable()
{ return item.setDisable(); } { return menuitem.setDisable(); }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
inline void FMenu::setSelected() inline void FMenu::setSelected()
{ item.setSelected(); } { menuitem.setSelected(); }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
inline void FMenu::unsetSelected() inline void FMenu::unsetSelected()
{ item.unsetSelected(); } { menuitem.unsetSelected(); }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
inline bool FMenu::setMenuWidget() inline bool FMenu::setMenuWidget()
@ -285,27 +283,27 @@ inline bool FMenu::unsetMenuWidget()
//---------------------------------------------------------------------- //----------------------------------------------------------------------
inline void FMenu::setMenu (FMenu* m) inline void FMenu::setMenu (FMenu* m)
{ item.setMenu(m); } { menuitem.setMenu(m); }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
inline void FMenu::setText (const FString& txt) inline void FMenu::setText (const FString& txt)
{ item.setText(txt); } { menuitem.setText(txt); }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
inline bool FMenu::isEnabled() const inline bool FMenu::isEnabled() const
{ return item.isEnabled(); } { return menuitem.isEnabled(); }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
inline bool FMenu::isSelected() const inline bool FMenu::isSelected() const
{ return item.isSelected(); } { return menuitem.isSelected(); }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
inline bool FMenu::hasHotkey() const inline bool FMenu::hasHotkey() const
{ return item.hasHotkey(); } { return menuitem.hasHotkey(); }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
inline bool FMenu::hasMenu() const inline bool FMenu::hasMenu() const
{ return item.hasMenu(); } { return menuitem.hasMenu(); }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
inline FWidget* FMenu::getSuperMenu() const inline FWidget* FMenu::getSuperMenu() const
@ -325,7 +323,7 @@ inline FMenu* FMenu::superMenuAt (const FPoint& p)
//---------------------------------------------------------------------- //----------------------------------------------------------------------
inline void FMenu::onAccel (FAccelEvent* ev) inline void FMenu::onAccel (FAccelEvent* ev)
{ item.onAccel(ev); } { menuitem.onAccel(ev); }
} // namespace finalcut } // namespace finalcut

View File

@ -132,6 +132,7 @@ class FMenuBar : public FWindow, public FMenuList
void drawItems(); void drawItems();
void drawItem (FMenuItem*, std::size_t&); void drawItem (FMenuItem*, std::size_t&);
void setLineAttributes (FMenuItem*); void setLineAttributes (FMenuItem*);
void setCursorToHotkeyPosition (FMenuItem*, std::size_t);
void drawMenuText (menuText&); void drawMenuText (menuText&);
void drawEllipsis (const menuText&, std::size_t); void drawEllipsis (const menuText&, std::size_t);
void drawLeadingSpace (std::size_t&); void drawLeadingSpace (std::size_t&);

View File

@ -94,9 +94,10 @@ class FMenuItem : public FWidget
// Accessors // Accessors
const char* getClassName() const override; const char* getClassName() const override;
uChar getHotkey() const; FKey getHotkey() const;
FMenu* getMenu() const; FMenu* getMenu() const;
std::size_t getTextLength() const; std::size_t getTextLength() const;
std::size_t getTextWidth() const;
FString getText() const; FString getText() const;
// Mutators // Mutators
@ -159,7 +160,6 @@ class FMenuItem : public FWidget
// Methods // Methods
void init (FWidget*); void init (FWidget*);
uChar hotKey();
void updateSuperMenuDimensions(); void updateSuperMenuDimensions();
void processActivate(); void processActivate();
void processDeactivate(); void processDeactivate();
@ -179,8 +179,9 @@ class FMenuItem : public FWidget
FWidget* super_menu{nullptr}; FWidget* super_menu{nullptr};
FDialog* associated_window{nullptr}; FDialog* associated_window{nullptr};
std::size_t text_length{0}; std::size_t text_length{0};
std::size_t text_width{0};
FKey accel_key{0}; FKey accel_key{0};
uChar hotkey{0}; FKey hotkey{0};
bool selected{false}; bool selected{false};
bool separator{false}; bool separator{false};
bool checkable{false}; bool checkable{false};
@ -202,7 +203,7 @@ inline const char* FMenuItem::getClassName() const
{ return "FMenuItem"; } { return "FMenuItem"; }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
inline uChar FMenuItem::getHotkey() const inline FKey FMenuItem::getHotkey() const
{ return hotkey; } { return hotkey; }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
@ -213,6 +214,10 @@ inline FMenu* FMenuItem::getMenu() const
inline std::size_t FMenuItem::getTextLength() const inline std::size_t FMenuItem::getTextLength() const
{ return text_length; } { return text_length; }
//----------------------------------------------------------------------
inline std::size_t FMenuItem::getTextWidth() const
{ return text_width; }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
inline FString FMenuItem::getText() const inline FString FMenuItem::getText() const
{ return text; } { return text; }

View File

@ -155,14 +155,13 @@ class FMessageBox : public FDialog
// Data members // Data members
FString headline_text{}; FString headline_text{};
FString text{}; FString text{};
FString* text_components{nullptr}; FStringList text_components{};
FStringList text_split{};
FButton* button[3]{nullptr}; FButton* button[3]{nullptr};
std::size_t max_line_width{0}; std::size_t max_line_width{0};
FColor emphasis_color{getFWidgetColors().dialog_emphasis_fg}; FColor emphasis_color{getFWidgetColors().dialog_emphasis_fg};
int button_digit[3]{0}; int button_digit[3]{0};
uInt num_buttons{0}; uInt num_buttons{0};
uInt text_num_lines{0}; std::size_t text_num_lines{0};
bool center_text{false}; bool center_text{false};
}; };

View File

@ -342,7 +342,9 @@ inline bool operator == ( const charData& lhs,
&& lhs.fg_color == rhs.fg_color && lhs.fg_color == rhs.fg_color
&& lhs.bg_color == rhs.bg_color && lhs.bg_color == rhs.bg_color
&& lhs.attr.byte[0] == rhs.attr.byte[0] && lhs.attr.byte[0] == rhs.attr.byte[0]
&& lhs.attr.byte[1] == rhs.attr.byte[1]; && lhs.attr.byte[1] == rhs.attr.byte[1]
&& lhs.attr.bit.fullwidth_padding \
== rhs.attr.bit.fullwidth_padding;
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------

View File

@ -35,6 +35,11 @@
#error "Only <final/final.h> can be included directly." #error "Only <final/final.h> can be included directly."
#endif #endif
#include <iostream>
#include "final/fc.h"
#include "final/ftypes.h"
namespace finalcut namespace finalcut
{ {
@ -42,27 +47,26 @@ namespace finalcut
// class FStartOptions // class FStartOptions
//---------------------------------------------------------------------- //----------------------------------------------------------------------
struct FStartOptions class FStartOptions final
{ {
public: public:
// Mutator // Constructors
void setDefault() FStartOptions();
{
cursor_optimisation = true;
mouse_support = true;
terminal_detection = true;
color_change = true;
vgafont = false;
newfont = false;
encoding = fc::UNKNOWN;
#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(UNIT_TEST) // Disable copy constructor
meta_sends_escape = true; FStartOptions (const FStartOptions&) = delete;
change_cursorstyle = true;
#elif defined(__NetBSD__) || defined(__OpenBSD__) // Destructor
meta_sends_escape = true; virtual ~FStartOptions();
#endif
} // Disable assignment operator (=)
FStartOptions& operator = (const FStartOptions&) = delete;
// Accessors
static FStartOptions& getFStartOptions();
// Mutator
void setDefault();
// Data members // Data members
uInt8 cursor_optimisation : 1; uInt8 cursor_optimisation : 1;
@ -75,20 +79,17 @@ struct FStartOptions
fc::encoding encoding; fc::encoding encoding;
#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(UNIT_TEST) #if defined(__FreeBSD__) || defined(__DragonFly__) || defined(UNIT_TEST)
uInt8 meta_sends_escape : 1; uInt8 meta_sends_escape : 1;
uInt8 change_cursorstyle : 1; uInt8 change_cursorstyle : 1;
uInt8 : 6; // padding bits uInt8 : 6; // padding bits
#elif defined(__NetBSD__) || defined(__OpenBSD__) #elif defined(__NetBSD__) || defined(__OpenBSD__)
uInt8 meta_sends_escape : 1; uInt8 meta_sends_escape : 1;
uInt8 : 7; // padding bits uInt8 : 7; // padding bits
#endif #endif
static FStartOptions* start_options;
}; };
static struct FStartOptions start_options{};
inline FStartOptions& getStartOptions()
{ return start_options; }
} // namespace finalcut } // namespace finalcut
#endif // FSTARTOPTIONS_H #endif // FSTARTOPTIONS_H

View File

@ -238,6 +238,8 @@ class FStatusBar : public FWindow
// Methods // Methods
void init(); void init();
int getKeyNameWidth (const FStatusKey*);
int getKeyTextWidth (const FStatusKey*);
void draw() override; void draw() override;
void drawKeys(); void drawKeys();
void drawKey (keyList::const_iterator); void drawKey (keyList::const_iterator);

View File

@ -78,7 +78,8 @@ class FString
{ {
public: public:
// Typedef // Typedef
typedef const wchar_t* iterator; typedef const wchar_t* const_iterator;
typedef wchar_t* iterator;
// Constructors // Constructors
FString () = default; FString () = default;
@ -191,12 +192,15 @@ class FString
std::size_t getUTF8length() const; std::size_t getUTF8length() const;
std::size_t capacity() const; std::size_t capacity() const;
iterator begin() const; iterator begin();
iterator end() const; iterator end();
const_iterator begin() const;
const_iterator end() const;
wchar_t front() const; wchar_t front() const;
wchar_t back() const; wchar_t back() const;
FString& sprintf (const FString, ...); template<typename... Args>
FString& sprintf (const FString, Args&&...);
FString clear(); FString clear();
const wchar_t* wc_str() const; const wchar_t* wc_str() const;
@ -369,11 +373,19 @@ inline std::size_t FString::capacity() const
{ return ( length > 0 ) ? bufsize - 1 : 0; } { return ( length > 0 ) ? bufsize - 1 : 0; }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
inline FString::iterator FString::begin() const inline FString::iterator FString::begin()
{ return string; } { return string; }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
inline FString::iterator FString::end() const inline FString::iterator FString::end()
{ return string + length; }
//----------------------------------------------------------------------
inline FString::const_iterator FString::begin() const
{ return string; }
//----------------------------------------------------------------------
inline FString::const_iterator FString::end() const
{ return string + length; } { return string + length; }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
@ -390,6 +402,25 @@ inline wchar_t FString::back() const
return string[length - 1]; return string[length - 1];
} }
//----------------------------------------------------------------------
template<typename... Args>
inline FString& FString::sprintf (const FString format, Args&&... args)
{
static constexpr int BUFSIZE = 4096;
wchar_t buffer[BUFSIZE]{};
if ( ! format )
{
clear();
return *this;
}
std::swprintf ( buffer, BUFSIZE
, format.wc_str(), std::forward<Args>(args)... );
_assign(buffer);
return *this;
}
//---------------------------------------------------------------------- //----------------------------------------------------------------------
template <typename NumT> template <typename NumT>
inline FString& FString::setNumber (NumT num, int precision) inline FString& FString::setNumber (NumT num, int precision)

View File

@ -116,6 +116,7 @@
#include "final/fc.h" #include "final/fc.h"
#include "final/fstring.h" #include "final/fstring.h"
#include "final/fsystem.h"
namespace finalcut namespace finalcut
{ {
@ -125,9 +126,10 @@ class FKeyboard;
class FMouseControl; class FMouseControl;
class FOptiAttr; class FOptiAttr;
class FOptiMove; class FOptiMove;
class FStartOptions;
class FSize; class FSize;
class FString; class FString;
class FSystem; class FTermBuffer;
class FTermData; class FTermData;
class FTermDebugData; class FTermDebugData;
class FTermDetection; class FTermDetection;
@ -272,8 +274,6 @@ class FTerm final
static bool charEncodable (wchar_t); static bool charEncodable (wchar_t);
static wchar_t charEncode (wchar_t); static wchar_t charEncode (wchar_t);
static wchar_t charEncode (wchar_t, fc::encoding); static wchar_t charEncode (wchar_t, fc::encoding);
static wchar_t cp437_to_unicode (uChar);
static uChar unicode_to_cp437 (wchar_t);
static bool scrollTermForward(); static bool scrollTermForward();
static bool scrollTermReverse(); static bool scrollTermReverse();
@ -281,13 +281,8 @@ class FTerm final
// function pointer -> static function // function pointer -> static function
static int (*Fputchar)(int); static int (*Fputchar)(int);
static void putstringf (const char[], ...) template<typename... Args>
#if defined(__clang__) static void putstringf (const char[], Args&&...);
__attribute__ ((__format__ (__printf__, 1, 2)))
#elif defined(__GNUC__)
__attribute__ ((format (printf, 1, 2)))
#endif
;
static void putstring (const char[], int = 1); static void putstring (const char[], int = 1);
static int putchar_ASCII (int); static int putchar_ASCII (int);
static int putchar_UTF8 (int); static int putchar_UTF8 (int);
@ -303,6 +298,7 @@ class FTerm final
; ;
private: private:
// Methods // Methods
static FStartOptions& getStartOptions();
static void init_global_values (bool); static void init_global_values (bool);
static void init_terminal_device_path(); static void init_terminal_device_path();
static void oscPrefix(); static void oscPrefix();
@ -386,6 +382,21 @@ class FTerm final
}; };
// non-member function forward declarations
//----------------------------------------------------------------------
wchar_t cp437_to_unicode (uChar);
uChar unicode_to_cp437 (wchar_t);
FString getFullWidth (const FString&);
FString getHalfWidth (const FString&);
std::size_t getColumnWidthToLength (const FString&, std::size_t);
FString getColumnSubString (const FString&, std::size_t, std::size_t);
std::size_t getColumnWidth (const FString&, std::size_t);
std::size_t getColumnWidth (const FString&);
std::size_t getColumnWidth (const wchar_t);
std::size_t getColumnWidth (charData&);
std::size_t getColumnWidth (const FTermBuffer&);
// FTerm inline functions // FTerm inline functions
//---------------------------------------------------------------------- //----------------------------------------------------------------------
inline const char* FTerm::getClassName() const inline const char* FTerm::getClassName() const
@ -403,6 +414,16 @@ inline bool FTerm::setUTF8()
inline bool FTerm::unsetUTF8() inline bool FTerm::unsetUTF8()
{ return setUTF8(false); } { return setUTF8(false); }
//----------------------------------------------------------------------
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);
}
} // namespace finalcut } // namespace finalcut

View File

@ -53,10 +53,14 @@ class FTermBuffer
{ {
public: public:
// Typedef // Typedef
typedef std::vector<charData> charDataVector; typedef std::vector<charData> charDataVector;
typedef charDataVector::iterator iterator;
typedef charDataVector::const_iterator const_iterator;
// Constructor // Constructor
FTermBuffer() = default; FTermBuffer() = default;
template<typename Iterator>
FTermBuffer (Iterator, Iterator);
// Destructor // Destructor
virtual ~FTermBuffer(); virtual ~FTermBuffer();
@ -64,6 +68,7 @@ class FTermBuffer
// Overloaded operators // Overloaded operators
template <typename typeT> template <typename typeT>
FTermBuffer& operator << (const typeT&); FTermBuffer& operator << (const typeT&);
FTermBuffer& operator << (const charDataVector&);
FTermBuffer& operator << (const std::string&); FTermBuffer& operator << (const std::string&);
FTermBuffer& operator << (const std::wstring&); FTermBuffer& operator << (const std::wstring&);
FTermBuffer& operator << (const FColorPair&); FTermBuffer& operator << (const FColorPair&);
@ -81,8 +86,16 @@ class FTermBuffer
bool isEmpty() const; bool isEmpty() const;
// Methods // Methods
iterator begin();
iterator end();
const_iterator begin() const;
const_iterator end() const;
charData front() const;
charData back() const;
const FString toString() const;
void clear(); void clear();
int writef (const FString, ...); template<typename... Args>
int writef (const FString, Args&&...);
int write (const FString&); int write (const FString&);
int write (wchar_t); int write (wchar_t);
void write (const FColorPair&); void write (const FColorPair&);
@ -94,6 +107,13 @@ class FTermBuffer
// FTermBuffer inline functions // FTermBuffer inline functions
//----------------------------------------------------------------------
template<typename Iterator>
inline FTermBuffer::FTermBuffer(Iterator first, Iterator last)
{
data.assign(first, last);
}
//---------------------------------------------------------------------- //----------------------------------------------------------------------
template <typename typeT> template <typename typeT>
inline FTermBuffer& FTermBuffer::operator << (const typeT& s) inline FTermBuffer& FTermBuffer::operator << (const typeT& s)
@ -107,6 +127,15 @@ inline FTermBuffer& FTermBuffer::operator << (const typeT& s)
return *this; return *this;
} }
//----------------------------------------------------------------------
inline FTermBuffer& FTermBuffer::operator << (const charDataVector& vec)
{
for (auto&& tc : vec)
data.push_back(tc);
return *this;
}
//---------------------------------------------------------------------- //----------------------------------------------------------------------
inline FTermBuffer& FTermBuffer::operator << (const std::string& string) inline FTermBuffer& FTermBuffer::operator << (const std::string& string)
{ {
@ -144,6 +173,30 @@ inline const FTermBuffer::charDataVector& FTermBuffer::getBuffer() const
inline bool FTermBuffer::isEmpty() const inline bool FTermBuffer::isEmpty() const
{ return data.empty(); } { return data.empty(); }
//----------------------------------------------------------------------
inline FTermBuffer::iterator FTermBuffer::begin()
{ return data.begin(); }
//----------------------------------------------------------------------
inline FTermBuffer::iterator FTermBuffer::end()
{ return data.end(); }
//----------------------------------------------------------------------
inline FTermBuffer::const_iterator FTermBuffer::begin() const
{ return data.begin(); }
//----------------------------------------------------------------------
inline FTermBuffer::const_iterator FTermBuffer::end() const
{ return data.end(); }
//----------------------------------------------------------------------
inline charData FTermBuffer::front() const
{ return data.front(); }
//----------------------------------------------------------------------
inline charData FTermBuffer::back() const
{ return data.back(); }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
inline void FTermBuffer::clear() inline void FTermBuffer::clear()
{ {
@ -151,6 +204,22 @@ inline void FTermBuffer::clear()
data.shrink_to_fit(); data.shrink_to_fit();
} }
//----------------------------------------------------------------------
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);
return write(str);
}
//---------------------------------------------------------------------- //----------------------------------------------------------------------
inline FTermBuffer& FTermBuffer::write() inline FTermBuffer& FTermBuffer::write()
{ return *this; } { return *this; }

View File

@ -148,6 +148,7 @@ class FTextView : public FWidget
, FTextViewCallback ); , FTextViewCallback );
void draw() override; void draw() override;
void drawText(); void drawText();
bool isPrintable (wchar_t);
void processChanged(); void processChanged();
// Callback methods // Callback methods

View File

@ -107,8 +107,7 @@ class FToolTip : public FWindow
// Data members // Data members
FString text{}; FString text{};
FString* text_components{nullptr}; FStringList text_components{};
FStringList text_split{};
std::size_t max_line_width{0}; std::size_t max_line_width{0};
std::size_t text_num_lines{0}; std::size_t text_num_lines{0};
}; };

View File

@ -118,30 +118,31 @@ typedef struct
struct struct
{ {
// Attribute byte #0 // Attribute byte #0
uInt8 bold : 1; // bold uInt8 bold : 1; // bold
uInt8 dim : 1; // dim uInt8 dim : 1; // dim
uInt8 italic : 1; // italic uInt8 italic : 1; // italic
uInt8 underline : 1; // underline uInt8 underline : 1; // underline
uInt8 blink : 1; // blink uInt8 blink : 1; // blink
uInt8 reverse : 1; // reverse uInt8 reverse : 1; // reverse
uInt8 standout : 1; // standout uInt8 standout : 1; // standout
uInt8 invisible : 1; // invisible uInt8 invisible : 1; // invisible
// Attribute byte #1 // Attribute byte #1
uInt8 protect : 1; // protect mode uInt8 protect : 1; // protect mode
uInt8 crossed_out : 1; // crossed out uInt8 crossed_out : 1; // crossed out
uInt8 dbl_underline : 1; // double underline uInt8 dbl_underline : 1; // double underline
uInt8 alt_charset : 1; // alternate character set (vt100) uInt8 alt_charset : 1; // alternate character set (vt100)
uInt8 pc_charset : 1; // pc character set (CP437) uInt8 pc_charset : 1; // pc character set (CP437)
uInt8 transparent : 1; // transparent uInt8 transparent : 1; // transparent
uInt8 trans_shadow : 1; // transparent shadow uInt8 trans_shadow : 1; // transparent shadow
uInt8 inherit_bg : 1; // inherit background uInt8 inherit_bg : 1; // inherit background
// Attribute byte #2 // Attribute byte #2
uInt8 no_changes : 1; // no changes required uInt8 no_changes : 1; // no changes required
uInt8 printed : 1; // is printed to VTerm uInt8 printed : 1; // is printed to VTerm
uInt8 char_with : 2; // Number of character cells on screen uInt8 fullwidth_padding : 1; // padding char (after a full-width char)
uInt8 : 4; // padding bits uInt8 char_width : 2; // number of character cells on screen
uInt8 : 3; // padding bits
// Attribute byte #3 // Attribute byte #3
uInt8 : 8; // padding byte uInt8 : 8; // padding byte
} bit; } bit;
uInt8 byte[4]; uInt8 byte[4];

View File

@ -291,7 +291,8 @@ class FVTerm
, FPreprocessingHandler ); , FPreprocessingHandler );
virtual void delPreprocessingHandler (FVTerm*); virtual void delPreprocessingHandler (FVTerm*);
int printf (const FString, ...); template<typename... Args>
int printf (const FString, Args&&...);
int print (const FString&); int print (const FString&);
int print (term_area*, const FString&); int print (term_area*, const FString&);
int print (const FTermBuffer&); int print (const FTermBuffer&);
@ -440,10 +441,19 @@ class FVTerm
static bool canClearTrailingWS (uInt&, uInt); static bool canClearTrailingWS (uInt&, uInt);
bool skipUnchangedCharacters (uInt&, uInt, uInt); bool skipUnchangedCharacters (uInt&, uInt, uInt);
void printRange (uInt, uInt, uInt, bool); void printRange (uInt, uInt, uInt, bool);
void replaceNonPrintableFullwidth (uInt, charData*&);
void printCharacter (uInt&, uInt, bool, charData*&);
void printFullWidthCharacter (uInt&, uInt, charData*&);
void printFullWidthPaddingCharacter (uInt&, uInt, charData*&);
void printHalfCovertFullWidthCharacter (uInt&, uInt, charData*&);
void skipPaddingCharacter (uInt&, uInt, charData*&);
exit_state eraseCharacters (uInt&, uInt, uInt, bool); exit_state eraseCharacters (uInt&, uInt, uInt, bool);
exit_state repeatCharacter (uInt&, uInt, uInt); exit_state repeatCharacter (uInt&, uInt, uInt);
bool isFullWidthChar (charData*&);
bool isFullWidthPaddingChar (charData*&);
static void cursorWrap(); static void cursorWrap();
bool printWrap (term_area*); bool printWrap (term_area*);
void printPaddingCharacter (term_area*, charData&);
void updateTerminalLine (uInt); void updateTerminalLine (uInt);
bool updateTerminalCursor(); bool updateTerminalCursor();
bool isInsideTerminal (const FPoint&); bool isInsideTerminal (const FPoint&);
@ -1033,6 +1043,22 @@ inline bool FVTerm::hasChangedTermSize()
inline bool FVTerm::hasUTF8() inline bool FVTerm::hasUTF8()
{ return FTerm::hasUTF8(); } { return FTerm::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);
return print(str);
}
//---------------------------------------------------------------------- //----------------------------------------------------------------------
inline FVTerm& FVTerm::print() inline FVTerm& FVTerm::print()
{ return *this; } { return *this; }

View File

@ -11,10 +11,12 @@ SRCS = $(wildcard *.cpp)
OBJS = $(SRCS:%.cpp=%) OBJS = $(SRCS:%.cpp=%)
CCXFLAGS = $(OPTIMIZE) $(PROFILE) $(DEBUG) -std=c++11 CCXFLAGS = $(OPTIMIZE) $(PROFILE) $(DEBUG) -std=c++11
MAKEFILE = -f Makefile.clang MAKEFILE = -f Makefile.clang
LDFLAGS = -L../src -lfinal -lcppunit -ldl LDFLAGS = -L../src -lfinal $(TERMCAP) -lcppunit -ldl
INCLUDES = -I. -I../src/include -I/usr/include/final INCLUDES = -I. -I../src/include -I/usr/include/final
RM = rm -f RM = rm -f
TERMCAP := $(shell test -n "$$(ldd {/usr,}/lib64/libncursesw.so.5 2>/dev/null | grep libtinfo)" && echo "-ltinfo" || echo "-lncurses")
ifdef DEBUG ifdef DEBUG
OPTIMIZE = -O0 -fsanitize=undefined OPTIMIZE = -O0 -fsanitize=undefined
else else
@ -28,11 +30,11 @@ endif
all: $(OBJS) all: $(OBJS)
debug: unittest:
$(MAKE) $(MAKEFILE) DEBUG="-g -D DEBUG -DUNIT_TEST -Wall -Wextra -Wpedantic -Wno-padded -Wno-c++98-compat -Wno-c++98-compat-pedantic -Wno-implicit-fallthrough" $(MAKE) $(MAKEFILE) DEBUG="-g -D DEBUG -DUNIT_TEST -Wall -Wextra -Wpedantic -Wno-padded -Wno-c++98-compat -Wno-c++98-compat-pedantic -Wno-implicit-fallthrough"
check: test check: test
test: debug test: unittest
$(OBJS) | sed -e "s/ OK/\x1b[32m OK\x1b[0m/g" -e "s/ failed/\x1b[31m failed\x1b[0m/g" $(OBJS) | sed -e "s/ OK/\x1b[32m OK\x1b[0m/g" -e "s/ failed/\x1b[31m failed\x1b[0m/g"
profile: profile:

View File

@ -11,10 +11,12 @@ SRCS = $(wildcard *.cpp)
OBJS = $(SRCS:%.cpp=%) OBJS = $(SRCS:%.cpp=%)
CCXFLAGS = $(OPTIMIZE) $(PROFILE) $(DEBUG) -std=c++11 CCXFLAGS = $(OPTIMIZE) $(PROFILE) $(DEBUG) -std=c++11
MAKEFILE = -f Makefile.gcc MAKEFILE = -f Makefile.gcc
LDFLAGS = -L../src -lfinal -lcppunit -ldl LDFLAGS = -L../src -lfinal $(TERMCAP) -lcppunit -ldl
INCLUDES = -I. -I../src/include -I/usr/include/final INCLUDES = -I. -I../src/include -I/usr/include/final
RM = rm -f RM = rm -f
TERMCAP := $(shell test -n "$$(ldd {/usr,}/lib64/libncursesw.so.5 2>/dev/null | grep libtinfo)" && echo "-ltinfo" || echo "-lncurses")
ifdef DEBUG ifdef DEBUG
OPTIMIZE = -O0 OPTIMIZE = -O0
else else
@ -28,11 +30,11 @@ endif
all: $(OBJS) all: $(OBJS)
debug: unittest:
$(MAKE) $(MAKEFILE) DEBUG="-g -D DEBUG -DUNIT_TEST -Wall -Wextra -Wpedantic" $(MAKE) $(MAKEFILE) DEBUG="-g -D DEBUG -DUNIT_TEST -Wall -Wextra -Wpedantic"
check: test check: test
test: debug test: unittest
$(OBJS) | sed -e "s/ OK/\x1b[32m OK\x1b[0m/g" -e "s/ failed/\x1b[31m failed\x1b[0m/g" $(OBJS) | sed -e "s/ OK/\x1b[32m OK\x1b[0m/g" -e "s/ failed/\x1b[31m failed\x1b[0m/g"
profile: profile:

View File

@ -551,7 +551,8 @@ inline pid_t ConEmu::forkConEmu()
while ( ! *shared_state && i < timeout ) while ( ! *shared_state && i < timeout )
{ {
// Wait 10 ms (= 10,000,000 ns) // Wait 10 ms (= 10,000,000 ns)
nanosleep ((const struct timespec[]){{0, 10000000L}}, NULL); const struct timespec ms[]{{0, 10000000L}};
nanosleep (ms, NULL);
i++; i++;
} }

View File

@ -348,7 +348,8 @@ void FKeyboardTest::escapeKeyTest()
input("\033"); input("\033");
processInput(); processInput();
// Wait 100 ms (= 100,000,000 ns) // Wait 100 ms (= 100,000,000 ns)
nanosleep ((const struct timespec[]){{0, 100000000L}}, NULL); const struct timespec ms[]{{0, 100000000L}};
nanosleep (ms, NULL);
keyboard->escapeKeyHandling(); keyboard->escapeKeyHandling();
std::cout << " - Key: " << keyboard->getKeyName(key_pressed) << std::endl; std::cout << " - Key: " << keyboard->getKeyName(key_pressed) << std::endl;
CPPUNIT_ASSERT ( key_pressed == finalcut::fc::Fkey_escape ); CPPUNIT_ASSERT ( key_pressed == finalcut::fc::Fkey_escape );
@ -2078,7 +2079,8 @@ void FKeyboardTest::metaKeyTest()
input("\033O"); input("\033O");
processInput(); processInput();
// Wait 100 ms - Substring keys needs a timeout // Wait 100 ms - Substring keys needs a timeout
nanosleep ((const struct timespec[]){{0, 100000000L}}, NULL); const struct timespec ms[]{{0, 100000000L}};
nanosleep (ms, NULL);
keyboard->escapeKeyHandling(); keyboard->escapeKeyHandling();
std::cout << " - Key: " << keyboard->getKeyName(key_pressed) << std::endl; std::cout << " - Key: " << keyboard->getKeyName(key_pressed) << std::endl;
CPPUNIT_ASSERT ( key_pressed == finalcut::fc::Fmkey_O ); CPPUNIT_ASSERT ( key_pressed == finalcut::fc::Fmkey_O );
@ -2165,7 +2167,7 @@ void FKeyboardTest::metaKeyTest()
input("\033["); input("\033[");
processInput(); processInput();
// Wait 100 ms - Substring keys needs a timeout // Wait 100 ms - Substring keys needs a timeout
nanosleep ((const struct timespec[]){{0, 100000000L}}, NULL); nanosleep (ms, NULL);
keyboard->escapeKeyHandling(); keyboard->escapeKeyHandling();
std::cout << " - Key: " << keyboard->getKeyName(key_pressed) << std::endl; std::cout << " - Key: " << keyboard->getKeyName(key_pressed) << std::endl;
CPPUNIT_ASSERT ( key_pressed == finalcut::fc::Fmkey_left_square_bracket ); CPPUNIT_ASSERT ( key_pressed == finalcut::fc::Fmkey_left_square_bracket );
@ -2182,7 +2184,7 @@ void FKeyboardTest::metaKeyTest()
input("\033]"); input("\033]");
processInput(); processInput();
// Wait 100 ms - Substring keys needs a timeout // Wait 100 ms - Substring keys needs a timeout
nanosleep ((const struct timespec[]){{0, 100000000L}}, NULL); nanosleep (ms, NULL);
keyboard->escapeKeyHandling(); keyboard->escapeKeyHandling();
std::cout << " - Key: " << keyboard->getKeyName(key_pressed) << std::endl; std::cout << " - Key: " << keyboard->getKeyName(key_pressed) << std::endl;
CPPUNIT_ASSERT ( key_pressed == finalcut::fc::Fmkey_right_square_bracket ); CPPUNIT_ASSERT ( key_pressed == finalcut::fc::Fmkey_right_square_bracket );

View File

@ -551,7 +551,8 @@ void FObjectTest::performTimerActionTest()
{ {
num_events += t1.processEvent(); num_events += t1.processEvent();
// Wait 100 ms // Wait 100 ms
nanosleep ((const struct timespec[]){{0, 100000000L}}, NULL); const struct timespec ms[]{{0, 100000000L}};
nanosleep (ms, NULL);
loop++; loop++;
} }

View File

@ -973,7 +973,7 @@ void FStringTest::iteratorTest()
CPPUNIT_ASSERT ( str.front() == L'1' ); CPPUNIT_ASSERT ( str.front() == L'1' );
CPPUNIT_ASSERT ( str.back() == L'9' ); CPPUNIT_ASSERT ( str.back() == L'9' );
finalcut::FString::iterator iter = str.begin(); finalcut::FString::const_iterator iter = str.begin();
CPPUNIT_ASSERT ( (*iter) == L'1' ); CPPUNIT_ASSERT ( (*iter) == L'1' );
++iter; ++iter;
CPPUNIT_ASSERT ( (*iter) == L'2' ); CPPUNIT_ASSERT ( (*iter) == L'2' );
@ -993,6 +993,17 @@ void FStringTest::iteratorTest()
CPPUNIT_ASSERT ( (*iter) == L'9' ); CPPUNIT_ASSERT ( (*iter) == L'9' );
++iter; ++iter;
CPPUNIT_ASSERT ( iter == str.end() ); CPPUNIT_ASSERT ( iter == str.end() );
finalcut::FString str2("bcdefg");
finalcut::FString::iterator iter2 = str2.begin();
while ( iter2 != str2.end() )
{
*iter2 -= 1;
++iter2;
}
CPPUNIT_ASSERT ( str2 == L"abcdef" );
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------

View File

@ -73,8 +73,8 @@ class FSystemTest : public finalcut::FSystem
private: private:
// Data members // Data members
std::string characters; std::string characters{};
int cursor_type = 0; int cursor_type{0};
static keymap_t keymap; static keymap_t keymap;
static keymap_t terminal_keymap; static keymap_t terminal_keymap;
}; };
@ -401,10 +401,10 @@ int FSystemTest::isTTY (int fd)
//---------------------------------------------------------------------- //----------------------------------------------------------------------
int FSystemTest::ioctl (int fd, uLong request, ...) int FSystemTest::ioctl (int fd, uLong request, ...)
{ {
va_list args; va_list args{};
void* argp; void* argp{};
std::string req_string; std::string req_string{};
int ret_val = -1; int ret_val{-1};
va_start (args, request); va_start (args, request);
argp = va_arg (args, void*); argp = va_arg (args, void*);
@ -481,7 +481,7 @@ int FSystemTest::ioctl (int fd, uLong request, ...)
//---------------------------------------------------------------------- //----------------------------------------------------------------------
int FSystemTest::open (const char* pathname, int flags, ...) int FSystemTest::open (const char* pathname, int flags, ...)
{ {
va_list args; va_list args{};
va_start (args, flags); va_start (args, flags);
mode_t mode = static_cast<mode_t>(va_arg (args, int)); mode_t mode = static_cast<mode_t>(va_arg (args, int));
va_end (args); va_end (args);
@ -622,12 +622,11 @@ void ftermfreebsdTest::freebsdConsoleTest()
setenv ("COLUMNS", "80", 1); setenv ("COLUMNS", "80", 1);
setenv ("LINES", "25", 1); setenv ("LINES", "25", 1);
finalcut::FTermData* data;
finalcut::FSystem* fsys = new test::FSystemTest(); finalcut::FSystem* fsys = new test::FSystemTest();
finalcut::FTermDetection* term_detection; finalcut::FTermDetection* term_detection{};
finalcut::FTerm::setFSystem(fsys); finalcut::FTerm::setFSystem(fsys);
std::cout << "\n"; std::cout << "\n";
data = finalcut::FTerm::getFTermData(); finalcut::FTermData* data = finalcut::FTerm::getFTermData();
auto& encoding_list = data->getEncodingList(); auto& encoding_list = data->getEncodingList();
encoding_list["UTF-8"] = finalcut::fc::UTF8; encoding_list["UTF-8"] = finalcut::fc::UTF8;
@ -698,45 +697,46 @@ void ftermfreebsdTest::freebsdConsoleTest()
freebsd.setCursorStyle(freebsd.getCursorStyle()); freebsd.setCursorStyle(freebsd.getCursorStyle());
CPPUNIT_ASSERT ( freebsd.getCursorStyle() == finalcut::fc::blink_cursor ); CPPUNIT_ASSERT ( freebsd.getCursorStyle() == finalcut::fc::blink_cursor );
CPPUNIT_ASSERT ( finalcut::fc::character[2][finalcut::fc::PC] == 21 ); finalcut::fc::encoding enc = finalcut::fc::PC;
CPPUNIT_ASSERT ( finalcut::fc::character[3][finalcut::fc::PC] == 8 ); CPPUNIT_ASSERT ( finalcut::fc::character[2][enc] == 21 );
CPPUNIT_ASSERT ( finalcut::fc::character[4][finalcut::fc::PC] == 10 ); CPPUNIT_ASSERT ( finalcut::fc::character[3][enc] == 8 );
CPPUNIT_ASSERT ( finalcut::fc::character[5][finalcut::fc::PC] == 19 ); CPPUNIT_ASSERT ( finalcut::fc::character[4][enc] == 10 );
CPPUNIT_ASSERT ( finalcut::fc::character[6][finalcut::fc::PC] == 18 ); CPPUNIT_ASSERT ( finalcut::fc::character[5][enc] == 19 );
CPPUNIT_ASSERT ( finalcut::fc::character[8][finalcut::fc::PC] == 22 ); CPPUNIT_ASSERT ( finalcut::fc::character[6][enc] == 18 );
CPPUNIT_ASSERT ( finalcut::fc::character[9][finalcut::fc::PC] == 24 ); CPPUNIT_ASSERT ( finalcut::fc::character[8][enc] == 22 );
CPPUNIT_ASSERT ( finalcut::fc::character[10][finalcut::fc::PC] == 25 ); CPPUNIT_ASSERT ( finalcut::fc::character[9][enc] == 24 );
CPPUNIT_ASSERT ( finalcut::fc::character[11][finalcut::fc::PC] == 26 ); CPPUNIT_ASSERT ( finalcut::fc::character[10][enc] == 25 );
CPPUNIT_ASSERT ( finalcut::fc::character[12][finalcut::fc::PC] == 27 ); CPPUNIT_ASSERT ( finalcut::fc::character[11][enc] == 26 );
CPPUNIT_ASSERT ( finalcut::fc::character[23][finalcut::fc::PC] == 4 ); CPPUNIT_ASSERT ( finalcut::fc::character[12][enc] == 27 );
CPPUNIT_ASSERT ( finalcut::fc::character[25][finalcut::fc::PC] == 4 ); CPPUNIT_ASSERT ( finalcut::fc::character[23][enc] == 4 );
CPPUNIT_ASSERT ( finalcut::fc::character[26][finalcut::fc::PC] == 4 ); CPPUNIT_ASSERT ( finalcut::fc::character[25][enc] == 4 );
CPPUNIT_ASSERT ( finalcut::fc::character[57][finalcut::fc::PC] == 16 ); CPPUNIT_ASSERT ( finalcut::fc::character[26][enc] == 4 );
CPPUNIT_ASSERT ( finalcut::fc::character[58][finalcut::fc::PC] == 17 ); CPPUNIT_ASSERT ( finalcut::fc::character[57][enc] == 16 );
CPPUNIT_ASSERT ( finalcut::fc::character[59][finalcut::fc::PC] == 16 ); CPPUNIT_ASSERT ( finalcut::fc::character[58][enc] == 17 );
CPPUNIT_ASSERT ( finalcut::fc::character[60][finalcut::fc::PC] == 17 ); CPPUNIT_ASSERT ( finalcut::fc::character[59][enc] == 16 );
CPPUNIT_ASSERT ( finalcut::fc::character[105][finalcut::fc::PC] == 4 ); CPPUNIT_ASSERT ( finalcut::fc::character[60][enc] == 17 );
CPPUNIT_ASSERT ( finalcut::fc::character[105][enc] == 4 );
freebsd.initCharMap(); freebsd.initCharMap();
CPPUNIT_ASSERT ( finalcut::fc::character[2][finalcut::fc::PC] == 36 ); CPPUNIT_ASSERT ( finalcut::fc::character[2][enc] == 36 );
CPPUNIT_ASSERT ( finalcut::fc::character[3][finalcut::fc::PC] == 42 ); CPPUNIT_ASSERT ( finalcut::fc::character[3][enc] == 42 );
CPPUNIT_ASSERT ( finalcut::fc::character[4][finalcut::fc::PC] == 42 ); CPPUNIT_ASSERT ( finalcut::fc::character[4][enc] == 42 );
CPPUNIT_ASSERT ( finalcut::fc::character[5][finalcut::fc::PC] == 33 ); CPPUNIT_ASSERT ( finalcut::fc::character[5][enc] == 33 );
CPPUNIT_ASSERT ( finalcut::fc::character[6][finalcut::fc::PC] == 73 ); CPPUNIT_ASSERT ( finalcut::fc::character[6][enc] == 73 );
CPPUNIT_ASSERT ( finalcut::fc::character[8][finalcut::fc::PC] == 95 ); CPPUNIT_ASSERT ( finalcut::fc::character[8][enc] == 95 );
CPPUNIT_ASSERT ( finalcut::fc::character[9][finalcut::fc::PC] == 94 ); CPPUNIT_ASSERT ( finalcut::fc::character[9][enc] == 94 );
CPPUNIT_ASSERT ( finalcut::fc::character[10][finalcut::fc::PC] == 118 ); CPPUNIT_ASSERT ( finalcut::fc::character[10][enc] == 118 );
CPPUNIT_ASSERT ( finalcut::fc::character[11][finalcut::fc::PC] == 62 ); CPPUNIT_ASSERT ( finalcut::fc::character[11][enc] == 62 );
CPPUNIT_ASSERT ( finalcut::fc::character[12][finalcut::fc::PC] == 60 ); CPPUNIT_ASSERT ( finalcut::fc::character[12][enc] == 60 );
CPPUNIT_ASSERT ( finalcut::fc::character[23][finalcut::fc::PC] == 42 ); CPPUNIT_ASSERT ( finalcut::fc::character[23][enc] == 42 );
CPPUNIT_ASSERT ( finalcut::fc::character[25][finalcut::fc::PC] == 42 ); CPPUNIT_ASSERT ( finalcut::fc::character[25][enc] == 42 );
CPPUNIT_ASSERT ( finalcut::fc::character[26][finalcut::fc::PC] == 42 ); CPPUNIT_ASSERT ( finalcut::fc::character[26][enc] == 42 );
CPPUNIT_ASSERT ( finalcut::fc::character[57][finalcut::fc::PC] == 62 ); CPPUNIT_ASSERT ( finalcut::fc::character[57][enc] == 62 );
CPPUNIT_ASSERT ( finalcut::fc::character[58][finalcut::fc::PC] == 60 ); CPPUNIT_ASSERT ( finalcut::fc::character[58][enc] == 60 );
CPPUNIT_ASSERT ( finalcut::fc::character[59][finalcut::fc::PC] == 62 ); CPPUNIT_ASSERT ( finalcut::fc::character[59][enc] == 62 );
CPPUNIT_ASSERT ( finalcut::fc::character[60][finalcut::fc::PC] == 60 ); CPPUNIT_ASSERT ( finalcut::fc::character[60][enc] == 60 );
CPPUNIT_ASSERT ( finalcut::fc::character[105][finalcut::fc::PC] == 42 ); CPPUNIT_ASSERT ( finalcut::fc::character[105][enc] == 42 );
term_detection->detect(); term_detection->detect();

View File

@ -145,10 +145,10 @@ class FSystemTest : public finalcut::FSystem
0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d,
0x0e, 0x0f, 0x0c, 0x00, 0x0f, 0x08, 0x00 0x0e, 0x0f, 0x0c, 0x00, 0x0f, 0x08, 0x00
}; };
uChar ac_index = 0; uChar ac_index{0};
bool palette_addr_source_field = true; bool palette_addr_source_field{true};
uChar port_3cc = 0x67; // Miscellaneous output uChar port_3cc{0x67}; // Miscellaneous output
uChar port_3da = 0; // Input status 1 uChar port_3da{0}; // Input status 1
static uChar vga8x16[]; static uChar vga8x16[];
static struct unipair unicode_cp437_pairs[]; static struct unipair unicode_cp437_pairs[];
}; };
@ -965,12 +965,12 @@ FSystemTest::rgb FSystemTest::defaultColor[16]
// static class attributes // static class attributes
//---------------------------------------------------------------------- //----------------------------------------------------------------------
FSystemTest::shiftstate FSystemTest::shift_state; FSystemTest::shiftstate FSystemTest::shift_state{};
struct console_font_op FSystemTest::terminal_font; struct console_font_op FSystemTest::terminal_font{};
unimapdesc FSystemTest::terminal_unicode_map; unimapdesc FSystemTest::terminal_unicode_map{};
struct fb_var_screeninfo FSystemTest::fb_terminal_info; struct fb_var_screeninfo FSystemTest::fb_terminal_info{};
struct fb_fix_screeninfo FSystemTest::fb_terminal_fix_info; struct fb_fix_screeninfo FSystemTest::fb_terminal_fix_info{};
bool FSystemTest::vga_port_access = false; bool FSystemTest::vga_port_access{false};
// constructors and destructor // constructors and destructor
@ -1062,10 +1062,10 @@ int FSystemTest::isTTY (int fd)
//---------------------------------------------------------------------- //----------------------------------------------------------------------
int FSystemTest::ioctl (int fd, uLong request, ...) int FSystemTest::ioctl (int fd, uLong request, ...)
{ {
va_list args; va_list args{};
void* argp; void* argp{};
std::string req_string; std::string req_string{};
int ret_val = -1; int ret_val{-1};
va_start (args, request); va_start (args, request);
argp = va_arg (args, void*); argp = va_arg (args, void*);
@ -1290,7 +1290,7 @@ int FSystemTest::ioctl (int fd, uLong request, ...)
//---------------------------------------------------------------------- //----------------------------------------------------------------------
int FSystemTest::open (const char* pathname, int flags, ...) int FSystemTest::open (const char* pathname, int flags, ...)
{ {
va_list args; va_list args{};
va_start (args, flags); va_start (args, flags);
mode_t mode = static_cast<mode_t>(va_arg (args, int)); mode_t mode = static_cast<mode_t>(va_arg (args, int));
va_end (args); va_end (args);
@ -1518,13 +1518,11 @@ void FTermLinuxTest::classNameTest()
//---------------------------------------------------------------------- //----------------------------------------------------------------------
void FTermLinuxTest::linuxConsoleTest() void FTermLinuxTest::linuxConsoleTest()
{ {
finalcut::FTermData* data; finalcut::FSystem* fsys = new test::FSystemTest();
finalcut::FSystem* fsys;
fsys = new test::FSystemTest();
finalcut::FTerm::setFSystem(fsys); finalcut::FTerm::setFSystem(fsys);
finalcut::FTermDetection* term_detection; finalcut::FTermDetection* term_detection{};
std::cout << "\n"; std::cout << "\n";
data = finalcut::FTerm::getFTermData(); finalcut::FTermData* data = finalcut::FTerm::getFTermData();
auto& encoding_list = data->getEncodingList(); auto& encoding_list = data->getEncodingList();
encoding_list["UTF-8"] = finalcut::fc::UTF8; encoding_list["UTF-8"] = finalcut::fc::UTF8;
@ -1642,13 +1640,11 @@ void FTermLinuxTest::linuxConsoleTest()
//---------------------------------------------------------------------- //----------------------------------------------------------------------
void FTermLinuxTest::linuxCursorStyleTest() void FTermLinuxTest::linuxCursorStyleTest()
{ {
finalcut::FTermData* data; finalcut::FSystem* fsys = new test::FSystemTest();
finalcut::FSystem* fsys;
fsys = new test::FSystemTest();
finalcut::FTerm::setFSystem(fsys); finalcut::FTerm::setFSystem(fsys);
finalcut::FTermDetection* term_detection; finalcut::FTermDetection* term_detection{};
std::cout << "\n"; std::cout << "\n";
data = finalcut::FTerm::getFTermData(); finalcut::FTermData* data = finalcut::FTerm::getFTermData();
auto& encoding_list = data->getEncodingList(); auto& encoding_list = data->getEncodingList();
encoding_list["UTF-8"] = finalcut::fc::UTF8; encoding_list["UTF-8"] = finalcut::fc::UTF8;
@ -1833,13 +1829,11 @@ void FTermLinuxTest::linuxCursorStyleTest()
//---------------------------------------------------------------------- //----------------------------------------------------------------------
void FTermLinuxTest::linuxColorPaletteTest() void FTermLinuxTest::linuxColorPaletteTest()
{ {
finalcut::FTermData* data; finalcut::FSystem* fsys = new test::FSystemTest();
finalcut::FSystem* fsys;
fsys = new test::FSystemTest();
finalcut::FTerm::setFSystem(fsys); finalcut::FTerm::setFSystem(fsys);
finalcut::FTermDetection* term_detection; finalcut::FTermDetection* term_detection{};
std::cout << "\n"; std::cout << "\n";
data = finalcut::FTerm::getFTermData(); finalcut::FTermData* data = finalcut::FTerm::getFTermData();
auto& encoding_list = data->getEncodingList(); auto& encoding_list = data->getEncodingList();
encoding_list["UTF-8"] = finalcut::fc::UTF8; encoding_list["UTF-8"] = finalcut::fc::UTF8;
@ -2111,13 +2105,11 @@ void FTermLinuxTest::linuxColorPaletteTest()
//---------------------------------------------------------------------- //----------------------------------------------------------------------
void FTermLinuxTest::linuxFontTest() void FTermLinuxTest::linuxFontTest()
{ {
finalcut::FTermData* data; finalcut::FSystem* fsys = new test::FSystemTest();
finalcut::FSystem* fsys;
fsys = new test::FSystemTest();
finalcut::FTerm::setFSystem(fsys); finalcut::FTerm::setFSystem(fsys);
finalcut::FTermDetection* term_detection; finalcut::FTermDetection* term_detection{};
std::cout << "\n"; std::cout << "\n";
data = finalcut::FTerm::getFTermData(); finalcut::FTermData* data = finalcut::FTerm::getFTermData();
auto& encoding_list = data->getEncodingList(); auto& encoding_list = data->getEncodingList();
encoding_list["UTF-8"] = finalcut::fc::UTF8; encoding_list["UTF-8"] = finalcut::fc::UTF8;
@ -2256,11 +2248,10 @@ void FTermLinuxTest::linuxFontTest()
//---------------------------------------------------------------------- //----------------------------------------------------------------------
void FTermLinuxTest::modifierKeyTest() void FTermLinuxTest::modifierKeyTest()
{ {
FKey keycode; FKey keycode{};
FKey mod_keycode; FKey mod_keycode{};
const finalcut::FTermLinux linux{}; const finalcut::FTermLinux linux{};
finalcut::FSystem* fsys; finalcut::FSystem* fsys(new test::FSystemTest());
fsys = new test::FSystemTest();
test::FSystemTest* fsystest = static_cast<test::FSystemTest*>(fsys); test::FSystemTest* fsystest = static_cast<test::FSystemTest*>(fsys);
test::FSystemTest::shiftstate& mod_key = fsystest->getShiftState(); test::FSystemTest::shiftstate& mod_key = fsystest->getShiftState();

View File

@ -88,8 +88,8 @@ class FSystemTest : public finalcut::FSystem
wskbd_bell_data& getBell(); wskbd_bell_data& getBell();
private: private:
kbd_t kbdencoding = 512; kbd_t kbdencoding{512};
wskbd_bell_data system_bell; wskbd_bell_data system_bell{};
}; };
@ -132,10 +132,10 @@ int FSystemTest::isTTY (int fd)
//---------------------------------------------------------------------- //----------------------------------------------------------------------
int FSystemTest::ioctl (int fd, uLong request, ...) int FSystemTest::ioctl (int fd, uLong request, ...)
{ {
va_list args; va_list args{};
void* argp; void* argp{};
std::string req_string; std::string req_string{};
int ret_val = -1; int ret_val{-1};
va_start (args, request); va_start (args, request);
argp = va_arg (args, void*); argp = va_arg (args, void*);
@ -218,7 +218,7 @@ int FSystemTest::ioctl (int fd, uLong request, ...)
//---------------------------------------------------------------------- //----------------------------------------------------------------------
int FSystemTest::open (const char* pathname, int flags, ...) int FSystemTest::open (const char* pathname, int flags, ...)
{ {
va_list args; va_list args{};
va_start (args, flags); va_start (args, flags);
mode_t mode = static_cast<mode_t>(va_arg (args, int)); mode_t mode = static_cast<mode_t>(va_arg (args, int));
va_end (args); va_end (args);
@ -345,13 +345,11 @@ void ftermopenbsdTest::classNameTest()
//---------------------------------------------------------------------- //----------------------------------------------------------------------
void ftermopenbsdTest::netbsdConsoleTest() void ftermopenbsdTest::netbsdConsoleTest()
{ {
finalcut::FTermData* data; finalcut::FSystem* fsys = new test::FSystemTest();
finalcut::FSystem* fsys;
fsys = new test::FSystemTest();
finalcut::FTerm::setFSystem(fsys); finalcut::FTerm::setFSystem(fsys);
finalcut::FTermDetection* term_detection; finalcut::FTermDetection* term_detection{};
std::cout << "\n"; std::cout << "\n";
data = finalcut::FTerm::getFTermData(); finalcut::FTermData* data = finalcut::FTerm::getFTermData();
auto& encoding_list = data->getEncodingList(); auto& encoding_list = data->getEncodingList();
encoding_list["UTF-8"] = finalcut::fc::UTF8; encoding_list["UTF-8"] = finalcut::fc::UTF8;
@ -452,13 +450,11 @@ void ftermopenbsdTest::netbsdConsoleTest()
//---------------------------------------------------------------------- //----------------------------------------------------------------------
void ftermopenbsdTest::openbsdConsoleTest() void ftermopenbsdTest::openbsdConsoleTest()
{ {
finalcut::FTermData* data; finalcut::FSystem* fsys = new test::FSystemTest();
finalcut::FSystem* fsys;
fsys = new test::FSystemTest();
finalcut::FTerm::setFSystem(fsys); finalcut::FTerm::setFSystem(fsys);
finalcut::FTermDetection* term_detection; finalcut::FTermDetection* term_detection{};
std::cout << "\n"; std::cout << "\n";
data = finalcut::FTerm::getFTermData(); finalcut::FTermData* data = finalcut::FTerm::getFTermData();
auto& encoding_list = data->getEncodingList(); auto& encoding_list = data->getEncodingList();
encoding_list["UTF-8"] = finalcut::fc::UTF8; encoding_list["UTF-8"] = finalcut::fc::UTF8;