diff --git "a/stuff/config/loc/\346\227\245\346\234\254\350\252\236/toonz.qm" "b/stuff/config/loc/\346\227\245\346\234\254\350\252\236/toonz.qm" index 50d23e5..071d2a8 100644 Binary files "a/stuff/config/loc/\346\227\245\346\234\254\350\252\236/toonz.qm" and "b/stuff/config/loc/\346\227\245\346\234\254\350\252\236/toonz.qm" differ diff --git a/stuff/config/qss/gray_048/gray_048.less b/stuff/config/qss/gray_048/gray_048.less index 5d0ce3c..c964387 100644 --- a/stuff/config/qss/gray_048/gray_048.less +++ b/stuff/config/qss/gray_048/gray_048.less @@ -277,6 +277,9 @@ QPushButton { &:checked { .base_inset(light, 10%); } + &:pressed { + .base_inset(light, 10%); + } /*lighten lilttle bit when hover*/ &:hover { .base_outset(light, 10%); diff --git a/stuff/config/qss/gray_048/gray_048.qss b/stuff/config/qss/gray_048/gray_048.qss index dcbe04f..a9a35c6 100644 --- a/stuff/config/qss/gray_048/gray_048.qss +++ b/stuff/config/qss/gray_048/gray_048.qss @@ -249,6 +249,14 @@ QPushButton:checked { border-right-color: #727272; border-bottom-color: #868686; } +QPushButton:pressed { + background-color: #4a4a4a; + border-style: inset; + border-left-color: #262626; + border-top-color: #1a1a1a; + border-right-color: #727272; + border-bottom-color: #868686; +} QPushButton:hover { background-color: #4a4a4a; border-style: outset; diff --git a/stuff/config/qss/gray_048/gray_048_mac.qss b/stuff/config/qss/gray_048/gray_048_mac.qss index d1dc2d1..f6005d4 100644 --- a/stuff/config/qss/gray_048/gray_048_mac.qss +++ b/stuff/config/qss/gray_048/gray_048_mac.qss @@ -249,6 +249,14 @@ QPushButton:checked { border-right-color: #727272; border-bottom-color: #868686; } +QPushButton:pressed { + background-color: #4a4a4a; + border-style: inset; + border-left-color: #262626; + border-top-color: #1a1a1a; + border-right-color: #727272; + border-bottom-color: #868686; +} QPushButton:hover { background-color: #4a4a4a; border-style: outset; diff --git a/stuff/config/qss/gray_072/gray_072.less b/stuff/config/qss/gray_072/gray_072.less index 4c7fe66..d8a63f4 100644 --- a/stuff/config/qss/gray_072/gray_072.less +++ b/stuff/config/qss/gray_072/gray_072.less @@ -276,6 +276,9 @@ QPushButton { &:checked { .base_inset(light, 10%); } + &:pressed { + .base_inset(light, 10%); + } /*lighten lilttle bit when hover*/ &:hover { .base_outset(light, 10%); diff --git a/stuff/config/qss/gray_072/gray_072.qss b/stuff/config/qss/gray_072/gray_072.qss index 5d8b18a..f18b35d 100644 --- a/stuff/config/qss/gray_072/gray_072.qss +++ b/stuff/config/qss/gray_072/gray_072.qss @@ -249,6 +249,14 @@ QPushButton:checked { border-right-color: #868686; border-bottom-color: #9a9a9a; } +QPushButton:pressed { + background-color: #626262; + border-style: inset; + border-left-color: #3a3a3a; + border-top-color: #1a1a1a; + border-right-color: #868686; + border-bottom-color: #9a9a9a; +} QPushButton:hover { background-color: #626262; border-style: outset; diff --git a/stuff/config/qss/gray_072/gray_072_mac.qss b/stuff/config/qss/gray_072/gray_072_mac.qss index cb96be4..d3cc3d9 100644 --- a/stuff/config/qss/gray_072/gray_072_mac.qss +++ b/stuff/config/qss/gray_072/gray_072_mac.qss @@ -249,6 +249,14 @@ QPushButton:checked { border-right-color: #868686; border-bottom-color: #9a9a9a; } +QPushButton:pressed { + background-color: #626262; + border-style: inset; + border-left-color: #3a3a3a; + border-top-color: #1a1a1a; + border-right-color: #868686; + border-bottom-color: #9a9a9a; +} QPushButton:hover { background-color: #626262; border-style: outset; diff --git a/toonz/sources/toonz/mainwindow.cpp b/toonz/sources/toonz/mainwindow.cpp index b58789f..2cedecf 100644 --- a/toonz/sources/toonz/mainwindow.cpp +++ b/toonz/sources/toonz/mainwindow.cpp @@ -1668,7 +1668,7 @@ void MainWindow::defineActions() { createMenuScanCleanupAction(MI_Cleanup, tr("&Cleanup"), ""); - createMenuScanCleanupAction(MI_PencilTest, tr("&Pencil Test..."), ""); + createMenuScanCleanupAction(MI_PencilTest, tr("&Camera Capture..."), ""); createMenuLevelAction(MI_AddFrames, tr("&Add Frames..."), ""); createMenuLevelAction(MI_Renumber, tr("&Renumber..."), ""); diff --git a/toonz/sources/toonz/penciltestpopup.cpp b/toonz/sources/toonz/penciltestpopup.cpp index ac7dd7f..261b08e 100644 --- a/toonz/sources/toonz/penciltestpopup.cpp +++ b/toonz/sources/toonz/penciltestpopup.cpp @@ -58,6 +58,9 @@ #include #include #include +#include +#include +#include using namespace DVGui; @@ -242,7 +245,8 @@ MyViewFinder::MyViewFinder(QWidget* parent) , m_camera(0) , m_showOnionSkin(false) , m_onionOpacity(128) - , m_upsideDown(false) {} + , m_upsideDown(false) + , m_countDownTime(0) {} void MyViewFinder::paintEvent(QPaintEvent* event) { QPainter p(this); @@ -274,6 +278,18 @@ void MyViewFinder::paintEvent(QPaintEvent* event) { p.drawRect(m_imageRect); p.setCompositionMode(QPainter::CompositionMode_DestinationOver); p.drawImage(m_imageRect, m_previousImage); + p.setCompositionMode(QPainter::CompositionMode_SourceOver); + } + + // draw countdown text + if (m_countDownTime > 0) { + QString str = + QTime::fromMSecsSinceStartOfDay(m_countDownTime).toString("s.zzz"); + p.setPen(Qt::yellow); + QFont font = p.font(); + font.setPixelSize(50); + p.setFont(font); + p.drawText(rect(), Qt::AlignRight | Qt::AlignBottom, str); } } @@ -303,7 +319,13 @@ PencilTestPopup::PencilTestPopup() , m_cameraImageCapture(0) , m_captureWhiteBGCue(false) , m_captureCue(false) { - setWindowTitle(tr("Pencil Test")); + setWindowTitle(tr("Camera Capture")); + + // add maximize button to the dialog + Qt::WindowFlags flags = windowFlags(); + flags |= Qt::WindowMaximizeButtonHint; + setWindowFlags(flags); + layout()->setSizeConstraint(QLayout::SetNoConstraint); std::wstring dateTime = @@ -328,6 +350,8 @@ PencilTestPopup::PencilTestPopup() m_saveInFileFld = new FileField( 0, QString("+%1").arg(QString::fromStdString(TProject::Extras))); QToolButton* nextLevelButton = new QToolButton(this); + m_saveOnCaptureCB = + new QCheckBox(tr("Save images as they are captured"), this); QGroupBox* imageFrame = new QGroupBox(tr("Image adjust"), this); m_colorTypeCombo = new QComboBox(this); @@ -344,13 +368,19 @@ PencilTestPopup::PencilTestPopup() m_onionSkinCB = new QCheckBox(tr("Show onion skin"), this); m_onionOpacityFld = new IntField(this); - QPushButton* captureButton = new QPushButton(tr("Capture"), this); - QPushButton* closeButton = new QPushButton(tr("Close"), this); + QGroupBox* timerFrame = new QGroupBox(tr("Interval timer"), this); + m_timerCB = new QCheckBox(tr("Use interval timer"), this); + m_timerIntervalFld = new IntField(this); + m_captureTimer = new QTimer(this); + m_countdownTimer = new QTimer(this); + + m_captureButton = new QPushButton(tr("Capture\n[Return key]"), this); + QPushButton* closeButton = new QPushButton(tr("Close"), this); //---- m_resolutionCombo->setMaximumWidth(fontMetrics().width("0000 x 0000") + 25); m_fileTypeCombo->addItems({"jpg", "png", "tga", "tif"}); - m_fileTypeCombo->setCurrentIndex(1); + m_fileTypeCombo->setCurrentIndex(0); fileFrame->setObjectName("CleanupSettingsFrame"); // Exclude all character which cannot fit in a filepath (Win). @@ -362,6 +392,7 @@ PencilTestPopup::PencilTestPopup() nextLevelButton->setFixedSize(24, 24); nextLevelButton->setArrowType(Qt::RightArrow); nextLevelButton->setToolTip(tr("Next Level")); + m_saveOnCaptureCB->setChecked(true); imageFrame->setObjectName("CleanupSettingsFrame"); m_colorTypeCombo->addItems({"Color", "Grayscale", "Black & White"}); @@ -385,8 +416,21 @@ PencilTestPopup::PencilTestPopup() m_onionOpacityFld->setValue(50); m_onionOpacityFld->setDisabled(true); - captureButton->setObjectName("LargeSizedText"); - captureButton->setFixedHeight(80); + timerFrame->setObjectName("CleanupSettingsFrame"); + m_timerCB->setChecked(false); + m_timerIntervalFld->setRange(0, 60); + m_timerIntervalFld->setValue(10); + m_timerIntervalFld->setDisabled(true); + // Make the interval timer single-shot. When the capture finished, restart + // timer for next frame. + // This is because capturing and saving the image needs some time. + m_captureTimer->setSingleShot(true); + + m_captureButton->setObjectName("LargeSizedText"); + m_captureButton->setFixedHeight(80); + QCommonStyle style; + m_captureButton->setIcon(style.standardIcon(QStyle::SP_DialogOkButton)); + m_captureButton->setIconSize(QSize(30, 30)); //---- layout ---- QHBoxLayout* mainLay = new QHBoxLayout(); @@ -460,6 +504,8 @@ PencilTestPopup::PencilTestPopup() saveInLay->addWidget(m_saveInFileFld, 1); } fileLay->addLayout(saveInLay, 0); + + fileLay->addWidget(m_saveOnCaptureCB, 0); } fileFrame->setLayout(fileLay); rightLay->addWidget(fileFrame, 0); @@ -504,21 +550,37 @@ PencilTestPopup::PencilTestPopup() displayLay->setHorizontalSpacing(3); displayLay->setVerticalSpacing(10); { - displayLay->addWidget(m_onionSkinCB, 0, 0, 1, 3); + displayLay->addWidget(m_onionSkinCB, 0, 0, 1, 2); displayLay->addWidget(new QLabel(tr("Opacity(%):"), this), 1, 0, Qt::AlignRight); - displayLay->addWidget(m_onionOpacityFld, 1, 1, 1, 2); + displayLay->addWidget(m_onionOpacityFld, 1, 1); } displayLay->setColumnStretch(0, 0); - displayLay->setColumnStretch(1, 0); - displayLay->setColumnStretch(2, 1); + displayLay->setColumnStretch(1, 1); + // displayLay->setColumnStretch(2, 1); displayFrame->setLayout(displayLay); rightLay->addWidget(displayFrame); + QGridLayout* timerLay = new QGridLayout(); + timerLay->setMargin(10); + timerLay->setHorizontalSpacing(3); + timerLay->setVerticalSpacing(10); + { + timerLay->addWidget(m_timerCB, 0, 0, 1, 2); + + timerLay->addWidget(new QLabel(tr("Interval(sec):"), this), 1, 0, + Qt::AlignRight); + timerLay->addWidget(m_timerIntervalFld, 1, 1); + } + timerLay->setColumnStretch(0, 0); + timerLay->setColumnStretch(1, 1); + timerFrame->setLayout(timerLay); + rightLay->addWidget(timerFrame); + rightLay->addStretch(1); - rightLay->addWidget(captureButton, 0); + rightLay->addWidget(m_captureButton, 0); rightLay->addSpacing(20); rightLay->addWidget(closeButton, 0); } @@ -548,9 +610,16 @@ PencilTestPopup::PencilTestPopup() SLOT(onOnionOpacityFldEdited())); ret = ret && connect(m_upsideDownCB, SIGNAL(toggled(bool)), m_cameraViewfinder, SLOT(onUpsideDownChecked(bool))); + ret = ret && connect(m_timerCB, SIGNAL(toggled(bool)), this, + SLOT(onTimerCBToggled(bool))); + ret = ret && connect(m_captureTimer, SIGNAL(timeout()), this, + SLOT(onCaptureTimerTimeout())); + ret = ret && + connect(m_countdownTimer, SIGNAL(timeout()), this, SLOT(onCountDown())); + ret = ret && connect(closeButton, SIGNAL(clicked()), this, SLOT(reject())); - ret = - ret && connect(captureButton, SIGNAL(clicked()), this, SLOT(onCapture())); + ret = ret && connect(m_captureButton, SIGNAL(clicked(bool)), this, + SLOT(onCaptureButtonClicked(bool))); assert(ret); refreshCameraList(); @@ -634,13 +703,14 @@ void PencilTestPopup::onCameraListComboActivated(int index) { QString("%1 x %2").arg(sizes.at(s).width()).arg(sizes.at(s).height())); } if (!sizes.isEmpty()) { - m_resolutionCombo->setCurrentIndex(0); + // select the largest available resolution + m_resolutionCombo->setCurrentIndex(m_resolutionCombo->count() - 1); QCameraViewfinderSettings settings = m_currentCamera->viewfinderSettings(); - settings.setResolution(sizes[0]); + settings.setResolution(sizes.last()); m_currentCamera->setViewfinderSettings(settings); QImageEncoderSettings imageEncoderSettings; imageEncoderSettings.setCodec("PNG"); - imageEncoderSettings.setResolution(sizes[0]); + imageEncoderSettings.setResolution(sizes.last()); m_cameraImageCapture->setEncodingSettings(imageEncoderSettings); } m_cameraViewfinder->setCamera(m_currentCamera); @@ -756,6 +826,19 @@ void PencilTestPopup::onImageCaptured(int id, const QImage& image) { if (importImage(procImg)) { m_cameraViewfinder->setPreviousImage(procImg); m_frameNumberEdit->setValue(m_frameNumberEdit->getValue() + 1); + + // restart interval timer for capturing next frame (it is single shot) + if (m_timerCB->isChecked() && m_captureButton->isChecked()) { + m_captureTimer->start(m_timerIntervalFld->getValue() * 1000); + // restart the count down as well (for aligning the timing. It is not + // single shot) + if (m_timerIntervalFld->getValue() != 0) m_countdownTimer->start(100); + } + } + // if capture was failed, stop interval capturing + else if (m_timerCB->isChecked()) { + m_captureButton->setChecked(false); + onCaptureButtonClicked(false); } } } @@ -779,11 +862,42 @@ void PencilTestPopup::timerEvent(QTimerEvent* event) { void PencilTestPopup::showEvent(QShowEvent* event) { m_timerId = startTimer(10); + + // if there is another action of which "return" key is assigned as short cut + // key, + // then release the shortcut key temporary while the popup opens + QAction* action = CommandManager::instance()->getActionFromShortcut("Return"); + if (action) action->setShortcut(QKeySequence("")); +} + +//----------------------------------------------------------------------------- + +void PencilTestPopup::hideEvent(QHideEvent* event) { + killTimer(m_timerId); + + // set back the "return" short cut key + QAction* action = CommandManager::instance()->getActionFromShortcut("Return"); + if (action) action->setShortcut(QKeySequence("Return")); + + // stop interval timer if it is active + if (m_timerCB->isChecked() && m_captureButton->isChecked()) { + m_captureButton->setChecked(false); + onCaptureButtonClicked(false); + } } //----------------------------------------------------------------------------- -void PencilTestPopup::hideEvent(QHideEvent* event) { killTimer(m_timerId); } +void PencilTestPopup::keyPressEvent(QKeyEvent* event) { + // override return (or enter) key as shortcut key for capturing + if (event->key() == Qt::Key_Return || event->key() == Qt::Key_Enter) { + // show button-clicking animation followed by calling + // onCaptureButtonClicked() + m_captureButton->animateClick(); + event->accept(); + } else + event->ignore(); +} //----------------------------------------------------------------------------- @@ -824,7 +938,51 @@ void PencilTestPopup::onOnionOpacityFldEdited() { //----------------------------------------------------------------------------- -void PencilTestPopup::onCapture() { m_captureCue = true; } +void PencilTestPopup::onTimerCBToggled(bool on) { + m_timerIntervalFld->setEnabled(on); + m_captureButton->setCheckable(on); + if (on) + m_captureButton->setText(tr("Start Capturing\n[Return key]")); + else + m_captureButton->setText(tr("Capture\n[Return key]")); +} + +//----------------------------------------------------------------------------- + +void PencilTestPopup::onCaptureButtonClicked(bool on) { + if (m_timerCB->isChecked()) { + m_timerCB->setDisabled(on); + m_timerIntervalFld->setDisabled(on); + // start interval capturing + if (on) { + m_captureButton->setText(tr("Stop Capturing\n[Return key]")); + m_captureTimer->start(m_timerIntervalFld->getValue() * 1000); + if (m_timerIntervalFld->getValue() != 0) m_countdownTimer->start(100); + } + // stop interval capturing + else { + m_captureButton->setText(tr("Start Capturing\n[Return key]")); + m_captureTimer->stop(); + m_countdownTimer->stop(); + // hide the count down text + m_cameraViewfinder->showCountDownTime(0); + } + } + // capture immediately + else + m_captureCue = true; +} + +//----------------------------------------------------------------------------- + +void PencilTestPopup::onCaptureTimerTimeout() { m_captureCue = true; } + +//----------------------------------------------------------------------------- + +void PencilTestPopup::onCountDown() { + m_cameraViewfinder->showCountDownTime( + m_captureTimer->isActive() ? m_captureTimer->remainingTime() : 0); +} //----------------------------------------------------------------------------- /*! referenced from LevelCreatePopup::apply() @@ -952,6 +1110,8 @@ bool PencilTestPopup::importImage(QImage& image) { /* set dirty flag */ sl->getProperties()->setDirtyFlag(true); + if (m_saveOnCaptureCB->isChecked()) sl->save(); + /* placement in xsheet */ int row = app->getCurrentFrame()->getFrame(); int col = app->getCurrentColumn()->getColumnIndex(); diff --git a/toonz/sources/toonz/penciltestpopup.h b/toonz/sources/toonz/penciltestpopup.h index c017060..7b56e1f 100644 --- a/toonz/sources/toonz/penciltestpopup.h +++ b/toonz/sources/toonz/penciltestpopup.h @@ -17,6 +17,7 @@ class QSlider; class QCheckBox; class QPushButton; class QVideoFrame; +class QTimer; namespace DVGui { class FileField; @@ -36,6 +37,8 @@ class MyViewFinder : public QFrame { QCamera* m_camera; QRect m_imageRect; + int m_countDownTime; + bool m_showOnionSkin; int m_onionOpacity; bool m_upsideDown; @@ -51,6 +54,11 @@ public: void setOnionOpacity(int value) { m_onionOpacity = value; } void setPreviousImage(QImage& prevImage) { m_previousImage = prevImage; } + void showCountDownTime(int time) { + m_countDownTime = time; + repaint(); + } + protected: void paintEvent(QPaintEvent* event); void resizeEvent(QResizeEvent* event); @@ -73,12 +81,15 @@ class PencilTestPopup : public DVGui::Dialog { QComboBox *m_cameraListCombo, *m_resolutionCombo, *m_fileTypeCombo, *m_colorTypeCombo; QLineEdit* m_levelNameEdit; - QCheckBox *m_upsideDownCB, *m_onionSkinCB; - QPushButton *m_fileFormatOptionButton, *m_captureWhiteBGButton; + QCheckBox *m_upsideDownCB, *m_onionSkinCB, *m_saveOnCaptureCB, *m_timerCB; + QPushButton *m_fileFormatOptionButton, *m_captureWhiteBGButton, + *m_captureButton; DVGui::FileField* m_saveInFileFld; DVGui::IntLineEdit* m_frameNumberEdit; DVGui::IntField *m_thresholdFld, *m_contrastFld, *m_brightnessFld, - *m_bgReductionFld, *m_onionOpacityFld; + *m_bgReductionFld, *m_onionOpacityFld, *m_timerIntervalFld; + + QTimer *m_captureTimer, *m_countdownTimer; QImage m_whiteBGImg; @@ -99,6 +110,8 @@ protected: void showEvent(QShowEvent* event); void hideEvent(QHideEvent* event); + void keyPressEvent(QKeyEvent* event); + protected slots: void refreshCameraList(); void onCameraListComboActivated(int index); @@ -110,8 +123,11 @@ protected slots: void onCaptureWhiteBGButtonPressed(); void onOnionCBToggled(bool); void onOnionOpacityFldEdited(); + void onTimerCBToggled(bool); + void onCaptureTimerTimeout(); + void onCountDown(); - void onCapture(); + void onCaptureButtonClicked(bool); }; #endif \ No newline at end of file diff --git a/toonz/sources/translations/japanese/toonz.ts b/toonz/sources/translations/japanese/toonz.ts index 53be825..d8616c8 100644 --- a/toonz/sources/translations/japanese/toonz.ts +++ b/toonz/sources/translations/japanese/toonz.ts @@ -3435,7 +3435,7 @@ Do you want to create it? Onion Skin - オニオンスキン + オニオンスキン Duplicate @@ -3815,7 +3815,7 @@ Do you want to create it? Pressure sensibility - 圧力感度 + 圧力感度 Segment Ink @@ -4407,7 +4407,7 @@ Do you want to create it? &Pencil Test... - ラインテスト (&P)... + ラインテスト (&P)... Drawing Substitution Forward @@ -4425,6 +4425,30 @@ Do you want to create it? Similar Drawing Substitution Backward + + &Camera Capture... + カメラから取り込む (&C)... + + + Toggle Maximize Panel + + + + Toggle Main Window's Full Screen Mode + + + + Onion Skin Toggle + オニオンスキン表示/非表示 + + + Zero Thick Lines + + + + Pressure sensitivity + + MatchlinesDialog @@ -5103,7 +5127,7 @@ Do you want to overwrite it? Capture - 取り込み + 取り込み Close @@ -5201,6 +5225,40 @@ Do you want to overwrite it? Failed to load %1. ファイル %1 の読み込みに失敗しました + + Save images as they are captured + 画像を取り込むと同時に保存する + + + Interval timer + インターバルタイマー + + + Use interval timer + インターバルタイマーを使用する + + + Capture +[Return key] + 取り込み +[Return キー] + + + Interval(sec): + 間隔(秒): + + + Start Capturing +[Return key] + 取り込み開始 +[Return キー] + + + Stop Capturing +[Return key] + 取り込み停止 +[Return キー] + PltGizmoPopup @@ -7409,6 +7467,14 @@ Are you sure to Change current drawing %1 + + Hide Zero Thickness Lines + + + + Show Zero Thickness Lines + + RenameAsToonzPopup @@ -8722,6 +8788,10 @@ Please commit or revert changes first. Remove 消去 + + Couldn't find any matching command. + + ShortcutTree