static int4 getscrollbarmintracksize() { int sliderWidth = 0 , troughBorder = 0, stepperSize = 0, stepperSpacing = 0, minSliderSize = 0 , focusLineWidth = 0, focusPadding = 0; Boolean slider = False; moz_gtk_get_scrollbar_metrics(&sliderWidth, &troughBorder, &stepperSize, &stepperSpacing, &minSliderSize, &focusLineWidth, &focusPadding); MCRectangle minrect; int n_steppers = (slider ? 0 : 2); static const int slider_length = 1; minrect.x = minrect.y = 0; minrect.width = troughBorder * 2 + sliderWidth; minrect.height = stepperSize * n_steppers + stepperSpacing * 2 + troughBorder * 2 + slider_length; int stepper_width = minrect.width; int stepper_height = 0; if(n_steppers > 0) stepper_height = MIN(stepperSize, (minrect.height / n_steppers)); if(stepper_width < 1) stepper_width = minrect.width; return stepper_width; }
int ScrollbarThemeGtk::scrollbarThickness(ScrollbarControlSize controlSize) { static int size; if (!size) { MozGtkScrollbarMetrics metrics; moz_gtk_get_scrollbar_metrics(&metrics); size = metrics.slider_width; } return size; }
void ScrollbarThemeGtk::updateThemeProperties() { MozGtkScrollbarMetrics metrics; moz_gtk_get_scrollbar_metrics(&metrics); m_thumbFatness = metrics.slider_width; m_troughBorderWidth = metrics.trough_border; m_stepperSize = metrics.stepper_size; m_stepperSpacing = metrics.stepper_spacing; m_minThumbLength = metrics.min_slider_size; m_troughUnderSteppers = metrics.trough_under_steppers; m_hasForwardButtonStartPart = metrics.has_secondary_forward_stepper; m_hasBackButtonEndPart = metrics.has_secondary_backward_stepper; updateScrollbarsFrameThickness(); }
void ScrollbarThemeGtk::updateThemeProperties() { MozGtkScrollbarMetrics metrics; moz_gtk_get_scrollbar_metrics(&metrics); m_thumbFatness = metrics.slider_width; m_troughBorderWidth = metrics.trough_border; m_stepperSize = metrics.stepper_size; m_stepperSpacing = metrics.stepper_spacing; m_minThumbLength = metrics.min_slider_size; m_troughUnderSteppers = metrics.trough_under_steppers; m_hasForwardButtonStartPart = metrics.has_secondary_forward_stepper; m_hasBackButtonEndPart = metrics.has_secondary_backward_stepper; if (!gScrollbars) return; // Update the thickness of every interior frame scrollbar widget. The // platform-independent scrollbar them code isn't yet smart enough to get // this information when it paints. HashSet<Scrollbar*>::iterator end = gScrollbars->end(); for (HashSet<Scrollbar*>::iterator it = gScrollbars->begin(); it != end; ++it) { Scrollbar* scrollbar = (*it); // Top-level scrollbar i.e. scrollbars who have a parent ScrollView // with no parent are native, and thus do not need to be resized. if (!scrollbar->parent() || !scrollbar->parent()->parent()) return; int thickness = scrollbarThickness(scrollbar->controlSize()); if (scrollbar->orientation() == HorizontalScrollbar) scrollbar->setFrameRect(IntRect(0, scrollbar->parent()->height() - thickness, scrollbar->width(), thickness)); else scrollbar->setFrameRect(IntRect(scrollbar->parent()->width() - thickness, 0, thickness, scrollbar->height())); } }
void MCNativeTheme::getwidgetrect(const MCWidgetInfo &winfo, Widget_Metric wmetric, const MCRectangle &srect, MCRectangle &drect) { //metric part size is to get size of a part in a widget //metric draw size is to get the actual size that the part will draw //in given a rect. Useful for fixed sized widgets (combobox, scrollbars) //optimum size is the default size that a part should be drawn at using the standard //hig guidlines. minimum size if the minimum size that a part can draw at.. //some widgets will crash in some themes if you try to draw smaller! switch (wmetric) { case WTHEME_METRIC_CONTENTSIZE: { gint xthickness,ythickness; GtkThemeWidgetType moztype; gint flags = 0 ; GtkWidgetState state = getpartandstate(winfo, moztype, flags); if (moz_gtk_get_widget_border(moztype, &xthickness, &ythickness) == MOZ_GTK_SUCCESS) { drect = srect; drect.width -= (xthickness * 2); drect.height -= (ythickness * 2); drect.x += xthickness; drect.y += ythickness; } return; } break; case WTHEME_METRIC_DRAWSIZE: //size that widget will draw at. needed for controls that cannot scale (scrollbars). if (winfo.type == WTHEME_TYPE_SCROLLBAR || winfo.type == WTHEME_TYPE_SLIDER) { bool isVertical = ((winfo.attributes & WTHEME_ATT_SBVERTICAL) != 0); int sliderWidth, troughBorder, stepperSize, stepperSpacing, minSliderSize, focusLineWidth, focusPadding; moz_gtk_get_scrollbar_metrics(&sliderWidth, &troughBorder, &stepperSize, &stepperSpacing, &minSliderSize, &focusLineWidth, &focusPadding); MCRectangle sbincarrowrect,sbdecarrowrect,sbthumbrect,sbinctrackrect,sbdectrackrect; getscrollbarrects(winfo, srect, sbincarrowrect, sbdecarrowrect, sbthumbrect, sbinctrackrect, sbdectrackrect); drect.x = srect.x; drect.y = srect.y; if(isVertical) { drect.width = sbinctrackrect.width; drect.height = sbincarrowrect.height + sbdecarrowrect.height + sbthumbrect.height + sbinctrackrect.height + sbdectrackrect.height + (troughBorder * 2); } else { drect.width = sbincarrowrect.width + sbdecarrowrect.width + sbthumbrect.width + sbinctrackrect.width + sbdectrackrect.width + (troughBorder * 2); drect.height = sbinctrackrect.height; } return; } case WTHEME_METRIC_PARTSIZE: switch (winfo.type) { case WTHEME_TYPE_SCROLLBAR: case WTHEME_TYPE_PROGRESSBAR: case WTHEME_TYPE_SLIDER: { MCRectangle sbincarrowrect, sbdecarrowrect, sbthumbrect, sbinctrackrect, sbdectrackrect; getscrollbarrects(winfo, srect, sbincarrowrect, sbdecarrowrect, sbthumbrect, sbinctrackrect, sbdectrackrect); switch (winfo.part) { case WTHEME_PART_ARROW_DEC: drect = sbdecarrowrect; break; case WTHEME_PART_ARROW_INC: drect = sbincarrowrect; break; case WTHEME_PART_TRACK_DEC: drect = sbdectrackrect; break; case WTHEME_PART_TRACK_INC: drect = sbinctrackrect; break; case WTHEME_PART_THUMB: drect = sbthumbrect; break; default: break; } return; } case WTHEME_TYPE_COMBO: { gint tcombobtnwidth = srect.width; gint tcombobtnheight = srect.height; MCRectangle combobuttonrect; moz_gtk_get_dropdown_arrow_size(&tcombobtnwidth,&tcombobtnheight); real8 theightscale = tcombobtnheight/tcombobtnwidth; uint1 comboframesize = 0;//we should query comboframe value tcombobtnwidth = srect.height - (comboframesize * 2); tcombobtnheight = (uint2)(tcombobtnwidth * theightscale); combobuttonrect.x = srect.x + (srect.width - tcombobtnwidth - comboframesize) ; combobuttonrect.y = srect.y + comboframesize; combobuttonrect.width = tcombobtnwidth; combobuttonrect.height = tcombobtnheight; if (winfo.part == WTHEME_PART_COMBOTEXT) drect = MCU_subtract_rect(srect,combobuttonrect); else if (winfo.part == WTHEME_PART_COMBOBUTTON) drect = combobuttonrect; return; } default: break; } break; default: break; } //pass through to base class or when themes inherit from each other //base class MCTheme::getwidgetrect(winfo, wmetric, srect, drect); }
void MCNativeTheme::getscrollbarrects(const MCWidgetInfo & winfo, const MCRectangle & srect, MCRectangle & sbincarrowrect, MCRectangle & sbdecarrowrect, MCRectangle & sbthumbrect, MCRectangle & sbinctrackrect, MCRectangle & sbdectrackrect) { int sliderWidth = 0 , troughBorder = 0, stepperSize = 0, stepperSpacing = 0, minSliderSize = 0 , focusLineWidth = 0, focusPadding = 0; Boolean isVertical = ((winfo.attributes & WTHEME_ATT_SBVERTICAL) != 0); Boolean slider = winfo.type == WTHEME_TYPE_SLIDER; #define CLEAR_RECT(rect) do { rect.x = rect.y = rect.width = rect.height = 0; } while(0) CLEAR_RECT(sbincarrowrect); CLEAR_RECT(sbdecarrowrect); CLEAR_RECT(sbthumbrect); CLEAR_RECT(sbinctrackrect); CLEAR_RECT(sbdectrackrect); if(slider) moz_gtk_get_slider_metrics(&sliderWidth, &troughBorder, &stepperSize, &stepperSpacing, &minSliderSize, &focusLineWidth, &focusPadding); else moz_gtk_get_scrollbar_metrics(&sliderWidth, &troughBorder, &stepperSize, &stepperSpacing, &minSliderSize, &focusLineWidth, &focusPadding); if (winfo.datatype != WTHEME_DATA_SCROLLBAR) return; MCRectangle minrect; int n_steppers = (slider ? 0 : 2); static const int slider_length = 1; minrect.x = minrect.y = 0; if (isVertical) { minrect.width = troughBorder * 2 + sliderWidth; minrect.height = stepperSize * n_steppers + stepperSpacing * 2 + troughBorder * 2 + slider_length; } else { minrect.width = stepperSize * n_steppers + stepperSpacing * 2 + troughBorder * 2 + slider_length; minrect.height = troughBorder * 2 + sliderWidth; } MCWidgetScrollBarInfo *sbinfo = (MCWidgetScrollBarInfo *) winfo.data; uint2 trackwidth,trackheight; if (slider) sbinfo->thumbsize = 1; // get bounds for arrow buttons sbdecarrowrect.x = srect.x + troughBorder; sbdecarrowrect.y = srect.y + troughBorder; if(isVertical) { int stepper_width = minrect.width - troughBorder * 2; int stepper_height = 0; if(n_steppers > 0) stepper_height = MIN(stepperSize, (minrect.height / n_steppers)); if(stepper_width < 1) stepper_width = minrect.width; sbdecarrowrect.width = sbincarrowrect.width = stepper_width; sbdecarrowrect.height = sbincarrowrect.height = stepper_height; trackwidth = stepper_width; trackheight = stepper_height; sbincarrowrect.x = sbdecarrowrect.x; sbincarrowrect.y = srect.y + srect.height - sbincarrowrect.height - troughBorder; } else { int stepper_height = minrect.height - troughBorder * 2; int stepper_width = 0; if(n_steppers > 0) stepper_width = MIN(stepperSize, (minrect.width / n_steppers)); if(stepper_height < 1) stepper_height = minrect.height; sbdecarrowrect.width = sbincarrowrect.width = stepper_width; sbdecarrowrect.height = sbincarrowrect.height = stepper_height; trackwidth = stepper_width; trackheight = stepper_height; sbincarrowrect.x = srect.x + srect.width - sbdecarrowrect.width - troughBorder; sbincarrowrect.y = sbdecarrowrect.y; } { //get bounds for thumb real8 range = sbinfo->endvalue - sbinfo->startvalue; if (winfo.attributes & WTHEME_ATT_SBVERTICAL) { // AL-2014-01-16: [[ Bug 11677 ]] No need to make slider thumb disappear at specific width/height ratio if (slider || ((sbinfo->thumbsize != 0 ) && srect.height > srect.width * 3)) { sbthumbrect.x = srect.x + troughBorder; sbthumbrect.width = trackwidth; if (MCproportionalthumbs) { sbthumbrect.y = sbdecarrowrect.y + sbdecarrowrect.height; real8 height = srect.height - (sbdecarrowrect.height + sbincarrowrect.height) - (troughBorder * 2); if (range != 0.0 && fabs(sbinfo->endvalue - sbinfo->startvalue) != sbinfo->thumbsize) { int2 miny = sbthumbrect.y; real8 offset = height * (sbinfo->thumbpos - sbinfo->startvalue); sbthumbrect.y += (int2) (offset / range); range = fabs(range); sbthumbrect.height = (uint2)(sbinfo->thumbsize * height / range); uint2 minsize = srect.width; if (sbthumbrect.height < minsize) { uint2 diff = minsize - sbthumbrect.height; sbthumbrect.height = minsize; sbthumbrect.y -= (int2) (diff * (sbinfo-> thumbpos + sbinfo-> thumbsize - sbinfo-> startvalue) / range); if (sbthumbrect.y < miny) sbthumbrect.y = miny; } } else sbthumbrect.height = (int2) height - 1; } else { real8 height = sbthumbrect.height - (srect.width << 1) - FIXED_THUMB_SIZE; real8 offset = height * (sbinfo->thumbpos - sbinfo->startvalue); if (range < 0) range += sbinfo->thumbsize; else range -= sbinfo->thumbsize; sbthumbrect.y = srect.y + srect.width; if (range != 0.0) sbthumbrect.y += (int2) (offset / range); sbthumbrect.height = FIXED_THUMB_SIZE; } sbdectrackrect.x = sbinctrackrect.x = srect.x; sbdectrackrect.width = sbinctrackrect.width = trackwidth + (troughBorder * 2); sbinctrackrect.y = sbthumbrect.y + sbthumbrect.height; sbinctrackrect.height = sbincarrowrect.y - (sbthumbrect.y + sbthumbrect.height); sbdectrackrect.y = sbdecarrowrect.y + sbdecarrowrect.height; sbdectrackrect.height = sbthumbrect.y - (sbdecarrowrect.y + sbdecarrowrect.height); } else { sbthumbrect.height = 0; sbinctrackrect = srect; sbinctrackrect.width = trackwidth; sbdectrackrect = sbinctrackrect; } } else { // AL-2014-01-16: [[ Bug 11677 ]] No need to make slider thumb disappear at specific width/height ratio if (slider || ((sbinfo->thumbsize != 0 ) && srect.width > srect.height * 3)) { sbthumbrect.y = srect.y + troughBorder; sbthumbrect.height = trackheight; if (MCproportionalthumbs) { sbthumbrect.x = sbdecarrowrect.x + sbdecarrowrect.width; real8 width = srect.width - (sbdecarrowrect.width + sbincarrowrect.width) - (troughBorder * 2); if (range != 0.0 && fabs(sbinfo->endvalue - sbinfo->startvalue) != sbinfo->thumbsize) { int2 minx = sbthumbrect.x; real8 offset = (width * (sbinfo->thumbpos - sbinfo->startvalue)); sbthumbrect.x += (int2)(offset / range); range = fabs(range); sbthumbrect.width = (uint2) ((slider?0:sbinfo->thumbsize) * width / range); uint2 minsize = srect.height; if (sbthumbrect.width < minsize) { uint2 diff = minsize - sbthumbrect.width; sbthumbrect.width = minsize; sbthumbrect.x -= (int2) (diff * (sbinfo-> thumbpos + (slider?0:sbinfo-> thumbsize) - sbinfo-> startvalue) / range); if (sbthumbrect.x < minx) sbthumbrect.x = minx; } } else sbthumbrect.width = (int2) width - 1; } else { real8 width = srect.width - (srect.height << 1) - FIXED_THUMB_SIZE; real8 offset = width * (sbinfo->thumbpos - sbinfo->startvalue); sbthumbrect.x = srect.x + srect.height; if (range < 0) range += sbinfo->thumbsize; else range -= sbinfo->thumbsize; if (range != 0.0) sbthumbrect.x += (int2) (offset / range); sbthumbrect.width = FIXED_THUMB_SIZE; } sbdectrackrect.y = sbinctrackrect.y = srect.y; sbdectrackrect.height = sbinctrackrect.height = trackheight + (troughBorder * 2); sbinctrackrect.x = sbthumbrect.x + sbthumbrect.width; sbinctrackrect.width = sbincarrowrect.x - (sbthumbrect.x + sbthumbrect.width); sbdectrackrect.x = sbdecarrowrect.x + sbdecarrowrect.width; sbdectrackrect.width = sbthumbrect.x - (sbdecarrowrect.x + sbdecarrowrect.width); } else { sbthumbrect.width = 0; sbinctrackrect = srect; sbinctrackrect.height = trackheight; sbdectrackrect = sbinctrackrect; } } } }
void MCNativeTheme::drawScrollbar(MCDC *dc, const MCWidgetInfo &winfo, const MCRectangle &drect) { if (winfo.datatype != WTHEME_DATA_SCROLLBAR && winfo.type != WTHEME_TYPE_SMALLSCROLLBAR) return; //draw arrows MCWidgetInfo twinfo = winfo; MCRectangle sbincarrowrect, sbdecarrowrect, sbthumbrect, sbinctrackrect, sbdectrackrect; MCRectangle rangerect; int sliderWidth, troughBorder, stepperSize, stepperSpacing, minSliderSize, focusLineWidth, focusPadding; moz_gtk_get_scrollbar_metrics(&sliderWidth, &troughBorder, &stepperSize, &stepperSpacing, &minSliderSize, &focusLineWidth, &focusPadding); getscrollbarrects(winfo, drect, sbincarrowrect, sbdecarrowrect, sbthumbrect, sbinctrackrect, sbdectrackrect); getwidgetrect(winfo, WTHEME_METRIC_DRAWSIZE, drect, rangerect); uint4 sbpartdefaultstate = winfo.state & WTHEME_STATE_DISABLED ? WTHEME_STATE_DISABLED : WTHEME_STATE_CLEAR; memset(&twinfo, 0, sizeof(MCWidgetInfo)); //clear widget info // Crux needs the track to be the same size as the actual scroll bar, so we // paint that first. twinfo.type = winfo.attributes & WTHEME_ATT_SBVERTICAL ? WTHEME_TYPE_SCROLLBAR_TRACK_VERTICAL : WTHEME_TYPE_SCROLLBAR_TRACK_HORIZONTAL; twinfo.state = sbpartdefaultstate; if (winfo.part == WTHEME_PART_TRACK_DEC) twinfo.state = winfo.state; drawwidget(dc, twinfo, rangerect); twinfo.type = winfo.attributes & WTHEME_ATT_SBVERTICAL ? WTHEME_TYPE_SCROLLBAR_BUTTON_UP : WTHEME_TYPE_SCROLLBAR_BUTTON_LEFT; twinfo.state = sbpartdefaultstate; if (winfo.part == WTHEME_PART_ARROW_DEC) twinfo.state = winfo.state; drawwidget(dc, twinfo, sbdecarrowrect); twinfo.type = winfo.attributes & WTHEME_ATT_SBVERTICAL ? WTHEME_TYPE_SCROLLBAR_BUTTON_DOWN : WTHEME_TYPE_SCROLLBAR_BUTTON_RIGHT; twinfo.state = sbpartdefaultstate; if (winfo.part == WTHEME_PART_ARROW_INC) twinfo.state = winfo.state; drawwidget(dc, twinfo, sbincarrowrect); //TS - 2007-10-25 - theme adjustments if ( winfo.attributes & WTHEME_ATT_SBVERTICAL ) sbthumbrect.height ++ ; else sbthumbrect.width ++ ; if (sbthumbrect.height && sbthumbrect.width) { //draw thumb twinfo.type = winfo.attributes & WTHEME_ATT_SBVERTICAL ? WTHEME_TYPE_SCROLLBAR_THUMB_VERTICAL : WTHEME_TYPE_SCROLLBAR_THUMB_HORIZONTAL; twinfo.state = sbpartdefaultstate; if (winfo.part == WTHEME_PART_THUMB) twinfo.state = winfo.state; drawwidget(dc, twinfo, sbthumbrect); } }