//--------------------------------------------------------------------------- void WtRubiksClockWidget::DrawRubiksClock( Wt::WPainter& painter, const int left, const int top, const int width, const int height, const RubiksClock * const clock, const bool front_side) { //Draw main clock ring { Wt::WPen pen = painter.pen(); pen.setColor(Wt::black); painter.setPen(pen); } { painter.setBrush( Wt::WBrush( Wt::WColor( front_side ? 127 : 96, front_side ? 127 : 96, 196))); } painter.drawEllipse( static_cast<double>(left), static_cast<double>(top), static_cast<double>(width), static_cast<double>(height)); //Draw the clocks and pegs { for (int y=0; y!=3; ++y) { for (int x=0; x!=3; ++x) { const boost::shared_ptr<RubiksClockDialWidget> w = (front_side ? clock->GetFrontTimes() : clock->GetBackTimes()).times[x][y]; WtDialWidget::DrawDial( painter, w->GetGeometry().GetX(), w->GetGeometry().GetY(), w->GetGeometry().GetWidth(), w->GetGeometry().GetHeight(), w->GetRubiksClockDial()->GetDial()); } } //Draw the pegs for (int y=0; y!=2; ++y) { for (int x=0; x!=2; ++x) { WtToggleButtonWidget::DrawToggleButton( painter, (front_side ? clock->GetFrontPegs() : clock->GetBackPegs()).pegs[x][y].get()); } } } }
void ribi::WtDialWidget::DrawDial( Wt::WPainter& painter, const int left, const int top, const int width, const int height, const Dial * const dial) { const double position = dial->GetPosition(); //Draw knob { Wt::WPen pen = painter.pen(); pen.setWidth(1); pen.setColor(Wt::WColor(0,0,0)); painter.setPen(pen); } painter.setBrush(Wt::WColor( dial->GetRed(), dial->GetGreen(), dial->GetBlue())); painter.drawEllipse(left+1,top+1,width-2,height-2); //Draw pointer const int midx = width / 2; const int midy = height / 2; const double ray = static_cast<double>(std::min( midx, midy )); const double two_pi = boost::math::constants::two_pi<double>(); const double angle = position * two_pi; const int pointerX = static_cast<int>( static_cast<double>(midx) + (std::sin(angle) * ray) ); const int pointerY = static_cast<int>( static_cast<double>(midy) - (std::cos(angle) * ray) ); { Wt::WPen pen = painter.pen(); pen.setWidth(4); painter.setPen(pen); } painter.drawLine(left+midx,top+midy,left+pointerX,top+pointerY); }
void ribi::WtToggleButtonWidget::DrawToggleButton( Wt::WPainter& painter, const int left, const int top, const int width, const int height, const ToggleButton * const button) { { Wt::WPen pen = painter.pen(); pen.setWidth(1); pen.setColor(Wt::WColor(0,0,0)); painter.setPen(pen); } painter.setBrush(Wt::WColor( button->GetRed(), button->GetGreen(), button->GetBlue())); //Draw base painter.drawArc( left + 0, top + (height * 1 / 3), width, height * 2 / 3, 180 * 16, 180 * 16); //Draw top painter.drawEllipse( left + 0, top + (button->IsPressed() ? (height * 1 / 3) - 2 : 0.0), width, height * 2 / 3); painter.drawLine( left + 1, top + (button->IsPressed() ? (height * 2 / 3) - 2 : (height * 1 / 3)), left + 1, top + (height * 2 / 3)); painter.drawLine( left + (width - 1), top + (button->IsPressed() ? (height * 2 / 3) - 2 : (height * 1 / 3)), left + width - 1, top + (height * 2 / 3)); }
void paintEvent(Wt::WPaintDevice *paintDevice) { Wt::WPainter painter(paintDevice); // Draw a grid of rectangles; each one in a different color. for (int row = 0; row < 6; row++) for (int col = 0; col < 6; col++) { // Generate a unique RGB color for each square. Only the red and // green values are modified; the blue channel has a fixed value. Wt::WBrush brush(Wt::WColor(255 - 42*row, 255 - 42*col, 0)); painter.fillRect(row*25, col*25, 25, 25, brush); } painter.translate(0, 160); // Draw a grid of circles similar to the above example but now using the // strokePath method. Wt::WPen pen; pen.setWidth(3); for (int row = 0; row < 6; row++) { for (int col = 0; col < 6; col++) { // Generate a unique RGB color for each circle. Only the green and // blue values are modified; the red channel has a fixed value. Wt::WPainterPath path; path.addEllipse(3 + col*25, 3 + row*25, 20, 20); pen.setColor(Wt::WColor(0, 255 - 42*row, 255 - 42*col)); painter.strokePath(path, pen); } } painter.translate(0, 160); // Transparency example with rectangles // Create a background composed of 4 stacked rectangles. painter.fillRect(0, 0, 150, 37.5, Wt::WBrush(Wt::yellow)); painter.fillRect(0, 37.5, 150, 37.5, Wt::WBrush(Wt::green)); painter.fillRect(0, 75, 150, 37.5, Wt::WBrush(Wt::blue)); painter.fillRect(0, 112.5, 150, 37.5, Wt::WBrush(Wt::red)); // On top of these draw semi transparent rectangles with increasing opacity for (int i = 0; i < 10; i++) { Wt::WBrush brush = Wt::WBrush(Wt::WColor(255, 255, 255, 255/10*i)); for (int j = 0; j < 4; j++) { Wt::WPainterPath path; path.addRect(5 + i*14, 5 + j*37.5, 14, 27.5); painter.fillPath(path, brush); } } painter.translate(0, 160); // Transparency example with circles // Create a square composed of four different colored squares. painter.fillRect(0, 0, 75, 75, Wt::WBrush(Wt::yellow)); painter.fillRect(75, 0, 75, 75, Wt::WBrush(Wt::green)); painter.fillRect(0, 75, 75, 75, Wt::WBrush(Wt::blue)); painter.fillRect(75, 75, 75, 75, Wt::WBrush(Wt::red)); // On top of these draw a set of semi-transparant white circles with // increasing diameter. The final result is a radial gradient. for (int i = 1; i < 8; i++) { Wt::WPainterPath path; path.addEllipse(75 - i*10, 75 - i*10, i*20, i*20); Wt::WBrush brush = Wt::WBrush(Wt::WColor(255, 255, 255, 50)); painter.fillPath(path, brush); } painter.translate(0, 170); // Gradient Brush example // Rectangle with a linear gradient from left top to right bottom painter.setPen(Wt::WPen(Wt::NoPen)); Wt::WGradient linGrad; linGrad.setLinearGradient(0, 0, 100, 150); linGrad.addColorStop(0, Wt::WColor(255, 0, 0, 255)); linGrad.addColorStop(0.5, Wt::WColor(0, 0, 255, 255)); linGrad.addColorStop(1, Wt::WColor(0, 255, 0, 255)); Wt::WBrush linearGradientBrush(linGrad); painter.setBrush(linearGradientBrush); painter.drawRect(0, 0, 100, 150); // Circle with a radial gradient Wt::WGradient radGrad; radGrad.setRadialGradient(170, 100, 50, 130, 130); radGrad.addColorStop(0.2, Wt::WColor(255, 0, 0, 255)); radGrad.addColorStop(0.9, Wt::WColor(0, 0, 255, 255)); radGrad.addColorStop(1, Wt::WColor(0, 0, 255, 0)); Wt::WBrush radialGradientBrush(radGrad); painter.setBrush(radialGradientBrush); painter.drawEllipse(120, 50, 100, 100); painter.translate(0, 170); // LineWidth example // You can use WPainter::drawLine() or WPainter::strokePath() to draw a // line. Using strokePath() you can draw thicker lines. // The line is centered on the path. In other words, the area that's drawn // extends to half the line width on either side of the path. Because // canvas coordinates do not directly reference pixels, you have to take // special care to obtain crisp horizontal and vertical lines. // All lines with an odd integer width thickness in the example below do // not appear crisp, because of the path's positioning. for (int i = 0; i < 11; i++) { Wt::WPainterPath path; path.moveTo(i*14, 0); path.lineTo(i*14, 150); pen = Wt::WPen(); pen.setWidth(i+1); painter.strokePath(path, pen); } painter.translate(160, 0); // LineWidth example with crisp lines // To obtain a crisp line for an odd integer width thickness line you have // to be very precise in your path creation, e.g. a 1.0 width line will // extend half a unit to either side of the path. for (int i = 0; i < 11; i++) { Wt::WPainterPath path; if (i % 2 == 0) { path.moveTo(i*14-0.5, 0); path.lineTo(i*14-0.5, 150); } else { path.moveTo(i*14, 0); path.lineTo(i*14, 150); } pen = Wt::WPen(); pen.setCapStyle(Wt::FlatCap); // Now, all lines will have equal length. pen.setWidth(i+1); painter.strokePath(path, pen); } painter.translate(-160, 170); // PenCapStyle example // The PenCapStyle can be FlatCap, SquareCap or RoundCap. // Start with drawing guides: Wt::WPainterPath guidePath; guidePath.moveTo(0, 10); guidePath.lineTo(150,10); guidePath.moveTo(0,140); guidePath.lineTo(150,140); pen = Wt::WPen(Wt::blue); painter.strokePath(guidePath, pen); // Draw lines with different cap styles // Create three parallel paths: std::vector<Wt::WPainterPath> paths; for (int i = 0; i < 3; i++) { Wt::WPainterPath path; path.moveTo(25+i*50, 10); path.lineTo(25+i*50, 140); paths.push_back(path); } pen = Wt::WPen(); pen.setWidth(20); pen.setCapStyle(Wt::FlatCap); painter.strokePath(paths[0], pen); pen = Wt::WPen(); pen.setWidth(20); pen.setCapStyle(Wt::SquareCap); painter.strokePath(paths[1], pen); pen = Wt::WPen(); pen.setWidth(20); pen.setCapStyle(Wt::RoundCap); painter.strokePath(paths[2], pen); painter.translate(0, 170); // PenJoinStyle example // The PenJoinStyle can be MiterJoin, BevelJoin or RoundJoin. // Create three parallel paths: paths.clear(); for (int i = 0; i < 3; i++) { Wt::WPainterPath path; path.moveTo(15, 5+i*40); path.lineTo(45, 45+i*40); path.lineTo(75, 5+i*40); path.lineTo(105,45+i*40); path.lineTo(135, 5+i*40); paths.push_back(path); } // Draw the first path with miter joins. // The connected segments are joined by extending their outside edges to // connect at a single point. pen = Wt::WPen(); pen.setWidth(20); pen.setJoinStyle(Wt::MiterJoin); painter.strokePath(paths[0], pen); // Draw the second path with bevel joins. // An additional triangular area is filled between the common endpoint of // connected segments and the separate outside rectangular corners of each // segment. pen = Wt::WPen(); pen.setWidth(20); pen.setJoinStyle(Wt::BevelJoin); painter.strokePath(paths[1], pen); // Draw the third path with round joins. // The corners of the shape are rounded off by filling an aditonal sector // of disc centered at the common endpoint of connected segments. The // radius of the rounded corners is equal to the line width. pen = Wt::WPen(); pen.setWidth(20); pen.setJoinStyle(Wt::RoundJoin); painter.strokePath(paths[2], pen); }
//--------------------------------------------------------------------------- void WtShapeGroupWidget::paintEvent(Wt::WPaintDevice *paintDevice) { Wt::WPainter painter(paintDevice); const int width = this->width().toPixels(); const int height = this->height().toPixels(); //Draw a background rectangle { Wt::WPen pen = painter.pen(); pen.setColor(Wt::WColor(1,1,1)); painter.setPen(pen); painter.setBrush(Wt::WBrush(Wt::WColor(254,254,254))); painter.drawRect(0.0,0.0,width,height); } if (m_v.empty()) return; const double mid_x = 0.5 * boost::numeric_cast<double>(width); const double mid_y = 0.5 * boost::numeric_cast<double>(height); const double ray_center = std::min(mid_x,mid_y); const double ray_group = 0.33 * ray_center; const double ray_member = 0.33 * ray_group; const int n_groups = boost::numeric_cast<double>(m_v.size()); for (int group=0; group!=n_groups; ++group) { //Draw the larger (group) circles first //Set the pen to black { Wt::WPen pen = painter.pen(); pen.setColor(Wt::WColor(1,1,1)); painter.setPen(pen); } const double f_group = (n_groups != 0 ? static_cast<double>(group) / static_cast<double>(n_groups) : 1.0); //Set the brush to the group's index { double r,g,b; Rainbow(f_group,r,g,b); painter.setBrush(Wt::WBrush(Wt::WColor(r*255.0,g*255.0,b*255.0))); } const double angle = 2.0 * M_PI * f_group; const double group_mid_x = mid_x + (std::sin(angle) * 0.66 * ray_center); const double group_mid_y = mid_y - (std::cos(angle) * 0.66 * ray_center); //Draw the group ellipse painter.drawEllipse( group_mid_x - ray_group, group_mid_y - ray_group, 2.0 * ray_group, 2.0 * ray_group); const std::vector<const Shape*>& members = m_v[group]; const int n_members = boost::numeric_cast<int>(members.size()); for (int member=0; member!=n_members;++member) { const double f_member = (n_members != 0 ? static_cast<double>(member) / static_cast<double>(n_members) : 1.0); const double angle = 2.0 * M_PI * f_member; const double member_mid_x = group_mid_x + (std::sin(angle) * 0.66 * ray_group); const double member_mid_y = group_mid_y - (std::cos(angle) * 0.66 * ray_group); //Draw the member his/her Shape ellipse WtShapeWidget::DrawShape(painter, member_mid_x - ray_member, member_mid_y - ray_member, 2.0 * ray_member, 2.0 * ray_member, members[member]); } } }