diff --git a/ChangeLog b/ChangeLog index 7045bf2c..d6061aef 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2019-01-30 Markus Gans + * Printing an FColorPair object can change the foreground and + background colors + 2019-01-27 Markus Gans * The print command can now have an FPoint object as a parameter to set the cursor position diff --git a/examples/calculator.cpp b/examples/calculator.cpp index 9bbc4ac9..442b9d3b 100644 --- a/examples/calculator.cpp +++ b/examples/calculator.cpp @@ -32,6 +32,7 @@ using finalcut::FPoint; using finalcut::FSize; +using finalcut::FColorPair; constexpr lDouble PI = 3.141592653589793238L; @@ -333,13 +334,12 @@ void Calc::drawDispay() if ( error ) display = " Error "; - setColor(finalcut::fc::Black, finalcut::fc::LightGray); - if ( isMonochron() ) setReverse(false); - print() << FPoint(3, 3) << display << ' '; - setColor(wc.dialog_fg, wc.dialog_bg); + print() << FColorPair(finalcut::fc::Black, finalcut::fc::LightGray) + << FPoint(3, 3) << display << ' ' + << FColorPair(wc.dialog_fg, wc.dialog_bg); if ( isMonochron() ) setReverse(true); diff --git a/examples/mouse.cpp b/examples/mouse.cpp index cf47ab6f..2d4731ae 100644 --- a/examples/mouse.cpp +++ b/examples/mouse.cpp @@ -24,6 +24,7 @@ using finalcut::FPoint; using finalcut::FSize; +using finalcut::FColorPair; //---------------------------------------------------------------------- @@ -142,9 +143,7 @@ void ColorChooser::draw() if ( c == bg_color ) { - print (' '); - print (finalcut::fc::Times); - print (' '); + print() << ' ' << finalcut::fc::Times << ' '; } else print (" "); @@ -244,8 +243,8 @@ void Brushes::draw() int pos; setColor(); finalcut::FWidget::drawBorder (1, 2, 8, 4); - setColor (fg_color, bg_color); - print() << FPoint(2, 3) << " " + print() << FPoint(2, 3) + << FColorPair(fg_color, bg_color) << " " << finalcut::FString(3, finalcut::fc::MediumShade); if ( brush == L' ' ) diff --git a/examples/term-attributes.cpp b/examples/term-attributes.cpp index 31dd2118..d134e96c 100644 --- a/examples/term-attributes.cpp +++ b/examples/term-attributes.cpp @@ -25,6 +25,7 @@ using finalcut::FPoint; using finalcut::FSize; +using finalcut::FColorPair; //---------------------------------------------------------------------- @@ -260,8 +261,7 @@ void AttribDemo::printColorLine() for (FColor color = 0; color < colors; color++) { - setColor (color, parent->bgcolor); - print (" # "); + print() << FColorPair(color, parent->bgcolor) << " # "; } } diff --git a/examples/timer.cpp b/examples/timer.cpp index afccfe94..dc06d182 100644 --- a/examples/timer.cpp +++ b/examples/timer.cpp @@ -75,8 +75,8 @@ void Timer::onTimer (finalcut::FTimerEvent* ev) if ( getPrintPos().getY() == int(getDesktopHeight()) ) is_last_line = true; - setColor (FColor(1 + timer_id), finalcut::fc::Default); - print() << "Timer event, id " << timer_id << '\n'; + print() << finalcut::FColorPair (FColor(1 + timer_id)) + << "Timer event, id " << timer_id << '\n'; if ( is_last_line ) scrollAreaForward (vdesktop); diff --git a/src/Makefile.am b/src/Makefile.am index 83b87c9e..76985c73 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -73,6 +73,7 @@ finalcutinclude_HEADERS = \ include/final/fbuttongroup.h \ include/final/fcharmap.h \ include/final/fcheckbox.h \ + include/final/fcolorpair.h \ include/final/fconfig.h \ include/final/fswitch.h \ include/final/fdialog.h \ diff --git a/src/Makefile.clang b/src/Makefile.clang index a0952cdc..396fbffc 100644 --- a/src/Makefile.clang +++ b/src/Makefile.clang @@ -12,6 +12,7 @@ INCLUDE_HEADERS = \ fapplication.h \ fbuttongroup.h \ fbutton.h \ + fcolorpair.h \ ftogglebutton.h \ fcheckbox.h \ fswitch.h \ diff --git a/src/Makefile.gcc b/src/Makefile.gcc index 41328af7..6656d79b 100644 --- a/src/Makefile.gcc +++ b/src/Makefile.gcc @@ -12,6 +12,7 @@ INCLUDE_HEADERS = \ fapplication.h \ fbuttongroup.h \ fbutton.h \ + fcolorpair.h \ ftogglebutton.h \ fcheckbox.h \ fswitch.h \ diff --git a/src/fbutton.cpp b/src/fbutton.cpp index e7f7a678..18aba978 100644 --- a/src/fbutton.cpp +++ b/src/fbutton.cpp @@ -582,8 +582,8 @@ inline void FButton::drawTopBottomBackground() inline void FButton::drawButtonTextLine (wchar_t button_text[]) { std::size_t pos; - print() << FPoint(2 + int(indent), 1 + int(vcenter_offset)); - setColor (button_fg, button_bg); + print() << FPoint(2 + int(indent), 1 + int(vcenter_offset)) + << FColorPair (button_fg, button_bg); if ( getWidth() < txtlength + 1 ) center_offset = 0; diff --git a/src/flabel.cpp b/src/flabel.cpp index 0bcd6674..c9b5221c 100644 --- a/src/flabel.cpp +++ b/src/flabel.cpp @@ -583,8 +583,7 @@ void FLabel::printLine ( wchar_t line[] if ( length > width ) { // Print ellipsis - setColor (ellipsis_color, getBackgroundColor()); - print (".."); + print() << FColorPair(ellipsis_color, getBackgroundColor()) << ".."; setColor(); } else if ( align_offset + to_char < width ) diff --git a/src/flistbox.cpp b/src/flistbox.cpp index 9f240709..2ce836d3 100644 --- a/src/flistbox.cpp +++ b/src/flistbox.cpp @@ -865,9 +865,8 @@ void FListBox::drawHeadline() else { // Print ellipsis - print (text.left(uInt(getClientWidth() - 2))); - setColor (wc.label_ellipsis_fg, wc.label_bg); - print(".."); + print() << text.left(uInt(getClientWidth() - 2)) + << FColorPair (wc.label_ellipsis_fg, wc.label_bg) << ".."; } } diff --git a/src/flistview.cpp b/src/flistview.cpp index a360d556..149a05c9 100644 --- a/src/flistview.cpp +++ b/src/flistview.cpp @@ -1849,10 +1849,10 @@ void FListView::drawColumnEllipsis ( const headerItems::const_iterator& iter static constexpr int ellipsis_length = 2; int width = iter->width; - headerline << ' '; - headerline << text.left(uInt(width - ellipsis_length)); - setColor (wc.label_ellipsis_fg, wc.label_bg); - headerline << ".."; + headerline << ' ' + << text.left(uInt(width - ellipsis_length)) + << FColorPair (wc.label_ellipsis_fg, wc.label_bg) + << ".."; if ( iter == header.end() - 1 ) // Last element headerline << ' '; diff --git a/src/fmenu.cpp b/src/fmenu.cpp index dcf97f08..a95ed734 100644 --- a/src/fmenu.cpp +++ b/src/fmenu.cpp @@ -1251,8 +1251,8 @@ void FMenu::drawItems() //---------------------------------------------------------------------- inline void FMenu::drawSeparator (int y) { - print() << FPoint(1, 2 + y); - setColor (wc.menu_active_fg, wc.menu_active_bg); + print() << FPoint(1, 2 + y) + << FColorPair(wc.menu_active_fg, wc.menu_active_bg); if ( isMonochron() ) setReverse(true); diff --git a/src/fprogressbar.cpp b/src/fprogressbar.cpp index 00b61ac1..819557d8 100644 --- a/src/fprogressbar.cpp +++ b/src/fprogressbar.cpp @@ -161,8 +161,8 @@ void FProgressbar::drawProgressLabel() void FProgressbar::drawProgressBar() { std::size_t len = 0; - print() << FPoint(1, 1); - setColor (wc.progressbar_bg, wc.progressbar_fg); + print() << FPoint(1, 1) + << FColorPair(wc.progressbar_bg, wc.progressbar_fg); if ( percentage > 0 && percentage <= 100 ) len = drawProgressIndicator(); @@ -206,8 +206,8 @@ std::size_t FProgressbar::drawProgressIndicator() } else { - setColor (wc.progressbar_fg, wc.progressbar_bg); - print (fc::LeftHalfBlock); // ▌ + print() << FColorPair(wc.progressbar_fg, wc.progressbar_bg) + << fc::LeftHalfBlock; // ▌ } len++; diff --git a/src/fswitch.cpp b/src/fswitch.cpp index 7d7658a9..bb156d33 100644 --- a/src/fswitch.cpp +++ b/src/fswitch.cpp @@ -175,8 +175,8 @@ void FSwitch::drawChecked() if ( isMonochron() || getMaxColor() < 16 ) setBold(false); - setColor (wc.button_inactive_fg, wc.button_inactive_bg); - print (off); + print() << FColorPair(wc.button_inactive_fg, wc.button_inactive_bg) + << off; if ( isMonochron() ) setReverse(false); diff --git a/src/ftermbuffer.cpp b/src/ftermbuffer.cpp index b68e9552..eed29505 100644 --- a/src/ftermbuffer.cpp +++ b/src/ftermbuffer.cpp @@ -3,7 +3,7 @@ * * * This file is part of the Final Cut widget toolkit * * * -* Copyright 2017-2018 Markus Gans * +* Copyright 2017-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 * @@ -81,7 +81,7 @@ int FTermBuffer::write (const FString& s) } //---------------------------------------------------------------------- -int FTermBuffer::write (int c) +int FTermBuffer::write (wchar_t c) { charData nc; // next character nc = FVTerm::getAttribute(); @@ -93,6 +93,15 @@ int FTermBuffer::write (int c) return 1; } +//---------------------------------------------------------------------- +void FTermBuffer::write (const FColorPair& pair) +{ + charData nc; // next character + nc = FVTerm::getAttribute(); + nc.fg_color = pair.fg_color; + nc.bg_color = pair.bg_color; +} + // FTermBuffer non-member operators //---------------------------------------------------------------------- diff --git a/src/fvterm.cpp b/src/fvterm.cpp index 3755b5de..a700ebd6 100644 --- a/src/fvterm.cpp +++ b/src/fvterm.cpp @@ -563,6 +563,12 @@ void FVTerm::print (const FPoint& p) setPrintCursor (p); } +//---------------------------------------------------------------------- +void FVTerm::print (const FColorPair& pair) +{ + setColor (pair.fg_color, pair.bg_color); +} + // protected methods of FVTerm //---------------------------------------------------------------------- diff --git a/src/fwidget.cpp b/src/fwidget.cpp index 696afeeb..b4c17efc 100644 --- a/src/fwidget.cpp +++ b/src/fwidget.cpp @@ -300,7 +300,7 @@ bool FWidget::setFocus (bool enable) } //---------------------------------------------------------------------- -void FWidget::setColor () +void FWidget::setColor() { // Changes colors to the widget default colors setColor (foreground_color, background_color); diff --git a/src/include/final/fcolorpair.h b/src/include/final/fcolorpair.h new file mode 100644 index 00000000..c109b9e1 --- /dev/null +++ b/src/include/final/fcolorpair.h @@ -0,0 +1,96 @@ +/*********************************************************************** +* fcolorpair.h - Foreground and background color of a character * +* * +* 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 * +* . * +***********************************************************************/ + +/* Standalone class + * ════════════════ + * + * ▕▔▔▔▔▔▔▔▔▔▔▔▔▏ + * ▕ FClassName ▏ + * ▕▁▁▁▁▁▁▁▁▁▁▁▁▏ + */ + +#ifndef FCOLORPAIR_H +#define FCOLORPAIR_H + +#if !defined (USE_FINAL_H) && !defined (COMPILE_FINAL_CUT) + #error "Only can be included directly." +#endif + +//#include ... + +namespace finalcut +{ + +//---------------------------------------------------------------------- +// class FColorPair +//---------------------------------------------------------------------- + +#pragma pack(push) +#pragma pack(1) + +class FColorPair +{ + public: + // Constructors + FColorPair (FColor fg = fc::Default, FColor bg = fc::Default) + : fg_color(fg) + , bg_color(bg) + { } + + // Copy constructor + FColorPair (const FColorPair& pair) + : fg_color(pair.fg_color) + , bg_color(pair.bg_color) + { } + + // Destructor + ~FColorPair() = default; + + // Assignment operator (=) + FColorPair& operator = (const FColorPair& pair) + { + fg_color = pair.fg_color; + bg_color = pair.bg_color; + return *this; + } + + // Accessor + const char* getClassName() const + { return "FColorPair"; } + + // Methods + void swap() + { + std::swap (fg_color, bg_color); + } + + // Data Members + FColor fg_color; // Foreground color + FColor bg_color; // Background color +}; +#pragma pack(pop) + +} // namespace finalcut + +#endif // FCOLORPAIR_H + + diff --git a/src/include/final/ftermbuffer.h b/src/include/final/ftermbuffer.h index 61a59c43..1db499bd 100644 --- a/src/include/final/ftermbuffer.h +++ b/src/include/final/ftermbuffer.h @@ -3,7 +3,7 @@ * * * This file is part of the Final Cut widget toolkit * * * -* Copyright 2017-2018 Markus Gans * +* Copyright 2017-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 * @@ -67,6 +67,8 @@ class FTermBuffer // Overloaded operators template FTermBuffer& operator << (const type&); + FTermBuffer& operator << (const FColorPair&); + // Non-member operators friend std::vector& operator << ( std::vector& , const FTermBuffer& ); @@ -82,7 +84,8 @@ class FTermBuffer void clear(); int writef (const FString, ...); int write (const FString&); - int write (int); + int write (wchar_t); + void write (const FColorPair&); FTermBuffer& write (); std::vector getBuffer(); @@ -104,6 +107,13 @@ inline FTermBuffer& FTermBuffer::operator << (const type& s) return *this; } +//---------------------------------------------------------------------- +inline FTermBuffer& FTermBuffer::operator << (const FColorPair& pair) +{ + write (pair); + return *this; +} + //---------------------------------------------------------------------- inline const char* FTermBuffer::getClassName() const { return "FTermBuffer"; } diff --git a/src/include/final/fvterm.h b/src/include/final/fvterm.h index 98261647..51547487 100644 --- a/src/include/final/fvterm.h +++ b/src/include/final/fvterm.h @@ -58,6 +58,7 @@ #include #include "final/fterm.h" +#include "final/fcolorpair.h" // Preprocessing handler macro @@ -133,6 +134,7 @@ class FVTerm FVTerm& operator << (const type&); FVTerm& operator << (const std::vector&); FVTerm& operator << (const FPoint&); + FVTerm& operator << (const FColorPair&); // Accessors virtual const char* getClassName() const; @@ -296,6 +298,7 @@ class FVTerm int print (charData&); int print (term_area*, charData&); virtual void print (const FPoint&); + virtual void print (const FColorPair&); virtual FVTerm& print(); static void beep(); static void redefineDefaultColors (bool); @@ -559,6 +562,13 @@ inline FVTerm& FVTerm::operator << (const FPoint& pos) return *this; } +//---------------------------------------------------------------------- +inline FVTerm& FVTerm::operator << (const FColorPair& pair) +{ + print (pair); + return *this; +} + //---------------------------------------------------------------------- inline const char* FVTerm::getClassName() const { return "FVTerm"; } diff --git a/test/Makefile.am b/test/Makefile.am index 10c868ec..1cedd8b6 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -15,6 +15,7 @@ noinst_PROGRAMS = \ ftermcapquirks_test \ foptimove_test \ foptiattr_test \ + fcolorpair_test \ fstring_test \ fsize_test \ fpoint_test \ @@ -28,6 +29,7 @@ ftermdetection_test_SOURCES = ftermdetection-test.cpp ftermcapquirks_test_SOURCES = ftermcapquirks-test.cpp foptimove_test_SOURCES = foptimove-test.cpp foptiattr_test_SOURCES = foptiattr-test.cpp +fcolorpair_test_SOURCES = fcolorpair-test.cpp fstring_test_SOURCES = fstring-test.cpp fsize_test_SOURCES = fsize-test.cpp fpoint_test_SOURCES = fpoint-test.cpp @@ -41,6 +43,7 @@ TESTS = fobject_test \ ftermcapquirks_test \ foptimove_test \ foptiattr_test \ + fcolorpair_test \ fstring_test \ fsize_test \ fpoint_test \ diff --git a/test/fcolorpair-test.cpp b/test/fcolorpair-test.cpp new file mode 100644 index 00000000..05f6b095 --- /dev/null +++ b/test/fcolorpair-test.cpp @@ -0,0 +1,148 @@ +/*********************************************************************** +* fcolorpair-test.cpp - FColorPair unit tests * +* * +* 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 * +* . * +***********************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include + +//---------------------------------------------------------------------- +// class FColorPairTest +//---------------------------------------------------------------------- + +#pragma pack(push) +#pragma pack(1) + +class FColorPairTest : public CPPUNIT_NS::TestFixture +{ + public: + FColorPairTest() + { } + + protected: + void classNameTest(); + void noArgumentTest(); + void copyConstructorTest(); + void assignmentTest(); + void swapTest(); + + private: + // Adds code needed to register the test suite + CPPUNIT_TEST_SUITE (FColorPairTest); + + // Add a methods to the test suite + CPPUNIT_TEST (classNameTest); + CPPUNIT_TEST (noArgumentTest); + CPPUNIT_TEST (copyConstructorTest); + CPPUNIT_TEST (assignmentTest); + CPPUNIT_TEST (swapTest); + + // End of test suite definition + CPPUNIT_TEST_SUITE_END(); +}; +#pragma pack(pop) + +//---------------------------------------------------------------------- +void FColorPairTest::classNameTest() +{ + const finalcut::FColorPair p; + const char* const classname = p.getClassName(); + CPPUNIT_ASSERT ( std::strcmp(classname, "FColorPair") == 0 ); +} + +//---------------------------------------------------------------------- +void FColorPairTest::noArgumentTest() +{ + const finalcut::FColorPair pair{}; + CPPUNIT_ASSERT ( pair.fg_color == finalcut::fc::Default ); + CPPUNIT_ASSERT ( pair.bg_color == finalcut::fc::Default ); +} + +//---------------------------------------------------------------------- +void FColorPairTest::copyConstructorTest() +{ + const finalcut::FColorPair p1a; + finalcut::FColorPair p1b (p1a); + CPPUNIT_ASSERT ( p1b.fg_color == finalcut::fc::Default ); + CPPUNIT_ASSERT ( p1b.bg_color == finalcut::fc::Default ); + + const finalcut::FColorPair p2a (finalcut::fc::Yellow ); + const finalcut::FColorPair p2b (p2a); + CPPUNIT_ASSERT ( p2b.fg_color == finalcut::fc::Yellow ); + CPPUNIT_ASSERT ( p2b.bg_color == finalcut::fc::Default ); + + const finalcut::FColorPair p3a (finalcut::fc::Red, finalcut::fc::Black); + const finalcut::FColorPair p3b (p3a); + CPPUNIT_ASSERT ( p3b.fg_color == finalcut::fc::Red ); + CPPUNIT_ASSERT ( p3b.bg_color == finalcut::fc::Black ); +} + +//---------------------------------------------------------------------- +void FColorPairTest::assignmentTest() +{ + const finalcut::FColorPair p1a; + const finalcut::FColorPair p1b = p1a; + CPPUNIT_ASSERT ( p1b.fg_color == finalcut::fc::Default ); + CPPUNIT_ASSERT ( p1b.bg_color == finalcut::fc::Default ); + + const finalcut::FColorPair p2a (finalcut::fc::Yellow ); + const finalcut::FColorPair p2b = p2a; + CPPUNIT_ASSERT ( p2b.fg_color == finalcut::fc::Yellow ); + CPPUNIT_ASSERT ( p2b.bg_color == finalcut::fc::Default ); + + const finalcut::FColorPair p3a (finalcut::fc::Red, finalcut::fc::Black); + const finalcut::FColorPair p3b = p3a; + CPPUNIT_ASSERT ( p3b.fg_color == finalcut::fc::Red ); + CPPUNIT_ASSERT ( p3b.bg_color == finalcut::fc::Black ); +} + +//---------------------------------------------------------------------- +void FColorPairTest::swapTest() +{ + finalcut::FColorPair p1; + p1.swap(); + CPPUNIT_ASSERT ( p1.fg_color == finalcut::fc::Default ); + CPPUNIT_ASSERT ( p1.bg_color == finalcut::fc::Default ); + + finalcut::FColorPair p2 (finalcut::fc::LightBlue ); + p2.swap(); + CPPUNIT_ASSERT ( p2.fg_color == finalcut::fc::Default ); + CPPUNIT_ASSERT ( p2.bg_color == finalcut::fc::LightBlue ); + + finalcut::FColorPair p3 (finalcut::fc::Cyan, finalcut::fc::White); + p3.swap(); + CPPUNIT_ASSERT ( p3.fg_color == finalcut::fc::White ); + CPPUNIT_ASSERT ( p3.bg_color == finalcut::fc::Cyan ); +} + +// Put the test suite in the registry +CPPUNIT_TEST_SUITE_REGISTRATION (FColorPairTest); + +// The general unit test main part +#include