comparison Applications/Samples/SingleFrameEditorApplication.h @ 357:ec4ad6c5eb99 am-2

avoid breaking class hierarchy
author Sebastien Jodogne <s.jodogne@gmail.com>
date Mon, 29 Oct 2018 17:59:04 +0100
parents 885f0a5eaa49
children b8eeb49f3e65
comparison
equal deleted inserted replaced
356:885f0a5eaa49 357:ec4ad6c5eb99
1273 } 1273 }
1274 1274
1275 return false; 1275 return false;
1276 } 1276 }
1277 1277
1278 void DrawControls(CairoSurface& surface, 1278 void DrawControls(CairoContext& context,
1279 const ViewportGeometry& view) 1279 double zoom)
1280 { 1280 {
1281 if (hasSelection_) 1281 if (hasSelection_)
1282 { 1282 {
1283 Bitmaps::const_iterator bitmap = bitmaps_.find(selectedBitmap_); 1283 Bitmaps::const_iterator bitmap = bitmaps_.find(selectedBitmap_);
1284 1284
1285 if (bitmap != bitmaps_.end()) 1285 if (bitmap != bitmaps_.end())
1286 { 1286 {
1287 CairoContext context(surface);
1288
1289 context.SetSourceColor(255, 0, 0); 1287 context.SetSourceColor(255, 0, 0);
1290 view.ApplyTransform(context); 1288 //view.ApplyTransform(context);
1291 bitmap->second->DrawBorders(context, view.GetZoom()); 1289 bitmap->second->DrawBorders(context, zoom);
1292 } 1290 }
1293 } 1291 }
1294 } 1292 }
1295 1293
1296 1294
1972 throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError); 1970 throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError);
1973 } 1971 }
1974 1972
1975 virtual void MouseUp() 1973 virtual void MouseUp()
1976 { 1974 {
1977 if (accessor_.IsValid()) 1975 if (accessor_.IsValid() &&
1976 accessor_.GetBitmap().IsResizeable())
1978 { 1977 {
1979 undoRedoStack_.Add(new UndoRedoCommand(*this)); 1978 undoRedoStack_.Add(new UndoRedoCommand(*this));
1980 } 1979 }
1981 } 1980 }
1982 1981
2440 public WorldSceneWidget, 2439 public WorldSceneWidget,
2441 public IObservable, 2440 public IObservable,
2442 public IObserver 2441 public IObserver
2443 { 2442 {
2444 private: 2443 private:
2445 BitmapStack& stack_; 2444 BitmapStack& stack_;
2446 BitmapStackInteractor myInteractor_; 2445 BitmapStackInteractor myInteractor_;
2447 2446 std::auto_ptr<Orthanc::Image> floatBuffer_;
2448 protected: 2447 std::auto_ptr<CairoSurface> cairoBuffer_;
2449 virtual Extent2D GetSceneExtent() 2448
2450 { 2449 virtual bool RenderInternal(unsigned int width,
2451 return stack_.GetSceneExtent(); 2450 unsigned int height,
2452 } 2451 ImageInterpolation interpolation)
2453 2452 {
2454 virtual bool RenderScene(CairoContext& context,
2455 const ViewportGeometry& view)
2456 {
2457 // "Render()" has been replaced
2458 throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError);
2459 }
2460
2461 public:
2462 BitmapStackWidget(MessageBroker& broker,
2463 BitmapStack& stack,
2464 const std::string& name) :
2465 WorldSceneWidget(name),
2466 IObservable(broker),
2467 IObserver(broker),
2468 stack_(stack),
2469 myInteractor_(stack_)
2470 {
2471 stack.RegisterObserverCallback(new Callable<BitmapStackWidget, BitmapStack::GeometryChangedMessage>(*this, &BitmapStackWidget::OnGeometryChanged));
2472 stack.RegisterObserverCallback(new Callable<BitmapStackWidget, BitmapStack::ContentChangedMessage>(*this, &BitmapStackWidget::OnContentChanged));
2473
2474 SetInteractor(myInteractor_);
2475 }
2476
2477 void OnGeometryChanged(const BitmapStack::GeometryChangedMessage& message)
2478 {
2479 printf("Geometry has changed\n");
2480 FitContent();
2481 }
2482
2483 void OnContentChanged(const BitmapStack::ContentChangedMessage& message)
2484 {
2485 printf("Content has changed\n");
2486 NotifyContentChanged();
2487 }
2488
2489 virtual bool Render(Orthanc::ImageAccessor& target)
2490 {
2491 Orthanc::Image buffer(Orthanc::PixelFormat_Float32, target.GetWidth(),
2492 target.GetHeight(), false);
2493
2494 // TODO => rendering quality
2495 stack_.Render(buffer, GetView(), ImageInterpolation_Nearest);
2496 //stack_.Render(buffer, GetView(), ImageInterpolation_Bilinear);
2497
2498 // As in GrayscaleFrameRenderer => TODO MERGE?
2499
2500 float windowCenter, windowWidth; 2453 float windowCenter, windowWidth;
2501 stack_.GetWindowingWithDefault(windowCenter, windowWidth); 2454 stack_.GetWindowingWithDefault(windowCenter, windowWidth);
2502 2455
2503 float x0 = windowCenter - windowWidth / 2.0f; 2456 float x0 = windowCenter - windowWidth / 2.0f;
2504 float x1 = windowCenter + windowWidth / 2.0f; 2457 float x1 = windowCenter + windowWidth / 2.0f;
2505 2458
2506 if (windowWidth >= 0.001f) // Avoid division by zero at (*) 2459 if (windowWidth <= 0.001f) // Avoid division by zero at (*)
2507 { 2460 {
2508 const unsigned int width = target.GetWidth(); 2461 return false;
2509 const unsigned int height = target.GetHeight(); 2462 }
2510 2463 else
2464 {
2465 if (floatBuffer_.get() == NULL ||
2466 floatBuffer_->GetWidth() != width ||
2467 floatBuffer_->GetHeight() != height)
2468 {
2469 floatBuffer_.reset(new Orthanc::Image(Orthanc::PixelFormat_Float32, width, height, false));
2470 }
2471
2472 if (cairoBuffer_.get() == NULL ||
2473 cairoBuffer_->GetWidth() != width ||
2474 cairoBuffer_->GetHeight() != height)
2475 {
2476 cairoBuffer_.reset(new CairoSurface(width, height));
2477 }
2478
2479 stack_.Render(*floatBuffer_, GetView(), interpolation);
2480
2481 // TODO => rendering quality
2482
2483 // As in GrayscaleFrameRenderer => TODO MERGE?
2484
2485 Orthanc::ImageAccessor target;
2486 cairoBuffer_->GetAccessor(target);
2487
2511 for (unsigned int y = 0; y < height; y++) 2488 for (unsigned int y = 0; y < height; y++)
2512 { 2489 {
2513 const float* p = reinterpret_cast<const float*>(buffer.GetConstRow(y)); 2490 const float* p = reinterpret_cast<const float*>(floatBuffer_->GetConstRow(y));
2514 uint8_t* q = reinterpret_cast<uint8_t*>(target.GetRow(y)); 2491 uint8_t* q = reinterpret_cast<uint8_t*>(target.GetRow(y));
2515 2492
2516 for (unsigned int x = 0; x < width; x++, p++, q += 4) 2493 for (unsigned int x = 0; x < width; x++, p++, q += 4)
2517 { 2494 {
2518 uint8_t v = 0; 2495 uint8_t v = 0;
2540 q[1] = v; 2517 q[1] = v;
2541 q[2] = v; 2518 q[2] = v;
2542 q[3] = 255; 2519 q[3] = 255;
2543 } 2520 }
2544 } 2521 }
2522
2523 return true;
2524 }
2525 }
2526
2527
2528 protected:
2529 virtual Extent2D GetSceneExtent()
2530 {
2531 return stack_.GetSceneExtent();
2532 }
2533
2534 virtual bool RenderScene(CairoContext& context,
2535 const ViewportGeometry& view)
2536 {
2537 ImageInterpolation interpolation = ImageInterpolation_Nearest; // TODO PARAMETER?
2538
2539 cairo_t* cr = context.GetObject();
2540
2541 if (RenderInternal(context.GetWidth(), context.GetHeight(), interpolation))
2542 {
2543 // https://www.cairographics.org/FAQ/#paint_from_a_surface
2544 cairo_save(cr);
2545 cairo_identity_matrix(cr);
2546 cairo_set_source_surface(cr, cairoBuffer_->GetObject(), 0, 0);
2547 cairo_paint(cr);
2548 cairo_restore(cr);
2549 }
2550 else
2551 {
2552 // https://www.cairographics.org/FAQ/#clear_a_surface
2553 context.SetSourceColor(0, 0, 0);
2554 cairo_paint(cr);
2555 }
2556
2557 stack_.DrawControls(context, view.GetZoom());
2558
2559 return true;
2560 }
2561
2562 public:
2563 BitmapStackWidget(MessageBroker& broker,
2564 BitmapStack& stack,
2565 const std::string& name) :
2566 WorldSceneWidget(name),
2567 IObservable(broker),
2568 IObserver(broker),
2569 stack_(stack),
2570 myInteractor_(stack_)
2571 {
2572 stack.RegisterObserverCallback(new Callable<BitmapStackWidget, BitmapStack::GeometryChangedMessage>(*this, &BitmapStackWidget::OnGeometryChanged));
2573 stack.RegisterObserverCallback(new Callable<BitmapStackWidget, BitmapStack::ContentChangedMessage>(*this, &BitmapStackWidget::OnContentChanged));
2574
2575 SetInteractor(myInteractor_);
2576 }
2577
2578 void OnGeometryChanged(const BitmapStack::GeometryChangedMessage& message)
2579 {
2580 printf("Geometry has changed\n");
2581 FitContent();
2582 }
2583
2584 void OnContentChanged(const BitmapStack::ContentChangedMessage& message)
2585 {
2586 printf("Content has changed\n");
2587 NotifyContentChanged();
2588 }
2589
2590 #if 0
2591 virtual bool Render(Orthanc::ImageAccessor& target)
2592 {
2593 if (RenderInternal(target.GetWidth(), target.GetHeight(), ImageInterpolation_Nearest))
2594 {
2595 assert(cairoBuffer_.get() != NULL);
2596
2597 Orthanc::ImageAccessor source;
2598 cairoBuffer_->GetAccessor(source);
2599 Orthanc::ImageProcessing::Copy(target, source);
2545 } 2600 }
2546 else 2601 else
2547 { 2602 {
2548 Orthanc::ImageProcessing::Set(target, 0, 0, 0, 255); 2603 Orthanc::ImageProcessing::Set(target, 0, 0, 0, 255);
2549 } 2604 }
2550 2605
2551 { 2606 {
2552 // TODO => REFACTOR 2607 // TODO => REFACTOR
2553 CairoSurface surface(target); 2608 CairoSurface surface(target);
2554 stack_.DrawControls(surface, GetView()); 2609 CairoContext context(surface);
2610 GetView().ApplyTransform(context);
2611 stack_.DrawControls(context, GetView().GetZoom());
2555 } 2612 }
2556 2613
2557 return true; 2614 return true;
2558 } 2615 }
2559 2616 #endif
2560 }; 2617 };
2561 2618
2562 2619
2563 namespace Samples 2620 namespace Samples
2564 { 2621 {
2732 2789
2733 Orthanc::FontRegistry fonts; 2790 Orthanc::FontRegistry fonts;
2734 fonts.AddFromResource(Orthanc::EmbeddedResources::FONT_UBUNTU_MONO_BOLD_16); 2791 fonts.AddFromResource(Orthanc::EmbeddedResources::FONT_UBUNTU_MONO_BOLD_16);
2735 2792
2736 stack_.reset(new BitmapStack(IObserver::broker_, *orthancApiClient_)); 2793 stack_.reset(new BitmapStack(IObserver::broker_, *orthancApiClient_));
2737 //stack_->LoadFrame(instance, frame, false); 2794 stack_->LoadFrame(instance, frame, false);
2738 //stack_->LoadFrame("61f3143e-96f34791-ad6bbb8d-62559e75-45943e1b", frame, false); 2795 stack_->LoadFrame("61f3143e-96f34791-ad6bbb8d-62559e75-45943e1b", frame, false);
2739 2796
2740 { 2797 {
2741 BitmapStack::Bitmap& bitmap = stack_->LoadText(fonts.GetFont(0), "Hello\nworld\nBonjour, Alain"); 2798 BitmapStack::Bitmap& bitmap = stack_->LoadText(fonts.GetFont(0), "Hello\nworld\nBonjour, Alain");
2742 dynamic_cast<BitmapStack::AlphaBitmap&>(bitmap).SetForegroundValue(256); 2799 //dynamic_cast<BitmapStack::AlphaBitmap&>(bitmap).SetForegroundValue(256);
2743 dynamic_cast<BitmapStack::AlphaBitmap&>(bitmap).SetResizeable(true); 2800 dynamic_cast<BitmapStack::AlphaBitmap&>(bitmap).SetResizeable(true);
2744 } 2801 }
2745 2802
2746 { 2803 {
2747 BitmapStack::Bitmap& bitmap = stack_->LoadTestBlock(100, 50); 2804 BitmapStack::Bitmap& bitmap = stack_->LoadTestBlock(100, 50);
2748 dynamic_cast<BitmapStack::AlphaBitmap&>(bitmap).SetForegroundValue(256); 2805 //dynamic_cast<BitmapStack::AlphaBitmap&>(bitmap).SetForegroundValue(256);
2749 dynamic_cast<BitmapStack::AlphaBitmap&>(bitmap).SetResizeable(true); 2806 dynamic_cast<BitmapStack::AlphaBitmap&>(bitmap).SetResizeable(true);
2750 } 2807 }
2751 2808
2752 2809
2753 mainWidget_ = new BitmapStackWidget(IObserver::broker_, *stack_, "main-widget"); 2810 mainWidget_ = new BitmapStackWidget(IObserver::broker_, *stack_, "main-widget");