File indexing completed on 2024-12-22 04:13:04
0001 /* 0002 * SPDX-FileCopyrightText: 2017 Laurent Valentin Jospin <laurent.valentin@famillejospin.ch> 0003 * 0004 * SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 #include "kis_document_aware_spin_box_unit_manager.h" 0008 0009 #include "KisPart.h" 0010 #include "KisMainWindow.h" 0011 #include "KisView.h" 0012 #include "KisDocument.h" 0013 #include "kis_types.h" 0014 #include "kis_image.h" 0015 #include "kis_image_animation_interface.h" 0016 #include "kis_time_span.h" 0017 0018 0019 KisSpinBoxUnitManager* KisDocumentAwareSpinBoxUnitManagerBuilder::buildUnitManager(QObject* parent) 0020 { 0021 return new KisDocumentAwareSpinBoxUnitManager(parent); 0022 } 0023 0024 void KisDocumentAwareSpinBoxUnitManager::setDocumentAwarenessToExistingUnitSpinBox(KisDoubleParseUnitSpinBox* spinBox, bool setUnitFromOutsideToggle) 0025 { 0026 KisDocumentAwareSpinBoxUnitManager* manager = new KisDocumentAwareSpinBoxUnitManager(spinBox); 0027 spinBox->setUnitManager(manager); 0028 spinBox->setUnitChangeFromOutsideBehavior(setUnitFromOutsideToggle); 0029 } 0030 0031 KisDoubleParseUnitSpinBox* KisDocumentAwareSpinBoxUnitManager::createUnitSpinBoxWithDocumentAwareness(QWidget* parent) 0032 { 0033 KisDoubleParseUnitSpinBox* spinBox = new KisDoubleParseUnitSpinBox(parent); 0034 setDocumentAwarenessToExistingUnitSpinBox(spinBox); 0035 0036 return spinBox; 0037 } 0038 0039 KisDocumentAwareSpinBoxUnitManager::KisDocumentAwareSpinBoxUnitManager(QObject *parent, int pPixDir): 0040 KisSpinBoxUnitManager(parent) 0041 { 0042 if (pPixDir == PIX_DIR_Y) { 0043 pixDir = PIX_DIR_Y; 0044 } else { 0045 pixDir = PIX_DIR_X; 0046 } 0047 0048 grantDocumentRelativeUnits(); //the purpose of this class is to manage document relative units. 0049 } 0050 0051 0052 qreal KisDocumentAwareSpinBoxUnitManager::getConversionFactor(int dim, QString psymbol) const 0053 { 0054 QString symbol = psymbol; 0055 0056 if (symbol == "%") { //percent can be seen as vw or vh depending of the reference side in the image. 0057 if (pixDir == PIX_DIR_X) { 0058 symbol = "vw"; 0059 } else { 0060 symbol = "vh"; 0061 } 0062 } 0063 0064 qreal factor = KisSpinBoxUnitManager::getConversionFactor(dim, symbol); 0065 0066 if (factor > 0) { 0067 //no errors occurred at a lower level, so the conversion factor has been get. 0068 return factor; 0069 } 0070 0071 factor = 1; //fall back to something natural in case document is unreachable (1 px = 1 pt = 1vw = 1vh). So a virtual document of 100x100 with a resolution of 1. 0072 0073 if (!KisPart::instance()->currentMainwindow()) { 0074 return factor; 0075 } 0076 0077 KisView* view = KisPart::instance()->currentMainwindow()->activeView(); 0078 0079 if (view == nullptr) { 0080 return factor; 0081 } 0082 0083 KisDocument* doc = view->document(); 0084 0085 if (doc == nullptr) { 0086 return factor; 0087 } 0088 0089 KisImage* img = doc->image().data(); 0090 0091 if (img == nullptr) { 0092 return factor; 0093 } 0094 0095 qreal resX = img->xRes(); 0096 qreal resY = img->yRes(); 0097 qreal sizeX = img->width(); 0098 qreal sizeY = img->height(); 0099 0100 switch (dim) { 0101 0102 case LENGTH: 0103 if (symbol == "px") { 0104 0105 if (pixDir == PIX_DIR_X) { 0106 factor = resX; 0107 } else { 0108 factor = resY; 0109 } 0110 } else if (symbol == "vw") { 0111 qreal docWidth = sizeX/resX; 0112 0113 factor = 100.0/docWidth; //1 vw is 1% of document width, 1 vw in point is docWidth/100 so 1 point in vw is the inverse. 0114 } else if (symbol == "vh") { 0115 qreal docHeight = sizeY/resY; 0116 0117 factor = 100.0/docHeight; 0118 } 0119 break; 0120 0121 case IMLENGTH: 0122 0123 if (symbol == "vw") { 0124 factor = 100.0/sizeX; //1 vw is 1% of document width, 1 vw in pixel is sizeX/100 so 1 pixel in vw is the inverse. 0125 0126 } else if (symbol == "vh") { 0127 factor = 100.0/sizeY; 0128 } 0129 break; 0130 0131 case TIME: 0132 { 0133 if (symbol == "s") { 0134 qreal fps = img->animationInterface()->framerate(); 0135 0136 factor = 1/fps; 0137 } else if (symbol == "%") { 0138 const KisTimeSpan & time_range = img->animationInterface()->documentPlaybackRange(); 0139 qreal n_frame = time_range.end() - time_range.start(); 0140 0141 factor = 100/n_frame; 0142 } 0143 } 0144 break; 0145 0146 default: 0147 break; 0148 0149 } 0150 0151 return factor; 0152 } 0153 0154 qreal KisDocumentAwareSpinBoxUnitManager::getConversionConstant(int dim, QString symbol) const 0155 { 0156 if (dim == TIME && symbol == "%") { 0157 KisImage* img = KisPart::instance()->currentMainwindow()->activeView()->document()->image().data(); 0158 const KisTimeSpan & time_range = img->animationInterface()->documentPlaybackRange(); 0159 qreal n_frame = time_range.end() - time_range.start(); 0160 0161 return -time_range.start()*100.0/n_frame; 0162 } 0163 0164 return KisSpinBoxUnitManager::getConversionConstant(dim, symbol); 0165 } 0166 0167 0168 bool KisDocumentAwareSpinBoxUnitManager::hasPercent(int unitDim) const { 0169 0170 if (unitDim == IMLENGTH || unitDim == LENGTH) { 0171 return true; 0172 } 0173 0174 return KisSpinBoxUnitManager::hasPercent(unitDim); 0175 }