3#include "../../global.hpp"
4#include "../../size_2d.hpp"
5#include "../../point_2d.hpp"
6#include "../../rect_lt.hpp"
7#include "../../image.hpp"
12# pragma warning(push, 1)
13# pragma warning(disable : 4005)
147 struct ZoomDescriptor final
159 ZoomDescriptor() =
default;
167 bool operator==(
const ZoomDescriptor &zoomDescriptor)
const noexcept
169 return ID == zoomDescriptor.ID &&
Factor == zoomDescriptor.Factor;
167 bool operator==(
const ZoomDescriptor &zoomDescriptor)
const noexcept {
…}
178 bool operator!=(
const ZoomDescriptor &zoomDescriptor)
const noexcept
180 return !(*
this == zoomDescriptor);
178 bool operator!=(
const ZoomDescriptor &zoomDescriptor)
const noexcept {
…}
147 struct ZoomDescriptor final {
…};
252 friend class ZoomHandler;
255 IImageView(
const IImageView &other) =
delete;
256 IImageView &operator=(
const IImageView &other) =
delete;
257 IImageView(IImageView &&other) =
delete;
258 IImageView &operator=(IImageView &&other) =
delete;
259 virtual ~IImageView() =
default;
262 IImageView() noexcept = default;
264 virtual
Size2D<
double> ViewSize() const noexcept = 0;
265 virtual
Size2D<
double> ImageSize() const noexcept = 0;
267 virtual
void ApplyZoom(
double factor) = 0;
273 explicit ZoomHandler(
class IImageView &view) noexcept
286 defaultDescriptorList_.swap(defaultDescriptorList);
289 currentZoomDescriptor_ = panoramaDescriptor_;
292 ZoomHandler(
const ZoomHandler &other) =
delete;
293 ZoomHandler &operator=(
const ZoomHandler &other) =
delete;
294 ZoomHandler(ZoomHandler &&other) =
delete;
295 ZoomHandler &operator=(ZoomHandler &&other) =
delete;
296 ~ZoomHandler() =
default;
298 void UpdatePanoramaFactor() noexcept
300 auto viewportSize = view_.ViewSize();
301 auto sceneSize = view_.ImageSize();
302 if ((viewportSize_ == viewportSize && sceneSize_ == sceneSize)
303 || (sceneSize.Width() < 1 || sceneSize.Height() < 1))
306 viewportSize_ = viewportSize;
307 sceneSize_ = sceneSize;
311 double panoramaFactor =
312 std::min(viewportSize_.Width() / sceneSize_.Width(), viewportSize_.Height() / sceneSize_.Height());
314 panoramaDescriptor_.Factor = panoramaFactor;
317 currentZoomDescriptor_ = panoramaDescriptor_;
322 struct ZoomDescriptor ZoomDescriptor() const noexcept
324 return currentZoomDescriptor_;
327 bool TryZoomIn() noexcept
329 struct ZoomDescriptor result;
331 for (
auto descriptor : defaultDescriptorList_)
333 if (descriptor.Factor > currentZoomDescriptor_.Factor
334 && (result.ID ==
ZoomID::Invalid || descriptor.Factor < result.Factor))
338 if (panoramaDescriptor_.Factor > currentZoomDescriptor_.Factor
339 && (result.ID ==
ZoomID::Invalid || panoramaDescriptor_.Factor < result.Factor))
340 result = panoramaDescriptor_;
345 currentZoomDescriptor_ = result;
350 bool TryZoomOut() noexcept
352 struct ZoomDescriptor result;
354 for (
auto descriptor : defaultDescriptorList_)
356 if (descriptor.Factor < currentZoomDescriptor_.Factor
357 && (result.ID ==
ZoomID::Invalid || descriptor.Factor > result.Factor))
361 if (panoramaDescriptor_.Factor < currentZoomDescriptor_.Factor
362 && (result.ID ==
ZoomID::Invalid || panoramaDescriptor_.Factor > result.Factor))
363 result = panoramaDescriptor_;
368 currentZoomDescriptor_ = result;
373 void SetZoomDescriptor(
struct ZoomDescriptor zoomDescriptor)
noexcept
376 currentZoomDescriptor_ = zoomDescriptor;
381 enum class RenderDescriptor
384 AsyncImageUploadRaster,
386 AsyncImageRepaintRaster,
387 AsyncImageScheduleGl,
388 AsyncImageScheduleRaster,
389 AsyncViewportUploadGl,
390 AsyncViewportUploadRaster,
391 AsyncViewportRepaintGl,
392 AsyncViewportRepaintRaster,
394 AsyncViewportScheduleGl,
395 AsyncViewportScheduleRaster,
398 SyncImageUploadRaster,
400 SyncImageRepaintRaster,
402 SyncImageScheduleRaster,
403 SyncViewportUploadGl,
404 SyncViewportUploadRaster,
405 SyncViewportRepaintGl,
407 SyncViewportRepaintRaster,
409 SyncViewportScheduleGl,
410 SyncViewportScheduleRaster,
413 void Apply() noexcept
415 if (currentZoomDescriptor_.ID ==
ZoomID::Invalid || std::isnan(currentZoomDescriptor_.Factor))
418 view_.ApplyZoom(currentZoomDescriptor_.Factor);
423 Size2D<double> sceneSize_;
424 Size2D<double> viewportSize_;
425 std::vector<struct ZoomDescriptor> defaultDescriptorList_;
426 struct ZoomDescriptor panoramaDescriptor_;
427 struct ZoomDescriptor currentZoomDescriptor_;
430 struct BGRAComponents
432 std::uint8_t Blue = 0;
433 std::uint8_t Green = 0;
434 std::uint8_t Red = 0;
435 std::uint8_t Alpha = 255;
438 struct RGBAComponents
440 std::uint8_t Red = 0;
441 std::uint8_t Green = 0;
442 std::uint8_t Blue = 0;
443 std::uint8_t Alpha = 255;
447 inline void CopyImageDataColorToColor(
const Image &src, T *dst)
noexcept
449 auto vpatR = src.Plane(0).Vpat();
450 auto vpatG = src.Plane(1).Vpat();
451 auto vpatB = src.Plane(2).Vpat();
453 auto entrysR = vpatR.VpatPtr();
454 auto entrysG = vpatG.VpatPtr();
455 auto entrysB = vpatB.VpatPtr();
457 auto baseR = vpatR.BasePtr();
458 auto baseG = vpatG.BasePtr();
459 auto baseB = vpatB.BasePtr();
461 auto widht = src.Width();
462 auto height = src.Height();
464 for (
int h = 0; h < height; ++h)
466 auto lineOffsetR = baseR + entrysR[h].OffsetY;
467 auto lineOffsetG = baseG + entrysG[h].OffsetY;
468 auto lineOffsetB = baseB + entrysB[h].OffsetY;
469 for (
int w = 0; w < widht; ++w)
472 (*dst).Red = *
reinterpret_cast<std::uint8_t *
>(lineOffsetR + entrysR[w].OffsetX);
473 (*dst).Green = *
reinterpret_cast<std::uint8_t *
>(lineOffsetG + entrysG[w].OffsetX);
474 (*dst).Blue = *
reinterpret_cast<std::uint8_t *
>(lineOffsetB + entrysB[w].OffsetX);
481 inline void CopyImageDataMonoToColor(
const Image &src, T *dst)
noexcept
483 auto vpat = src.Plane(0).Vpat();
484 auto entrys = vpat.VpatPtr();
485 auto base = vpat.BasePtr();
487 auto widht = src.Width();
488 auto height = src.Height();
490 for (
int h = 0; h < height; ++h)
492 auto lineOffset = base + entrys[h].OffsetY;
493 for (
int w = 0; w < widht; ++w)
496 auto value = *
reinterpret_cast<std::uint8_t *
>(lineOffset + entrys[w].OffsetX);
497 (*dst).Blue = (*dst).Green = (*dst).Red = value;
503 inline void CopyImageDataMonoToMono(
const Image &src,
void *dst,
int linePad)
noexcept
505 auto dstMono =
reinterpret_cast<std::uint8_t *
>(dst);
506 auto vpat = src.Plane(0).Vpat();
507 auto entrys = vpat.VpatPtr();
508 auto base = vpat.BasePtr();
510 auto widht = src.Width();
511 auto height = src.Height();
513 for (
int h = 0; h < height; ++h)
515 auto lineOffset = base + entrys[h].OffsetY;
516 for (
int w = 0; w < widht; ++w)
518 (*dstMono) = *
reinterpret_cast<std::uint8_t *
>(lineOffset + entrys[w].OffsetX);
525 inline void CopyImageDataMonoToBGRA(
const Image &src,
void *dst)
noexcept
527 CopyImageDataMonoToColor(src,
reinterpret_cast<BGRAComponents *
>(dst));
530 inline void CopyImageDataMonoToRGBA(
const Image &src,
void *dst)
noexcept
532 CopyImageDataMonoToColor(src,
reinterpret_cast<RGBAComponents *
>(dst));
535 inline void CopyImageDataRGBToBGRA(
const Image &src,
void *dst)
noexcept
537 CopyImageDataColorToColor(src,
reinterpret_cast<BGRAComponents *
>(dst));
540 inline void CopyImageDataRGBToRGBA(
const Image &src,
void *dst)
noexcept
542 CopyImageDataColorToColor(src,
reinterpret_cast<RGBAComponents *
>(dst));
545 class ImageViewDispatcher :
public UI::Private::IImageView
547 friend class ImageViewDispatcherGuard;
550 explicit ImageViewDispatcher(std::function<
void()> notifyZoom)
551 : zoomHandler_(*this)
552 , notifyZoom_(notifyZoom)
556 UI::ZoomID
ZoomID() const noexcept
558 return zoomHandler_.ZoomDescriptor().ID;
561 void UpdateZoomID(UI::ZoomID
id, std::function<
void()> notify)
566 zoomHandler_.SetZoomDescriptor(ZoomDescriptor(
id));
570 void UpdateUploadMode(UI::UploadMode uploadMode, std::function<
void()> notify)
572 if (uploadMode_ == uploadMode)
576 std::unique_lock<std::mutex> gurad(
578 uploadMode_ = uploadMode;
583 double ZoomFactor() const noexcept
585 return zoomHandler_.ZoomDescriptor().Factor;
588 void UpdateZoomFactor(
double factor, std::function<
void()> notify)
590 if (factor == ZoomFactor())
593 zoomHandler_.SetZoomDescriptor(ZoomDescriptor(factor));
597 Point2D<double> ImageAnchor() const noexcept
602 void UpdateImageAnchor(Point2D<double> imageAnchor, std::function<
void()> notify)
604 if (imageAnchor_ == imageAnchor)
607 imageAnchor_ = imageAnchor;
611 Point2D<double> ViewAnchor() const noexcept
616 void UpdateViewAnchor(Point2D<double> viewAnchor, std::function<
void()> notify)
618 if (viewAnchor_ == viewAnchor)
621 viewAnchor_ = viewAnchor;
625 Point2D<double> LastMousePosition() const noexcept
630 Point2D<double> HoverPosition() const noexcept
632 return *hoverPosition_;
635 bool TryTranslate(Vector2D<double> translation, std::function<
void()> notifySourceRect)
637 auto zoom = zoomHandler_.ZoomDescriptor().Factor;
639 auto imageTranslation = translation / zoom;
640 auto xRange = imageRect_.Width() - sourceRect_.Width();
641 auto yRange = imageRect_.Height() - sourceRect_.Height();
643 auto sourceCandidate = sourceRect_;
645 auto translationCandidate = sourceCandidate.Location() - imageTranslation;
655 translationCandidate.SetX(std::max(translationCandidate.X(), 0.0));
656 translationCandidate.SetY(std::max(translationCandidate.Y(), 0.0));
659 Point2D<double> location(std::min(xRange, translationCandidate.X()),
660 std::min(yRange, translationCandidate.Y()));
661 sourceCandidate.SetLocation(location);
663 auto result = sourceRect_ != sourceCandidate;
664 UpdateSourceRect(sourceCandidate, notifySourceRect);
668 bool TryZoomIn(std::function<
void()> notifyTargetRect, std::function<
void()> notifySourceRect)
670 auto result = zoomHandler_.TryZoomIn();
671 UpdateTargetSource(notifyTargetRect, notifySourceRect);
675 bool TryZoomOut(std::function<
void()> notifyTargetRect, std::function<
void()> notifySourceRect)
677 auto result = zoomHandler_.TryZoomOut();
678 UpdateTargetSource(notifyTargetRect, notifySourceRect);
682 RectLT<double> ViewRect() const noexcept
687 RectLT<double> ImageRect() const noexcept
692 RectLT<double> SourceRect() const noexcept
697 RectLT<double> TargetRect() const noexcept
702 void UpdateViewRect(RectLT<double> rect, std::function<
void()> notify)
704 if (viewRect_ == rect)
715 Point2D<double> MapViewToTarget(Point2D<double> viewPoint)
const
717 return viewPoint - targetRect_.Location();
720 Point2D<double> MapTargetToSource(Point2D<double> targetPoint)
const
722 return targetPoint / zoomHandler_.ZoomDescriptor().Factor;
725 Point2D<double> MapSourceToImage(Point2D<double> sourcePoint)
const
727 return sourcePoint + sourceRect_.Location();
730 Point2D<double> MapTargetToView(Point2D<double> targetPoint)
const
732 return targetPoint + targetRect_.Location();
735 Point2D<double> MapSourceToTarget(Point2D<double> sourcePoint)
const
737 return sourcePoint * zoomHandler_.ZoomDescriptor().Factor;
740 Point2D<double> MapImageToSource(Point2D<double> imagePoint)
const
742 return imagePoint - sourceRect_.Location();
745 Point2D<double> MapViewToImage(Point2D<double> viewPoint)
const
747 return MapSourceToImage(MapTargetToSource(MapViewToTarget(viewPoint)));
750 void UploadImage(
const Image &image, std::function<
void()> notifyImageRect)
752 std::unique_lock<std::mutex> guard(renderMutex_);
753 UpdateImageRect(image, notifyImageRect);
755 auto mappedImage = UpdateRenderTarget(image);
757 if (uploadMode_ == UI::UploadMode::Image)
758 CopyImageData(image);
759 else if (mappedImage)
760 CopyImageData(*mappedImage);
763 void CopyImageData(
const Image &image)
noexcept
765 switch (image.PlanesCount())
771 UI::Private::CopyImageDataMonoToBGRA(image, buffer_.data());
776 UI::Private::CopyImageDataRGBToBGRA(image, buffer_.data());
781 void UpdateImageRect(
const Cvb::Image &image, std::function<
void()> notify)
783 RectLT<double> requestedImageRect(
784 Point2D<double>(0.0, 0.0),
785 Size2D<double>(
static_cast<double>(image.
Width()),
static_cast<double>(image.
Height())));
787 if (imageRect_ == requestedImageRect)
790 imageRect_ = requestedImageRect;
794 void UpdateTargetRect(RectLT<double> rect, std::function<
void()> notify)
796 if (targetRect_ == rect)
802 void UpdateSourceRect(RectLT<double> rect, std::function<
void()> notify)
804 if (sourceRect_ == rect)
810 void UpdateBuffer(Size2D<int> size)
813 std::vector<std::uint8_t>(
static_cast<size_t>(bufferSize_.Width()) *
static_cast<size_t>(bufferSize_.Height())
818 std::unique_ptr<class Image> UpdateRenderTarget(
const Cvb::Image &image)
820 if (uploadMode_ == UI::UploadMode::Image)
822 auto currentWidth = image.
Width();
823 auto currentHeight = image.
Height();
824 if (bufferSize_ == Size2D<int>(currentWidth, currentHeight))
825 return std::unique_ptr<class Image>();
827 UpdateBuffer(Size2D<int>(currentWidth, currentHeight));
828 return std::unique_ptr<class Image>();
834 auto sourceLeft = std::max(
static_cast<int>(std::floor(sourceRect_.Left())), 0);
835 auto sourceTop = std::max(
static_cast<int>(std::floor(sourceRect_.Top())), 0);
836 auto sourceRight = std::min(
static_cast<int>(std::ceil(sourceRect_.Right())), image.
Width() - 1);
837 auto sourceBottom = std::min(
static_cast<int>(std::ceil(sourceRect_.Bottom())), image.
Height() - 1);
838 Size2D<int> sourceSize(sourceRight - sourceLeft, sourceBottom - sourceTop);
839 Rect<int> sourceRect(Point2D<int>(sourceLeft, sourceTop), sourceSize);
842 if (sourceRect.Width() <= 0 || sourceRect.Height() <= 0)
843 return std::unique_ptr<class Image>();
846 if (!targetRect_.IsValid())
847 return std::unique_ptr<class Image>();
849 Size2D<int> targetSize;
850 if (sourceRect_.Width() <= targetRect_.Width())
852 targetSize = sourceRect.Size();
853 sourceRectAdj_ = RectLT<double>(
854 Point2D<double>(sourceRect_.Left() - std::floor(sourceRect_.Left()),
855 sourceRect_.Top() - std::floor(sourceRect_.Top())),
856 Size2D<double>(std::min(sourceRect_.Width(),
static_cast<double>(sourceRect.Width())),
857 std::min(sourceRect_.Height(),
static_cast<double>(sourceRect.Height()))));
861 targetSize = Size2D<int>(
static_cast<int>(targetRect_.Width()),
static_cast<int>(targetRect_.Height()));
863 RectLT<double>(Point2D<double>(0.0, 0.0), Size2D<double>(targetSize.Width(), targetSize.Height()));
866 if (targetSize.Width() <= 0 || targetSize.Height() <= 0)
867 return std::unique_ptr<class Image>();
869 auto mappedImage = image.
Map(sourceRect, targetSize);
870 if (bufferSize_ == Size2D<int>(targetSize.Width(), targetSize.Height()))
873 UpdateBuffer(targetSize);
878 Point2D<double> LimitPointToRect(Point2D<double> point, RectLT<double> rect)
881 if (result.X() < 0.0)
883 else if (result.X() > rect.Width())
884 result.SetX(rect.Width());
885 if (result.Y() < 0.0)
887 else if (result.Y() > rect.Height())
888 result.SetY(rect.Height());
892 void UpdateTargetSource(std::function<
void()> notifyTargetRect, std::function<
void()> notifySourceRect)
894 zoomHandler_.UpdatePanoramaFactor();
895 auto zoom = zoomHandler_.ZoomDescriptor().Factor;
897 auto contentWidth = zoom * imageRect_.Width();
898 auto contentHeight = zoom * imageRect_.Height();
903 (contentWidth <= viewRect_.Width()) ? (viewRect_.Width() - contentWidth) / 2.0
906 (contentHeight <= viewRect_.Height()) ? (viewRect_.Height() - contentHeight) / 2.0
909 Size2D<double>((contentWidth < viewRect_.Width())
913 (contentHeight < viewRect_.Height()) ? contentHeight : viewRect_.Height())),
918 auto sourceCandidate = viewRect_;
919 sourceCandidate.SetWidth(sourceCandidate.Width() / zoom);
920 sourceCandidate.SetHeight(sourceCandidate.Height() / zoom);
923 sourceCandidate.SetWidth(std::min(sourceCandidate.Width(), imageRect_.Width()));
924 sourceCandidate.SetHeight(std::min(sourceCandidate.Height(), imageRect_.Height()));
926 auto targetPoint = MapViewToTarget(viewAnchor_);
927 targetPoint = LimitPointToRect(targetPoint, targetRect_);
928 auto sourcePoint = MapTargetToSource(targetPoint);
930 auto offsetCandidate = imageAnchor_ - sourcePoint;
933 auto xRange = imageRect_.Width() - sourceCandidate.Width();
934 auto yRange = imageRect_.Height() - sourceCandidate.Height();
937 auto xOffsetCandidate = offsetCandidate.X();
938 auto yOffsetCandidate = offsetCandidate.Y();
941 xOffsetCandidate = std::max(xOffsetCandidate, 0.0);
942 yOffsetCandidate = std::max(yOffsetCandidate, 0.0);
945 Point2D<double> location(std::min(xRange, xOffsetCandidate), std::min(yRange, yOffsetCandidate));
946 sourceCandidate.SetLocation(location);
948 UpdateSourceRect(sourceCandidate, notifySourceRect);
951 void UpdateHoverPosition(Point2D<double> point, std::function<
void()> notify)
953 if (hoverPosition_ && *hoverPosition_ == point)
956 hoverPosition_ = std::make_unique<Point2D<double>>(point);
960 void InvalidateLastMousePosition() noexcept
965 void InvalidateLastMousePosition(Point2D<double> point)
noexcept
967 lastPos_ = std::make_unique<Point2D<double>>(point);
970 bool IsLastMousePositionValid() const noexcept
972 return (lastPos_) ? true :
false;
975 bool IsHoverPositionValid() const noexcept
977 return (hoverPosition_) ? true :
false;
980 Size2D<double> ViewSize() const noexcept
override
982 return viewRect_.Size();
985 Size2D<double> ImageSize() const noexcept
override
987 return imageRect_.Size();
990 void ApplyZoom(
double)
override
995 RectLT<double> SourceRectAdj() const noexcept
997 return sourceRectAdj_;
1000 bool IsBufferValid() const noexcept
1002 return (buffer_.size()) ? true :
false;
1005 std::uint8_t *Buffer() const noexcept
1007 return buffer_.data();
1010 Size2D<int> BufferSize() const noexcept
1016 RectLT<double> imageRect_;
1017 RectLT<double> viewRect_;
1018 RectLT<double> sourceRect_;
1019 RectLT<double> targetRect_;
1021 RectLT<double> sourceRectAdj_;
1023 Point2D<double> viewAnchor_;
1024 Point2D<double> imageAnchor_;
1026 std::mutex renderMutex_;
1028 UI::Private::ZoomHandler zoomHandler_;
1030 std::unique_ptr<Point2D<double>> lastPos_;
1031 std::unique_ptr<Point2D<double>> hoverPosition_;
1035 mutable std::vector<std::uint8_t> buffer_;
1036 Size2D<int> bufferSize_;
1038 std::function<void()> notifyZoom_;
1041 class ImageViewDispatcherGuard
1044 explicit ImageViewDispatcherGuard(ImageViewDispatcher &dispatcher)
1045 : dispatcher_(dispatcher)
1047 dispatcher_.renderMutex_.lock();
1050 ImageViewDispatcherGuard(
const ImageViewDispatcherGuard &other) =
delete;
1051 ImageViewDispatcherGuard &operator=(
const ImageViewDispatcherGuard &other) =
delete;
1052 ImageViewDispatcherGuard(ImageViewDispatcherGuard &&other) =
delete;
1053 ImageViewDispatcherGuard &operator=(ImageViewDispatcherGuard &&other) =
delete;
1054 ~ImageViewDispatcherGuard()
1056 dispatcher_.renderMutex_.unlock();
1060 ImageViewDispatcher &dispatcher_;
int Width() const noexcept
Width of the image in pixels.
Definition decl_image.hpp:309
int Height() const noexcept
Height of the image in pixels.
Definition decl_image.hpp:299
std::unique_ptr< Image > Map(Rect< int > rect) const
Creates a mapped image of the region of this image.
Definition decl_image.hpp:352
Stores a pair of numbers that represents the width and the height of a subject, typically a rectangle...
Definition size_2d.hpp:20
Namespace for user interface components.
Definition decl_image_scene.hpp:39
ZoomID
Identifier for a zoom factor.
Definition detail_ui.hpp:61
@ Factor4
Definition detail_ui.hpp:85
@ Factor2
Definition detail_ui.hpp:81
@ Factor64
Definition detail_ui.hpp:101
@ Invalid
Definition detail_ui.hpp:65
@ Factor32
Definition detail_ui.hpp:97
@ Factor8
Definition detail_ui.hpp:89
@ Factor128
Definition detail_ui.hpp:105
@ Factor1
Definition detail_ui.hpp:77
@ Panorama
Definition detail_ui.hpp:73
@ Custom
Definition detail_ui.hpp:69
@ Factor16
Definition detail_ui.hpp:93
AutoRefresh
Allows to automatically refresh, if image content changes.
Definition detail_ui.hpp:114
@ On
Definition detail_ui.hpp:121
@ Off
Definition detail_ui.hpp:125
LabelScale
Switch defining if image view labels are sensitive to zoom operations.
Definition detail_ui.hpp:130
UploadMode
Defines the upload behavior.
Definition detail_ui.hpp:37
@ Viewport
Definition detail_ui.hpp:53
@ Image
Definition detail_ui.hpp:45
Root namespace for the Image Manager interface.
Definition c_bayer_to_rgb.h:17
Describes an zoom setting for the display.
Definition detail_ui.hpp:148
bool operator==(const ZoomDescriptor &zoomDescriptor) const noexcept
Compares to an other zoom descriptor.
Definition detail_ui.hpp:167
bool operator!=(const ZoomDescriptor &zoomDescriptor) const noexcept
Compares to an other zoom descriptor.
Definition detail_ui.hpp:178
ZoomDescriptor(double customFactor) noexcept
Constructor for a custom zoom descriptor.
Definition detail_ui.hpp:240
double Factor
Numeric representation of the zoom factor.
Definition detail_ui.hpp:157
ZoomDescriptor(ZoomID id) noexcept
Constructor for a standard zoom descriptor.
Definition detail_ui.hpp:189
ZoomID ID
Zoom identifier for known factors.
Definition detail_ui.hpp:155