1 /* 2 * Copyright 2011, Haiku. 3 * Distributed under the terms of the MIT License. 4 * 5 * Authors: 6 * Philippe Houdoin 7 */ 8 9 10 #include "TestPageView.h" 11 12 #include <math.h> 13 14 #include <AffineTransform.h> 15 #include <Catalog.h> 16 #include <Font.h> 17 #include <GradientLinear.h> 18 #include <GradientRadial.h> 19 #include <GridLayoutBuilder.h> 20 #include <GroupLayoutBuilder.h> 21 #include <LayoutUtils.h> 22 #include <TextView.h> 23 #include <Shape.h> 24 #include <String.h> 25 #include <StringView.h> 26 27 #include "PrinterListView.h" 28 29 30 #undef B_TRANSLATION_CONTEXT 31 #define B_TRANSLATION_CONTEXT "TestPageView" 32 33 34 // #pragma mark LeafView 35 36 37 // path data for the leaf shape 38 static const BPoint kLeafBegin(56.24793f, 15.46287f); 39 static BPoint kLeafCurves[][3] = { 40 { BPoint(61.14, 28.89), BPoint(69.78, 38.25), BPoint(83.48, 44.17) }, 41 { BPoint(99.46, 37.52), BPoint(113.27, 29.61), BPoint(134.91, 30.86) }, 42 { BPoint(130.58, 36.53), BPoint(126.74, 42.44), BPoint(123.84, 48.81) }, 43 { BPoint(131.81, 42.22), BPoint(137.53, 38.33), BPoint(144.37, 33.10) }, 44 { BPoint(169.17, 23.55), BPoint(198.90, 15.55), BPoint(232.05, 10.51) }, 45 { BPoint(225.49, 18.37), BPoint(219.31, 28.17), BPoint(217.41, 40.24) }, 46 { BPoint(227.70, 26.60), BPoint(239.97, 14.63), BPoint(251.43, 8.36) }, 47 { BPoint(288.89, 9.12), BPoint(322.73, 14.33), BPoint(346.69, 31.67) }, 48 { BPoint(330.49, 37.85), BPoint(314.36, 44.25), BPoint(299.55, 54.17) }, 49 { BPoint(292.48, 52.54), BPoint(289.31, 49.70), BPoint(285.62, 47.03) }, 50 { BPoint(283.73, 54.61), BPoint(284.46, 57.94), BPoint(285.62, 60.60) }, 51 { BPoint(259.78, 76.14), BPoint(233.24, 90.54), BPoint(202.41, 98.10) }, 52 { BPoint(194.43, 95.36), BPoint(185.96, 92.39), BPoint(179.63, 88.33) }, 53 { BPoint(180.15, 94.75), BPoint(182.73, 99.76), BPoint(185.62, 104.53) }, 54 { BPoint(154.83, 119.46), BPoint(133.21, 118.97), BPoint(125.62, 94.88) }, 55 { BPoint(124.70, 98.79), BPoint(124.11, 103.67), BPoint(124.19, 110.60) }, 56 { BPoint(116.42, 111.81), BPoint(85.82, 99.60), BPoint(83.25, 51.96) }, 57 { BPoint(62.50, 42.57), BPoint(58.12, 33.18), BPoint(50.98, 23.81) } }; 58 static const int kNumLeafCurves = sizeof(kLeafCurves) / sizeof(kLeafCurves[0]); 59 static const float kLeafWidth = 372.f; 60 static const float kLeafHeight = 121.f; 61 62 63 class LeafView : public BView { 64 public: 65 LeafView(); 66 virtual void Draw(BRect updateRect); 67 }; 68 69 70 LeafView::LeafView() 71 : 72 BView("leafview", B_WILL_DRAW | B_FULL_UPDATE_ON_RESIZE) 73 { 74 SetViewColor(255, 255, 255); 75 } 76 77 78 void 79 LeafView::Draw(BRect updateRect) 80 { 81 float scale = Bounds().Width() / kLeafWidth; 82 BAffineTransform transform; 83 transform.ScaleBy(scale); 84 85 // BGradientRadial gradient(BPoint(kLeafWidth * 0.75, kLeafHeight * 1.5), 86 // kLeafWidth * 2); 87 BGradientLinear gradient(B_ORIGIN, 88 transform.Apply(BPoint(kLeafWidth, kLeafHeight))); 89 rgb_color lightBlue = make_color(6, 169, 255); 90 rgb_color darkBlue = make_color(0, 50, 126); 91 gradient.AddColor(darkBlue, 0.0); 92 gradient.AddColor(lightBlue, 255.0); 93 94 // build leaf shape 95 BShape leafShape; 96 leafShape.MoveTo(transform.Apply(kLeafBegin)); 97 for (int i = 0; i < kNumLeafCurves; ++i) { 98 BPoint controlPoints[3]; 99 for (int j = 0; j < 3; ++j) 100 controlPoints[j] = transform.Apply(kLeafCurves[i][j]); 101 leafShape.BezierTo(controlPoints); 102 } 103 leafShape.Close(); 104 105 PushState(); 106 SetDrawingMode(B_OP_ALPHA); 107 SetHighColor(0, 0, 0, 50); 108 for (int i = 2; i >= 0; --i) { 109 SetOrigin(i * 0.1, i * 0.3); 110 SetPenSize(i * 2); 111 StrokeShape(&leafShape); 112 } 113 PopState(); 114 115 FillShape(&leafShape, gradient); 116 } 117 118 119 // #pragma mark - 120 121 122 class RadialLinesView : public BView { 123 public: 124 RadialLinesView(); 125 126 virtual void Draw(BRect updateRect); 127 128 virtual bool HasHeightForWidth() { return true; } 129 virtual void GetHeightForWidth(float width, float* min, 130 float* max, float* preferred); 131 }; 132 133 134 RadialLinesView::RadialLinesView() 135 : BView("radiallinesview", B_WILL_DRAW | B_FULL_UPDATE_ON_RESIZE) 136 { 137 SetViewColor(255, 255, 255); 138 } 139 140 141 void 142 RadialLinesView::GetHeightForWidth(float width, 143 float* min, float* max, float* preferred) 144 { 145 // Enforce a width/height ratio of 1 146 147 if (min) 148 *min = width; 149 150 if (max) 151 *max = width; 152 153 if (preferred) 154 *preferred = width; 155 } 156 157 158 void 159 RadialLinesView::Draw(BRect updateRect) 160 { 161 const rgb_color black = { 0, 0, 0, 255 }; 162 const int angleStep = 4; 163 164 BRect rect(Bounds()); 165 float size = rect.Width(); 166 if (size > rect.Height()) 167 size = rect.Height(); 168 size *= 0.45; // leave 10% of margin 169 170 BPoint center(rect.Width() / 2, rect.Height() / 2); 171 172 BeginLineArray(360 / angleStep); 173 for (int i = 0; i < 360; i += angleStep) { 174 double angle = i * M_PI / 180; 175 BPoint pt(size * cos(angle), size * sin(angle)); 176 AddLine(center, center + pt, black); 177 } 178 EndLineArray(); 179 } 180 181 182 // #pragma mark - 183 184 185 static const struct { 186 const char* name; 187 rgb_color color; 188 } kColorGradients[] = { 189 { B_TRANSLATE_MARK("Red"), {255, 0, 0, 255} }, 190 { B_TRANSLATE_MARK("Green"), {0, 255, 0, 255} }, 191 { B_TRANSLATE_MARK("Blue"), {0, 0, 255, 255} }, 192 { B_TRANSLATE_MARK("Yellow"), {255, 255, 0, 255} }, 193 { B_TRANSLATE_MARK("Magenta"), {255, 0, 255, 255} }, 194 { B_TRANSLATE_MARK("Cyan"), {0, 255, 255, 255} }, 195 { B_TRANSLATE_MARK("Black"), {0, 0, 0, 255} } 196 }; 197 static const int kNumColorGradients = sizeof(kColorGradients) 198 / sizeof(kColorGradients[0]); 199 200 201 class ColorGradientView : public BView { 202 public: 203 ColorGradientView(rgb_color color); 204 virtual void Draw(BRect updateRect); 205 206 private: 207 rgb_color fColor; 208 }; 209 210 211 ColorGradientView::ColorGradientView(rgb_color color) 212 : 213 BView("colorgradientview", B_WILL_DRAW | B_FULL_UPDATE_ON_RESIZE), 214 fColor(color) 215 { 216 } 217 218 219 void 220 ColorGradientView::Draw(BRect updateRect) 221 { 222 BRect rect(Bounds()); 223 224 BGradientLinear gradient(rect.LeftTop(), rect.RightBottom()); 225 rgb_color white = make_color(255, 255, 255); 226 gradient.AddColor(white, 0.0); 227 gradient.AddColor(fColor, 255.0); 228 229 FillRect(rect, gradient); 230 StrokeRect(rect); 231 } 232 233 234 // #pragma mark - 235 236 237 TestPageView::TestPageView(BRect frame, PrinterItem* printer) 238 : BView(frame, "testpage", B_FOLLOW_ALL, 239 B_DRAW_ON_CHILDREN | B_FULL_UPDATE_ON_RESIZE), 240 fPrinter(printer) 241 { 242 SetViewColor(255, 255, 255); 243 } 244 245 246 void 247 TestPageView::AttachedToWindow() 248 { 249 BTextView* statusView = new BTextView("statusView", 250 be_plain_font, NULL, B_WILL_DRAW); 251 252 statusView->SetInsets(10, 10, 10, 10); 253 statusView->MakeEditable(false); 254 statusView->MakeSelectable(false); 255 256 const char* title = B_TRANSLATE("Test page"); 257 BString text; 258 text << title << "\n\n"; 259 text << B_TRANSLATE( 260 "Printer: %printer_name%\n" 261 "Driver: %driver%\n"); 262 263 text.ReplaceFirst("%printer_name%", fPrinter->Name()); 264 text.ReplaceFirst("%driver%", fPrinter->Driver()); 265 if (strlen(fPrinter->Transport()) > 0) { 266 text << B_TRANSLATE("Transport: %transport% %transport_address%"); 267 268 text.ReplaceFirst("%transport%", fPrinter->Transport()); 269 text.ReplaceFirst("%transport_address%", fPrinter->TransportAddress()); 270 } 271 272 statusView->SetText(text.String()); 273 BFont font; 274 statusView->SetStylable(true); 275 statusView->GetFont(&font); 276 font.SetFace(B_BOLD_FACE); 277 font.SetSize(font.Size() * 1.7); 278 statusView->SetFontAndColor(0, strlen(title), &font); 279 280 BGridLayoutBuilder gradients(2.0); 281 gradients.View()->SetViewColor(B_TRANSPARENT_COLOR); 282 283 for (int i = 0; i < kNumColorGradients; ++i) { 284 BStringView* label = new BStringView( 285 kColorGradients[i].name, 286 B_TRANSLATE(kColorGradients[i].name)); 287 // label->SetAlignment(B_ALIGN_RIGHT); 288 gradients.Add(label, 0, i); 289 gradients.Add(new ColorGradientView(kColorGradients[i].color), 1, i); 290 } 291 292 SetLayout(new BGroupLayout(B_HORIZONTAL)); 293 AddChild(BGroupLayoutBuilder(B_VERTICAL, 0) 294 .Add(BGroupLayoutBuilder(B_HORIZONTAL, 0) 295 .Add(statusView) 296 .Add(new LeafView()) 297 ) 298 .Add(BGroupLayoutBuilder(B_HORIZONTAL, 0) 299 .Add(gradients, 0.60) 300 .Add(new RadialLinesView(), 0.40) 301 ) 302 .AddGlue() 303 .End() 304 ); 305 306 // set layout background color to transparent instead 307 // of default UI panel color 308 ChildAt(0)->SetViewColor(B_TRANSPARENT_COLOR); 309 } 310 311 312 void 313 TestPageView::DrawAfterChildren(BRect updateRect) 314 { 315 // Draw corners marks 316 317 float width = Bounds().Width(); 318 float height = Bounds().Height(); 319 float minDimension = MIN(width, height); 320 321 float size = minDimension * 0.05; 322 323 SetPenSize(3.0); 324 325 BPoint pt = Bounds().LeftTop(); 326 StrokeLine(pt, BPoint(pt.x + size, pt.y)); 327 StrokeLine(pt, BPoint(pt.x, pt.y + size)); 328 329 pt = Bounds().RightTop(); 330 StrokeLine(pt, BPoint(pt.x - size, pt.y)); 331 StrokeLine(pt, BPoint(pt.x, pt.y + size)); 332 333 pt = Bounds().RightBottom(); 334 StrokeLine(pt, BPoint(pt.x - size, pt.y)); 335 StrokeLine(pt, BPoint(pt.x, pt.y - size)); 336 337 pt = Bounds().LeftBottom(); 338 StrokeLine(pt, BPoint(pt.x + size, pt.y)); 339 StrokeLine(pt, BPoint(pt.x, pt.y - size)); 340 } 341