UndoTransaction::UndoTransaction(Context* context, const char* label, undo::Modification modification) : m_context(context) , m_label(label) , m_modification(modification) { ASSERT(label != NULL); DocumentLocation location = m_context->getActiveLocation(); m_document = location.document(); m_sprite = location.sprite(); m_undo = m_document->getUndo(); m_closed = false; m_committed = false; m_enabledFlag = m_undo->isEnabled(); if (isEnabled()) { SpritePosition position(m_sprite->layerToIndex(location.layer()), location.frame()); m_undo->pushUndoer(new undoers::OpenGroup(getObjects(), m_label, m_modification, m_sprite, position)); } }
void ColorPicker::pickColor(const DocumentLocation& location, int x, int y, Mode mode) { m_alpha = 255; m_color = app::Color::fromMask(); // Get the color from the image if (mode == FromComposition) { // Pick from the composed image m_color = app::Color::fromImage( location.sprite()->pixelFormat(), location.sprite()->getPixel(x, y, location.frame())); } else { // Pick from the current layer int u, v; doc::Image* image = location.image(&u, &v, NULL); gfx::Point pt(x-u, y-v); if (image && image->bounds().contains(pt)) { doc::color_t imageColor = get_pixel(image, pt.x, pt.y); switch (image->pixelFormat()) { case IMAGE_RGB: m_alpha = doc::rgba_geta(imageColor); break; case IMAGE_GRAYSCALE: m_alpha = doc::graya_geta(imageColor); break; } m_color = app::Color::fromImage(image->pixelFormat(), imageColor); } } }
DocumentLocation Context::activeLocation() const { DocumentLocation location; onGetActiveLocation(&location); ASSERT(location.document() == doc::Context::activeDocument()); return location; }
ExpandCelCanvas::ExpandCelCanvas(DocumentLocation location, TiledMode tiledMode, Transaction& transaction, Flags flags) : m_document(location.document()) , m_sprite(location.sprite()) , m_layer(location.layer()) , m_cel(NULL) , m_celImage(NULL) , m_celCreated(false) , m_flags(flags) , m_srcImage(NULL) , m_dstImage(NULL) , m_closed(false) , m_committed(false) , m_transaction(transaction) { create_buffers(); if (m_layer->isImage()) { m_cel = m_layer->cel(location.frame()); if (m_cel) m_celImage = m_cel->imageRef(); } // Create a new cel if (m_cel == NULL) { m_celCreated = true; m_cel = new Cel(location.frame(), ImageRef(NULL)); } m_origCelPos = m_cel->position(); // Region to draw gfx::Rect celBounds( m_cel->x(), m_cel->y(), m_celImage ? m_celImage->width(): m_sprite->width(), m_celImage ? m_celImage->height(): m_sprite->height()); gfx::Rect spriteBounds(0, 0, m_sprite->width(), m_sprite->height()); if (tiledMode == TiledMode::NONE) { // Non-tiled m_bounds = celBounds.createUnion(spriteBounds); } else { // Tiled m_bounds = spriteBounds; } // We have to adjust the cel position to match the m_dstImage // position (the new m_dstImage will be used in RenderEngine to // draw this cel). m_cel->setPosition(m_bounds.x, m_bounds.y); if (m_celCreated) { getDestCanvas(); m_cel->data()->setImage(m_dstImage); static_cast<LayerImage*>(m_layer)->addCel(m_cel); } }
// Updates palette and redraw the screen. void app_refresh_screen() { Context* context = UIContext::instance(); ASSERT(context != NULL); DocumentLocation location = context->activeLocation(); if (Palette* pal = location.palette()) set_current_palette(pal, false); else set_current_palette(NULL, false); // Invalidate the whole screen. ui::Manager::getDefault()->invalidate(); }
static bool copy_from_document(const DocumentLocation& location) { const Document* document = location.document(); ASSERT(document != NULL); ASSERT(document->isMaskVisible()); Image* image = NewImageFromMask(location); if (!image) return false; clipboard_x = document->getMask()->getBounds().x; clipboard_y = document->getMask()->getBounds().y; const Palette* pal = document->getSprite()->getPalette(location.frame()); set_clipboard(image, pal ? new Palette(*pal): NULL, true); return true; }
void UndoTransaction::closeUndoGroup() { ASSERT(!m_closed); if (isEnabled()) { DocumentLocation location = m_context->getActiveLocation(); SpritePosition position(m_sprite->layerToIndex(location.layer()), location.frame()); // Close the undo information. m_undo->pushUndoer(new undoers::CloseGroup(getObjects(), m_label, m_modification, m_sprite, position)); m_closed = true; } }
ExpandCelCanvas::ExpandCelCanvas(Context* context, TiledMode tiledMode, UndoTransaction& undo, Flags flags) : m_cel(NULL) , m_celImage(NULL) , m_celCreated(false) , m_flags(flags) , m_srcImage(NULL) , m_dstImage(NULL) , m_closed(false) , m_committed(false) , m_undo(undo) { create_buffers(); DocumentLocation location = context->activeLocation(); m_document = location.document(); m_sprite = location.sprite(); m_layer = location.layer(); if (m_layer->isImage()) { m_cel = static_cast<LayerImage*>(m_layer)->getCel(location.frame()); if (m_cel) m_celImage = m_cel->image(); } // If there is no Cel if (m_cel == NULL) { // Create the cel m_celCreated = true; m_cel = new Cel(location.frame(), 0); static_cast<LayerImage*>(m_layer)->addCel(m_cel); } m_origCelPos = m_cel->position(); // Region to draw gfx::Rect celBounds( m_cel->x(), m_cel->y(), m_celImage ? m_celImage->width(): m_sprite->width(), m_celImage ? m_celImage->height(): m_sprite->height()); gfx::Rect spriteBounds(0, 0, m_sprite->width(), m_sprite->height()); if (tiledMode == TILED_NONE) { // Non-tiled m_bounds = celBounds.createUnion(spriteBounds); } else { // Tiled m_bounds = spriteBounds; } // We have to adjust the cel position to match the m_dstImage // position (the new m_dstImage will be used in RenderEngine to // draw this cel). m_cel->setPosition(m_bounds.x, m_bounds.y); }
void ColorPicker::pickColor(const DocumentLocation& location, const gfx::Point& pos, Mode mode) { m_alpha = 255; m_color = app::Color::fromMask(); // Get the color from the image if (mode == FromComposition) { // Pick from the composed image m_color = app::Color::fromImage( location.sprite()->pixelFormat(), render::get_sprite_pixel(location.sprite(), pos.x, pos.y, location.frame())); doc::CelList cels; location.sprite()->pickCels(pos.x, pos.y, location.frame(), 128, cels); if (!cels.empty()) m_layer = cels.front()->layer(); } else { // Pick from the current layer int u, v; doc::Image* image = location.image(&u, &v, NULL); gfx::Point pt(pos.x-u, pos.y-v); if (image && image->bounds().contains(pt)) { doc::color_t imageColor = get_pixel(image, pt.x, pt.y); switch (image->pixelFormat()) { case IMAGE_RGB: m_alpha = doc::rgba_geta(imageColor); break; case IMAGE_GRAYSCALE: m_alpha = doc::graya_geta(imageColor); break; } m_color = app::Color::fromImage(image->pixelFormat(), imageColor); m_layer = const_cast<Layer*>(location.layer()); } } }
bool StandbyState::onMouseDown(Editor* editor, MouseMessage* msg) { if (editor->hasCapture()) return true; UIContext* context = UIContext::instance(); tools::Ink* clickedInk = editor->getCurrentEditorInk(); DocumentLocation location; editor->getDocumentLocation(&location); Document* document = location.document(); Layer* layer = location.layer(); // When an editor is clicked the current view is changed. context->setActiveView(editor->getDocumentView()); // Start scroll loop if (checkForScroll(editor, msg) || checkForZoom(editor, msg)) return true; // Move cel X,Y coordinates if (clickedInk->isCelMovement()) { // Handle "Auto Select Layer" if (editor->isAutoSelectLayer()) { gfx::Point cursor = editor->screenToEditor(msg->position()); ColorPicker picker; picker.pickColor(location, cursor, ColorPicker::FromComposition); if (layer != picker.layer()) { layer = picker.layer(); if (layer) { editor->setLayer(layer); editor->flashCurrentLayer(); } } } if ((layer) && (layer->type() == ObjectType::LayerImage)) { // TODO we should be able to move the `Background' with tiled mode if (layer->isBackground()) { StatusBar::instance()->showTip(1000, "The background layer cannot be moved"); } else if (!layer->isVisible()) { StatusBar::instance()->showTip(1000, "Layer '%s' is hidden", layer->name().c_str()); } else if (!layer->isMovable() || !layer->isEditable()) { StatusBar::instance()->showTip(1000, "Layer '%s' is locked", layer->name().c_str()); } else { // Change to MovingCelState editor->setState(EditorStatePtr(new MovingCelState(editor, msg))); } } return true; } // Call the eyedropper command if (clickedInk->isEyedropper()) { callEyedropper(editor); return true; } if (clickedInk->isSelection()) { // Transform selected pixels if (document->isMaskVisible() && m_decorator->getTransformHandles(editor)) { TransformHandles* transfHandles = m_decorator->getTransformHandles(editor); // Get the handle covered by the mouse. HandleType handle = transfHandles->getHandleAtPoint(editor, msg->position(), document->getTransformation()); if (handle != NoHandle) { int x, y, opacity; Image* image = location.image(&x, &y, &opacity); if (layer && image) { if (!layer->isEditable()) { StatusBar::instance()->showTip(1000, "Layer '%s' is locked", layer->name().c_str()); return true; } // Change to MovingPixelsState transformSelection(editor, msg, handle); } return true; } } // Move selected pixels if (layer && editor->isInsideSelection() && msg->left()) { if (!layer->isEditable()) { StatusBar::instance()->showTip(1000, "Layer '%s' is locked", layer->name().c_str()); return true; } // Change to MovingPixelsState transformSelection(editor, msg, MoveHandle); return true; } } // Start the Tool-Loop if (layer) { tools::ToolLoop* toolLoop = create_tool_loop(editor, context); if (toolLoop) { EditorStatePtr newState(new DrawingState(toolLoop)); editor->setState(newState); static_cast<DrawingState*>(newState.get()) ->initToolLoop(editor, msg); } return true; } return true; }
bool ColorButton::onProcessMessage(Message* msg) { switch (msg->type()) { case kCloseMessage: if (m_window && m_window->isVisible()) m_window->closeWindow(NULL); break; case kMouseEnterMessage: StatusBar::instance()->showColor(0, "", m_color, 255); break; case kMouseLeaveMessage: StatusBar::instance()->clearText(); break; case kMouseMoveMessage: if (hasCapture()) { gfx::Point mousePos = static_cast<MouseMessage*>(msg)->position(); Widget* picked = getManager()->pick(mousePos); app::Color color = m_color; if (picked && picked != this) { // Pick a color from another color-button if (ColorButton* pickedColBut = dynamic_cast<ColorButton*>(picked)) { color = pickedColBut->getColor(); } // Pick a color from the color-bar else if (picked->type == palette_view_type()) { color = ((PaletteView*)picked)->getColorByPosition(mousePos.x, mousePos.y); } // Pick a color from a editor else if (picked->type == editor_type()) { Editor* editor = static_cast<Editor*>(picked); DocumentLocation location = editor->getDocumentLocation(); if (location.sprite()) { int x = mousePos.x; int y = mousePos.y; editor->screenToEditor(x, y, &x, &y); ColorPicker picker; picker.pickColor(location, x, y, ColorPicker::FromComposition); color = picker.color(); } } } // Did the color change? if (color != m_color) { setColor(color); } } break; case kSetCursorMessage: if (hasCapture()) { jmouse_set_cursor(kEyedropperCursor); return true; } break; } return ButtonBase::onProcessMessage(msg); }
void StatusBar::updateCurrentFrame() { DocumentLocation location = UIContext::instance()->getActiveLocation(); if (location.sprite()) m_currentFrame->setTextf("%d", location.frame()+1); }
ExpandCelCanvas::ExpandCelCanvas(Context* context, TiledMode tiledMode, UndoTransaction& undo) : m_cel(NULL) , m_celImage(NULL) , m_celCreated(false) , m_closed(false) , m_committed(false) , m_undo(undo) { create_buffers(); DocumentLocation location = context->getActiveLocation(); m_document = location.document(); m_sprite = location.sprite(); m_layer = location.layer(); if (m_layer->isImage()) { m_cel = static_cast<LayerImage*>(m_layer)->getCel(location.frame()); if (m_cel) m_celImage = m_sprite->getStock()->getImage(m_cel->getImage()); } // If there is no Cel if (m_cel == NULL) { // Create the image m_celImage = Image::create(m_sprite->getPixelFormat(), m_sprite->getWidth(), m_sprite->getHeight()); clear_image(m_celImage, m_sprite->getTransparentColor()); // Create the cel m_cel = new Cel(location.frame(), 0); static_cast<LayerImage*>(m_layer)->addCel(m_cel); m_celCreated = true; } m_originalCelX = m_cel->getX(); m_originalCelY = m_cel->getY(); // Region to draw int x1, y1, x2, y2; if (tiledMode == TILED_NONE) { // Non-tiled x1 = MIN(m_cel->getX(), 0); y1 = MIN(m_cel->getY(), 0); x2 = MAX(m_cel->getX()+m_celImage->getWidth(), m_sprite->getWidth()); y2 = MAX(m_cel->getY()+m_celImage->getHeight(), m_sprite->getHeight()); } else { // Tiled x1 = 0; y1 = 0; x2 = m_sprite->getWidth(); y2 = m_sprite->getHeight(); } // create two copies of the image region which we'll modify with the tool m_srcImage = crop_image(m_celImage, x1-m_cel->getX(), y1-m_cel->getY(), x2-x1, y2-y1, m_sprite->getTransparentColor(), src_buffer); m_dstImage = Image::createCopy(m_srcImage, dst_buffer); // We have to adjust the cel position to match the m_dstImage // position (the new m_dstImage will be used in RenderEngine to // draw this cel). m_cel->setPosition(x1, y1); }
bool StandbyState::onMouseDown(Editor* editor, MouseMessage* msg) { if (editor->hasCapture()) return true; UIContext* context = UIContext::instance(); tools::Tool* currentTool = editor->getCurrentEditorTool(); tools::Ink* clickedInk = editor->getCurrentEditorInk(); DocumentLocation location; editor->getDocumentLocation(&location); Document* document = location.document(); Layer* layer = location.layer(); // When an editor is clicked the current view is changed. context->setActiveView(editor->getDocumentView()); // Start scroll loop if (checkForScroll(editor, msg) || checkForZoom(editor, msg)) return true; // Move cel X,Y coordinates if (clickedInk->isCelMovement()) { if ((layer) && (layer->type() == OBJECT_LAYER_IMAGE)) { // TODO you can move the `Background' with tiled mode if (layer->isBackground()) { Alert::show(PACKAGE "<<You can't move the `Background' layer." "||&Close"); } else if (!layer->isMoveable()) { Alert::show(PACKAGE "<<The layer movement is locked.||&Close"); } else { // Change to MovingCelState editor->setState(EditorStatePtr(new MovingCelState(editor, msg))); } } return true; } // Transform selected pixels if (document->isMaskVisible() && m_decorator->getTransformHandles(editor)) { TransformHandles* transfHandles = m_decorator->getTransformHandles(editor); // Get the handle covered by the mouse. HandleType handle = transfHandles->getHandleAtPoint(editor, msg->position(), document->getTransformation()); if (handle != NoHandle) { int x, y, opacity; Image* image = location.image(&x, &y, &opacity); if (image) { if (!layer->isWritable()) { Alert::show(PACKAGE "<<The layer is locked.||&Close"); return true; } // Change to MovingPixelsState transformSelection(editor, msg, handle); } return true; } } // Move selected pixels if (editor->isInsideSelection() && currentTool->getInk(0)->isSelection() && msg->left()) { if (!layer->isWritable()) { Alert::show(PACKAGE "<<The layer is locked.||&Close"); return true; } // Change to MovingPixelsState transformSelection(editor, msg, MoveHandle); return true; } // Call the eyedropper command if (clickedInk->isEyedropper()) { onMouseMove(editor, msg); return true; } // Start the Tool-Loop if (layer) { tools::ToolLoop* toolLoop = create_tool_loop(editor, context); if (toolLoop) editor->setState(EditorStatePtr(new DrawingState(toolLoop, editor, msg))); return true; } return true; }