File indexing completed on 2024-05-12 16:23:35

0001 /***************************************************************************
0002  *   Copyright (C) 2005-2017 by Linuxstopmotion contributors;              *
0003  *   see the AUTHORS file for details.                                     *
0004  *                                                                         *
0005  *   This program is free software; you can redistribute it and/or modify  *
0006  *   it under the terms of the GNU General Public License as published by  *
0007  *   the Free Software Foundation; either version 2 of the License, or     *
0008  *   (at your option) any later version.                                   *
0009  *                                                                         *
0010  *   This program is distributed in the hope that it will be useful,       *
0011  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
0012  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
0013  *   GNU General Public License for more details.                          *
0014  *                                                                         *
0015  *   You should have received a copy of the GNU General Public License     *
0016  *   along with this program; if not, write to the                         *
0017  *   Free Software Foundation, Inc.,                                       *
0018  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
0019  ***************************************************************************/
0020 #include "toolsmenu.h"
0021 #include "ui_toolsmenu.h"
0022 
0023 #include "src/foundation/preferencestool.h"
0024 #include "graphics/icons/play.xpm"
0025 #include "graphics/icons/fastforward.xpm"
0026 #include "graphics/icons/rewind.xpm"
0027 #include "graphics/icons/steptoend.xpm"
0028 #include "graphics/icons/steptobeginning.xpm"
0029 #include "graphics/icons/stop.xpm"
0030 #include "graphics/icons/pause.xpm"
0031 #include "graphics/icons/loop.xpm"
0032 #include "graphics/icons/capture.xpm"
0033 #include "graphics/icons/cameraon.xpm"
0034 #include "graphics/icons/addframeicon.xpm"
0035 #include "graphics/icons/removeframeicon.xpm"
0036 #include "graphics/icons/newscene.xpm"
0037 #include "graphics/icons/removescene.xpm"
0038 #include "graphics/icons/gimp.xpm"
0039 
0040 #include "src/application/runanimationhandler.h"
0041 #include "src/application/modelhandler.h"
0042 #include "src/application/camerahandler.h"
0043 #include "src/domain/domainfacade.h"
0044 #include "src/presentation/frontends/qtfrontend/framebar/framebar.h"
0045 
0046 #include <QShortcut>
0047 #include <QWidget>
0048 #include <QToolTip>
0049 #include <QAction>
0050 #include <QMessageBox>
0051 #include <QPixmap>
0052 #include <QLabel>
0053 #include <QTimer>
0054 
0055 
0056 ToolsMenu::ToolsMenu(RunAnimationHandler *runAnimationHandler,
0057         ModelHandler *modelHandler, CameraHandler *cameraHandler,
0058         FrameBar *frameBar, QWidget *parent)
0059     : QWidget(parent), ui(0), runAnimationHandler(runAnimationHandler),
0060       modelHandler(modelHandler), cameraHandler(cameraHandler),
0061       frameBar(frameBar) {
0062     ui = new Ui::Form;
0063     ui->setupUi(this);
0064 
0065     loopAccel = 0;
0066     playAccel = 0;
0067     mixAccel = 0;
0068     diffAccel = 0;
0069     playbackAccel = 0;
0070 
0071     captureTimer = new QTimer(this);
0072     connect( captureTimer, SIGNAL( timeout() ), cameraHandler, SLOT(captureFrame()));
0073 
0074     setupUi();
0075     createAccelerators();
0076 }
0077 
0078 ToolsMenu::~ToolsMenu() {
0079     delete captureTimer;
0080 }
0081 
0082 void ToolsMenu::setupUi() {
0083     setFocusPolicy(Qt::ClickFocus);
0084 
0085     ui->addFramesButton->setIcon( QPixmap(addframeicon) );
0086     connect(ui->addFramesButton, SIGNAL(clicked()), modelHandler, SLOT(chooseFrame()));
0087 
0088     ui->removeFramesButton->setIcon( QPixmap(removeframeicon) );
0089     connect(ui->removeFramesButton, SIGNAL(clicked()), modelHandler, SLOT(removeFrames()));
0090 
0091     runAnimationHandler->setRemoveFramesButton(ui->removeFramesButton);
0092     modelHandler->setRemoveFramesButton(ui->removeFramesButton);
0093 
0094     ui->addSceneButton->setIcon( QPixmap(newscene) );
0095     connect(ui->addSceneButton, SIGNAL(clicked()), modelHandler, SLOT(newScene()));
0096 
0097     ui->removeSceneButton->setIcon( QPixmap(removescene) );
0098     connect(ui->removeSceneButton, SIGNAL(clicked()), modelHandler, SLOT(removeScene()));
0099 
0100     ui->cameraButton->setIcon( QPixmap(cameraon) );
0101     cameraHandler->setCameraButton(ui->cameraButton);
0102     connect( ui->cameraButton, SIGNAL(clicked()), cameraHandler, SLOT(toggleCamera()) );
0103 
0104     ui->captureGroup->hide();
0105     connect( cameraHandler, SIGNAL(cameraStateChanged(bool)), this, SLOT(activateCaptureGroup(bool)) );
0106 
0107     ui->captureButton->setIcon(  QPixmap(captureicon) );
0108     connect(ui->captureButton, SIGNAL(clicked()), cameraHandler, SLOT(captureFrame()));
0109 
0110     connect(ui->viewChooseCombo, SIGNAL(activated (int)),this, SLOT(changeViewingMode(int)));
0111 
0112     ui->unitChooseCombo->setEnabled(false);
0113     connect(ui->unitChooseCombo, SIGNAL(activated (int)),this, SLOT(changeUnitMode(int)));
0114 
0115     ui->mixSlider->setMinimum(0);
0116     ui->mixSlider->setMaximum(5);
0117     ui->mixSlider->setPageStep(1);
0118     ui->mixSlider->setValue(2);
0119     ui->mixSlider->setTickPosition(QSlider::TicksBelow);
0120     connect( ui->mixSlider, SIGNAL(valueChanged(int)), cameraHandler, SLOT(setMixCount(int)) );
0121     connect( ui->mixSlider, SIGNAL(valueChanged(int)), this, SLOT(updateSliderValue(int)) );
0122 
0123     ui->speedChooser->setMinimum(1);
0124     ui->speedChooser->setMaximum(30);
0125     ui->speedChooser->setValue(1);
0126     ui->speedChooser->setValue(PreferencesTool::get()->getPreference("fps", 10));
0127     connect( ui->speedChooser, SIGNAL(valueChanged(int)), runAnimationHandler, SLOT(setSpeed(int)));
0128     connect( ui->speedChooser, SIGNAL( valueChanged(int) ), cameraHandler, SLOT(setPlaybackSpeed(int)) );
0129     connect( ui->speedChooser, SIGNAL(editingFinished()), frameBar, SLOT(setFocus()) );
0130 
0131     ui->playButton->setIcon( QPixmap(playicon));
0132 
0133     runAnimationHandler->setPlayButton(ui->playButton);
0134     connect(ui->playButton, SIGNAL(clicked()), runAnimationHandler, SLOT(runAnimation()));
0135     ui->playButton->setEnabled(false);
0136 
0137     ui->nextFrameButton->setIcon( QPixmap(fastforwardicon) );
0138     ui->nextFrameButton->setAutoRepeat(true);
0139     connect( ui->nextFrameButton, SIGNAL(clicked()),
0140             frameBar, SLOT(selectNextFrame()) );
0141     ui->nextFrameButton->setEnabled(false);
0142 
0143     ui->previousFrameButton->setIcon( QIcon(QPixmap(rewindicon)) );
0144     ui->previousFrameButton->setAutoRepeat(true);
0145     connect( ui->previousFrameButton, SIGNAL(clicked()),
0146             frameBar, SLOT(selectPreviousFrame()) );
0147     ui->previousFrameButton->setEnabled(false);
0148 
0149     ui->toEndButton->setIcon( QIcon(QPixmap(steptoendicon)) );
0150     connect( ui->toEndButton, SIGNAL(clicked()),
0151             frameBar, SLOT(selectNextScene()) );
0152     ui->toEndButton->setEnabled(false);
0153 
0154     ui->toBeginningButton->setIcon( QIcon(QPixmap(steptobeginningicon)) );
0155     connect( ui->toBeginningButton, SIGNAL(clicked()),
0156             frameBar, SLOT(selectPreviousScene()) );
0157     ui->toBeginningButton->setEnabled(false);
0158 
0159     ui->stopButton->setIcon( QIcon(QPixmap(stopicon)) );
0160     connect( ui->stopButton, SIGNAL(clicked()), runAnimationHandler, SLOT(stopAnimation()));
0161     ui->stopButton->setEnabled(false);
0162 
0163     ui->pauseButton->setIcon( QIcon(QPixmap(pauseicon)) );
0164     ui->pauseButton->setEnabled(false);
0165     runAnimationHandler->setPauseButton(ui->pauseButton);
0166     connect(ui->pauseButton, SIGNAL(clicked()), runAnimationHandler, SLOT(pauseAnimation()));
0167 
0168     ui->loopButton->setIcon( QIcon(QPixmap(loopicon)) );
0169     runAnimationHandler->setLoopButton(ui->loopButton);
0170     connect( ui->loopButton, SIGNAL(clicked()), runAnimationHandler, SLOT(toggleLooping()) );
0171     ui->loopButton->setEnabled(false);
0172 
0173     //Launcher for the Gimp.
0174     ui->launchGimp->setIcon(QIcon(QPixmap(gimpicon)));
0175     connect(ui->launchGimp, SIGNAL(clicked()), modelHandler, SLOT(editCurrentFrame()));
0176 }
0177 
0178 
0179 void ToolsMenu::createAccelerators() {
0180     loopAccel = new QShortcut(QKeySequence(Qt::ControlModifier + Qt::Key_L), this);
0181     connect(loopAccel, SIGNAL(activated()), ui->loopButton, SLOT(toggle()));
0182 
0183     playAccel = new QShortcut(QKeySequence(Qt::Key_K), this);
0184     connect(playAccel, SIGNAL(activated()), runAnimationHandler, SLOT(toggleRunning()));
0185 
0186     mixAccel = new QShortcut(QKeySequence(Qt::Key_1), this);
0187     connect(mixAccel, SIGNAL(activated()), this, SLOT(setMixingMode()));
0188 
0189     diffAccel = new QShortcut(QKeySequence(Qt::Key_2), this);
0190     connect(diffAccel, SIGNAL(activated()), this, SLOT(setDiffingMode()));
0191 
0192     playbackAccel = new QShortcut(QKeySequence(Qt::Key_3), this);
0193     connect(playbackAccel, SIGNAL(activated()), this, SLOT(setPlaybackMode()));
0194 }
0195 
0196 
0197 void ToolsMenu::activateCaptureGroup(bool activate) {
0198     if (activate) {
0199         ui->captureGroup->show();
0200     } else {
0201         ui->captureGroup->hide();
0202     }
0203 }
0204 
0205 
0206 void ToolsMenu::retranslateStrings() {
0207     ui->speedChooserCaption->setText( tr("FPS chooser") );
0208     ui->mixSliderCaption->setText( tr("Number of images:") );
0209 
0210     ui->viewChooseCombo->clear();
0211     ui->viewChooseCombo->addItem( tr("Mix") );
0212     ui->viewChooseCombo->addItem( tr("Diff") );
0213     ui->viewChooseCombo->addItem( tr("Playback") );
0214     ui->viewChooseCombo->addItem( tr("Auto") );
0215 
0216     ui->unitChooseCombo->clear();
0217     ui->unitChooseCombo->addItem("Off");
0218     ui->unitChooseCombo->addItem( tr("Per second") );
0219     ui->unitChooseCombo->addItem( tr("Per minute") );
0220     ui->unitChooseCombo->addItem( tr("Per hour") );
0221     ui->unitChooseCombo->setCurrentIndex(0);
0222 
0223     //Tooltip and whatsthis text
0224     QString infoText =
0225             tr("<h4>Add Frames (CTRL+F)</h4> "
0226             "<p>Click on this button to <em>add</em> frames to the "
0227             "animation.</p>");
0228     ui->addFramesButton->setToolTip(infoText);
0229     ui->addFramesButton->setWhatsThis(infoText);
0230 
0231     infoText =
0232             tr("<h4>Remove Selection (Delete)</h4> "
0233             "<p>Click this button to <em>remove</em> the selected frames "
0234             "from the animation.</p>");
0235     ui->removeFramesButton->setToolTip(infoText);
0236     ui->removeFramesButton->setWhatsThis(infoText);
0237 
0238     infoText =
0239             tr("<h4>New Scene (CTRL+E)</h4> "
0240             "<p>Click this button to <em>create</em> a new <em>scene</em> "
0241             "to the animation.</p>");
0242     ui->addSceneButton->setToolTip(infoText);
0243     ui->addSceneButton->setWhatsThis(infoText);
0244 
0245     infoText =
0246             tr("<h4>Remove Scene (SHIFT+Delete)</h4> "
0247             "<p>Click this button to <em>remove</em> the selected scene "
0248             "from the animation.</p>");
0249     ui->removeSceneButton->setToolTip(infoText);
0250     ui->removeSceneButton->setWhatsThis(infoText);
0251 
0252     infoText =
0253             tr("<h4>Toggle camera on/off (C)</h4> "
0254             "<p>Click this button to toggle the camera on and off</p> ");
0255     ui->cameraButton->setToolTip(infoText);
0256     ui->cameraButton->setWhatsThis(infoText );
0257 
0258     infoText =
0259             tr("<h4>Launch Gimp</h4> "
0260             "<p>Click this button to open the active frame in Gimp</p> "
0261             "<p>Note that you can also drag images from the frame bar and drop them on Gimp</p>");
0262     ui->launchGimp->setToolTip(infoText);
0263     ui->launchGimp->setWhatsThis(infoText );
0264 
0265     infoText =
0266             tr("<h4>Capture Frame (Space)</h4> "
0267             "<p>Click on this button to <em>capture</em> a frame from the "
0268             "camera an put it in the animation</p> <p> This can also be "
0269             "done by pressing the <b>Space key</b></p>");
0270     ui->captureButton->setWhatsThis(infoText);
0271     ui->captureButton->setToolTip(infoText);
0272 
0273     infoText =
0274             tr("<h4>Number of images</h4> "
0275             "<p>By changing the value in this slidebar you can specify how many images "
0276             "backwards in the animation which should be mixed on top of the camera or "
0277             "if you are in playback mode: how many images to play. </p> "
0278             "<p>By mixing the previous image(s) onto the camera you can more easily see "
0279             "how the next shot will be in relation to the other, thereby making a smoother "
0280             "stop motion animation!</p>");
0281     ui->mixSliderCaption->setWhatsThis(infoText );
0282     ui->mixSlider->setWhatsThis(infoText);
0283 
0284     infoText =
0285             tr("<h4>FPS chooser</h4> "
0286             "<p>By changing the value in this "
0287             "chooser you set which speed the "
0288             "animation in the <b>FrameView</b> "
0289             "should run at.</p> "
0290             "<p>To start an animation press the "
0291             "<b>Run Animation</b> button.</p>");
0292     ui->speedChooserCaption->setWhatsThis(infoText );
0293     ui->speedChooser->setWhatsThis(infoText);
0294 
0295     infoText = tr("<h4>Play animation (K, P)</h4>");
0296     ui->playButton->setToolTip(infoText);
0297 
0298     infoText = tr("<h4>Stop animation (K, P)</h4>");
0299     ui->stopButton->setToolTip(infoText);
0300 
0301     infoText = tr("<h4>Previous frame (J, Left)</h4>");
0302     ui->previousFrameButton->setToolTip(infoText);
0303 
0304     infoText = tr("<h4>Next frame (L, Right)</h4>");
0305     ui->nextFrameButton->setToolTip(infoText);
0306 
0307     infoText = tr("<h4>Previous scene (I)</h4>");
0308     ui->toBeginningButton->setToolTip(infoText);
0309 
0310     infoText = tr("<h4>Next scene (O)</h4>");
0311     ui->toEndButton->setToolTip(infoText);
0312 
0313     infoText =
0314             tr("<h4>Loop animation (CTRL+L)</h4> <p>With this button you can set whether "
0315             "you want the animation to play to the end, or to loop indefinitely.</p>");
0316     ui->loopButton->setToolTip(infoText);
0317 }
0318 
0319 
0320 void ToolsMenu::updateSliderValue(int sliderValue) {
0321     if ( captureTimer->isActive() && sliderValue != 0) {
0322         int factor = 0;
0323         int index = ui->unitChooseCombo->currentIndex();
0324         switch (index) {
0325             case 1:
0326                 factor = 1000;
0327                 break;
0328             case 2:
0329                 factor = 60000;
0330                 break;
0331             case 3:
0332                 factor = 3600000;
0333                 break;
0334         }
0335         captureTimer->setInterval(factor / sliderValue);
0336     }
0337 }
0338 
0339 
0340 void ToolsMenu::setMixingMode() {
0341     changeViewingMode(0);
0342 }
0343 
0344 
0345 void ToolsMenu::setDiffingMode() {
0346     changeViewingMode(1);
0347 }
0348 
0349 
0350 void ToolsMenu::setPlaybackMode() {
0351     changeViewingMode(2);
0352 }
0353 
0354 
0355 void ToolsMenu::changeViewingMode(int index) {
0356     if ( cameraHandler->setViewMode(index) ) {
0357         ui->viewChooseCombo->setCurrentIndex(index);
0358         ui->unitChooseCombo->setCurrentIndex(0);
0359         switch (index) {
0360             case 0:
0361             {
0362                 ui->mixSlider->setValue(PreferencesTool::get()->getPreference("mixcount", 2));
0363                 ui->mixSlider->setMaximum(5);
0364                 ui->mixSlider->setEnabled(true);
0365                 ui->mixSliderCaption->setEnabled(true);
0366                 ui->unitChooseCombo->setEnabled(false);
0367                 captureTimer->stop();
0368                 break;
0369             }
0370             case 2:
0371             {
0372                 ui->mixSlider->setMaximum(50);
0373                 ui->mixSlider->setValue(PreferencesTool::get()->getPreference("playbackcount", 5));
0374                 ui->mixSliderCaption->setEnabled(true);
0375                 ui->mixSlider->setEnabled(true);
0376                 ui->unitChooseCombo->setEnabled(false);
0377                 captureTimer->stop();
0378                 break;
0379             }
0380             case 3:
0381             {
0382                 ui->mixSlider->setMaximum(10);
0383                 ui->mixSlider->setValue(1);
0384                 ui->mixSliderCaption->setEnabled(true);
0385                 ui->mixSlider->setEnabled(true);
0386                 ui->unitChooseCombo->setEnabled(true);
0387                 break;
0388             }
0389             default:
0390             {
0391                 ui->mixSlider->setEnabled(false);
0392                 ui->mixSliderCaption->setEnabled(false);
0393                 ui->unitChooseCombo->setEnabled(false);
0394                 captureTimer->stop();
0395                 break;
0396             }
0397         }
0398     } else {
0399         QMessageBox::warning(this, tr("Notice"), tr(
0400                 "Playback only currently works when running the grabber "
0401                 "as a daemon. Go to the preferences menu (CTRL+P) to switch "
0402                 "to running the image grabbing as a daemon."),
0403                 QMessageBox::Ok,
0404                 QMessageBox::NoButton,
0405                 QMessageBox::NoButton);
0406         ui->viewChooseCombo->setCurrentIndex(0);
0407         cameraHandler->setViewMode(0);
0408     }
0409 }
0410 
0411 
0412 void ToolsMenu::changeUnitMode(int index) {
0413     int sliderValue = ui->mixSlider->value();
0414     if (sliderValue == 0 || index == 0) {
0415         if (captureTimer->isActive()) {
0416             captureTimer->stop();
0417         }
0418         return;
0419     }
0420 
0421     int factor = 0;
0422     switch (index) {
0423         case 1:
0424             factor = 1000;
0425             break;
0426         case 2:
0427             factor = 60000;
0428             break;
0429         case 3:
0430             factor = 3600000;
0431             break;
0432         default:
0433             if ( captureTimer->isActive() ) {
0434                 captureTimer->stop();
0435             }
0436             break;
0437     }
0438 
0439     if ( captureTimer->isActive() == false) {
0440         // Grab the first frame manually
0441         cameraHandler->captureFrame();
0442         // then grab at the given interval
0443         captureTimer->start(factor / sliderValue);
0444     } else {
0445         captureTimer->setInterval(factor / sliderValue);
0446     }
0447 }
0448 
0449 
0450 void ToolsMenu::fixNavigationButtons(int modelSize) {
0451     //Not <=1 because it is signed with a meaning for -1.
0452     if (modelSize == 0 || modelSize == 1) {
0453         if (ui->previousFrameButton->isEnabled()) {
0454             ui->previousFrameButton->setEnabled(false);
0455             ui->nextFrameButton->setEnabled(false);
0456             ui->playButton->setEnabled(false);
0457             ui->loopButton->setEnabled(false);
0458             ui->pauseButton->setEnabled(false);
0459             ui->stopButton->setEnabled(false);
0460             ui->toEndButton->setEnabled(false);
0461             ui->toBeginningButton->setEnabled(false);
0462         }
0463     } else if (modelSize >= 2) {
0464         if ( !ui->previousFrameButton->isEnabled() && !cameraHandler->isCameraRunning() ) {
0465             ui->previousFrameButton->setEnabled(true);
0466             ui->nextFrameButton->setEnabled(true);
0467             ui->playButton->setEnabled(true);
0468             ui->loopButton->setEnabled(true);
0469             ui->pauseButton->setEnabled(true);
0470             ui->stopButton->setEnabled(true);
0471             ui->toEndButton->setEnabled(true);
0472             ui->toBeginningButton->setEnabled(true);
0473         }
0474     }
0475 }
0476 
0477 
0478 void ToolsMenu::cameraOn(bool isOn) {
0479     if (isOn) {
0480         ui->playButton->setEnabled(false);
0481         ui->loopButton->setEnabled(false);
0482         ui->pauseButton->setEnabled(false);
0483         ui->stopButton->setEnabled(false);
0484         ui->launchGimp->setEnabled(false);
0485         runAnimationHandler->stopAnimation();
0486         changeViewingMode(0);
0487         ui->viewChooseCombo->setCurrentIndex(0);
0488     } else {
0489         ui->playButton->setEnabled(true);
0490         ui->loopButton->setEnabled(true);
0491         ui->pauseButton->setEnabled(true);
0492         ui->stopButton->setEnabled(true);
0493         ui->launchGimp->setEnabled(true);
0494         if ( captureTimer->isActive() ) {
0495             captureTimer->stop();
0496         }
0497     }
0498     fixNavigationButtons(DomainFacade::getFacade()->getModelSize());
0499 }