File indexing completed on 2025-02-02 04:26:09
0001 /* SPDX-FileCopyrightText: 2022 Marco Martin <mart@kde.org> 0002 * SPDX-FileCopyrightText: 2022 Noah Davis <noahadvs@gmail.com> 0003 * SPDX-License-Identifier: LGPL-2.0-or-later 0004 */ 0005 0006 #include "AnnotationTool.h" 0007 #include "settings.h" 0008 0009 using enum AnnotationTool::Tool; 0010 using enum AnnotationTool::Option; 0011 0012 // clang-format off 0013 0014 // Default value macros 0015 0016 #define DEFAULT_STROKE_WIDTH(ToolName) case ToolName##Tool: { return Settings::default##ToolName##StrokeWidthValue(); } 0017 0018 #define DEFAULT_STROKE_COLOR(ToolName) case ToolName##Tool: { return Settings::default##ToolName##StrokeColorValue(); } 0019 0020 #define DEFAULT_FILL_COLOR(ToolName) case ToolName##Tool: { return Settings::default##ToolName##FillColorValue(); } 0021 0022 #define DEFAULT_FONT(ToolName) case ToolName##Tool: { return Settings::default##ToolName##FontValue(); } 0023 0024 #define DEFAULT_FONT_COLOR(ToolName) case ToolName##Tool: { return Settings::default##ToolName##FontColorValue(); } 0025 0026 #define DEFAULT_SHADOW(ToolName) case ToolName##Tool: { return Settings::default##ToolName##ShadowValue(); } 0027 0028 // No getter macros because there's no way to lowercase the ToolName arg 0029 0030 // Setter macros 0031 0032 #define SET_STROKE_WIDTH(ToolName) case ToolName##Tool: { Settings::set##ToolName##StrokeWidth(width); } break; 0033 0034 #define SET_STROKE_COLOR(ToolName) case ToolName##Tool: { Settings::set##ToolName##StrokeColor(color); } break; 0035 0036 #define SET_FILL_COLOR(ToolName) case ToolName##Tool: { Settings::set##ToolName##FillColor(color); } break; 0037 0038 #define SET_FONT(ToolName) case ToolName##Tool: { Settings::set##ToolName##Font(font); } break; 0039 0040 #define SET_FONT_COLOR(ToolName) case ToolName##Tool: { Settings::set##ToolName##FontColor(color); } break; 0041 0042 #define SET_SHADOW(ToolName) case ToolName##Tool: { Settings::set##ToolName##Shadow(shadow); } break; 0043 0044 // clang-format on 0045 0046 AnnotationTool::AnnotationTool(QObject *parent) 0047 : QObject(parent) 0048 { 0049 } 0050 0051 AnnotationTool::~AnnotationTool() 0052 { 0053 } 0054 0055 AnnotationTool::Tool AnnotationTool::type() const 0056 { 0057 return m_type; 0058 } 0059 0060 void AnnotationTool::setType(AnnotationTool::Tool type) 0061 { 0062 if (m_type == type) { 0063 return; 0064 } 0065 0066 auto oldType = m_type; 0067 m_type = type; 0068 Q_EMIT typeChanged(); 0069 0070 auto newOptions = optionsForType(type); 0071 if (m_options != newOptions) { 0072 m_options = newOptions; 0073 Q_EMIT optionsChanged(); 0074 } 0075 0076 const auto &oldStrokeWidth = strokeWidthForType(oldType); 0077 const auto &newStrokeWidth = strokeWidthForType(type); 0078 if (oldStrokeWidth != newStrokeWidth) { 0079 Q_EMIT strokeWidthChanged(newStrokeWidth); 0080 } 0081 0082 const auto &oldStrokeColor = strokeColorForType(oldType); 0083 const auto &newStrokeColor = strokeColorForType(type); 0084 if (oldStrokeColor != newStrokeColor) { 0085 Q_EMIT strokeColorChanged(newStrokeColor); 0086 } 0087 0088 const auto &oldFillColor = fillColorForType(oldType); 0089 const auto &newFillColor = fillColorForType(type); 0090 if (oldFillColor != newFillColor) { 0091 Q_EMIT fillColorChanged(newFillColor); 0092 } 0093 0094 const auto &oldFont = fontForType(oldType); 0095 const auto &newFont = fontForType(type); 0096 if (oldFont != newFont) { 0097 Q_EMIT fontChanged(newFont); 0098 } 0099 0100 const auto &oldFontColor = fontColorForType(oldType); 0101 const auto &newFontColor = fontColorForType(type); 0102 if (oldFontColor != newFontColor) { 0103 Q_EMIT fontColorChanged(newFontColor); 0104 } 0105 0106 const auto &oldShadow = typeHasShadow(oldType); 0107 const auto &newShadow = typeHasShadow(type); 0108 if (oldShadow != newShadow) { 0109 Q_EMIT shadowChanged(newShadow); 0110 } 0111 } 0112 0113 void AnnotationTool::resetType() 0114 { 0115 setType(AnnotationTool::NoTool); 0116 } 0117 0118 bool AnnotationTool::isCreationTool() const 0119 { 0120 return m_type != NoTool && m_type != SelectTool; 0121 } 0122 0123 AnnotationTool::Options AnnotationTool::options() const 0124 { 0125 return m_options; 0126 } 0127 0128 constexpr AnnotationTool::Options AnnotationTool::optionsForType(AnnotationTool::Tool type) 0129 { 0130 switch (type) { 0131 case HighlighterTool: 0132 return StrokeOption; 0133 case FreehandTool: 0134 case LineTool: 0135 case ArrowTool: 0136 return {StrokeOption, ShadowOption}; 0137 case RectangleTool: 0138 case EllipseTool: 0139 return {StrokeOption, ShadowOption, FillOption}; 0140 case TextTool: 0141 return {FontOption, TextOption, ShadowOption}; 0142 case NumberTool: 0143 return {FillOption, ShadowOption, FontOption, NumberOption}; 0144 default: 0145 return NoOptions; 0146 } 0147 } 0148 0149 int AnnotationTool::strokeWidth() const 0150 { 0151 return strokeWidthForType(m_type); 0152 } 0153 0154 constexpr int AnnotationTool::defaultStrokeWidthForType(AnnotationTool::Tool type) 0155 { 0156 switch (type) { 0157 DEFAULT_STROKE_WIDTH(Freehand) 0158 DEFAULT_STROKE_WIDTH(Highlighter) 0159 DEFAULT_STROKE_WIDTH(Line) 0160 DEFAULT_STROKE_WIDTH(Arrow) 0161 DEFAULT_STROKE_WIDTH(Rectangle) 0162 DEFAULT_STROKE_WIDTH(Ellipse) 0163 default: 0164 return 0; 0165 } 0166 } 0167 0168 int AnnotationTool::strokeWidthForType(AnnotationTool::Tool type) const 0169 { 0170 switch (type) { 0171 case FreehandTool: 0172 return Settings::freehandStrokeWidth(); 0173 case HighlighterTool: 0174 return Settings::highlighterStrokeWidth(); 0175 case LineTool: 0176 return Settings::lineStrokeWidth(); 0177 case ArrowTool: 0178 return Settings::arrowStrokeWidth(); 0179 case RectangleTool: 0180 return Settings::rectangleStrokeWidth(); 0181 case EllipseTool: 0182 return Settings::ellipseStrokeWidth(); 0183 default: 0184 return 0; 0185 } 0186 } 0187 0188 void AnnotationTool::setStrokeWidth(int width) 0189 { 0190 if (!m_options.testFlag(Option::StrokeOption) || strokeWidth() == width) { 0191 return; 0192 } 0193 0194 setStrokeWidthForType(width, m_type); 0195 Q_EMIT strokeWidthChanged(width); 0196 } 0197 0198 void AnnotationTool::setStrokeWidthForType(int width, AnnotationTool::Tool type) 0199 { 0200 switch (type) { 0201 SET_STROKE_WIDTH(Freehand) 0202 SET_STROKE_WIDTH(Highlighter) 0203 SET_STROKE_WIDTH(Line) 0204 SET_STROKE_WIDTH(Arrow) 0205 SET_STROKE_WIDTH(Rectangle) 0206 SET_STROKE_WIDTH(Ellipse) 0207 default: 0208 break; 0209 } 0210 } 0211 0212 void AnnotationTool::resetStrokeWidth() 0213 { 0214 setStrokeWidth(defaultStrokeWidthForType(m_type)); 0215 } 0216 0217 QColor AnnotationTool::strokeColor() const 0218 { 0219 return strokeColorForType(m_type); 0220 } 0221 0222 constexpr QColor AnnotationTool::defaultStrokeColorForType(AnnotationTool::Tool type) 0223 { 0224 switch (type) { 0225 DEFAULT_STROKE_COLOR(Freehand) 0226 DEFAULT_STROKE_COLOR(Highlighter) 0227 DEFAULT_STROKE_COLOR(Line) 0228 DEFAULT_STROKE_COLOR(Arrow) 0229 DEFAULT_STROKE_COLOR(Rectangle) 0230 DEFAULT_STROKE_COLOR(Ellipse) 0231 default: 0232 return Qt::transparent; 0233 } 0234 } 0235 0236 QColor AnnotationTool::strokeColorForType(AnnotationTool::Tool type) const 0237 { 0238 switch (type) { 0239 case FreehandTool: 0240 return Settings::freehandStrokeColor(); 0241 case HighlighterTool: 0242 return Settings::highlighterStrokeColor(); 0243 case LineTool: 0244 return Settings::lineStrokeColor(); 0245 case ArrowTool: 0246 return Settings::arrowStrokeColor(); 0247 case RectangleTool: 0248 return Settings::rectangleStrokeColor(); 0249 case EllipseTool: 0250 return Settings::ellipseStrokeColor(); 0251 default: 0252 return Qt::transparent; 0253 } 0254 } 0255 0256 void AnnotationTool::setStrokeColor(const QColor &color) 0257 { 0258 if (!m_options.testFlag(Option::StrokeOption) || strokeColor() == color) { 0259 return; 0260 } 0261 0262 setStrokeColorForType(color, m_type); 0263 Q_EMIT strokeColorChanged(color); 0264 } 0265 0266 void AnnotationTool::setStrokeColorForType(const QColor &color, AnnotationTool::Tool type) 0267 { 0268 switch (type) { 0269 SET_STROKE_COLOR(Freehand) 0270 SET_STROKE_COLOR(Highlighter) 0271 SET_STROKE_COLOR(Line) 0272 SET_STROKE_COLOR(Arrow) 0273 SET_STROKE_COLOR(Rectangle) 0274 SET_STROKE_COLOR(Ellipse) 0275 default: 0276 break; 0277 } 0278 } 0279 0280 void AnnotationTool::resetStrokeColor() 0281 { 0282 setStrokeColor(defaultStrokeColorForType(m_type)); 0283 } 0284 0285 QColor AnnotationTool::fillColor() const 0286 { 0287 return fillColorForType(m_type); 0288 } 0289 0290 constexpr QColor AnnotationTool::defaultFillColorForType(AnnotationTool::Tool type) 0291 { 0292 switch (type) { 0293 DEFAULT_FILL_COLOR(Rectangle) 0294 DEFAULT_FILL_COLOR(Ellipse) 0295 DEFAULT_FILL_COLOR(Number) 0296 default: 0297 return Qt::transparent; 0298 } 0299 } 0300 0301 QColor AnnotationTool::fillColorForType(AnnotationTool::Tool type) const 0302 { 0303 switch (type) { 0304 case RectangleTool: 0305 return Settings::rectangleFillColor(); 0306 case EllipseTool: 0307 return Settings::ellipseFillColor(); 0308 case NumberTool: 0309 return Settings::numberFillColor(); 0310 default: 0311 return Qt::transparent; 0312 } 0313 } 0314 0315 void AnnotationTool::setFillColor(const QColor &color) 0316 { 0317 if (!m_options.testFlag(Option::FillOption) || fillColor() == color) { 0318 return; 0319 } 0320 0321 setFillColorForType(color, m_type); 0322 Q_EMIT fillColorChanged(color); 0323 } 0324 0325 void AnnotationTool::setFillColorForType(const QColor &color, AnnotationTool::Tool type) 0326 { 0327 switch (type) { 0328 SET_FILL_COLOR(Rectangle) 0329 SET_FILL_COLOR(Ellipse) 0330 SET_FILL_COLOR(Number) 0331 default: 0332 break; 0333 } 0334 } 0335 0336 void AnnotationTool::resetFillColor() 0337 { 0338 setFillColor(defaultFillColorForType(m_type)); 0339 } 0340 0341 QFont AnnotationTool::font() const 0342 { 0343 return fontForType(m_type); 0344 } 0345 0346 QFont AnnotationTool::fontForType(AnnotationTool::Tool type) const 0347 { 0348 switch (type) { 0349 case TextTool: 0350 return Settings::textFont(); 0351 case NumberTool: 0352 return Settings::numberFont(); 0353 default: 0354 return {}; 0355 } 0356 } 0357 0358 void AnnotationTool::setFont(const QFont &font) 0359 { 0360 if (!m_options.testFlag(Option::FontOption) || this->font() == font) { 0361 return; 0362 } 0363 0364 setFontForType(font, m_type); 0365 Q_EMIT fontChanged(font); 0366 } 0367 0368 void AnnotationTool::setFontForType(const QFont &font, AnnotationTool::Tool type) 0369 { 0370 switch (type) { 0371 SET_FONT(Text) 0372 SET_FONT(Number) 0373 default: 0374 break; 0375 } 0376 } 0377 0378 void AnnotationTool::resetFont() 0379 { 0380 setFont({}); 0381 } 0382 0383 QColor AnnotationTool::fontColor() const 0384 { 0385 return fontColorForType(m_type); 0386 } 0387 0388 constexpr QColor AnnotationTool::defaultFontColorForType(AnnotationTool::Tool type) 0389 { 0390 switch (type) { 0391 DEFAULT_FONT_COLOR(Text) 0392 DEFAULT_FONT_COLOR(Number) 0393 default: 0394 return Qt::transparent; 0395 } 0396 } 0397 0398 QColor AnnotationTool::fontColorForType(AnnotationTool::Tool type) const 0399 { 0400 switch (type) { 0401 case TextTool: 0402 return Settings::textFontColor(); 0403 case NumberTool: 0404 return Settings::numberFontColor(); 0405 default: 0406 return Qt::transparent; 0407 } 0408 } 0409 0410 void AnnotationTool::setFontColor(const QColor &color) 0411 { 0412 if (!m_options.testFlag(Option::FontOption) || fontColor() == color) { 0413 return; 0414 } 0415 0416 setFontColorForType(color, m_type); 0417 Q_EMIT fontColorChanged(color); 0418 } 0419 0420 void AnnotationTool::setFontColorForType(const QColor &color, AnnotationTool::Tool type) 0421 { 0422 switch (type) { 0423 SET_FONT_COLOR(Text) 0424 SET_FONT_COLOR(Number) 0425 default: 0426 break; 0427 } 0428 } 0429 0430 void AnnotationTool::resetFontColor() 0431 { 0432 setFontColor(defaultFontColorForType(m_type)); 0433 } 0434 0435 int AnnotationTool::number() const 0436 { 0437 return m_number; 0438 } 0439 0440 void AnnotationTool::setNumber(int number) 0441 { 0442 if (m_number == number) { 0443 return; 0444 } 0445 0446 m_number = number; 0447 Q_EMIT numberChanged(number); 0448 } 0449 0450 void AnnotationTool::resetNumber() 0451 { 0452 setNumber(1); 0453 } 0454 0455 bool AnnotationTool::typeHasShadow(AnnotationTool::Tool type) const 0456 { 0457 switch (type) { 0458 case FreehandTool: 0459 return Settings::freehandShadow(); 0460 case LineTool: 0461 return Settings::lineShadow(); 0462 case ArrowTool: 0463 return Settings::arrowShadow(); 0464 case RectangleTool: 0465 return Settings::rectangleShadow(); 0466 case EllipseTool: 0467 return Settings::ellipseShadow(); 0468 case TextTool: 0469 return Settings::textShadow(); 0470 case NumberTool: 0471 return Settings::numberShadow(); 0472 default: 0473 return false; 0474 } 0475 } 0476 0477 bool AnnotationTool::hasShadow() const 0478 { 0479 return typeHasShadow(m_type); 0480 } 0481 0482 void AnnotationTool::setTypeHasShadow(AnnotationTool::Tool type, bool shadow) 0483 { 0484 switch (type) { 0485 SET_SHADOW(Freehand) 0486 SET_SHADOW(Line) 0487 SET_SHADOW(Arrow) 0488 SET_SHADOW(Rectangle) 0489 SET_SHADOW(Ellipse) 0490 SET_SHADOW(Text) 0491 SET_SHADOW(Number) 0492 default: 0493 break; 0494 } 0495 } 0496 0497 void AnnotationTool::setShadow(bool shadow) 0498 { 0499 if (!m_options.testFlag(Option::ShadowOption) || hasShadow() == shadow) { 0500 return; 0501 } 0502 0503 setTypeHasShadow(m_type, shadow); 0504 Q_EMIT shadowChanged(shadow); 0505 } 0506 0507 void AnnotationTool::resetShadow() 0508 { 0509 setShadow(true); 0510 } 0511 0512 #include <moc_AnnotationTool.cpp>