//---------------------------------------------------------------------------------------------------- void UISearchTextField::drawClearMark (CDrawContext* context) const { if (getText ().empty ()) return; SharedPointer<CGraphicsPath> path = owned (context->createGraphicsPath ()); if (path == 0) return; CRect r = getClearMarkRect (); CColor color (fontColor); color.alpha /= 2; context->setFillColor (color); context->setDrawMode (kAntiAliasing); context->drawEllipse (r, kDrawFilled); double h,s,v; color.toHSV (h, s, v); v = 1. - v; color.fromHSV (h, s, v); context->setFrameColor (color); context->setLineWidth (2.); r.inset (r.getWidth () / (M_PI * 2.) + 1, r.getHeight () / (M_PI * 2.) + 1); path->beginSubpath (r.getTopLeft ()); path->addLine (r.getBottomRight ()); path->beginSubpath (r.getBottomLeft ()); path->addLine (r.getTopRight ()); context->setDrawMode (kAntiAliasing|kNonIntegralMode); context->drawGraphicsPath (path, CDrawContext::kPathStroked); }
//----------------------------------------------------------------------------- void D2DDrawContext::drawEllipse (const CRect &_rect, const CDrawStyle drawStyle) { if (renderTarget == 0) return; D2DApplyClip ac (this); if (ac.isEmpty ()) return; CRect rect (_rect); if (currentState.drawMode.integralMode ()) pixelAllign (rect); CPoint center (rect.getTopLeft ()); center.offset (rect.getWidth () / 2., rect.getHeight () / 2.); D2D1_ELLIPSE ellipse; ellipse.point = makeD2DPoint (center); ellipse.radiusX = (FLOAT)(rect.getWidth () / 2.); ellipse.radiusY = (FLOAT)(rect.getHeight () / 2.); if (drawStyle == kDrawFilled || drawStyle == kDrawFilledAndStroked) { renderTarget->FillEllipse (ellipse, fillBrush); } if (drawStyle == kDrawStroked || drawStyle == kDrawFilledAndStroked) { renderTarget->DrawEllipse (ellipse, strokeBrush, (FLOAT)currentState.frameWidth, strokeStyle); } }
//----------------------------------------------------------------------------- void D2DDrawContext::drawEllipse (const CRect &_rect, const CDrawStyle drawStyle) { if (renderTarget) { CRect rect (_rect); rect.offset (currentState.offset.x, currentState.offset.y); rect.normalize (); D2DApplyClip clip (this); CPoint center (rect.getTopLeft ()); center.offset (rect.getWidth () / 2., rect.getHeight () / 2.); D2D1_ELLIPSE ellipse; ellipse.point = makeD2DPoint (center); ellipse.radiusX = (FLOAT)(rect.getWidth () / 2.); ellipse.radiusY = (FLOAT)(rect.getHeight () / 2.); if (drawStyle == kDrawFilled || drawStyle == kDrawFilledAndStroked) { renderTarget->FillEllipse (ellipse, fillBrush); } if (drawStyle == kDrawStroked || drawStyle == kDrawFilledAndStroked) { renderTarget->DrawEllipse (ellipse, strokeBrush, (FLOAT)currentState.frameWidth, strokeStyle); } } }
//----------------------------------------------------------------------------- ID2D1PathGeometry* D2DGraphicsPath::getPath (int32_t fillMode) { if (path == 0 || fillMode != currentPathFillMode) { dirty (); if (!SUCCEEDED (getD2DFactory ()->CreatePathGeometry (&path))) return 0; if (fillMode == -1) fillMode = 0; currentPathFillMode = fillMode; ID2D1GeometrySink* sink = 0; if (!SUCCEEDED (path->Open (&sink))) { path->Release (); path = 0; return 0; } sink->SetFillMode ((D2D1_FILL_MODE)fillMode); bool figureOpen = false; CPoint lastPos; for (ElementList::const_iterator it = elements.begin (); it != elements.end (); it++) { Element e = (*it); switch (e.type) { case Element::kArc: { bool clockwise = e.instruction.arc.clockwise; double startAngle = e.instruction.arc.startAngle; double endAngle = e.instruction.arc.endAngle; CRect o_r (e.instruction.arc.rect.left, e.instruction.arc.rect.top, e.instruction.arc.rect.right, e.instruction.arc.rect.bottom); CRect r (o_r); o_r.originize (); CPoint center = o_r.getCenter (); CPoint start; start.x = r.left + center.x + center.x * cos (radians (startAngle)); start.y = r.top + center.y + center.y * sin (radians (startAngle)); if (!figureOpen) { sink->BeginFigure (makeD2DPoint (start), D2D1_FIGURE_BEGIN_FILLED); figureOpen = true; } else if (lastPos != start) { sink->AddLine (makeD2DPoint (start)); } double sweepangle = endAngle - startAngle; if (clockwise) { // sweepangle positive while (sweepangle < 0.0) sweepangle += 360.0; while (sweepangle > 360.0) sweepangle -= 360.0; } else { // sweepangle negative while (sweepangle > 0.0) sweepangle -= 360.0; while (sweepangle < -360.0) sweepangle += 360.0; } CPoint endPoint; endPoint.x = r.left + center.x + center.x * cos (radians (endAngle)); endPoint.y = r.top + center.y + center.y * sin (radians (endAngle)); D2D1_ARC_SEGMENT arc; arc.size = makeD2DSize (r.getWidth ()/2., r.getHeight ()/2.); arc.rotationAngle = 0; arc.sweepDirection = clockwise ? D2D1_SWEEP_DIRECTION_CLOCKWISE : D2D1_SWEEP_DIRECTION_COUNTER_CLOCKWISE; arc.point = makeD2DPoint (endPoint); arc.arcSize = fabs(sweepangle) <= 180. ? D2D1_ARC_SIZE_SMALL : D2D1_ARC_SIZE_LARGE; sink->AddArc (arc); lastPos = endPoint; break; } case Element::kEllipse: { CRect r (e.instruction.rect.left, e.instruction.rect.top, e.instruction.rect.right, e.instruction.rect.bottom); CPoint top (r.getTopLeft ()); top.x += r.getWidth () / 2.; CPoint bottom (r.getBottomLeft ()); bottom.x += r.getWidth () / 2.; if (figureOpen && lastPos != CPoint (e.instruction.rect.left, e.instruction.rect.top)) { sink->EndFigure (D2D1_FIGURE_END_OPEN); figureOpen = false; } if (!figureOpen) { sink->BeginFigure (makeD2DPoint (top), D2D1_FIGURE_BEGIN_FILLED); figureOpen = true; } D2D1_ARC_SEGMENT arc = D2D1::ArcSegment (makeD2DPoint (bottom), D2D1::SizeF ((FLOAT)r.getWidth ()/2.f, (FLOAT)r.getHeight ()/2.f), 180.f, D2D1_SWEEP_DIRECTION_CLOCKWISE, D2D1_ARC_SIZE_SMALL); sink->AddArc (arc); arc.point = makeD2DPoint (top); sink->AddArc (arc); lastPos = top; break; } case Element::kRect: { D2D1_POINT_2F points[4] = { {(FLOAT)e.instruction.rect.right, (FLOAT)e.instruction.rect.top}, {(FLOAT)e.instruction.rect.right, (FLOAT)e.instruction.rect.bottom}, {(FLOAT)e.instruction.rect.left, (FLOAT)e.instruction.rect.bottom}, {(FLOAT)e.instruction.rect.left, (FLOAT)e.instruction.rect.top} }; if (figureOpen && lastPos != CPoint (e.instruction.rect.left, e.instruction.rect.top)) { sink->EndFigure (D2D1_FIGURE_END_OPEN); figureOpen = false; } if (figureOpen == false) { sink->BeginFigure (points[3], D2D1_FIGURE_BEGIN_FILLED); figureOpen = true; } sink->AddLine (points[0]); sink->AddLine (points[1]); sink->AddLine (points[2]); sink->AddLine (points[3]); lastPos = CPoint (e.instruction.rect.left, e.instruction.rect.top); break; } case Element::kLine: { if (figureOpen) { D2D1_POINT_2F end = {(FLOAT)e.instruction.point.x, (FLOAT)e.instruction.point.y}; sink->AddLine (end); lastPos = CPoint (e.instruction.point.x, e.instruction.point.y); } break; } case Element::kBezierCurve: { if (figureOpen) { D2D1_POINT_2F control1 = {(FLOAT)e.instruction.curve.control1.x, (FLOAT)e.instruction.curve.control1.y}; D2D1_POINT_2F control2 = {(FLOAT)e.instruction.curve.control2.x, (FLOAT)e.instruction.curve.control2.y}; D2D1_POINT_2F end = {(FLOAT)e.instruction.curve.end.x, (FLOAT)e.instruction.curve.end.y}; D2D1_BEZIER_SEGMENT bezier = D2D1::BezierSegment (control1, control2, end); sink->AddBezier (bezier); lastPos = CPoint (e.instruction.curve.end.x, e.instruction.curve.end.y); } break; } case Element::kBeginSubpath: { if (figureOpen) sink->EndFigure (D2D1_FIGURE_END_OPEN); D2D1_POINT_2F start = {(FLOAT)e.instruction.point.x, (FLOAT)e.instruction.point.y}; sink->BeginFigure (start, D2D1_FIGURE_BEGIN_FILLED); figureOpen = true; lastPos = CPoint (e.instruction.point.x, e.instruction.point.y); break; } case Element::kCloseSubpath: { if (figureOpen) { sink->EndFigure (D2D1_FIGURE_END_CLOSED); figureOpen = false; } break; } } } if (figureOpen) sink->EndFigure (D2D1_FIGURE_END_OPEN); HRESULT res = sink->Close (); if (!SUCCEEDED (res)) { path->Release (); path = 0; } sink->Release (); } return path; }
//---------------------------------------------------------------------------------------------------- void UIColorSlider::updateBackground (CDrawContext* context) { double scaleFactor = context->getScaleFactor (); SharedPointer<COffscreenContext> offscreen = owned (COffscreenContext::create (getFrame (), getWidth (), getHeight (), scaleFactor)); if (offscreen) { const int32_t kNumPoints = (style <= kLightness) ? 360 : 256; CCoord width = std::floor (getWidth () + 0.5); offscreen->beginDraw (); offscreen->setDrawMode (kAliasing); CCoord minWidth = 1. / scaleFactor; CCoord widthPerColor = width / static_cast<double> (kNumPoints - 1); CRect r; r.setHeight (getHeight ()); r.setWidth (widthPerColor < minWidth ? minWidth : (std::floor (widthPerColor * scaleFactor + 0.5) / scaleFactor)); r.offset (-r.getWidth (), 0); offscreen->setLineWidth (minWidth); for (int32_t i = 0; i < kNumPoints; i++) { CCoord x = std::floor (widthPerColor * i * scaleFactor + 0.5) / scaleFactor; if (x > r.right || i == kNumPoints -1) { CColor c = color->base (); switch (style) { case kRed: { c.red = (uint8_t)i; break; } case kGreen: { c.green = (uint8_t)i; break; } case kBlue: { c.blue = (uint8_t)i; break; } case kAlpha: { c.alpha = (uint8_t)i; break; } case kHue: { double hue = (static_cast<double> (i) / static_cast<double> (kNumPoints)) * 360.; c.fromHSL (hue, color->getSaturation (), color->getLightness ()); break; } case kSaturation: { double sat = (static_cast<double> (i) / static_cast<double> (kNumPoints)); c.fromHSL (color->getHue (), sat, color->getLightness ()); break; } case kLightness: { double light = (static_cast<double> (i) / static_cast<double> (kNumPoints)); c.fromHSL (color->getHue (), color->getSaturation (), light); break; } } offscreen->setFrameColor (c); CCoord next = r.left + widthPerColor; while (r.left < next) { offscreen->drawLine (r.getTopLeft (), r.getBottomLeft ()); r.offset (minWidth, 0); } } } offscreen->drawLine (r.getTopLeft (), r.getBottomLeft ()); offscreen->endDraw (); setBackground (offscreen->getBitmap ()); } if (getHandle () == 0) { offscreen = owned (COffscreenContext::create (getFrame (), 7, getHeight (), context->getScaleFactor ())); if (offscreen) { offscreen->beginDraw (); offscreen->setFrameColor (kBlackCColor); offscreen->setLineWidth (1); offscreen->setDrawMode (kAliasing); CRect r (0, 0, 7, getHeight ()); offscreen->drawRect (r, kDrawStroked); r.inset (1, 1); offscreen->setFrameColor (kWhiteCColor); offscreen->drawRect (r, kDrawStroked); offscreen->endDraw (); setHandle (offscreen->getBitmap ()); } } }
//------------------------------------------------------------------------ void CTextButton::draw (CDrawContext* context) { bool highlight = value > 0.5 ? true : false; context->setDrawMode (kAntiAliasing); context->setLineWidth (frameWidth); context->setLineStyle (CLineStyle (CLineStyle::kLineCapRound, CLineStyle::kLineJoinRound)); context->setFrameColor (highlight ? frameColorHighlighted : frameColor); CRect r (getViewSize ()); r.inset (frameWidth / 2., frameWidth / 2.); CGraphicsPath* path = getPath (context); if (path) { CColor color1 = highlight ? gradientStartColorHighlighted : gradientStartColor; CColor color2 = highlight ? gradientEndColorHighlighted : gradientEndColor; CGradient* gradient = path->createGradient (0.2, 1, color1, color2); if (gradient) { context->fillLinearGradient (path, *gradient, r.getTopLeft (), r.getBottomLeft (), false); gradient->forget (); } else { context->setFillColor (highlight ? gradientStartColorHighlighted : gradientStartColor); context->drawGraphicsPath (path, CDrawContext::kPathFilled); } context->drawGraphicsPath (path, CDrawContext::kPathStroked); } else { context->setFillColor (highlight ? gradientStartColorHighlighted : gradientStartColor); context->drawRect (getViewSize (), kDrawFilledAndStroked); } CRect titleRect = getViewSize (); titleRect.inset (frameWidth / 2., frameWidth / 2.); CBitmap* iconToDraw = highlight ? (iconHighlighted ? iconHighlighted : icon) : (icon ? icon : iconHighlighted); if (iconToDraw) { CRect iconRect (0, 0, iconToDraw->getWidth (), iconToDraw->getHeight ()); iconRect.offset (titleRect.left, titleRect.top); switch (iconPosition) { case kLeft: { iconRect.offset (textMargin, titleRect.getHeight () / 2. - iconRect.getHeight () / 2.); titleRect.left = iconRect.right; titleRect.right -= textMargin; if (getTextAlignment () == kLeftText) titleRect.left += textMargin; break; } case kRight: { iconRect.offset (titleRect.getWidth () - (textMargin + iconRect.getWidth ()), titleRect.getHeight () / 2. - iconRect.getHeight () / 2.); titleRect.right = iconRect.left; titleRect.left += textMargin; if (getTextAlignment () == kRightText) titleRect.right -= textMargin; break; } case kCenterAbove: { iconRect.offset (titleRect.getWidth () / 2. - iconRect.getWidth () / 2., 0); if (title.size () > 0) { iconRect.offset (0, titleRect.getHeight () / 2. - (iconRect.getHeight () / 2. + (textMargin + font->getSize ()) / 2.)); titleRect.top = iconRect.bottom + textMargin; titleRect.setHeight (font->getSize ()); if (getTextAlignment () == kLeftText) titleRect.left += textMargin; else if (getTextAlignment () == kRightText) titleRect.right -= textMargin; } else { iconRect.offset (0, titleRect.getHeight () / 2. - iconRect.getHeight () / 2.); } break; } case kCenterBelow: { iconRect.offset (titleRect.getWidth () / 2. - iconRect.getWidth () / 2., 0); if (title.size () > 0) { iconRect.offset (0, titleRect.getHeight () / 2. - (iconRect.getHeight () / 2.) + (textMargin + font->getSize ()) / 2.); titleRect.top = iconRect.top - (textMargin + font->getSize ()); titleRect.setHeight (font->getSize ()); if (getTextAlignment () == kLeftText) titleRect.left += textMargin; else if (getTextAlignment () == kRightText) titleRect.right -= textMargin; } else { iconRect.offset (0, titleRect.getHeight () / 2. - iconRect.getHeight () / 2.); } break; } } context->drawBitmap (iconToDraw, iconRect); } else { if (getTextAlignment () == kLeftText) titleRect.left += textMargin; else if (getTextAlignment () == kRightText) titleRect.right -= textMargin; } if (title.size () > 0) { context->setFont (font); context->setFontColor (highlight ? textColorHighlighted : textColor); context->drawString (title.c_str (), titleRect, horiTxtAlign); } setDirty (false); }