[Libreoffice-commits] .: Branch 'libreoffice-3-4' - 7 commits - vcl/unx
Lubos Lunak
llunak at kemper.freedesktop.org
Fri Apr 8 13:01:39 PDT 2011
vcl/unx/kde4/KDESalFrame.cxx | 1
vcl/unx/kde4/KDESalGraphics.cxx | 235 +++++++++++++++++++++++++---------------
vcl/unx/kde4/KDESalGraphics.hxx | 1
3 files changed, 152 insertions(+), 85 deletions(-)
New commits:
commit 3638e82b039c071dbc3908a8977cb909ef71c07b
Author: LuboÅ¡ LuÅák <l.lunak at suse.cz>
Date: Fri Apr 8 21:55:54 2011 +0200
better fix for KDE4 popup painting covering popup frame
diff --git a/vcl/unx/kde4/KDESalGraphics.cxx b/vcl/unx/kde4/KDESalGraphics.cxx
index 8e9aad8..7fefe8f 100644
--- a/vcl/unx/kde4/KDESalGraphics.cxx
+++ b/vcl/unx/kde4/KDESalGraphics.cxx
@@ -264,6 +264,9 @@ sal_Bool KDESalGraphics::drawNativeControl( ControlType type, ControlPart part,
const ImplControlValue& value,
const OUString& )
{
+ if( lastPopupRect.isValid() && ( type != CTRL_MENU_POPUP || part != PART_MENU_ITEM ))
+ lastPopupRect = QRect();
+
// put not implemented types here
if (type == CTRL_SPINBUTTONS)
{
@@ -323,15 +326,21 @@ sal_Bool KDESalGraphics::drawNativeControl( ControlType type, ControlPart part,
}
else if (type == CTRL_MENU_POPUP)
{
+ OSL_ASSERT( part == PART_MENU_ITEM ? lastPopupRect.isValid() : !lastPopupRect.isValid());
if( part == PART_MENU_ITEM )
{
QStyleOptionMenuItem option;
- // this is painted after popup frame, so highlight would be painted
- // over popup border
- int fw = kapp->style()->pixelMetric( QStyle::PM_MenuPanelWidth );
- clipRegion = new QRegion( widgetRect.adjusted( fw, fw, -fw, -fw ));
draw( QStyle::CE_MenuItem, &option, m_image,
vclStateValue2StateFlag(nControlState, value) );
+ // HACK: LO core first paints the entire popup and only then it paints menu items,
+ // but QMenu::paintEvent() paints popup frame after all items. That means highlighted
+ // items here would paint the highlight over the frame border. Since calls to PART_MENU_ITEM
+ // are always preceded by calls to PART_ENTIRE_CONTROL, just remember the size for the whole
+ // popup (otherwise not possible to get here) and draw the border afterwards.
+ QRect framerect( lastPopupRect.topLeft() - widgetRect.topLeft(),
+ widgetRect.size().expandedTo( lastPopupRect.size()));
+ QStyleOptionFrame frame;
+ draw( QStyle::PE_FrameMenu, &frame, m_image, vclStateValue2StateFlag( nControlState, value ), framerect );
}
else if( part == PART_MENU_SEPARATOR )
{
@@ -346,7 +355,7 @@ sal_Bool KDESalGraphics::drawNativeControl( ControlType type, ControlPart part,
QPoint center = rect.center();
rect.setHeight( size.height());
rect.moveCenter( center );
- // don't paint over popup frame border
+ // don't paint over popup frame border (like the hack above, but here it can be simpler)
int fw = kapp->style()->pixelMetric( QStyle::PM_MenuPanelWidth );
clipRegion = new QRegion( rect.translated( widgetRect.topLeft()).adjusted( fw, 0, -fw, 0 ));
draw( QStyle::CE_MenuItem, &option, m_image,
@@ -375,8 +384,8 @@ sal_Bool KDESalGraphics::drawNativeControl( ControlType type, ControlPart part,
QStyleOptionMenuItem option;
draw( QStyle::PE_PanelMenu, &option, m_image, vclStateValue2StateFlag( nControlState, value ));
QStyleOptionFrame frame;
- frame.lineWidth = kapp->style()->pixelMetric( QStyle::PM_MenuPanelWidth );
draw( QStyle::PE_FrameMenu, &frame, m_image, vclStateValue2StateFlag( nControlState, value ));
+ lastPopupRect = widgetRect;
}
else
returnVal = false;
diff --git a/vcl/unx/kde4/KDESalGraphics.hxx b/vcl/unx/kde4/KDESalGraphics.hxx
index 55697e4..e1ec6ba 100644
--- a/vcl/unx/kde4/KDESalGraphics.hxx
+++ b/vcl/unx/kde4/KDESalGraphics.hxx
@@ -40,6 +40,7 @@
class KDESalGraphics : public X11SalGraphics
{
QImage* m_image;
+ QRect lastPopupRect;
public:
KDESalGraphics();
commit b2d1508fd2dfd22113b343914cb382be092fd628
Author: LuboÅ¡ LuÅák <l.lunak at suse.cz>
Date: Fri Apr 8 21:43:11 2011 +0200
rework KDE4 popup menu drawing to avoid various glitches
diff --git a/vcl/unx/kde4/KDESalGraphics.cxx b/vcl/unx/kde4/KDESalGraphics.cxx
index e0f736b..8e9aad8 100644
--- a/vcl/unx/kde4/KDESalGraphics.cxx
+++ b/vcl/unx/kde4/KDESalGraphics.cxx
@@ -160,10 +160,10 @@ sal_Bool KDESalGraphics::IsNativeControlSupported( ControlType type, ControlPart
/// helper drawing methods
namespace
{
- void draw( QStyle::ControlElement element, QStyleOption* option, QImage* image, QStyle::State state )
+ void draw( QStyle::ControlElement element, QStyleOption* option, QImage* image, QStyle::State state, QRect rect = QRect())
{
option->state |= state;
- option->rect = image->rect();
+ option->rect = !rect.isNull() ? rect : image->rect();
QPainter painter(image);
kapp->style()->drawControl(element, option, &painter);
@@ -323,43 +323,63 @@ sal_Bool KDESalGraphics::drawNativeControl( ControlType type, ControlPart part,
}
else if (type == CTRL_MENU_POPUP)
{
- if (part == PART_MENU_ITEM)
+ if( part == PART_MENU_ITEM )
{
QStyleOptionMenuItem option;
- draw( QStyle::CE_MenuItem, &option, m_image,
+ // this is painted after popup frame, so highlight would be painted
+ // over popup border
+ int fw = kapp->style()->pixelMetric( QStyle::PM_MenuPanelWidth );
+ clipRegion = new QRegion( widgetRect.adjusted( fw, fw, -fw, -fw ));
+ draw( QStyle::CE_MenuItem, &option, m_image,
vclStateValue2StateFlag(nControlState, value) );
}
- else if (part == PART_MENU_ITEM_CHECK_MARK)
+ else if( part == PART_MENU_SEPARATOR )
{
- m_image->fill(Qt::transparent);
- if(nControlState & CTRL_STATE_PRESSED) // at least Oxygen paints always as checked
- {
- QStyleOptionButton option;
- draw( QStyle::PE_IndicatorMenuCheckMark, &option, m_image,
- vclStateValue2StateFlag(nControlState, value));
- }
+ QStyleOptionMenuItem option;
+ option.menuItemType = QStyleOptionMenuItem::Separator;
+ // Painting the whole menu item area results in different background
+ // with at least Plastique style, so clip only to the separator itself
+ // (QSize( 2, 2 ) is hardcoded in Qt)
+ option.rect = m_image->rect();
+ QSize size = kapp->style()->sizeFromContents( QStyle::CT_MenuItem, &option, QSize( 2, 2 ));
+ QRect rect = m_image->rect();
+ QPoint center = rect.center();
+ rect.setHeight( size.height());
+ rect.moveCenter( center );
+ // don't paint over popup frame border
+ int fw = kapp->style()->pixelMetric( QStyle::PM_MenuPanelWidth );
+ clipRegion = new QRegion( rect.translated( widgetRect.topLeft()).adjusted( fw, 0, -fw, 0 ));
+ draw( QStyle::CE_MenuItem, &option, m_image,
+ vclStateValue2StateFlag(nControlState, value), rect );
}
- else if (part == PART_MENU_ITEM_RADIO_MARK)
+ else if( part == PART_MENU_ITEM_CHECK_MARK || part == PART_MENU_ITEM_RADIO_MARK )
{
- m_image->fill(Qt::transparent);
- QStyleOptionButton option;
- // we get always passed BUTTONVALUE_DONTKNOW in 'value', and the checked
- // state is actually CTRL_STATE_PRESSED
- QStyle::State set = ( nControlState & CTRL_STATE_PRESSED ) ? QStyle::State_On : QStyle::State_Off;
- draw( QStyle::PE_IndicatorRadioButton, &option, m_image,
- vclStateValue2StateFlag(nControlState, value) | set );
+ QStyleOptionMenuItem option;
+ option.checkType = ( part == PART_MENU_ITEM_CHECK_MARK )
+ ? QStyleOptionMenuItem::NonExclusive : QStyleOptionMenuItem::Exclusive;
+ option.checked = ( nControlState & CTRL_STATE_PRESSED );
+ // widgetRect is now the rectangle for the checkbox/radiobutton itself, but Qt
+ // paints the whole menu item, so translate position (and it'll be clipped);
+ // it is also necessary to fill the background transparently first, as this
+ // is painted after menuitem highlight, otherwise there would be a grey area
+ const MenupopupValue* menuVal = static_cast<const MenupopupValue*>(&value);
+ QRect menuItemRect( region2QRect( menuVal->maItemRect ));
+ QRect rect( menuItemRect.topLeft() - widgetRect.topLeft(),
+ widgetRect.size().expandedTo( menuItemRect.size()));
+ m_image->fill( Qt::transparent );
+ draw( QStyle::CE_MenuItem, &option, m_image,
+ vclStateValue2StateFlag(nControlState, value), rect );
}
- else
+ else if( part == PART_ENTIRE_CONTROL )
{
- #if ( QT_VERSION >= QT_VERSION_CHECK( 4, 5, 0 ) )
- QStyleOptionFrameV3 option;
- option.frameShape = QFrame::StyledPanel;
- #else
- QStyleOptionFrameV2 option;
- #endif
- draw( QStyle::PE_FrameMenu, &option, m_image,
- vclStateValue2StateFlag(nControlState, value) );
+ QStyleOptionMenuItem option;
+ draw( QStyle::PE_PanelMenu, &option, m_image, vclStateValue2StateFlag( nControlState, value ));
+ QStyleOptionFrame frame;
+ frame.lineWidth = kapp->style()->pixelMetric( QStyle::PM_MenuPanelWidth );
+ draw( QStyle::PE_FrameMenu, &frame, m_image, vclStateValue2StateFlag( nControlState, value ));
}
+ else
+ returnVal = false;
}
else if ( (type == CTRL_TOOLBAR) && (part == PART_BUTTON) )
{
commit c15593ad44e736f55b26f5c117b07fd86be65178
Author: LuboÅ¡ LuÅák <l.lunak at suse.cz>
Date: Fri Apr 8 18:19:19 2011 +0200
kde4 size of menu radio/checkboxes
diff --git a/vcl/unx/kde4/KDESalGraphics.cxx b/vcl/unx/kde4/KDESalGraphics.cxx
index 92af333..e0f736b 100644
--- a/vcl/unx/kde4/KDESalGraphics.cxx
+++ b/vcl/unx/kde4/KDESalGraphics.cxx
@@ -810,16 +810,8 @@ sal_Bool KDESalGraphics::getNativeControlRegion( ControlType type, ControlPart p
break;
}
case CTRL_MENU_POPUP:
- //just limit the widget of the menu items
- //OO isn't very flexible in all reguards with the menu
- //so we do the best we can
- if (part == PART_MENU_ITEM_CHECK_MARK)
- {
- contentRect.setWidth(contentRect.height());
- retVal = true;
- }
- else if (part == PART_MENU_ITEM_RADIO_MARK)
- {
+ if (part == PART_MENU_ITEM_CHECK_MARK || part == PART_MENU_ITEM_RADIO_MARK)
+ { // core uses this to detect radio/checkbox sizes, so just set a square
contentRect.setWidth(contentRect.height());
retVal = true;
}
commit 9a389766e67f8832381238d6c6f3dbb26ffdd660
Author: LuboÅ¡ LuÅák <l.lunak at suse.cz>
Date: Fri Apr 8 17:55:14 2011 +0200
implement CTRL_PROGRESS for KDE4
diff --git a/vcl/unx/kde4/KDESalGraphics.cxx b/vcl/unx/kde4/KDESalGraphics.cxx
index ebe939a..92af333 100644
--- a/vcl/unx/kde4/KDESalGraphics.cxx
+++ b/vcl/unx/kde4/KDESalGraphics.cxx
@@ -146,12 +146,13 @@ sal_Bool KDESalGraphics::IsNativeControlSupported( ControlType type, ControlPart
if (type == CTRL_SLIDER && (part == PART_TRACK_HORZ_AREA || part == PART_TRACK_VERT_AREA) )
return true;
+ if ( (type == CTRL_PROGRESS) && (part == PART_ENTIRE_CONTROL) ) return true;
+
return false;
if ( (type == CTRL_TAB_ITEM) && (part == PART_ENTIRE_CONTROL) ) return true;
if ( (type == CTRL_TAB_PANE) && (part == PART_ENTIRE_CONTROL) ) return true;
// no CTRL_TAB_BODY for KDE
- if ( (type == CTRL_PROGRESS) && (part == PART_ENTIRE_CONTROL) ) return true;
return false;
}
@@ -568,6 +569,18 @@ sal_Bool KDESalGraphics::drawNativeControl( ControlType type, ControlPart part,
draw( QStyle::CC_Slider, &option, m_image, vclStateValue2StateFlag(nControlState, value) );
}
+ else if( type == CTRL_PROGRESS && part == PART_ENTIRE_CONTROL )
+ {
+ QStyleOptionProgressBarV2 option;
+ option.minimum = 0;
+ option.maximum = widgetRect.width();
+ option.progress = value.getNumericVal();
+ option.rect = QRect(0, 0, widgetRect.width(), widgetRect.height());
+ option.state = vclStateValue2StateFlag( nControlState, value );
+
+ draw( QStyle::CE_ProgressBar, &option, m_image,
+ vclStateValue2StateFlag(nControlState, value) );
+ }
else
{
returnVal = false;
commit f38caab61313a7a18bf5c9215273f4c15c8ef68c
Author: LuboÅ¡ LuÅák <l.lunak at suse.cz>
Date: Fri Apr 8 17:17:15 2011 +0200
define minimal scrollbar slider size for KDE4
diff --git a/vcl/unx/kde4/KDESalFrame.cxx b/vcl/unx/kde4/KDESalFrame.cxx
index 3d34957..ab6bf1a 100644
--- a/vcl/unx/kde4/KDESalFrame.cxx
+++ b/vcl/unx/kde4/KDESalFrame.cxx
@@ -345,6 +345,7 @@ void KDESalFrame::UpdateSettings( AllSettings& rSettings )
// Scroll bar size
style.SetScrollBarSize( kapp->style()->pixelMetric( QStyle::PM_ScrollBarExtent ) );
+ style.SetMinThumbSize( kapp->style()->pixelMetric( QStyle::PM_ScrollBarSliderMin ));
rSettings.SetStyleSettings( style );
}
commit 5a27f468b350f81becd088b565c3bc8ed3a6d824
Author: LuboÅ¡ LuÅák <l.lunak at suse.cz>
Date: Fri Apr 8 16:30:34 2011 +0200
provide scrollbar track area, to fix detection of KDE4 scrollbar areas
diff --git a/vcl/unx/kde4/KDESalGraphics.cxx b/vcl/unx/kde4/KDESalGraphics.cxx
index d3f8965..ebe939a 100644
--- a/vcl/unx/kde4/KDESalGraphics.cxx
+++ b/vcl/unx/kde4/KDESalGraphics.cxx
@@ -862,6 +862,35 @@ sal_Bool KDESalGraphics::getNativeControlRegion( ControlType type, ControlPart p
}
break;
}
+ case CTRL_SCROLLBAR:
+ {
+ // core can't handle 3-button scrollbars well, so we fix that in hitTestNativeControl(),
+ // for the rest also provide the track area (i.e. area not taken by buttons)
+ if( part == PART_TRACK_VERT_AREA || part == PART_TRACK_HORZ_AREA )
+ {
+ QStyleOptionSlider option;
+ OSL_ASSERT( val.getType() == CTRL_SCROLLBAR );
+ const ScrollbarValue* sbVal = static_cast<const ScrollbarValue *>(&val);
+ option.orientation = ( part == PART_TRACK_HORZ_AREA ) ? Qt::Horizontal : Qt::Vertical;
+ option.minimum = sbVal->mnMin;
+ option.maximum = sbVal->mnMax;
+ option.sliderValue = sbVal->mnCur;
+ option.sliderPosition = sbVal->mnCur;
+ option.pageStep = sbVal->mnVisibleSize;
+ // Adjust coordinates to make the widget appear to be at (0,0), i.e. make
+ // widget and screen coordinates the same. QStyle functions should use screen
+ // coordinates but at least QPlastiqueStyle::subControlRect() is buggy
+ // and sometimes uses widget coordinates.
+ QRect rect = contentRect;
+ rect.moveTo( 0, 0 );
+ option.rect = rect;
+ rect = kapp->style()->subControlRect( QStyle::CC_ScrollBar, &option,
+ QStyle::SC_ScrollBarGroove );
+ rect.translate( contentRect.topLeft()); // reverse the workaround above
+ contentRect = boundingRect = rect;
+ retVal = true;
+ }
+ }
default:
break;
}
@@ -894,7 +923,8 @@ sal_Bool KDESalGraphics::hitTestNativeControl( ControlType nType, ControlPart nP
{
if( nPart != PART_BUTTON_UP && nPart != PART_BUTTON_DOWN
&& nPart != PART_BUTTON_LEFT && nPart != PART_BUTTON_RIGHT )
- { // we adjust only for buttons (because some scrollbars have 3 buttons)
+ { // we adjust only for buttons (because some scrollbars have 3 buttons,
+ // and LO core doesn't handle such scrollbars well)
return FALSE;
}
rIsInside = FALSE;
commit 4a9a7743d0aa9d5372f3e1debc4ae46336f8315c
Author: LuboÅ¡ LuÅák <l.lunak at suse.cz>
Date: Fri Apr 8 15:15:49 2011 +0200
move hitTestNativeControl() to be next to getNativeControlRegion()
diff --git a/vcl/unx/kde4/KDESalGraphics.cxx b/vcl/unx/kde4/KDESalGraphics.cxx
index 6cf466d..d3f8965 100644
--- a/vcl/unx/kde4/KDESalGraphics.cxx
+++ b/vcl/unx/kde4/KDESalGraphics.cxx
@@ -156,51 +156,6 @@ sal_Bool KDESalGraphics::IsNativeControlSupported( ControlType type, ControlPart
return false;
}
-/** Test whether the position is in the native widget.
- If the return value is TRUE, bIsInside contains information whether
- aPos was or was not inside the native widget specified by the
- nType/nPart combination.
-*/
-sal_Bool KDESalGraphics::hitTestNativeControl( ControlType nType, ControlPart nPart,
- const Rectangle& rControlRegion, const Point& rPos,
- sal_Bool& rIsInside )
-{
- if ( nType == CTRL_SCROLLBAR )
- {
- if( nPart != PART_BUTTON_UP && nPart != PART_BUTTON_DOWN
- && nPart != PART_BUTTON_LEFT && nPart != PART_BUTTON_RIGHT )
- { // we adjust only for buttons (because some scrollbars have 3 buttons)
- return FALSE;
- }
- rIsInside = FALSE;
- bool bHorizontal = ( nPart == PART_BUTTON_LEFT || nPart == PART_BUTTON_RIGHT );
- QRect rect = region2QRect( rControlRegion );
- QPoint pos( rPos.X(), rPos.Y());
- // Adjust coordinates to make the widget appear to be at (0,0), i.e. make
- // widget and screen coordinates the same. QStyle functions should use screen
- // coordinates but at least QPlastiqueStyle::subControlRect() is buggy
- // and sometimes uses widget coordinates.
- pos -= rect.topLeft();
- rect.moveTo( 0, 0 );
- QStyleOptionSlider options;
- options.orientation = bHorizontal ? Qt::Horizontal : Qt::Vertical;
- options.rect = rect;
- // some random sensible values, since we call this code only for scrollbar buttons,
- // the slider position does not exactly matter
- options.maximum = 10;
- options.minimum = 0;
- options.sliderPosition = options.sliderValue = 4;
- options.pageStep = 2;
- QStyle::SubControl control = kapp->style()->hitTestComplexControl( QStyle::CC_ScrollBar, &options, pos );
- if( nPart == PART_BUTTON_UP || nPart == PART_BUTTON_LEFT )
- rIsInside = ( control == QStyle::SC_ScrollBarSubLine );
- else // DOWN, RIGHT
- rIsInside = ( control == QStyle::SC_ScrollBarAddLine );
- return TRUE;
- }
- return FALSE;
-}
-
/// helper drawing methods
namespace
{
@@ -926,4 +881,50 @@ sal_Bool KDESalGraphics::getNativeControlRegion( ControlType type, ControlPart p
return retVal;
}
+/** Test whether the position is in the native widget.
+ If the return value is TRUE, bIsInside contains information whether
+ aPos was or was not inside the native widget specified by the
+ nType/nPart combination.
+*/
+sal_Bool KDESalGraphics::hitTestNativeControl( ControlType nType, ControlPart nPart,
+ const Rectangle& rControlRegion, const Point& rPos,
+ sal_Bool& rIsInside )
+{
+ if ( nType == CTRL_SCROLLBAR )
+ {
+ if( nPart != PART_BUTTON_UP && nPart != PART_BUTTON_DOWN
+ && nPart != PART_BUTTON_LEFT && nPart != PART_BUTTON_RIGHT )
+ { // we adjust only for buttons (because some scrollbars have 3 buttons)
+ return FALSE;
+ }
+ rIsInside = FALSE;
+ bool bHorizontal = ( nPart == PART_BUTTON_LEFT || nPart == PART_BUTTON_RIGHT );
+ QRect rect = region2QRect( rControlRegion );
+ QPoint pos( rPos.X(), rPos.Y());
+ // Adjust coordinates to make the widget appear to be at (0,0), i.e. make
+ // widget and screen coordinates the same. QStyle functions should use screen
+ // coordinates but at least QPlastiqueStyle::subControlRect() is buggy
+ // and sometimes uses widget coordinates.
+ pos -= rect.topLeft();
+ rect.moveTo( 0, 0 );
+ QStyleOptionSlider options;
+ options.orientation = bHorizontal ? Qt::Horizontal : Qt::Vertical;
+ options.rect = rect;
+ // some random sensible values, since we call this code only for scrollbar buttons,
+ // the slider position does not exactly matter
+ options.maximum = 10;
+ options.minimum = 0;
+ options.sliderPosition = options.sliderValue = 4;
+ options.pageStep = 2;
+ QStyle::SubControl control = kapp->style()->hitTestComplexControl( QStyle::CC_ScrollBar, &options, pos );
+ if( nPart == PART_BUTTON_UP || nPart == PART_BUTTON_LEFT )
+ rIsInside = ( control == QStyle::SC_ScrollBarSubLine );
+ else // DOWN, RIGHT
+ rIsInside = ( control == QStyle::SC_ScrollBarAddLine );
+ return TRUE;
+ }
+ return FALSE;
+}
+
+
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
More information about the Libreoffice-commits
mailing list