Skip to content

Commit

Permalink
Add ability to select timeline + color bar at the same time (related to
Browse files Browse the repository at this point in the history
  • Loading branch information
dacap committed Jun 5, 2018
1 parent f29ead0 commit 05f6aec
Show file tree
Hide file tree
Showing 16 changed files with 147 additions and 62 deletions.
54 changes: 43 additions & 11 deletions src/app/document_range.cpp
@@ -1,5 +1,5 @@
// Aseprite
// Copyright (C) 2001-2016 David Capello
// Copyright (C) 2001-2018 David Capello
//
// This program is distributed under the terms of
// the End-User License Agreement for Aseprite.
Expand All @@ -21,13 +21,15 @@ using namespace doc;

DocumentRange::DocumentRange()
: m_type(kNone)
, m_flags(m_type)
, m_selectingFromLayer(nullptr)
, m_selectingFromFrame(-1)
{
}

DocumentRange::DocumentRange(Cel* cel)
: m_type(kCels)
, m_flags(m_type)
, m_selectingFromLayer(nullptr)
, m_selectingFromFrame(-1)
{
Expand All @@ -38,13 +40,15 @@ DocumentRange::DocumentRange(Cel* cel)
void DocumentRange::clearRange()
{
m_type = kNone;
m_flags = kNone;
m_selectedLayers.clear();
m_selectedFrames.clear();
}

void DocumentRange::startRange(Layer* fromLayer, frame_t fromFrame, Type type)
{
m_type = type;
m_flags |= type;
m_selectingFromLayer = fromLayer;
m_selectingFromFrame = fromFrame;

Expand All @@ -69,6 +73,7 @@ void DocumentRange::selectLayer(Layer* layer)
{
if (m_type == kNone)
m_type = kLayers;
m_flags |= kLayers;

m_selectedLayers.insert(layer);
}
Expand All @@ -77,19 +82,48 @@ void DocumentRange::selectLayers(const SelectedLayers& selLayers)
{
if (m_type == kNone)
m_type = kLayers;
m_flags |= kLayers;

for (auto layer : selLayers)
m_selectedLayers.insert(layer);
}

bool DocumentRange::contains(Layer* layer) const
bool DocumentRange::contains(const Layer* layer) const
{
if (enabled())
return m_selectedLayers.contains(layer);
return m_selectedLayers.contains(const_cast<Layer*>(layer));
else
return false;
}

bool DocumentRange::contains(const Layer* layer,
const frame_t frame) const
{
switch (m_type) {
case DocumentRange::kNone:
return false;
case DocumentRange::kCels:
return contains(layer) && contains(frame);
case DocumentRange::kFrames:
if (contains(frame)) {
if ((m_flags & (kCels | kLayers)) != 0)
return contains(layer);
else
return true;
}
break;
case DocumentRange::kLayers:
if (contains(layer)) {
if ((m_flags & (kCels | kFrames)) != 0)
return contains(frame);
else
return true;
}
break;
}
return false;
}

void DocumentRange::displace(layer_t layerDelta, frame_t frameDelta)
{
m_selectedLayers.displace(layerDelta);
Expand All @@ -104,18 +138,16 @@ bool DocumentRange::convertToCels(const Sprite* sprite)
case DocumentRange::kCels:
break;
case DocumentRange::kFrames: {
LayerList layers = sprite->allBrowsableLayers();
ASSERT(layers.empty());
if (!layers.empty()) {
selectLayerRange(layers.front(), layers.back());
m_type = DocumentRange::kCels;
if ((m_flags & (kCels | kLayers)) == 0) {
for (auto layer : sprite->allBrowsableLayers())
m_selectedLayers.insert(layer);
}
else
return false;
m_type = DocumentRange::kCels;
break;
}
case DocumentRange::kLayers:
selectFrameRange(0, sprite->lastFrame());
if ((m_flags & (kCels | kFrames)) == 0)
selectFrameRange(0, sprite->lastFrame());
m_type = DocumentRange::kCels;
break;
}
Expand Down
19 changes: 11 additions & 8 deletions src/app/document_range.h
@@ -1,5 +1,5 @@
// Aseprite
// Copyright (C) 2001-2016 David Capello
// Copyright (C) 2001-2018 David Capello
//
// This program is distributed under the terms of
// the End-User License Agreement for Aseprite.
Expand All @@ -22,7 +22,10 @@ namespace app {

class DocumentRange {
public:
enum Type { kNone, kCels, kFrames, kLayers };
enum Type { kNone = 0,
kCels = 1,
kFrames = 2,
kLayers = 4 };

DocumentRange();
DocumentRange(Cel* cel);
Expand All @@ -36,13 +39,12 @@ namespace app {

void displace(layer_t layerDelta, frame_t frameDelta);

bool contains(Layer* layer) const;
bool contains(frame_t frame) const {
bool contains(const Layer* layer) const;
bool contains(const frame_t frame) const {
return m_selectedFrames.contains(frame);
}
bool contains(Layer* layer, frame_t frame) const {
return contains(layer) && contains(frame);
}
bool contains(const Layer* layer,
const frame_t frame) const;

void clearRange();
void startRange(Layer* fromLayer, frame_t fromFrame, Type type);
Expand All @@ -66,7 +68,8 @@ namespace app {
void selectLayerRange(Layer* fromLayer, Layer* toLayer);
void selectFrameRange(frame_t fromFrame, frame_t toFrame);

Type m_type;
Type m_type; // Last used type of the range
int m_flags; // All used types in startRange()
SelectedLayers m_selectedLayers;
SelectedFrames m_selectedFrames;
Layer* m_selectingFromLayer;
Expand Down
19 changes: 13 additions & 6 deletions src/app/ui/color_bar.cpp
@@ -1,5 +1,5 @@
// Aseprite
// Copyright (C) 2001-2017 David Capello
// Copyright (C) 2001-2018 David Capello
//
// This program is distributed under the terms of
// the End-User License Agreement for Aseprite.
Expand Down Expand Up @@ -45,6 +45,7 @@
#include "app/ui/palette_popup.h"
#include "app/ui/skin/skin_theme.h"
#include "app/ui/status_bar.h"
#include "app/ui/timeline/timeline.h"
#include "app/ui_context.h"
#include "app/ui_context.h"
#include "app/util/clipboard.h"
Expand Down Expand Up @@ -271,7 +272,7 @@ ColorBar::ColorBar(int align)
m_afterCmdConn = UIContext::instance()->AfterCommandExecution.connect(&ColorBar::onAfterExecuteCommand, this);
m_fgConn = Preferences::instance().colorBar.fgColor.AfterChange.connect(base::Bind<void>(&ColorBar::onFgColorChangeFromPreferences, this));
m_bgConn = Preferences::instance().colorBar.bgColor.AfterChange.connect(base::Bind<void>(&ColorBar::onBgColorChangeFromPreferences, this));
m_paletteView.FocusEnter.connect(&ColorBar::onFocusPaletteView, this);
m_paletteView.FocusOrClick.connect(&ColorBar::onFocusPaletteView, this);
m_appPalChangeConn = App::instance()->PaletteChange.connect(&ColorBar::onAppPaletteChange, this);
KeyboardShortcuts::instance()->UserChange.connect(
base::Bind<void>(&ColorBar::setupTooltips, this, tooltipManager));
Expand Down Expand Up @@ -451,9 +452,9 @@ void ColorBar::onAppPaletteChange()
updateWarningIcon(m_bgColor.getColor(), m_bgWarningIcon);
}

void ColorBar::onFocusPaletteView()
void ColorBar::onFocusPaletteView(ui::Message* msg)
{
App::instance()->inputChain().prioritize(this);
App::instance()->inputChain().prioritize(this, msg);
}

void ColorBar::onBeforeExecuteCommand(CommandExecutionEvent& ev)
Expand Down Expand Up @@ -967,9 +968,15 @@ void ColorBar::hideRemap()
layout();
}

void ColorBar::onNewInputPriority(InputChainElement* element)
void ColorBar::onNewInputPriority(InputChainElement* element,
const ui::Message* msg)
{
m_paletteView.deselect();
if (dynamic_cast<Timeline*>(element) &&
msg && (msg->ctrlPressed() || msg->shiftPressed()))
return;

if (element != this)
m_paletteView.deselect();
}

bool ColorBar::onCanCut(Context* ctx)
Expand Down
5 changes: 3 additions & 2 deletions src/app/ui/color_bar.h
Expand Up @@ -90,7 +90,8 @@ namespace app {
void onGeneralUpdate(doc::DocumentEvent& ev) override;

// InputChainElement impl
void onNewInputPriority(InputChainElement* element) override;
void onNewInputPriority(InputChainElement* element,
const ui::Message* msg) override;
bool onCanCut(Context* ctx) override;
bool onCanCopy(Context* ctx) override;
bool onCanPaste(Context* ctx) override;
Expand All @@ -105,7 +106,7 @@ namespace app {

protected:
void onAppPaletteChange();
void onFocusPaletteView();
void onFocusPaletteView(ui::Message* msg);
void onBeforeExecuteCommand(CommandExecutionEvent& ev);
void onAfterExecuteCommand(CommandExecutionEvent& ev);
void onPaletteButtonClick();
Expand Down
3 changes: 2 additions & 1 deletion src/app/ui/document_view.cpp
Expand Up @@ -455,7 +455,8 @@ void DocumentView::onLayerRestacked(doc::DocumentEvent& ev)
m_editor->invalidate();
}

void DocumentView::onNewInputPriority(InputChainElement* element)
void DocumentView::onNewInputPriority(InputChainElement* element,
const ui::Message* msg)
{
// Do nothing
}
Expand Down
5 changes: 3 additions & 2 deletions src/app/ui/document_view.h
@@ -1,5 +1,5 @@
// Aseprite
// Copyright (C) 2001-2016 David Capello
// Copyright (C) 2001-2018 David Capello
//
// This program is distributed under the terms of
// the End-User License Agreement for Aseprite.
Expand Down Expand Up @@ -84,7 +84,8 @@ namespace app {
void onLayerRestacked(doc::DocumentEvent& ev) override;

// InputChainElement impl
void onNewInputPriority(InputChainElement* element) override;
void onNewInputPriority(InputChainElement* element,
const ui::Message* msg) override;
bool onCanCut(Context* ctx) override;
bool onCanCopy(Context* ctx) override;
bool onCanPaste(Context* ctx) override;
Expand Down
22 changes: 13 additions & 9 deletions src/app/ui/input_chain.cpp
@@ -1,5 +1,5 @@
// Aseprite
// Copyright (C) 2001-2015 David Capello
// Copyright (C) 2001-2018 David Capello
//
// This program is distributed under the terms of
// the End-User License Agreement for Aseprite.
Expand All @@ -16,19 +16,23 @@

namespace app {

void InputChain::prioritize(InputChainElement* element)
void InputChain::prioritize(InputChainElement* element,
const ui::Message* msg)
{
if (!m_elements.empty() && m_elements.front() == element)
return;
const bool alreadyInFront =
(!m_elements.empty() && m_elements.front() == element);

auto it = std::find(m_elements.begin(), m_elements.end(), element);
if (it != m_elements.end())
m_elements.erase(it);
if (!alreadyInFront) {
auto it = std::find(m_elements.begin(), m_elements.end(), element);
if (it != m_elements.end())
m_elements.erase(it);
}

for (auto e : m_elements)
e->onNewInputPriority(element);
e->onNewInputPriority(element, msg);

m_elements.insert(m_elements.begin(), element);
if (!alreadyInFront)
m_elements.insert(m_elements.begin(), element);
}

bool InputChain::canCut(Context* ctx)
Expand Down
9 changes: 7 additions & 2 deletions src/app/ui/input_chain.h
@@ -1,5 +1,5 @@
// Aseprite
// Copyright (C) 2001-2016 David Capello
// Copyright (C) 2001-2018 David Capello
//
// This program is distributed under the terms of
// the End-User License Agreement for Aseprite.
Expand All @@ -10,6 +10,10 @@

#include <vector>

namespace ui {
class Message;
}

namespace app {

class Context;
Expand All @@ -21,7 +25,8 @@ namespace app {
// user focus, they call InputChain::prioritize().
class InputChain {
public:
void prioritize(InputChainElement* element);
void prioritize(InputChainElement* element,
const ui::Message* msg);

bool canCut(Context* ctx);
bool canCopy(Context* ctx);
Expand Down
9 changes: 7 additions & 2 deletions src/app/ui/input_chain_element.h
@@ -1,5 +1,5 @@
// Aseprite
// Copyright (C) 2001-2015 David Capello
// Copyright (C) 2001-2018 David Capello
//
// This program is distributed under the terms of
// the End-User License Agreement for Aseprite.
Expand All @@ -8,6 +8,10 @@
#define APP_INPUT_CHAIN_ELEMENT_H_INCLUDED
#pragma once

namespace ui {
class Message;
}

namespace app {

class Context;
Expand All @@ -17,7 +21,8 @@ namespace app {
virtual ~InputChainElement() { }

// Called when a new element has priorty in the chain.
virtual void onNewInputPriority(InputChainElement* element) = 0;
virtual void onNewInputPriority(InputChainElement* element,
const ui::Message* msg) = 0;

virtual bool onCanCut(Context* ctx) = 0;
virtual bool onCanCopy(Context* ctx) = 0;
Expand Down

0 comments on commit 05f6aec

Please sign in to comment.