Exemple #1
0
void UndoCommand::onExecute(Context* context)
{
    ContextWriter writer(context);
    Document* document(writer.document());
    DocumentUndo* undo = document->getUndo();
    Sprite* sprite = document->sprite();

    if (context->settings()->undoGotoModified()) {
        SpritePosition spritePosition;
        SpritePosition currentPosition(writer.location()->layerIndex(),
                                       writer.location()->frame());

        if (m_type == Undo)
            spritePosition = undo->getNextUndoSpritePosition();
        else
            spritePosition = undo->getNextRedoSpritePosition();

        if (spritePosition != currentPosition) {
            current_editor->setLayer(sprite->indexToLayer(spritePosition.layerIndex()));
            current_editor->setFrame(spritePosition.frameNumber());

            // Draw the current layer/frame (which is not undone yet) so the
            // user can see the doUndo/doRedo effect.
            current_editor->drawSpriteClipped(
                gfx::Region(gfx::Rect(0, 0, sprite->width(), sprite->height())));

            ui::dirty_display_flag = true;
            gui_feedback();

            base::this_thread::sleep_for(0.01);
        }
    }

    StatusBar::instance()
    ->showTip(1000, "%s %s",
              (m_type == Undo ? "Undid": "Redid"),
              (m_type == Undo ? undo->getNextUndoLabel():
               undo->getNextRedoLabel()));

    // Effectively undo/redo.
    if (m_type == Undo)
        undo->doUndo();
    else
        undo->doRedo();

    document->generateMaskBoundaries();
    document->destroyExtraCel(); // Regenerate extras

    update_screen_for_document(document);
    set_current_palette(writer.palette(), false);
}
Exemple #2
0
void UndoCommand::onExecute(Context* context)
{
  ActiveDocumentWriter document(context);
  DocumentUndo* undo = document->getUndo();
  Sprite* sprite = document->getSprite();

  if (get_config_bool("Options", "UndoGotoModified", true)) {
    SpritePosition spritePosition;

    if (m_type == Undo)
      spritePosition = undo->getNextUndoSpritePosition();
    else
      spritePosition = undo->getNextRedoSpritePosition();

    if (spritePosition != sprite->getCurrentPosition()) {
      sprite->setCurrentPosition(spritePosition);

      current_editor->drawSpriteSafe(0, 0, sprite->getWidth(), sprite->getHeight());
      update_screen_for_document(document);

      ui::dirty_display_flag = true;
      gui_feedback();

      base::this_thread::sleep_for(0.01);
    }
  }

  StatusBar::instance()
    ->showTip(1000, "%s %s",
              (m_type == Undo ? "Undid": "Redid"),
              (m_type == Undo ? undo->getNextUndoLabel():
                                undo->getNextRedoLabel()));

  if (m_type == Undo)
    undo->doUndo();
  else
    undo->doRedo();

  document->generateMaskBoundaries();
  document->destroyExtraCel(); // Regenerate extras

  update_screen_for_document(document);
}
Exemple #3
0
// Manager event handler.
bool CustomizedGuiManager::onProcessMessage(Message* msg)
{
    switch (msg->type()) {

    case kCloseAppMessage:
    {
        // Execute the "Exit" command.
        Command* command = CommandsModule::instance()->getCommandByName(CommandId::Exit);
        UIContext::instance()->executeCommand(command);
    }
    break;

    case kDropFilesMessage:
    {
        // If the main window is not the current foreground one. We
        // discard the drop-files event.
        if (getForegroundWindow() != App::instance()->getMainWindow())
            break;

        const DropFilesMessage::Files& files = static_cast<DropFilesMessage*>(msg)->files();

        // Open all files
        Command* cmd_open_file =
            CommandsModule::instance()->getCommandByName(CommandId::OpenFile);
        Params params;

        for (DropFilesMessage::Files::const_iterator
                it = files.begin(); it != files.end(); ++it) {
            params.set("filename", it->c_str());
            UIContext::instance()->executeCommand(cmd_open_file, &params);
        }
    }
    break;

    case kQueueProcessingMessage:
        gui_feedback();
        break;

    case kKeyDownMessage: {
        Window* toplevel_window = getTopWindow();

        // If there is a foreground window as top level...
        if (toplevel_window &&
                toplevel_window != App::instance()->getMainWindow() &&
                toplevel_window->isForeground()) {
            // We just do not process keyboard shortcuts for menus and tools
            break;
        }

        for (Shortcut* shortcut : *shortcuts) {
            if (shortcut->is_pressed(msg)) {
                // Cancel menu-bar loops (to close any popup menu)
                App::instance()->getMainWindow()->getMenuBar()->cancelMenuLoop();

                switch (shortcut->type) {

                case Shortcut::Type::ChangeTool: {
                    tools::Tool* current_tool = UIContext::instance()->settings()->getCurrentTool();
                    tools::Tool* select_this_tool = shortcut->tool;
                    tools::ToolBox* toolbox = App::instance()->getToolBox();
                    std::vector<tools::Tool*> possibles;

                    // Iterate over all tools
                    for (tools::ToolIterator it = toolbox->begin(); it != toolbox->end(); ++it) {
                        Shortcut* shortcut = get_keyboard_shortcut_for_tool(*it);

                        // Collect all tools with the pressed keyboard-shortcut
                        if (shortcut && shortcut->is_pressed(msg))
                            possibles.push_back(*it);
                    }

                    if (possibles.size() >= 2) {
                        bool done = false;

                        for (size_t i=0; i<possibles.size(); ++i) {
                            if (possibles[i] != current_tool &&
                                    ToolBar::instance()->isToolVisible(possibles[i])) {
                                select_this_tool = possibles[i];
                                done = true;
                                break;
                            }
                        }

                        if (!done) {
                            for (size_t i=0; i<possibles.size(); ++i) {
                                // If one of the possibilities is the current tool
                                if (possibles[i] == current_tool) {
                                    // We select the next tool in the possibilities
                                    select_this_tool = possibles[(i+1) % possibles.size()];
                                    break;
                                }
                            }
                        }
                    }

                    ToolBar::instance()->selectTool(select_this_tool);
                    return true;
                }

                case Shortcut::Type::ExecuteCommand: {
                    Command* command = shortcut->command;

                    // Commands are executed only when the main window is
                    // the current window running at foreground.
                    UI_FOREACH_WIDGET(getChildren(), it) {
                        Window* child = static_cast<Window*>(*it);

                        // There are a foreground window executing?
                        if (child->isForeground()) {
                            break;
                        }
                        // Is it the desktop and the top-window=
                        else if (child->isDesktop() && child == App::instance()->getMainWindow()) {
                            // OK, so we can execute the command represented
                            // by the pressed-key in the message...
                            UIContext::instance()->executeCommand(command, shortcut->params);
                            return true;
                        }
                    }
                    break;
                }

                case Shortcut::Type::EditorQuicktool: {
                    // Do nothing, it is used in the editor through the
                    // get_selected_quicktool() function.
                    break;
                }

                }
                break;
            }
        }
        break;
    }
Exemple #4
0
// Returns false when the user stop the click-loop: releases the
// button or press the second click (depend of the mode)
int Editor::editor_click(int *x, int *y, int *update,
                         void (*scroll_callback) (int before_change))
{
  int prev_x, prev_y;

  poll_keyboard();

  if (click_first) {
    click_first = false;

    if (click_mode == MODE_CLICKANDCLICK) {
      do {
        jmouse_poll();
        gui_feedback();
      } while (jmouse_b(0));

      jmouse_set_position(click_start_x, click_start_y);
      clear_keybuf();
    }
  }

  *update = jmouse_poll();

  screenToEditor(click_last_x, click_last_y, &prev_x, &prev_y);

  click_prev_last_b = click_last_b;

  click_last_x = jmouse_x(0);
  click_last_y = jmouse_y(0);
  click_last_b = jmouse_b(0);

  screenToEditor(click_last_x, click_last_y, x, y);

  /* the mouse was moved */
  if (*update) {
    View* view = View::getView(this);
    gfx::Rect vp = view->getViewportBounds();

    /* update scroll */
    if (jmouse_control_infinite_scroll(vp)) {
      if (scroll_callback)
        (*scroll_callback)(true);

      /* smooth scroll movement */
      if (get_config_bool("Options", "MoveSmooth", true)) {
        jmouse_set_position(MID(vp.x+1, click_last_x, vp.x+vp.w-2),
                            MID(vp.y+1, click_last_y, vp.y+vp.h-2));
      }
      /* this is better for high resolutions: scroll movement by big steps */
      else {
        jmouse_set_position((click_last_x != jmouse_x(0)) ?
                            (click_last_x + (vp.x+vp.w/2))/2: jmouse_x(0),

                            (click_last_y != jmouse_y(0)) ?
                            (click_last_y + (vp.y+vp.h/2))/2: jmouse_y(0));
      }

      gfx::Point scroll = view->getViewScroll();
      setEditorScroll(scroll.x+click_last_x-jmouse_x(0),
                      scroll.y+click_last_y-jmouse_y(0), true);

      click_last_x = jmouse_x(0);
      click_last_y = jmouse_y(0);

      if (scroll_callback)
        (*scroll_callback)(false);
    }

    // If the cursor hasn't subpixel movement
    if (!editor_cursor_is_subpixel()) {
      // Check if the mouse change to other pixel of the sprite
      *update = ((prev_x != *x) || (prev_y != *y));
    }
    else {
      // Check if the mouse change to other pixel of the screen
      *update = ((prev_x != click_last_x) || (prev_y != click_last_y));
    }
  }

  /* click-and-click mode */
  if (click_mode == MODE_CLICKANDCLICK) {
    if (click_last_b) {
      click_prev_last_b = click_last_b;

      do {
        jmouse_poll();
        gui_feedback();
      } while (jmouse_b(0));

      jmouse_set_position(click_last_x, click_last_y);
      clear_keybuf();

      return false;
    }
    else {
      return true;
    }
  }
  /* click-and-release mode */
  else {
    return (click_last_b) ? true: false;
  }
}
Exemple #5
0
// Gives to the user the possibility to move the sprite's layer in the
// current editor, returns true if the position was changed.
int interactive_move_layer(int mode, bool use_undo, int (*callback)())
{
    Editor* editor = current_editor;
    Document* document = editor->getDocument();
    undo::UndoHistory* undo = document->getUndoHistory();
    Sprite* sprite = document->getSprite();

    ASSERT(sprite->getCurrentLayer()->is_image());

    LayerImage* layer = static_cast<LayerImage*>(sprite->getCurrentLayer());
    Cel *cel = layer->getCel(sprite->getCurrentFrame());
    int start_x, new_x;
    int start_y, new_y;
    int start_b;
    int ret;
    int update = false;
    int quiet_clock = -1;
    int first_time = true;
    int begin_x;
    int begin_y;

    if (!cel)
        return false;

    begin_x = cel->getX();
    begin_y = cel->getY();

    editor->hideDrawingCursor();
    jmouse_set_cursor(JI_CURSOR_MOVE);

    editor->editor_click_start(mode, &start_x, &start_y, &start_b);

    do {
        if (update) {
            cel->setPosition(begin_x - start_x + new_x,
                             begin_y - start_y + new_y);

            // Update layer-bounds.
            editor->invalidate();

            // Update status bar.
            app_get_statusbar()->setStatusText
            (0,
             "Pos %3d %3d Offset %3d %3d",
             (int)cel->getX(),
             (int)cel->getY(),
             (int)(cel->getX() - begin_x),
             (int)(cel->getY() - begin_y));

            /* update clock */
            quiet_clock = ji_clock;
            first_time = false;
        }

        /* call the user's routine */
        if (callback)
            (*callback)();

        /* redraw dirty widgets */
        jwidget_flush_redraw(ji_get_default_manager());
        jmanager_dispatch_messages(ji_get_default_manager());

        gui_feedback();
    } while (editor->editor_click(&new_x, &new_y, &update, NULL));

    new_x = cel->getX();
    new_y = cel->getY();
    cel->setPosition(begin_x, begin_y);

    /* the position was changed */
    if (!editor->editor_click_cancel()) {
        if (use_undo && undo->isEnabled()) {
            undo->setLabel("Cel Movement");
            undo->setModification(undo::ModifyDocument);

            undo->pushUndoer(new undoers::SetCelPosition(undo->getObjects(), cel));
        }

        cel->setPosition(new_x, new_y);
        ret = true;
    }
    /* the position wasn't changed */
    else {
        ret = false;
    }

    /* redraw the sprite in all editors */
    update_screen_for_document(document);

    /* restore the cursor */
    editor->showDrawingCursor();

    editor->editor_click_done();

    return ret;
}