1 //------------------------------------------------------
2 /*! Finger Tool : 線のノイズを埋めるツール
3 */
4 #include "tstroke.h"
5 #include "tools/toolutils.h"
6 #include "tools/tool.h"
7 #include "tmathutil.h"
8 #include "tools/cursors.h"
9 #include "drawutil.h"
10 #include "tcolorstyles.h"
11 #include "tundo.h"
12 #include "tvectorimage.h"
13 #include "ttoonzimage.h"
14 #include "tproperty.h"
15 #include "toonz/strokegenerator.h"
16 #include "toonz/ttilesaver.h"
17 #include "toonz/txshsimplelevel.h"
18 #include "toonz/observer.h"
19 #include "toonz/toonzimageutils.h"
20 #include "toonz/levelproperties.h"
21 #include "toonz/stage2.h"
22 #include "toonz/ttileset.h"
23 #include "toonz/rasterstrokegenerator.h"
24 #include "toonz/preferences.h"
25 #include "tgl.h"
26 #include "tenv.h"
27
28 #include "trop.h"
29
30 #include "tinbetween.h"
31 #include "ttile.h"
32
33 #include "toonz/tpalettehandle.h"
34 #include "toonz/txsheethandle.h"
35 #include "toonz/txshlevelhandle.h"
36 #include "toonz/tframehandle.h"
37 #include "tools/toolhandle.h"
38
39 // For Qt translation support
40 #include <QCoreApplication>
41
42 #include "tools/stylepicker.h"
43 #include "toonzqt/tselectionhandle.h"
44 #include "toonzqt/styleselection.h"
45 #include "historytypes.h"
46
47 using namespace ToolUtils;
48
49 TEnv::IntVar FingerInvert("InknpaintFingerInvert", 0);
50 TEnv::DoubleVar FingerSize("InknpaintFingerSize", 10);
51
52 //-----------------------------------------------------------------------------
53
54 const int BackgroundStyle = 0;
55
56 //-----------------------------------------------------------------------------
57
58 namespace {
59
60 class FingerUndo final : public TRasterUndo {
61 std::vector<TThickPoint> m_points;
62 int m_styleId;
63 bool m_invert;
64
65 public:
FingerUndo(TTileSetCM32 * tileSet,const std::vector<TThickPoint> & points,int styleId,bool invert,TXshSimpleLevel * level,const TFrameId & frameId)66 FingerUndo(TTileSetCM32 *tileSet, const std::vector<TThickPoint> &points,
67 int styleId, bool invert, TXshSimpleLevel *level,
68 const TFrameId &frameId)
69 : TRasterUndo(tileSet, level, frameId, false, false, 0)
70 , m_points(points)
71 , m_styleId(styleId)
72 , m_invert(invert) {}
73
redo() const74 void redo() const override {
75 TToonzImageP image = m_level->getFrame(m_frameId, true);
76 TRasterCM32P ras = image->getRaster();
77 RasterStrokeGenerator m_rasterTrack(ras, FINGER, INK, m_styleId,
78 m_points[0], m_invert, 0, false);
79 m_rasterTrack.setPointsSequence(m_points);
80 m_rasterTrack.generateStroke(true);
81 image->setSavebox(image->getSavebox() +
82 m_rasterTrack.getBBox(m_rasterTrack.getPointsSequence()));
83
84 ToolUtils::updateSaveBox();
85
86 TTool::getApplication()->getCurrentXsheet()->notifyXsheetChanged();
87 notifyImageChanged();
88 }
89
getSize() const90 int getSize() const override {
91 return sizeof(*this) + TRasterUndo::getSize();
92 }
93
getToolName()94 QString getToolName() override { return QString("Finger Tool"); }
getHistoryType()95 int getHistoryType() override { return HistoryType::FingerTool; }
96 };
97
98 //-------------------------------------------------------------------------------------------
99
drawLine(const TPointD & point,const TPointD & centre,bool horizontal,bool isDecimal)100 void drawLine(const TPointD &point, const TPointD ¢re, bool horizontal,
101 bool isDecimal) {
102 if (!isDecimal) {
103 if (horizontal) {
104 tglDrawSegment(TPointD(point.x - 1.5, point.y + 0.5) + centre,
105 TPointD(point.x - 0.5, point.y + 0.5) + centre);
106 tglDrawSegment(TPointD(point.y - 0.5, -point.x + 1.5) + centre,
107 TPointD(point.y - 0.5, -point.x + 0.5) + centre);
108 tglDrawSegment(TPointD(-point.x + 0.5, -point.y + 0.5) + centre,
109 TPointD(-point.x - 0.5, -point.y + 0.5) + centre);
110 tglDrawSegment(TPointD(-point.y - 0.5, point.x - 0.5) + centre,
111 TPointD(-point.y - 0.5, point.x + 0.5) + centre);
112
113 tglDrawSegment(TPointD(point.y - 0.5, point.x + 0.5) + centre,
114 TPointD(point.y - 0.5, point.x - 0.5) + centre);
115 tglDrawSegment(TPointD(point.x - 0.5, -point.y + 0.5) + centre,
116 TPointD(point.x - 1.5, -point.y + 0.5) + centre);
117 tglDrawSegment(TPointD(-point.y - 0.5, -point.x + 0.5) + centre,
118 TPointD(-point.y - 0.5, -point.x + 1.5) + centre);
119 tglDrawSegment(TPointD(-point.x - 0.5, point.y + 0.5) + centre,
120 TPointD(-point.x + 0.5, point.y + 0.5) + centre);
121 } else {
122 tglDrawSegment(TPointD(point.x - 1.5, point.y + 1.5) + centre,
123 TPointD(point.x - 1.5, point.y + 0.5) + centre);
124 tglDrawSegment(TPointD(point.x - 1.5, point.y + 0.5) + centre,
125 TPointD(point.x - 0.5, point.y + 0.5) + centre);
126 tglDrawSegment(TPointD(point.y + 0.5, -point.x + 1.5) + centre,
127 TPointD(point.y - 0.5, -point.x + 1.5) + centre);
128 tglDrawSegment(TPointD(point.y - 0.5, -point.x + 1.5) + centre,
129 TPointD(point.y - 0.5, -point.x + 0.5) + centre);
130 tglDrawSegment(TPointD(-point.x + 0.5, -point.y - 0.5) + centre,
131 TPointD(-point.x + 0.5, -point.y + 0.5) + centre);
132 tglDrawSegment(TPointD(-point.x + 0.5, -point.y + 0.5) + centre,
133 TPointD(-point.x - 0.5, -point.y + 0.5) + centre);
134 tglDrawSegment(TPointD(-point.y - 1.5, point.x - 0.5) + centre,
135 TPointD(-point.y - 0.5, point.x - 0.5) + centre);
136 tglDrawSegment(TPointD(-point.y - 0.5, point.x - 0.5) + centre,
137 TPointD(-point.y - 0.5, point.x + 0.5) + centre);
138
139 tglDrawSegment(TPointD(point.y + 0.5, point.x - 0.5) + centre,
140 TPointD(point.y - 0.5, point.x - 0.5) + centre);
141 tglDrawSegment(TPointD(point.y - 0.5, point.x - 0.5) + centre,
142 TPointD(point.y - 0.5, point.x + 0.5) + centre);
143 tglDrawSegment(TPointD(point.x - 1.5, -point.y - 0.5) + centre,
144 TPointD(point.x - 1.5, -point.y + 0.5) + centre);
145 tglDrawSegment(TPointD(point.x - 1.5, -point.y + 0.5) + centre,
146 TPointD(point.x - 0.5, -point.y + 0.5) + centre);
147 tglDrawSegment(TPointD(-point.y - 1.5, -point.x + 1.5) + centre,
148 TPointD(-point.y - 0.5, -point.x + 1.5) + centre);
149 tglDrawSegment(TPointD(-point.y - 0.5, -point.x + 1.5) + centre,
150 TPointD(-point.y - 0.5, -point.x + 0.5) + centre);
151 tglDrawSegment(TPointD(-point.x + 0.5, point.y + 1.5) + centre,
152 TPointD(-point.x + 0.5, point.y + 0.5) + centre);
153 tglDrawSegment(TPointD(-point.x + 0.5, point.y + 0.5) + centre,
154 TPointD(-point.x - 0.5, point.y + 0.5) + centre);
155 }
156 } else {
157 if (horizontal) {
158 tglDrawSegment(TPointD(point.x - 0.5, point.y + 0.5) + centre,
159 TPointD(point.x + 0.5, point.y + 0.5) + centre);
160 tglDrawSegment(TPointD(point.y + 0.5, point.x - 0.5) + centre,
161 TPointD(point.y + 0.5, point.x + 0.5) + centre);
162 tglDrawSegment(TPointD(point.y + 0.5, -point.x + 0.5) + centre,
163 TPointD(point.y + 0.5, -point.x - 0.5) + centre);
164 tglDrawSegment(TPointD(point.x + 0.5, -point.y - 0.5) + centre,
165 TPointD(point.x - 0.5, -point.y - 0.5) + centre);
166 tglDrawSegment(TPointD(-point.x - 0.5, -point.y - 0.5) + centre,
167 TPointD(-point.x + 0.5, -point.y - 0.5) + centre);
168 tglDrawSegment(TPointD(-point.y - 0.5, -point.x + 0.5) + centre,
169 TPointD(-point.y - 0.5, -point.x - 0.5) + centre);
170 tglDrawSegment(TPointD(-point.y - 0.5, point.x - 0.5) + centre,
171 TPointD(-point.y - 0.5, point.x + 0.5) + centre);
172 tglDrawSegment(TPointD(-point.x + 0.5, point.y + 0.5) + centre,
173 TPointD(-point.x - 0.5, point.y + 0.5) + centre);
174 } else {
175 tglDrawSegment(TPointD(point.x - 0.5, point.y + 1.5) + centre,
176 TPointD(point.x - 0.5, point.y + 0.5) + centre);
177 tglDrawSegment(TPointD(point.x - 0.5, point.y + 0.5) + centre,
178 TPointD(point.x + 0.5, point.y + 0.5) + centre);
179 tglDrawSegment(TPointD(point.y + 1.5, point.x - 0.5) + centre,
180 TPointD(point.y + 0.5, point.x - 0.5) + centre);
181 tglDrawSegment(TPointD(point.y + 0.5, point.x - 0.5) + centre,
182 TPointD(point.y + 0.5, point.x + 0.5) + centre);
183 tglDrawSegment(TPointD(point.y + 1.5, -point.x + 0.5) + centre,
184 TPointD(point.y + 0.5, -point.x + 0.5) + centre);
185 tglDrawSegment(TPointD(point.y + 0.5, -point.x + 0.5) + centre,
186 TPointD(point.y + 0.5, -point.x - 0.5) + centre);
187 tglDrawSegment(TPointD(point.x - 0.5, -point.y - 1.5) + centre,
188 TPointD(point.x - 0.5, -point.y - 0.5) + centre);
189 tglDrawSegment(TPointD(point.x - 0.5, -point.y - 0.5) + centre,
190 TPointD(point.x + 0.5, -point.y - 0.5) + centre);
191
192 tglDrawSegment(TPointD(-point.x + 0.5, -point.y - 1.5) + centre,
193 TPointD(-point.x + 0.5, -point.y - 0.5) + centre);
194 tglDrawSegment(TPointD(-point.x + 0.5, -point.y - 0.5) + centre,
195 TPointD(-point.x - 0.5, -point.y - 0.5) + centre);
196 tglDrawSegment(TPointD(-point.y - 1.5, -point.x + 0.5) + centre,
197 TPointD(-point.y - 0.5, -point.x + 0.5) + centre);
198 tglDrawSegment(TPointD(-point.y - 0.5, -point.x + 0.5) + centre,
199 TPointD(-point.y - 0.5, -point.x - 0.5) + centre);
200 tglDrawSegment(TPointD(-point.y - 1.5, point.x - 0.5) + centre,
201 TPointD(-point.y - 0.5, point.x - 0.5) + centre);
202 tglDrawSegment(TPointD(-point.y - 0.5, point.x - 0.5) + centre,
203 TPointD(-point.y - 0.5, point.x + 0.5) + centre);
204 tglDrawSegment(TPointD(-point.x + 0.5, point.y + 1.5) + centre,
205 TPointD(-point.x + 0.5, point.y + 0.5) + centre);
206 tglDrawSegment(TPointD(-point.x + 0.5, point.y + 0.5) + centre,
207 TPointD(-point.x - 0.5, point.y + 0.5) + centre);
208 }
209 }
210 }
211
212 //-------------------------------------------------------------------------------------------------------
213
drawEmptyCircle(int thick,const TPointD & mousePos,bool isPencil,bool isLxEven,bool isLyEven)214 void drawEmptyCircle(int thick, const TPointD &mousePos, bool isPencil,
215 bool isLxEven, bool isLyEven) {
216 TPointD pos = mousePos;
217 if (isLxEven) pos.x += 0.5;
218 if (isLyEven) pos.y += 0.5;
219 if (!isPencil)
220 tglDrawCircle(pos, (thick + 1) * 0.5);
221 else {
222 int x = 0, y = tround((thick * 0.5) - 0.5);
223 int d = 3 - 2 * (int)(thick * 0.5);
224 bool horizontal = true, isDecimal = thick % 2 != 0;
225 drawLine(TPointD(x, y), pos, horizontal, isDecimal);
226 while (y > x) {
227 if (d < 0) {
228 d = d + 4 * x + 6;
229 horizontal = true;
230 } else {
231 d = d + 4 * (x - y) + 10;
232 horizontal = false;
233 y--;
234 }
235 x++;
236 drawLine(TPointD(x, y), pos, horizontal, isDecimal);
237 }
238 }
239 }
240
241 } // namespace
242
243 //-----------------------------------------------------------------------------
244
245 class FingerTool final : public TTool {
246 Q_DECLARE_TR_FUNCTIONS(FingerTool)
247
248 RasterStrokeGenerator *m_rasterTrack;
249
250 bool m_firstTime;
251
252 double m_pointSize, m_distance2;
253
254 bool m_selecting;
255 TTileSaverCM32 *m_tileSaver;
256
257 TPointD m_mousePos;
258
259 TIntProperty m_toolSize;
260 TBoolProperty m_invert;
261 TPropertyGroup m_prop;
262 int m_cursor;
263
264 /*--- 作業中のFrameIdをクリック時に保存し、マウスリリース時(Undoの登録時)
265 に別のフレームに移動している場合があるため ---*/
266 TFrameId m_workingFrameId;
267
268 /*-- 最初のクリックでStyleを切り替える --*/
269 void pick(const TPointD &pos);
270
271 public:
272 FingerTool();
273
274 void draw() override;
275 void update(TToonzImageP ti, TRectD area);
276
277 void updateTranslation() override;
278
279 void leftButtonDown(const TPointD &pos, const TMouseEvent &e) override;
280 void leftButtonDrag(const TPointD &pos, const TMouseEvent &e) override;
281 void leftButtonUp(const TPointD &pos, const TMouseEvent &) override;
282 void mouseMove(const TPointD &pos, const TMouseEvent &e) override;
283 void onEnter() override;
284 void onLeave() override;
285 void onActivate() override;
286 void onDeactivate() override;
287 bool onPropertyChanged(std::string propertyName) override;
288
getProperties(int targetType)289 TPropertyGroup *getProperties(int targetType) override { return &m_prop; }
getToolType() const290 ToolType getToolType() const override { return TTool::LevelWriteTool; }
getCursorId() const291 int getCursorId() const override { return m_cursor; }
292
getColorClass() const293 int getColorClass() const { return 2; }
294
295 /*--
296 * ドラッグ中にツールが切り替わった場合に備え、onDeactivateにもMouseReleaseと同じ処理を行う
297 * --*/
298 void finishBrush();
299 };
300
301 FingerTool fingerTool;
302
303 //=============================================================================
304 //
305 // InkPaintTool implemention
306 //
307 //-----------------------------------------------------------------------------
308
FingerTool()309 FingerTool::FingerTool()
310 : TTool("T_Finger")
311 , m_rasterTrack(0)
312 , m_pointSize(-1)
313 , m_selecting(false)
314 , m_tileSaver(0)
315 , m_cursor(ToolCursor::EraserCursor)
316 , m_toolSize("Size:", 1, 1000, 10, false)
317 , m_invert("Invert", false)
318 , m_firstTime(true)
319 , m_workingFrameId(TFrameId()) {
320 bind(TTool::ToonzImage);
321
322 m_toolSize.setNonLinearSlider();
323
324 m_prop.bind(m_toolSize);
325 m_prop.bind(m_invert);
326
327 m_invert.setId("Invert");
328 }
329
330 //-----------------------------------------------------------------------------
331
updateTranslation()332 void FingerTool::updateTranslation() {
333 m_toolSize.setQStringName(tr("Size:"));
334 m_invert.setQStringName(tr("Invert", NULL));
335 }
336
337 //-----------------------------------------------------------------------------
338
draw()339 void FingerTool::draw() {
340 if (m_pointSize == -1) {
341 return;
342 }
343
344 // If toggled off, don't draw brush outline
345 if (!Preferences::instance()->isCursorOutlineEnabled()) return;
346
347 TToonzImageP ti = (TToonzImageP)getImage(false);
348 if (!ti) return;
349 TRasterP ras = ti->getRaster();
350 int lx = ras->getLx();
351 int ly = ras->getLy();
352
353 if ((ToonzCheck::instance()->getChecks() & ToonzCheck::eInk) ||
354 (ToonzCheck::instance()->getChecks() & ToonzCheck::ePaint))
355 glColor3d(0.5, 0.8, 0.8);
356 else
357 glColor3d(1.0, 0.0, 0.0);
358
359 drawEmptyCircle(m_toolSize.getValue(), m_mousePos, true, lx % 2 == 0,
360 ly % 2 == 0);
361 }
362
363 //-----------------------------------------------------------------------------
364
365 const UINT pointCount = 20;
366
367 //-----------------------------------------------------------------------------
368
onPropertyChanged(std::string propertyName)369 bool FingerTool::onPropertyChanged(std::string propertyName) {
370 /*-- サイズ --*/
371 if (propertyName == m_toolSize.getName()) {
372 FingerSize = m_toolSize.getValue();
373 double x = m_toolSize.getValue();
374
375 double minRange = 1;
376 double maxRange = 100;
377
378 double minSize = 0.01;
379 double maxSize = 100;
380
381 m_pointSize =
382 (x - minRange) / (maxRange - minRange) * (maxSize - minSize) + minSize;
383 invalidate();
384 }
385
386 // Invert
387 else if (propertyName == m_invert.getName()) {
388 FingerInvert = (int)(m_invert.getValue());
389 }
390
391 return true;
392 }
393
394 //-----------------------------------------------------------------------------
395
leftButtonDown(const TPointD & pos,const TMouseEvent & e)396 void FingerTool::leftButtonDown(const TPointD &pos, const TMouseEvent &e) {
397 pick(pos);
398
399 m_selecting = true;
400 TImageP image(getImage(true));
401
402 if (TToonzImageP ti = image) {
403 TRasterCM32P ras = ti->getRaster();
404 if (ras) {
405 int thickness = m_toolSize.getValue();
406 int styleId = TTool::getApplication()->getCurrentLevelStyleIndex();
407 TTileSetCM32 *tileSet = new TTileSetCM32(ras->getSize());
408 m_tileSaver = new TTileSaverCM32(ras, tileSet);
409 m_rasterTrack = new RasterStrokeGenerator(
410 ras, FINGER, INK, styleId,
411 TThickPoint(pos + convert(ras->getCenter()), thickness),
412 m_invert.getValue(), 0, false);
413
414 /*-- 作業中Fidを現在のFIDにする --*/
415 m_workingFrameId = getFrameId();
416
417 m_tileSaver->save(m_rasterTrack->getLastRect());
418 TRect modifiedBbox = m_rasterTrack->generateLastPieceOfStroke(true);
419 invalidate();
420 }
421 }
422 }
423
424 //-----------------------------------------------------------------------------
425
leftButtonDrag(const TPointD & pos,const TMouseEvent & e)426 void FingerTool::leftButtonDrag(const TPointD &pos, const TMouseEvent &e) {
427 if (!m_selecting) return;
428
429 m_mousePos = pos;
430 if (TToonzImageP ri = TImageP(getImage(true))) {
431 /*--- マウスを動かしながらショートカットで切り替わった場合、
432 いきなりleftButtonDragから呼ばれることがあり、
433 m_rasterTrackが無くて落ちることがある。 ---*/
434 if (m_rasterTrack) {
435 int thickness = m_toolSize.getValue();
436 m_rasterTrack->add(
437 TThickPoint(pos + convert(ri->getRaster()->getCenter()), thickness));
438 m_tileSaver->save(m_rasterTrack->getLastRect());
439 TRect modifiedBbox = m_rasterTrack->generateLastPieceOfStroke(true);
440 invalidate();
441 }
442 }
443 }
444
445 //-----------------------------------------------------------------------------
446
leftButtonUp(const TPointD & pos,const TMouseEvent &)447 void FingerTool::leftButtonUp(const TPointD &pos, const TMouseEvent &) {
448 if (!m_selecting) return;
449
450 m_mousePos = pos;
451
452 finishBrush();
453 }
454
455 //-----------------------------------------------------------------------------
456
mouseMove(const TPointD & pos,const TMouseEvent & e)457 void FingerTool::mouseMove(const TPointD &pos, const TMouseEvent &e) {
458 m_mousePos = pos;
459 TPointD pp(tround(pos.x), tround(pos.y));
460 m_mousePos = pp;
461 invalidate();
462 }
463
464 //-----------------------------------------------------------------------------
465
onEnter()466 void FingerTool::onEnter() {
467 if (m_firstTime) {
468 m_invert.setValue(FingerInvert ? 1 : 0);
469 m_toolSize.setValue(FingerSize);
470 m_firstTime = false;
471 }
472 double x = m_toolSize.getValue();
473
474 double minRange = 1;
475 double maxRange = 100;
476
477 double minSize = 0.01;
478 double maxSize = 100;
479
480 m_pointSize =
481 (x - minRange) / (maxRange - minRange) * (maxSize - minSize) + minSize;
482
483 if ((TToonzImageP)getImage(false))
484 m_cursor = ToolCursor::PenCursor;
485 else
486 m_cursor = ToolCursor::CURSOR_NO;
487 }
488
489 //-----------------------------------------------------------------------------
490
onLeave()491 void FingerTool::onLeave() { m_pointSize = -1; }
492
493 //-----------------------------------------------------------------------------
494
onActivate()495 void FingerTool::onActivate() { onEnter(); }
496
497 //-----------------------------------------------------------------------------
498
onDeactivate()499 void FingerTool::onDeactivate() {
500 /*---
501 * マウスドラッグ中(m_selecting=true)にツールが切り替わったときに線を終わらせる
502 * ---*/
503 if (m_selecting) finishBrush();
504 }
505
506 //-----------------------------------------------------------------------------
507 /*!
508 * ドラッグ中にツールが切り替わった場合に備え、onDeactivateにもMouseReleaseと同じ処理を行う
509 */
finishBrush()510 void FingerTool::finishBrush() {
511 if (TToonzImageP ti = (TToonzImageP)getImage(true)) {
512 if (m_rasterTrack) {
513 int thickness = m_toolSize.getValue();
514 m_rasterTrack->add(TThickPoint(
515 m_mousePos + convert(ti->getRaster()->getCenter()), thickness));
516 m_tileSaver->save(m_rasterTrack->getLastRect());
517 TRect modifiedBbox = m_rasterTrack->generateLastPieceOfStroke(true, true);
518
519 TTool::Application *app = TTool::getApplication();
520 TXshLevel *level = app->getCurrentLevel()->getLevel();
521 TXshSimpleLevelP simLevel = level->getSimpleLevel();
522
523 TFrameId frameId =
524 m_workingFrameId.isEmptyFrame() ? getCurrentFid() : m_workingFrameId;
525
526 TUndoManager::manager()->add(new FingerUndo(
527 m_tileSaver->getTileSet(), m_rasterTrack->getPointsSequence(),
528 m_rasterTrack->getStyleId(), m_rasterTrack->isSelective(),
529 simLevel.getPointer(), frameId));
530 ToolUtils::updateSaveBox();
531
532 /*! FIdを指定して、作業中にフレームが動いても、
533 クリック時のFidのサムネイルが更新されるようにする。
534 */
535 notifyImageChanged(frameId);
536
537 invalidate();
538 delete m_rasterTrack;
539 m_rasterTrack = 0;
540 delete m_tileSaver;
541
542 /*-- 作業中fIdをリセット --*/
543 m_workingFrameId = TFrameId();
544 }
545 }
546 m_selecting = false;
547 }
548
pick(const TPointD & pos)549 void FingerTool::pick(const TPointD &pos) {
550 int modeValue = 2; // LINES
551
552 TImageP image = getImage(false);
553 TToonzImageP ti = image;
554 TVectorImageP vi = image;
555 TXshSimpleLevel *level =
556 getApplication()->getCurrentLevel()->getSimpleLevel();
557 if (!ti || !level) return;
558
559 /*--- 画面外をpickしても拾えないようにする ---*/
560 if (!m_viewer->getGeometry().contains(pos)) return;
561
562 int subsampling = level->getImageSubsampling(getCurrentFid());
563
564 StylePicker picker(image);
565
566 int styleId =
567 picker.pickStyleId(TScale(1.0 / subsampling) * pos + TPointD(-0.5, -0.5),
568 getPixelSize() * getPixelSize(), 1.0, modeValue);
569
570 if (styleId < 0) return;
571
572 if (modeValue == 2) // LINES
573 {
574 /*--- pickLineモードのとき、取得Styleが0の場合はカレントStyleを変えない。
575 * ---*/
576 if (styleId == 0) return;
577
578 /*---
579 * pickLineモードのとき、PurePaintの部分をクリックしてもカレントStyleを変えない
580 * ---*/
581 if (ti && picker.pickTone(TScale(1.0 / subsampling) * pos +
582 TPointD(-0.5, -0.5)) == 255)
583 return;
584 }
585
586 /*--- Styleを選択している場合は選択を解除する ---*/
587 TSelection *selection =
588 TTool::getApplication()->getCurrentSelection()->getSelection();
589 if (selection) {
590 TStyleSelection *styleSelection =
591 dynamic_cast<TStyleSelection *>(selection);
592 if (styleSelection) styleSelection->selectNone();
593 }
594
595 getApplication()->setCurrentLevelStyleIndex(styleId);
596 }
597