diff --git a/ChangeLog b/ChangeLog index 52ca5c04..64226301 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2017-02-19 Markus Gans + * New FWidget methods setMinimumWidth(), setMinimumHeight(), + setMaximumWidth() and setMaximumHeight() + * FButtonGroup now inherits from FScrollView. This supports + many buttons to be displayed in a smaller frame. + 2017-02-18 Markus Gans * Allows a window to have more than one FScrollView widget diff --git a/src/fbuttongroup.cpp b/src/fbuttongroup.cpp index 99107ff4..bec95946 100644 --- a/src/fbuttongroup.cpp +++ b/src/fbuttongroup.cpp @@ -14,9 +14,8 @@ // constructor and destructor //---------------------------------------------------------------------- FButtonGroup::FButtonGroup(FWidget* parent) - : FWidget(parent) + : FScrollView(parent) , text() - , border(true) , buttonlist() { init(); @@ -24,9 +23,8 @@ FButtonGroup::FButtonGroup(FWidget* parent) //---------------------------------------------------------------------- FButtonGroup::FButtonGroup (const FString& txt, FWidget* parent) - : FWidget(parent) + : FScrollView(parent) , text(txt) - , border(true) , buttonlist() { init(); @@ -88,17 +86,6 @@ bool FButtonGroup::setEnable (bool on) return on; } -//---------------------------------------------------------------------- -bool FButtonGroup::setBorder(bool on) -{ - if ( on ) - border = true; - else - border = false; - - return on; -} - //---------------------------------------------------------------------- void FButtonGroup::setText (const FString& txt) { @@ -203,7 +190,7 @@ void FButtonGroup::hide() for (int y=0; y < getHeight(); y++) { - setPrintPos (1, 1+y); + FWidget::setPrintPos (1, 1+y); print (blank); } @@ -426,14 +413,13 @@ void FButtonGroup::draw() setReverse(true); setColor(); - - if ( border ) - drawBorder(); - - drawLabel(); + clearArea(); if ( isMonochron() ) setReverse(false); + + FScrollView::draw(); + drawLabel(); } //---------------------------------------------------------------------- @@ -459,6 +445,7 @@ void FButtonGroup::drawLabel() isActive = ((flags & fc::active) != 0); isNoUnderline = ((flags & fc::no_underline) != 0); + unsetViewportPrint(); // find hotkey position in string // + generate a new string without the '&'-sign @@ -476,10 +463,10 @@ void FButtonGroup::drawLabel() if ( hotkeypos != -1 ) length--; - if ( border ) - setPrintPos (2, 1); + if ( hasBorder() ) + FWidget::setPrintPos (2, 1); else - setPrintPos (0, 1); + FWidget::setPrintPos (0, 1); if ( isEnabled() ) setColor(wc.label_emphasis_fg, wc.label_bg); @@ -506,13 +493,14 @@ void FButtonGroup::drawLabel() print ( LabelText[z] ); } + setViewportPrint(); delete[] LabelText; } // private methods of FButtonGroup //---------------------------------------------------------------------- -bool FButtonGroup::isRadioButton(FToggleButton* button) const +bool FButtonGroup::isRadioButton (FToggleButton* button) const { if ( ! button ) return false; @@ -524,16 +512,12 @@ bool FButtonGroup::isRadioButton(FToggleButton* button) const //---------------------------------------------------------------------- void FButtonGroup::init() { - setTopPadding(1); - setLeftPadding(1); - setBottomPadding(1); - setRightPadding(1); - if ( isEnabled() ) flags |= fc::active; setForegroundColor (wc.label_fg); setBackgroundColor (wc.label_bg); + setMinimumSize (7, 4); buttonlist.clear(); // no buttons yet } diff --git a/src/fbuttongroup.h b/src/fbuttongroup.h index 61501cab..c4b5c698 100644 --- a/src/fbuttongroup.h +++ b/src/fbuttongroup.h @@ -28,7 +28,7 @@ #ifndef _FBUTTONGROUP_H #define _FBUTTONGROUP_H -#include "fwidget.h" +#include "fscrollview.h" // class forward declaration @@ -41,7 +41,7 @@ class FToggleButton; #pragma pack(push) #pragma pack(1) -class FButtonGroup : public FWidget +class FButtonGroup : public FScrollView { public: // Constructors @@ -62,9 +62,6 @@ class FButtonGroup : public FWidget bool setEnable(); bool unsetEnable(); bool setDisable(); - bool setBorder(bool); - bool setBorder(); - bool unsetBorder(); void setText (const FString&); // Inquiries @@ -103,7 +100,7 @@ class FButtonGroup : public FWidget FButtonGroup& operator = (const FButtonGroup&); // Inquiries - bool isRadioButton(FToggleButton*) const; + bool isRadioButton (FToggleButton*) const; // Methods void init(); @@ -111,7 +108,6 @@ class FButtonGroup : public FWidget // Data Members FString text; - bool border; FObjectList buttonlist; }; #pragma pack(pop) @@ -134,14 +130,6 @@ inline bool FButtonGroup::unsetEnable() inline bool FButtonGroup::setDisable() { return setEnable(false); } -//---------------------------------------------------------------------- -inline bool FButtonGroup::setBorder() -{ return setBorder(true); } - -//---------------------------------------------------------------------- -inline bool FButtonGroup::unsetBorder() -{ return setBorder(false); } - //---------------------------------------------------------------------- inline FString& FButtonGroup::getText() { return text; } diff --git a/src/fradiobutton.cpp b/src/fradiobutton.cpp index 1ec31e75..ba3aedc7 100644 --- a/src/fradiobutton.cpp +++ b/src/fradiobutton.cpp @@ -70,10 +70,12 @@ void FRadioButton::drawRadioButton() else { print ('('); + if ( isCygwinTerminal() ) print (0x04); else print (fc::Bullet); // Bullet ● + print (')'); } } diff --git a/src/fscrollbar.cpp b/src/fscrollbar.cpp index 72bac9e1..f369d61f 100644 --- a/src/fscrollbar.cpp +++ b/src/fscrollbar.cpp @@ -286,112 +286,112 @@ void FScrollbar::drawButtons() //---------------------------------------------------------------------- void FScrollbar::drawBar() { - if ( slider_pos != current_slider_pos ) + int z; + + if ( slider_pos == current_slider_pos || length < 3 ) + return; + + if ( bar_orientation == fc::vertical ) { - int z; + setColor (wc.scrollbar_fg, wc.scrollbar_bg); - if ( bar_orientation == fc::vertical ) + for (z=1; z <= slider_pos; z++) { - setColor (wc.scrollbar_fg, wc.scrollbar_bg); - - for (z=1; z <= slider_pos; z++) - { - setPrintPos (1, 1 + z); - - if ( isNewFont() ) - print (fc::NF_border_line_left); // ⎸ - - if ( isMonochron() || max_color < 16 ) - print (fc::MediumShade); // ▒ - else - print (' '); - } - - setColor (wc.scrollbar_bg, wc.scrollbar_fg); - - if ( isMonochron() ) - setReverse(false); - - for (z=1; z <= slider_length; z++) - { - setPrintPos (1, 1 + slider_pos + z); - - if ( isNewFont() ) - print (' '); - - print (' '); - } - - if ( isMonochron() ) - setReverse(true); - - setColor (wc.scrollbar_fg, wc.scrollbar_bg); - - for (z=slider_pos+slider_length+1; z <= bar_length; z++) - { - setPrintPos (1, 1 + z); - - if ( isNewFont() ) - print (fc::NF_border_line_left); // ⎸ - - if ( isMonochron() || max_color < 16 ) - print (fc::MediumShade); - else - print (' '); - } - } - else // horizontal - { - setColor (wc.scrollbar_fg, wc.scrollbar_bg); - z = 0; + setPrintPos (1, 1 + z); if ( isNewFont() ) - setPrintPos (3 + z, 1); + print (fc::NF_border_line_left); // ⎸ + + if ( isMonochron() || max_color < 16 ) + print (fc::MediumShade); // ▒ else - setPrintPos (2 + z, 1); - - for (; z < slider_pos; z++) - { - if ( isNewFont() ) - print (fc::NF_border_line_upper); // ¯ - else if ( isMonochron() || max_color < 16 ) - print (fc::MediumShade); // ▒ - else - print (' '); - } - - setColor (wc.scrollbar_bg, wc.scrollbar_fg); - - if ( isMonochron() ) - setReverse(false); - - z = 0; - - for (; z < slider_length; z++) print (' '); - - if ( isMonochron() ) - setReverse(true); - - setColor (wc.scrollbar_fg, wc.scrollbar_bg); - z = slider_pos + slider_length + 1; - - for (; z <= bar_length; z++) - { - if ( isNewFont() ) - print (fc::NF_border_line_upper); // ¯ - else if ( isMonochron() || max_color < 16 ) - print (fc::MediumShade); // ▒ - else - print (' '); - } } - current_slider_pos = slider_pos; + setColor (wc.scrollbar_bg, wc.scrollbar_fg); if ( isMonochron() ) setReverse(false); + + for (z=1; z <= slider_length; z++) + { + setPrintPos (1, 1 + slider_pos + z); + + if ( isNewFont() ) + print (' '); + + print (' '); + } + + if ( isMonochron() ) + setReverse(true); + + setColor (wc.scrollbar_fg, wc.scrollbar_bg); + + for (z=slider_pos+slider_length+1; z <= bar_length; z++) + { + setPrintPos (1, 1 + z); + + if ( isNewFont() ) + print (fc::NF_border_line_left); // ⎸ + + if ( isMonochron() || max_color < 16 ) + print (fc::MediumShade); + else + print (' '); + } } + else // horizontal + { + setColor (wc.scrollbar_fg, wc.scrollbar_bg); + z = 0; + + if ( isNewFont() ) + setPrintPos (3 + z, 1); + else + setPrintPos (2 + z, 1); + + for (; z < slider_pos; z++) + { + if ( isNewFont() ) + print (fc::NF_border_line_upper); // ¯ + else if ( isMonochron() || max_color < 16 ) + print (fc::MediumShade); // ▒ + else + print (' '); + } + + setColor (wc.scrollbar_bg, wc.scrollbar_fg); + + if ( isMonochron() ) + setReverse(false); + + z = 0; + + for (; z < slider_length; z++) + print (' '); + + if ( isMonochron() ) + setReverse(true); + + setColor (wc.scrollbar_fg, wc.scrollbar_bg); + z = slider_pos + slider_length + 1; + + for (; z <= bar_length; z++) + { + if ( isNewFont() ) + print (fc::NF_border_line_upper); // ¯ + else if ( isMonochron() || max_color < 16 ) + print (fc::MediumShade); // ▒ + else + print (' '); + } + } + + current_slider_pos = slider_pos; + + if ( isMonochron() ) + setReverse(false); } //---------------------------------------------------------------------- @@ -418,27 +418,30 @@ void FScrollbar::onMouseDown (FMouseEvent* ev) // process LeftButton scroll_type = getClickedScrollType(mouse_x, mouse_y); - if ( bar_orientation == fc::vertical ) + if ( scroll_type == FScrollbar::noScroll ) { - if ( mouse_y > slider_pos+1 && mouse_y <= slider_pos+slider_length+1 ) - slider_click_pos = mouse_y; // on slider - } - else // horizontal - { - if ( isNewFont() ) + if ( bar_orientation == fc::vertical ) { - if ( mouse_x > slider_pos+2 && mouse_x <= slider_pos+slider_length+2 ) - slider_click_pos = mouse_x; // on slider + if ( mouse_y > slider_pos+1 && mouse_y <= slider_pos+slider_length+1 ) + slider_click_pos = mouse_y; // on slider } - else + else // horizontal { - if ( mouse_x > slider_pos+1 && mouse_x <= slider_pos+slider_length+1 ) - slider_click_pos = mouse_x; // on slider + if ( isNewFont() ) + { + if ( mouse_x > slider_pos+2 && mouse_x <= slider_pos+slider_length+2 ) + slider_click_pos = mouse_x; // on slider + } + else + { + if ( mouse_x > slider_pos+1 && mouse_x <= slider_pos+slider_length+1 ) + slider_click_pos = mouse_x; // on slider + } } - } - if ( slider_click_pos > 0 ) - scroll_type = FScrollbar::scrollJump; + if ( slider_click_pos > 0 ) + scroll_type = FScrollbar::scrollJump; + } if ( scroll_type == FScrollbar::scrollPageBackward || scroll_type == FScrollbar::scrollPageForward ) @@ -609,6 +612,9 @@ void FScrollbar::init() //---------------------------------------------------------------------- void FScrollbar::draw() { + if ( length < 2 ) + return; + drawButtons(); current_slider_pos = -1; drawBar(); diff --git a/src/fscrollview.cpp b/src/fscrollview.cpp index 0a139f46..ec098ea5 100644 --- a/src/fscrollview.cpp +++ b/src/fscrollview.cpp @@ -187,7 +187,7 @@ void FScrollView::setPos (int x, int y, bool adjust) void FScrollView::setWidth (int w, bool adjust) { FWidget::setWidth (w, adjust); - viewport_geometry.setWidth(w); + viewport_geometry.setWidth(w - vertical_border_spacing - nf_offset); calculateScrollbarPos(); if ( getScrollWidth() < getViewportWidth() ) @@ -198,7 +198,7 @@ void FScrollView::setWidth (int w, bool adjust) void FScrollView::setHeight (int h, bool adjust) { FWidget::setHeight (h, adjust); - viewport_geometry.setHeight(h); + viewport_geometry.setHeight(h - horizontal_border_spacing); calculateScrollbarPos(); if ( getScrollHeight() < getViewportHeight() ) @@ -209,7 +209,8 @@ void FScrollView::setHeight (int h, bool adjust) void FScrollView::setSize (int w, int h, bool adjust) { FWidget::setSize (w, h, adjust); - viewport_geometry.setSize(w, h); + viewport_geometry.setSize ( w - vertical_border_spacing - nf_offset + , h - horizontal_border_spacing ); calculateScrollbarPos(); if ( getScrollWidth() < getViewportWidth() @@ -223,7 +224,8 @@ void FScrollView::setGeometry (int x, int y, int w, int h, bool adjust) FWidget::setGeometry (x, y, w, h, adjust); scroll_geometry.setPos ( getTermX() + getLeftPadding() - 1 , getTermY() + getTopPadding() - 1 ); - viewport_geometry.setSize(w, h); + viewport_geometry.setSize ( w - vertical_border_spacing - nf_offset + , h - horizontal_border_spacing ); calculateScrollbarPos(); if ( getScrollWidth() < getViewportWidth() @@ -296,6 +298,8 @@ void FScrollView::scrollTo (int x, int y) short& yoffset = viewport_geometry.y1_ref(); short xoffset_end = short(getScrollWidth() - getViewportWidth()); short yoffset_end = short(getScrollHeight() - getViewportHeight()); + int save_width = viewport_geometry.getWidth(); + int save_height = viewport_geometry.getHeight(); x--; y--; @@ -317,6 +321,8 @@ void FScrollView::scrollTo (int x, int y) if ( xoffset > xoffset_end ) xoffset = xoffset_end; + viewport_geometry.setWidth(save_width); + viewport_geometry.setHeight(save_height); hbar->setValue (xoffset); vbar->setValue (yoffset); drawHBar(); @@ -377,6 +383,8 @@ void FScrollView::onKeyPress (FKeyEvent* ev) short yoffset_before = yoffset; short xoffset_end = short(getScrollWidth() - getViewportWidth()); short yoffset_end = short(getScrollHeight() - getViewportHeight()); + int save_width = viewport_geometry.getWidth(); + int save_height = viewport_geometry.getHeight(); switch ( key ) { @@ -445,6 +453,8 @@ void FScrollView::onKeyPress (FKeyEvent* ev) if ( isVisible() && viewport && (xoffset_before != xoffset || yoffset_before != yoffset) ) { + viewport_geometry.setWidth(save_width); + viewport_geometry.setHeight(save_height); viewport->has_changes = true; setTopPadding (1 - yoffset); setLeftPadding (1 - xoffset); @@ -469,6 +479,7 @@ void FScrollView::onWheel (FWheelEvent* ev) bool hasChanges = false; short& yoffset = viewport_geometry.y1_ref(); short yoffset_before = yoffset; + int save_height = viewport_geometry.getHeight(); int wheel = ev->getWheel(); switch ( wheel ) @@ -507,6 +518,7 @@ void FScrollView::onWheel (FWheelEvent* ev) if ( isVisible() && viewport && yoffset_before != yoffset ) { + viewport_geometry.setHeight(save_height); viewport->has_changes = true; setTopPadding (1 - yoffset); setBottomPadding (1 - (getScrollHeight() - getViewportHeight() - yoffset)); @@ -551,28 +563,31 @@ void FScrollView::onChildFocusIn (FFocusEvent*) // Scrolls the viewport so that the focused widget is visible FRect widget_geometry; + FRect vp_geometry; FWidget* focus_widget = FWidget::getFocusWidget(); if ( ! focus_widget ) return; widget_geometry = focus_widget->getGeometryWithShadow(); + vp_geometry = viewport_geometry; + vp_geometry.move(1,1); - if ( ! viewport_geometry.contains(widget_geometry) ) + if ( ! vp_geometry.contains(widget_geometry) ) { int x, y; - int vx = viewport_geometry.getX(); - int vy = viewport_geometry.getY(); + int vx = vp_geometry.getX(); + int vy = vp_geometry.getY(); int wx = widget_geometry.getX(); int wy = widget_geometry.getY(); if ( wx > vx ) - x = widget_geometry.getX2() - viewport_geometry.getWidth() + 3; + x = widget_geometry.getX2() - vp_geometry.getWidth() + 1; else x = wx; if ( wy > vy ) - y = widget_geometry.getY2() - viewport_geometry.getHeight() + 3; + y = widget_geometry.getY2() - vp_geometry.getHeight() + 1; else y = wy; @@ -837,6 +852,7 @@ void FScrollView::cb_VBarChange (FWidget*, void*) short& yoffset = viewport_geometry.y1_ref(); short yoffset_before = yoffset; short yoffset_end = short(getScrollHeight() - getViewportHeight()); + int save_height = viewport_geometry.getHeight(); scrollType = vbar->getScrollType(); switch ( scrollType ) @@ -912,6 +928,7 @@ void FScrollView::cb_VBarChange (FWidget*, void*) if ( isVisible() && viewport && yoffset_before != yoffset ) { + viewport_geometry.setHeight(save_height); viewport->has_changes = true; setTopPadding (1 - yoffset); setBottomPadding (1 - (getScrollHeight() - getViewportHeight() - yoffset)); @@ -940,6 +957,7 @@ void FScrollView::cb_HBarChange (FWidget*, void*) short& xoffset = viewport_geometry.x1_ref(); short xoffset_before = xoffset; short xoffset_end = short(getScrollWidth() - getViewportWidth()); + int save_width = viewport_geometry.getWidth(); scrollType = hbar->getScrollType(); switch ( scrollType ) @@ -1015,6 +1033,7 @@ void FScrollView::cb_HBarChange (FWidget*, void*) if ( isVisible() && viewport && xoffset_before != xoffset ) { + viewport_geometry.setWidth(save_width); viewport->has_changes = true; setLeftPadding (1 - xoffset); setRightPadding (1 - (getScrollWidth() - getViewportWidth() - xoffset) + nf_offset); diff --git a/src/ftogglebutton.cpp b/src/ftogglebutton.cpp index 30fea73a..f41b5cc3 100644 --- a/src/ftogglebutton.cpp +++ b/src/ftogglebutton.cpp @@ -13,7 +13,7 @@ // constructor and destructor //---------------------------------------------------------------------- -FToggleButton::FToggleButton(FWidget* parent) +FToggleButton::FToggleButton (FWidget* parent) : FWidget(parent) , checked(false) , label_offset_pos(0) diff --git a/src/fwidget.h b/src/fwidget.h index 37b52dee..3d787563 100644 --- a/src/fwidget.h +++ b/src/fwidget.h @@ -204,7 +204,11 @@ class FWidget : public FVTerm virtual void setGeometry (const FRect&, bool = true); virtual void setGeometry (int, int, int, int, bool = true); virtual void setShadowSize (int, int); + void setMinimumWidth (int); + void setMinimumHeight (int); void setMinimumSize (int, int); + void setMaximumWidth (int); + void setMaximumHeight (int); void setMaximumSize (int, int); void setFixedSize (int, int); bool setCursorPos (const FPoint&); @@ -771,10 +775,26 @@ inline void FWidget::setGeometry (const FRect& box, bool adjust) inline void FWidget::setShadowSize (int right, int bottom) { wshadow.setPoint (right, bottom); } +//---------------------------------------------------------------------- +inline void FWidget::setMinimumWidth (int min_width) +{ size_hints.setMinimum (min_width, size_hints.min_height); } + +//---------------------------------------------------------------------- +inline void FWidget::setMinimumHeight (int min_height) +{ size_hints.setMinimum (size_hints.min_width, min_height); } + //---------------------------------------------------------------------- inline void FWidget::setMinimumSize (int min_width, int min_height) { size_hints.setMinimum (min_width, min_height); } +//---------------------------------------------------------------------- +inline void FWidget::setMaximumWidth (int max_width) +{ size_hints.setMaximum (max_width, size_hints.max_height); } + +//---------------------------------------------------------------------- +inline void FWidget::setMaximumHeight (int max_height) +{ size_hints.setMaximum (size_hints.max_width, max_height); } + //---------------------------------------------------------------------- inline void FWidget::setMaximumSize (int max_width, int max_height) { size_hints.setMaximum (max_width, max_height); }