Antrax
16th October 2006, 09:50
Having accomplished something similar for a QSlider, I thought it'd be simple. However, I've overriden drawComplexControl, subControlRect, hitTestComplexControl and pixelMetric, and I still encouter two related bugs: when dragging the handle, the handle moves to other places than what the mouse cursor points to, and the handle, instead of being confined to the slider groove, manages to escape the QScrollBar and overwrite its arrows.
I'm guessing both of these is because somehow I've screwed up the calculation of pixel position to slider position to value to screen position, but I can't figure out where. Below are cleaned up code snippets.
void PictureScrollbarStyle::drawComplexControl(ComplexC ontrol control, const QStyleOptionComplex* option,
QPainter* painter, const QWidget* widget) const
{
-snip-
//drawing the handle
QRect Pos = subControlRect(CC_ScrollBar, option, SC_ScrollBarSlider, widget);
painter->drawPixmap(Pos , *handlePicture);
-snip-
}
QRect PictureScrollbarStyle::subControlRect(ComplexContr ol control, const QStyleOptionComplex* option,
SubControl subControl, const QWidget* widget) const
{
-snip-
if (SC_ScrollBarSlider == subControl)
{
int h = handlePicture->height() / 2;
int span = StyleOptions->maximum - StyleOptions->minimum;
float ratio = (float)StyleOptions->rect.height() / (float)span;
int position = (int)(StyleOptions->sliderPosition * ratio);
QRect result(0, position - h, handlePicture->width(), handlePicture->height());
return result.isValid() ? result : QRect(0, 0, 0, 0);
}
-snip-
}
QStyle::SubControl PictureScrollbarStyle::hitTestComplexControl(Compl exControl control, const QStyleOptionComplex* option,
const QPoint& pos, const QWidget* widget) const
{
-snip-
r = subControlRect(CC_ScrollBar, option, SC_ScrollBarSlider, widget);
if (r.isValid() && r.contains(pos))
{
return SC_ScrollBarSlider;
}
return SC_ScrollBarGroove;
}
pixelMetric code isn't attached because debug prints show it's not used.
Thanks in advance.
I'm guessing both of these is because somehow I've screwed up the calculation of pixel position to slider position to value to screen position, but I can't figure out where. Below are cleaned up code snippets.
void PictureScrollbarStyle::drawComplexControl(ComplexC ontrol control, const QStyleOptionComplex* option,
QPainter* painter, const QWidget* widget) const
{
-snip-
//drawing the handle
QRect Pos = subControlRect(CC_ScrollBar, option, SC_ScrollBarSlider, widget);
painter->drawPixmap(Pos , *handlePicture);
-snip-
}
QRect PictureScrollbarStyle::subControlRect(ComplexContr ol control, const QStyleOptionComplex* option,
SubControl subControl, const QWidget* widget) const
{
-snip-
if (SC_ScrollBarSlider == subControl)
{
int h = handlePicture->height() / 2;
int span = StyleOptions->maximum - StyleOptions->minimum;
float ratio = (float)StyleOptions->rect.height() / (float)span;
int position = (int)(StyleOptions->sliderPosition * ratio);
QRect result(0, position - h, handlePicture->width(), handlePicture->height());
return result.isValid() ? result : QRect(0, 0, 0, 0);
}
-snip-
}
QStyle::SubControl PictureScrollbarStyle::hitTestComplexControl(Compl exControl control, const QStyleOptionComplex* option,
const QPoint& pos, const QWidget* widget) const
{
-snip-
r = subControlRect(CC_ScrollBar, option, SC_ScrollBarSlider, widget);
if (r.isValid() && r.contains(pos))
{
return SC_ScrollBarSlider;
}
return SC_ScrollBarGroove;
}
pixelMetric code isn't attached because debug prints show it's not used.
Thanks in advance.