void TkClipBox( TkRegion r, XRectangle* rect_return) { CGRect rect; HIShapeGetBounds((HIShapeRef) r, &rect); rect_return->x = rect.origin.x; rect_return->y = rect.origin.y; rect_return->width = rect.size.width; rect_return->height = rect.size.height; }
BOOL MacWidgetPainter::DrawScrollbar(const OpRect &drawrect) { HIThemeTrackDrawInfo drawInfo; ThemeTrackPressState pressState = 0; OpScrollbar *scroll = (OpScrollbar*)widget; HIShapeRef thumbRgn; OpRect opBounds = scroll->GetBounds(); CGRect bounds = {{-drawrect.x, -drawrect.y}, {opBounds.width, opBounds.height}}; pressState = (ThemeTrackPressState)scroll->GetHitPart(); // hack to draw correctly, for some reason DrawThemeTrack needs this. if(pressState == kThemeTopInsideArrowPressed) pressState = kThemeBottomInsideArrowPressed; else if(pressState == kThemeBottomInsideArrowPressed) pressState = kThemeTopInsideArrowPressed; if(scroll->horizontal) { bounds.size.width++; } else { bounds.size.height++; } OpWindow *rootWindow; BOOL inActiveWindow = FALSE; if (vd->GetView()) { rootWindow = vd->GetView()->GetContainer()->GetOpView()->GetRootWindow(); inActiveWindow = rootWindow->IsActiveTopmostWindow() || rootWindow->GetStyle() == OpWindow::STYLE_POPUP; } drawInfo.version = 0; drawInfo.kind = kThemeMediumScrollBar; drawInfo.enableState = (scroll->IsEnabled() && inActiveWindow) ? kThemeTrackActive : kThemeTrackInactive; drawInfo.attributes = kThemeTrackShowThumb | (scroll->horizontal ? kThemeTrackHorizontal : 0); drawInfo.bounds = bounds; drawInfo.min = scroll->limit_min; drawInfo.max = scroll->limit_max; drawInfo.value = scroll->value; drawInfo.trackInfo.scrollbar.viewsize = scroll->limit_visible; drawInfo.trackInfo.scrollbar.pressState = pressState; int minSize = g_op_ui_info->GetHorizontalScrollbarHeight(); if (GetOSVersion() >= 0x1070) { minSize = 0; } else if (GetInfo()->GetScrollbarArrowStyle() == ARROWS_AT_BOTTOM_AND_TOP) { minSize *= 6; minSize -= 4; } else { minSize *= 4; } // Bail out if smaller than minSize if(scroll->horizontal) { if((bounds.size.width) < minSize) { return FALSE; } } else { if((bounds.size.height) < minSize) { return FALSE; } } // Ok, the thumb(knob) could have been changed, let's update if(noErr == HIThemeGetTrackThumbShape(&drawInfo, &thumbRgn)) { HIRect thumbRect; OpRect thumbOpRect; HIShapeGetBounds(thumbRgn, &thumbRect); CFRelease(thumbRgn); thumbOpRect.x = thumbRect.origin.x - bounds.origin.x; thumbOpRect.y = thumbRect.origin.y - bounds.origin.y; thumbOpRect.width = thumbRect.size.width; thumbOpRect.height = thumbRect.size.height; scroll->SetKnobRect(thumbOpRect); } if (OpStatus::IsError(MacCachedObjectFactory<MacWidgetBitmap, MacWidgetBitmapTraits>::Init())) return FALSE; int bmpwidth = drawrect.width; int bmpheight = drawrect.height; #ifdef PIXEL_SCALE_RENDERING_SUPPORT const PixelScaler& scaler = vd->GetVPScale(); bmpwidth = TO_DEVICE_PIXEL(scaler, bmpwidth); bmpheight = TO_DEVICE_PIXEL(scaler, bmpheight); #endif // PIXEL_SCALE_RENDERING_SUPPORT MacWidgetBitmap* bitmap = MacCachedObjectFactory<MacWidgetBitmap, MacWidgetBitmapTraits>::CreateObject(MacWidgetBitmapTraits::CreateParam(bmpwidth, bmpheight)); if (!bitmap) return FALSE; // Set clip and draw widget->SetClipRect(drawrect); OpBitmap* bmp = bitmap->GetOpBitmap(); void* image_data = bmp->GetPointer(OpBitmap::ACCESS_WRITEONLY); if (!image_data) { bitmap->DecRef(); widget->RemoveClipRect(); return FALSE; } bitmap->Lock(); const int bpl = bmp->GetBytesPerLine(); memset(image_data, 0, bpl * bmp->Height()); CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); CGBitmapInfo alpha = kCGBitmapByteOrderVegaInternal; // create the context at size of drawrect instead of bitmap itself. // we cache the bitmap to prevent create-destroy cycle and reallocation. // since we need the bitmap's memory only, we can create a much smaller context within that buffer. CGContextRef context = CGBitmapContextCreate(image_data, bmpwidth, bmpheight, 8, bpl, colorSpace, alpha); CGColorSpaceRelease(colorSpace); if (!context) { bitmap->DecRef(); bmp->ReleasePointer(FALSE); widget->RemoveClipRect(); bitmap->Unlock(); return FALSE; } const int win_height = drawrect.height; CGFloat scale = 1.0f; #ifdef PIXEL_SCALE_RENDERING_SUPPORT scale = CGFloat(scaler.GetScale()) / 100.0f; #endif // PIXEL_SCALE_RENDERING_SUPPORT CGContextScaleCTM(context, scale, -scale); CGContextTranslateCTM(context, 0.0f, -win_height); HIThemeDrawTrack(&drawInfo, NULL, context, kHIThemeOrientationNormal); bmp->ReleasePointer(); vd->BitmapOut(bmp, OpRect(0, 0, bmp->Width(), bmp->Height()), drawrect); CGContextRelease(context); widget->RemoveClipRect(); bitmap->Unlock(); bitmap->DecRef(); return TRUE; }
BOOL MacWidgetPainter::DrawSlider(const OpRect& rect, BOOL horizontal, double min, double max, double pos, BOOL highlighted, BOOL pressed_knob, OpRect& out_knob_position, OpPoint& out_start_track, OpPoint& out_end_track) { // Opera 11.50: We are going to use special skinned (non-toolkit) sliders for zoom sliders // so we are not drawing with our painter in that case if (!widget || widget->GetType() == OpTypedObject::WIDGET_TYPE_ZOOM_SLIDER) return FALSE; OpSkinElement *border_skin = widget->GetBorderSkin()->GetSkinElement(); if(!g_skin_manager->GetCurrentSkin() || (border_skin && !border_skin->IsNative())) { return IndpWidgetPainter::DrawSlider(rect, horizontal, min, max, pos, highlighted, pressed_knob, out_knob_position, out_start_track, out_end_track); } CGRect r = {{0, 0}, {rect.width, rect.height}}; CGContextRef context; OpBitmap* bitmap = NULL; int bmpwidth = rect.width; int bmpheight = rect.height; #ifdef PIXEL_SCALE_RENDERING_SUPPORT const PixelScaler& scaler = vd->GetVPScale(); bmpwidth = TO_DEVICE_PIXEL(scaler, bmpwidth); bmpheight = TO_DEVICE_PIXEL(scaler, bmpheight); #endif // PIXEL_SCALE_RENDERING_SUPPORT if(OpStatus::IsSuccess(OpBitmap::Create(&bitmap, bmpwidth, bmpheight, FALSE, TRUE, 0, 0, TRUE))) { int w = bitmap->Width(); int h = bitmap->Height(); int bpl = bitmap->GetBytesPerLine(); void *image_data = bitmap->GetPointer(OpBitmap::ACCESS_WRITEONLY); if (!image_data) { delete bitmap; return FALSE; } memset(image_data, 0, bpl*h); CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); CGBitmapInfo alpha = kCGBitmapByteOrderVegaInternal; context = CGBitmapContextCreate(image_data, w, h, 8, bpl, colorSpace, alpha); CGColorSpaceRelease(colorSpace); int win_height = rect.height; float scale = 1.0f; #ifdef PIXEL_SCALE_RENDERING_SUPPORT scale = TO_DEVICE_PIXEL(scaler, scale); #endif // PIXEL_SCALE_RENDERING_SUPPORT CGContextScaleCTM(context, scale, -scale); CGContextTranslateCTM(context, 0.0, -win_height); HIThemeTrackDrawInfo drawInfo; SInt32 thickness = 0; SInt32 shadow = 0; if (noErr == GetThemeMetric(kThemeMetricLargeProgressBarThickness, &thickness) && (noErr == GetThemeMetric(kThemeMetricProgressBarShadowOutset, &shadow))) { SInt32 progressHeight = thickness + shadow; if (horizontal) { if((r.size.height) > progressHeight) { float f = (r.size.height - progressHeight); r.origin.y += f / 2; r.size.height -= f; } } else { if((r.size.width) > progressHeight) { float f = (r.size.width - progressHeight); r.origin.x += f / 2; r.size.width -= f; } } } else { if (horizontal) { float f = (r.size.height / 4) - 1; r.origin.y += f / 2; r.size.height -= f; } else { float f = (r.size.width / 4) - 1; r.origin.x += f / 2; r.size.width -= f; } } drawInfo.version = 0; drawInfo.kind = kThemeSliderSmall; drawInfo.bounds = r; drawInfo.min = 0; drawInfo.max = NUMBER_OF_STEPS; if (widget->GetRTL()) drawInfo.value = (max - pos) / (max - min) * NUMBER_OF_STEPS; else drawInfo.value = (pos - min) / (max - min) * NUMBER_OF_STEPS; drawInfo.attributes = kThemeTrackShowThumb; if (horizontal) { drawInfo.attributes |= kThemeTrackHorizontal; } else { drawInfo.attributes |= kThemeTrackRightToLeft; } drawInfo.enableState = widget->IsEnabled() ? kThemeTrackActive : kThemeTrackInactive; drawInfo.trackInfo.slider.thumbDir = kThemeThumbPlain; drawInfo.trackInfo.slider.pressState = 0; if (highlighted) drawInfo.attributes |= kThemeTrackHasFocus; HIThemeDrawTrack(&drawInfo, NULL, context, kHIThemeOrientationNormal); HIShapeRef thumb_shape; HIRect thumb_bounds, track_bounds; HIThemeGetTrackThumbShape(&drawInfo, &thumb_shape); HIShapeGetBounds(thumb_shape, &thumb_bounds); HIThemeGetTrackBounds(&drawInfo, &track_bounds); CFRelease(thumb_shape); out_knob_position.Set(thumb_bounds.origin.x, thumb_bounds.origin.y, thumb_bounds.size.width, thumb_bounds.size.height); out_start_track.Set(track_bounds.origin.x, track_bounds.origin.y); out_end_track.Set(track_bounds.origin.x+track_bounds.size.width, track_bounds.origin.y+track_bounds.size.height); CGContextRelease(context); bitmap->ReleasePointer(); vd->BitmapOut(bitmap, OpRect(0, 0, bitmap->Width(), bitmap->Height()), rect); delete bitmap; } return TRUE; }