Refactoring of some methods in FVTerm and FDialog

This commit is contained in:
Markus Gans 2019-01-24 00:23:00 +01:00
parent eeb32bd66e
commit c4df64c5bc
5 changed files with 158 additions and 180 deletions

View File

@ -1,3 +1,6 @@
2019-01-24 Markus Gans <guru.mail@muenster.de>
* Refactoring of some methods in FVTerm and FDialog
2019-01-21 Markus Gans <guru.mail@muenster.de>
* More accurate interfaces through the strict use of FPoint()
and FSize()

View File

@ -2,6 +2,21 @@
First steps with the Final Cut widget toolkit
=============================================
Table of Contents
-----------------
<!-- TOC -->
- [How to use the library](#how-to-use-the-library)
- [Memory Management](#memory-management)
- [Event Processing](#event-processing)
- [Event handler reimplementation](#event-handler-reimplementation)
- [Signals and Callbacks](#signals-and-callbacks)
- [Default signals](#the-final-cut-widgets-emit-the-following-default-signals)
- [Callback function](#example-of-a-callback-function)
- [Callback method](#example-of-a-callback-function)
- [Custom signals](#send-custom-signals)
<!-- /TOC -->
How to use the library
----------------------
@ -20,7 +35,9 @@ int main (int argc, char* argv[])
finalcut::FApplication app(argc, argv);
finalcut::FDialog dialog(&app);
dialog.setText ("A dialog");
dialog.setGeometry (25, 5, 30, 10);
const finalcut::FPoint position(25, 5);
const finalcut::FSize size(30, 10);
dialog.setGeometry (position, size);
app.setMainWidget(&dialog);
dialog.show();
return app.exec();
@ -69,7 +86,9 @@ dialog.setText ("A dialog");
The title bar of the dialog box gets the text "A dialog".
```cpp
dialog.setGeometry (25, 5, 30, 10);
finalcut::FPoint position(25, 5);
finalcut::FSize size(30, 10);
dialog.setGeometry (position, size);
```
The dialog window gets a width of 30 and a height of 10 characters.
The position of the window in the terminal is at x=25 and
@ -147,11 +166,11 @@ int main (int argc, char* argv[])
// The object dialog is managed by app
FDialog* dialog = new FDialog(&app);
dialog->setText ("Window Title");
dialog->setGeometry (25, 5, 40, 8);
dialog->setGeometry (FPoint(25, 5), FSize(40, 8));
// The object input is managed by dialog
FLineEdit* input = new FLineEdit("predefined text", dialog);
input->setGeometry(8, 2, 29, 1);
input->setGeometry(FPoint(8, 2), FSize(29, 1));
input->setLabelText (L"&Input");
// The object label is managed by dialog
@ -159,7 +178,7 @@ int main (int argc, char* argv[])
"adipiscing elit, sed do eiusmod tempor "
"incididunt ut labore et dolore magna aliqua."
, dialog );
label->setGeometry (2, 4, 36, 1);
label->setGeometry (FPoint(2, 4), FSize(36, 1));
app.setMainWidget(dialog);
dialog->show();
return app.exec();
@ -260,10 +279,10 @@ class dialogWidget : public FDialog
: FDialog(parent)
{
setText ("Dialog");
setGeometry (25, 5, 23, 4);
label.setGeometry (1, 1, 10, 1);
setGeometry (FPoint(25, 5), FSize(23, 4));
label.setGeometry (FPoint(1, 1), FSize(10, 1));
label.setAlignment (fc::alignRight);
value.setGeometry (11, 1, 10, 1);
value.setGeometry (FPoint(11, 1), FSize(10, 1));
id = addTimer(100);
}
@ -300,7 +319,7 @@ int main (int argc, char* argv[])
After entering the source code in *timer.cpp* you can compile
the above program with gcc:
```cpp
g++ -O2 -std=c++11 -lfinal timer.cpp -o timer
g++ -O2 -lfinal -std=c++11 timer.cpp -o timer
```
@ -396,6 +415,9 @@ use `delCallbacks()` to remove all existing callbacks from an object.
<dt>FToggleButton</dt>
<dd>"clicked"<br />"toggled"</dd>
<dt>FWidget</dt>
<dd>"destroy"</dd>
</dl>
&nbsp;
@ -423,14 +445,14 @@ int main (int argc, char* argv[])
FApplication app(argc, argv);
FDialog dialog(&app);
dialog.setText ("A dialog with callback function");
dialog.setGeometry (25, 5, 45, 9);
dialog.setGeometry (FRect(25, 5, 45, 9));
FLabel label (&dialog);
label = "The button has never been pressed before";
label.setGeometry (2, 2, 41, 1);
label.setGeometry (FPoint(2, 2), FSize(41, 1));
FButton button (&dialog);
// Character follows '&' will be used as the accelerator key
button = "&Click me";
button.setGeometry (15, 5, 14, 1);
button.setGeometry (FPoint(15, 5), FSize(14, 1));
// Connect the button signal "clicked" with the callback function
button.addCallback
@ -472,8 +494,8 @@ class dialogWidget : public FDialog
: FDialog(parent)
{
setText ("Callback method");
setGeometry (25, 5, 25, 7);
button.setGeometry (7, 3, 10, 1);
setGeometry (FPoint(25, 5), FSize(25, 7));
button.setGeometry (FPoint(7, 3), FSize(10, 1));
// Connect the button signal "clicked" with the callback method
button.addCallback
@ -504,7 +526,7 @@ int main (int argc, char* argv[])
After entering the source code in *callback-method.cpp* you can compile
the above program with gcc:
```cpp
g++ -O2 -std=c++11 -lfinal callback-method.cpp -o callback-method
g++ -O2 -lfinal -std=c++11 callback-method.cpp -o callback-method
```
&nbsp;
@ -527,13 +549,14 @@ class dialogWidget : public FDialog
explicit dialogWidget (FWidget* parent = nullptr)
: FDialog(parent)
{
setGeometry (25, 5, 22, 7);
setGeometry (FPoint(25, 5), FSize(22, 7));
setText ("Emit signal");
label.setGeometry (8, 1, 5, 1);
FSize size(5, 1);
label.setGeometry (FPoint(8, 1), size);
label.setAlignment (fc::alignRight);
label.setForegroundColor (fc::Black);
plus.setGeometry (3, 3, 5, 1);
minus.setGeometry (13, 3, 5, 1);
plus.setGeometry (FPoint(3, 3), size);
minus.setGeometry (FPoint(13, 3), size);
plus.setNoUnderline();
minus.setNoUnderline();
@ -641,6 +664,6 @@ int main (int argc, char* argv[])
After entering the source code in *emit-signal.cpp* you can compile
the above program with gcc:
```cpp
g++ -O2 -std=c++11 -lfinal emit-signal.cpp -o emit-signal
g++ -O2 -lfinal -std=c++11 emit-signal.cpp -o emit-signal
```
The FINAL CUT widgets emit the following default signals:

View File

@ -163,44 +163,24 @@ int FDialog::exec()
//----------------------------------------------------------------------
void FDialog::setPos (const FPoint& pos, bool)
{
int rsw, bsh, width, height;
int x = pos.getX();
int y = pos.getY();
FRect old_geometry;
FRect old_geometry, restore;
setPos_error = false;
if ( getX() == x && getY() == y )
{
setPos_error = true;
return;
}
width = int(getWidth());
height = int(getHeight());
// Avoid to move widget completely outside the terminal
if ( x + width <= 1
|| x > int(getMaxWidth())
|| y < 1
|| y > int(getMaxHeight()) )
// or moving a zoomed dialog or a motionless dialog
if ( isOutsideTerminal(pos) || isZoomed() || getPos() == pos )
{
setPos_error = true;
return;
}
if ( isZoomed() )
{
setPos_error = true;
return;
}
int dx = getX() - x
, dy = getY() - y
, old_x = getTermX()
, old_y = getTermY();
int dx = getX() - pos.getX();
int dy = getY() - pos.getY();
int old_x = getTermX();
int old_y = getTermY();
const auto& shadow = getShadow();
rsw = int(shadow.getWidth()); // right shadow width;
bsh = int(shadow.getHeight()); // bottom shadow height
std::size_t width = getWidth() + shadow.getWidth(); // width + right shadow
std::size_t height = getHeight() + shadow.getHeight(); // height + bottom shadow
old_geometry = getTermGeometryWithShadow();
// move to the new position
@ -217,28 +197,34 @@ void FDialog::setPos (const FPoint& pos, bool)
// dy = 0 : move horizontal
// dy < 0 : move down
std::size_t d_width = std::size_t(std::abs(dx));
std::size_t d_height = std::size_t(std::abs(dy));
if ( dx > 0 )
{
if ( dy > 0 )
restoreVTerm (FRect ( old_x + width + rsw - dx, old_y
, std::size_t(dx), std::size_t(height + bsh - dy) ));
restore.setRect ( old_x + int(width) - dx, old_y
, d_width, height - d_height );
else
restoreVTerm (FRect ( old_x + width + rsw - dx, old_y + std::abs(dy)
, std::size_t(dx), std::size_t(height + bsh - std::abs(dy)) ));
restore.setRect ( old_x + int(width) - dx, old_y - dy
, d_width, height - d_height );
}
else
{
if ( dy > 0 )
restoreVTerm (FRect(old_x, old_y, std::size_t(std::abs(dx)), std::size_t(height + bsh - dy)));
restore.setRect (old_x, old_y, d_width, height - d_height);
else
restoreVTerm (FRect ( old_x, old_y + std::abs(dy)
, std::size_t(std::abs(dx)), std::size_t(height + bsh - std::abs(dy)) ));
restore.setRect (old_x, old_y - dy, d_width, height - d_height);
}
restoreVTerm (restore);
if ( dy > 0 )
restoreVTerm (FRect(old_x, old_y + height + bsh - dy, std::size_t(width + rsw), std::size_t(dy)));
restore.setRect ( old_x, old_y + int(height) - dy, width, d_height);
else
restoreVTerm (FRect(old_x, old_y, std::size_t(width + rsw), std::size_t(std::abs(dy))));
restore.setRect ( old_x, old_y, width, d_height);
restoreVTerm (restore);
}
else
{
@ -290,33 +276,22 @@ void FDialog::setSize (const FSize& size, bool adjust)
{
setSize_error = false;
if ( getSize() == size )
if ( getSize() == size || isZoomed() )
{
setSize_error = true;
return;
}
if ( isZoomed() )
{
setSize_error = true;
return;
}
int x = getTermX()
, y = getTermY()
, old_width = int(getWidth())
, old_height = int(getHeight())
, dw = old_width - int(size.getWidth())
, dh = old_height - int(size.getHeight());
int x = getTermX();
int y = getTermY();
int dw = int(getWidth()) - int(size.getWidth());
int dh = int(getHeight()) - int(size.getHeight());
const auto& shadow = getShadow();
int rsw = int(shadow.getWidth()); // right shadow width;
int bsh = int(shadow.getHeight()); // bottom shadow height
FWindow::setSize (size, adjust);
// get adjust width and height
std::size_t w = getWidth();
std::size_t h = getHeight();
std::size_t w = getWidth() + shadow.getWidth();
std::size_t h = getHeight()+ shadow.getHeight();
// dw > 0 : scale down width
// dw = 0 : scale only height
@ -325,39 +300,23 @@ void FDialog::setSize (const FSize& size, bool adjust)
// dh = 0 : scale only width
// dh < 0 : scale up height
std::size_t d_width = std::size_t(dw);
std::size_t d_height = std::size_t(dh);
// restoring the non-covered terminal areas
if ( dw > 0 )
restoreVTerm (FRect(x + int(w) + rsw, y, std::size_t(dw), h + std::size_t(bsh + dh))); // restore right
restoreVTerm (FRect(x + int(w), y, d_width, h + d_height)); // restore right
if ( dh > 0 )
restoreVTerm (FRect(x, y + int(h) + bsh, w + std::size_t(rsw + dw), std::size_t(dh))); // restore bottom
restoreVTerm (FRect(x, y + int(h), w + d_width, d_height)); // restore bottom
redraw();
// handle overlaid windows
if ( window_list && ! window_list->empty() )
{
bool overlaid = false;
for (auto&& win : *window_list)
{
if ( overlaid )
putArea (win->getTermPos(), win->getVWin());
if ( vwin == win->getVWin() )
overlaid = true;
}
}
restoreOverlaidWindows();
// set the cursor to the focus widget
auto focus = FWidget::getFocusWidget();
if ( focus
&& focus->isShown()
&& focus->hasVisibleCursor() )
{
FPoint cursor_pos = focus->getCursorPos();
focus->setCursorPos(cursor_pos);
}
setCursorToFocusWidget();
}
//----------------------------------------------------------------------
@ -1486,6 +1445,18 @@ inline void FDialog::lowerActivateDialog()
updateTerminal();
}
//----------------------------------------------------------------------
bool FDialog::isOutsideTerminal (const FPoint& pos)
{
if ( pos.getX() + int(getWidth()) <= 1
|| pos.getX() > int(getMaxWidth())
|| pos.getY() < 1
|| pos.getY() > int(getMaxHeight()) )
return true;
return false;
}
//----------------------------------------------------------------------
bool FDialog::isLowerRightResizeCorner (const mouseStates& ms)
{

View File

@ -854,10 +854,10 @@ FVTerm::covered_state FVTerm::isCovered ( const FPoint& pos
if ( found && geometry.contains(pos) )
{
int line_len = win->width + win->right_shadow;
int width = win->width + win->right_shadow;
int x = pos.getX();
int y = pos.getY();
auto tmp = &win->text[(y - win_y) * line_len + (x - win_x)];
auto tmp = &win->text[(y - win_y) * width + (x - win_x)];
if ( tmp->attr.bit.trans_shadow )
{
@ -885,15 +885,13 @@ void FVTerm::updateOverlappedColor ( term_area* area
{
// Add the overlapping color to this character
int& aw = area->width;
int& rsh = area->right_shadow;
int x = area_pos.getX();
int y = area_pos.getY();
int tx = terminal_pos.getX();
int ty = terminal_pos.getY();
int line_len = aw + rsh;
int width = area->width + area->right_shadow;
// Area character
auto ac = &area->text[y * line_len + x];
auto ac = &area->text[y * width + x];
// Terminal character
auto tc = &vterm->text[ty * vterm->width + tx];
// New character
@ -941,15 +939,13 @@ void FVTerm::updateShadedCharacter ( term_area* area
{
// Get covered character + add the current color
int& aw = area->width;
int& rsh = area->right_shadow;
int x = area_pos.getX();
int y = area_pos.getY();
int tx = terminal_pos.getX();
int ty = terminal_pos.getY();
int line_len = aw + rsh;
int width = area->width + area->right_shadow;
// Area character
auto ac = &area->text[y * line_len + x];
auto ac = &area->text[y * width + x];
// Terminal character
auto tc = &vterm->text[ty * vterm->width + tx];
// Overlapped character
@ -978,15 +974,13 @@ void FVTerm::updateInheritBackground ( term_area* area
{
// Add the covered background to this character
int& aw = area->width;
int& rsh = area->right_shadow;
int x = area_pos.getX();
int y = area_pos.getY();
int tx = terminal_pos.getX();
int ty = terminal_pos.getY();
int line_len = aw + rsh;
int width = area->width + area->right_shadow;
// Area character
auto ac = &area->text[y * line_len + x];
auto ac = &area->text[y * width + x];
// Terminal character
auto tc = &vterm->text[ty * vterm->width + tx];
// New character
@ -1006,15 +1000,13 @@ void FVTerm::updateCharacter ( term_area* area
{
// Copy a area character to the virtual terminal
int& aw = area->width;
int& rsh = area->right_shadow;
int x = area_pos.getX();
int y = area_pos.getY();
int tx = terminal_pos.getX();
int ty = terminal_pos.getY();
int line_len = aw + rsh;
int width = area->width + area->right_shadow;
// Area character
auto ac = &area->text[y * line_len + x];
auto ac = &area->text[y * width + x];
// Terminal character
auto tc = &vterm->text[ty * vterm->width + tx];
std::memcpy (tc, ac, sizeof(*tc));
@ -1030,13 +1022,11 @@ bool FVTerm::updateVTermCharacter ( term_area* area
, const FPoint& area_pos
, const FPoint& terminal_pos )
{
int& aw = area->width;
int& rsh = area->right_shadow;
int x = area_pos.getX();
int y = area_pos.getY();
int line_len = aw + rsh;
int width = area->width + area->right_shadow;
// Area character
auto ac = &area->text[y * line_len + x];
auto ac = &area->text[y * width + x];
// Get covered state
auto is_covered = isCovered(terminal_pos, area);
@ -1154,14 +1144,12 @@ void FVTerm::updateVTerm (term_area* area)
if ( ! area || ! area->visible )
return;
int ax = area->offset_left
, ay = area->offset_top
, aw = area->width
, ah = area->height
, rsh = area->right_shadow
, bsh = area->bottom_shadow
, ol = 0 // Outside left
, y_end;
int ax = area->offset_left;
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;
// Call the processing handler methods
callPreprocessingHandler(area);
@ -1172,10 +1160,10 @@ void FVTerm::updateVTerm (term_area* area)
ax = 0;
}
if ( ah + bsh + ay > vterm->height )
if ( height + ay > vterm->height )
y_end = vterm->height - ay;
else
y_end = ah + bsh;
y_end = height;
for (int y = 0; y < y_end; y++) // Line loop
{
@ -1190,7 +1178,7 @@ void FVTerm::updateVTerm (term_area* area)
if ( ax == 0 )
line_xmin = ol;
if ( aw + rsh + ax - ol >= vterm->width )
if ( width + ax - ol >= vterm->width )
line_xmax = vterm->width + ol - ax - 1;
if ( ax + line_xmin >= vterm->width )
@ -1226,7 +1214,7 @@ void FVTerm::updateVTerm (term_area* area)
if ( _xmax > int(vterm->changes[ay + y].xmax) )
vterm->changes[ay + y].xmax = uInt(_xmax);
area->changes[y].xmin = uInt(aw + rsh);
area->changes[y].xmin = uInt(width);
area->changes[y].xmax = 0;
}
@ -1394,21 +1382,15 @@ void FVTerm::putArea (const FPoint& pos, term_area* area)
charData* tc; // terminal character
charData* ac; // area character
if ( ! area )
return;
if ( ! area->visible )
if ( ! area || ! area->visible )
return;
int ax = pos.getX() - 1;
int ay = pos.getY() - 1;
int aw = area->width;
int ah = area->height;
int rsh = area->right_shadow;
int bsh = area->bottom_shadow;
int width = area->width + area->right_shadow;
int height = area->height + area->bottom_shadow;
int ol = 0; // outside left
int y_end;
int length;
int y_end, length;
if ( ax < 0 )
{
@ -1416,27 +1398,25 @@ void FVTerm::putArea (const FPoint& pos, term_area* area)
ax = 0;
}
if ( ay + ah + bsh > vterm->height )
if ( ay + height > vterm->height )
y_end = vterm->height - ay;
else
y_end = ah + bsh;
y_end = height;
if ( aw + rsh - ol + ax > vterm->width )
if ( width - ol + ax > vterm->width )
length = vterm->width - ax;
else
length = aw + rsh - ol;
length = width - ol;
if ( length < 1 )
return;
for (int y = 0; y < y_end; y++) // line loop
{
int line_len = aw + rsh;
if ( area->changes[y].trans_count == 0 )
{
// Line has only covered characters
ac = &area->text[y * line_len + ol];
ac = &area->text[y * width + ol];
tc = &vterm->text[(ay + y) * vterm->width + ax];
putAreaLine (ac, tc, length);
}
@ -1447,7 +1427,7 @@ void FVTerm::putArea (const FPoint& pos, term_area* area)
{
int cx = ax + x;
int cy = ay + y;
ac = &area->text[y * line_len + ol + x];
ac = &area->text[y * width + ol + x];
tc = &vterm->text[cy * vterm->width + cx];
putAreaCharacter (FPoint(cx + 1, cy + 1), area->widget, ac, tc);
}

View File

@ -205,6 +205,7 @@ class FDialog : public FWindow
void moveSizeKey (FKeyEvent*);
void raiseActivateDialog();
void lowerActivateDialog();
bool isOutsideTerminal (const FPoint&);
bool isLowerRightResizeCorner (const mouseStates&);
void resizeMouseDown (const mouseStates&);
void resizeMouseUpMove (const mouseStates&, bool = false);