Support for displaying full-width characters
This commit is contained in:
parent
e15f1a344a
commit
8c67f64db4
|
@ -49,6 +49,7 @@ examples/windows
|
|||
examples/term-attributes
|
||||
examples/transparent
|
||||
examples/input-dialog
|
||||
examples/fullwidth-character
|
||||
examples/7segment
|
||||
examples/choice
|
||||
examples/listbox
|
||||
|
|
|
@ -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>
|
||||
* Remove the lines of the #pragma pack() directive from the code
|
||||
because they caused a misaligned address
|
||||
|
|
25
README.md
25
README.md
|
@ -1,7 +1,12 @@
|
|||
![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](https://img.shields.io/github/release/gansm/finalcut.svg)](https://github.com/gansm/finalcut/releases) <br />
|
||||
*License:*<br />
|
||||
|
@ -15,12 +20,7 @@
|
|||
*Class Reference:*<br />
|
||||
     [![documented](https://codedocs.xyz/gansm/finalcut.svg)](https://codedocs.xyz/gansm/finalcut/hierarchy.html)
|
||||
|
||||
### Description
|
||||
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
|
||||
## Installation
|
||||
```bash
|
||||
> git clone git://github.com/gansm/finalcut.git
|
||||
> cd finalcut
|
||||
|
@ -30,7 +30,7 @@ The structure of the Qt framework was originally the inspiration for the C++ cla
|
|||
> su -c "make install"
|
||||
```
|
||||
|
||||
### Supported platforms
|
||||
## Supported platforms
|
||||
* Linux
|
||||
* FreeBSD
|
||||
* NetBSD
|
||||
|
@ -39,13 +39,12 @@ The structure of the Qt framework was originally the inspiration for the C++ cla
|
|||
* Cygwin
|
||||
* 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:
|
||||
The FFileDialog widget with incremental file name search:
|
||||
|
||||
![FFileDialog](doc/fileopen-dialog.png)
|
||||
|
||||
|
|
2
build.sh
2
build.sh
|
@ -59,7 +59,7 @@ case "$1" in
|
|||
;;
|
||||
|
||||
"--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
|
||||
echo "${RED}Configure failed!${NORMAL}" 1>&2
|
||||
exit 255
|
||||
|
|
|
@ -1,8 +1,20 @@
|
|||
AUTHORS
|
||||
COPYING
|
||||
COPYING.LESSER
|
||||
ChangeLog
|
||||
README.md
|
||||
doc/calendar-draft.png
|
||||
doc/calculator.png
|
||||
doc/class-diagram.txt
|
||||
doc/class_template.cpp
|
||||
doc/class_template.h
|
||||
doc/console_codes-manual.sh
|
||||
doc/console_ioctl-manual.sh
|
||||
doc/faq.md
|
||||
doc/fileopen-dialog.png
|
||||
doc/first-steps.md
|
||||
doc/framebuffer.txt
|
||||
doc/Mandelbrot.png
|
||||
doc/ncurses.supp
|
||||
doc/newfont1.png
|
||||
doc/newfont2.png
|
||||
|
@ -13,6 +25,8 @@ doc/terminfo-capabilities.sh
|
|||
doc/terminfo-manual.sh
|
||||
doc/textview.png
|
||||
doc/TODO
|
||||
doc/vga.txt
|
||||
doc/vt100_line_drawing_graphics.png
|
||||
doc/virtual-terminal.txt
|
||||
doc/xterm.txt
|
||||
doc/xgraphics
|
||||
|
|
|
@ -6,12 +6,17 @@ docdir = ${datadir}/doc/${PACKAGE}
|
|||
|
||||
EXTRA_DIST = \
|
||||
calendar-draft.png \
|
||||
calculator.png \
|
||||
class-diagram.txt \
|
||||
class_template.cpp \
|
||||
class_template.h \
|
||||
console_codes-manual.sh \
|
||||
console_ioctl-manual.sh \
|
||||
faq.md \
|
||||
fileopen-dialog.png \
|
||||
first-steps.md \
|
||||
framebuffer.txt \
|
||||
Mandelbrot.png \
|
||||
ncurses.supp \
|
||||
newfont1.png \
|
||||
newfont2.png \
|
||||
|
@ -22,18 +27,25 @@ EXTRA_DIST = \
|
|||
terminfo-manual.sh \
|
||||
textview.png \
|
||||
TODO \
|
||||
vga.txt \
|
||||
vt100_line_drawing_graphics.png \
|
||||
virtual-terminal.txt \
|
||||
xterm.txt \
|
||||
xgraphics
|
||||
|
||||
doc_DATA = \
|
||||
calendar-draft.png \
|
||||
calculator.png \
|
||||
class-diagram.txt \
|
||||
class_template.cpp \
|
||||
class_template.h \
|
||||
console_codes-manual.sh \
|
||||
console_ioctl-manual.sh \
|
||||
faq.md \
|
||||
fileopen-dialog.png \
|
||||
first-steps.md \
|
||||
framebuffer.txt \
|
||||
Mandelbrot.png \
|
||||
ncurses.supp \
|
||||
newfont1.png \
|
||||
newfont2.png \
|
||||
|
@ -44,6 +56,8 @@ doc_DATA = \
|
|||
terminfo-manual.sh \
|
||||
textview.png \
|
||||
TODO \
|
||||
vga.txt \
|
||||
vt100_line_drawing_graphics.png \
|
||||
virtual-terminal.txt \
|
||||
xterm.txt \
|
||||
xgraphics
|
||||
|
|
|
@ -11,6 +11,7 @@ noinst_PROGRAMS = \
|
|||
hello \
|
||||
dialog \
|
||||
input-dialog \
|
||||
fullwidth-character \
|
||||
7segment \
|
||||
choice \
|
||||
listbox \
|
||||
|
@ -36,6 +37,7 @@ noinst_PROGRAMS = \
|
|||
hello_SOURCES = hello.cpp
|
||||
dialog_SOURCES = dialog.cpp
|
||||
input_dialog_SOURCES = input-dialog.cpp
|
||||
fullwidth_character_SOURCES = fullwidth-character.cpp
|
||||
7segment_SOURCES = 7segment.cpp
|
||||
choice_SOURCES = choice.cpp
|
||||
listbox_SOURCES = listbox.cpp
|
||||
|
|
|
@ -73,14 +73,14 @@ CheckList::CheckList (finalcut::FWidget* parent)
|
|||
{
|
||||
setText (L"Shopping list");
|
||||
setShadow();
|
||||
setGeometry ( FPoint(int(1 + (parent->getWidth() - 30) / 2), 5)
|
||||
, FSize(30, 13) );
|
||||
setGeometry ( FPoint(int(1 + (parent->getWidth() - 28) / 2), 5)
|
||||
, FSize(28, 13) );
|
||||
listView.ignorePadding();
|
||||
listView.setGeometry (FPoint(1, 2), FSize(getWidth(), getHeight() - 1));
|
||||
|
||||
// Add columns to the view
|
||||
listView.addColumn ("Item");
|
||||
listView.addColumn ("Priority", 12);
|
||||
listView.addColumn ("Priority", 9);
|
||||
|
||||
// Set the type of sorting
|
||||
listView.setColumnSortType (1, fc::by_name);
|
||||
|
|
|
@ -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("&OK", &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"&File", &Menubar};
|
||||
finalcut::FMenuItem Edit{L"&Edit", &Menubar};
|
||||
finalcut::FMenuItem Exit{L"E&xit", &Menubar};
|
||||
|
||||
// Create file menu items
|
||||
finalcut::FMenuItem Open{"&Open", &File};
|
||||
finalcut::FMenuItem Print{"&Print", &File};
|
||||
finalcut::FMenuItem Line{&File};
|
||||
Line.setSeparator();
|
||||
finalcut::FMenuItem Quit{"&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();
|
||||
}
|
|
@ -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 *
|
||||
* *
|
||||
|
|
|
@ -118,8 +118,8 @@ Scrollview::~Scrollview()
|
|||
void Scrollview::setScrollSize (const FSize& size)
|
||||
{
|
||||
FScrollView::setScrollSize (size);
|
||||
auto width = int(size.getWidth());
|
||||
auto height = int(size.getHeight());
|
||||
int width = int(size.getWidth());
|
||||
int height = int(size.getHeight());
|
||||
go_south.setPos (FPoint(width - 5, 1));
|
||||
go_west.setPos (FPoint(width - 5, height - 1));
|
||||
go_north.setPos (FPoint(1, height - 1));
|
||||
|
@ -141,6 +141,7 @@ void Scrollview::draw()
|
|||
|
||||
for (int x{0}; x < int(getScrollWidth()); x++)
|
||||
print (32 + ((x + y) % 0x5f));
|
||||
|
||||
}
|
||||
|
||||
if ( isMonochron() )
|
||||
|
|
|
@ -643,7 +643,7 @@ void iteratorExample()
|
|||
{
|
||||
// Test: character access with std::iterator
|
||||
const finalcut::FString stringIterator{"iterator"};
|
||||
finalcut::FString::iterator iter;
|
||||
finalcut::FString::const_iterator iter;
|
||||
iter = stringIterator.begin();
|
||||
std::cout << " " << stringIterator << ": ";
|
||||
|
||||
|
|
|
@ -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 *
|
||||
* *
|
||||
|
@ -556,6 +556,7 @@ void MyDialog::initWidgets()
|
|||
// A multiple selection listbox
|
||||
myList.setGeometry(FPoint(38, 1), FSize(14, 17));
|
||||
myList.setText ("Items");
|
||||
|
||||
myList.setStatusbarMessage ("99 items in a list");
|
||||
myList.setMultiSelection();
|
||||
myList.reserve(100);
|
||||
|
@ -737,7 +738,7 @@ void MyDialog::adjustSize()
|
|||
{
|
||||
auto h = getParentWidget()->getHeight() - 4;
|
||||
setHeight (h, false);
|
||||
auto X = int((getDesktopWidth() - getWidth()) / 2);
|
||||
int X = int((getDesktopWidth() - getWidth()) / 2);
|
||||
|
||||
if ( X < 1 )
|
||||
X = 1;
|
||||
|
|
|
@ -344,10 +344,10 @@ void Window::adjustSize()
|
|||
{
|
||||
std::size_t w = getDesktopWidth();
|
||||
std::size_t h = getDesktopHeight();
|
||||
int X = int(1 + (w - 40) / 2)
|
||||
, Y = int(1 + (h - 22) / 2)
|
||||
, dx = ( w > 80 ) ? int(w - 80) / 2 : 0
|
||||
, dy = ( h > 24 ) ? int(h - 24) / 2 : 0;
|
||||
int X = int(1 + (w - 40) / 2);
|
||||
int Y = int(1 + (h - 22) / 2);
|
||||
int dx = ( w > 80 ) ? int(w - 80) / 2 : 0;
|
||||
int dy = ( h > 24 ) ? int(h - 24) / 2 : 0;
|
||||
|
||||
if ( Y < 2 )
|
||||
Y = 2;
|
||||
|
@ -360,9 +360,9 @@ void Window::adjustSize()
|
|||
{
|
||||
if ( (*iter)->is_open )
|
||||
{
|
||||
int n = int(std::distance(first, iter))
|
||||
, x = dx + 5 + (n % 3) * 25 + int(n / 3) * 3
|
||||
, y = dy + 11 + int(n / 3) * 3;
|
||||
int n = int(std::distance(first, iter));
|
||||
int x = dx + 5 + (n % 3) * 25 + int(n / 3) * 3;
|
||||
int y = dy + 11 + int(n / 3) * 3;
|
||||
(*iter)->dgl->setPos (FPoint(x, y));
|
||||
}
|
||||
|
||||
|
|
|
@ -45,6 +45,7 @@ libfinal_la_SOURCES = \
|
|||
fkey_map.cpp \
|
||||
fcharmap.cpp \
|
||||
ftextview.cpp \
|
||||
fstartoptions.cpp \
|
||||
fstatusbar.cpp \
|
||||
ftermcap.cpp \
|
||||
ftermcapquirks.cpp \
|
||||
|
@ -114,6 +115,7 @@ finalcutinclude_HEADERS = \
|
|||
include/final/frect.h \
|
||||
include/final/fscrollbar.h \
|
||||
include/final/fscrollview.h \
|
||||
include/final/fstartoptions.h \
|
||||
include/final/fstatusbar.h \
|
||||
include/final/fstring.h \
|
||||
include/final/fsystem.h \
|
||||
|
|
|
@ -48,6 +48,7 @@ INCLUDE_HEADERS = \
|
|||
fmouse.h \
|
||||
fkeyboard.h \
|
||||
ftermcap.h \
|
||||
fstartoptions.h \
|
||||
fterm.h \
|
||||
ftermdata.h \
|
||||
ftermdebugdata.h \
|
||||
|
@ -114,6 +115,7 @@ OBJS = \
|
|||
fsystem.o \
|
||||
fsystemimpl.o \
|
||||
fkeyboard.o \
|
||||
fstartoptions.o \
|
||||
ftermcap.o \
|
||||
fterm.o \
|
||||
ftermdebugdata.o \
|
||||
|
@ -159,7 +161,10 @@ all: dep $(OBJS)
|
|||
$(LIB): all
|
||||
|
||||
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:
|
||||
$(MAKE) $(MAKEFILE) PROFILE="-pg"
|
||||
|
|
|
@ -47,6 +47,7 @@ INCLUDE_HEADERS = \
|
|||
fsystemimpl.h \
|
||||
fmouse.h \
|
||||
fkeyboard.h \
|
||||
fstartoptions.h \
|
||||
ftermcap.h \
|
||||
fterm.h \
|
||||
ftermdata.h \
|
||||
|
@ -115,6 +116,7 @@ OBJS = \
|
|||
fsystemimpl.o \
|
||||
fkeyboard.o \
|
||||
ftermcap.o \
|
||||
fstartoptions.o \
|
||||
fterm.o \
|
||||
ftermdebugdata.o \
|
||||
ftermios.o \
|
||||
|
@ -160,6 +162,9 @@ $(LIB): all
|
|||
debug:
|
||||
$(MAKE) $(MAKEFILE) DEBUG="-g -D DEBUG -Wall -Wextra -Wpedantic"
|
||||
|
||||
unittest:
|
||||
$(MAKE) $(MAKEFILE) DEBUG="-g -D DEBUG -DUNIT_TEST -Wall -Wextra -Wpedantic"
|
||||
|
||||
profile:
|
||||
$(MAKE) $(MAKEFILE) PROFILE="-pg"
|
||||
|
||||
|
|
|
@ -489,6 +489,12 @@ void FApplication::cmd_options (const int& argc, char* argv[])
|
|||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
inline FStartOptions& FApplication::getStartOptions()
|
||||
{
|
||||
return FStartOptions::getFStartOptions();
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
inline void FApplication::findKeyboardWidget()
|
||||
{
|
||||
|
|
|
@ -238,7 +238,7 @@ void FButton::hide()
|
|||
}
|
||||
else
|
||||
{
|
||||
const FWidgetColors& wc = getFWidgetColors();
|
||||
const auto& wc = getFWidgetColors();
|
||||
fg = wc.dialog_fg;
|
||||
bg = wc.dialog_bg;
|
||||
}
|
||||
|
@ -410,7 +410,7 @@ void FButton::onFocusOut (FFocusEvent*)
|
|||
//----------------------------------------------------------------------
|
||||
void FButton::init()
|
||||
{
|
||||
const FWidgetColors& wc = getFWidgetColors();
|
||||
const auto& wc = getFWidgetColors();
|
||||
setForegroundColor (wc.button_active_fg);
|
||||
setBackgroundColor (wc.button_active_bg);
|
||||
setShadow();
|
||||
|
@ -424,6 +424,9 @@ void FButton::setHotkeyAccelerator()
|
|||
{
|
||||
FKey hotkey = getHotkey(text);
|
||||
|
||||
if ( hotkey > 0xff00 && hotkey < 0xff5f ) // full-width character
|
||||
hotkey -= 0xfee0;
|
||||
|
||||
if ( hotkey )
|
||||
{
|
||||
if ( std::isalpha(int(hotkey)) || std::isdigit(int(hotkey)) )
|
||||
|
@ -466,9 +469,9 @@ inline std::size_t FButton::clickAnimationIndent (FWidget* parent_widget)
|
|||
setColor ( parent_widget->getForegroundColor()
|
||||
, 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;
|
||||
|
@ -563,10 +566,10 @@ inline void FButton::drawButtonTextLine (wchar_t button_text[])
|
|||
print() << FPoint(2 + int(indent), 1 + int(vcenter_offset))
|
||||
<< FColorPair (button_fg, button_bg);
|
||||
|
||||
if ( getWidth() < txtlength + 1 )
|
||||
if ( getWidth() < column_width + 1 )
|
||||
center_offset = 0;
|
||||
else
|
||||
center_offset = (getWidth() - txtlength - 1) / 2;
|
||||
center_offset = (getWidth() - column_width - 1) / 2;
|
||||
|
||||
// Print button text line
|
||||
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) )
|
||||
setBold();
|
||||
|
||||
for ( std::size_t z{0}
|
||||
; pos < center_offset + txtlength && z + 2 < getWidth()
|
||||
; z++, pos++)
|
||||
for ( std::size_t z{0}, columns{0}
|
||||
; pos < center_offset + column_width && columns + 2 < getWidth()
|
||||
; z++)
|
||||
{
|
||||
if ( z == hotkeypos && getFlags().active )
|
||||
{
|
||||
|
@ -613,9 +616,13 @@ inline void FButton::drawButtonTextLine (wchar_t button_text[])
|
|||
{
|
||||
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() << FPoint(int(getWidth() + indent) - 2, 1) << "..";
|
||||
|
@ -624,7 +631,7 @@ inline void FButton::drawButtonTextLine (wchar_t button_text[])
|
|||
if ( active_focus && (isMonochron() || getMaxColor() < 16) )
|
||||
unsetBold();
|
||||
|
||||
for (pos = center_offset + txtlength; pos < getWidth() - 2; pos++)
|
||||
for (pos = center_offset + column_width; pos < getWidth() - 2; pos++)
|
||||
print (space_char); // █
|
||||
}
|
||||
|
||||
|
@ -633,7 +640,8 @@ void FButton::draw()
|
|||
{
|
||||
wchar_t* button_text{};
|
||||
auto parent_widget = getParentWidget();
|
||||
txtlength = text.getLength();
|
||||
auto txtlength = text.getLength();
|
||||
column_width = getColumnWidth(text);
|
||||
space_char = int(' ');
|
||||
active_focus = getFlags().active && getFlags().focus;
|
||||
|
||||
|
@ -668,7 +676,7 @@ void FButton::draw()
|
|||
hotkeypos = finalcut::getHotkeyPos(text.wc_str(), button_text, uInt(txtlength));
|
||||
|
||||
if ( hotkeypos != NOT_SET )
|
||||
txtlength--;
|
||||
column_width--;
|
||||
|
||||
if ( getHeight() >= 2 )
|
||||
vcenter_offset = (getHeight() - 1) / 2;
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
|
||||
#include "final/fapplication.h"
|
||||
#include "final/fbuttongroup.h"
|
||||
#include "final/fcolorpair.h"
|
||||
#include "final/fevent.h"
|
||||
#include "final/fsize.h"
|
||||
#include "final/fstatusbar.h"
|
||||
|
@ -142,17 +143,12 @@ bool FButtonGroup::hasFocusedButton() const
|
|||
if ( buttonlist.empty() )
|
||||
return false;
|
||||
|
||||
auto iter = buttonlist.begin();
|
||||
auto last = buttonlist.end();
|
||||
|
||||
while ( iter != last )
|
||||
for (auto&& item : buttonlist)
|
||||
{
|
||||
auto toggle_button = static_cast<FToggleButton*>(*iter);
|
||||
auto toggle_button = static_cast<FToggleButton*>(item);
|
||||
|
||||
if ( toggle_button->hasFocus() )
|
||||
return true;
|
||||
|
||||
++iter;
|
||||
}
|
||||
|
||||
return false;
|
||||
|
@ -164,17 +160,12 @@ bool FButtonGroup::hasCheckedButton() const
|
|||
if ( buttonlist.empty() )
|
||||
return false;
|
||||
|
||||
auto iter = buttonlist.begin();
|
||||
auto last = buttonlist.end();
|
||||
|
||||
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() )
|
||||
return true;
|
||||
|
||||
++iter;
|
||||
}
|
||||
|
||||
return false;
|
||||
|
@ -189,14 +180,10 @@ void FButtonGroup::hide()
|
|||
|
||||
if ( ! buttonlist.empty() )
|
||||
{
|
||||
auto iter = buttonlist.begin();
|
||||
auto last = buttonlist.end();
|
||||
|
||||
while ( iter != last )
|
||||
for (auto&& item : buttonlist)
|
||||
{
|
||||
auto toggle_button = static_cast<FToggleButton*>(*iter);
|
||||
auto toggle_button = static_cast<FToggleButton*>(item);
|
||||
toggle_button->hide();
|
||||
++iter;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -207,7 +194,7 @@ void FButtonGroup::hide()
|
|||
}
|
||||
else
|
||||
{
|
||||
const FWidgetColors& wc = getFWidgetColors();
|
||||
const auto& wc = getFWidgetColors();
|
||||
fg = wc.dialog_fg;
|
||||
bg = wc.dialog_bg;
|
||||
}
|
||||
|
@ -323,13 +310,11 @@ void FButtonGroup::onFocusIn (FFocusEvent* in_ev)
|
|||
{
|
||||
if ( hasCheckedButton() && ! buttonlist.empty() )
|
||||
{
|
||||
auto iter = buttonlist.begin();
|
||||
auto last = buttonlist.end();
|
||||
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() )
|
||||
{
|
||||
|
@ -356,9 +341,7 @@ void FButtonGroup::onFocusIn (FFocusEvent* in_ev)
|
|||
|
||||
break;
|
||||
}
|
||||
|
||||
++iter;
|
||||
}
|
||||
} // end of range-based for loop
|
||||
}
|
||||
|
||||
if ( ! in_ev->isAccepted() )
|
||||
|
@ -393,6 +376,9 @@ void FButtonGroup::setHotkeyAccelerator()
|
|||
{
|
||||
FKey hotkey = getHotkey(text);
|
||||
|
||||
if ( hotkey > 0xff00 && hotkey < 0xff5f ) // full-width character
|
||||
hotkey -= 0xfee0;
|
||||
|
||||
if ( hotkey )
|
||||
{
|
||||
if ( std::isalpha(int(hotkey)) || std::isdigit(int(hotkey)) )
|
||||
|
@ -478,10 +464,10 @@ bool FButtonGroup::isRadioButton (const FToggleButton* button) const
|
|||
//----------------------------------------------------------------------
|
||||
void FButtonGroup::init()
|
||||
{
|
||||
const FWidgetColors& wc = getFWidgetColors();
|
||||
const auto& wc = getFWidgetColors();
|
||||
setForegroundColor (wc.label_fg);
|
||||
setBackgroundColor (wc.label_bg);
|
||||
setMinimumSize (FSize(7, 4));
|
||||
setMinimumSize (FSize(7, 3));
|
||||
buttonlist.clear(); // no buttons yet
|
||||
}
|
||||
|
||||
|
@ -490,11 +476,21 @@ void FButtonGroup::drawText ( wchar_t LabelText[]
|
|||
, std::size_t hotkeypos
|
||||
, 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() )
|
||||
setReverse(true);
|
||||
|
||||
const FWidgetColors& wc = getFWidgetColors();
|
||||
|
||||
if ( isEnabled() )
|
||||
setColor(wc.label_emphasis_fg, wc.label_bg);
|
||||
else
|
||||
|
@ -520,6 +516,9 @@ void FButtonGroup::drawText ( wchar_t LabelText[]
|
|||
print (LabelText[z]);
|
||||
}
|
||||
|
||||
if ( ellipsis ) // Print ellipsis
|
||||
print() << FColorPair (wc.label_ellipsis_fg, wc.label_bg) << "..";
|
||||
|
||||
if ( isMonochron() )
|
||||
setReverse(true);
|
||||
}
|
||||
|
@ -533,12 +532,9 @@ void FButtonGroup::directFocus()
|
|||
|
||||
if ( hasCheckedButton() && ! buttonlist.empty() )
|
||||
{
|
||||
auto iter = buttonlist.begin();
|
||||
auto last = buttonlist.end();
|
||||
|
||||
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() )
|
||||
{
|
||||
|
@ -559,9 +555,7 @@ void FButtonGroup::directFocus()
|
|||
|
||||
break;
|
||||
}
|
||||
|
||||
++iter;
|
||||
}
|
||||
} // end of range-based for loop
|
||||
}
|
||||
|
||||
if ( ! found_checked )
|
||||
|
@ -598,12 +592,9 @@ void FButtonGroup::cb_buttonToggled (FWidget* widget, FDataPtr)
|
|||
if ( buttonlist.empty() )
|
||||
return;
|
||||
|
||||
auto iter = buttonlist.begin();
|
||||
auto last = buttonlist.end();
|
||||
|
||||
while ( iter != last )
|
||||
for (auto&& item : buttonlist)
|
||||
{
|
||||
auto toggle_button = static_cast<FToggleButton*>(*iter);
|
||||
auto toggle_button = static_cast<FToggleButton*>(item);
|
||||
|
||||
if ( toggle_button != button
|
||||
&& toggle_button->isChecked()
|
||||
|
@ -614,8 +605,6 @@ void FButtonGroup::cb_buttonToggled (FWidget* widget, FDataPtr)
|
|||
if ( toggle_button->isShown() )
|
||||
toggle_button->redraw();
|
||||
}
|
||||
|
||||
++iter;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
245
src/fcharmap.cpp
245
src/fcharmap.cpp
|
@ -50,6 +50,9 @@ uInt character[][fc::NUM_OF_ENCODINGS] =
|
|||
{0x2193, 'v', 0x19, 'v'}, // ↓ - DownwardsArrow
|
||||
{0x2192, '>', 0x1a, '>'}, // → - RightwardsArrow
|
||||
{0x2190, '<', 0x1b, '<'}, // ← - LeftwardsArrow
|
||||
{0x203a, '>', 0xaf, '>'}, // › - SingleRightAngleQuotationMark
|
||||
{0x2039, '<', 0xae, '<'}, // ‹ - SingleLeftAngleQuotationMark
|
||||
{0x2026, '.', '.', '.'}, // … - HorizontalEllipsis
|
||||
{0x03c0, '{', 0xe3, 'n'}, // π - Pi
|
||||
{0x207F, 'I', 0xfc, ' '}, // ⁿ - SuperscriptLatinSmallLetterN
|
||||
{0x2265, 'z', 0xf2, '>'}, // ≥ - GreaterThanOrEqualTo
|
||||
|
@ -464,6 +467,248 @@ wchar_t cp437_to_ucs[][2] =
|
|||
const std::size_t lastCP437Item = \
|
||||
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 -> 0
|
||||
{0x0031, 0xff11}, // 1 -> 1
|
||||
{0x0032, 0xff12}, // 2 -> 2
|
||||
{0x0033, 0xff13}, // 3 -> 3
|
||||
{0x0034, 0xff14}, // 4 -> 4
|
||||
{0x0035, 0xff15}, // 5 -> 5
|
||||
{0x0036, 0xff16}, // 6 -> 6
|
||||
{0x0037, 0xff17}, // 7 -> 7
|
||||
{0x0038, 0xff18}, // 8 -> 8
|
||||
{0x0039, 0xff19}, // 9 -> 9
|
||||
{0x003a, 0xff1a}, // : -> :
|
||||
{0x003b, 0xff1b}, // ; -> ;
|
||||
{0x003c, 0xff1c}, // < -> <
|
||||
{0x003d, 0xff1d}, // = -> =
|
||||
{0x003e, 0xff1e}, // > -> >
|
||||
{0x003f, 0xff1f}, // ? -> ?
|
||||
{0x0040, 0xff20}, // @ -> @
|
||||
{0x0041, 0xff21}, // A -> A
|
||||
{0x0042, 0xff22}, // B -> B
|
||||
{0x0043, 0xff23}, // C -> C
|
||||
{0x0044, 0xff24}, // D -> D
|
||||
{0x0045, 0xff25}, // E -> E
|
||||
{0x0046, 0xff26}, // F -> F
|
||||
{0x0047, 0xff27}, // G -> G
|
||||
{0x0048, 0xff28}, // H -> H
|
||||
{0x0049, 0xff29}, // I -> I
|
||||
{0x004a, 0xff2a}, // J -> J
|
||||
{0x004b, 0xff2b}, // K -> K
|
||||
{0x004c, 0xff2c}, // L -> L
|
||||
{0x004d, 0xff2d}, // M -> M
|
||||
{0x004e, 0xff2e}, // N -> N
|
||||
{0x004f, 0xff2f}, // O -> O
|
||||
{0x0050, 0xff30}, // P -> P
|
||||
{0x0051, 0xff31}, // Q -> Q
|
||||
{0x0052, 0xff32}, // R -> R
|
||||
{0x0053, 0xff33}, // S -> S
|
||||
{0x0054, 0xff34}, // T -> T
|
||||
{0x0055, 0xff35}, // U -> U
|
||||
{0x0056, 0xff36}, // V -> V
|
||||
{0x0057, 0xff37}, // W -> W
|
||||
{0x0058, 0xff38}, // X -> X
|
||||
{0x0059, 0xff39}, // Y -> Y
|
||||
{0x005a, 0xff3a}, // Z -> Z
|
||||
{0x005b, 0xff3b}, // [ -> [
|
||||
{0x005c, 0xff3c}, // \ -> \
|
||||
{0x005d, 0xff3c}, // ] -> ]
|
||||
{0x005e, 0xff3e}, // ^ -> ^
|
||||
{0x005f, 0xff3f}, // _ -> _
|
||||
{0x0060, 0xff40}, // ` -> `
|
||||
{0x0061, 0xff41}, // a -> a
|
||||
{0x0062, 0xff42}, // b -> b
|
||||
{0x0063, 0xff43}, // c -> c
|
||||
{0x0064, 0xff44}, // d -> d
|
||||
{0x0065, 0xff45}, // e -> e
|
||||
{0x0066, 0xff46}, // f -> f
|
||||
{0x0067, 0xff47}, // g -> g
|
||||
{0x0068, 0xff48}, // h -> h
|
||||
{0x0069, 0xff49}, // i -> i
|
||||
{0x006a, 0xff4a}, // j -> j
|
||||
{0x006b, 0xff4b}, // k -> k
|
||||
{0x006c, 0xff4c}, // l -> l
|
||||
{0x006d, 0xff4d}, // m -> m
|
||||
{0x006e, 0xff4e}, // n -> n
|
||||
{0x006f, 0xff4f}, // o -> o
|
||||
{0x0070, 0xff50}, // p -> p
|
||||
{0x0071, 0xff51}, // q -> q
|
||||
{0x0072, 0xff52}, // r -> r
|
||||
{0x0073, 0xff53}, // s -> s
|
||||
{0x0074, 0xff54}, // t -> t
|
||||
{0x0075, 0xff55}, // u -> u
|
||||
{0x0076, 0xff56}, // v -> v
|
||||
{0x0077, 0xff57}, // w -> w
|
||||
{0x0078, 0xff58}, // x -> x
|
||||
{0x0079, 0xff59}, // y -> y
|
||||
{0x007a, 0xff5a}, // z -> 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 finalcut
|
||||
|
|
|
@ -784,7 +784,7 @@ void FDialog::init()
|
|||
addDialog(this);
|
||||
setActiveWindow(this);
|
||||
setTransparentShadow();
|
||||
const FWidgetColors& wc = getFWidgetColors();
|
||||
const auto& wc = getFWidgetColors();
|
||||
setForegroundColor (wc.dialog_fg);
|
||||
setBackgroundColor (wc.dialog_bg);
|
||||
auto old_focus = FWidget::getFocusWidget();
|
||||
|
@ -908,7 +908,7 @@ void FDialog::drawBorder()
|
|||
if ( (getMoveSizeWidget() == this || ! resize_click_pos.isOrigin() )
|
||||
&& ! isZoomed() )
|
||||
{
|
||||
const FWidgetColors& wc = getFWidgetColors();
|
||||
const auto& wc = getFWidgetColors();
|
||||
setColor (wc.dialog_resize_fg, getBackgroundColor());
|
||||
}
|
||||
else
|
||||
|
@ -971,7 +971,7 @@ void FDialog::drawBarButton()
|
|||
{
|
||||
// Print the title button
|
||||
print() << FPoint(1, 1);
|
||||
const FWidgetColors& wc = getFWidgetColors();
|
||||
const auto& wc = getFWidgetColors();
|
||||
|
||||
if ( dialog_menu && dialog_menu->isShown() )
|
||||
setColor (wc.titlebar_button_focus_fg, wc.titlebar_button_focus_bg);
|
||||
|
@ -1024,7 +1024,7 @@ void FDialog::drawZoomButton()
|
|||
if ( ! isResizeable() )
|
||||
return;
|
||||
|
||||
const FWidgetColors& wc = getFWidgetColors();
|
||||
const auto& wc = getFWidgetColors();
|
||||
|
||||
if ( zoom_button_pressed )
|
||||
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)
|
||||
std::size_t center_offset{0};
|
||||
std::size_t x{1};
|
||||
const FWidgetColors& wc = getFWidgetColors();
|
||||
const auto& wc = getFWidgetColors();
|
||||
|
||||
if ( getMaxColor() < 16 )
|
||||
setBold();
|
||||
|
@ -1103,9 +1103,9 @@ void FDialog::drawTextBar()
|
|||
else
|
||||
setColor (wc.titlebar_inactive_fg, wc.titlebar_inactive_bg);
|
||||
|
||||
std::size_t width = getWidth();
|
||||
std::size_t zoom_btn = getZoomButtonWidth();
|
||||
std::size_t length = tb_text.getLength();
|
||||
auto width = getWidth();
|
||||
auto zoom_btn = getZoomButtonWidth();
|
||||
auto length = getColumnWidth(tb_text);
|
||||
|
||||
if ( width > length + MENU_BTN + zoom_btn )
|
||||
center_offset = (width - length - MENU_BTN - zoom_btn) / 2;
|
||||
|
|
|
@ -54,8 +54,8 @@ FDialogListMenu::~FDialogListMenu()
|
|||
//----------------------------------------------------------------------
|
||||
void FDialogListMenu::init()
|
||||
{
|
||||
auto menuitem = getItem();
|
||||
menuitem->dialog_index = true;
|
||||
auto m_item = getItem();
|
||||
m_item->dialog_index = true;
|
||||
}
|
||||
|
||||
} // namespace finalcut
|
||||
|
|
|
@ -701,7 +701,7 @@ int FFileDialog::changeDir (const FString& dirname)
|
|||
filename.setText('/');
|
||||
else
|
||||
{
|
||||
auto baseName = basename(C_STR(lastdir.c_str()));
|
||||
auto baseName = basename(lastdir.c_str());
|
||||
selectDirectoryEntry (baseName);
|
||||
}
|
||||
}
|
||||
|
@ -728,10 +728,16 @@ int FFileDialog::changeDir (const FString& dirname)
|
|||
void FFileDialog::printPath (const FString& 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 )
|
||||
filebrowser.setText(".." + path.right(max_width - 2));
|
||||
if ( column_width > max_width )
|
||||
{
|
||||
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
|
||||
filebrowser.setText(path);
|
||||
}
|
||||
|
|
|
@ -183,24 +183,6 @@ void FLabel::setAlignment (fc::text_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)
|
||||
{
|
||||
|
@ -342,7 +324,7 @@ void FLabel::init()
|
|||
}
|
||||
else
|
||||
{
|
||||
const FWidgetColors& wc = getFWidgetColors();
|
||||
const auto& wc = getFWidgetColors();
|
||||
setForegroundColor (wc.dialog_fg);
|
||||
setBackgroundColor (wc.dialog_bg);
|
||||
}
|
||||
|
@ -353,6 +335,9 @@ void FLabel::setHotkeyAccelerator()
|
|||
{
|
||||
FKey hotkey = getHotkey(text);
|
||||
|
||||
if ( hotkey > 0xff00 && hotkey < 0xff5f ) // full-width character
|
||||
hotkey -= 0xfee0;
|
||||
|
||||
if ( hotkey )
|
||||
{
|
||||
if ( std::isalpha(int(hotkey)) || std::isdigit(int(hotkey)) )
|
||||
|
@ -372,7 +357,7 @@ void FLabel::setHotkeyAccelerator()
|
|||
//----------------------------------------------------------------------
|
||||
std::size_t FLabel::getAlignOffset (std::size_t length)
|
||||
{
|
||||
std::size_t width = std::size_t(getWidth());
|
||||
std::size_t width(getWidth());
|
||||
|
||||
switch ( alignment )
|
||||
{
|
||||
|
@ -398,6 +383,9 @@ std::size_t FLabel::getAlignOffset (std::size_t length)
|
|||
//----------------------------------------------------------------------
|
||||
void FLabel::draw()
|
||||
{
|
||||
if ( text.isEmpty() )
|
||||
return;
|
||||
|
||||
if ( isMonochron() )
|
||||
{
|
||||
setReverse(true);
|
||||
|
@ -435,10 +423,11 @@ void FLabel::drawMultiLine()
|
|||
|
||||
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 align_offset{};
|
||||
std::size_t length = multiline_text[y].getLength();
|
||||
auto length = multiline_text[y].getLength();
|
||||
auto column_width = getColumnWidth(multiline_text[y]);
|
||||
|
||||
try
|
||||
{
|
||||
|
@ -463,13 +452,13 @@ void FLabel::drawMultiLine()
|
|||
if ( hotkeypos != NOT_SET )
|
||||
{
|
||||
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;
|
||||
}
|
||||
else
|
||||
{
|
||||
align_offset = getAlignOffset(length);
|
||||
printLine (label_text, length, NOT_SET, align_offset);
|
||||
printLine (label_text, length, column_width, NOT_SET, align_offset);
|
||||
}
|
||||
|
||||
y++;
|
||||
|
@ -480,9 +469,10 @@ void FLabel::drawMultiLine()
|
|||
//----------------------------------------------------------------------
|
||||
void FLabel::drawSingleLine()
|
||||
{
|
||||
wchar_t* label_text;
|
||||
wchar_t* label_text{};
|
||||
std::size_t hotkeypos{NOT_SET};
|
||||
std::size_t length = text.getLength();
|
||||
auto length = text.getLength();
|
||||
auto column_width = getColumnWidth(text);
|
||||
|
||||
try
|
||||
{
|
||||
|
@ -497,37 +487,48 @@ void FLabel::drawSingleLine()
|
|||
hotkeypos = finalcut::getHotkeyPos (text.wc_str(), label_text, length);
|
||||
|
||||
if ( hotkeypos != NOT_SET )
|
||||
{
|
||||
length--;
|
||||
column_width--;
|
||||
}
|
||||
|
||||
print() << FPoint(1, 1);
|
||||
std::size_t align_offset = getAlignOffset(length);
|
||||
printLine (label_text, length, hotkeypos, align_offset);
|
||||
auto align_offset = getAlignOffset(column_width);
|
||||
printLine (label_text, length, column_width, hotkeypos, align_offset);
|
||||
delete[] label_text;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
void FLabel::printLine ( wchar_t line[]
|
||||
, std::size_t length
|
||||
, std::size_t column_width
|
||||
, std::size_t hotkeypos
|
||||
, std::size_t align_offset )
|
||||
{
|
||||
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 )
|
||||
print (FString(align_offset, ' ')); // leading spaces
|
||||
|
||||
if ( length <= width )
|
||||
if ( column_width <= width )
|
||||
{
|
||||
to_char = length;
|
||||
to_column = column_width;
|
||||
}
|
||||
else
|
||||
to_char = width - 2;
|
||||
{
|
||||
to_column = width - 2;
|
||||
to_char = getColumnWidthToLength(line, to_column);
|
||||
}
|
||||
|
||||
if ( hasReverseMode() )
|
||||
setReverse(true);
|
||||
|
||||
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
|
||||
|| int(line[z]) > fc::NF_check_mark ) )
|
||||
|
@ -538,7 +539,7 @@ void FLabel::printLine ( wchar_t line[]
|
|||
|
||||
if ( z == hotkeypos && getFlags().active )
|
||||
{
|
||||
const FWidgetColors& wc = getFWidgetColors();
|
||||
const auto& wc = getFWidgetColors();
|
||||
setColor (wc.label_hotkey_fg, wc.label_hotkey_bg);
|
||||
|
||||
if ( ! getFlags().no_underline )
|
||||
|
@ -558,16 +559,16 @@ void FLabel::printLine ( wchar_t line[]
|
|||
print (line[z]);
|
||||
}
|
||||
|
||||
if ( length > width )
|
||||
if ( column_width > width )
|
||||
{
|
||||
// Print ellipsis
|
||||
print() << FColorPair(ellipsis_color, getBackgroundColor()) << "..";
|
||||
setColor();
|
||||
}
|
||||
else if ( align_offset + to_char < width )
|
||||
else if ( align_offset + to_column < width )
|
||||
{
|
||||
// Print trailing spaces
|
||||
std::size_t len = width - align_offset - to_char;
|
||||
std::size_t len = width - align_offset - to_column;
|
||||
print (FString(len, ' '));
|
||||
}
|
||||
|
||||
|
|
|
@ -168,7 +168,7 @@ const FLineEdit& FLineEdit::operator >> (FString& s)
|
|||
//----------------------------------------------------------------------
|
||||
bool FLineEdit::setEnable (bool enable)
|
||||
{
|
||||
const FWidgetColors& wc = getFWidgetColors();
|
||||
const auto& wc = getFWidgetColors();
|
||||
FWidget::setEnable(enable);
|
||||
|
||||
if ( enable )
|
||||
|
@ -196,7 +196,7 @@ bool FLineEdit::setEnable (bool enable)
|
|||
//----------------------------------------------------------------------
|
||||
bool FLineEdit::setFocus (bool enable)
|
||||
{
|
||||
const FWidgetColors& wc = getFWidgetColors();
|
||||
const auto& wc = getFWidgetColors();
|
||||
FWidget::setFocus(enable);
|
||||
|
||||
if ( enable )
|
||||
|
@ -263,7 +263,11 @@ void FLineEdit::setText (const FString& txt)
|
|||
else
|
||||
text.setString("");
|
||||
|
||||
keyEnd();
|
||||
if ( isShown() )
|
||||
{
|
||||
cursorEnd();
|
||||
adjustTextOffset();
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
@ -274,20 +278,26 @@ void FLineEdit::setMaxLength (std::size_t max)
|
|||
if ( text.getLength() > max_length )
|
||||
text.setString(text.left(max_length));
|
||||
|
||||
keyEnd();
|
||||
if ( isShown() )
|
||||
{
|
||||
cursorEnd();
|
||||
adjustTextOffset();
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
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() )
|
||||
keyEnd();
|
||||
else if ( cursor_pos + 1 >= getWidth() )
|
||||
text_offset = text.getLength() - getWidth() + 2;
|
||||
else
|
||||
text_offset = 0;
|
||||
cursor_pos = text.getLength();
|
||||
|
||||
if ( isShown() )
|
||||
adjustTextOffset();
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
@ -310,8 +320,11 @@ void FLineEdit::setGeometry ( const FPoint& pos, const FSize& size
|
|||
, bool adjust )
|
||||
{
|
||||
FWidget::setGeometry(pos, size, adjust);
|
||||
keyEnd();
|
||||
|
||||
if ( isShown() )
|
||||
adjustTextOffset();
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
void FLineEdit::hide()
|
||||
{
|
||||
|
@ -326,8 +339,9 @@ void FLineEdit::hide()
|
|||
//----------------------------------------------------------------------
|
||||
void FLineEdit::clear()
|
||||
{
|
||||
text_offset = 0;
|
||||
cursor_pos = 0;
|
||||
text_offset = 0;
|
||||
char_width_offset = 0;
|
||||
text.clear();
|
||||
}
|
||||
|
||||
|
@ -339,44 +353,44 @@ void FLineEdit::onKeyPress (FKeyEvent* ev)
|
|||
switch ( key )
|
||||
{
|
||||
case fc::Fkey_left:
|
||||
keyLeft();
|
||||
cursorLeft();
|
||||
ev->accept();
|
||||
break;
|
||||
|
||||
case fc::Fkey_right:
|
||||
keyRight();
|
||||
cursorRight();
|
||||
ev->accept();
|
||||
break;
|
||||
|
||||
case fc::Fkey_home:
|
||||
keyHome();
|
||||
cursorHome();
|
||||
ev->accept();
|
||||
break;
|
||||
|
||||
case fc::Fkey_end:
|
||||
keyEnd();
|
||||
cursorEnd();
|
||||
ev->accept();
|
||||
break;
|
||||
|
||||
case fc::Fkey_dc: // del key
|
||||
keyDel();
|
||||
deleteCurrentCharacter();
|
||||
ev->accept();
|
||||
break;
|
||||
|
||||
case fc::Fkey_erase:
|
||||
case fc::Fkey_backspace:
|
||||
keyBackspace();
|
||||
deletePreviousCharacter();
|
||||
ev->accept();
|
||||
break;
|
||||
|
||||
case fc::Fkey_ic: // insert key
|
||||
keyInsert();
|
||||
switchInsertMode();
|
||||
ev->accept();
|
||||
break;
|
||||
|
||||
case fc::Fkey_return:
|
||||
case fc::Fkey_enter:
|
||||
keyEnter();
|
||||
acceptInput();
|
||||
ev->accept();
|
||||
break;
|
||||
|
||||
|
@ -421,15 +435,19 @@ void FLineEdit::onMouseDown (FMouseEvent* ev)
|
|||
|
||||
int mouse_x = ev->getX();
|
||||
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();
|
||||
cursor_pos = text_offset + std::size_t(mouse_x) - 2;
|
||||
cursor_pos = clickPosToCursorPos (std::size_t(mouse_x) - 2);
|
||||
|
||||
if ( cursor_pos >= len )
|
||||
cursor_pos = len;
|
||||
|
||||
if ( mouse_x == int(getWidth()) )
|
||||
adjustTextOffset();
|
||||
|
||||
drawInputField();
|
||||
updateTerminal();
|
||||
}
|
||||
|
@ -458,11 +476,12 @@ void FLineEdit::onMouseMove (FMouseEvent* ev)
|
|||
|
||||
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 )
|
||||
cursor_pos = len;
|
||||
|
||||
adjustTextOffset();
|
||||
drawInputField();
|
||||
updateTerminal();
|
||||
}
|
||||
|
@ -487,14 +506,14 @@ void FLineEdit::onMouseMove (FMouseEvent* ev)
|
|||
else if ( mouse_x >= int(getWidth()) )
|
||||
{
|
||||
// drag right
|
||||
if ( ! scroll_timer && text_offset <= len - getWidth() + 1 )
|
||||
if ( ! scroll_timer && cursor_pos < len )
|
||||
{
|
||||
scroll_timer = true;
|
||||
addTimer(scroll_repeat);
|
||||
drag_scroll = FLineEdit::scrollRight;
|
||||
}
|
||||
|
||||
if ( text_offset == len - getWidth() + 2 )
|
||||
if ( cursor_pos == len )
|
||||
{
|
||||
delOwnTimer();
|
||||
drag_scroll = FLineEdit::noScroll;
|
||||
|
@ -512,7 +531,7 @@ void FLineEdit::onMouseMove (FMouseEvent* ev)
|
|||
//----------------------------------------------------------------------
|
||||
void FLineEdit::onTimer (FTimerEvent*)
|
||||
{
|
||||
std::size_t len = text.getLength();
|
||||
auto len = text.getLength();
|
||||
|
||||
switch ( int(drag_scroll) )
|
||||
{
|
||||
|
@ -534,14 +553,13 @@ void FLineEdit::onTimer (FTimerEvent*)
|
|||
break;
|
||||
|
||||
case FLineEdit::scrollRight:
|
||||
if ( len + 2 < getWidth()
|
||||
|| text_offset == len - getWidth() + 2 )
|
||||
if ( text_offset == endPosToOffset(len).first )
|
||||
{
|
||||
drag_scroll = FLineEdit::noScroll;
|
||||
return;
|
||||
}
|
||||
|
||||
if ( text_offset <= len - getWidth() + 1 )
|
||||
if ( text_offset < endPosToOffset(len).first )
|
||||
text_offset++;
|
||||
|
||||
if ( cursor_pos < len )
|
||||
|
@ -553,6 +571,7 @@ void FLineEdit::onTimer (FTimerEvent*)
|
|||
break;
|
||||
}
|
||||
|
||||
adjustTextOffset();
|
||||
drawInputField();
|
||||
updateTerminal();
|
||||
}
|
||||
|
@ -626,10 +645,10 @@ void FLineEdit::onFocusOut (FFocusEvent*)
|
|||
//----------------------------------------------------------------------
|
||||
void FLineEdit::adjustLabel()
|
||||
{
|
||||
std::size_t label_length = label_text.getLength();
|
||||
auto label_width = getColumnWidth(label_text);
|
||||
|
||||
if ( hasHotkey() )
|
||||
label_length--;
|
||||
label_width--;
|
||||
|
||||
assert ( label_orientation == label_above
|
||||
|| label_orientation == label_left );
|
||||
|
@ -638,12 +657,12 @@ void FLineEdit::adjustLabel()
|
|||
{
|
||||
case label_above:
|
||||
label->setGeometry ( FPoint(getX(), getY() - 1)
|
||||
, FSize(label_length, 1) );
|
||||
, FSize(label_width, 1) );
|
||||
break;
|
||||
|
||||
case label_left:
|
||||
label->setGeometry ( FPoint(getX() - int(label_length) - 1, getY())
|
||||
, FSize(label_length, 1) );
|
||||
label->setGeometry ( FPoint(getX() - int(label_width) - 1, getY())
|
||||
, FSize(label_width, 1) );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -653,6 +672,9 @@ void FLineEdit::adjustSize()
|
|||
{
|
||||
FWidget::adjustSize();
|
||||
adjustLabel();
|
||||
|
||||
if ( isShown() )
|
||||
adjustTextOffset();
|
||||
}
|
||||
|
||||
|
||||
|
@ -660,7 +682,7 @@ void FLineEdit::adjustSize()
|
|||
//----------------------------------------------------------------------
|
||||
void FLineEdit::init()
|
||||
{
|
||||
const FWidgetColors& wc = getFWidgetColors();
|
||||
const auto& wc = getFWidgetColors();
|
||||
label->setAccelWidget(this);
|
||||
setVisibleCursor();
|
||||
setShadow();
|
||||
|
@ -697,6 +719,12 @@ bool FLineEdit::hasHotkey()
|
|||
//----------------------------------------------------------------------
|
||||
void FLineEdit::draw()
|
||||
{
|
||||
if ( cursor_pos == NOT_SET )
|
||||
cursorEnd();
|
||||
|
||||
if ( ! isShown() )
|
||||
adjustTextOffset();
|
||||
|
||||
drawInputField();
|
||||
|
||||
if ( getFlags().focus && getStatusBar() )
|
||||
|
@ -737,12 +765,15 @@ void FLineEdit::drawInputField()
|
|||
if ( isActiveFocus && getMaxColor() < 16 )
|
||||
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 )
|
||||
print (show_text);
|
||||
|
||||
std::size_t x = show_text.getLength();
|
||||
std::size_t x = getColumnWidth(show_text);
|
||||
|
||||
while ( x + 1 < getWidth() )
|
||||
{
|
||||
|
@ -762,56 +793,174 @@ void FLineEdit::drawInputField()
|
|||
if ( getFlags().shadow )
|
||||
drawShadow ();
|
||||
|
||||
// set the cursor to the first pos.
|
||||
setCursorPos (FPoint(int(2 + cursor_pos - text_offset), 1));
|
||||
// set the cursor to the insert pos.
|
||||
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 )
|
||||
cursor_pos--;
|
||||
|
||||
if ( cursor_pos < text_offset )
|
||||
text_offset--;
|
||||
adjustTextOffset();
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
inline void FLineEdit::keyRight()
|
||||
inline void FLineEdit::cursorRight()
|
||||
{
|
||||
std::size_t len = text.getLength();
|
||||
auto len = text.getLength();
|
||||
|
||||
if ( cursor_pos < len )
|
||||
cursor_pos++;
|
||||
|
||||
if ( cursor_pos - text_offset + 2 >= getWidth()
|
||||
&& text_offset <= len - getWidth() + 1 )
|
||||
text_offset++;
|
||||
adjustTextOffset();
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
inline void FLineEdit::keyHome()
|
||||
inline void FLineEdit::cursorHome()
|
||||
{
|
||||
cursor_pos = 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;
|
||||
|
||||
if ( cursor_pos + 1 >= getWidth() )
|
||||
text_offset = len - getWidth() + 2;
|
||||
else
|
||||
text_offset = 0;
|
||||
adjustTextOffset();
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
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 )
|
||||
{
|
||||
|
@ -822,38 +971,34 @@ inline void FLineEdit::keyDel()
|
|||
if ( cursor_pos >= len )
|
||||
cursor_pos = len;
|
||||
|
||||
if ( text_offset > 0 && len - text_offset + 1 < getWidth() )
|
||||
text_offset--;
|
||||
adjustTextOffset();
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
inline void FLineEdit::keyBackspace()
|
||||
inline void FLineEdit::deletePreviousCharacter()
|
||||
{
|
||||
if ( text.getLength() > 0 && cursor_pos > 0 )
|
||||
{
|
||||
text.remove(cursor_pos - 1, 1);
|
||||
cursor_pos--;
|
||||
// Backspace functionality
|
||||
|
||||
if ( text_offset > 0 )
|
||||
text_offset--;
|
||||
if ( text.getLength() == 0 || cursor_pos == 0 )
|
||||
return;
|
||||
|
||||
processChanged();
|
||||
}
|
||||
cursorLeft();
|
||||
deleteCurrentCharacter();
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
inline void FLineEdit::keyInsert()
|
||||
inline void FLineEdit::switchInsertMode()
|
||||
{
|
||||
insert_mode = ! insert_mode;
|
||||
|
||||
if ( insert_mode )
|
||||
setInsertCursor();
|
||||
setInsertCursor(); // Insert mode
|
||||
else
|
||||
unsetInsertCursor();
|
||||
unsetInsertCursor(); // Overtype mode
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
inline void FLineEdit::keyEnter()
|
||||
inline void FLineEdit::acceptInput()
|
||||
{
|
||||
processActivate();
|
||||
}
|
||||
|
@ -869,28 +1014,28 @@ inline bool FLineEdit::keyInput (FKey key)
|
|||
|
||||
if ( key >= 0x20 && key <= 0x10fff )
|
||||
{
|
||||
std::size_t len = text.getLength();
|
||||
wchar_t c = characterFilter(wchar_t(key));
|
||||
auto len = text.getLength();
|
||||
auto ch = characterFilter(wchar_t(key));
|
||||
|
||||
if ( c == L'\0' )
|
||||
if ( ch == L'\0' )
|
||||
return false;
|
||||
else if ( cursor_pos == len )
|
||||
text += c;
|
||||
text += ch;
|
||||
else if ( len > 0 )
|
||||
{
|
||||
if ( insert_mode )
|
||||
text.insert(c, cursor_pos);
|
||||
else
|
||||
text.overwrite(c, cursor_pos);
|
||||
{
|
||||
text.insert(ch, cursor_pos);
|
||||
len++;
|
||||
}
|
||||
else
|
||||
text.setString(c);
|
||||
text.overwrite(ch, cursor_pos);
|
||||
}
|
||||
else
|
||||
text.setString(ch);
|
||||
|
||||
cursor_pos++;
|
||||
|
||||
if ( cursor_pos + 1 >= getWidth() )
|
||||
text_offset++;
|
||||
|
||||
adjustTextOffset();
|
||||
processChanged();
|
||||
return true;
|
||||
}
|
||||
|
|
191
src/flistbox.cpp
191
src/flistbox.cpp
|
@ -140,13 +140,13 @@ void FListBox::showInsideBrackets ( std::size_t index
|
|||
if ( b == fc::NoBrackets )
|
||||
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(max_line_width - getWidth() + nf_offset + 4)
|
||||
|
@ -222,9 +222,9 @@ void FListBox::hide()
|
|||
//----------------------------------------------------------------------
|
||||
void FListBox::insert (FListBoxItem listItem)
|
||||
{
|
||||
std::size_t len = listItem.text.getLength();
|
||||
bool has_brackets = bool(listItem.brackets);
|
||||
recalculateHorizontalBar (len, has_brackets);
|
||||
std::size_t column_width = getColumnWidth(listItem.text);
|
||||
bool has_brackets(listItem.brackets);
|
||||
recalculateHorizontalBar (column_width, has_brackets);
|
||||
|
||||
itemlist.push_back (listItem);
|
||||
|
||||
|
@ -244,10 +244,10 @@ void FListBox::remove (std::size_t item)
|
|||
|
||||
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 )
|
||||
max_line_width = len;
|
||||
if ( column_width > max_line_width )
|
||||
max_line_width = column_width;
|
||||
}
|
||||
|
||||
int hmax = ( max_line_width > getWidth() - nf_offset - 4 )
|
||||
|
@ -284,7 +284,6 @@ void FListBox::remove (std::size_t item)
|
|||
//----------------------------------------------------------------------
|
||||
void FListBox::clear()
|
||||
{
|
||||
std::size_t size;
|
||||
itemlist.clear();
|
||||
itemlist.shrink_to_fit();
|
||||
current = 0;
|
||||
|
@ -303,9 +302,9 @@ void FListBox::clear()
|
|||
hbar->hide();
|
||||
|
||||
// clear list from screen
|
||||
const FWidgetColors& wc = getFWidgetColors();
|
||||
const auto& wc = getFWidgetColors();
|
||||
setColor (wc.list_fg, wc.list_bg);
|
||||
size = getWidth() - 2;
|
||||
std::size_t size = getWidth() - 2;
|
||||
|
||||
if ( size == 0 )
|
||||
return;
|
||||
|
@ -335,69 +334,69 @@ void FListBox::onKeyPress (FKeyEvent* ev)
|
|||
{
|
||||
case fc::Fkey_return:
|
||||
case fc::Fkey_enter:
|
||||
keyEnter();
|
||||
acceptSelection();
|
||||
ev->accept();
|
||||
break;
|
||||
|
||||
case fc::Fkey_up:
|
||||
keyUp();
|
||||
onePosUp();
|
||||
ev->accept();
|
||||
break;
|
||||
|
||||
case fc::Fkey_down:
|
||||
keyDown();
|
||||
onePosDown();
|
||||
ev->accept();
|
||||
break;
|
||||
|
||||
case fc::Fkey_left:
|
||||
keyLeft();
|
||||
scrollLeft();
|
||||
ev->accept();
|
||||
break;
|
||||
|
||||
case fc::Fkey_right:
|
||||
keyRight();
|
||||
scrollRight();
|
||||
ev->accept();
|
||||
break;
|
||||
|
||||
case fc::Fkey_ppage:
|
||||
keyPgUp();
|
||||
onePageUp();
|
||||
ev->accept();
|
||||
break;
|
||||
|
||||
case fc::Fkey_npage:
|
||||
keyPgDn();
|
||||
onePageDown();
|
||||
ev->accept();
|
||||
break;
|
||||
|
||||
case fc::Fkey_home:
|
||||
keyHome();
|
||||
firstPos();
|
||||
ev->accept();
|
||||
break;
|
||||
|
||||
case fc::Fkey_end:
|
||||
keyEnd();
|
||||
lastPos();
|
||||
ev->accept();
|
||||
break;
|
||||
|
||||
case fc::Fkey_ic: // insert key
|
||||
if ( keyInsert() )
|
||||
if ( changeSelectionAndPosition() )
|
||||
ev->accept();
|
||||
break;
|
||||
|
||||
case fc::Fkey_space:
|
||||
if ( keySpace() )
|
||||
if ( spacebarProcessing() )
|
||||
ev->accept();
|
||||
break;
|
||||
|
||||
case fc::Fkey_erase:
|
||||
case fc::Fkey_backspace:
|
||||
if ( keyBackspace() )
|
||||
if ( deletePreviousCharacter() )
|
||||
ev->accept();
|
||||
break;
|
||||
|
||||
case fc::Fkey_escape:
|
||||
case fc::Fkey_escape_mintty:
|
||||
if ( keyEsc() )
|
||||
if ( skipIncrementalSearch() )
|
||||
ev->accept();
|
||||
break;
|
||||
|
||||
|
@ -416,8 +415,8 @@ void FListBox::onKeyPress (FKeyEvent* ev)
|
|||
|
||||
if ( ev->isAccepted() )
|
||||
{
|
||||
bool draw_vbar = yoffset_before != yoffset;
|
||||
bool draw_hbar = xoffset_before != xoffset;
|
||||
bool draw_vbar( yoffset_before != yoffset );
|
||||
bool draw_hbar( xoffset_before != xoffset );
|
||||
updateDrawing (draw_vbar, draw_hbar);
|
||||
}
|
||||
}
|
||||
|
@ -758,7 +757,7 @@ void FListBox::init()
|
|||
initScrollbar (vbar, fc::vertical, &FListBox::cb_VBarChange);
|
||||
initScrollbar (hbar, fc::horizontal, &FListBox::cb_HBarChange);
|
||||
setGeometry (FPoint(1, 1), FSize(5, 4), false); // initialize geometry values
|
||||
const FWidgetColors& wc = getFWidgetColors();
|
||||
const auto& wc = getFWidgetColors();
|
||||
setForegroundColor (wc.dialog_fg);
|
||||
setBackgroundColor (wc.dialog_bg);
|
||||
nf_offset = isNewFont() ? 1 : 0;
|
||||
|
@ -874,21 +873,21 @@ void FListBox::drawHeadline()
|
|||
return;
|
||||
|
||||
FString txt(" " + text + " ");
|
||||
std::size_t length = txt.getLength();
|
||||
auto column_width = getColumnWidth(txt);
|
||||
print() << FPoint(2, 1);
|
||||
const FWidgetColors& wc = getFWidgetColors();
|
||||
const auto& wc = getFWidgetColors();
|
||||
|
||||
if ( isEnabled() )
|
||||
setColor(wc.label_emphasis_fg, wc.label_bg);
|
||||
else
|
||||
setColor(wc.label_inactive_fg, wc.label_inactive_bg);
|
||||
|
||||
if ( length <= uInt(getClientWidth()) )
|
||||
if ( column_width <= getClientWidth() )
|
||||
print (txt);
|
||||
else
|
||||
{
|
||||
// Print ellipsis
|
||||
print() << text.left(uInt(getClientWidth() - 2))
|
||||
print() << getColumnSubString (text, 1, getClientWidth() - 2)
|
||||
<< FColorPair (wc.label_ellipsis_fg, wc.label_bg) << "..";
|
||||
}
|
||||
}
|
||||
|
@ -900,7 +899,7 @@ void FListBox::drawList()
|
|||
return;
|
||||
|
||||
std::size_t start{};
|
||||
std::size_t num = uInt(getHeight() - 2);
|
||||
std::size_t num(getHeight() - 2);
|
||||
|
||||
if ( num > getCount() )
|
||||
num = getCount();
|
||||
|
@ -954,12 +953,12 @@ inline void FListBox::drawListLine ( int y
|
|||
, bool serach_mark )
|
||||
{
|
||||
std::size_t inc_len = inc_search.getLength();
|
||||
const FWidgetColors& wc = getFWidgetColors();
|
||||
bool isCurrentLine = bool(y + yoffset + 1 == int(current));
|
||||
FString element (getString(iter).mid ( std::size_t(xoffset) + 1
|
||||
, getWidth() - nf_offset - 4 ));
|
||||
const wchar_t* const& element_str = element.wc_str();
|
||||
std::size_t len = element.getLength();
|
||||
const auto& wc = getFWidgetColors();
|
||||
bool isCurrentLine( y + yoffset + 1 == int(current) );
|
||||
std::size_t first = std::size_t(xoffset) + 1;
|
||||
std::size_t max_width = getWidth() - nf_offset - 4;
|
||||
FString element(getColumnSubString (getString(iter), first, max_width));
|
||||
std::size_t column_width = getColumnWidth(element);
|
||||
|
||||
if ( isMonochron() && isCurrentLine && getFlags().focus )
|
||||
print (fc::BlackRightPointingPointer); // ►
|
||||
|
@ -970,24 +969,22 @@ inline void FListBox::drawListLine ( int y
|
|||
setColor ( wc.current_inc_search_element_fg
|
||||
, wc.current_element_focus_bg );
|
||||
|
||||
std::size_t i{};
|
||||
|
||||
for (i = 0; i < len; i++)
|
||||
for (std::size_t i{0}; i < element.getLength(); i++)
|
||||
{
|
||||
if ( serach_mark && i == inc_len && getFlags().focus )
|
||||
setColor ( wc.current_element_focus_fg
|
||||
, wc.current_element_focus_bg );
|
||||
|
||||
print (element_str[i]);
|
||||
print (element[i]);
|
||||
}
|
||||
|
||||
if ( isMonochron() && isCurrentLine && getFlags().focus )
|
||||
{
|
||||
print (fc::BlackLeftPointingPointer); // ◄
|
||||
i++;
|
||||
column_width++;
|
||||
}
|
||||
|
||||
for (; i < getWidth() - nf_offset - 3; i++)
|
||||
for (; column_width < getWidth() - nf_offset - 3; column_width++)
|
||||
print (' ');
|
||||
}
|
||||
|
||||
|
@ -1010,10 +1007,9 @@ inline void FListBox::drawListBracketsLine ( int y
|
|||
, listBoxItems::iterator iter
|
||||
, bool serach_mark )
|
||||
{
|
||||
FString element{};
|
||||
std::size_t inc_len = inc_search.getLength()
|
||||
, b{0};
|
||||
bool isCurrentLine = bool(y + yoffset + 1 == int(current));
|
||||
bool isCurrentLine( y + yoffset + 1 == int(current) );
|
||||
|
||||
if ( isMonochron() && isCurrentLine && getFlags().focus )
|
||||
print (fc::BlackRightPointingPointer); // ►
|
||||
|
@ -1022,23 +1018,19 @@ inline void FListBox::drawListBracketsLine ( int y
|
|||
|
||||
if ( xoffset == 0 )
|
||||
{
|
||||
b = 1;
|
||||
b = 1; // Required bracket space
|
||||
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 full_length = getString(iter).getLength()
|
||||
, len = element.getLength()
|
||||
, i{0};
|
||||
const FWidgetColors& wc = getFWidgetColors();
|
||||
std::size_t first = std::size_t(xoffset);
|
||||
std::size_t max_width = getWidth() - nf_offset - 4 - b;
|
||||
FString element(getColumnSubString (getString(iter), first, max_width));
|
||||
std::size_t column_width = getColumnWidth(element);
|
||||
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 )
|
||||
setColor ( wc.current_inc_search_element_fg
|
||||
|
@ -1048,27 +1040,27 @@ inline void FListBox::drawListBracketsLine ( int y
|
|||
setColor ( wc.current_element_focus_fg
|
||||
, wc.current_element_focus_bg );
|
||||
|
||||
print (element_str[i]);
|
||||
print (element[i]);
|
||||
}
|
||||
|
||||
if ( b + i < getWidth() - nf_offset - 4
|
||||
&& std::size_t(xoffset) <= full_length + 1 )
|
||||
if ( b + column_width < getWidth() - nf_offset - 4
|
||||
&& std::size_t(xoffset) <= text_width )
|
||||
{
|
||||
if ( serach_mark && i == inc_len )
|
||||
setColor ( wc.current_element_focus_fg
|
||||
, wc.current_element_focus_bg );
|
||||
|
||||
printRightBracket (iter->brackets);
|
||||
i++;
|
||||
column_width++;
|
||||
}
|
||||
|
||||
if ( isMonochron() && isCurrentLine && getFlags().focus )
|
||||
{
|
||||
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 (' ');
|
||||
}
|
||||
|
||||
|
@ -1078,9 +1070,10 @@ inline void FListBox::setLineAttributes ( int y
|
|||
, bool lineHasBrackets
|
||||
, 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();
|
||||
const FWidgetColors& wc = getFWidgetColors();
|
||||
std::size_t inc_width = getColumnWidth(inc_search);
|
||||
const auto& wc = getFWidgetColors();
|
||||
print() << FPoint(2, 2 + int(y));
|
||||
|
||||
if ( isLineSelected )
|
||||
|
@ -1131,7 +1124,7 @@ inline void FListBox::setLineAttributes ( int y
|
|||
{
|
||||
serach_mark = true;
|
||||
// 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
|
||||
setCursorPos (FPoint(3 + b, 2 + int(y))); // first character
|
||||
|
@ -1554,35 +1547,35 @@ void FListBox::scrollRight (int distance)
|
|||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
inline void FListBox::keyUp()
|
||||
{
|
||||
prevListItem (1);
|
||||
inc_search.clear();
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
inline void FListBox::keyDown()
|
||||
{
|
||||
nextListItem (1);
|
||||
inc_search.clear();
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
inline void FListBox::keyLeft()
|
||||
inline void FListBox::scrollLeft()
|
||||
{
|
||||
scrollLeft(1);
|
||||
inc_search.clear();
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
inline void FListBox::keyRight()
|
||||
inline void FListBox::scrollRight()
|
||||
{
|
||||
scrollRight(1);
|
||||
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;
|
||||
prevListItem (pagesize);
|
||||
|
@ -1590,7 +1583,7 @@ inline void FListBox::keyPgUp()
|
|||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
inline void FListBox::keyPgDn()
|
||||
inline void FListBox::onePageDown()
|
||||
{
|
||||
int pagesize = int(getClientHeight()) - 1;
|
||||
nextListItem (pagesize);
|
||||
|
@ -1598,7 +1591,7 @@ inline void FListBox::keyPgDn()
|
|||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
inline void FListBox::keyHome()
|
||||
inline void FListBox::firstPos()
|
||||
{
|
||||
current = 1;
|
||||
yoffset = 0;
|
||||
|
@ -1606,7 +1599,7 @@ inline void FListBox::keyHome()
|
|||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
inline void FListBox::keyEnd()
|
||||
inline void FListBox::lastPos()
|
||||
{
|
||||
std::size_t element_count = getCount();
|
||||
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 )
|
||||
{
|
||||
|
@ -1631,18 +1624,18 @@ inline bool FListBox::keyEsc()
|
|||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
inline void FListBox::keyEnter()
|
||||
inline void FListBox::acceptSelection()
|
||||
{
|
||||
processClick();
|
||||
inc_search.clear();
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
inline bool FListBox::keySpace()
|
||||
inline bool FListBox::spacebarProcessing()
|
||||
{
|
||||
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' ';
|
||||
bool inc_found{false};
|
||||
|
@ -1668,7 +1661,7 @@ inline bool FListBox::keySpace()
|
|||
return false;
|
||||
}
|
||||
}
|
||||
else if ( isMultiSelection() )
|
||||
else if ( isMultiSelection() ) // Change selection
|
||||
{
|
||||
if ( isSelected(current) )
|
||||
unselectItem(current);
|
||||
|
@ -1683,7 +1676,7 @@ inline bool FListBox::keySpace()
|
|||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
inline bool FListBox::keyInsert()
|
||||
inline bool FListBox::changeSelectionAndPosition()
|
||||
{
|
||||
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();
|
||||
|
||||
|
@ -1810,8 +1803,8 @@ void FListBox::lazyConvert(listBoxItems::iterator iter, int y)
|
|||
return;
|
||||
|
||||
convertToItem (*iter, source_container, y + yoffset);
|
||||
std::size_t len = iter->text.getLength();
|
||||
recalculateHorizontalBar (len, hasBrackets(iter));
|
||||
std::size_t column_width = getColumnWidth(iter->text);
|
||||
recalculateHorizontalBar (column_width, hasBrackets(iter));
|
||||
|
||||
if ( hbar->isShown() )
|
||||
hbar->redraw();
|
||||
|
|
|
@ -232,7 +232,7 @@ FString FListViewItem::getText (int column) const
|
|||
return fc::emptyFString::get();
|
||||
|
||||
// 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];
|
||||
}
|
||||
|
||||
|
@ -259,7 +259,7 @@ void FListViewItem::setText (int column, const FString& text)
|
|||
return;
|
||||
|
||||
// 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();
|
||||
|
||||
if ( parent && parent->isInstanceOf("FListView") )
|
||||
|
@ -268,10 +268,10 @@ void FListViewItem::setText (int column, const FString& text)
|
|||
|
||||
if ( ! listview->header[index].fixed_width )
|
||||
{
|
||||
int length = int(text.getLength());
|
||||
int column_width = int(getColumnWidth(text));
|
||||
|
||||
if ( length > listview->header[index].width )
|
||||
listview->header[index].width = length;
|
||||
if ( column_width > listview->header[index].width )
|
||||
listview->header[index].width = column_width;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -596,13 +596,11 @@ FListView::~FListView() // destructor
|
|||
std::size_t FListView::getCount()
|
||||
{
|
||||
int n{0};
|
||||
auto iter = itemlist.begin();
|
||||
|
||||
while ( iter != itemlist.end() )
|
||||
for (auto&& item : itemlist)
|
||||
{
|
||||
auto item = static_cast<FListViewItem*>(*iter);
|
||||
n += item->getVisibleLines();
|
||||
++iter;
|
||||
auto listitem = static_cast<FListViewItem*>(item);
|
||||
n += listitem->getVisibleLines();
|
||||
}
|
||||
|
||||
return std::size_t(n);
|
||||
|
@ -617,7 +615,7 @@ fc::text_alignment FListView::getColumnAlignment (int column) const
|
|||
return fc::alignLeft;
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
|
@ -630,7 +628,7 @@ FString FListView::getColumnText (int column) const
|
|||
return fc::emptyFString::get();
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
|
@ -698,10 +696,10 @@ void FListView::setColumnText (int column, const FString& label)
|
|||
|
||||
if ( ! header[index].fixed_width )
|
||||
{
|
||||
int length = int(label.getLength());
|
||||
int column_width = int(getColumnWidth(label));
|
||||
|
||||
if ( length > header[index].width )
|
||||
header[index].width = length;
|
||||
if ( column_width > header[index].width )
|
||||
header[index].width = column_width;
|
||||
}
|
||||
|
||||
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()) )
|
||||
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 )
|
||||
sort_type.resize(size);
|
||||
|
@ -745,7 +743,7 @@ int FListView::addColumn (const FString& label, int width)
|
|||
if ( new_column.width == USE_MAX_SIZE )
|
||||
{
|
||||
new_column.fixed_width = false;
|
||||
new_column.width = int(label.getLength());
|
||||
new_column.width = int(getColumnWidth(label));
|
||||
}
|
||||
else
|
||||
new_column.fixed_width = true;
|
||||
|
@ -895,7 +893,7 @@ void FListView::onKeyPress (FKeyEvent* ev)
|
|||
break;
|
||||
|
||||
case fc::Fkey_space:
|
||||
keySpace();
|
||||
toggleCheckbox();
|
||||
ev->accept();
|
||||
break;
|
||||
|
||||
|
@ -910,12 +908,12 @@ void FListView::onKeyPress (FKeyEvent* ev)
|
|||
break;
|
||||
|
||||
case fc::Fkey_left:
|
||||
keyLeft (first_line_position_before);
|
||||
collapseAndScrollLeft (first_line_position_before);
|
||||
ev->accept();
|
||||
break;
|
||||
|
||||
case fc::Fkey_right:
|
||||
keyRight(first_line_position_before);
|
||||
expandAndScrollRight (first_line_position_before);
|
||||
ev->accept();
|
||||
break;
|
||||
|
||||
|
@ -930,22 +928,22 @@ void FListView::onKeyPress (FKeyEvent* ev)
|
|||
break;
|
||||
|
||||
case fc::Fkey_home:
|
||||
keyHome();
|
||||
firstPos();
|
||||
ev->accept();
|
||||
break;
|
||||
|
||||
case fc::Fkey_end:
|
||||
keyEnd();
|
||||
lastPos();
|
||||
ev->accept();
|
||||
break;
|
||||
|
||||
case int('+'):
|
||||
if ( keyPlus() )
|
||||
if ( expandSubtree() )
|
||||
ev->accept();
|
||||
break;
|
||||
|
||||
case int('-'):
|
||||
if ( keyMinus() )
|
||||
if ( collapseSubtree() )
|
||||
ev->accept();
|
||||
break;
|
||||
|
||||
|
@ -958,9 +956,9 @@ void FListView::onKeyPress (FKeyEvent* ev)
|
|||
|
||||
if ( ev->isAccepted() )
|
||||
{
|
||||
bool draw_vbar = first_line_position_before
|
||||
!= first_visible_line.getPosition();
|
||||
bool draw_hbar = xoffset_before != xoffset;
|
||||
bool draw_vbar( first_line_position_before
|
||||
!= first_visible_line.getPosition() );
|
||||
bool draw_hbar(xoffset_before != xoffset);
|
||||
updateDrawing (draw_vbar, draw_hbar);
|
||||
}
|
||||
}
|
||||
|
@ -1387,7 +1385,7 @@ void FListView::init()
|
|||
root = selflist.begin();
|
||||
null_iter = selflist.end();
|
||||
setGeometry (FPoint(1, 1), FSize(5, 4), false); // initialize geometry values
|
||||
const FWidgetColors& wc = getFWidgetColors();
|
||||
const auto& wc = getFWidgetColors();
|
||||
setForegroundColor (wc.dialog_fg);
|
||||
setBackgroundColor (wc.dialog_bg);
|
||||
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 txt_length
|
||||
, std::size_t column_width
|
||||
, std::size_t width )
|
||||
{
|
||||
switch ( align )
|
||||
|
@ -1446,14 +1444,14 @@ std::size_t FListView::getAlignOffset ( fc::text_alignment align
|
|||
return 0;
|
||||
|
||||
case fc::alignCenter:
|
||||
if ( txt_length < width )
|
||||
return (width - txt_length) / 2;
|
||||
if ( column_width < width )
|
||||
return (width - column_width) / 2;
|
||||
else
|
||||
return 0;
|
||||
|
||||
case fc::alignRight:
|
||||
if ( txt_length < width )
|
||||
return width - txt_length;
|
||||
if ( column_width < width )
|
||||
return width - column_width;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
@ -1536,8 +1534,6 @@ void FListView::drawScrollbars()
|
|||
//----------------------------------------------------------------------
|
||||
void FListView::drawHeadlines()
|
||||
{
|
||||
std::vector<charData>::const_iterator first, last;
|
||||
|
||||
if ( header.empty()
|
||||
|| getHeight() <= 2
|
||||
|| getWidth() <= 4
|
||||
|
@ -1548,7 +1544,7 @@ void FListView::drawHeadlines()
|
|||
headerline.clear();
|
||||
|
||||
if ( hasCheckableItems() )
|
||||
drawHeaderBorder(4);
|
||||
drawHeaderBorder(4); // Draw into FTermBuffer object
|
||||
|
||||
while ( iter != header.end() )
|
||||
{
|
||||
|
@ -1560,27 +1556,12 @@ void FListView::drawHeadlines()
|
|||
continue;
|
||||
}
|
||||
|
||||
drawHeadlineLabel(iter);
|
||||
drawHeadlineLabel(iter); // Draw into FTermBuffer object
|
||||
++iter;
|
||||
}
|
||||
|
||||
std::vector<charData> h;
|
||||
h << headerline;
|
||||
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);
|
||||
// Print the FTermBuffer object
|
||||
drawBufferedHeadline();
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
@ -1590,12 +1571,12 @@ void FListView::drawList()
|
|||
return;
|
||||
|
||||
uInt y{0};
|
||||
uInt page_height = uInt(getHeight() - 2);
|
||||
uInt page_height = uInt(getHeight()) - 2;
|
||||
auto iter = first_visible_line;
|
||||
|
||||
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);
|
||||
int tree_offset = ( tree_view ) ? int(item->getDepth() << 1) + 1 : 0;
|
||||
int checkbox_offset = ( item->isCheckable() ) ? 1 : 0;
|
||||
|
@ -1606,9 +1587,13 @@ void FListView::drawList()
|
|||
|
||||
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());
|
||||
setCursorPos (FPoint ( 3 + tree_offset + checkbox_offset - xoffset
|
||||
, 2 + int(y) )); // first character
|
||||
setCursorPos (FPoint(xpos, 2 + int(y))); // first character
|
||||
}
|
||||
|
||||
last_visible_line = iter;
|
||||
|
@ -1651,12 +1636,12 @@ void FListView::drawListLine ( const FListViewItem* item
|
|||
static constexpr std::size_t ellipsis_length = 2;
|
||||
const auto& text = item->column_list[col];
|
||||
std::size_t width = std::size_t(header[col].width);
|
||||
std::size_t txt_length = text.getLength();
|
||||
// Increment the value of i for the column position
|
||||
std::size_t column_width = getColumnWidth(text);
|
||||
// Increment the value of col for the column position
|
||||
// and the next iteration
|
||||
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 )
|
||||
{
|
||||
|
@ -1673,40 +1658,43 @@ void FListView::drawListLine ( const FListViewItem* item
|
|||
if ( align_offset > 0 )
|
||||
line += FString(align_offset, L' ');
|
||||
|
||||
if ( align_offset + txt_length <= width )
|
||||
if ( align_offset + column_width <= width )
|
||||
{
|
||||
// Insert text and trailing space
|
||||
static constexpr std::size_t leading_space = 1;
|
||||
line += text.left(width);
|
||||
line += getColumnSubString (text, 1, width);
|
||||
line += FString ( leading_space + width
|
||||
- align_offset - txt_length, L' ');
|
||||
- align_offset - column_width, L' ');
|
||||
}
|
||||
else if ( align == fc::alignRight )
|
||||
{
|
||||
// Ellipse right align text
|
||||
std::size_t first = getColumnWidth(text) + 1 - width;
|
||||
line += FString (L"..");
|
||||
line += text.right(width - ellipsis_length);
|
||||
line += getColumnSubString (text, first, width - ellipsis_length);
|
||||
line += L' ';
|
||||
}
|
||||
else
|
||||
{
|
||||
// Ellipse left align text and center text
|
||||
line += text.left(width - ellipsis_length);
|
||||
line += getColumnSubString (text, 1, width - ellipsis_length);
|
||||
line += FString (L".. ");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
line = line.mid ( std::size_t(xoffset) + 1
|
||||
, getWidth() - nf_offset - 2);
|
||||
const wchar_t* const& element_str = line.wc_str();
|
||||
std::size_t width = getWidth() - nf_offset - 2;
|
||||
line = getColumnSubString ( line, std::size_t(xoffset) + 1, width );
|
||||
std::size_t len = line.getLength();
|
||||
std::size_t i;
|
||||
std::size_t char_width{0};
|
||||
|
||||
for (i = 0; i < len; i++)
|
||||
print() << element_str[i];
|
||||
for (std::size_t i{0}; i < len; 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 (' ');
|
||||
}
|
||||
|
||||
|
@ -1714,7 +1702,7 @@ void FListView::drawListLine ( const FListViewItem* item
|
|||
inline void FListView::setLineAttributes ( bool is_current
|
||||
, bool is_focus )
|
||||
{
|
||||
const FWidgetColors& wc = getFWidgetColors();
|
||||
const auto& wc = getFWidgetColors();
|
||||
setColor (wc.list_fg, wc.list_bg);
|
||||
|
||||
if ( is_current )
|
||||
|
@ -1805,9 +1793,9 @@ inline FString FListView::getLinePrefix ( const FListViewItem* item
|
|||
|
||||
//----------------------------------------------------------------------
|
||||
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;
|
||||
|
||||
setColor();
|
||||
|
@ -1818,7 +1806,7 @@ inline void FListView::drawSortIndicator ( std::size_t& length
|
|||
else if ( sort_order == fc::descending )
|
||||
headerline << fc::BlackDownPointingTriangle; // ▼
|
||||
|
||||
if ( length < column_width )
|
||||
if ( length < column_max )
|
||||
{
|
||||
length++;
|
||||
headerline << ' ';
|
||||
|
@ -1833,65 +1821,153 @@ inline void FListView::drawHeaderBorder (std::size_t length)
|
|||
headerline << line; // horizontal line
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
void FListView::drawHeadlineLabel (const headerItems::const_iterator& iter)
|
||||
{
|
||||
// Print lable text
|
||||
// Print label text
|
||||
static constexpr std::size_t leading_space = 1;
|
||||
const auto& text = iter->name;
|
||||
FString txt(" " + text);
|
||||
std::size_t width = std::size_t(iter->width);
|
||||
std::size_t txt_length = txt.getLength();
|
||||
std::size_t column_width = leading_space + width;
|
||||
std::size_t column_width = getColumnWidth(txt);
|
||||
std::size_t column_max = leading_space + width;
|
||||
headerItems::const_iterator first = header.begin();
|
||||
int column = int(std::distance(first, iter)) + 1;
|
||||
bool has_sort_indicator = bool ( sort_column == column
|
||||
&& ! hide_sort_indicator );
|
||||
const FWidgetColors& wc = getFWidgetColors();
|
||||
bool has_sort_indicator( sort_column == column && ! hide_sort_indicator );
|
||||
const auto& wc = getFWidgetColors();
|
||||
|
||||
if ( isEnabled() )
|
||||
setColor (wc.label_emphasis_fg, wc.label_bg);
|
||||
else
|
||||
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;
|
||||
txt = txt.left(txt_length);
|
||||
column_width = column_max - 2;
|
||||
txt = getColumnSubString (txt, 1, column_width);
|
||||
}
|
||||
|
||||
if ( txt_length <= column_width )
|
||||
if ( column_width <= column_max )
|
||||
{
|
||||
std::size_t length = txt_length;
|
||||
headerline << txt;
|
||||
|
||||
if ( length < column_width )
|
||||
if ( column_width < column_max )
|
||||
{
|
||||
length++;
|
||||
column_width++;
|
||||
headerline << ' '; // trailing space
|
||||
}
|
||||
|
||||
if ( has_sort_indicator )
|
||||
drawSortIndicator (length, column_width );
|
||||
drawSortIndicator (column_width, column_max );
|
||||
|
||||
if ( length < column_width )
|
||||
drawHeaderBorder (column_width - length);
|
||||
if ( column_width < column_max )
|
||||
drawHeaderBorder (column_max - column_width);
|
||||
}
|
||||
else
|
||||
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
|
||||
, const FString& text )
|
||||
{
|
||||
// Print lable ellipsis
|
||||
// Print label ellipsis
|
||||
static constexpr int ellipsis_length = 2;
|
||||
int width = iter->width;
|
||||
const FWidgetColors& wc = getFWidgetColors();
|
||||
const auto& wc = getFWidgetColors();
|
||||
|
||||
headerline << ' '
|
||||
<< text.left(uInt(width - ellipsis_length))
|
||||
<< getColumnSubString (text, 1, uInt(width - ellipsis_length))
|
||||
<< 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)
|
||||
{
|
||||
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
|
||||
uInt column_idx{0};
|
||||
uInt entries = uInt(item->column_list.size());
|
||||
headerItems::iterator header_iter = header.begin();
|
||||
std::size_t column_idx{0};
|
||||
std::size_t entries = std::size_t(item->column_list.size());
|
||||
|
||||
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);
|
||||
bool fixed_width = header_iter->fixed_width;
|
||||
std::size_t width = std::size_t(header_item.width);
|
||||
bool fixed_width = header_item.fixed_width;
|
||||
|
||||
if ( ! fixed_width )
|
||||
{
|
||||
std::size_t len;
|
||||
std::size_t len{};
|
||||
|
||||
if ( column_idx < entries )
|
||||
len = item->column_list[column_idx].getLength();
|
||||
len = getColumnWidth(item->column_list[column_idx]);
|
||||
else
|
||||
len = 0;
|
||||
|
||||
if ( len > width )
|
||||
header_iter->width = int(len);
|
||||
header_item.width = int(len);
|
||||
}
|
||||
|
||||
line_width += std::size_t(header_iter->width)
|
||||
+ padding_space; // width + trailing space
|
||||
// width + trailing space
|
||||
line_width += std::size_t(header_item.width) + padding_space;
|
||||
|
||||
column_idx++;
|
||||
++header_iter;
|
||||
}
|
||||
|
||||
return line_width;
|
||||
|
@ -2033,19 +2112,18 @@ void FListView::mouseHeaderClicked()
|
|||
int checkbox_offset = ( hasCheckableItems() ) ? 4 : 0;
|
||||
int header_start = 2 + checkbox_offset;
|
||||
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;
|
||||
bool has_sort_indicator = bool( column == sort_column );
|
||||
int click_width = int(iter->name.getLength());
|
||||
bool has_sort_indicator( column == sort_column );
|
||||
int click_width = int(getColumnWidth(item.name));
|
||||
|
||||
if ( has_sort_indicator )
|
||||
click_width += 2;
|
||||
|
||||
if ( click_width > iter->width )
|
||||
click_width = iter->width;
|
||||
if ( click_width > item.width )
|
||||
click_width = item.width;
|
||||
|
||||
if ( header_pos > header_start
|
||||
&& header_pos <= header_start + click_width )
|
||||
|
@ -2063,9 +2141,8 @@ void FListView::mouseHeaderClicked()
|
|||
break;
|
||||
}
|
||||
|
||||
header_start += leading_space + iter->width;
|
||||
header_start += leading_space + item.width;
|
||||
column++;
|
||||
++iter;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2234,7 +2311,7 @@ void FListView::processChanged()
|
|||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
inline void FListView::keySpace()
|
||||
inline void FListView::toggleCheckbox()
|
||||
{
|
||||
if ( itemlist.empty() )
|
||||
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() )
|
||||
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() )
|
||||
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() )
|
||||
return;
|
||||
|
@ -2343,7 +2420,7 @@ inline void FListView::keyHome()
|
|||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
inline void FListView::keyEnd()
|
||||
inline void FListView::lastPos()
|
||||
{
|
||||
if ( itemlist.empty() )
|
||||
return;
|
||||
|
@ -2356,7 +2433,7 @@ inline void FListView::keyEnd()
|
|||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
inline bool FListView::keyPlus()
|
||||
inline bool FListView::expandSubtree()
|
||||
{
|
||||
if ( itemlist.empty() )
|
||||
return false;
|
||||
|
@ -2374,7 +2451,7 @@ inline bool FListView::keyPlus()
|
|||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
inline bool FListView::keyMinus()
|
||||
inline bool FListView::collapseSubtree()
|
||||
{
|
||||
if ( itemlist.empty() )
|
||||
return false;
|
||||
|
|
278
src/fmenu.cpp
278
src/fmenu.cpp
|
@ -51,7 +51,7 @@ FMenu::FMenu(FWidget* parent)
|
|||
//----------------------------------------------------------------------
|
||||
FMenu::FMenu (const FString& txt, FWidget* parent)
|
||||
: FWindow(parent)
|
||||
, item(txt, parent)
|
||||
, menuitem(txt, parent)
|
||||
{
|
||||
init(parent);
|
||||
}
|
||||
|
@ -80,7 +80,7 @@ bool FMenu::setMenuWidget (bool enable)
|
|||
void FMenu::setStatusbarMessage (const FString& msg)
|
||||
{
|
||||
FWidget::setStatusbarMessage(msg);
|
||||
item.setStatusbarMessage(msg);
|
||||
menuitem.setStatusbarMessage(msg);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
@ -138,29 +138,29 @@ void FMenu::onKeyPress (FKeyEvent* ev)
|
|||
switch ( ev->key() )
|
||||
{
|
||||
case fc::Fkey_up:
|
||||
keyUp();
|
||||
selectPrevItem();
|
||||
break;
|
||||
|
||||
case fc::Fkey_down:
|
||||
keyDown();
|
||||
selectNextItem();
|
||||
break;
|
||||
|
||||
case fc::Fkey_left:
|
||||
keyLeft(ev);
|
||||
selectPrevMenu(ev);
|
||||
break;
|
||||
|
||||
case fc::Fkey_right:
|
||||
keyRight(ev);
|
||||
selectNextMenu(ev);
|
||||
break;
|
||||
|
||||
case fc::Fkey_return:
|
||||
case fc::Fkey_enter:
|
||||
keyEnter();
|
||||
acceptSelection();
|
||||
break;
|
||||
|
||||
case fc::Fkey_escape:
|
||||
case fc::Fkey_escape_mintty:
|
||||
keyEscape();
|
||||
closeMenu();
|
||||
break;
|
||||
|
||||
case fc::Fmkey_1:
|
||||
|
@ -320,12 +320,12 @@ void FMenu::onMouseMove (FMouseEvent* ev)
|
|||
//----------------------------------------------------------------------
|
||||
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 )
|
||||
return;
|
||||
|
||||
if ( ! menuitem->isChecked() )
|
||||
if ( ! m_item->isChecked() )
|
||||
return;
|
||||
|
||||
auto list = getItemList();
|
||||
|
@ -333,19 +333,14 @@ void FMenu::cb_menuitem_toggled (FWidget* widget, FDataPtr)
|
|||
if ( list.empty() )
|
||||
return;
|
||||
|
||||
auto iter = list.begin();
|
||||
auto last = list.end();
|
||||
|
||||
while ( iter != last )
|
||||
for (auto&& item : list)
|
||||
{
|
||||
if ( (*iter) != menuitem
|
||||
&& (*iter)->isChecked()
|
||||
&& isRadioMenuItem(*iter) )
|
||||
if ( item != m_item
|
||||
&& item->isChecked()
|
||||
&& isRadioMenuItem(item) )
|
||||
{
|
||||
(*iter)->unsetChecked();
|
||||
item->unsetChecked();
|
||||
}
|
||||
|
||||
++iter;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -445,10 +440,10 @@ void FMenu::init(FWidget* parent)
|
|||
setMenuWidget();
|
||||
hide();
|
||||
|
||||
const FWidgetColors& wc = getFWidgetColors();
|
||||
const auto& wc = getFWidgetColors();
|
||||
setForegroundColor (wc.menu_active_fg);
|
||||
setBackgroundColor (wc.menu_active_bg);
|
||||
item.setMenu(this);
|
||||
menuitem.setMenu(this);
|
||||
|
||||
if ( parent )
|
||||
{
|
||||
|
@ -472,17 +467,14 @@ void FMenu::init(FWidget* parent)
|
|||
//----------------------------------------------------------------------
|
||||
void FMenu::calculateDimensions()
|
||||
{
|
||||
auto list = getItemList();
|
||||
auto iter = list.begin();
|
||||
auto last = list.end();
|
||||
max_item_width = 10; // minimum width
|
||||
|
||||
// find the maximum item width
|
||||
while ( iter != last )
|
||||
for (auto&& item : getItemList())
|
||||
{
|
||||
std::size_t item_width = (*iter)->getTextLength() + 2;
|
||||
FKey accel_key = (*iter)->accel_key;
|
||||
bool has_menu = (*iter)->hasMenu();
|
||||
std::size_t item_width = item->getTextWidth() + 2;
|
||||
FKey accel_key = item->accel_key;
|
||||
bool has_menu = item->hasMenu();
|
||||
|
||||
if ( has_menu )
|
||||
{
|
||||
|
@ -499,8 +491,6 @@ void FMenu::calculateDimensions()
|
|||
|
||||
if ( item_width > max_item_width )
|
||||
max_item_width = item_width;
|
||||
|
||||
++iter;
|
||||
}
|
||||
|
||||
int adjust_X = adjustX(getX());
|
||||
|
@ -510,42 +500,36 @@ void FMenu::calculateDimensions()
|
|||
, FSize(max_item_width + 2, getCount() + 2) );
|
||||
|
||||
// set geometry of all items
|
||||
iter = list.begin();
|
||||
int item_X = 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_Y = (*iter)->getTermY() - 2;
|
||||
int menu_Y = item->getTermY() - 2;
|
||||
// set sub-menu position
|
||||
(*iter)->getMenu()->setPos (FPoint(menu_X, menu_Y), false);
|
||||
item->getMenu()->setPos (FPoint(menu_X, menu_Y), false);
|
||||
}
|
||||
|
||||
item_Y++;
|
||||
++iter;
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
void FMenu::adjustItems()
|
||||
{
|
||||
auto list = getItemList();
|
||||
auto iter = list.begin();
|
||||
auto last = list.end();
|
||||
|
||||
while ( iter != last )
|
||||
for (auto&& item : getItemList())
|
||||
{
|
||||
if ( (*iter)->hasMenu() )
|
||||
if ( item->hasMenu() )
|
||||
{
|
||||
auto menu = (*iter)->getMenu();
|
||||
auto menu = item->getMenu();
|
||||
int menu_X = getTermX() + int(max_item_width) + 1;
|
||||
menu_X = menu->adjustX(menu_X);
|
||||
int menu_Y = (*iter)->getTermY() - 2;
|
||||
int menu_Y = item->getTermY() - 2;
|
||||
|
||||
// set sub-menu position
|
||||
menu->setPos (FPoint(menu_X, menu_Y));
|
||||
|
@ -554,8 +538,6 @@ void FMenu::adjustItems()
|
|||
if ( menu->getCount() > 0 )
|
||||
menu->adjustItems();
|
||||
}
|
||||
|
||||
++iter;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -664,16 +646,13 @@ void FMenu::hideSuperMenus()
|
|||
bool FMenu::mouseDownOverList (FPoint mouse_pos)
|
||||
{
|
||||
bool focus_changed{false};
|
||||
auto list = getItemList();
|
||||
auto iter = list.begin();
|
||||
auto last = list.end();
|
||||
mouse_pos -= FPoint(getRightPadding(), getTopPadding());
|
||||
|
||||
while ( iter != last )
|
||||
for (auto&& item : getItemList())
|
||||
{
|
||||
int x1 = (*iter)->getX()
|
||||
, x2 = (*iter)->getX() + int((*iter)->getWidth())
|
||||
, y = (*iter)->getY()
|
||||
int x1 = item->getX()
|
||||
, x2 = item->getX() + int(item->getWidth())
|
||||
, y = item->getY()
|
||||
, mouse_x = mouse_pos.getX()
|
||||
, mouse_y = mouse_pos.getY();
|
||||
|
||||
|
@ -682,11 +661,9 @@ bool FMenu::mouseDownOverList (FPoint mouse_pos)
|
|||
&& mouse_y == y )
|
||||
{
|
||||
// Mouse pointer over item
|
||||
mouseDownSubmenu (*iter);
|
||||
mouseDownSelection (*iter, focus_changed);
|
||||
mouseDownSubmenu (item);
|
||||
mouseDownSelection (item, focus_changed);
|
||||
}
|
||||
|
||||
++iter;
|
||||
}
|
||||
|
||||
return focus_changed;
|
||||
|
@ -753,28 +730,25 @@ void FMenu::mouseDownSelection (FMenuItem* m_item, bool& focus_changed)
|
|||
//----------------------------------------------------------------------
|
||||
bool FMenu::mouseUpOverList (FPoint mouse_pos)
|
||||
{
|
||||
auto list = getItemList();
|
||||
auto iter = list.begin();
|
||||
auto last = list.end();
|
||||
mouse_pos -= FPoint(getRightPadding(), getTopPadding());
|
||||
|
||||
while ( iter != last )
|
||||
for (auto&& item : getItemList())
|
||||
{
|
||||
int x1 = (*iter)->getX()
|
||||
, x2 = (*iter)->getX() + int((*iter)->getWidth())
|
||||
, y = (*iter)->getY()
|
||||
int x1 = item->getX()
|
||||
, x2 = item->getX() + int(item->getWidth())
|
||||
, y = item->getY()
|
||||
, mouse_x = mouse_pos.getX()
|
||||
, mouse_y = mouse_pos.getY();
|
||||
|
||||
if ( (*iter)->isSelected()
|
||||
if ( item->isSelected()
|
||||
&& mouse_x >= x1
|
||||
&& mouse_x < x2
|
||||
&& mouse_y == y )
|
||||
{
|
||||
// Mouse pointer over item
|
||||
if ( (*iter)->hasMenu() )
|
||||
if ( item->hasMenu() )
|
||||
{
|
||||
auto sub_menu = (*iter)->getMenu();
|
||||
auto sub_menu = item->getMenu();
|
||||
if ( ! sub_menu->isShown() )
|
||||
openSubMenu (sub_menu, SELECT_ITEM);
|
||||
else if ( opened_sub_menu )
|
||||
|
@ -800,11 +774,9 @@ bool FMenu::mouseUpOverList (FPoint mouse_pos)
|
|||
unselectItem();
|
||||
hide();
|
||||
hideSuperMenus();
|
||||
(*iter)->processClicked();
|
||||
item->processClicked();
|
||||
}
|
||||
}
|
||||
|
||||
++iter;
|
||||
}
|
||||
|
||||
return false;
|
||||
|
@ -813,25 +785,20 @@ bool FMenu::mouseUpOverList (FPoint mouse_pos)
|
|||
//----------------------------------------------------------------------
|
||||
void FMenu::mouseMoveOverList (FPoint mouse_pos, mouseStates& ms)
|
||||
{
|
||||
auto list = getItemList();
|
||||
auto iter = list.begin();
|
||||
auto last = list.end();
|
||||
mouse_pos -= FPoint(getRightPadding(), getTopPadding());
|
||||
|
||||
while ( iter != last )
|
||||
for (auto&& item : getItemList())
|
||||
{
|
||||
int x1 = (*iter)->getX()
|
||||
, x2 = (*iter)->getX() + int((*iter)->getWidth())
|
||||
, y = (*iter)->getY()
|
||||
int x1 = item->getX()
|
||||
, x2 = item->getX() + int(item->getWidth())
|
||||
, y = item->getY()
|
||||
, mouse_x = mouse_pos.getX()
|
||||
, mouse_y = mouse_pos.getY();
|
||||
|
||||
if ( mouse_x >= x1 && mouse_x < x2 && mouse_y == y )
|
||||
mouseMoveSelection (*iter, ms);
|
||||
mouseMoveSelection (item, ms);
|
||||
else
|
||||
mouseMoveDeselection (*iter, ms);
|
||||
|
||||
++iter;
|
||||
mouseMoveDeselection (item, ms);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1001,7 +968,7 @@ bool FMenu::containsMenuStructure (int x, int y)
|
|||
return true;
|
||||
else if ( si && si->hasMenu() && opened_sub_menu )
|
||||
return si->getMenu()->containsMenuStructure(x, y);
|
||||
else if ( item.getTermGeometry().contains(x, y) )
|
||||
else if ( menuitem.getTermGeometry().contains(x, y) )
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
|
@ -1038,9 +1005,8 @@ bool FMenu::selectNextItem()
|
|||
{
|
||||
auto list = getItemList();
|
||||
auto iter = list.begin();
|
||||
auto last = list.end();
|
||||
|
||||
while ( iter != last )
|
||||
while ( iter != list.end() )
|
||||
{
|
||||
if ( (*iter)->isSelected() )
|
||||
{
|
||||
|
@ -1087,7 +1053,6 @@ bool FMenu::selectPrevItem()
|
|||
{
|
||||
auto list = getItemList();
|
||||
auto iter = list.end();
|
||||
auto first = list.begin();
|
||||
|
||||
do
|
||||
{
|
||||
|
@ -1127,7 +1092,7 @@ bool FMenu::selectPrevItem()
|
|||
break;
|
||||
}
|
||||
}
|
||||
while ( iter != first );
|
||||
while ( iter != list.begin() );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -1144,22 +1109,21 @@ void FMenu::keypressMenuBar (FKeyEvent* ev)
|
|||
//----------------------------------------------------------------------
|
||||
bool FMenu::hotkeyMenu (FKeyEvent* ev)
|
||||
{
|
||||
auto list = getItemList();
|
||||
auto iter = list.begin();
|
||||
auto last = list.end();
|
||||
|
||||
while ( iter != last )
|
||||
for (auto&& item : getItemList())
|
||||
{
|
||||
if ( (*iter)->hasHotkey() )
|
||||
if ( item->hasHotkey() )
|
||||
{
|
||||
bool found{false};
|
||||
uChar hotkey = (*iter)->getHotkey();
|
||||
FKey hotkey = item->getHotkey();
|
||||
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
|
||||
|| FKey(std::toupper(hotkey)) == key )
|
||||
if ( FKey(std::tolower(int(hotkey))) == key
|
||||
|| FKey(std::toupper(int(hotkey))) == key )
|
||||
found = true;
|
||||
}
|
||||
else if ( hotkey == key )
|
||||
|
@ -1167,14 +1131,17 @@ bool FMenu::hotkeyMenu (FKeyEvent* ev)
|
|||
|
||||
if ( found )
|
||||
{
|
||||
if ( (*iter)->hasMenu() )
|
||||
if ( item->hasMenu() )
|
||||
{
|
||||
auto sub_menu = (*iter)->getMenu();
|
||||
auto sub_menu = item->getMenu();
|
||||
unselectItem();
|
||||
(*iter)->setSelected();
|
||||
setSelectedItem (*iter);
|
||||
item->setSelected();
|
||||
setSelectedItem (item);
|
||||
redraw();
|
||||
|
||||
if ( ! sub_menu->isShown() )
|
||||
openSubMenu (sub_menu, SELECT_ITEM);
|
||||
|
||||
sub_menu->redraw();
|
||||
}
|
||||
else
|
||||
|
@ -1186,14 +1153,13 @@ bool FMenu::hotkeyMenu (FKeyEvent* ev)
|
|||
updateTerminal();
|
||||
flush_out();
|
||||
ev->accept();
|
||||
(*iter)->processClicked();
|
||||
item->processClicked();
|
||||
}
|
||||
|
||||
ev->accept();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
++iter;
|
||||
}
|
||||
|
||||
return false;
|
||||
|
@ -1203,7 +1169,7 @@ bool FMenu::hotkeyMenu (FKeyEvent* ev)
|
|||
void FMenu::draw()
|
||||
{
|
||||
// Fill the background
|
||||
const FWidgetColors& wc = getFWidgetColors();
|
||||
const auto& wc = getFWidgetColors();
|
||||
setColor (wc.menu_active_fg, wc.menu_active_bg);
|
||||
|
||||
if ( isMonochron() )
|
||||
|
@ -1222,18 +1188,14 @@ void FMenu::draw()
|
|||
void FMenu::drawItems()
|
||||
{
|
||||
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);
|
||||
else
|
||||
drawMenuLine (*iter, y);
|
||||
drawMenuLine (item, y);
|
||||
|
||||
++iter;
|
||||
y++;
|
||||
}
|
||||
}
|
||||
|
@ -1241,7 +1203,7 @@ void FMenu::drawItems()
|
|||
//----------------------------------------------------------------------
|
||||
inline void FMenu::drawSeparator (int y)
|
||||
{
|
||||
const FWidgetColors& wc = getFWidgetColors();
|
||||
const auto& wc = getFWidgetColors();
|
||||
print() << FPoint(1, 2 + y)
|
||||
<< 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{};
|
||||
std::size_t txt_length = txt.getLength();
|
||||
std::size_t to_char = txt_length;
|
||||
FKey accel_key = menuitem->accel_key;
|
||||
bool is_enabled = menuitem->isEnabled();
|
||||
bool is_selected = menuitem->isSelected();
|
||||
std::size_t column_width = getColumnWidth(txt);
|
||||
FKey accel_key = m_item->accel_key;
|
||||
bool is_enabled = m_item->isEnabled();
|
||||
bool is_selected = m_item->isSelected();
|
||||
|
||||
// Set screen position and attributes
|
||||
setLineAttributes (menuitem, y);
|
||||
setLineAttributes (m_item, y);
|
||||
|
||||
// Draw check mark prefix for checkable items
|
||||
drawCheckMarkPrefix (menuitem);
|
||||
drawCheckMarkPrefix (m_item);
|
||||
|
||||
// Print leading blank space
|
||||
print (' ');
|
||||
|
@ -1302,11 +1265,14 @@ inline void FMenu::drawMenuLine (FMenuItem* menuitem, int y)
|
|||
hotkeypos = finalcut::getHotkeyPos(txt.wc_str(), txtdata.text, txt_length);
|
||||
|
||||
if ( hotkeypos != NOT_SET )
|
||||
{
|
||||
to_char--;
|
||||
column_width--;
|
||||
}
|
||||
|
||||
txtdata.length = to_char;
|
||||
txtdata.no_underline = menuitem->getFlags().no_underline;
|
||||
setCursorToHotkeyPosition (menuitem);
|
||||
txtdata.no_underline = m_item->getFlags().no_underline;
|
||||
setCursorToHotkeyPosition (m_item);
|
||||
|
||||
if ( ! is_enabled || is_selected )
|
||||
txtdata.hotkeypos = NOT_SET;
|
||||
|
@ -1315,14 +1281,14 @@ inline void FMenu::drawMenuLine (FMenuItem* menuitem, int y)
|
|||
|
||||
drawMenuText (txtdata);
|
||||
|
||||
if ( menuitem->hasMenu() )
|
||||
drawSubMenuIndicator (to_char);
|
||||
if ( m_item->hasMenu() )
|
||||
drawSubMenuIndicator (column_width);
|
||||
else if ( accel_key )
|
||||
drawAcceleratorKey (to_char, accel_key);
|
||||
drawAcceleratorKey (column_width, accel_key);
|
||||
|
||||
// Draw the trailing spaces of the selected line
|
||||
if ( is_selected )
|
||||
drawTrailingSpaces (to_char);
|
||||
drawTrailingSpaces (column_width);
|
||||
|
||||
if ( isMonochron() && is_enabled && is_selected )
|
||||
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_checkable = menuitem->checkable;
|
||||
bool is_radio_btn = menuitem->radio_button;
|
||||
bool is_checked = m_item->isChecked();
|
||||
bool is_checkable = m_item->checkable;
|
||||
bool is_radio_btn = m_item->radio_button;
|
||||
|
||||
if ( ! has_checkable_items )
|
||||
return;
|
||||
|
@ -1361,7 +1327,7 @@ inline void FMenu::drawCheckMarkPrefix (FMenuItem* menuitem)
|
|||
}
|
||||
else
|
||||
{
|
||||
const FWidgetColors& wc = getFWidgetColors();
|
||||
const auto& wc = getFWidgetColors();
|
||||
setColor (wc.menu_inactive_fg, getBackgroundColor());
|
||||
|
||||
if ( getEncoding() == fc::ASCII )
|
||||
|
@ -1383,7 +1349,7 @@ inline void FMenu::drawMenuText (menuText& data)
|
|||
|
||||
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()
|
||||
&& ( int(data.text[z]) < fc::NF_rev_left_arrow2
|
||||
|
@ -1396,7 +1362,7 @@ inline void FMenu::drawMenuText (menuText& data)
|
|||
|
||||
if ( z == data.hotkeypos )
|
||||
{
|
||||
const FWidgetColors& wc = getFWidgetColors();
|
||||
const auto& wc = getFWidgetColors();
|
||||
setColor (wc.menu_hotkey_fg, wc.menu_hotkey_bg);
|
||||
|
||||
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_selected = menuitem->isSelected();
|
||||
const FWidgetColors& wc = getFWidgetColors();
|
||||
bool is_enabled = m_item->isEnabled();
|
||||
bool is_selected = m_item->isSelected();
|
||||
const auto& wc = getFWidgetColors();
|
||||
|
||||
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_selected = menuitem->isSelected();
|
||||
bool is_checkable = m_item->checkable;
|
||||
bool is_selected = m_item->isSelected();
|
||||
|
||||
if ( hotkeypos == NOT_SET )
|
||||
{
|
||||
|
@ -1508,9 +1474,9 @@ inline void FMenu::setCursorToHotkeyPosition (FMenuItem* menuitem)
|
|||
if ( is_selected )
|
||||
{
|
||||
if ( is_checkable )
|
||||
menuitem->setCursorPos (FPoint(3, 1));
|
||||
m_item->setCursorPos (FPoint(3, 1));
|
||||
else
|
||||
menuitem->setCursorPos (FPoint(2, 1));
|
||||
m_item->setCursorPos (FPoint(2, 1));
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -1518,28 +1484,18 @@ inline void FMenu::setCursorToHotkeyPosition (FMenuItem* menuitem)
|
|||
if ( is_selected )
|
||||
{
|
||||
// set cursor to the hotkey position
|
||||
auto x = getColumnWidth (m_item->getText(), hotkeypos);
|
||||
|
||||
if ( is_checkable )
|
||||
menuitem->setCursorPos (FPoint(3 + int(hotkeypos), 1));
|
||||
m_item->setCursorPos (FPoint(3 + int(x), 1));
|
||||
else
|
||||
menuitem->setCursorPos (FPoint(2 + int(hotkeypos), 1));
|
||||
m_item->setCursorPos (FPoint(2 + int(x), 1));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
inline void FMenu::keyUp()
|
||||
{
|
||||
selectPrevItem();
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
inline void FMenu::keyDown()
|
||||
{
|
||||
selectNextItem();
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
inline void FMenu::keyLeft (FKeyEvent* ev)
|
||||
inline void FMenu::selectPrevMenu (FKeyEvent* ev)
|
||||
{
|
||||
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() )
|
||||
{
|
||||
|
@ -1579,7 +1535,7 @@ inline void FMenu::keyRight (FKeyEvent* ev)
|
|||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
inline void FMenu::keyEnter()
|
||||
inline void FMenu::acceptSelection()
|
||||
{
|
||||
if ( ! hasSelectedItem() )
|
||||
return;
|
||||
|
@ -1598,7 +1554,7 @@ inline void FMenu::keyEnter()
|
|||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
inline void FMenu::keyEscape()
|
||||
inline void FMenu::closeMenu()
|
||||
{
|
||||
unselectItem();
|
||||
hideSubMenus();
|
||||
|
|
164
src/fmenubar.cpp
164
src/fmenubar.cpp
|
@ -65,7 +65,7 @@ void FMenuBar::resetMenu()
|
|||
void FMenuBar::hide()
|
||||
{
|
||||
FWindow::hide();
|
||||
const FWidgetColors& wc = getFWidgetColors();
|
||||
const auto& wc = getFWidgetColors();
|
||||
FColor fg = wc.term_fg;
|
||||
FColor bg = wc.term_bg;
|
||||
setColor (fg, bg);
|
||||
|
@ -250,7 +250,7 @@ void FMenuBar::init()
|
|||
|
||||
addAccelerator (fc::Fkey_f10);
|
||||
addAccelerator (fc::Fckey_space);
|
||||
const FWidgetColors& wc = getFWidgetColors();
|
||||
const auto& wc = getFWidgetColors();
|
||||
setForegroundColor (wc.menu_active_fg);
|
||||
setBackgroundColor (wc.menu_active_bg);
|
||||
unsetFocusable();
|
||||
|
@ -260,26 +260,21 @@ void FMenuBar::init()
|
|||
void FMenuBar::calculateDimensions()
|
||||
{
|
||||
FPoint item_pos (1, 1);
|
||||
auto list = getItemList();
|
||||
auto iter = list.begin();
|
||||
auto last = list.end();
|
||||
|
||||
// find the maximum item width
|
||||
while ( iter != last )
|
||||
for (auto&& item : getItemList())
|
||||
{
|
||||
std::size_t len = (*iter)->getTextLength();
|
||||
int item_width = int(len) + 2;
|
||||
int len = int(item->getTextWidth());
|
||||
int item_width = len + 2;
|
||||
|
||||
// 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
|
||||
if ( (*iter)->hasMenu() )
|
||||
(*iter)->getMenu()->setPos (item_pos, false);
|
||||
if ( item->hasMenu() )
|
||||
item->getMenu()->setPos (item_pos, false);
|
||||
|
||||
item_pos.x_ref() += item_width;
|
||||
|
||||
++iter;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -288,9 +283,8 @@ bool FMenuBar::selectNextItem()
|
|||
{
|
||||
auto list = getItemList();
|
||||
auto iter = list.begin();
|
||||
auto last = list.end();
|
||||
|
||||
while ( iter != last )
|
||||
while ( iter != list.end() )
|
||||
{
|
||||
if ( (*iter)->isSelected() )
|
||||
{
|
||||
|
@ -351,7 +345,6 @@ bool FMenuBar::selectPrevItem()
|
|||
{
|
||||
auto list = getItemList();
|
||||
auto iter = list.end();
|
||||
auto first = list.begin();
|
||||
|
||||
do
|
||||
{
|
||||
|
@ -405,7 +398,7 @@ bool FMenuBar::selectPrevItem()
|
|||
break;
|
||||
}
|
||||
}
|
||||
while ( iter != first );
|
||||
while ( iter != list.begin() );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -413,18 +406,17 @@ bool FMenuBar::selectPrevItem()
|
|||
//----------------------------------------------------------------------
|
||||
bool FMenuBar::hotkeyMenu (FKeyEvent*& ev)
|
||||
{
|
||||
auto list = getItemList();
|
||||
auto iter = list.begin();
|
||||
auto last = list.end();
|
||||
|
||||
while ( iter != last )
|
||||
for (auto&& item : getItemList())
|
||||
{
|
||||
if ( (*iter)->isEnabled() )
|
||||
if ( item->isEnabled() )
|
||||
{
|
||||
uChar hotkey = (*iter)->getHotkey();
|
||||
FKey hotkey = item->getHotkey();
|
||||
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();
|
||||
|
||||
|
@ -433,13 +425,13 @@ bool FMenuBar::hotkeyMenu (FKeyEvent*& ev)
|
|||
|
||||
unselectItem();
|
||||
|
||||
if ( (*iter)->hasMenu() )
|
||||
if ( item->hasMenu() )
|
||||
{
|
||||
auto menu = (*iter)->getMenu();
|
||||
(*iter)->setSelected();
|
||||
setSelectedItem(*iter);
|
||||
(*iter)->setFocus();
|
||||
(*iter)->openMenu();
|
||||
auto menu = item->getMenu();
|
||||
item->setSelected();
|
||||
setSelectedItem(item);
|
||||
item->setFocus();
|
||||
item->openMenu();
|
||||
menu->selectFirstItem();
|
||||
auto first_item = menu->getSelectedItem();
|
||||
|
||||
|
@ -459,15 +451,13 @@ bool FMenuBar::hotkeyMenu (FKeyEvent*& ev)
|
|||
setSelectedItem(nullptr);
|
||||
redraw();
|
||||
drop_down = false;
|
||||
(*iter)->processClicked();
|
||||
item->processClicked();
|
||||
}
|
||||
|
||||
ev->accept();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
++iter;
|
||||
}
|
||||
|
||||
return false;
|
||||
|
@ -493,15 +483,10 @@ void FMenuBar::drawItems()
|
|||
setReverse(true);
|
||||
|
||||
screenWidth = getDesktopWidth();
|
||||
auto iter = list.begin();
|
||||
auto last = list.end();
|
||||
std::size_t x{1};
|
||||
|
||||
while ( iter != last )
|
||||
{
|
||||
drawItem (*iter, x);
|
||||
++iter;
|
||||
}
|
||||
for (auto&& item : list)
|
||||
drawItem (item, x);
|
||||
|
||||
// Print spaces to end of line
|
||||
for (; x <= screenWidth; x++)
|
||||
|
@ -520,6 +505,7 @@ inline void FMenuBar::drawItem (FMenuItem* menuitem, std::size_t& x)
|
|||
FString txt(menuitem->getText());
|
||||
std::size_t to_char{};
|
||||
std::size_t txt_length = txt.getLength();
|
||||
std::size_t column_width = getColumnWidth(txt);
|
||||
bool is_enabled = menuitem->isEnabled();
|
||||
bool is_selected = menuitem->isSelected();
|
||||
|
||||
|
@ -549,22 +535,24 @@ inline void FMenuBar::drawItem (FMenuItem* menuitem, std::size_t& x)
|
|||
if ( hotkeypos != NOT_SET )
|
||||
{
|
||||
txt_length--;
|
||||
column_width--;
|
||||
to_char--;
|
||||
}
|
||||
|
||||
txtdata.length = to_char;
|
||||
x += txt_length;
|
||||
x += column_width;
|
||||
|
||||
if ( ! is_enabled || is_selected )
|
||||
txtdata.hotkeypos = NOT_SET;
|
||||
else
|
||||
txtdata.hotkeypos = hotkeypos;
|
||||
|
||||
setCursorToHotkeyPosition (menuitem, hotkeypos);
|
||||
drawMenuText (txtdata);
|
||||
drawEllipsis (txtdata, x);
|
||||
drawTrailingSpace (x);
|
||||
|
||||
const FWidgetColors& wc = getFWidgetColors();
|
||||
const auto& wc = getFWidgetColors();
|
||||
setColor (wc.menu_active_fg, wc.menu_active_bg);
|
||||
|
||||
if ( isMonochron() && is_enabled && is_selected )
|
||||
|
@ -578,7 +566,7 @@ inline void FMenuBar::setLineAttributes (FMenuItem* menuitem)
|
|||
{
|
||||
bool is_enabled = menuitem->isEnabled();
|
||||
bool is_selected = menuitem->isSelected();
|
||||
const FWidgetColors& wc = getFWidgetColors();
|
||||
const auto& wc = getFWidgetColors();
|
||||
|
||||
if ( is_enabled )
|
||||
{
|
||||
|
@ -605,6 +593,25 @@ inline void FMenuBar::setLineAttributes (FMenuItem* menuitem)
|
|||
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)
|
||||
{
|
||||
|
@ -615,7 +622,7 @@ inline void FMenuBar::drawMenuText (menuText& data)
|
|||
if ( data.startpos > screenWidth - z )
|
||||
break;
|
||||
|
||||
if ( ! std::iswprint(wint_t(data.text[z])) )
|
||||
if ( ! std::iswprint(std::wint_t(data.text[z])) )
|
||||
{
|
||||
if ( ! isNewFont()
|
||||
&& ( int(data.text[z]) < fc::NF_rev_left_arrow2
|
||||
|
@ -627,7 +634,7 @@ inline void FMenuBar::drawMenuText (menuText& data)
|
|||
|
||||
if ( z == data.hotkeypos )
|
||||
{
|
||||
const FWidgetColors& wc = getFWidgetColors();
|
||||
const auto& wc = getFWidgetColors();
|
||||
setColor (wc.menu_hotkey_fg, wc.menu_hotkey_bg);
|
||||
|
||||
if ( ! data.no_underline )
|
||||
|
@ -692,18 +699,15 @@ void FMenuBar::adjustItems()
|
|||
{
|
||||
int item_X = 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
|
||||
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
|
||||
menu->setPos (FPoint(menu->adjustX(item_X), item_Y));
|
||||
|
@ -713,7 +717,6 @@ void FMenuBar::adjustItems()
|
|||
}
|
||||
|
||||
item_X += item_width;
|
||||
++iter;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -817,32 +820,23 @@ void FMenuBar::mouseDownOverList (const FMouseEvent* ev)
|
|||
return;
|
||||
|
||||
focus_changed = false;
|
||||
auto iter = list.begin();
|
||||
auto last = list.end();
|
||||
int mouse_x = ev->getX();
|
||||
int mouse_y = ev->getY();
|
||||
|
||||
while ( iter != last )
|
||||
for (auto&& item : list)
|
||||
{
|
||||
int x1 = (*iter)->getX();
|
||||
int x2 = (*iter)->getX() + int((*iter)->getWidth());
|
||||
int x1 = item->getX();
|
||||
int x2 = item->getX() + int(item->getWidth());
|
||||
|
||||
if ( mouse_y == 1 )
|
||||
{
|
||||
if ( mouse_x >= x1 && mouse_x < x2 )
|
||||
{
|
||||
// Mouse pointer over item
|
||||
selectMenuItem (*iter);
|
||||
}
|
||||
selectMenuItem (item); // Mouse pointer over item
|
||||
else
|
||||
{
|
||||
unselectMenuItem (*iter);
|
||||
unselectMenuItem (item);
|
||||
}
|
||||
}
|
||||
|
||||
++iter;
|
||||
}
|
||||
|
||||
if ( getStatusBar() )
|
||||
{
|
||||
if ( ! hasSelectedItem() )
|
||||
|
@ -866,36 +860,32 @@ void FMenuBar::mouseUpOverList (const FMouseEvent* ev)
|
|||
if ( list.empty() )
|
||||
return;
|
||||
|
||||
auto iter = list.begin();
|
||||
auto last = list.end();
|
||||
int mouse_x = ev->getX();
|
||||
int mouse_y = ev->getY();
|
||||
|
||||
while ( iter != last )
|
||||
for (auto&& item : list)
|
||||
{
|
||||
int x1 = (*iter)->getX();
|
||||
int x2 = (*iter)->getX() + int((*iter)->getWidth());
|
||||
int x1 = item->getX();
|
||||
int x2 = item->getX() + int(item->getWidth());
|
||||
|
||||
if ( mouse_y == 1
|
||||
&& mouse_x >= x1
|
||||
&& mouse_x < x2
|
||||
&& (*iter)->isEnabled()
|
||||
&& (*iter)->isSelected() )
|
||||
&& item->isEnabled()
|
||||
&& item->isSelected() )
|
||||
{
|
||||
// Mouse pointer over item
|
||||
if ( ! activateMenu(*iter) )
|
||||
if ( ! activateMenu(item) )
|
||||
{
|
||||
if ( clickItem(*iter) )
|
||||
if ( clickItem(item) )
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
unselectMenuItem(*iter);
|
||||
unselectMenuItem(item);
|
||||
redraw();
|
||||
}
|
||||
|
||||
++iter;
|
||||
}
|
||||
|
||||
if ( ! hasSelectedItem() )
|
||||
|
@ -912,32 +902,30 @@ void FMenuBar::mouseMoveOverList (const FMouseEvent* ev)
|
|||
|
||||
focus_changed = false;
|
||||
bool mouse_over_menubar{false};
|
||||
auto iter = list.begin();
|
||||
auto last = list.end();
|
||||
int mouse_x = ev->getX();
|
||||
int mouse_y = ev->getY();
|
||||
|
||||
if ( getTermGeometry().contains(ev->getTermPos()) )
|
||||
mouse_over_menubar = true;
|
||||
|
||||
while ( iter != last )
|
||||
for (auto&& item : list)
|
||||
{
|
||||
int x1 = (*iter)->getX();
|
||||
int x2 = (*iter)->getX() + int((*iter)->getWidth());
|
||||
int x1 = item->getX();
|
||||
int x2 = item->getX() + int(item->getWidth());
|
||||
|
||||
if ( mouse_x >= x1
|
||||
&& mouse_x < x2
|
||||
&& mouse_y == 1 )
|
||||
{
|
||||
// Mouse pointer over item
|
||||
selectMenuItem(*iter);
|
||||
selectMenuItem(item);
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( mouse_over_menubar )
|
||||
{
|
||||
// Unselect selected item without mouse focus
|
||||
unselectMenuItem(*iter);
|
||||
unselectMenuItem(item);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -945,8 +933,6 @@ void FMenuBar::mouseMoveOverList (const FMouseEvent* ev)
|
|||
passEventToMenu(ev);
|
||||
}
|
||||
}
|
||||
|
||||
++iter;
|
||||
}
|
||||
|
||||
if ( getStatusBar() )
|
||||
|
|
|
@ -94,7 +94,7 @@ bool FMenuItem::setEnable (bool enable)
|
|||
if ( super && isMenuBar(super) )
|
||||
{
|
||||
// Meta + hotkey
|
||||
super->addAccelerator ( fc::Fmkey_meta + FKey(std::tolower(hotkey))
|
||||
super->addAccelerator ( fc::Fmkey_meta + FKey(std::tolower(int(hotkey)))
|
||||
, this );
|
||||
}
|
||||
}
|
||||
|
@ -190,10 +190,14 @@ void FMenuItem::setText (const FString& txt)
|
|||
{
|
||||
text.setString(txt);
|
||||
text_length = text.getLength();
|
||||
hotkey = hotKey();
|
||||
text_width = getColumnWidth(txt);
|
||||
hotkey = finalcut::getHotkey(text);
|
||||
|
||||
if ( hotkey )
|
||||
{
|
||||
text_length--;
|
||||
text_width--;
|
||||
}
|
||||
|
||||
updateSuperMenuDimensions();
|
||||
}
|
||||
|
@ -524,12 +528,19 @@ FMenuList* FMenuItem::getFMenuList (FWidget& widget)
|
|||
void FMenuItem::init (FWidget* parent)
|
||||
{
|
||||
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 )
|
||||
{
|
||||
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 )
|
||||
return;
|
||||
|
@ -550,7 +561,7 @@ void FMenuItem::init (FWidget* parent)
|
|||
menubar_ptr->calculateDimensions();
|
||||
|
||||
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 );
|
||||
|
||||
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()
|
||||
{
|
||||
|
|
|
@ -61,7 +61,6 @@ FMessageBox::FMessageBox (const FMessageBox& mbox)
|
|||
, headline_text(mbox.headline_text)
|
||||
, text(mbox.text)
|
||||
, text_components(mbox.text_components)
|
||||
, text_split(mbox.text_split)
|
||||
, max_line_width(mbox.max_line_width)
|
||||
, emphasis_color(mbox.emphasis_color)
|
||||
, num_buttons(mbox.num_buttons)
|
||||
|
@ -114,7 +113,6 @@ FMessageBox& FMessageBox::operator = (const FMessageBox& mbox)
|
|||
headline_text = mbox.headline_text;
|
||||
text = mbox.text;
|
||||
text_components = mbox.text_components;
|
||||
text_split = mbox.text_split;
|
||||
max_line_width = mbox.max_line_width;
|
||||
center_text = mbox.center_text;
|
||||
emphasis_color = mbox.emphasis_color;
|
||||
|
@ -139,10 +137,10 @@ void FMessageBox::setHeadline (const FString& headline)
|
|||
for (uInt n{0}; n < num_buttons; n++)
|
||||
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 )
|
||||
max_line_width = len;
|
||||
if ( column_width > max_line_width )
|
||||
max_line_width = column_width;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
@ -311,9 +309,9 @@ void FMessageBox::calculateDimensions()
|
|||
{
|
||||
FSize size{};
|
||||
std::size_t headline_height{0};
|
||||
text_split = text.split("\n");
|
||||
text_components = text.split("\n");
|
||||
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 )
|
||||
return;
|
||||
|
@ -321,13 +319,12 @@ void FMessageBox::calculateDimensions()
|
|||
if ( ! headline_text.isNull() )
|
||||
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 len = text_components[i].getLength();
|
||||
std::size_t column_width = getColumnWidth(line);
|
||||
|
||||
if ( len > max_line_width )
|
||||
max_line_width = len;
|
||||
if ( column_width > max_line_width )
|
||||
max_line_width = column_width;
|
||||
}
|
||||
|
||||
size.setHeight (text_num_lines + 8 + headline_height);
|
||||
|
@ -344,21 +341,22 @@ void FMessageBox::draw()
|
|||
{
|
||||
FDialog::draw();
|
||||
|
||||
int head_offset = 0;
|
||||
int center_x = 0;
|
||||
int y{0};
|
||||
int head_offset{0};
|
||||
int center_x{0};
|
||||
// center the whole block
|
||||
int msg_x = int((getWidth() - max_line_width) / 2);
|
||||
|
||||
if ( isMonochron() )
|
||||
setReverse(true);
|
||||
|
||||
if ( ! headline_text.isNull() )
|
||||
if ( ! headline_text.isEmpty() )
|
||||
{
|
||||
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
|
||||
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;
|
||||
head_offset = 2;
|
||||
|
@ -366,15 +364,16 @@ void FMessageBox::draw()
|
|||
|
||||
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
|
||||
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)
|
||||
<< text_components[i];
|
||||
print() << FPoint(1 + msg_x + center_x, 4 + head_offset + y)
|
||||
<< line;
|
||||
y++;
|
||||
}
|
||||
|
||||
if ( isMonochron() )
|
||||
|
|
|
@ -1220,10 +1220,10 @@ inline bool FOptiAttr::hasColorChanged (charData*& term, charData*& next)
|
|||
{
|
||||
if ( term && next )
|
||||
{
|
||||
bool frev = ( on.attr.bit.reverse
|
||||
bool frev ( ( on.attr.bit.reverse
|
||||
|| on.attr.bit.standout
|
||||
|| off.attr.bit.reverse
|
||||
|| off.attr.bit.standout ) && fake_reverse;
|
||||
|| off.attr.bit.standout ) && fake_reverse );
|
||||
return bool ( frev
|
||||
|| term->fg_color != next->fg_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& Sb = F_set_background.cap;
|
||||
auto& sp = F_set_color_pair.cap;
|
||||
bool frev = ( off.attr.bit.reverse
|
||||
bool frev ( ( off.attr.bit.reverse
|
||||
|| off.attr.bit.standout
|
||||
|| term->attr.bit.reverse
|
||||
|| term->attr.bit.standout ) && fake_reverse;
|
||||
|| term->attr.bit.standout ) && fake_reverse );
|
||||
|
||||
if ( AF && AB )
|
||||
{
|
||||
|
|
|
@ -146,7 +146,7 @@ void FProgressbar::drawProgressLabel()
|
|||
, parent_widget->getBackgroundColor() );
|
||||
else
|
||||
{
|
||||
const FWidgetColors& wc = getFWidgetColors();
|
||||
const auto& wc = getFWidgetColors();
|
||||
setColor ( wc.dialog_fg, wc.dialog_bg );
|
||||
}
|
||||
|
||||
|
@ -192,7 +192,7 @@ std::size_t FProgressbar::drawProgressIndicator()
|
|||
|
||||
double length = double(bar_length * percentage) / 100;
|
||||
auto len = std::size_t(trunc(length));
|
||||
const FWidgetColors& wc = getFWidgetColors();
|
||||
const auto& wc = getFWidgetColors();
|
||||
print() << FColorPair (wc.progressbar_fg, wc.progressbar_fg)
|
||||
<< FString (len, fc::FullBlock); // █
|
||||
|
||||
|
@ -225,7 +225,7 @@ void FProgressbar::drawProgressBackground (std::size_t len)
|
|||
// Draw the progress background
|
||||
|
||||
std::size_t bg_len = bar_length - len;
|
||||
const FWidgetColors& wc = getFWidgetColors();
|
||||
const auto& wc = getFWidgetColors();
|
||||
setColor (wc.progressbar_fg, wc.progressbar_bg);
|
||||
|
||||
if ( getMaxColor() < 16 )
|
||||
|
|
|
@ -472,7 +472,7 @@ void FScrollbar::draw()
|
|||
//----------------------------------------------------------------------
|
||||
void FScrollbar::drawVerticalBar()
|
||||
{
|
||||
const FWidgetColors& wc = getFWidgetColors();
|
||||
const auto& wc = getFWidgetColors();
|
||||
setColor (wc.scrollbar_fg, wc.scrollbar_bg);
|
||||
|
||||
for (int z{1}; z <= slider_pos; z++)
|
||||
|
@ -531,7 +531,7 @@ inline void FScrollbar::drawVerticalBackgroundLine()
|
|||
//----------------------------------------------------------------------
|
||||
void FScrollbar::drawHorizontalBar()
|
||||
{
|
||||
const FWidgetColors& wc = getFWidgetColors();
|
||||
const auto& wc = getFWidgetColors();
|
||||
setColor (wc.scrollbar_fg, wc.scrollbar_bg);
|
||||
|
||||
if ( isNewFont() )
|
||||
|
@ -577,7 +577,7 @@ inline void FScrollbar::drawHorizontalBackgroundColumn()
|
|||
//----------------------------------------------------------------------
|
||||
void FScrollbar::drawButtons()
|
||||
{
|
||||
const FWidgetColors& wc = getFWidgetColors();
|
||||
const auto& wc = getFWidgetColors();
|
||||
setColor (wc.scrollbar_button_fg, wc.scrollbar_button_bg);
|
||||
|
||||
if ( isNewFont() )
|
||||
|
|
|
@ -764,7 +764,7 @@ void FScrollView::init (FWidget* parent)
|
|||
|
||||
initScrollbar (vbar, fc::vertical, &FScrollView::cb_VBarChange);
|
||||
initScrollbar (hbar, fc::horizontal, &FScrollView::cb_HBarChange);
|
||||
const FWidgetColors& wc = getFWidgetColors();
|
||||
const auto& wc = getFWidgetColors();
|
||||
setForegroundColor (wc.dialog_fg);
|
||||
setBackgroundColor (wc.dialog_bg);
|
||||
setGeometry (FPoint(1, 1), FSize(4, 4));
|
||||
|
|
|
@ -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
|
||||
|
|
@ -175,7 +175,7 @@ bool FStatusBar::hasActivatedKey()
|
|||
void FStatusBar::hide()
|
||||
{
|
||||
FWindow::hide();
|
||||
const FWidgetColors& wc = getFWidgetColors();
|
||||
const auto& wc = getFWidgetColors();
|
||||
FColor fg = wc.term_fg;
|
||||
FColor bg = wc.term_bg;
|
||||
setColor (fg, bg);
|
||||
|
@ -196,7 +196,7 @@ void FStatusBar::drawMessage()
|
|||
|
||||
x = x_msg;
|
||||
int space_offset{1};
|
||||
bool hasKeys = bool(! key_list.empty());
|
||||
bool hasKeys( ! key_list.empty() );
|
||||
bool isLastActiveFocus{false};
|
||||
std::size_t termWidth = getDesktopWidth();
|
||||
|
||||
|
@ -212,7 +212,7 @@ void FStatusBar::drawMessage()
|
|||
if ( isLastActiveFocus )
|
||||
space_offset = 0;
|
||||
|
||||
const FWidgetColors& wc = getFWidgetColors();
|
||||
const auto& wc = getFWidgetColors();
|
||||
setColor (wc.statusbar_fg, wc.statusbar_bg);
|
||||
setPrintPos (FPoint(x, 1));
|
||||
|
||||
|
@ -236,7 +236,7 @@ void FStatusBar::drawMessage()
|
|||
print (' ');
|
||||
}
|
||||
|
||||
std::size_t msg_length = getMessage().getLength();
|
||||
auto msg_length = getColumnWidth(getMessage());
|
||||
x += int(msg_length);
|
||||
|
||||
if ( x - 1 <= int(termWidth) )
|
||||
|
@ -244,8 +244,9 @@ void FStatusBar::drawMessage()
|
|||
else
|
||||
{
|
||||
// Print ellipsis
|
||||
print ( getMessage().left(msg_length + termWidth - uInt(x) - 1) );
|
||||
print ("..");
|
||||
std::size_t len = msg_length + termWidth - uInt(x) - 1;
|
||||
print() << getColumnSubString ( getMessage(), 1, len)
|
||||
<< "..";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -358,8 +359,8 @@ void FStatusBar::onMouseDown (FMouseEvent* ev)
|
|||
while ( iter != last )
|
||||
{
|
||||
int x1 = X
|
||||
, kname_len = int(getKeyName((*iter)->getKey()).getLength())
|
||||
, txt_length = int((*iter)->getText().getLength())
|
||||
, kname_len = getKeyNameWidth(*iter)
|
||||
, txt_length = getKeyTextWidth(*iter)
|
||||
, x2 = x1 + kname_len + txt_length + 1
|
||||
, mouse_x = ev->getX()
|
||||
, mouse_y = ev->getY();
|
||||
|
@ -401,8 +402,8 @@ void FStatusBar::onMouseUp (FMouseEvent* ev)
|
|||
while ( iter != last )
|
||||
{
|
||||
int x1 = X
|
||||
, kname_len = int(getKeyName((*iter)->getKey()).getLength())
|
||||
, txt_length = int((*iter)->getText().getLength())
|
||||
, kname_len = getKeyNameWidth(*iter)
|
||||
, txt_length = getKeyTextWidth(*iter)
|
||||
, x2 = x1 + kname_len + txt_length + 1;
|
||||
|
||||
if ( (*iter)->hasMouseFocus() )
|
||||
|
@ -446,8 +447,8 @@ void FStatusBar::onMouseMove (FMouseEvent* ev)
|
|||
while ( iter != last )
|
||||
{
|
||||
int x1 = X
|
||||
, kname_len = int(getKeyName((*iter)->getKey()).getLength())
|
||||
, txt_length = int((*iter)->getText().getLength())
|
||||
, kname_len = getKeyNameWidth(*iter)
|
||||
, txt_length = getKeyTextWidth(*iter)
|
||||
, x2 = x1 + kname_len + txt_length + 1
|
||||
, mouse_x = ev->getX()
|
||||
, mouse_y = ev->getY();
|
||||
|
@ -518,12 +519,26 @@ void FStatusBar::init()
|
|||
if ( getRootWidget() )
|
||||
getRootWidget()->setBottomPadding(1, true);
|
||||
|
||||
const FWidgetColors& wc = getFWidgetColors();
|
||||
const auto& wc = getFWidgetColors();
|
||||
setForegroundColor (wc.statusbar_fg);
|
||||
setBackgroundColor (wc.statusbar_bg);
|
||||
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()
|
||||
{
|
||||
|
@ -549,22 +564,22 @@ void FStatusBar::drawKeys()
|
|||
setReverse(true);
|
||||
|
||||
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 ( (*iter)->isActivated() || (*iter)->hasMouseFocus() )
|
||||
if ( item->isActivated() || item->hasMouseFocus() )
|
||||
drawActiveKey (iter);
|
||||
else
|
||||
drawKey (iter);
|
||||
}
|
||||
else
|
||||
{
|
||||
const FWidgetColors& wc = getFWidgetColors();
|
||||
const auto& wc = getFWidgetColors();
|
||||
setColor (wc.statusbar_fg, wc.statusbar_bg);
|
||||
|
||||
for (; x <= int(screenWidth); x++)
|
||||
|
@ -586,7 +601,7 @@ void FStatusBar::drawKey (keyList::const_iterator iter)
|
|||
// Draw not active key
|
||||
|
||||
auto item = *iter;
|
||||
const FWidgetColors& wc = getFWidgetColors();
|
||||
const auto& wc = getFWidgetColors();
|
||||
setColor (wc.statusbar_hotkey_fg, wc.statusbar_hotkey_bg);
|
||||
x++;
|
||||
print (' ');
|
||||
|
@ -595,23 +610,22 @@ void FStatusBar::drawKey (keyList::const_iterator iter)
|
|||
setColor (wc.statusbar_fg, wc.statusbar_bg);
|
||||
x++;
|
||||
print ('-');
|
||||
std::size_t txt_length = item->getText().getLength();
|
||||
x += int(txt_length);
|
||||
auto column_width = getColumnWidth (item->getText());
|
||||
x += int(column_width);
|
||||
|
||||
if ( x - 1 <= int(screenWidth) )
|
||||
print (item->getText());
|
||||
else
|
||||
{
|
||||
// Print ellipsis
|
||||
std::size_t len = txt_length + screenWidth - std::size_t(x) - 1;
|
||||
print (item->getText().left(len));
|
||||
print ("..");
|
||||
std::size_t len = column_width + screenWidth - std::size_t(x) - 1;
|
||||
print() << getColumnSubString(item->getText(), 1, len)
|
||||
<< "..";
|
||||
}
|
||||
|
||||
if ( iter + 1 != key_list.end()
|
||||
&& ( (*(iter + 1))->isActivated() || (*(iter + 1))->hasMouseFocus() )
|
||||
&& x + int(getKeyName((*(iter + 1))->getKey()).getLength()) + 3
|
||||
< int(screenWidth) )
|
||||
&& x + getKeyNameWidth(*(iter + 1)) + 3 < int(screenWidth) )
|
||||
{
|
||||
// Next element is active
|
||||
if ( isMonochron() )
|
||||
|
@ -649,7 +663,7 @@ void FStatusBar::drawActiveKey (keyList::const_iterator iter)
|
|||
if ( isMonochron() )
|
||||
setReverse(false);
|
||||
|
||||
const FWidgetColors& wc = getFWidgetColors();
|
||||
const auto& wc = getFWidgetColors();
|
||||
setColor ( wc.statusbar_active_hotkey_fg
|
||||
, wc.statusbar_active_hotkey_bg );
|
||||
x++;
|
||||
|
@ -659,8 +673,8 @@ void FStatusBar::drawActiveKey (keyList::const_iterator iter)
|
|||
setColor (wc.statusbar_active_fg, wc.statusbar_active_bg);
|
||||
x++;
|
||||
print ('-');
|
||||
std::size_t txt_length = item->getText().getLength();
|
||||
x += int(txt_length);
|
||||
auto column_width = getColumnWidth (item->getText());
|
||||
x += int(column_width);
|
||||
|
||||
if ( x <= int(screenWidth) )
|
||||
{
|
||||
|
@ -671,9 +685,9 @@ void FStatusBar::drawActiveKey (keyList::const_iterator iter)
|
|||
else
|
||||
{
|
||||
// Print ellipsis
|
||||
print ( item->getText()
|
||||
.left(txt_length + screenWidth - std::size_t(x) - 1) );
|
||||
print ("..");
|
||||
std::size_t len = column_width + screenWidth - std::size_t(x) - 1;
|
||||
print() << getColumnSubString(item->getText(), 1, len)
|
||||
<< "..";
|
||||
}
|
||||
|
||||
if ( isMonochron() )
|
||||
|
|
148
src/fstring.cpp
148
src/fstring.cpp
|
@ -20,6 +20,7 @@
|
|||
* <http://www.gnu.org/licenses/>. *
|
||||
***********************************************************************/
|
||||
|
||||
#include <algorithm>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
@ -417,7 +418,7 @@ std::size_t FString::getUTF8length() const
|
|||
if ( ! string )
|
||||
return 0;
|
||||
|
||||
std::size_t len = 0;
|
||||
std::size_t len{0};
|
||||
const char* s = c_str();
|
||||
|
||||
while ( *s )
|
||||
|
@ -426,27 +427,6 @@ std::size_t FString::getUTF8length() const
|
|||
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()
|
||||
{
|
||||
|
@ -511,17 +491,11 @@ const std::string FString::toString() const
|
|||
FString FString::toLower() const
|
||||
{
|
||||
FString s(string);
|
||||
wchar_t* p = s.string;
|
||||
|
||||
if ( p )
|
||||
auto to_lower = [] (wchar_t& c)
|
||||
{
|
||||
while ( *p )
|
||||
{
|
||||
*p = wchar_t(std::towlower(wint_t(*p)));
|
||||
p++;
|
||||
}
|
||||
}
|
||||
|
||||
c = wchar_t(std::towlower(std::wint_t(c)));
|
||||
};
|
||||
std::for_each (s.begin(), s.end(), to_lower);
|
||||
return s;
|
||||
}
|
||||
|
||||
|
@ -529,17 +503,11 @@ FString FString::toLower() const
|
|||
FString FString::toUpper() const
|
||||
{
|
||||
FString s(string);
|
||||
wchar_t* p = s.string;
|
||||
|
||||
if ( p )
|
||||
auto to_upper = [] (wchar_t& c)
|
||||
{
|
||||
while ( *p )
|
||||
{
|
||||
*p = wchar_t(std::towupper(wint_t(*p)));
|
||||
p++;
|
||||
}
|
||||
}
|
||||
|
||||
c = wchar_t(std::towupper(std::wint_t(c)));
|
||||
};
|
||||
std::for_each (s.begin(), s.end(), to_upper);
|
||||
return s;
|
||||
}
|
||||
|
||||
|
@ -621,9 +589,9 @@ long FString::toLong() const
|
|||
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
|
||||
|| (num == tenth_limit && d > tenth_limit_digit) )
|
||||
|
@ -638,7 +606,7 @@ long FString::toLong() const
|
|||
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");
|
||||
|
||||
if ( neg )
|
||||
|
@ -671,9 +639,9 @@ uLong FString::toULong() const
|
|||
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
|
||||
|| (num == tenth_limit && d > tenth_limit_digit) )
|
||||
|
@ -685,7 +653,7 @@ uLong FString::toULong() const
|
|||
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");
|
||||
|
||||
return num;
|
||||
|
@ -743,7 +711,7 @@ FString FString::ltrim() const
|
|||
|
||||
const wchar_t* p = s.string;
|
||||
|
||||
while ( std::iswspace(wint_t(*p)) )
|
||||
while ( std::iswspace(std::wint_t(*p)) )
|
||||
p++;
|
||||
|
||||
return FString(p);
|
||||
|
@ -761,10 +729,10 @@ FString FString::rtrim() const
|
|||
wchar_t* p = s.string;
|
||||
wchar_t* last = p + length;
|
||||
|
||||
while ( std::iswspace(wint_t(*--last)) && last > p )
|
||||
while ( std::iswspace(std::wint_t(*--last)) && last > p )
|
||||
s.length--;
|
||||
|
||||
if ( last == p && std::iswspace(wint_t(*last)) )
|
||||
if ( last == p && std::iswspace(std::wint_t(*last)) )
|
||||
s = L"";
|
||||
else
|
||||
*(last + 1) = '\0';
|
||||
|
@ -1166,29 +1134,23 @@ FString FString::replace (const FString& from, const FString& to)
|
|||
FString FString::replaceControlCodes() const
|
||||
{
|
||||
FString s(string);
|
||||
wchar_t* p = s.string;
|
||||
|
||||
if ( p )
|
||||
for (auto&& c : s)
|
||||
{
|
||||
while ( *p )
|
||||
if ( c <= L'\x1f' )
|
||||
{
|
||||
if ( *p <= L'\x1f' )
|
||||
{
|
||||
*p += L'\x2400';
|
||||
c += L'\x2400';
|
||||
}
|
||||
else if ( *p == L'\x7f' )
|
||||
else if ( c == L'\x7f' )
|
||||
{
|
||||
*p = L'\x2421';
|
||||
c = L'\x2421';
|
||||
}
|
||||
else if ( *p >= L'\x80' && *p <= L'\x9f' )
|
||||
else if ( c >= L'\x80' && c <= L'\x9f' )
|
||||
{
|
||||
*p = L' ';
|
||||
}
|
||||
else if ( ! std::iswprint(wint_t(*p)) )
|
||||
*p = L' ';
|
||||
|
||||
p++;
|
||||
c = L' ';
|
||||
}
|
||||
else if ( ! std::iswprint(std::wint_t(c)) )
|
||||
c = L' ';
|
||||
}
|
||||
|
||||
return s;
|
||||
|
@ -1224,36 +1186,28 @@ FString FString::expandTabs (int tabstop) const
|
|||
FString FString::removeDel() const
|
||||
{
|
||||
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};
|
||||
uInt d{0};
|
||||
|
||||
while ( *p )
|
||||
if ( c == 0x7f )
|
||||
{
|
||||
if ( *p == 0x7f )
|
||||
{
|
||||
d++;
|
||||
count++;
|
||||
}
|
||||
else if ( d > 0 )
|
||||
else if ( count > 0 )
|
||||
{
|
||||
d--;
|
||||
count--;
|
||||
}
|
||||
else
|
||||
else // count == 0
|
||||
{
|
||||
s.string[i] = *p;
|
||||
s.string[i] = c;
|
||||
i++;
|
||||
}
|
||||
|
||||
p++;
|
||||
}
|
||||
|
||||
s.string[i] = L'\0';
|
||||
s.length = i;
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
|
@ -1262,31 +1216,23 @@ FString FString::removeDel() const
|
|||
FString FString::removeBackspaces() const
|
||||
{
|
||||
FString s(string);
|
||||
const wchar_t* p = s.string;
|
||||
std::size_t i{0};
|
||||
|
||||
if ( p )
|
||||
for (auto&& c : s)
|
||||
{
|
||||
uInt i = 0;
|
||||
|
||||
while ( *p )
|
||||
if ( c != L'\b' )
|
||||
{
|
||||
if ( *p != L'\b' )
|
||||
{
|
||||
s.string[i] = *p;
|
||||
s.string[i] = c;
|
||||
i++;
|
||||
}
|
||||
else if ( i > 0 )
|
||||
{
|
||||
i--;
|
||||
}
|
||||
|
||||
p++;
|
||||
}
|
||||
|
||||
s.string[i] = L'\0';
|
||||
s.length = i;
|
||||
}
|
||||
|
||||
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 )
|
||||
{
|
||||
|
@ -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
|
||||
return;
|
||||
|
@ -1430,7 +1376,7 @@ 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
|
||||
, const wchar_t s[] )
|
||||
{
|
||||
|
@ -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 )
|
||||
{
|
||||
|
@ -1558,7 +1504,7 @@ inline char* FString::wc_to_c_str (const wchar_t s[]) const
|
|||
int size = int(std::wcslen(s)) + 1;
|
||||
int dest_size = size * int(CHAR_SIZE);
|
||||
const wchar_t* src = s;
|
||||
std::mbstate_t state;
|
||||
std::mbstate_t state{};
|
||||
std::memset (&state, '\0', sizeof(mbstate_t));
|
||||
|
||||
try
|
||||
|
@ -1611,7 +1557,7 @@ inline wchar_t* FString::c_to_wc_str (const char s[]) const
|
|||
int dest_size = size * int(CHAR_SIZE);
|
||||
const char* src = s;
|
||||
wchar_t* dest{};
|
||||
std::mbstate_t state;
|
||||
std::mbstate_t state{};
|
||||
std::memset (&state, '\0', sizeof(mbstate_t));
|
||||
|
||||
try
|
||||
|
|
|
@ -143,7 +143,7 @@ inline void FSwitch::drawChecked()
|
|||
{
|
||||
wchar_t on[6]{L" On "};
|
||||
wchar_t off[6]{L" Off "};
|
||||
const FWidgetColors& wc = getFWidgetColors();
|
||||
const auto& wc = getFWidgetColors();
|
||||
|
||||
if ( hasFocus() && ! button_pressed )
|
||||
{
|
||||
|
@ -194,7 +194,7 @@ inline void FSwitch::drawUnchecked()
|
|||
wchar_t on[6]{L" On "};
|
||||
wchar_t off[6]{L" Off "};
|
||||
|
||||
const FWidgetColors& wc = getFWidgetColors();
|
||||
const auto& wc = getFWidgetColors();
|
||||
setColor (wc.button_inactive_fg, wc.button_inactive_bg);
|
||||
|
||||
if ( isMonochron() )
|
||||
|
|
293
src/fterm.cpp
293
src/fterm.cpp
|
@ -35,9 +35,9 @@
|
|||
#include "final/foptimove.h"
|
||||
#include "final/fstartoptions.h"
|
||||
#include "final/fstring.h"
|
||||
#include "final/fsystem.h"
|
||||
#include "final/fsystemimpl.h"
|
||||
#include "final/fterm.h"
|
||||
#include "final/ftermbuffer.h"
|
||||
#include "final/ftermcap.h"
|
||||
#include "final/ftermcapquirks.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 )
|
||||
ch_enc = FTerm::unicode_to_cp437(c);
|
||||
ch_enc = finalcut::unicode_to_cp437(c);
|
||||
|
||||
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()
|
||||
{
|
||||
|
@ -1234,21 +1196,6 @@ bool FTerm::scrollTermReverse()
|
|||
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)
|
||||
{
|
||||
|
@ -1352,6 +1299,12 @@ void FTerm::exitWithMessage (const FString& message)
|
|||
|
||||
|
||||
// private methods of FTerm
|
||||
//----------------------------------------------------------------------
|
||||
inline FStartOptions& FTerm::getStartOptions()
|
||||
{
|
||||
return FStartOptions::getFStartOptions();
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
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 altChar = uChar(vt100_alt_char[keyChar]);
|
||||
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]
|
||||
, 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
|
||||
|
|
|
@ -41,55 +41,43 @@ FTermBuffer::~FTermBuffer() // destructor
|
|||
|
||||
// public methods of FTermBuffer
|
||||
//----------------------------------------------------------------------
|
||||
int FTermBuffer::writef (const FString format, ...)
|
||||
const FString FTermBuffer::toString() const
|
||||
{
|
||||
static constexpr int BUFSIZE = 4096;
|
||||
wchar_t buffer[BUFSIZE]{};
|
||||
va_list args{};
|
||||
std::wstring wide_string{};
|
||||
wide_string.reserve(data.size());
|
||||
|
||||
if ( format.isEmpty() )
|
||||
return 0;
|
||||
for (auto&& tc : data)
|
||||
wide_string.push_back(tc.code);
|
||||
|
||||
va_start (args, format);
|
||||
std::vswprintf (buffer, BUFSIZE, format.wc_str(), args);
|
||||
va_end (args);
|
||||
|
||||
FString str(buffer);
|
||||
return write(str);
|
||||
return FString(wide_string);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
int FTermBuffer::write (const FString& s)
|
||||
int FTermBuffer::write (const FString& string)
|
||||
{
|
||||
assert ( ! s.isNull() );
|
||||
int len{0};
|
||||
const wchar_t* p = s.wc_str();
|
||||
assert ( ! string.isNull() );
|
||||
int len = int(string.getLength());
|
||||
|
||||
if ( p )
|
||||
{
|
||||
while ( *p )
|
||||
for (auto&& c : string)
|
||||
{
|
||||
charData nc; // next character
|
||||
nc = FVTerm::getAttribute();
|
||||
nc.code = *p;
|
||||
nc.code = c;
|
||||
getColumnWidth(nc); // add column width
|
||||
nc.attr.bit.no_changes = false;
|
||||
nc.attr.bit.printed = false;
|
||||
|
||||
data.push_back(nc);
|
||||
|
||||
p++;
|
||||
len++;
|
||||
} // end of while
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
int FTermBuffer::write (wchar_t c)
|
||||
int FTermBuffer::write (wchar_t ch)
|
||||
{
|
||||
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.printed = false;
|
||||
|
||||
|
|
|
@ -193,7 +193,7 @@ bool FTermFreeBSD::saveFreeBSDAltKey()
|
|||
return false;
|
||||
|
||||
// Save current mapping
|
||||
bsd_alt_keymap = keymap.key[left_alt].map[0];
|
||||
bsd_alt_keymap = uInt(keymap.key[left_alt].map[0]);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -213,7 +213,7 @@ bool FTermFreeBSD::setFreeBSDAltKey (uInt key)
|
|||
return false;
|
||||
|
||||
// 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)
|
||||
&& fsystem && (fsystem->ioctl(0, PIO_KEYMAP, &keymap) < 0) )
|
||||
|
|
|
@ -358,7 +358,7 @@ bool FTermLinux::loadNewFont()
|
|||
//----------------------------------------------------------------------
|
||||
bool FTermLinux::loadOldFont()
|
||||
{
|
||||
bool retval = false;
|
||||
bool retval{false};
|
||||
|
||||
if ( FTerm::openConsole() == 0 )
|
||||
{
|
||||
|
|
|
@ -104,8 +104,8 @@ bool FTermOpenBSD::setBeep (int Hz, int ms)
|
|||
|
||||
wskbd_bell_data bell;
|
||||
bell.which = WSKBD_BELL_DOALL;
|
||||
bell.pitch = Hz;
|
||||
bell.period = ms;
|
||||
bell.pitch = uInt(Hz);
|
||||
bell.period = uInt(ms);
|
||||
bell.volume = 50; // 50% volume
|
||||
|
||||
if ( fsystem && fsystem->ioctl(0, WSKBDIO_SETBELL, &bell) < 0 )
|
||||
|
|
|
@ -398,6 +398,7 @@ void FTermXTerminal::setXTermCursorStyle()
|
|||
|
||||
if ( TCAP(fc::t_cursor_style)
|
||||
|| term_detection->isXTerminal()
|
||||
|| term_detection->isCygwinTerminal()
|
||||
|| term_detection->isMinttyTerm()
|
||||
|| term_detection->hasSetCursorStyleSupport() )
|
||||
{
|
||||
|
@ -413,6 +414,7 @@ void FTermXTerminal::setXTermTitle()
|
|||
|
||||
if ( term_detection->isXTerminal()
|
||||
|| term_detection->isScreenTerm()
|
||||
|| term_detection->isCygwinTerminal()
|
||||
|| term_detection->isMinttyTerm()
|
||||
|| term_detection->isPuttyTerminal()
|
||||
|| FTermcap::osc_support )
|
||||
|
@ -626,12 +628,12 @@ void FTermXTerminal::resetXTermColorMap()
|
|||
|
||||
if ( term_detection->isMinttyTerm() )
|
||||
{
|
||||
FTerm::putstringf (ESC "c"); // Full Reset (RIS)
|
||||
FTerm::putstring (ESC "c"); // Full Reset (RIS)
|
||||
}
|
||||
else if ( canResetColor() )
|
||||
{
|
||||
oscPrefix();
|
||||
FTerm::putstringf (OSC "104" BEL);
|
||||
FTerm::putstring (OSC "104" BEL);
|
||||
oscPostfix();
|
||||
std::fflush(stdout);
|
||||
}
|
||||
|
@ -715,7 +717,7 @@ void FTermXTerminal::resetXTermHighlightBackground()
|
|||
if ( canResetColor() )
|
||||
{
|
||||
oscPrefix();
|
||||
FTerm::putstringf (OSC "117" BEL);
|
||||
FTerm::putstring (OSC "117" BEL);
|
||||
oscPostfix();
|
||||
std::fflush(stdout);
|
||||
}
|
||||
|
|
|
@ -145,8 +145,8 @@ void FTextView::scrollBy (int dx, int dy)
|
|||
//----------------------------------------------------------------------
|
||||
void FTextView::scrollTo (int x, int y)
|
||||
{
|
||||
bool changeX = bool(x != xoffset);
|
||||
bool changeY = bool(y != yoffset);
|
||||
bool changeX( x != xoffset );
|
||||
bool changeY( y != yoffset );
|
||||
|
||||
if ( ! isShown() || ! (changeX || changeY) )
|
||||
return;
|
||||
|
@ -207,7 +207,7 @@ void FTextView::append (const FString& str)
|
|||
//----------------------------------------------------------------------
|
||||
void FTextView::insert (const FString& str, int pos)
|
||||
{
|
||||
FString s;
|
||||
FString s{};
|
||||
|
||||
if ( pos < 0 || pos >= int(getRows()) )
|
||||
pos = int(getRows());
|
||||
|
@ -217,23 +217,22 @@ void FTextView::insert (const FString& str, int pos)
|
|||
else
|
||||
s = FString(str).rtrim().expandTabs(getTabstop());
|
||||
|
||||
auto iter = data.begin();
|
||||
auto text_split = s.split("\r\n");
|
||||
auto num = text_split.size();
|
||||
|
||||
for (std::size_t i{0}; i < num; i++)
|
||||
auto text_split = s.split("\r\n");
|
||||
|
||||
for (auto&& line : text_split) // Line loop
|
||||
{
|
||||
text_split[i] = text_split[i].removeBackspaces()
|
||||
line = line.removeBackspaces()
|
||||
.removeDel()
|
||||
.replaceControlCodes()
|
||||
.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(maxLineWidth) - int(getTextWidth())
|
||||
|
@ -242,12 +241,13 @@ void FTextView::insert (const FString& str, int pos)
|
|||
hbar->setPageSize (int(maxLineWidth), int(getTextWidth()));
|
||||
hbar->calculateSliderValues();
|
||||
|
||||
if ( ! hbar->isShown() )
|
||||
if ( isShown() && ! hbar->isShown() )
|
||||
hbar->show();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
auto iter = data.begin();
|
||||
data.insert (iter + pos, text_split.begin(), text_split.end());
|
||||
int vmax = ( getRows() > getTextHeight() )
|
||||
? int(getRows()) - int(getTextHeight())
|
||||
|
@ -256,10 +256,10 @@ void FTextView::insert (const FString& str, int pos)
|
|||
vbar->setPageSize (int(getRows()), int(getTextHeight()));
|
||||
vbar->calculateSliderValues();
|
||||
|
||||
if ( ! vbar->isShown() && getRows() > getTextHeight() )
|
||||
if ( isShown() && ! vbar->isShown() && getRows() > getTextHeight() )
|
||||
vbar->show();
|
||||
|
||||
if ( vbar->isShown() && getRows() <= getTextHeight() )
|
||||
if ( isShown() && vbar->isShown() && getRows() <= getTextHeight() )
|
||||
vbar->hide();
|
||||
|
||||
processChanged();
|
||||
|
@ -597,7 +597,7 @@ void FTextView::init()
|
|||
{
|
||||
initScrollbar (vbar, fc::vertical, &FTextView::cb_VBarChange);
|
||||
initScrollbar (hbar, fc::horizontal, &FTextView::cb_HBarChange);
|
||||
const FWidgetColors& wc = getFWidgetColors();
|
||||
const auto& wc = getFWidgetColors();
|
||||
setForegroundColor (wc.dialog_fg);
|
||||
setBackgroundColor (wc.dialog_bg);
|
||||
nf_offset = isNewFont() ? 1 : 0;
|
||||
|
@ -662,6 +662,12 @@ void FTextView::draw()
|
|||
if ( isMonochron() )
|
||||
setReverse(false);
|
||||
|
||||
if ( ! isShown() ) // first drawing
|
||||
{
|
||||
vbar->show();
|
||||
hbar->show();
|
||||
}
|
||||
|
||||
if ( vbar->isShown() )
|
||||
vbar->redraw();
|
||||
|
||||
|
@ -703,40 +709,48 @@ void FTextView::drawText()
|
|||
if ( isMonochron() )
|
||||
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 = y + std::size_t(yoffset);
|
||||
std::size_t x = std::size_t(xoffset) + 1;
|
||||
FString line(data[n].mid (x, getTextWidth()));
|
||||
const auto line_str = line.wc_str();
|
||||
const auto len = line.getLength();
|
||||
std::size_t n = std::size_t(yoffset) + y;
|
||||
std::size_t pos = std::size_t(xoffset) + 1;
|
||||
std::size_t trailing_whitespace{0};
|
||||
auto text_width = getTextWidth();
|
||||
FString line(getColumnSubString(data[n], pos, text_width));
|
||||
auto column_width = getColumnWidth(line);
|
||||
print() << FPoint(2, 2 - nf_offset + int(y));
|
||||
|
||||
for (i = 0; i < len; i++)
|
||||
{
|
||||
wchar_t ch = line_str[i];
|
||||
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 )
|
||||
for (auto&& ch : line) // Column loop
|
||||
{
|
||||
if ( isPrintable(ch) )
|
||||
print (ch);
|
||||
}
|
||||
else
|
||||
print ('.');
|
||||
}
|
||||
|
||||
for (; i < getTextWidth(); i++)
|
||||
print (' ');
|
||||
if ( column_width <= text_width )
|
||||
trailing_whitespace = text_width - column_width;
|
||||
|
||||
print() << FString(trailing_whitespace, L' ');
|
||||
}
|
||||
|
||||
if ( isMonochron() )
|
||||
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()
|
||||
{
|
||||
|
|
|
@ -86,7 +86,8 @@ void FToggleButton::setGeometry ( const FPoint& pos, const FSize& s
|
|||
|
||||
FSize size(s);
|
||||
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 )
|
||||
size.setWidth(min_width);
|
||||
|
@ -109,7 +110,7 @@ bool FToggleButton::setNoUnderline (bool enable)
|
|||
bool FToggleButton::setEnable (bool enable)
|
||||
{
|
||||
FWidget::setEnable(enable);
|
||||
const FWidgetColors& wc = getFWidgetColors();
|
||||
const auto& wc = getFWidgetColors();
|
||||
|
||||
if ( enable )
|
||||
{
|
||||
|
@ -140,7 +141,7 @@ bool FToggleButton::setEnable (bool enable)
|
|||
bool FToggleButton::setFocus (bool enable)
|
||||
{
|
||||
FWidget::setFocus(enable);
|
||||
const FWidgetColors& wc = getFWidgetColors();
|
||||
const auto& wc = getFWidgetColors();
|
||||
|
||||
if ( enable )
|
||||
{
|
||||
|
@ -194,8 +195,8 @@ void FToggleButton::setText (const FString& txt)
|
|||
{
|
||||
text.setString(txt);
|
||||
std::size_t hotkey_mark = ( getHotkey(text) ) ? 1 : 0;
|
||||
|
||||
setWidth(button_width + text.getLength() - hotkey_mark);
|
||||
std::size_t column_width = getColumnWidth(text);
|
||||
setWidth(button_width + column_width - hotkey_mark);
|
||||
|
||||
if ( isEnabled() )
|
||||
{
|
||||
|
@ -371,6 +372,9 @@ void FToggleButton::setHotkeyAccelerator()
|
|||
{
|
||||
FKey hotkey = getHotkey(text);
|
||||
|
||||
if ( hotkey > 0xff00 && hotkey < 0xff5f ) // full-width character
|
||||
hotkey -= 0xfee0;
|
||||
|
||||
if ( hotkey )
|
||||
{
|
||||
if ( std::isalpha(int(hotkey)) || std::isdigit(int(hotkey)) )
|
||||
|
@ -534,7 +538,7 @@ void FToggleButton::setGroup (FButtonGroup* btngroup)
|
|||
void FToggleButton::init()
|
||||
{
|
||||
setGeometry (FPoint(1, 1), FSize(4, 1), false); // initialize geometry values
|
||||
const FWidgetColors& wc = getFWidgetColors();
|
||||
const auto& wc = getFWidgetColors();
|
||||
|
||||
if ( isEnabled() )
|
||||
{
|
||||
|
@ -564,7 +568,7 @@ void FToggleButton::drawText ( wchar_t LabelText[]
|
|||
if ( isMonochron() )
|
||||
setReverse(true);
|
||||
|
||||
const FWidgetColors& wc = getFWidgetColors();
|
||||
const auto& wc = getFWidgetColors();
|
||||
|
||||
if ( isEnabled() )
|
||||
setColor (wc.label_fg, wc.label_bg);
|
||||
|
|
|
@ -78,6 +78,7 @@ void FToolTip::setText (const FString& txt)
|
|||
//----------------------------------------------------------------------
|
||||
void FToolTip::draw()
|
||||
{
|
||||
int y{0};
|
||||
setColor();
|
||||
|
||||
if ( getMaxColor() < 16 )
|
||||
|
@ -86,9 +87,10 @@ void FToolTip::draw()
|
|||
clearArea();
|
||||
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();
|
||||
|
@ -126,7 +128,7 @@ void FToolTip::init()
|
|||
// initialize geometry values
|
||||
setGeometry (FPoint(1, 1), FSize(3, 3), false);
|
||||
setMinimumSize (FSize(3, 3));
|
||||
const FWidgetColors& wc = getFWidgetColors();
|
||||
const auto& wc = getFWidgetColors();
|
||||
setForegroundColor (wc.tooltip_fg);
|
||||
setBackgroundColor (wc.tooltip_bg);
|
||||
calculateDimensions();
|
||||
|
@ -138,19 +140,18 @@ void FToolTip::calculateDimensions()
|
|||
int x{}, y{};
|
||||
auto r = getRootWidget();
|
||||
max_line_width = 0;
|
||||
text_split = text.split("\n");
|
||||
text_num_lines = uInt(text_split.size());
|
||||
text_components = text.split("\n");
|
||||
text_num_lines = std::size_t(text_components.size());
|
||||
|
||||
if ( text_num_lines == 0 )
|
||||
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 len = text_components[i].getLength();
|
||||
std::size_t column_width = getColumnWidth(line);
|
||||
|
||||
if ( len > max_line_width )
|
||||
max_line_width = len;
|
||||
if ( column_width > max_line_width )
|
||||
max_line_width = column_width;
|
||||
}
|
||||
|
||||
std::size_t h = text_num_lines + 2;
|
||||
|
|
267
src/fvterm.cpp
267
src/fvterm.cpp
|
@ -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)
|
||||
{
|
||||
|
@ -532,6 +514,10 @@ int FVTerm::print (term_area* area, charData& term_char)
|
|||
int bsh = area->bottom_shadow;
|
||||
int ax = area->cursor_x - 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
|
||||
&& area->cursor_y > 0
|
||||
|
@ -579,6 +565,8 @@ int FVTerm::print (term_area* area, charData& term_char)
|
|||
area->cursor_x = 1;
|
||||
area->cursor_y++;
|
||||
}
|
||||
else if ( char_width == 2 )
|
||||
printPaddingCharacter (area, nc);
|
||||
|
||||
// Prevent up scrolling
|
||||
if ( area->cursor_y > height + bsh )
|
||||
|
@ -872,7 +860,7 @@ FVTerm::covered_state FVTerm::isCovered ( const FPoint& pos
|
|||
if ( ! area )
|
||||
return non_covered;
|
||||
|
||||
bool found = bool(area == vdesktop);
|
||||
bool found( area == vdesktop );
|
||||
auto is_covered = non_covered;
|
||||
|
||||
if ( FWidget::getWindowList() && ! FWidget::getWindowList()->empty() )
|
||||
|
@ -1190,8 +1178,8 @@ void FVTerm::updateVTerm (term_area* area)
|
|||
int ay = area->offset_top;
|
||||
int width = area->width + area->right_shadow;
|
||||
int height = area->height + area->bottom_shadow;
|
||||
int ol = 0; // Outside left
|
||||
int y_end;
|
||||
int ol{0}; // Outside left
|
||||
int y_end{};
|
||||
|
||||
// Call the processing handler methods
|
||||
callPreprocessingHandler(area);
|
||||
|
@ -1209,8 +1197,7 @@ void FVTerm::updateVTerm (term_area* area)
|
|||
|
||||
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_xmax = int(area->changes[y].xmax);
|
||||
|
||||
|
@ -1244,8 +1231,8 @@ void FVTerm::updateVTerm (term_area* area)
|
|||
line_xmin++; // Don't update covered character
|
||||
}
|
||||
|
||||
_xmin = ax + line_xmin - ol;
|
||||
_xmax = ax + line_xmax;
|
||||
int _xmin = ax + line_xmin - ol;
|
||||
int _xmax = ax + line_xmax;
|
||||
|
||||
if ( _xmin < int(vterm->changes[ay + y].xmin) )
|
||||
vterm->changes[ay + y].xmin = uInt(_xmin);
|
||||
|
@ -1340,10 +1327,9 @@ void FVTerm::getArea (const FPoint& pos, term_area* area)
|
|||
if ( ! area )
|
||||
return;
|
||||
|
||||
int y_end;
|
||||
int length;
|
||||
int ax = pos.getX() - 1;
|
||||
int ay = pos.getY() - 1;
|
||||
int y_end{}, length{};
|
||||
|
||||
if ( area->height + ay > vterm->height )
|
||||
y_end = area->height - ay;
|
||||
|
@ -1431,7 +1417,7 @@ void FVTerm::putArea (const FPoint& pos, term_area* area)
|
|||
int ay = pos.getY() - 1;
|
||||
int width = area->width + area->right_shadow;
|
||||
int height = area->height + area->bottom_shadow;
|
||||
int ol = 0; // outside left
|
||||
int ol{0}; // outside left
|
||||
int y_end{}, length{};
|
||||
|
||||
if ( ax < 0 )
|
||||
|
@ -2308,6 +2294,7 @@ void FVTerm::printRange ( uInt xmin, uInt xmax, uInt y
|
|||
auto& rp = TCAP(fc::t_repeat_char);
|
||||
auto print_char = &vt->text[y * uInt(vt->width) + x];
|
||||
print_char->attr.bit.printed = true;
|
||||
replaceNonPrintableFullwidth (x, print_char);
|
||||
|
||||
// skip character with no changes
|
||||
if ( skipUnchangedCharacters(x, xmax, y) )
|
||||
|
@ -2326,14 +2313,193 @@ void FVTerm::printRange ( uInt xmin, uInt xmax, uInt y
|
|||
{
|
||||
repeatCharacter(x, xmax, y);
|
||||
}
|
||||
else // General character output
|
||||
{
|
||||
bool min_and_not_max( x == xmin && xmin != xmax );
|
||||
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
|
||||
{
|
||||
// General character output
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
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
|
||||
, bool draw_trailing_ws )
|
||||
|
@ -2347,7 +2513,7 @@ FVTerm::exit_state FVTerm::eraseCharacters ( uInt& x, uInt xmax, uInt y
|
|||
if ( ! ec || print_char->code != ' ' )
|
||||
return not_used;
|
||||
|
||||
uInt whitespace = 1;
|
||||
uInt whitespace{1};
|
||||
bool normal = FTerm::isNormal(print_char);
|
||||
|
||||
for (uInt i = x + 1; i <= xmax; i++)
|
||||
|
@ -2358,6 +2524,7 @@ FVTerm::exit_state FVTerm::eraseCharacters ( uInt& x, uInt xmax, uInt y
|
|||
whitespace++;
|
||||
else
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
if ( whitespace == 1 )
|
||||
|
@ -2454,6 +2621,18 @@ FVTerm::exit_state FVTerm::repeatCharacter (uInt& x, uInt xmax, uInt y)
|
|||
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()
|
||||
{
|
||||
|
@ -2507,6 +2686,34 @@ bool FVTerm::printWrap (term_area* 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)
|
||||
{
|
||||
|
|
|
@ -1250,10 +1250,10 @@ void FWidget::drawShadow()
|
|||
return;
|
||||
}
|
||||
|
||||
int x1 = 1
|
||||
, x2 = int(getWidth())
|
||||
, y1 = 1
|
||||
, y2 = int(getHeight());
|
||||
int x1 = 1;
|
||||
int x2 = int(getWidth());
|
||||
int y1 = 1;
|
||||
int y2 = int(getHeight());
|
||||
|
||||
if ( flags.trans_shadow )
|
||||
{
|
||||
|
@ -1310,10 +1310,10 @@ void FWidget::drawFlatBorder()
|
|||
if ( ! isNewFont() )
|
||||
return;
|
||||
|
||||
int x1 = 1
|
||||
, x2 = int(getWidth()) + 1
|
||||
, y1 = 0
|
||||
, y2 = int(getHeight()) + 1;
|
||||
int x1 = 1;
|
||||
int x2 = int(getWidth() + 1);
|
||||
int y1 = 0;
|
||||
int y2 = int(getHeight() + 1);
|
||||
|
||||
if ( auto p = getParentWidget() )
|
||||
setColor (wcolors.dialog_fg, p->getBackgroundColor());
|
||||
|
@ -1377,10 +1377,10 @@ void FWidget::clearFlatBorder()
|
|||
if ( ! isNewFont() )
|
||||
return;
|
||||
|
||||
int x1 = 1
|
||||
, x2 = int(getWidth()) + 1
|
||||
, y1 = 0
|
||||
, y2 = int(getHeight()) + 1;
|
||||
int x1 = 1;
|
||||
int x2 = int(getWidth() + 1);
|
||||
int y1 = 0;
|
||||
int y2 = int(getHeight() + 1);
|
||||
|
||||
if ( auto p = getParentWidget() )
|
||||
setColor (wcolors.dialog_fg, p->getBackgroundColor());
|
||||
|
|
|
@ -782,18 +782,18 @@ void FWindow::setShadowSize (const FSize& size)
|
|||
//----------------------------------------------------------------------
|
||||
void FWindow::adjustSize()
|
||||
{
|
||||
int old_x = getX();
|
||||
int old_y = getY();
|
||||
int old_x = getTermX();
|
||||
int old_y = getTermY();
|
||||
FWidget::adjustSize();
|
||||
|
||||
if ( zoomed )
|
||||
setGeometry (FPoint(1, 1), FSize(getMaxWidth(), getMaxHeight()), false);
|
||||
else if ( isVirtualWindow() )
|
||||
{
|
||||
if ( getX() != old_x )
|
||||
if ( getTermX() != old_x )
|
||||
getVWin()->offset_left = getTermX() - 1;
|
||||
|
||||
if ( getY() != old_y )
|
||||
if ( getTermY() != old_y )
|
||||
getVWin()->offset_top = getTermY() - 1;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -79,6 +79,7 @@ class FCloseEvent;
|
|||
class FFocusEvent;
|
||||
class FKeyEvent;
|
||||
class FMouseEvent;
|
||||
class FStartOptions;
|
||||
class FTimerEvent;
|
||||
class FWheelEvent;
|
||||
class FMouseControl;
|
||||
|
@ -144,6 +145,7 @@ class FApplication : public FWidget
|
|||
// Methods
|
||||
void init (uInt64, uInt64);
|
||||
static void cmd_options (const int&, char*[]);
|
||||
static FStartOptions& getStartOptions();
|
||||
void findKeyboardWidget();
|
||||
bool isKeyPressed();
|
||||
void keyPressed();
|
||||
|
|
|
@ -173,7 +173,7 @@ class FButton : public FWidget
|
|||
std::size_t indent{0};
|
||||
std::size_t center_offset{0};
|
||||
std::size_t vcenter_offset{0};
|
||||
std::size_t txtlength{0};
|
||||
std::size_t column_width{0};
|
||||
};
|
||||
|
||||
// FButton inline functions
|
||||
|
|
|
@ -152,6 +152,9 @@ enum SpecialCharacter : wchar_t
|
|||
DownwardsArrow = 0x2193, // ↓
|
||||
RightwardsArrow = 0x2192, // →
|
||||
LeftwardsArrow = 0x2190, // ←
|
||||
SingleRightAngleQuotationMark = 0x203a, // › (1)
|
||||
SingleLeftAngleQuotationMark = 0x2039, // ‹ (1)
|
||||
HorizontalEllipsis = 0x2026, // … (1)
|
||||
DoubleExclamationMark = 0x203c, // ‼
|
||||
SuperscriptLatinSmallLetterN = 0x207f, // ⁿ
|
||||
GreaterThanOrEqualTo = 0x2265, // ≥
|
||||
|
|
|
@ -45,6 +45,9 @@ extern const std::size_t lastKeyItem;
|
|||
extern wchar_t cp437_to_ucs[][2];
|
||||
extern const std::size_t lastCP437Item;
|
||||
|
||||
extern wchar_t halfWidth_fullWidth[][2];
|
||||
extern const std::size_t lastHalfWidthItem;
|
||||
|
||||
} // namespace fc
|
||||
|
||||
} // namespace finalcut
|
||||
|
|
|
@ -146,7 +146,7 @@ class FLabel : public FWidget
|
|||
void draw() override;
|
||||
void drawMultiLine();
|
||||
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 );
|
||||
|
||||
// Data members
|
||||
|
@ -178,6 +178,10 @@ inline fc::text_alignment FLabel::getAlignment()
|
|||
inline FString& FLabel::getText()
|
||||
{ return text; }
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
inline bool FLabel::setEmphasis (bool enable)
|
||||
{ return (emphasis = enable); }
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
inline bool FLabel::setEmphasis()
|
||||
{ return setEmphasis(true); }
|
||||
|
@ -186,6 +190,10 @@ inline bool FLabel::setEmphasis()
|
|||
inline bool FLabel::unsetEmphasis()
|
||||
{ return setEmphasis(false); }
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
inline bool FLabel::setReverseMode (bool enable)
|
||||
{ return (reverse_mode = enable); }
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
inline bool FLabel::setReverseMode()
|
||||
{ return setReverseMode(true); }
|
||||
|
|
|
@ -156,6 +156,9 @@ class FLineEdit : public FWidget
|
|||
void adjustSize() override;
|
||||
|
||||
private:
|
||||
// Typedef
|
||||
typedef std::pair<std::size_t, std::size_t> offsetPair;
|
||||
|
||||
// Enumeration
|
||||
enum dragScroll
|
||||
{
|
||||
|
@ -164,19 +167,25 @@ class FLineEdit : public FWidget
|
|||
scrollRight = 2
|
||||
};
|
||||
|
||||
// Constants
|
||||
static constexpr std::size_t NOT_SET = static_cast<std::size_t>(-1);
|
||||
|
||||
// Methods
|
||||
void init();
|
||||
bool hasHotkey();
|
||||
void draw() override;
|
||||
void drawInputField();
|
||||
void keyLeft();
|
||||
void keyRight();
|
||||
void keyHome();
|
||||
void keyEnd();
|
||||
void keyDel();
|
||||
void keyBackspace();
|
||||
void keyInsert();
|
||||
void keyEnter();
|
||||
offsetPair endPosToOffset (std::size_t);
|
||||
std::size_t clickPosToCursorPos (std::size_t);
|
||||
void adjustTextOffset();
|
||||
void cursorLeft();
|
||||
void cursorRight();
|
||||
void cursorHome();
|
||||
void cursorEnd();
|
||||
void deleteCurrentCharacter();
|
||||
void deletePreviousCharacter();
|
||||
void switchInsertMode();
|
||||
void acceptInput();
|
||||
bool keyInput (FKey);
|
||||
wchar_t characterFilter (const wchar_t);
|
||||
void processActivate();
|
||||
|
@ -192,8 +201,9 @@ class FLineEdit : public FWidget
|
|||
int scroll_repeat{100};
|
||||
bool scroll_timer{false};
|
||||
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 char_width_offset{0};
|
||||
std::size_t max_length{std::numeric_limits<std::size_t>::max()};
|
||||
};
|
||||
|
||||
|
|
|
@ -290,19 +290,19 @@ class FListBox : public FWidget
|
|||
void scrollToY (int);
|
||||
void scrollLeft (int);
|
||||
void scrollRight (int);
|
||||
void keyUp();
|
||||
void keyDown();
|
||||
void keyLeft();
|
||||
void keyRight();
|
||||
void keyPgUp();
|
||||
void keyPgDn();
|
||||
void keyHome();
|
||||
void keyEnd();
|
||||
bool keyEsc();
|
||||
void keyEnter();
|
||||
bool keySpace();
|
||||
bool keyInsert();
|
||||
bool keyBackspace();
|
||||
void scrollLeft();
|
||||
void scrollRight();
|
||||
void onePosUp();
|
||||
void onePosDown();
|
||||
void onePageUp();
|
||||
void onePageDown();
|
||||
void firstPos();
|
||||
void lastPos();
|
||||
bool skipIncrementalSearch();
|
||||
void acceptSelection();
|
||||
bool spacebarProcessing();
|
||||
bool changeSelectionAndPosition();
|
||||
bool deletePreviousCharacter();
|
||||
bool keyIncSearchInput (FKey);
|
||||
void processClick();
|
||||
void processSelect();
|
||||
|
|
|
@ -394,6 +394,7 @@ class FListView : public FWidget
|
|||
void drawSortIndicator (std::size_t&, std::size_t);
|
||||
void drawHeadlineLabel (const headerItems::const_iterator&);
|
||||
void drawHeaderBorder (std::size_t);
|
||||
void drawBufferedHeadline();
|
||||
void drawColumnEllipsis ( const headerItems::const_iterator&
|
||||
, const FString& );
|
||||
void updateDrawing (bool, bool);
|
||||
|
@ -413,13 +414,13 @@ class FListView : public FWidget
|
|||
FObjectIterator appendItem (FListViewItem*);
|
||||
void processClick();
|
||||
void processChanged();
|
||||
void keySpace();
|
||||
void keyLeft (int&);
|
||||
void keyRight (int&);
|
||||
void keyHome();
|
||||
void keyEnd();
|
||||
bool keyPlus();
|
||||
bool keyMinus();
|
||||
void toggleCheckbox();
|
||||
void collapseAndScrollLeft (int&);
|
||||
void expandAndScrollRight (int&);
|
||||
void firstPos();
|
||||
void lastPos();
|
||||
bool expandSubtree();
|
||||
bool collapseSubtree();
|
||||
void setRelativePosition (int);
|
||||
void stepForward();
|
||||
void stepBackward();
|
||||
|
|
|
@ -210,12 +210,10 @@ class FMenu : public FWindow, public FMenuList
|
|||
void drawTrailingSpaces (std::size_t);
|
||||
void setLineAttributes (FMenuItem*, int);
|
||||
void setCursorToHotkeyPosition (FMenuItem*);
|
||||
void keyUp();
|
||||
void keyDown();
|
||||
void keyLeft (FKeyEvent*);
|
||||
void keyRight (FKeyEvent*);
|
||||
void keyEnter();
|
||||
void keyEscape();
|
||||
void selectPrevMenu (FKeyEvent*);
|
||||
void selectNextMenu (FKeyEvent*);
|
||||
void acceptSelection();
|
||||
void closeMenu();
|
||||
void processActivate();
|
||||
|
||||
// Friend classes
|
||||
|
@ -227,7 +225,7 @@ class FMenu : public FWindow, public FMenuList
|
|||
friend class FRadioMenuItem;
|
||||
|
||||
// Data members
|
||||
FMenuItem item{};
|
||||
FMenuItem menuitem{};
|
||||
FWidget* super_menu{nullptr};
|
||||
FMenu* opened_sub_menu{nullptr};
|
||||
FMenu* shown_sub_menu{nullptr};
|
||||
|
@ -245,35 +243,35 @@ inline const char* FMenu::getClassName() const
|
|||
|
||||
//----------------------------------------------------------------------
|
||||
inline FString FMenu::getText() const
|
||||
{ return item.getText(); }
|
||||
{ return menuitem.getText(); }
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
inline FMenuItem* FMenu::getItem()
|
||||
{ return &item; }
|
||||
{ return &menuitem; }
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
inline bool FMenu::setEnable (bool enable)
|
||||
{ return item.setEnable(enable); }
|
||||
{ return menuitem.setEnable(enable); }
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
inline bool FMenu::setEnable()
|
||||
{ return item.setEnable(); }
|
||||
{ return menuitem.setEnable(); }
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
inline bool FMenu::unsetEnable()
|
||||
{ return item.unsetEnable(); }
|
||||
{ return menuitem.unsetEnable(); }
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
inline bool FMenu::setDisable()
|
||||
{ return item.setDisable(); }
|
||||
{ return menuitem.setDisable(); }
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
inline void FMenu::setSelected()
|
||||
{ item.setSelected(); }
|
||||
{ menuitem.setSelected(); }
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
inline void FMenu::unsetSelected()
|
||||
{ item.unsetSelected(); }
|
||||
{ menuitem.unsetSelected(); }
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
inline bool FMenu::setMenuWidget()
|
||||
|
@ -285,27 +283,27 @@ inline bool FMenu::unsetMenuWidget()
|
|||
|
||||
//----------------------------------------------------------------------
|
||||
inline void FMenu::setMenu (FMenu* m)
|
||||
{ item.setMenu(m); }
|
||||
{ menuitem.setMenu(m); }
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
inline void FMenu::setText (const FString& txt)
|
||||
{ item.setText(txt); }
|
||||
{ menuitem.setText(txt); }
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
inline bool FMenu::isEnabled() const
|
||||
{ return item.isEnabled(); }
|
||||
{ return menuitem.isEnabled(); }
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
inline bool FMenu::isSelected() const
|
||||
{ return item.isSelected(); }
|
||||
{ return menuitem.isSelected(); }
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
inline bool FMenu::hasHotkey() const
|
||||
{ return item.hasHotkey(); }
|
||||
{ return menuitem.hasHotkey(); }
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
inline bool FMenu::hasMenu() const
|
||||
{ return item.hasMenu(); }
|
||||
{ return menuitem.hasMenu(); }
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
inline FWidget* FMenu::getSuperMenu() const
|
||||
|
@ -325,7 +323,7 @@ inline FMenu* FMenu::superMenuAt (const FPoint& p)
|
|||
|
||||
//----------------------------------------------------------------------
|
||||
inline void FMenu::onAccel (FAccelEvent* ev)
|
||||
{ item.onAccel(ev); }
|
||||
{ menuitem.onAccel(ev); }
|
||||
|
||||
} // namespace finalcut
|
||||
|
||||
|
|
|
@ -132,6 +132,7 @@ class FMenuBar : public FWindow, public FMenuList
|
|||
void drawItems();
|
||||
void drawItem (FMenuItem*, std::size_t&);
|
||||
void setLineAttributes (FMenuItem*);
|
||||
void setCursorToHotkeyPosition (FMenuItem*, std::size_t);
|
||||
void drawMenuText (menuText&);
|
||||
void drawEllipsis (const menuText&, std::size_t);
|
||||
void drawLeadingSpace (std::size_t&);
|
||||
|
|
|
@ -94,9 +94,10 @@ class FMenuItem : public FWidget
|
|||
|
||||
// Accessors
|
||||
const char* getClassName() const override;
|
||||
uChar getHotkey() const;
|
||||
FKey getHotkey() const;
|
||||
FMenu* getMenu() const;
|
||||
std::size_t getTextLength() const;
|
||||
std::size_t getTextWidth() const;
|
||||
FString getText() const;
|
||||
|
||||
// Mutators
|
||||
|
@ -159,7 +160,6 @@ class FMenuItem : public FWidget
|
|||
|
||||
// Methods
|
||||
void init (FWidget*);
|
||||
uChar hotKey();
|
||||
void updateSuperMenuDimensions();
|
||||
void processActivate();
|
||||
void processDeactivate();
|
||||
|
@ -179,8 +179,9 @@ class FMenuItem : public FWidget
|
|||
FWidget* super_menu{nullptr};
|
||||
FDialog* associated_window{nullptr};
|
||||
std::size_t text_length{0};
|
||||
std::size_t text_width{0};
|
||||
FKey accel_key{0};
|
||||
uChar hotkey{0};
|
||||
FKey hotkey{0};
|
||||
bool selected{false};
|
||||
bool separator{false};
|
||||
bool checkable{false};
|
||||
|
@ -202,7 +203,7 @@ inline const char* FMenuItem::getClassName() const
|
|||
{ return "FMenuItem"; }
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
inline uChar FMenuItem::getHotkey() const
|
||||
inline FKey FMenuItem::getHotkey() const
|
||||
{ return hotkey; }
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
@ -213,6 +214,10 @@ inline FMenu* FMenuItem::getMenu() const
|
|||
inline std::size_t FMenuItem::getTextLength() const
|
||||
{ return text_length; }
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
inline std::size_t FMenuItem::getTextWidth() const
|
||||
{ return text_width; }
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
inline FString FMenuItem::getText() const
|
||||
{ return text; }
|
||||
|
|
|
@ -155,14 +155,13 @@ class FMessageBox : public FDialog
|
|||
// Data members
|
||||
FString headline_text{};
|
||||
FString text{};
|
||||
FString* text_components{nullptr};
|
||||
FStringList text_split{};
|
||||
FStringList text_components{};
|
||||
FButton* button[3]{nullptr};
|
||||
std::size_t max_line_width{0};
|
||||
FColor emphasis_color{getFWidgetColors().dialog_emphasis_fg};
|
||||
int button_digit[3]{0};
|
||||
uInt num_buttons{0};
|
||||
uInt text_num_lines{0};
|
||||
std::size_t text_num_lines{0};
|
||||
bool center_text{false};
|
||||
};
|
||||
|
||||
|
|
|
@ -342,7 +342,9 @@ inline bool operator == ( const charData& lhs,
|
|||
&& lhs.fg_color == rhs.fg_color
|
||||
&& lhs.bg_color == rhs.bg_color
|
||||
&& 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;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
|
|
@ -35,6 +35,11 @@
|
|||
#error "Only <final/final.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include "final/fc.h"
|
||||
#include "final/ftypes.h"
|
||||
|
||||
namespace finalcut
|
||||
{
|
||||
|
||||
|
@ -42,27 +47,26 @@ namespace finalcut
|
|||
// class FStartOptions
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
struct FStartOptions
|
||||
class FStartOptions final
|
||||
{
|
||||
public:
|
||||
// Mutator
|
||||
void setDefault()
|
||||
{
|
||||
cursor_optimisation = true;
|
||||
mouse_support = true;
|
||||
terminal_detection = true;
|
||||
color_change = true;
|
||||
vgafont = false;
|
||||
newfont = false;
|
||||
encoding = fc::UNKNOWN;
|
||||
// Constructors
|
||||
FStartOptions();
|
||||
|
||||
#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
|
||||
}
|
||||
// Disable copy constructor
|
||||
FStartOptions (const FStartOptions&) = delete;
|
||||
|
||||
// Destructor
|
||||
virtual ~FStartOptions();
|
||||
|
||||
// Disable assignment operator (=)
|
||||
FStartOptions& operator = (const FStartOptions&) = delete;
|
||||
|
||||
// Accessors
|
||||
static FStartOptions& getFStartOptions();
|
||||
|
||||
// Mutator
|
||||
void setDefault();
|
||||
|
||||
// Data members
|
||||
uInt8 cursor_optimisation : 1;
|
||||
|
@ -82,13 +86,10 @@ struct FStartOptions
|
|||
uInt8 meta_sends_escape : 1;
|
||||
uInt8 : 7; // padding bits
|
||||
#endif
|
||||
|
||||
static FStartOptions* start_options;
|
||||
};
|
||||
|
||||
static struct FStartOptions start_options{};
|
||||
|
||||
inline FStartOptions& getStartOptions()
|
||||
{ return start_options; }
|
||||
|
||||
} // namespace finalcut
|
||||
|
||||
#endif // FSTARTOPTIONS_H
|
||||
|
|
|
@ -238,6 +238,8 @@ class FStatusBar : public FWindow
|
|||
|
||||
// Methods
|
||||
void init();
|
||||
int getKeyNameWidth (const FStatusKey*);
|
||||
int getKeyTextWidth (const FStatusKey*);
|
||||
void draw() override;
|
||||
void drawKeys();
|
||||
void drawKey (keyList::const_iterator);
|
||||
|
|
|
@ -78,7 +78,8 @@ class FString
|
|||
{
|
||||
public:
|
||||
// Typedef
|
||||
typedef const wchar_t* iterator;
|
||||
typedef const wchar_t* const_iterator;
|
||||
typedef wchar_t* iterator;
|
||||
|
||||
// Constructors
|
||||
FString () = default;
|
||||
|
@ -191,12 +192,15 @@ class FString
|
|||
std::size_t getUTF8length() const;
|
||||
std::size_t capacity() const;
|
||||
|
||||
iterator begin() const;
|
||||
iterator end() const;
|
||||
iterator begin();
|
||||
iterator end();
|
||||
const_iterator begin() const;
|
||||
const_iterator end() const;
|
||||
wchar_t front() const;
|
||||
wchar_t back() const;
|
||||
|
||||
FString& sprintf (const FString, ...);
|
||||
template<typename... Args>
|
||||
FString& sprintf (const FString, Args&&...);
|
||||
FString clear();
|
||||
|
||||
const wchar_t* wc_str() const;
|
||||
|
@ -369,11 +373,19 @@ inline std::size_t FString::capacity() const
|
|||
{ return ( length > 0 ) ? bufsize - 1 : 0; }
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
inline FString::iterator FString::begin() const
|
||||
inline FString::iterator FString::begin()
|
||||
{ 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; }
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
@ -390,6 +402,25 @@ inline wchar_t FString::back() const
|
|||
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>
|
||||
inline FString& FString::setNumber (NumT num, int precision)
|
||||
|
|
|
@ -116,6 +116,7 @@
|
|||
|
||||
#include "final/fc.h"
|
||||
#include "final/fstring.h"
|
||||
#include "final/fsystem.h"
|
||||
|
||||
namespace finalcut
|
||||
{
|
||||
|
@ -125,9 +126,10 @@ class FKeyboard;
|
|||
class FMouseControl;
|
||||
class FOptiAttr;
|
||||
class FOptiMove;
|
||||
class FStartOptions;
|
||||
class FSize;
|
||||
class FString;
|
||||
class FSystem;
|
||||
class FTermBuffer;
|
||||
class FTermData;
|
||||
class FTermDebugData;
|
||||
class FTermDetection;
|
||||
|
@ -272,8 +274,6 @@ class FTerm final
|
|||
static bool charEncodable (wchar_t);
|
||||
static wchar_t charEncode (wchar_t);
|
||||
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 scrollTermReverse();
|
||||
|
@ -281,13 +281,8 @@ class FTerm final
|
|||
// function pointer -> static function
|
||||
static int (*Fputchar)(int);
|
||||
|
||||
static void putstringf (const char[], ...)
|
||||
#if defined(__clang__)
|
||||
__attribute__ ((__format__ (__printf__, 1, 2)))
|
||||
#elif defined(__GNUC__)
|
||||
__attribute__ ((format (printf, 1, 2)))
|
||||
#endif
|
||||
;
|
||||
template<typename... Args>
|
||||
static void putstringf (const char[], Args&&...);
|
||||
static void putstring (const char[], int = 1);
|
||||
static int putchar_ASCII (int);
|
||||
static int putchar_UTF8 (int);
|
||||
|
@ -303,6 +298,7 @@ class FTerm final
|
|||
;
|
||||
private:
|
||||
// Methods
|
||||
static FStartOptions& getStartOptions();
|
||||
static void init_global_values (bool);
|
||||
static void init_terminal_device_path();
|
||||
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
|
||||
//----------------------------------------------------------------------
|
||||
inline const char* FTerm::getClassName() const
|
||||
|
@ -403,6 +414,16 @@ inline bool FTerm::setUTF8()
|
|||
inline bool FTerm::unsetUTF8()
|
||||
{ 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
|
||||
|
||||
|
||||
|
|
|
@ -54,9 +54,13 @@ class FTermBuffer
|
|||
public:
|
||||
// Typedef
|
||||
typedef std::vector<charData> charDataVector;
|
||||
typedef charDataVector::iterator iterator;
|
||||
typedef charDataVector::const_iterator const_iterator;
|
||||
|
||||
// Constructor
|
||||
FTermBuffer() = default;
|
||||
template<typename Iterator>
|
||||
FTermBuffer (Iterator, Iterator);
|
||||
|
||||
// Destructor
|
||||
virtual ~FTermBuffer();
|
||||
|
@ -64,6 +68,7 @@ class FTermBuffer
|
|||
// Overloaded operators
|
||||
template <typename typeT>
|
||||
FTermBuffer& operator << (const typeT&);
|
||||
FTermBuffer& operator << (const charDataVector&);
|
||||
FTermBuffer& operator << (const std::string&);
|
||||
FTermBuffer& operator << (const std::wstring&);
|
||||
FTermBuffer& operator << (const FColorPair&);
|
||||
|
@ -81,8 +86,16 @@ class FTermBuffer
|
|||
bool isEmpty() const;
|
||||
|
||||
// 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();
|
||||
int writef (const FString, ...);
|
||||
template<typename... Args>
|
||||
int writef (const FString, Args&&...);
|
||||
int write (const FString&);
|
||||
int write (wchar_t);
|
||||
void write (const FColorPair&);
|
||||
|
@ -94,6 +107,13 @@ class FTermBuffer
|
|||
|
||||
|
||||
// FTermBuffer inline functions
|
||||
//----------------------------------------------------------------------
|
||||
template<typename Iterator>
|
||||
inline FTermBuffer::FTermBuffer(Iterator first, Iterator last)
|
||||
{
|
||||
data.assign(first, last);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
template <typename typeT>
|
||||
inline FTermBuffer& FTermBuffer::operator << (const typeT& s)
|
||||
|
@ -107,6 +127,15 @@ inline FTermBuffer& FTermBuffer::operator << (const typeT& s)
|
|||
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)
|
||||
{
|
||||
|
@ -144,6 +173,30 @@ inline const FTermBuffer::charDataVector& FTermBuffer::getBuffer() const
|
|||
inline bool FTermBuffer::isEmpty() const
|
||||
{ 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()
|
||||
{
|
||||
|
@ -151,6 +204,22 @@ inline void FTermBuffer::clear()
|
|||
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()
|
||||
{ return *this; }
|
||||
|
|
|
@ -148,6 +148,7 @@ class FTextView : public FWidget
|
|||
, FTextViewCallback );
|
||||
void draw() override;
|
||||
void drawText();
|
||||
bool isPrintable (wchar_t);
|
||||
void processChanged();
|
||||
|
||||
// Callback methods
|
||||
|
|
|
@ -107,8 +107,7 @@ class FToolTip : public FWindow
|
|||
|
||||
// Data members
|
||||
FString text{};
|
||||
FString* text_components{nullptr};
|
||||
FStringList text_split{};
|
||||
FStringList text_components{};
|
||||
std::size_t max_line_width{0};
|
||||
std::size_t text_num_lines{0};
|
||||
};
|
||||
|
|
|
@ -138,8 +138,9 @@ typedef struct
|
|||
// Attribute byte #2
|
||||
uInt8 no_changes : 1; // no changes required
|
||||
uInt8 printed : 1; // is printed to VTerm
|
||||
uInt8 char_with : 2; // Number of character cells on screen
|
||||
uInt8 : 4; // padding bits
|
||||
uInt8 fullwidth_padding : 1; // padding char (after a full-width char)
|
||||
uInt8 char_width : 2; // number of character cells on screen
|
||||
uInt8 : 3; // padding bits
|
||||
// Attribute byte #3
|
||||
uInt8 : 8; // padding byte
|
||||
} bit;
|
||||
|
|
|
@ -291,7 +291,8 @@ class FVTerm
|
|||
, FPreprocessingHandler );
|
||||
virtual void delPreprocessingHandler (FVTerm*);
|
||||
|
||||
int printf (const FString, ...);
|
||||
template<typename... Args>
|
||||
int printf (const FString, Args&&...);
|
||||
int print (const FString&);
|
||||
int print (term_area*, const FString&);
|
||||
int print (const FTermBuffer&);
|
||||
|
@ -440,10 +441,19 @@ class FVTerm
|
|||
static bool canClearTrailingWS (uInt&, uInt);
|
||||
bool skipUnchangedCharacters (uInt&, uInt, uInt);
|
||||
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 repeatCharacter (uInt&, uInt, uInt);
|
||||
bool isFullWidthChar (charData*&);
|
||||
bool isFullWidthPaddingChar (charData*&);
|
||||
static void cursorWrap();
|
||||
bool printWrap (term_area*);
|
||||
void printPaddingCharacter (term_area*, charData&);
|
||||
void updateTerminalLine (uInt);
|
||||
bool updateTerminalCursor();
|
||||
bool isInsideTerminal (const FPoint&);
|
||||
|
@ -1033,6 +1043,22 @@ inline bool FVTerm::hasChangedTermSize()
|
|||
inline bool FVTerm::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()
|
||||
{ return *this; }
|
||||
|
|
|
@ -11,10 +11,12 @@ SRCS = $(wildcard *.cpp)
|
|||
OBJS = $(SRCS:%.cpp=%)
|
||||
CCXFLAGS = $(OPTIMIZE) $(PROFILE) $(DEBUG) -std=c++11
|
||||
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
|
||||
RM = rm -f
|
||||
|
||||
TERMCAP := $(shell test -n "$$(ldd {/usr,}/lib64/libncursesw.so.5 2>/dev/null | grep libtinfo)" && echo "-ltinfo" || echo "-lncurses")
|
||||
|
||||
ifdef DEBUG
|
||||
OPTIMIZE = -O0 -fsanitize=undefined
|
||||
else
|
||||
|
@ -28,11 +30,11 @@ endif
|
|||
|
||||
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"
|
||||
|
||||
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"
|
||||
|
||||
profile:
|
||||
|
|
|
@ -11,10 +11,12 @@ SRCS = $(wildcard *.cpp)
|
|||
OBJS = $(SRCS:%.cpp=%)
|
||||
CCXFLAGS = $(OPTIMIZE) $(PROFILE) $(DEBUG) -std=c++11
|
||||
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
|
||||
RM = rm -f
|
||||
|
||||
TERMCAP := $(shell test -n "$$(ldd {/usr,}/lib64/libncursesw.so.5 2>/dev/null | grep libtinfo)" && echo "-ltinfo" || echo "-lncurses")
|
||||
|
||||
ifdef DEBUG
|
||||
OPTIMIZE = -O0
|
||||
else
|
||||
|
@ -28,11 +30,11 @@ endif
|
|||
|
||||
all: $(OBJS)
|
||||
|
||||
debug:
|
||||
unittest:
|
||||
$(MAKE) $(MAKEFILE) DEBUG="-g -D DEBUG -DUNIT_TEST -Wall -Wextra -Wpedantic"
|
||||
|
||||
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"
|
||||
|
||||
profile:
|
||||
|
|
|
@ -551,7 +551,8 @@ inline pid_t ConEmu::forkConEmu()
|
|||
while ( ! *shared_state && i < timeout )
|
||||
{
|
||||
// Wait 10 ms (= 10,000,000 ns)
|
||||
nanosleep ((const struct timespec[]){{0, 10000000L}}, NULL);
|
||||
const struct timespec ms[]{{0, 10000000L}};
|
||||
nanosleep (ms, NULL);
|
||||
i++;
|
||||
}
|
||||
|
||||
|
|
|
@ -348,7 +348,8 @@ void FKeyboardTest::escapeKeyTest()
|
|||
input("\033");
|
||||
processInput();
|
||||
// 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();
|
||||
std::cout << " - Key: " << keyboard->getKeyName(key_pressed) << std::endl;
|
||||
CPPUNIT_ASSERT ( key_pressed == finalcut::fc::Fkey_escape );
|
||||
|
@ -2078,7 +2079,8 @@ void FKeyboardTest::metaKeyTest()
|
|||
input("\033O");
|
||||
processInput();
|
||||
// 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();
|
||||
std::cout << " - Key: " << keyboard->getKeyName(key_pressed) << std::endl;
|
||||
CPPUNIT_ASSERT ( key_pressed == finalcut::fc::Fmkey_O );
|
||||
|
@ -2165,7 +2167,7 @@ void FKeyboardTest::metaKeyTest()
|
|||
input("\033[");
|
||||
processInput();
|
||||
// Wait 100 ms - Substring keys needs a timeout
|
||||
nanosleep ((const struct timespec[]){{0, 100000000L}}, NULL);
|
||||
nanosleep (ms, NULL);
|
||||
keyboard->escapeKeyHandling();
|
||||
std::cout << " - Key: " << keyboard->getKeyName(key_pressed) << std::endl;
|
||||
CPPUNIT_ASSERT ( key_pressed == finalcut::fc::Fmkey_left_square_bracket );
|
||||
|
@ -2182,7 +2184,7 @@ void FKeyboardTest::metaKeyTest()
|
|||
input("\033]");
|
||||
processInput();
|
||||
// Wait 100 ms - Substring keys needs a timeout
|
||||
nanosleep ((const struct timespec[]){{0, 100000000L}}, NULL);
|
||||
nanosleep (ms, NULL);
|
||||
keyboard->escapeKeyHandling();
|
||||
std::cout << " - Key: " << keyboard->getKeyName(key_pressed) << std::endl;
|
||||
CPPUNIT_ASSERT ( key_pressed == finalcut::fc::Fmkey_right_square_bracket );
|
||||
|
|
|
@ -551,7 +551,8 @@ void FObjectTest::performTimerActionTest()
|
|||
{
|
||||
num_events += t1.processEvent();
|
||||
// Wait 100 ms
|
||||
nanosleep ((const struct timespec[]){{0, 100000000L}}, NULL);
|
||||
const struct timespec ms[]{{0, 100000000L}};
|
||||
nanosleep (ms, NULL);
|
||||
loop++;
|
||||
}
|
||||
|
||||
|
|
|
@ -973,7 +973,7 @@ void FStringTest::iteratorTest()
|
|||
CPPUNIT_ASSERT ( str.front() == L'1' );
|
||||
CPPUNIT_ASSERT ( str.back() == L'9' );
|
||||
|
||||
finalcut::FString::iterator iter = str.begin();
|
||||
finalcut::FString::const_iterator iter = str.begin();
|
||||
CPPUNIT_ASSERT ( (*iter) == L'1' );
|
||||
++iter;
|
||||
CPPUNIT_ASSERT ( (*iter) == L'2' );
|
||||
|
@ -993,6 +993,17 @@ void FStringTest::iteratorTest()
|
|||
CPPUNIT_ASSERT ( (*iter) == L'9' );
|
||||
++iter;
|
||||
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" );
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
|
|
@ -73,8 +73,8 @@ class FSystemTest : public finalcut::FSystem
|
|||
|
||||
private:
|
||||
// Data members
|
||||
std::string characters;
|
||||
int cursor_type = 0;
|
||||
std::string characters{};
|
||||
int cursor_type{0};
|
||||
static keymap_t keymap;
|
||||
static keymap_t terminal_keymap;
|
||||
};
|
||||
|
@ -401,10 +401,10 @@ int FSystemTest::isTTY (int fd)
|
|||
//----------------------------------------------------------------------
|
||||
int FSystemTest::ioctl (int fd, uLong request, ...)
|
||||
{
|
||||
va_list args;
|
||||
void* argp;
|
||||
std::string req_string;
|
||||
int ret_val = -1;
|
||||
va_list args{};
|
||||
void* argp{};
|
||||
std::string req_string{};
|
||||
int ret_val{-1};
|
||||
|
||||
va_start (args, request);
|
||||
argp = va_arg (args, void*);
|
||||
|
@ -481,7 +481,7 @@ int FSystemTest::ioctl (int fd, uLong request, ...)
|
|||
//----------------------------------------------------------------------
|
||||
int FSystemTest::open (const char* pathname, int flags, ...)
|
||||
{
|
||||
va_list args;
|
||||
va_list args{};
|
||||
va_start (args, flags);
|
||||
mode_t mode = static_cast<mode_t>(va_arg (args, int));
|
||||
va_end (args);
|
||||
|
@ -622,12 +622,11 @@ void ftermfreebsdTest::freebsdConsoleTest()
|
|||
setenv ("COLUMNS", "80", 1);
|
||||
setenv ("LINES", "25", 1);
|
||||
|
||||
finalcut::FTermData* data;
|
||||
finalcut::FSystem* fsys = new test::FSystemTest();
|
||||
finalcut::FTermDetection* term_detection;
|
||||
finalcut::FTermDetection* term_detection{};
|
||||
finalcut::FTerm::setFSystem(fsys);
|
||||
std::cout << "\n";
|
||||
data = finalcut::FTerm::getFTermData();
|
||||
finalcut::FTermData* data = finalcut::FTerm::getFTermData();
|
||||
|
||||
auto& encoding_list = data->getEncodingList();
|
||||
encoding_list["UTF-8"] = finalcut::fc::UTF8;
|
||||
|
@ -698,45 +697,46 @@ void ftermfreebsdTest::freebsdConsoleTest()
|
|||
freebsd.setCursorStyle(freebsd.getCursorStyle());
|
||||
CPPUNIT_ASSERT ( freebsd.getCursorStyle() == finalcut::fc::blink_cursor );
|
||||
|
||||
CPPUNIT_ASSERT ( finalcut::fc::character[2][finalcut::fc::PC] == 21 );
|
||||
CPPUNIT_ASSERT ( finalcut::fc::character[3][finalcut::fc::PC] == 8 );
|
||||
CPPUNIT_ASSERT ( finalcut::fc::character[4][finalcut::fc::PC] == 10 );
|
||||
CPPUNIT_ASSERT ( finalcut::fc::character[5][finalcut::fc::PC] == 19 );
|
||||
CPPUNIT_ASSERT ( finalcut::fc::character[6][finalcut::fc::PC] == 18 );
|
||||
CPPUNIT_ASSERT ( finalcut::fc::character[8][finalcut::fc::PC] == 22 );
|
||||
CPPUNIT_ASSERT ( finalcut::fc::character[9][finalcut::fc::PC] == 24 );
|
||||
CPPUNIT_ASSERT ( finalcut::fc::character[10][finalcut::fc::PC] == 25 );
|
||||
CPPUNIT_ASSERT ( finalcut::fc::character[11][finalcut::fc::PC] == 26 );
|
||||
CPPUNIT_ASSERT ( finalcut::fc::character[12][finalcut::fc::PC] == 27 );
|
||||
CPPUNIT_ASSERT ( finalcut::fc::character[23][finalcut::fc::PC] == 4 );
|
||||
CPPUNIT_ASSERT ( finalcut::fc::character[25][finalcut::fc::PC] == 4 );
|
||||
CPPUNIT_ASSERT ( finalcut::fc::character[26][finalcut::fc::PC] == 4 );
|
||||
CPPUNIT_ASSERT ( finalcut::fc::character[57][finalcut::fc::PC] == 16 );
|
||||
CPPUNIT_ASSERT ( finalcut::fc::character[58][finalcut::fc::PC] == 17 );
|
||||
CPPUNIT_ASSERT ( finalcut::fc::character[59][finalcut::fc::PC] == 16 );
|
||||
CPPUNIT_ASSERT ( finalcut::fc::character[60][finalcut::fc::PC] == 17 );
|
||||
CPPUNIT_ASSERT ( finalcut::fc::character[105][finalcut::fc::PC] == 4 );
|
||||
finalcut::fc::encoding enc = finalcut::fc::PC;
|
||||
CPPUNIT_ASSERT ( finalcut::fc::character[2][enc] == 21 );
|
||||
CPPUNIT_ASSERT ( finalcut::fc::character[3][enc] == 8 );
|
||||
CPPUNIT_ASSERT ( finalcut::fc::character[4][enc] == 10 );
|
||||
CPPUNIT_ASSERT ( finalcut::fc::character[5][enc] == 19 );
|
||||
CPPUNIT_ASSERT ( finalcut::fc::character[6][enc] == 18 );
|
||||
CPPUNIT_ASSERT ( finalcut::fc::character[8][enc] == 22 );
|
||||
CPPUNIT_ASSERT ( finalcut::fc::character[9][enc] == 24 );
|
||||
CPPUNIT_ASSERT ( finalcut::fc::character[10][enc] == 25 );
|
||||
CPPUNIT_ASSERT ( finalcut::fc::character[11][enc] == 26 );
|
||||
CPPUNIT_ASSERT ( finalcut::fc::character[12][enc] == 27 );
|
||||
CPPUNIT_ASSERT ( finalcut::fc::character[23][enc] == 4 );
|
||||
CPPUNIT_ASSERT ( finalcut::fc::character[25][enc] == 4 );
|
||||
CPPUNIT_ASSERT ( finalcut::fc::character[26][enc] == 4 );
|
||||
CPPUNIT_ASSERT ( finalcut::fc::character[57][enc] == 16 );
|
||||
CPPUNIT_ASSERT ( finalcut::fc::character[58][enc] == 17 );
|
||||
CPPUNIT_ASSERT ( finalcut::fc::character[59][enc] == 16 );
|
||||
CPPUNIT_ASSERT ( finalcut::fc::character[60][enc] == 17 );
|
||||
CPPUNIT_ASSERT ( finalcut::fc::character[105][enc] == 4 );
|
||||
|
||||
freebsd.initCharMap();
|
||||
|
||||
CPPUNIT_ASSERT ( finalcut::fc::character[2][finalcut::fc::PC] == 36 );
|
||||
CPPUNIT_ASSERT ( finalcut::fc::character[3][finalcut::fc::PC] == 42 );
|
||||
CPPUNIT_ASSERT ( finalcut::fc::character[4][finalcut::fc::PC] == 42 );
|
||||
CPPUNIT_ASSERT ( finalcut::fc::character[5][finalcut::fc::PC] == 33 );
|
||||
CPPUNIT_ASSERT ( finalcut::fc::character[6][finalcut::fc::PC] == 73 );
|
||||
CPPUNIT_ASSERT ( finalcut::fc::character[8][finalcut::fc::PC] == 95 );
|
||||
CPPUNIT_ASSERT ( finalcut::fc::character[9][finalcut::fc::PC] == 94 );
|
||||
CPPUNIT_ASSERT ( finalcut::fc::character[10][finalcut::fc::PC] == 118 );
|
||||
CPPUNIT_ASSERT ( finalcut::fc::character[11][finalcut::fc::PC] == 62 );
|
||||
CPPUNIT_ASSERT ( finalcut::fc::character[12][finalcut::fc::PC] == 60 );
|
||||
CPPUNIT_ASSERT ( finalcut::fc::character[23][finalcut::fc::PC] == 42 );
|
||||
CPPUNIT_ASSERT ( finalcut::fc::character[25][finalcut::fc::PC] == 42 );
|
||||
CPPUNIT_ASSERT ( finalcut::fc::character[26][finalcut::fc::PC] == 42 );
|
||||
CPPUNIT_ASSERT ( finalcut::fc::character[57][finalcut::fc::PC] == 62 );
|
||||
CPPUNIT_ASSERT ( finalcut::fc::character[58][finalcut::fc::PC] == 60 );
|
||||
CPPUNIT_ASSERT ( finalcut::fc::character[59][finalcut::fc::PC] == 62 );
|
||||
CPPUNIT_ASSERT ( finalcut::fc::character[60][finalcut::fc::PC] == 60 );
|
||||
CPPUNIT_ASSERT ( finalcut::fc::character[105][finalcut::fc::PC] == 42 );
|
||||
CPPUNIT_ASSERT ( finalcut::fc::character[2][enc] == 36 );
|
||||
CPPUNIT_ASSERT ( finalcut::fc::character[3][enc] == 42 );
|
||||
CPPUNIT_ASSERT ( finalcut::fc::character[4][enc] == 42 );
|
||||
CPPUNIT_ASSERT ( finalcut::fc::character[5][enc] == 33 );
|
||||
CPPUNIT_ASSERT ( finalcut::fc::character[6][enc] == 73 );
|
||||
CPPUNIT_ASSERT ( finalcut::fc::character[8][enc] == 95 );
|
||||
CPPUNIT_ASSERT ( finalcut::fc::character[9][enc] == 94 );
|
||||
CPPUNIT_ASSERT ( finalcut::fc::character[10][enc] == 118 );
|
||||
CPPUNIT_ASSERT ( finalcut::fc::character[11][enc] == 62 );
|
||||
CPPUNIT_ASSERT ( finalcut::fc::character[12][enc] == 60 );
|
||||
CPPUNIT_ASSERT ( finalcut::fc::character[23][enc] == 42 );
|
||||
CPPUNIT_ASSERT ( finalcut::fc::character[25][enc] == 42 );
|
||||
CPPUNIT_ASSERT ( finalcut::fc::character[26][enc] == 42 );
|
||||
CPPUNIT_ASSERT ( finalcut::fc::character[57][enc] == 62 );
|
||||
CPPUNIT_ASSERT ( finalcut::fc::character[58][enc] == 60 );
|
||||
CPPUNIT_ASSERT ( finalcut::fc::character[59][enc] == 62 );
|
||||
CPPUNIT_ASSERT ( finalcut::fc::character[60][enc] == 60 );
|
||||
CPPUNIT_ASSERT ( finalcut::fc::character[105][enc] == 42 );
|
||||
|
||||
term_detection->detect();
|
||||
|
||||
|
|
|
@ -145,10 +145,10 @@ class FSystemTest : public finalcut::FSystem
|
|||
0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d,
|
||||
0x0e, 0x0f, 0x0c, 0x00, 0x0f, 0x08, 0x00
|
||||
};
|
||||
uChar ac_index = 0;
|
||||
bool palette_addr_source_field = true;
|
||||
uChar port_3cc = 0x67; // Miscellaneous output
|
||||
uChar port_3da = 0; // Input status 1
|
||||
uChar ac_index{0};
|
||||
bool palette_addr_source_field{true};
|
||||
uChar port_3cc{0x67}; // Miscellaneous output
|
||||
uChar port_3da{0}; // Input status 1
|
||||
static uChar vga8x16[];
|
||||
static struct unipair unicode_cp437_pairs[];
|
||||
};
|
||||
|
@ -965,12 +965,12 @@ FSystemTest::rgb FSystemTest::defaultColor[16]
|
|||
|
||||
// static class attributes
|
||||
//----------------------------------------------------------------------
|
||||
FSystemTest::shiftstate FSystemTest::shift_state;
|
||||
struct console_font_op FSystemTest::terminal_font;
|
||||
unimapdesc FSystemTest::terminal_unicode_map;
|
||||
struct fb_var_screeninfo FSystemTest::fb_terminal_info;
|
||||
struct fb_fix_screeninfo FSystemTest::fb_terminal_fix_info;
|
||||
bool FSystemTest::vga_port_access = false;
|
||||
FSystemTest::shiftstate FSystemTest::shift_state{};
|
||||
struct console_font_op FSystemTest::terminal_font{};
|
||||
unimapdesc FSystemTest::terminal_unicode_map{};
|
||||
struct fb_var_screeninfo FSystemTest::fb_terminal_info{};
|
||||
struct fb_fix_screeninfo FSystemTest::fb_terminal_fix_info{};
|
||||
bool FSystemTest::vga_port_access{false};
|
||||
|
||||
|
||||
// constructors and destructor
|
||||
|
@ -1062,10 +1062,10 @@ int FSystemTest::isTTY (int fd)
|
|||
//----------------------------------------------------------------------
|
||||
int FSystemTest::ioctl (int fd, uLong request, ...)
|
||||
{
|
||||
va_list args;
|
||||
void* argp;
|
||||
std::string req_string;
|
||||
int ret_val = -1;
|
||||
va_list args{};
|
||||
void* argp{};
|
||||
std::string req_string{};
|
||||
int ret_val{-1};
|
||||
|
||||
va_start (args, request);
|
||||
argp = va_arg (args, void*);
|
||||
|
@ -1290,7 +1290,7 @@ int FSystemTest::ioctl (int fd, uLong request, ...)
|
|||
//----------------------------------------------------------------------
|
||||
int FSystemTest::open (const char* pathname, int flags, ...)
|
||||
{
|
||||
va_list args;
|
||||
va_list args{};
|
||||
va_start (args, flags);
|
||||
mode_t mode = static_cast<mode_t>(va_arg (args, int));
|
||||
va_end (args);
|
||||
|
@ -1518,13 +1518,11 @@ void FTermLinuxTest::classNameTest()
|
|||
//----------------------------------------------------------------------
|
||||
void FTermLinuxTest::linuxConsoleTest()
|
||||
{
|
||||
finalcut::FTermData* data;
|
||||
finalcut::FSystem* fsys;
|
||||
fsys = new test::FSystemTest();
|
||||
finalcut::FSystem* fsys = new test::FSystemTest();
|
||||
finalcut::FTerm::setFSystem(fsys);
|
||||
finalcut::FTermDetection* term_detection;
|
||||
finalcut::FTermDetection* term_detection{};
|
||||
std::cout << "\n";
|
||||
data = finalcut::FTerm::getFTermData();
|
||||
finalcut::FTermData* data = finalcut::FTerm::getFTermData();
|
||||
|
||||
auto& encoding_list = data->getEncodingList();
|
||||
encoding_list["UTF-8"] = finalcut::fc::UTF8;
|
||||
|
@ -1642,13 +1640,11 @@ void FTermLinuxTest::linuxConsoleTest()
|
|||
//----------------------------------------------------------------------
|
||||
void FTermLinuxTest::linuxCursorStyleTest()
|
||||
{
|
||||
finalcut::FTermData* data;
|
||||
finalcut::FSystem* fsys;
|
||||
fsys = new test::FSystemTest();
|
||||
finalcut::FSystem* fsys = new test::FSystemTest();
|
||||
finalcut::FTerm::setFSystem(fsys);
|
||||
finalcut::FTermDetection* term_detection;
|
||||
finalcut::FTermDetection* term_detection{};
|
||||
std::cout << "\n";
|
||||
data = finalcut::FTerm::getFTermData();
|
||||
finalcut::FTermData* data = finalcut::FTerm::getFTermData();
|
||||
|
||||
auto& encoding_list = data->getEncodingList();
|
||||
encoding_list["UTF-8"] = finalcut::fc::UTF8;
|
||||
|
@ -1833,13 +1829,11 @@ void FTermLinuxTest::linuxCursorStyleTest()
|
|||
//----------------------------------------------------------------------
|
||||
void FTermLinuxTest::linuxColorPaletteTest()
|
||||
{
|
||||
finalcut::FTermData* data;
|
||||
finalcut::FSystem* fsys;
|
||||
fsys = new test::FSystemTest();
|
||||
finalcut::FSystem* fsys = new test::FSystemTest();
|
||||
finalcut::FTerm::setFSystem(fsys);
|
||||
finalcut::FTermDetection* term_detection;
|
||||
finalcut::FTermDetection* term_detection{};
|
||||
std::cout << "\n";
|
||||
data = finalcut::FTerm::getFTermData();
|
||||
finalcut::FTermData* data = finalcut::FTerm::getFTermData();
|
||||
|
||||
auto& encoding_list = data->getEncodingList();
|
||||
encoding_list["UTF-8"] = finalcut::fc::UTF8;
|
||||
|
@ -2111,13 +2105,11 @@ void FTermLinuxTest::linuxColorPaletteTest()
|
|||
//----------------------------------------------------------------------
|
||||
void FTermLinuxTest::linuxFontTest()
|
||||
{
|
||||
finalcut::FTermData* data;
|
||||
finalcut::FSystem* fsys;
|
||||
fsys = new test::FSystemTest();
|
||||
finalcut::FSystem* fsys = new test::FSystemTest();
|
||||
finalcut::FTerm::setFSystem(fsys);
|
||||
finalcut::FTermDetection* term_detection;
|
||||
finalcut::FTermDetection* term_detection{};
|
||||
std::cout << "\n";
|
||||
data = finalcut::FTerm::getFTermData();
|
||||
finalcut::FTermData* data = finalcut::FTerm::getFTermData();
|
||||
|
||||
auto& encoding_list = data->getEncodingList();
|
||||
encoding_list["UTF-8"] = finalcut::fc::UTF8;
|
||||
|
@ -2256,11 +2248,10 @@ void FTermLinuxTest::linuxFontTest()
|
|||
//----------------------------------------------------------------------
|
||||
void FTermLinuxTest::modifierKeyTest()
|
||||
{
|
||||
FKey keycode;
|
||||
FKey mod_keycode;
|
||||
FKey keycode{};
|
||||
FKey mod_keycode{};
|
||||
const finalcut::FTermLinux linux{};
|
||||
finalcut::FSystem* fsys;
|
||||
fsys = new test::FSystemTest();
|
||||
finalcut::FSystem* fsys(new test::FSystemTest());
|
||||
test::FSystemTest* fsystest = static_cast<test::FSystemTest*>(fsys);
|
||||
test::FSystemTest::shiftstate& mod_key = fsystest->getShiftState();
|
||||
|
||||
|
|
|
@ -88,8 +88,8 @@ class FSystemTest : public finalcut::FSystem
|
|||
wskbd_bell_data& getBell();
|
||||
|
||||
private:
|
||||
kbd_t kbdencoding = 512;
|
||||
wskbd_bell_data system_bell;
|
||||
kbd_t kbdencoding{512};
|
||||
wskbd_bell_data system_bell{};
|
||||
};
|
||||
|
||||
|
||||
|
@ -132,10 +132,10 @@ int FSystemTest::isTTY (int fd)
|
|||
//----------------------------------------------------------------------
|
||||
int FSystemTest::ioctl (int fd, uLong request, ...)
|
||||
{
|
||||
va_list args;
|
||||
void* argp;
|
||||
std::string req_string;
|
||||
int ret_val = -1;
|
||||
va_list args{};
|
||||
void* argp{};
|
||||
std::string req_string{};
|
||||
int ret_val{-1};
|
||||
|
||||
va_start (args, request);
|
||||
argp = va_arg (args, void*);
|
||||
|
@ -218,7 +218,7 @@ int FSystemTest::ioctl (int fd, uLong request, ...)
|
|||
//----------------------------------------------------------------------
|
||||
int FSystemTest::open (const char* pathname, int flags, ...)
|
||||
{
|
||||
va_list args;
|
||||
va_list args{};
|
||||
va_start (args, flags);
|
||||
mode_t mode = static_cast<mode_t>(va_arg (args, int));
|
||||
va_end (args);
|
||||
|
@ -345,13 +345,11 @@ void ftermopenbsdTest::classNameTest()
|
|||
//----------------------------------------------------------------------
|
||||
void ftermopenbsdTest::netbsdConsoleTest()
|
||||
{
|
||||
finalcut::FTermData* data;
|
||||
finalcut::FSystem* fsys;
|
||||
fsys = new test::FSystemTest();
|
||||
finalcut::FSystem* fsys = new test::FSystemTest();
|
||||
finalcut::FTerm::setFSystem(fsys);
|
||||
finalcut::FTermDetection* term_detection;
|
||||
finalcut::FTermDetection* term_detection{};
|
||||
std::cout << "\n";
|
||||
data = finalcut::FTerm::getFTermData();
|
||||
finalcut::FTermData* data = finalcut::FTerm::getFTermData();
|
||||
|
||||
auto& encoding_list = data->getEncodingList();
|
||||
encoding_list["UTF-8"] = finalcut::fc::UTF8;
|
||||
|
@ -452,13 +450,11 @@ void ftermopenbsdTest::netbsdConsoleTest()
|
|||
//----------------------------------------------------------------------
|
||||
void ftermopenbsdTest::openbsdConsoleTest()
|
||||
{
|
||||
finalcut::FTermData* data;
|
||||
finalcut::FSystem* fsys;
|
||||
fsys = new test::FSystemTest();
|
||||
finalcut::FSystem* fsys = new test::FSystemTest();
|
||||
finalcut::FTerm::setFSystem(fsys);
|
||||
finalcut::FTermDetection* term_detection;
|
||||
finalcut::FTermDetection* term_detection{};
|
||||
std::cout << "\n";
|
||||
data = finalcut::FTerm::getFTermData();
|
||||
finalcut::FTermData* data = finalcut::FTerm::getFTermData();
|
||||
|
||||
auto& encoding_list = data->getEncodingList();
|
||||
encoding_list["UTF-8"] = finalcut::fc::UTF8;
|
||||
|
|
Loading…
Reference in New Issue