Merge branch 'master' into konero_svg_icons
This commit is contained in:
commit
e8422eb87f
44 changed files with 4295 additions and 1806 deletions
|
@ -125,9 +125,12 @@ bool isDouble(std::wstring s) { return isDouble(::to_string(s)); }
|
|||
|
||||
std::string toUpper(std::string a) {
|
||||
#ifdef _WIN32
|
||||
return _strupr(const_cast<char *>(a.c_str()));
|
||||
size_t size = a.size();
|
||||
const char* cstr = a.c_str();
|
||||
std::vector<char> buf(cstr, cstr + size + 1);
|
||||
return _strupr(&buf[0]);
|
||||
#else
|
||||
std::string ret = a;
|
||||
std::string ret(a);
|
||||
for (int i = 0; i < (int)ret.length(); i++) ret[i] = toupper(ret[i]);
|
||||
return ret;
|
||||
#endif
|
||||
|
@ -135,9 +138,12 @@ std::string toUpper(std::string a) {
|
|||
|
||||
std::string toLower(std::string a) {
|
||||
#ifdef _WIN32
|
||||
return _strlwr(const_cast<char *>(a.c_str()));
|
||||
size_t size = a.size();
|
||||
const char* cstr = a.c_str();
|
||||
std::vector<char> buf(cstr, cstr + size + 1);
|
||||
return _strlwr(&buf[0]);
|
||||
#else
|
||||
std::string ret = a;
|
||||
std::string ret(a);
|
||||
for (int i = 0; i < (int)ret.length(); i++) ret[i] = tolower(ret[i]);
|
||||
return ret;
|
||||
#endif
|
||||
|
@ -145,27 +151,26 @@ std::string toLower(std::string a) {
|
|||
|
||||
std::wstring toUpper(std::wstring a) {
|
||||
#ifdef _WIN32
|
||||
return _wcsupr(const_cast<wchar_t *>(a.c_str()));
|
||||
size_t size = a.size();
|
||||
const wchar_t* cstr = a.c_str();
|
||||
std::vector<wchar_t> buf(cstr, cstr + size + 1);
|
||||
return _wcsupr(&buf[0]);
|
||||
#else
|
||||
std::wstring ret;
|
||||
for (int i = 0; i < (int)a.length(); i++) {
|
||||
wchar_t c = towupper(a[i]);
|
||||
ret += c;
|
||||
}
|
||||
std::wstring ret(a);
|
||||
for (int i = 0; i < (int)ret.length(); i++) ret[i] = towupper(ret[i]);
|
||||
return ret;
|
||||
#endif
|
||||
}
|
||||
|
||||
std::wstring toLower(std::wstring a) {
|
||||
#ifdef _WIN32
|
||||
return _wcslwr(const_cast<wchar_t *>(a.c_str()));
|
||||
size_t size = a.size();
|
||||
const wchar_t* cstr = a.c_str();
|
||||
std::vector<wchar_t> buf(cstr, cstr + size + 1);
|
||||
return _wcslwr(&buf[0]);
|
||||
#else
|
||||
const int length = (int)a.length();
|
||||
std::wstring ret;
|
||||
ret.resize(length);
|
||||
for (int i = 0; i < length; i++) {
|
||||
ret[i] = towlower(a[i]);
|
||||
}
|
||||
std::wstring ret(a);
|
||||
for (int i = 0; i < (int)ret.length(); i++) ret[i] = towlower(ret[i]);
|
||||
return ret;
|
||||
#endif
|
||||
}
|
||||
|
|
58
toonz/sources/include/cellposition.h
Normal file
58
toonz/sources/include/cellposition.h
Normal file
|
@ -0,0 +1,58 @@
|
|||
#pragma once
|
||||
|
||||
#ifndef CELL_POSITION_INCLUDED
|
||||
#define CELL_POSITION_INCLUDED
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
using std::min;
|
||||
using std::max;
|
||||
|
||||
// Identifies cells by frame and layer rather than row and column
|
||||
class CellPosition {
|
||||
int _frame; // a frame number. corresponds to row in vertical xsheet
|
||||
int _layer; // a layer number. corresponds to col in vertical xsheet
|
||||
|
||||
public:
|
||||
CellPosition() : _frame(0), _layer(0) {}
|
||||
CellPosition(int frame, int layer) : _frame(frame), _layer(layer) {}
|
||||
|
||||
int frame() const { return _frame; }
|
||||
int layer() const { return _layer; }
|
||||
|
||||
void setFrame(int frame) { _frame = frame; }
|
||||
void setLayer(int layer) { _layer = layer; }
|
||||
|
||||
CellPosition &operator=(const CellPosition &that) = default;
|
||||
|
||||
operator bool() const { return _frame || _layer; }
|
||||
|
||||
CellPosition operator+(const CellPosition &add) {
|
||||
return CellPosition(_frame + add._frame, _layer + add._layer);
|
||||
}
|
||||
CellPosition operator*(const CellPosition &mult) {
|
||||
return CellPosition(_frame * mult._frame, _layer * mult._layer);
|
||||
}
|
||||
void ensureValid() {
|
||||
if (_frame < 0) _frame = 0;
|
||||
if (_layer < 0) _layer = 0;
|
||||
}
|
||||
};
|
||||
|
||||
// A square range identified by two corners
|
||||
class CellRange {
|
||||
CellPosition _from, _to; // from.frame <= to.frame && from.layer <= to.layer
|
||||
|
||||
public:
|
||||
CellRange() {}
|
||||
CellRange(const CellPosition &from, const CellPosition &to)
|
||||
: _from(min(from.frame(), to.frame()), min(from.layer(), to.layer()))
|
||||
, _to(max(from.frame(), to.frame()), max(from.layer(), to.layer())) {}
|
||||
|
||||
const CellPosition &from() const { return _from; }
|
||||
const CellPosition &to() const { return _to; }
|
||||
|
||||
CellRange &operator=(const CellRange &that) = default;
|
||||
};
|
||||
|
||||
#endif
|
243
toonz/sources/include/orientation.h
Normal file
243
toonz/sources/include/orientation.h
Normal file
|
@ -0,0 +1,243 @@
|
|||
#pragma once
|
||||
|
||||
#ifndef ORIENTATION_INCLUDED
|
||||
#define ORIENTATION_INCLUDED
|
||||
|
||||
#undef DVAPI
|
||||
#undef DVVAR
|
||||
#ifdef TOONZLIB_EXPORTS
|
||||
#define DVAPI DV_EXPORT_API
|
||||
#define DVVAR DV_EXPORT_VAR
|
||||
#else
|
||||
#define DVAPI DV_IMPORT_API
|
||||
#define DVVAR DV_IMPORT_VAR
|
||||
#endif
|
||||
|
||||
#include "tcommon.h"
|
||||
#include "cellposition.h"
|
||||
#include "toonz/cellpositionratio.h"
|
||||
#include <QPoint>
|
||||
#include <QLine>
|
||||
#include <QRect>
|
||||
#include <QPainterPath>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
|
||||
using std::vector;
|
||||
using std::map;
|
||||
|
||||
// Defines timeline direction: top to bottom; left to right.
|
||||
// old (vertical timeline) = new (universal) = old (kept)
|
||||
// x = layer axis = column
|
||||
// y = frame axis = row
|
||||
|
||||
// A pair of numbers
|
||||
class DVAPI NumberRange {
|
||||
int _from, _to; // _from <= _to
|
||||
|
||||
NumberRange() : _from(0), _to(0) {}
|
||||
|
||||
public:
|
||||
NumberRange(int from, int to) : _from(min(from, to)), _to(max(from, to)) {}
|
||||
|
||||
int from() const { return _from; }
|
||||
int to() const { return _to; }
|
||||
|
||||
int length() const { return _to - _from; }
|
||||
int middle() const { return (_to + _from) / 2; }
|
||||
int weight(double toWeight) const;
|
||||
double ratio(int at) const;
|
||||
|
||||
NumberRange adjusted(int addFrom, int addTo) const;
|
||||
};
|
||||
|
||||
class ColumnFan;
|
||||
class QPixmap;
|
||||
class QPainterPath;
|
||||
|
||||
//! lists predefined rectangle sizes and positions (relative to top left corner
|
||||
//! of a cell)
|
||||
enum class PredefinedRect {
|
||||
CELL, //! size of a cell
|
||||
DRAG_HANDLE_CORNER, //! area for dragging a cell
|
||||
KEY_ICON, //! position of key icon
|
||||
CELL_NAME, //! cell name box
|
||||
CELL_NAME_WITH_KEYFRAME, //! cell name box when keyframe is displayed
|
||||
END_EXTENDER, //! bottom / right extender
|
||||
BEGIN_EXTENDER, //! top / left extender
|
||||
KEYFRAME_AREA, //! part of cell dedicated to key frames
|
||||
DRAG_AREA, //! draggable side bar
|
||||
SOUND_TRACK, //! area dedicated to waveform display
|
||||
PREVIEW_TRACK, //! sound preview area
|
||||
BEGIN_SOUND_EDIT, //! top sound resize
|
||||
END_SOUND_EDIT, //! bottom sound resize
|
||||
NOTE_AREA, //! size of top left note controls
|
||||
NOTE_ICON, //! size of note icons that appear in cells area
|
||||
FRAME_LABEL, //! area for writing frame number
|
||||
FRAME_HEADER,
|
||||
LAYER_HEADER,
|
||||
FOLDED_LAYER_HEADER, //! size of layer header when it is folded
|
||||
PLAY_RANGE, //! area for play range marker within frame header
|
||||
ONION, //! onion handle placement
|
||||
ONION_DOT, //! moveable dot placement
|
||||
ONION_DOT_FIXED, //! fixed dot placement
|
||||
ONION_AREA, //! area where mouse events will alter onion
|
||||
ONION_FIXED_DOT_AREA,
|
||||
ONION_DOT_AREA,
|
||||
PINNED_CENTER_KEY, //! displays a small blue number
|
||||
RENAME_COLUMN, //! where column rename control appears after clicking
|
||||
EYE_AREA, //! clickable area larger than the eye, containing it
|
||||
EYE, //! the eye itself
|
||||
PREVIEW_LAYER_AREA, //! clickable area larger than preview icon, containing
|
||||
//! it
|
||||
PREVIEW_LAYER,
|
||||
LOCK_AREA, //! clickable area larger than lock icon, containing it
|
||||
LOCK, //! the lock icon itself
|
||||
DRAG_LAYER, //! draggable area in layer header
|
||||
LAYER_NAME, //! where to display column name. clicking will rename
|
||||
LAYER_NUMBER, //! where to display column number.
|
||||
SOUND_ICON,
|
||||
VOLUME_TRACK, //! area where track is displayed
|
||||
VOLUME_AREA, //! active area for volume control
|
||||
LOOP_ICON, //! area for repeat animation icon
|
||||
LAYER_HEADER_PANEL, //! panel displaying headers for the layer rows in
|
||||
//! timeline mode
|
||||
THUMBNAIL_AREA, //! area for header thumbnails and other icons
|
||||
THUMBNAIL, //! the actual thumbnail, if there is one
|
||||
PEGBAR_NAME, //! where to display pegbar name
|
||||
PARENT_HANDLE_NAME, //! where to display parent handle number
|
||||
FILTER_COLOR //! where to show layer's filter color
|
||||
};
|
||||
enum class PredefinedLine {
|
||||
LOCKED, //! dotted vertical line when cell is locked
|
||||
SEE_MARKER_THROUGH, //! horizontal marker visible through drag handle
|
||||
CONTINUE_LEVEL, //! level with the same name represented by vertical line
|
||||
CONTINUE_LEVEL_WITH_NAME, //! adjusted when level name is on each marker
|
||||
EXTENDER_LINE //! see grid through extender handle
|
||||
};
|
||||
enum class PredefinedDimension {
|
||||
LAYER, //! width of a layer column / height of layer row
|
||||
FRAME, //! height of frame row / width of frame column
|
||||
INDEX, //! index of this orientation in the array of all
|
||||
SOUND_AMPLITUDE, //! amplitude of sound track, in pixels
|
||||
FRAME_LABEL_ALIGN, //! alignment flag for frame number
|
||||
ONION_TURN, //! onion handle turn in degrees
|
||||
QBOXLAYOUT_DIRECTION, //! direction of QBoxLayout
|
||||
CENTER_ALIGN, //! horizontal / vertical align
|
||||
};
|
||||
enum class PredefinedPath {
|
||||
DRAG_HANDLE_CORNER, //! triangle corner at drag sidebar
|
||||
BEGIN_EASE_TRIANGLE, //! triangle marking beginning of ease range
|
||||
END_EASE_TRIANGLE, //! triangle marking end of ease range
|
||||
BEGIN_PLAY_RANGE, //! play range markers
|
||||
END_PLAY_RANGE,
|
||||
VOLUME_SLIDER_TRACK, //! slider track
|
||||
VOLUME_SLIDER_HEAD //! slider head
|
||||
};
|
||||
enum class PredefinedPoint {
|
||||
KEY_HIDDEN, //! move extender handle that much if key icons are disabled
|
||||
EXTENDER_XY_RADIUS, //! x and y radius for rounded rectangle
|
||||
VOLUME_DIVISIONS_TOP_LEFT //! where to draw volume slider
|
||||
};
|
||||
enum class PredefinedRange {
|
||||
HEADER_FRAME, //! size of of column header height(v) / row header width(h)
|
||||
HEADER_LAYER, //! size of row header width(v) / column header height(h)
|
||||
};
|
||||
|
||||
// Knows everything about geometry of a particular orientation.
|
||||
class DVAPI Orientation {
|
||||
protected:
|
||||
map<PredefinedRect, QRect> _rects;
|
||||
map<PredefinedLine, QLine> _lines;
|
||||
map<PredefinedDimension, int> _dimensions;
|
||||
map<PredefinedPath, QPainterPath> _paths;
|
||||
map<PredefinedPoint, QPoint> _points;
|
||||
map<PredefinedRange, NumberRange> _ranges;
|
||||
|
||||
public:
|
||||
virtual CellPosition xyToPosition(const QPoint &xy,
|
||||
const ColumnFan *fan) const = 0;
|
||||
virtual QPoint positionToXY(const CellPosition &position,
|
||||
const ColumnFan *fan) const = 0;
|
||||
virtual CellPositionRatio xyToPositionRatio(const QPoint &xy) const = 0;
|
||||
virtual QPoint positionRatioToXY(const CellPositionRatio &ratio) const = 0;
|
||||
|
||||
virtual int colToLayerAxis(int layer, const ColumnFan *fan) const = 0;
|
||||
virtual int rowToFrameAxis(int frame) const = 0;
|
||||
|
||||
virtual QPoint frameLayerToXY(int frameAxis, int layerAxis) const = 0;
|
||||
QRect frameLayerRect(const NumberRange &frameAxis,
|
||||
const NumberRange &layerAxis) const;
|
||||
|
||||
virtual NumberRange layerSide(const QRect &area) const = 0;
|
||||
virtual NumberRange frameSide(const QRect &area) const = 0;
|
||||
virtual int layerAxis(const QPoint &xy) const = 0;
|
||||
virtual int frameAxis(const QPoint &xy) const = 0;
|
||||
//! top right corner in vertical layout. bottom left in horizontal
|
||||
virtual QPoint topRightCorner(const QRect &area) const = 0;
|
||||
QRect foldedRectangle(int layerAxis, const NumberRange &frameAxis,
|
||||
int i) const;
|
||||
QLine foldedRectangleLine(int layerAxis, const NumberRange &frameAxis,
|
||||
int i) const;
|
||||
|
||||
virtual CellPosition arrowShift(int direction) const = 0;
|
||||
|
||||
//! line was vertical in vertical timeline. adjust accordingly
|
||||
QLine verticalLine(int layerAxis, const NumberRange &frameAxis) const;
|
||||
QLine horizontalLine(int frameAxis, const NumberRange &layerAxis) const;
|
||||
|
||||
virtual bool isVerticalTimeline() const = 0;
|
||||
virtual bool flipVolume() const = 0;
|
||||
|
||||
virtual QString name() const = 0;
|
||||
virtual QString caption() const = 0;
|
||||
virtual const Orientation *next() const = 0;
|
||||
|
||||
const QRect &rect(PredefinedRect which) const { return _rects.at(which); }
|
||||
const QLine &line(PredefinedLine which) const { return _lines.at(which); }
|
||||
int dimension(PredefinedDimension which) const {
|
||||
return _dimensions.at(which);
|
||||
}
|
||||
const QPainterPath &path(PredefinedPath which) const {
|
||||
return _paths.at(which);
|
||||
}
|
||||
const QPoint &point(PredefinedPoint which) const { return _points.at(which); }
|
||||
const NumberRange &range(PredefinedRange which) const {
|
||||
return _ranges.at(which);
|
||||
}
|
||||
|
||||
virtual int cellWidth() const = 0;
|
||||
virtual int cellHeight() const = 0;
|
||||
|
||||
protected:
|
||||
void addRect(PredefinedRect which, const QRect &rect);
|
||||
void addLine(PredefinedLine which, const QLine &line);
|
||||
void addDimension(PredefinedDimension which, int dimension);
|
||||
void addPath(PredefinedPath which, const QPainterPath &path);
|
||||
void addPoint(PredefinedPoint which, const QPoint &point);
|
||||
void addRange(PredefinedRange which, const NumberRange &range);
|
||||
};
|
||||
|
||||
// Enumerates all orientations available in the system as global const objects.
|
||||
class DVAPI Orientations {
|
||||
const Orientation *_topToBottom, *_leftToRight;
|
||||
vector<const Orientation *> _all;
|
||||
|
||||
Orientations();
|
||||
|
||||
public:
|
||||
~Orientations();
|
||||
|
||||
static const Orientations &instance();
|
||||
|
||||
static const int COUNT = 2;
|
||||
|
||||
static const Orientation *topToBottom();
|
||||
static const Orientation *leftToRight();
|
||||
|
||||
static const vector<const Orientation *> &all();
|
||||
|
||||
static const Orientation *byName(const QString &name);
|
||||
};
|
||||
|
||||
#endif
|
18
toonz/sources/include/saveloadqsettings.h
Normal file
18
toonz/sources/include/saveloadqsettings.h
Normal file
|
@ -0,0 +1,18 @@
|
|||
#pragma once
|
||||
|
||||
#ifndef SAVE_LOAD_QSETTINGS_INCLUDED
|
||||
#define SAVE_LOAD_QSETTINGS_INCLUDED
|
||||
|
||||
#include <QSettings>
|
||||
|
||||
class QSettings;
|
||||
|
||||
//! An interface that claims: this object wants to save / load something
|
||||
//! into / from provided qsettings
|
||||
class SaveLoadQSettings {
|
||||
public:
|
||||
virtual void save(QSettings &settings) const = 0;
|
||||
virtual void load(QSettings &settings) = 0;
|
||||
};
|
||||
|
||||
#endif
|
48
toonz/sources/include/toonz/cellpositionratio.h
Normal file
48
toonz/sources/include/toonz/cellpositionratio.h
Normal file
|
@ -0,0 +1,48 @@
|
|||
#pragma once
|
||||
|
||||
#ifndef CELL_POSITION_RATIO_INCLUDED
|
||||
#define CELL_POSITION_RATIO_INCLUDED
|
||||
|
||||
#undef DVAPI
|
||||
#undef DVVAR
|
||||
#ifdef TOONZLIB_EXPORTS
|
||||
#define DVAPI DV_EXPORT_API
|
||||
#define DVVAR DV_EXPORT_VAR
|
||||
#else
|
||||
#define DVAPI DV_IMPORT_API
|
||||
#define DVVAR DV_IMPORT_VAR
|
||||
#endif
|
||||
|
||||
#include "tcommon.h"
|
||||
|
||||
class DVAPI Ratio {
|
||||
int m_num, m_denom;
|
||||
|
||||
void normalize();
|
||||
Ratio normalized() const;
|
||||
|
||||
public:
|
||||
Ratio(int num, int denom);
|
||||
|
||||
friend Ratio operator+(const Ratio &a, const Ratio &b);
|
||||
friend Ratio operator-(const Ratio &a, const Ratio &b);
|
||||
friend Ratio operator*(const Ratio &a, const Ratio &b);
|
||||
friend Ratio operator/(const Ratio &a, const Ratio &b);
|
||||
|
||||
friend int operator*(const Ratio &a, int b);
|
||||
|
||||
bool operator!() const { return m_num == 0; }
|
||||
};
|
||||
|
||||
class DVAPI CellPositionRatio {
|
||||
Ratio m_frame, m_layer;
|
||||
|
||||
public:
|
||||
CellPositionRatio(const Ratio &frame, const Ratio &layer)
|
||||
: m_frame(frame), m_layer(layer) {}
|
||||
|
||||
Ratio frame() const { return m_frame; }
|
||||
Ratio layer() const { return m_layer; }
|
||||
};
|
||||
|
||||
#endif
|
|
@ -24,9 +24,10 @@ class TIStream;
|
|||
open folded columns, activate() and to know if column is folded or not,
|
||||
isActive().
|
||||
|
||||
Class provides column x-axis coordinate too.
|
||||
It's possible to know column index by column x-axis coordinate, colToX()
|
||||
and vice versa, xToCol().
|
||||
Class provides column layer-axis coordinate too.
|
||||
It's possible to know column index by column layer-axis coordinate,
|
||||
colToLayerAxis()
|
||||
and vice versa, layerAxisToCol().
|
||||
*/
|
||||
//=============================================================================
|
||||
|
||||
|
@ -40,6 +41,7 @@ class DVAPI ColumnFan {
|
|||
std::vector<Column> m_columns;
|
||||
std::map<int, int> m_table;
|
||||
int m_firstFreePos;
|
||||
int m_unfolded, m_folded;
|
||||
|
||||
/*!
|
||||
Called by activate() and deactivate() to update columns coordinates.
|
||||
|
@ -52,6 +54,9 @@ Constructs a ColumnFan with default value.
|
|||
*/
|
||||
ColumnFan();
|
||||
|
||||
//! Adjust column sizes when switching orientation
|
||||
void setDimension(int unfolded);
|
||||
|
||||
/*!
|
||||
Set column \b col not folded.
|
||||
\sa deactivate() and isActive()
|
||||
|
@ -69,15 +74,19 @@ Return true if column \b col is active, column is not folded, else return false.
|
|||
bool isActive(int col) const;
|
||||
|
||||
/*!
|
||||
Return column index of column in x-axis coordinate \b x.
|
||||
\sa colToX()
|
||||
Return column index of column in layer axis (x for vertical timeline, y for
|
||||
horizontal).
|
||||
\sa colToLayerAxis()
|
||||
*/
|
||||
int xToCol(int x) const;
|
||||
int layerAxisToCol(int layerAxis) const;
|
||||
/*!
|
||||
Return column x-axis coordinate of column identify with \b col.
|
||||
\sa xToCol()
|
||||
Return layer coordinate (x for vertical timeline, y for horizontal)
|
||||
of column identified by \b col.
|
||||
\sa layerAxisToCol()
|
||||
*/
|
||||
int colToX(int col) const;
|
||||
int colToLayerAxis(int col) const;
|
||||
|
||||
void copyFoldedStateFrom(const ColumnFan &from);
|
||||
|
||||
bool isEmpty() const;
|
||||
|
||||
|
|
|
@ -362,6 +362,9 @@ public:
|
|||
void enableExpandFunctionHeader(bool on);
|
||||
bool isExpandFunctionHeaderEnabled() const { return m_expandFunctionHeader; }
|
||||
|
||||
void enableShowColumnNumbers(bool on);
|
||||
bool isShowColumnNumbersEnabled() const { return m_showColumnNumbers; }
|
||||
|
||||
// Animation tab
|
||||
|
||||
void setKeyframeType(int s);
|
||||
|
@ -503,7 +506,7 @@ private:
|
|||
m_rewindAfterPlaybackEnabled, m_fitToFlipbookEnabled, m_autosaveEnabled,
|
||||
m_autosaveSceneEnabled, m_autosaveOtherFilesEnabled,
|
||||
m_defaultViewerEnabled, m_pixelsOnly, m_showXSheetToolbar,
|
||||
m_expandFunctionHeader;
|
||||
m_expandFunctionHeader, m_showColumnNumbers;
|
||||
bool m_rasterOptimizedMemory, m_saveUnpaintedInCleanup,
|
||||
m_askForOverrideRender, m_automaticSVNFolderRefreshEnabled, m_SVNEnabled,
|
||||
m_levelsBackupEnabled, m_minimizeSaveboxAfterEditing,
|
||||
|
|
|
@ -13,6 +13,8 @@
|
|||
// TnzLib includes
|
||||
#include "toonz/txshcolumn.h"
|
||||
|
||||
#include "cellposition.h"
|
||||
|
||||
// STD includes
|
||||
#include <set>
|
||||
|
||||
|
@ -46,6 +48,7 @@ class ToonzScene;
|
|||
class TXshSoundColumn;
|
||||
class TXshNoteSet;
|
||||
class TFrameId;
|
||||
class Orientation;
|
||||
|
||||
//=============================================================================
|
||||
|
||||
|
@ -58,62 +61,68 @@ class TFrameId;
|
|||
/*!
|
||||
Inherits \b TSmartObject and \b TPersist.
|
||||
|
||||
The class provides a collection of functions that returns xsheet
|
||||
The class provides a collection of functions that returns xsheet
|
||||
elements, defined in
|
||||
struct \b TXsheetImp, and enables manipulation of these. Most
|
||||
important xsheet elements
|
||||
are: a \b column \b set \b TColumnSetT, a \b pegbar \b tree \b
|
||||
struct \b TXsheetImp, and enables manipulation of these. Most important
|
||||
xsheet elements
|
||||
are: a \b column \b set \b TColumnSetT, a \b pegbar \b tree \b
|
||||
TStageObjectTree, a \b fx
|
||||
\b dag \b FxDag, a \b sound \b track \b TSoundTrack and a \b
|
||||
scene \b ToonzScene.
|
||||
\b dag \b FxDag, a \b sound \b track \b TSoundTrack and a \b scene \b
|
||||
ToonzScene.
|
||||
|
||||
A \b column \b set contains all xsheet column. A collection of
|
||||
function, concern column
|
||||
set, allows to manage xsheet column. It's possible to know
|
||||
xsheet column number,
|
||||
getColumnCount(), know first not empty column index,
|
||||
For purposes of this class, a Column is a graphics layer, and a
|
||||
row is a frame number.
|
||||
(Whether horizontal or vertial is a matter of displaying).
|
||||
|
||||
A \b column \b set contains all xsheet columns. A collection of
|
||||
functions, concerning column
|
||||
set, allows to manage xsheet column. It's possible to know xsheet column
|
||||
count,
|
||||
getColumnCount(), know first non empty column index,
|
||||
getFirstFreeColumnIndex(),
|
||||
or know if column in datum index is empty, isColumnEmpty(). You
|
||||
can work on single xsheet
|
||||
column, getColumn(), using its indexes: insert and remove a
|
||||
column with insertColumn()
|
||||
and removeColumn() or move column from an index to another using
|
||||
or know if column in datum index is empty, isColumnEmpty(). You can work
|
||||
on single xsheet
|
||||
column, getColumn(), using its indexes: insert and remove a column with
|
||||
insertColumn()
|
||||
and removeColumn() or move column from an index to another using
|
||||
moveColumn().
|
||||
|
||||
You can manage also column visualization in xsheet, using the
|
||||
xsheet object \b ColumnFan
|
||||
getColumnFan(), and find column icon getColumnIcon().
|
||||
You can manage also column visualization in xsheet, using the xsheet
|
||||
object \b ColumnFan
|
||||
getColumnFan(), and find column icon getColumnIcon().
|
||||
|
||||
It's possible work on xsheet cells directly, getCell() and
|
||||
setCell() or getCells() and
|
||||
setCells(); cells are identified in xsheet by two index one for
|
||||
row and one for column.
|
||||
You can insert, remove or clear cells using insertCells(),
|
||||
removeCells() or clearCells();
|
||||
the difference between the remove and the clear function is the
|
||||
shift of remains cells.
|
||||
Also there are functions to manipulate cells reverseCells(),
|
||||
cell positions will be identified by a pair of row+column index,
|
||||
which is a separate class.
|
||||
|
||||
It's possible work on xsheet cells directly, getCell() and setCell() or
|
||||
getCells() and
|
||||
setCells(); cells are identified in xsheet by two index one for row and
|
||||
one for column.
|
||||
You can insert, remove or clear cells using insertCells(), removeCells()
|
||||
or clearCells();
|
||||
the difference between the remove and the clear function is the shift of
|
||||
remains cells.
|
||||
Also there are functions to manipulate cells reverseCells(),
|
||||
swingCells(),
|
||||
incrementCells(), duplicateCells(), int upTo, stepCells(),
|
||||
eachCells().
|
||||
incrementCells(), duplicateCells(), int upTo, stepCells(), eachCells().
|
||||
|
||||
About \b pegbar \b tree \b TStageObjectTree, it's possible to
|
||||
manage it through the stage object's
|
||||
related functions.
|
||||
About \b pegbar \b tree \b TStageObjectTree, it's possible to manage it
|
||||
through the stage object's
|
||||
related functions.
|
||||
|
||||
The \b fx \b dag \b FxDag getFxDag() is not managed with direct
|
||||
The \b fx \b dag \b FxDag getFxDag() is not managed with direct
|
||||
functions but is always
|
||||
up to date; in fact same functions update it. For example
|
||||
up to date; in fact same functions update it. For example
|
||||
insertColumn(), if necessary,
|
||||
insert column index in fx dag, the same happen in setCells().
|
||||
insert column index in fx dag, the same happen in setCells().
|
||||
|
||||
The \b sound \b track \b TSoundTrack contain a mixed sound,
|
||||
computed using makeSound(),
|
||||
of all \b TXshSoundColumn present in xsheet.
|
||||
The \b sound \b track \b TSoundTrack contain a mixed sound, computed
|
||||
using makeSound(),
|
||||
of all \b TXshSoundColumn present in xsheet.
|
||||
|
||||
It's possible take and know the \b scene \b ToonzScene to which
|
||||
the xsheet refers using
|
||||
getScene() and setScene().
|
||||
It's possible take and know the \b scene \b ToonzScene to which the
|
||||
xsheet refers using
|
||||
getScene() and setScene().
|
||||
*/
|
||||
|
||||
class DVAPI TXsheet final : public TSmartObject, public TPersist {
|
||||
|
@ -159,64 +168,66 @@ public:
|
|||
\sa getMaxFrame()
|
||||
*/
|
||||
int getFrameCount() const;
|
||||
/*! Returns true if cells contained in rect delimited by first row \b \e r0,
|
||||
last row \b \e r1
|
||||
and first column \b \e c0, last column \b \e c1 are empty; otherwise,
|
||||
returns false.
|
||||
|
||||
/*! Returns true if all cells in rect delimited by first frame \b \e
|
||||
pos0.frame,
|
||||
last frame \b \e pos1.frame and first layer \b \e pos0.layer, last layer \b
|
||||
\e pos1.layer
|
||||
are empty; otherwise, false.
|
||||
*/
|
||||
bool isRectEmpty(int r0, int c0, int r1, int c1) const;
|
||||
bool isRectEmpty(const CellPosition &pos0, const CellPosition &pos1) const;
|
||||
|
||||
/*! Returns the \b TXshCell cell in row identified by index \b \e row and
|
||||
column identified by
|
||||
index \b \e col. If column \b TXshColumnP in \b \e col is empty return
|
||||
column identified by index \b \e col. If column \b TXshColumnP in \b \e col
|
||||
is empty return
|
||||
an empty cell.
|
||||
\sa setCell(), getCells(), setCells()
|
||||
*/
|
||||
const TXshCell &getCell(int row, int col) const;
|
||||
|
||||
const TXshCell &getCell(const CellPosition &pos) const;
|
||||
|
||||
bool setCell(int row, int col, const TXshCell &cell);
|
||||
/*! Set \b \e cells[] to \b \e rowCount cells of column identified by index \b
|
||||
\e col starting from
|
||||
row identified by index \b \e row. If column is empty or is not a \b
|
||||
TXshCellColumn
|
||||
set \b \e cells[] to \b \e rowCount empty cells.
|
||||
\e col starting from row identified by index \b \e row. If column is empty
|
||||
or is not a \b
|
||||
TXshCellColumn set \b \e cells[] to \b \e rowCount empty cells.
|
||||
\sa getCells(), setCells(), getCell()
|
||||
*/
|
||||
void getCells(int row, int col, int rowCount, TXshCell cells[]) const;
|
||||
/*! If column identified by index \b \e col is a \b TXshCellColumn or is empty
|
||||
and is not
|
||||
locked, this method sets to \b \e cells[] the given \b \e rowCount
|
||||
cells of column \b \e col starting from
|
||||
row \b \e row. If column in \b \e col is empty it creates a new column
|
||||
recalling
|
||||
\b TColumnSetT::touchColumn() and sets the new cells to \b \e cells[],
|
||||
and on creating a new
|
||||
column it adds it to fx dag \b FxDag.
|
||||
If cells in \b \e row and \b \e col are not empty recalls \b
|
||||
TXshCellColumn::setCells(),
|
||||
insert the new cells \b \e cells[] in \b \e row \b \e col and shift
|
||||
old cells.
|
||||
If xsheet change it updates xsheet's frame count.
|
||||
Return false if cannot set cells.
|
||||
\sa getCells(), setCell(), getCell()
|
||||
and is not
|
||||
locked, this method sets to \b \e cells[] the given \b \e rowCount cells of
|
||||
column \b \e col starting from
|
||||
row \b \e row. If column in \b \e col is empty it creates a new column
|
||||
recalling
|
||||
\b TColumnSetT::touchColumn() and sets the new cells to \b \e cells[], and
|
||||
on creating a new
|
||||
column it adds it to fx dag \b FxDag.
|
||||
If cells in \b \e row and \b \e col are not empty recalls \b
|
||||
TXshCellColumn::setCells(),
|
||||
insert the new cells \b \e cells[] in \b \e row \b \e col and shift old
|
||||
cells.
|
||||
If xsheet change it updates xsheet's frame count. Return false if cannot set
|
||||
cells.
|
||||
\sa getCells(), setCell(), getCell()
|
||||
*/
|
||||
bool setCells(int row, int col, int rowCount, const TXshCell cells[]);
|
||||
/*! If column identified by index \b \e col is not empty, is a \b \e
|
||||
TXshCellColumn and is not
|
||||
locked this method inserts in row identified by index \b \e row \b \e
|
||||
rowCount empty cells, it calls
|
||||
TXshCellColumn::insertEmptyCells(). An update of xsheet's frame count
|
||||
TXshCellColumn and is not locked this method inserts in row identified by
|
||||
index \b \e row \b \e
|
||||
rowCount empty cells, it calls TXshCellColumn::insertEmptyCells(). An
|
||||
update of xsheet's frame count
|
||||
is performed.
|
||||
\sa setCells(), removeCells()
|
||||
*/
|
||||
void insertCells(int row, int col, int rowCount = 1);
|
||||
|
||||
/*! If column identified by index \b \e col is not empty, is a \b
|
||||
TXshCellColumn and is not
|
||||
locked, this method removes \b \e rowCount cells starting from \b \e
|
||||
row, it calls
|
||||
TXshCellColumn::removeCells(). It removes cells without shift
|
||||
remaining cells.
|
||||
An update of xsheet's frame count is performed.
|
||||
TXshCellColumn and is not locked, this method removes \b \e rowCount cells
|
||||
starting from \b \e
|
||||
row, it calls TXshCellColumn::removeCells(). It removes cells without shift
|
||||
remaining cells. An update of xsheet's frame count is performed.
|
||||
\sa clearCells(), insertCells()
|
||||
*/
|
||||
void removeCells(int row, int col, int rowCount = 1);
|
||||
|
@ -232,10 +243,10 @@ Return false if cannot set cells.
|
|||
*/
|
||||
void clearAll();
|
||||
/*! Returns cell range of column identified by index \b \e col and set \b \e
|
||||
r0 and \b \e r1
|
||||
respectively to first and last not empty cell, it then recalls \b
|
||||
TXshCellColumn::getRange().
|
||||
If column is empty or is not a \b TXshCellColumn this method returns
|
||||
r0 and \b \e r1 respectively to first and last not empty cell, it then
|
||||
recalls \b
|
||||
TXshCellColumn::getRange(). If column is empty or is not a \b
|
||||
TXshCellColumn this method returns
|
||||
zero and sets
|
||||
\b \e r0 to 0 and \b \e r1 to -1.
|
||||
*/
|
||||
|
@ -504,8 +515,9 @@ in TXsheetImp.
|
|||
FxDag *getFxDag() const;
|
||||
/*! Returns a pointer to object \b ColumnFan contained in \b TXsheetImp, this
|
||||
object allows the user to manage columns visualization in xsheet.
|
||||
TXsheet maintains one column fan per each orientation.
|
||||
*/
|
||||
ColumnFan *getColumnFan() const;
|
||||
ColumnFan *getColumnFan(const Orientation *o) const;
|
||||
/*! Returns a pointer to \b ToonzScene contained in \b TXsheetImp, that is the
|
||||
scene to
|
||||
which the xsheet refers.
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#include <QList>
|
||||
|
||||
#include "tpersist.h"
|
||||
#include "orientation.h"
|
||||
|
||||
#undef DVAPI
|
||||
#undef DVVAR
|
||||
|
@ -30,10 +31,11 @@ class DVAPI TXshSoundLevel final : public TXshLevel {
|
|||
int m_frameSoundCount;
|
||||
double m_fps;
|
||||
//! Values is a map of \b Integer and \b DoublePair.
|
||||
/*!Integer is horizontal value of row pixel.
|
||||
/*! Two maps, one for vertical layout and one for horizontal.
|
||||
Integer is pixel number since start of sound.
|
||||
DoublePair is computed according to frameRate, frameCount
|
||||
and soundtrack pressure.*/
|
||||
std::map<int, DoublePair> m_values;
|
||||
and soundtrack pressure. Means sound min and max.*/
|
||||
std::map<int, DoublePair> m_values[Orientations::COUNT];
|
||||
|
||||
TFilePath m_path;
|
||||
|
||||
|
@ -60,9 +62,11 @@ public:
|
|||
void save() override;
|
||||
void save(const TFilePath &path);
|
||||
|
||||
void computeValues(int frameHeight = 20);
|
||||
void computeValuesFor(const Orientation *o);
|
||||
void computeValues();
|
||||
|
||||
void getValueAtPixel(int pixel, DoublePair &values) const;
|
||||
void getValueAtPixel(const Orientation *o, int pixel,
|
||||
DoublePair &values) const;
|
||||
|
||||
/*! Set frame rate to \b fps. \sa getSamplePerFrame() */
|
||||
void setFrameRate(double fps);
|
||||
|
|
|
@ -4,6 +4,9 @@
|
|||
#define SPREADSHEETVIEWER_H
|
||||
|
||||
#include "tcommon.h"
|
||||
#include "cellposition.h"
|
||||
#include "toonz/cellpositionratio.h"
|
||||
// #include "orientation.h"
|
||||
#include <QFrame>
|
||||
#include <QScrollArea>
|
||||
|
||||
|
@ -20,6 +23,7 @@
|
|||
// forward declaration
|
||||
class TFrameHandle;
|
||||
class SpreadsheetViewer;
|
||||
class Orientation;
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
|
||||
|
@ -30,23 +34,51 @@ class GenericPanel;
|
|||
|
||||
//-------------------------------------------------------------------
|
||||
|
||||
class DVAPI FrameScroller {
|
||||
QList<FrameScroller *> m_connectedScrollers;
|
||||
// Use composition rather than inheritance.
|
||||
// How this works:
|
||||
// * scroll area scrollbars sends event to this;
|
||||
// * it notifies every other FrameScroller with difference;
|
||||
// * they handle it by adjusting their scrollbars
|
||||
class DVAPI FrameScroller final : public QObject {
|
||||
Q_OBJECT
|
||||
|
||||
const Orientation *m_orientation;
|
||||
QScrollArea *m_scrollArea;
|
||||
int m_lastX, m_lastY;
|
||||
bool m_syncing;
|
||||
|
||||
public:
|
||||
FrameScroller();
|
||||
virtual ~FrameScroller();
|
||||
void connectScroller(FrameScroller *scroller);
|
||||
void disconnectScroller(FrameScroller *scroller);
|
||||
bool isScrollerConnected(FrameScroller *scroller);
|
||||
|
||||
virtual QScrollArea *getFrameScrollArea() const = 0;
|
||||
void setFrameScrollArea(QScrollArea *scrollArea);
|
||||
QScrollArea *getFrameScrollArea() const { return m_scrollArea; }
|
||||
|
||||
void setOrientation(const Orientation *o) { m_orientation = o; }
|
||||
const Orientation *orientation() const { return m_orientation; }
|
||||
|
||||
void registerFrameScroller();
|
||||
void unregisterFrameScroller();
|
||||
|
||||
void prepareToScroll(int dy);
|
||||
virtual void onPrepareToScroll(int dy) {}
|
||||
void prepareToScrollOthers(const QPoint &offset);
|
||||
|
||||
void setSyncing(bool s) { m_syncing = s; }
|
||||
bool isSyncing() { return m_syncing; }
|
||||
|
||||
private:
|
||||
void connectScrollbars();
|
||||
void disconnectScrollbars();
|
||||
|
||||
void handleScroll(const QPoint &offset) const;
|
||||
void onScroll(const CellPositionRatio &offset);
|
||||
|
||||
void prepareToScrollRatio(const CellPositionRatio &offset);
|
||||
|
||||
private slots:
|
||||
void onVScroll(int value);
|
||||
void onHScroll(int value);
|
||||
signals:
|
||||
void prepareToScrollOffset(const QPoint &offset);
|
||||
};
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
|
@ -190,8 +222,7 @@ protected:
|
|||
|
||||
//-------------------------------------------------------------------
|
||||
|
||||
class DVAPI SpreadsheetViewer : public QFrame,
|
||||
public Spreadsheet::FrameScroller {
|
||||
class DVAPI SpreadsheetViewer : public QFrame {
|
||||
Q_OBJECT
|
||||
|
||||
QColor m_lightLightBgColor; // RowPanel background (124,124,124)
|
||||
|
@ -269,6 +300,10 @@ class DVAPI SpreadsheetViewer : public QFrame,
|
|||
int m_markRowDistance, m_markRowOffset;
|
||||
// QRect m_selectedCells; // x=col, y=row
|
||||
bool m_isComputingSize;
|
||||
// const Orientation *m_orientation;
|
||||
|
||||
protected:
|
||||
Spreadsheet::FrameScroller m_frameScroller;
|
||||
|
||||
public:
|
||||
SpreadsheetViewer(QWidget *parent);
|
||||
|
@ -286,9 +321,6 @@ public:
|
|||
|
||||
int getRowCount() const { return m_rowCount; }
|
||||
|
||||
// provvisorio
|
||||
QScrollArea *getFrameScrollArea() const override { return m_cellScrollArea; }
|
||||
|
||||
// QProperty
|
||||
void setLightLightBGColor(const QColor &color) {
|
||||
m_lightLightBgColor = color;
|
||||
|
@ -354,7 +386,6 @@ public:
|
|||
}
|
||||
|
||||
void scroll(QPoint delta);
|
||||
void onPrepareToScroll(int dy) override { refreshContentSize(0, dy); }
|
||||
|
||||
void setAutoPanSpeed(const QPoint &speed);
|
||||
void setAutoPanSpeed(const QRect &widgetBounds, const QPoint &mousePos);
|
||||
|
@ -368,6 +399,13 @@ public:
|
|||
int columnToX(int col) const;
|
||||
int rowToY(int row) const;
|
||||
|
||||
CellPosition xyToPosition(const QPoint &point) const;
|
||||
QPoint positionToXY(const CellPosition &pos) const;
|
||||
|
||||
CellRange xyRectToRange(const QRect &rect) const;
|
||||
|
||||
// const Orientation *orientation () const { return m_orientation; }
|
||||
|
||||
bool refreshContentSize(int scrollDx, int scrollDy);
|
||||
|
||||
int getCurrentRow() const { return m_currentRow; }
|
||||
|
@ -413,6 +451,8 @@ public slots:
|
|||
void updateAreas();
|
||||
void onVSliderChanged(int);
|
||||
void onHSliderChanged(int);
|
||||
|
||||
void onPrepareToScrollOffset(const QPoint &offset);
|
||||
/*
|
||||
void updateAllAree();
|
||||
void updateCellColumnAree();
|
||||
|
|
|
@ -19,6 +19,7 @@ set(MOC_HEADERS
|
|||
cellkeyframedata.h
|
||||
cellkeyframeselection.h
|
||||
cellselection.h
|
||||
../include/cellposition.h
|
||||
cleanuppaletteviewer.h
|
||||
cleanuppopup.h
|
||||
cleanuppreview.h
|
||||
|
@ -61,6 +62,7 @@ set(MOC_HEADERS
|
|||
keyframedata.h
|
||||
keyframeselection.h
|
||||
keyframemover.h
|
||||
layerheaderpanel.h
|
||||
levelcreatepopup.h
|
||||
levelsettingspopup.h
|
||||
linesfadepopup.h
|
||||
|
@ -77,6 +79,7 @@ set(MOC_HEADERS
|
|||
meshifypopup.h
|
||||
messagepanel.h
|
||||
moviegenerator.h
|
||||
../include/orientation.h
|
||||
onionskinmaskgui.h
|
||||
outputsettingspopup.h
|
||||
overwritepopup.h
|
||||
|
@ -90,6 +93,7 @@ set(MOC_HEADERS
|
|||
renumberpopup.h
|
||||
reslist.h
|
||||
ruler.h
|
||||
../include/saveloadqsettings.h
|
||||
savepresetpopup.h
|
||||
scanlist.h
|
||||
scanpopup.h
|
||||
|
@ -217,6 +221,7 @@ set(SOURCES
|
|||
fxparameditorpopup.cpp
|
||||
histogrampopup.cpp
|
||||
insertfxpopup.cpp
|
||||
layerheaderpanel.cpp
|
||||
levelcreatepopup.cpp
|
||||
levelsettingspopup.cpp
|
||||
linetestcapturepane.cpp
|
||||
|
|
|
@ -1586,7 +1586,7 @@ void TCellSelection::deleteCells() {
|
|||
getSelectedCells(r0, c0, r1, c1);
|
||||
TXsheet *xsh = TApp::instance()->getCurrentXsheet()->getXsheet();
|
||||
// if all the selected cells are already empty, then do nothing
|
||||
if (xsh->isRectEmpty(r0, c0, r1, c1)) return;
|
||||
if (xsh->isRectEmpty(CellPosition(r0, c0), CellPosition(r1, c1))) return;
|
||||
TCellData *data = new TCellData();
|
||||
data->setCells(xsh, r0, c0, r1, c1);
|
||||
DeleteCellsUndo *undo =
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
#include "toonz/txshleveltypes.h"
|
||||
#include "toonz/txshsimplelevel.h"
|
||||
#include "toonz/txshcell.h"
|
||||
#include "orientation.h"
|
||||
|
||||
// TnzCore includes
|
||||
#include "tvectorimage.h"
|
||||
|
@ -201,10 +202,13 @@ void TColumnSelection::cloneChild() {
|
|||
//-----------------------------------------------------------------------------
|
||||
|
||||
void TColumnSelection::hideColumns() {
|
||||
TApp *app = TApp::instance();
|
||||
ColumnFan *columnFan = app->getCurrentXsheet()->getXsheet()->getColumnFan();
|
||||
std::set<int>::iterator it = m_indices.begin();
|
||||
for (; it != m_indices.end(); ++it) columnFan->deactivate(*it);
|
||||
TApp *app = TApp::instance();
|
||||
for (auto o : Orientations::all()) {
|
||||
ColumnFan *columnFan =
|
||||
app->getCurrentXsheet()->getXsheet()->getColumnFan(o);
|
||||
std::set<int>::iterator it = m_indices.begin();
|
||||
for (; it != m_indices.end(); ++it) columnFan->deactivate(*it);
|
||||
}
|
||||
m_indices.clear();
|
||||
app->getCurrentXsheet()->notifyXsheetChanged();
|
||||
// DA FARE (non c'e una notica per il solo cambiamento della testa delle
|
||||
|
|
|
@ -334,7 +334,7 @@ bool KeyframeMoverTool::canMove(const TPoint &pos) {
|
|||
if (pos.x < 0) return false;
|
||||
|
||||
int col = pos.x;
|
||||
int startCol = getViewer()->xToColumn(m_startPos.x);
|
||||
int startCol = getViewer()->xyToPosition(m_startPos).layer();
|
||||
if (col != startCol) return false;
|
||||
|
||||
return true;
|
||||
|
@ -358,14 +358,15 @@ void KeyframeMoverTool::onCellChange(int row, int col) {
|
|||
//-----------------------------------------------------------------------------
|
||||
|
||||
void KeyframeMoverTool::onClick(const QMouseEvent *event) {
|
||||
m_firstKeyframeMovement = true;
|
||||
m_selecting = false;
|
||||
TXsheet *xsheet = getViewer()->getXsheet();
|
||||
int row = getViewer()->yToRow(event->pos().y());
|
||||
int col = getViewer()->xToColumn(event->pos().x());
|
||||
m_firstRow = row;
|
||||
m_firstCol = col;
|
||||
bool isSelected = getSelection()->isSelected(row, col);
|
||||
m_firstKeyframeMovement = true;
|
||||
m_selecting = false;
|
||||
TXsheet *xsheet = getViewer()->getXsheet();
|
||||
CellPosition cellPosition = getViewer()->xyToPosition(event->pos());
|
||||
int row = cellPosition.frame();
|
||||
int col = cellPosition.layer();
|
||||
m_firstRow = row;
|
||||
m_firstCol = col;
|
||||
bool isSelected = getSelection()->isSelected(row, col);
|
||||
if (!m_justMovement) {
|
||||
if (event->modifiers() & Qt::ControlModifier)
|
||||
ctrlSelect(row, col);
|
||||
|
@ -389,11 +390,12 @@ void KeyframeMoverTool::onClick(const QMouseEvent *event) {
|
|||
//-----------------------------------------------------------------------------
|
||||
|
||||
void KeyframeMoverTool::onDrag(const QMouseEvent *e) {
|
||||
int x = e->pos().x();
|
||||
int y = e->pos().y();
|
||||
m_curPos = TPointD(x, y);
|
||||
int row = getViewer()->yToRow(y);
|
||||
int col = getViewer()->xToColumn(x);
|
||||
int x = e->pos().x();
|
||||
int y = e->pos().y();
|
||||
m_curPos = TPointD(x, y);
|
||||
CellPosition cellPosition = getViewer()->xyToPosition(e->pos());
|
||||
int row = cellPosition.frame();
|
||||
int col = cellPosition.layer();
|
||||
if (m_selecting)
|
||||
rectSelect(row, col);
|
||||
else {
|
||||
|
@ -417,7 +419,7 @@ void KeyframeMoverTool::onDrag(const QMouseEvent *e) {
|
|||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void KeyframeMoverTool::onRelease(int row, int col) {
|
||||
void KeyframeMoverTool::onRelease(const CellPosition &pos) {
|
||||
if (m_selecting) {
|
||||
m_selecting = false;
|
||||
getViewer()->updateCells();
|
||||
|
|
|
@ -92,7 +92,7 @@ public:
|
|||
|
||||
void onClick(const QMouseEvent *event) override;
|
||||
void onDrag(const QMouseEvent *event) override;
|
||||
void onRelease(int row, int col) override;
|
||||
void onRelease(const CellPosition &pos) override;
|
||||
void drawCellsArea(QPainter &p) override;
|
||||
};
|
||||
|
||||
|
|
240
toonz/sources/toonz/layerheaderpanel.cpp
Normal file
240
toonz/sources/toonz/layerheaderpanel.cpp
Normal file
|
@ -0,0 +1,240 @@
|
|||
#include "layerheaderpanel.h"
|
||||
|
||||
#include <QPainter>
|
||||
#include <QToolTip>
|
||||
|
||||
#include "xsheetviewer.h"
|
||||
#include "xshcolumnviewer.h"
|
||||
|
||||
#include "tapp.h"
|
||||
#include "toonz/tscenehandle.h"
|
||||
#include "toonz/txsheethandle.h"
|
||||
#include "toonz/tobjecthandle.h"
|
||||
|
||||
#include "toonz/preferences.h"
|
||||
|
||||
using XsheetGUI::ColumnArea;
|
||||
|
||||
#if QT_VERSION >= 0x050500
|
||||
LayerHeaderPanel::LayerHeaderPanel(XsheetViewer *viewer, QWidget *parent,
|
||||
Qt::WindowFlags flags)
|
||||
#else
|
||||
LayerHeaderPanel::LayerHeaderPanel(XsheetViewer *viewer, QWidget *parent,
|
||||
Qt::WFlags flags)
|
||||
#endif
|
||||
: QWidget(parent, flags), m_viewer(viewer) {
|
||||
const Orientation *o = Orientations::leftToRight();
|
||||
QRect rect = o->rect(PredefinedRect::LAYER_HEADER_PANEL);
|
||||
|
||||
setObjectName("layerHeaderPanel");
|
||||
|
||||
setFixedSize(rect.size());
|
||||
|
||||
setMouseTracking(true);
|
||||
}
|
||||
|
||||
LayerHeaderPanel::~LayerHeaderPanel() {}
|
||||
|
||||
namespace {
|
||||
|
||||
QColor mix(const QColor &a, const QColor &b, double w) {
|
||||
return QColor(a.red() * w + b.red() * (1 - w),
|
||||
a.green() * w + b.green() * (1 - w),
|
||||
a.blue() * w + b.blue() * (1 - w));
|
||||
}
|
||||
|
||||
QColor withAlpha(const QColor &color, double alpha) {
|
||||
QColor result(color);
|
||||
result.setAlpha(alpha * 255);
|
||||
return result;
|
||||
}
|
||||
|
||||
QRect shorter(const QRect original) { return original.adjusted(0, 2, 0, -2); }
|
||||
|
||||
QLine leftSide(const QRect &r) { return QLine(r.topLeft(), r.bottomLeft()); }
|
||||
|
||||
QLine rightSide(const QRect &r) { return QLine(r.topRight(), r.bottomRight()); }
|
||||
}
|
||||
|
||||
void LayerHeaderPanel::paintEvent(QPaintEvent *event) {
|
||||
QPainter p(this);
|
||||
p.setRenderHint(QPainter::SmoothPixmapTransform, true);
|
||||
|
||||
const Orientation *o = Orientations::leftToRight();
|
||||
|
||||
QColor background = m_viewer->getBGColor();
|
||||
QColor slightlyLighter = {mix(background, Qt::white, 0.95)};
|
||||
QRect rect = QRect(QPoint(0, 0), size());
|
||||
p.fillRect(rect.adjusted(0, 0, -3, 0), slightlyLighter);
|
||||
|
||||
drawIcon(p, PredefinedRect::EYE, XsheetGUI::PreviewVisibleColor,
|
||||
ColumnArea::Pixmaps::eye());
|
||||
drawIcon(p, PredefinedRect::PREVIEW_LAYER, boost::none,
|
||||
ColumnArea::Pixmaps::cameraStand());
|
||||
drawIcon(p, PredefinedRect::LOCK, QColor(255, 255, 255, 128),
|
||||
ColumnArea::Pixmaps::lock());
|
||||
|
||||
QRect numberRect = o->rect(PredefinedRect::LAYER_NUMBER);
|
||||
|
||||
int leftadj = 2;
|
||||
if (Preferences::instance()->isShowColumnNumbersEnabled())
|
||||
{
|
||||
p.drawText(numberRect, Qt::AlignCenter | Qt::TextSingleLine, "#");
|
||||
|
||||
leftadj += 20;
|
||||
}
|
||||
|
||||
QRect nameRect = o->rect(PredefinedRect::LAYER_NAME).adjusted(leftadj, 0, -1, 0);
|
||||
p.drawText(nameRect, Qt::AlignLeft | Qt::AlignVCenter | Qt::TextSingleLine,
|
||||
QObject::tr("Layer name"));
|
||||
|
||||
drawLines(p, numberRect, nameRect);
|
||||
}
|
||||
|
||||
void LayerHeaderPanel::drawIcon(QPainter &p, PredefinedRect rect,
|
||||
optional<QColor> fill,
|
||||
const QPixmap &pixmap) const {
|
||||
QRect iconRect = Orientations::leftToRight()->rect(rect).adjusted(-2, 0,-2, 0);
|
||||
|
||||
if (rect == PredefinedRect::LOCK)
|
||||
{
|
||||
p.setPen(Qt::gray);
|
||||
p.setBrush(QColor(255, 255, 255, 128));
|
||||
p.drawRect(iconRect);
|
||||
iconRect.adjust(1, 1, -1, -1);
|
||||
}
|
||||
else
|
||||
if (fill) p.fillRect(iconRect, *fill);
|
||||
p.drawPixmap(iconRect, pixmap);
|
||||
}
|
||||
|
||||
void LayerHeaderPanel::drawLines(QPainter &p, const QRect &numberRect,
|
||||
const QRect &nameRect) const {
|
||||
p.setPen(withAlpha(m_viewer->getTextColor(), 0.5));
|
||||
|
||||
QLine line = {leftSide(shorter(numberRect)).translated(-2, 0)};
|
||||
p.drawLine(line);
|
||||
|
||||
if (Preferences::instance()->isShowColumnNumbersEnabled())
|
||||
{
|
||||
line = rightSide(shorter(numberRect)).translated(-2, 0);
|
||||
p.drawLine(line);
|
||||
}
|
||||
|
||||
line = rightSide(shorter(nameRect));
|
||||
p.drawLine(line);
|
||||
}
|
||||
|
||||
void LayerHeaderPanel::showOrHide(const Orientation *o) {
|
||||
QRect rect = o->rect(PredefinedRect::LAYER_HEADER_PANEL);
|
||||
if (rect.isEmpty())
|
||||
hide();
|
||||
else
|
||||
show();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void LayerHeaderPanel::mousePressEvent(QMouseEvent *event) {
|
||||
const Orientation *o = Orientations::leftToRight();
|
||||
|
||||
m_doOnRelease = 0;
|
||||
|
||||
if (event->button() == Qt::LeftButton) {
|
||||
// get mouse position
|
||||
QPoint pos = event->pos();
|
||||
|
||||
// preview button
|
||||
if (o->rect(PredefinedRect::EYE_AREA).contains(pos)) {
|
||||
m_doOnRelease = ToggleAllPreviewVisible;
|
||||
}
|
||||
// camstand button
|
||||
else if (o->rect(PredefinedRect::PREVIEW_LAYER_AREA).contains(pos)) {
|
||||
m_doOnRelease = ToggleAllTransparency;
|
||||
}
|
||||
// lock button
|
||||
else if (o->rect(PredefinedRect::LOCK_AREA).contains(pos)) {
|
||||
m_doOnRelease = ToggleAllLock;
|
||||
}
|
||||
}
|
||||
|
||||
update();
|
||||
}
|
||||
|
||||
void LayerHeaderPanel::mouseMoveEvent(QMouseEvent *event) {
|
||||
const Orientation *o = Orientations::leftToRight();
|
||||
|
||||
QPoint pos = event->pos();
|
||||
|
||||
// preview button
|
||||
if (o->rect(PredefinedRect::EYE_AREA).contains(pos)) {
|
||||
m_tooltip = tr("Preview Visbility Toggle All");
|
||||
}
|
||||
// camstand button
|
||||
else if (o->rect(PredefinedRect::PREVIEW_LAYER_AREA).contains(pos)) {
|
||||
m_tooltip = tr("Camera Stand Visibility Toggle All");
|
||||
}
|
||||
// lock button
|
||||
else if (o->rect(PredefinedRect::LOCK).contains(pos)) {
|
||||
m_tooltip = tr("Lock Toggle All");
|
||||
}
|
||||
else {
|
||||
m_tooltip = tr("");
|
||||
}
|
||||
|
||||
m_pos = pos;
|
||||
|
||||
update();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
bool LayerHeaderPanel::event(QEvent *event) {
|
||||
if (event->type() == QEvent::ToolTip) {
|
||||
if (!m_tooltip.isEmpty())
|
||||
QToolTip::showText(mapToGlobal(m_pos), m_tooltip);
|
||||
else
|
||||
QToolTip::hideText();
|
||||
}
|
||||
return QWidget::event(event);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void LayerHeaderPanel::mouseReleaseEvent(QMouseEvent *event) {
|
||||
TApp *app = TApp::instance();
|
||||
TXsheet *xsh = m_viewer->getXsheet();
|
||||
int col, totcols = xsh->getColumnCount();
|
||||
bool sound_changed = false;
|
||||
|
||||
if (m_doOnRelease != 0 && totcols > 0)
|
||||
{
|
||||
for (col = 0; col < totcols; col++)
|
||||
{
|
||||
if (!xsh->isColumnEmpty(col)) {
|
||||
TXshColumn *column = xsh->getColumn(col);
|
||||
|
||||
if (m_doOnRelease == ToggleAllPreviewVisible) {
|
||||
column->setPreviewVisible(!column->isPreviewVisible());
|
||||
}
|
||||
else if (m_doOnRelease == ToggleAllTransparency) {
|
||||
column->setCamstandVisible(!column->isCamstandVisible());
|
||||
if (column->getSoundColumn()) sound_changed = true;
|
||||
}
|
||||
else if (m_doOnRelease == ToggleAllLock) {
|
||||
column->lock(!column->isLocked());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (sound_changed) {
|
||||
app->getCurrentXsheet()->notifyXsheetSoundChanged();
|
||||
}
|
||||
|
||||
app->getCurrentScene()->notifySceneChanged();
|
||||
app->getCurrentXsheet()->notifyXsheetChanged();
|
||||
}
|
||||
m_viewer->updateColumnArea();
|
||||
update();
|
||||
m_doOnRelease = 0;
|
||||
}
|
55
toonz/sources/toonz/layerheaderpanel.h
Normal file
55
toonz/sources/toonz/layerheaderpanel.h
Normal file
|
@ -0,0 +1,55 @@
|
|||
#pragma once
|
||||
|
||||
#ifndef LAYER_HEADER_PANEL_INCLUDED
|
||||
#define LAYER_HEADER_PANEL_INCLUDED
|
||||
|
||||
#include <QWidget>
|
||||
#include <boost/optional.hpp>
|
||||
|
||||
#include "orientation.h"
|
||||
|
||||
using boost::optional;
|
||||
|
||||
class XsheetViewer;
|
||||
|
||||
// Panel showing column headers for layers in timeline mode
|
||||
class LayerHeaderPanel final : public QWidget {
|
||||
Q_OBJECT
|
||||
|
||||
enum { ToggleAllTransparency = 1, ToggleAllPreviewVisible, ToggleAllLock };
|
||||
|
||||
int m_doOnRelease;
|
||||
QString m_tooltip;
|
||||
QPoint m_pos;
|
||||
|
||||
private:
|
||||
XsheetViewer *m_viewer;
|
||||
|
||||
public:
|
||||
#if QT_VERSION >= 0x050500
|
||||
LayerHeaderPanel(XsheetViewer *viewer, QWidget *parent = 0,
|
||||
Qt::WindowFlags flags = 0);
|
||||
#else
|
||||
LayerHeaderPanel(XsheetViewer *viewer, QWidget *parent = 0,
|
||||
Qt::WFlags flags = 0);
|
||||
#endif
|
||||
~LayerHeaderPanel();
|
||||
|
||||
void showOrHide(const Orientation *o);
|
||||
|
||||
protected:
|
||||
void paintEvent(QPaintEvent *event) override;
|
||||
|
||||
void mousePressEvent(QMouseEvent *event) override;
|
||||
void mouseMoveEvent(QMouseEvent *event) override;
|
||||
void mouseReleaseEvent(QMouseEvent *event) override;
|
||||
bool event(QEvent *event) override;
|
||||
|
||||
private:
|
||||
void drawIcon(QPainter &p, PredefinedRect rect, optional<QColor> fill,
|
||||
const QPixmap &pixmap) const;
|
||||
void drawLines(QPainter &p, const QRect &numberRect,
|
||||
const QRect &nameRect) const;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -89,7 +89,8 @@ TEnv::IntVar NoShiftToggleAction("NoShiftToggleAction", 0);
|
|||
namespace {
|
||||
//=============================================================================
|
||||
|
||||
const std::string layoutsFileName = "layouts.txt";
|
||||
// layout file name may be overwritten by the argument
|
||||
std::string layoutsFileName = "layouts.txt";
|
||||
const std::string currentRoomFileName = "currentRoom.txt";
|
||||
bool scrambledRooms = false;
|
||||
|
||||
|
@ -108,8 +109,10 @@ bool readRoomList(std::vector<TFilePath> &roomPaths,
|
|||
" not found!");
|
||||
fp = ToonzFolder::getRoomsFile(layoutsFileName);
|
||||
if (!TFileStatus(fp).doesExist()) return false;
|
||||
} else
|
||||
} else {
|
||||
argumentLayoutFileLoaded = true;
|
||||
layoutsFileName = argumentLayoutFileName.toStdString();
|
||||
}
|
||||
} else {
|
||||
fp = ToonzFolder::getRoomsFile(layoutsFileName);
|
||||
if (!TFileStatus(fp).doesExist()) return false;
|
||||
|
@ -255,6 +258,9 @@ void Room::save() {
|
|||
TPanel *pane = static_cast<TPanel *>(layout->itemAt(i)->widget());
|
||||
settings.setValue("name", pane->objectName());
|
||||
settings.setValue("geometry", geometries[i]); // Use passed geometry
|
||||
if (SaveLoadQSettings *persistent =
|
||||
dynamic_cast<SaveLoadQSettings *>(pane->widget()))
|
||||
persistent->save(settings);
|
||||
if (pane->getViewType() != -1)
|
||||
// If panel has different viewtypes, store current one
|
||||
settings.setValue("viewtype", pane->getViewType());
|
||||
|
@ -303,6 +309,9 @@ void Room::load(const TFilePath &fp) {
|
|||
// Allocate panel
|
||||
paneObjectName = name.toString();
|
||||
pane = TPanelFactory::createPanel(this, paneObjectName);
|
||||
if (SaveLoadQSettings *persistent =
|
||||
dynamic_cast<SaveLoadQSettings *>(pane->widget()))
|
||||
persistent->load(settings);
|
||||
}
|
||||
|
||||
if (!pane) {
|
||||
|
|
|
@ -671,7 +671,7 @@ void PreferencesPopup::setChessboardColor2(const TPixel32 &color,
|
|||
//-----------------------------------------------------------------------------
|
||||
|
||||
void PreferencesPopup::onColumnIconChange(const QString &value) {
|
||||
m_pref->setColumnIconLoadingPolicy(value == QString("At Once")
|
||||
m_pref->setColumnIconLoadingPolicy(value == tr("At Once")
|
||||
? Preferences::LoadAtOnce
|
||||
: Preferences::LoadOnDemand);
|
||||
}
|
||||
|
@ -1002,6 +1002,10 @@ void PreferencesPopup::onExpandFunctionHeaderClicked(bool checked) {
|
|||
m_pref->enableExpandFunctionHeader(checked);
|
||||
}
|
||||
|
||||
void PreferencesPopup::onShowColumnNumbersChanged(int index) {
|
||||
m_pref->enableShowColumnNumbers(index == Qt::Checked);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void PreferencesPopup::onUseArrowKeyToShiftCellSelectionClicked(int on) {
|
||||
|
@ -1224,6 +1228,7 @@ PreferencesPopup::PreferencesPopup()
|
|||
tr("Expand Function Editor Header to Match XSheet Toolbar Height "
|
||||
"(Requires Restart)"),
|
||||
this);
|
||||
CheckBox *showColumnNumbersCB = new CheckBox(tr("Show Column Numbers in Column Headers"), this);
|
||||
|
||||
//--- Animation ------------------------------
|
||||
categoryList->addItem(tr("Animation"));
|
||||
|
@ -1492,6 +1497,7 @@ PreferencesPopup::PreferencesPopup()
|
|||
m_pref->isInputCellsWithoutDoubleClickingEnabled());
|
||||
m_showXSheetToolbar->setChecked(m_pref->isShowXSheetToolbarEnabled());
|
||||
m_expandFunctionHeader->setChecked(m_pref->isExpandFunctionHeaderEnabled());
|
||||
showColumnNumbersCB->setChecked(m_pref->isShowColumnNumbersEnabled());
|
||||
|
||||
//--- Animation ------------------------------
|
||||
QStringList list;
|
||||
|
@ -1929,7 +1935,7 @@ PreferencesPopup::PreferencesPopup()
|
|||
QGridLayout *xsheetFrameLay = new QGridLayout();
|
||||
xsheetFrameLay->setMargin(15);
|
||||
xsheetFrameLay->setHorizontalSpacing(15);
|
||||
xsheetFrameLay->setVerticalSpacing(10);
|
||||
xsheetFrameLay->setVerticalSpacing(11);
|
||||
{
|
||||
xsheetFrameLay->addWidget(new QLabel(tr("Next/Previous Step Frames:")), 0,
|
||||
0, Qt::AlignRight | Qt::AlignVCenter);
|
||||
|
@ -1955,7 +1961,8 @@ PreferencesPopup::PreferencesPopup()
|
|||
m_showXSheetToolbar->setLayout(xSheetToolbarLay);
|
||||
|
||||
xsheetFrameLay->addWidget(m_showXSheetToolbar, 7, 0, 3, 3);
|
||||
}
|
||||
xsheetFrameLay->addWidget(showColumnNumbersCB, 10, 0, 1, 2);
|
||||
}
|
||||
xsheetFrameLay->setColumnStretch(0, 0);
|
||||
xsheetFrameLay->setColumnStretch(1, 0);
|
||||
xsheetFrameLay->setColumnStretch(2, 1);
|
||||
|
@ -2305,6 +2312,9 @@ PreferencesPopup::PreferencesPopup()
|
|||
ret = ret && connect(m_expandFunctionHeader, SIGNAL(clicked(bool)),
|
||||
SLOT(onExpandFunctionHeaderClicked(bool)));
|
||||
|
||||
ret = ret && connect(showColumnNumbersCB, SIGNAL(stateChanged(int)),
|
||||
this, SLOT(onShowColumnNumbersChanged(int)));
|
||||
|
||||
//--- Animation ----------------------
|
||||
ret = ret && connect(m_keyframeType, SIGNAL(currentIndexChanged(int)),
|
||||
SLOT(onKeyframeTypeChanged(int)));
|
||||
|
|
|
@ -174,6 +174,7 @@ private slots:
|
|||
void onUseNumpadForSwitchingStylesClicked(bool);
|
||||
void onShowXSheetToolbarClicked(bool);
|
||||
void onExpandFunctionHeaderClicked(bool);
|
||||
void onShowColumnNumbersChanged(int);
|
||||
void onUseArrowKeyToShiftCellSelectionClicked(int);
|
||||
void onInputCellsWithoutDoubleClickingClicked(int);
|
||||
void onWatchFileSystemClicked(int);
|
||||
|
|
|
@ -935,9 +935,9 @@ void SceneViewer::keyPressEvent(QKeyEvent *event) {
|
|||
if (!ret) {
|
||||
TFrameHandle *fh = TApp::instance()->getCurrentFrame();
|
||||
|
||||
if (key == TwConsts::TK_UpArrow)
|
||||
if (key == TwConsts::TK_UpArrow || key == TwConsts::TK_LeftArrow)
|
||||
fh->prevFrame();
|
||||
else if (key == TwConsts::TK_DownArrow)
|
||||
else if (key == TwConsts::TK_DownArrow || key == TwConsts::TK_RightArrow)
|
||||
fh->nextFrame();
|
||||
else if (key == TwConsts::TK_Home)
|
||||
fh->firstFrame();
|
||||
|
|
|
@ -371,9 +371,10 @@ qDebug() << "check: " << srcIndex << ":" <<
|
|||
}
|
||||
|
||||
void LevelMoverTool::onClick(const QMouseEvent *e) {
|
||||
QPoint pos = e->pos();
|
||||
int row = getViewer()->yToRow(pos.y());
|
||||
int col = getViewer()->xToColumn(pos.x());
|
||||
QPoint pos = e->pos();
|
||||
CellPosition cellPosition = getViewer()->xyToPosition(e->pos());
|
||||
int row = cellPosition.frame();
|
||||
int col = cellPosition.layer();
|
||||
|
||||
m_qualifiers = 0;
|
||||
if (Preferences::instance()->getDragCellsBehaviour() == 1)
|
||||
|
@ -509,13 +510,13 @@ void LevelMoverTool::onCellChange(int row, int col) {
|
|||
}
|
||||
|
||||
void LevelMoverTool::onDrag(const QMouseEvent *e) {
|
||||
QPoint pos = e->pos();
|
||||
onCellChange(getViewer()->yToRow(pos.y()), getViewer()->xToColumn(pos.x()));
|
||||
CellPosition cellPosition = getViewer()->xyToPosition(e->pos());
|
||||
onCellChange(cellPosition.frame(), cellPosition.layer());
|
||||
refreshCellsArea();
|
||||
refreshColumnsArea();
|
||||
}
|
||||
|
||||
void LevelMoverTool::onRelease(int row, int col) {
|
||||
void LevelMoverTool::onRelease(const CellPosition &pos) {
|
||||
m_validPos = false;
|
||||
m_range.lx = 0;
|
||||
m_range.ly = 0;
|
||||
|
@ -534,15 +535,13 @@ void LevelMoverTool::drawCellsArea(QPainter &p) {
|
|||
if (rect.x1 < 0 || rect.y1 < 0) return;
|
||||
if (rect.x0 < 0) rect.x0 = 0;
|
||||
if (rect.y0 < 0) rect.y0 = 0;
|
||||
int x0, y0, x1, y1;
|
||||
x0 = getViewer()->columnToX(rect.x0);
|
||||
x1 = getViewer()->columnToX(rect.x1 + 1);
|
||||
y0 = getViewer()->rowToY(rect.y0);
|
||||
y1 = getViewer()->rowToY(rect.y1 + 1);
|
||||
int x = x1 - x0;
|
||||
int y = y1 - y0;
|
||||
|
||||
QRect screen = getViewer()->rangeToXYRect(CellRange(
|
||||
CellPosition(rect.y0, rect.x0), CellPosition(rect.y1 + 1, rect.x1 + 1)));
|
||||
p.setPen((m_aimedPos == m_lastPos && m_validPos) ? QColor(190, 220, 255)
|
||||
: QColor(255, 0, 0));
|
||||
int i;
|
||||
for (i = 0; i < 3; i++) p.drawRect(x0 + i, y0 + i, x - 2 * i, y - 2 * i);
|
||||
for (i = 0; i < 3; i++) // thick border inside cell
|
||||
p.drawRect(QRect(screen.topLeft() + QPoint(i, i),
|
||||
screen.size() - QSize(2 * i, 2 * i)));
|
||||
}
|
||||
|
|
|
@ -89,7 +89,7 @@ private:
|
|||
class LevelMoverTool : public XsheetGUI::DragTool {
|
||||
protected:
|
||||
TPoint m_grabOffset;
|
||||
TPoint m_startPos, m_lastPos, m_aimedPos;
|
||||
TPoint m_startPos, m_lastPos, m_aimedPos; // x=col, y=row coordinates
|
||||
TDimension m_range;
|
||||
|
||||
int m_qualifiers;
|
||||
|
@ -109,7 +109,7 @@ public:
|
|||
void onClick(const QMouseEvent *e) override;
|
||||
void onCellChange(int row, int col);
|
||||
void onDrag(const QMouseEvent *e) override;
|
||||
void onRelease(int row, int col) override;
|
||||
void onRelease(const CellPosition &pos) override;
|
||||
void drawCellsArea(QPainter &p) override;
|
||||
};
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -5,6 +5,7 @@
|
|||
|
||||
#include <QWidget>
|
||||
#include <QLineEdit>
|
||||
#include "orientation.h"
|
||||
|
||||
// forward declaration
|
||||
class XsheetViewer;
|
||||
|
@ -70,11 +71,27 @@ class CellArea final : public QWidget {
|
|||
RenameCellField *m_renameCell;
|
||||
|
||||
void drawCells(QPainter &p, const QRect toBeUpdated);
|
||||
void drawNonEmptyBackground(QPainter &p) const;
|
||||
void drawFoldedColumns(QPainter &p, int layerAxis,
|
||||
const NumberRange &frameAxis) const;
|
||||
void drawSelectionBackground(QPainter &p) const;
|
||||
void drawExtenderHandles(QPainter &p);
|
||||
|
||||
void drawDragHandle(QPainter &p, const QPoint &xy,
|
||||
const QColor &sideColor) const;
|
||||
void drawEndOfDragHandle(QPainter &p, bool isEnd, const QPoint &xy,
|
||||
const QColor &cellColor) const;
|
||||
void drawLockedDottedLine(QPainter &p, bool isLocked, const QPoint &xy,
|
||||
const QColor &cellColor) const;
|
||||
|
||||
void drawLevelCell(QPainter &p, int row, int col, bool isReference = false);
|
||||
void drawSoundTextCell(QPainter &p, int row, int col);
|
||||
void drawSoundCell(QPainter &p, int row, int col);
|
||||
void drawPaletteCell(QPainter &p, int row, int col, bool isReference = false);
|
||||
|
||||
void drawKeyframe(QPainter &p, const QRect toBeUpdated);
|
||||
void drawKeyframeLine(QPainter &p, int col, const NumberRange &rows) const;
|
||||
|
||||
void drawNotes(QPainter &p, const QRect toBeUpdated);
|
||||
|
||||
// Restistusce true
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -6,6 +6,8 @@
|
|||
#include <QWidget>
|
||||
#include <QListWidget>
|
||||
#include <QLineEdit>
|
||||
#include <QPoint>
|
||||
#include <QColor>
|
||||
|
||||
// forward declaration
|
||||
class XsheetViewer;
|
||||
|
@ -14,6 +16,9 @@ class TXsheetHandle;
|
|||
class TStageObjectId;
|
||||
class TXshColumn;
|
||||
class QComboBox;
|
||||
class Orientation;
|
||||
class TApp;
|
||||
class TXsheet;
|
||||
|
||||
//=============================================================================
|
||||
namespace XsheetGUI {
|
||||
|
@ -134,7 +139,7 @@ public:
|
|||
m_xsheetHandle = xsheetHandle;
|
||||
}
|
||||
|
||||
void show(QPoint pos, int col);
|
||||
void show(const QRect &rect, int col);
|
||||
|
||||
protected:
|
||||
void focusOutEvent(QFocusEvent *) override;
|
||||
|
@ -173,11 +178,11 @@ protected slots:
|
|||
void onFilterColorChanged(int id);
|
||||
};
|
||||
|
||||
//! La classe si occupa della visualizzazione dell'area che gestisce le colonne.
|
||||
//! The class in charge of the region showing layer headers
|
||||
class ColumnArea final : public QWidget {
|
||||
Q_OBJECT
|
||||
|
||||
enum { ToggleTransparency = 1, TogglePreviewVisible, ToggleLock };
|
||||
enum { ToggleTransparency = 1, ToggleAllTransparency, TogglePreviewVisible, ToggleAllPreviewVisible, ToggleLock, ToggleAllLock };
|
||||
|
||||
ColumnTransparencyPopup *m_columnTransparencyPopup;
|
||||
QTimer *m_transparencyPopupTimer;
|
||||
|
@ -188,9 +193,6 @@ class ColumnArea final : public QWidget {
|
|||
QRect m_tabBox;
|
||||
QRect m_nameBox;
|
||||
QRect m_linkBox;
|
||||
QRect m_prevViewBox;
|
||||
QRect m_tableViewBox;
|
||||
QRect m_lockBox;
|
||||
|
||||
bool m_isPanning;
|
||||
|
||||
|
@ -214,6 +216,43 @@ class ColumnArea final : public QWidget {
|
|||
void setDragTool(DragTool *dragTool);
|
||||
void startTransparencyPopupTimer(QMouseEvent *e);
|
||||
|
||||
// extracted all variables of drawSomething methods
|
||||
class DrawHeader {
|
||||
ColumnArea *area;
|
||||
QPainter &p;
|
||||
int col;
|
||||
XsheetViewer *m_viewer;
|
||||
const Orientation *o;
|
||||
TApp *app;
|
||||
TXsheet *xsh;
|
||||
bool isEmpty, isCurrent;
|
||||
TXshColumn *column;
|
||||
QPoint orig;
|
||||
|
||||
public:
|
||||
DrawHeader(ColumnArea *area, QPainter &p, int col);
|
||||
|
||||
void prepare() const;
|
||||
|
||||
void levelColors(QColor &columnColor, QColor &dragColor) const;
|
||||
void soundColors(QColor &columnColor, QColor &dragColor) const;
|
||||
void paletteColors(QColor &columnColor, QColor &dragColor) const;
|
||||
|
||||
void drawBaseFill(const QColor &columnColor, const QColor &dragColor) const;
|
||||
void drawEye() const;
|
||||
void drawPreviewToggle(int opacity) const;
|
||||
void drawLock() const;
|
||||
void drawColumnNumber() const;
|
||||
void drawColumnName() const;
|
||||
void drawThumbnail(QPixmap &iconPixmap) const;
|
||||
void drawPegbarName() const;
|
||||
void drawParentHandleName() const;
|
||||
void drawFilterColor() const;
|
||||
|
||||
void drawSoundIcon(bool isPlaying) const;
|
||||
void drawVolumeControl(double volume) const;
|
||||
};
|
||||
|
||||
public:
|
||||
#if QT_VERSION >= 0x050500
|
||||
ColumnArea(XsheetViewer *parent, Qt::WindowFlags flags = 0);
|
||||
|
@ -222,6 +261,10 @@ public:
|
|||
#endif
|
||||
~ColumnArea();
|
||||
|
||||
void onControlPressed(bool pressed);
|
||||
const bool isControlPressed();
|
||||
|
||||
void drawFoldedColumnHead(QPainter &p, int col);
|
||||
void drawLevelColumnHead(QPainter &p, int col);
|
||||
void drawSoundColumnHead(QPainter &p, int col);
|
||||
void drawPaletteColumnHead(QPainter &p, int col);
|
||||
|
@ -229,6 +272,16 @@ public:
|
|||
|
||||
QPixmap getColumnIcon(int columnIndex);
|
||||
|
||||
class Pixmaps {
|
||||
public:
|
||||
static const QPixmap &eye();
|
||||
static const QPixmap &cameraStand();
|
||||
static const QPixmap &cameraStandTransparent();
|
||||
static const QPixmap &lock();
|
||||
static const QPixmap &sound();
|
||||
static const QPixmap &soundPlaying();
|
||||
};
|
||||
|
||||
protected:
|
||||
void select(int columnIndex, QMouseEvent *event);
|
||||
|
||||
|
|
|
@ -86,22 +86,25 @@ void XsheetGUI::DragTool::refreshRowsArea() { getViewer()->updateRows(); }
|
|||
//-----------------------------------------------------------------------------
|
||||
|
||||
void XsheetGUI::DragTool::onClick(const QMouseEvent *event) {
|
||||
QPoint pos = event->pos();
|
||||
onClick(getViewer()->yToRow(pos.y()), getViewer()->xToColumn(pos.x()));
|
||||
QPoint xy = event->pos();
|
||||
CellPosition pos = getViewer()->xyToPosition(xy);
|
||||
onClick(pos);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void XsheetGUI::DragTool::onDrag(const QMouseEvent *event) {
|
||||
QPoint pos = event->pos();
|
||||
onDrag(getViewer()->yToRow(pos.y()), getViewer()->xToColumn(pos.x()));
|
||||
QPoint xy = event->pos();
|
||||
CellPosition pos = getViewer()->xyToPosition(xy);
|
||||
onDrag(pos);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void XsheetGUI::DragTool::onRelease(const QMouseEvent *event) {
|
||||
QPoint pos = event->pos();
|
||||
onRelease(getViewer()->yToRow(pos.y()), getViewer()->xToColumn(pos.x()));
|
||||
QPoint xy = event->pos();
|
||||
CellPosition pos = getViewer()->xyToPosition(xy);
|
||||
onRelease(pos);
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
|
@ -117,11 +120,12 @@ public:
|
|||
: DragTool(viewer), m_firstRow(0), m_firstCol(0), m_modifier() {}
|
||||
// activate when clicked the cell
|
||||
void onClick(const QMouseEvent *event) override {
|
||||
m_modifier = event->modifiers();
|
||||
int row = getViewer()->yToRow(event->pos().y());
|
||||
int col = getViewer()->xToColumn(event->pos().x());
|
||||
m_firstCol = col;
|
||||
m_firstRow = row;
|
||||
m_modifier = event->modifiers();
|
||||
CellPosition pos = getViewer()->xyToPosition(event->pos());
|
||||
int row = pos.frame();
|
||||
int col = pos.layer();
|
||||
m_firstCol = col;
|
||||
m_firstRow = row;
|
||||
if (m_modifier & Qt::ShiftModifier) {
|
||||
int r0, c0, r1, c1;
|
||||
getViewer()->getCellSelection()->getSelectedCells(r0, c0, r1, c1);
|
||||
|
@ -171,7 +175,8 @@ public:
|
|||
refreshCellsArea();
|
||||
refreshRowsArea();
|
||||
}
|
||||
void onDrag(int row, int col) override {
|
||||
void onDrag(const CellPosition &pos) override {
|
||||
int row = pos.frame(), col = pos.layer();
|
||||
if (col < 0) return;
|
||||
if (row < 0) row = 0;
|
||||
if (m_modifier & Qt::ControlModifier)
|
||||
|
@ -626,7 +631,8 @@ public:
|
|||
, m_invert(invert) {}
|
||||
|
||||
// called when the smart tab is clicked
|
||||
void onClick(int row, int col) override {
|
||||
void onClick(const CellPosition &pos) override {
|
||||
int row = pos.frame(), col = pos.layer();
|
||||
int r0, c0, r1, c1;
|
||||
getViewer()->getCellSelection()->getSelectedCells(r0, c0, r1, c1);
|
||||
if (m_invert)
|
||||
|
@ -647,7 +653,8 @@ public:
|
|||
m_undo->setCells(xsh, r0, c0, m_rowCount, m_colCount);
|
||||
}
|
||||
|
||||
void onDrag(int row, int col) override {
|
||||
void onDrag(const CellPosition &pos) override {
|
||||
int row = pos.frame(), col = pos.layer();
|
||||
if (!m_invert)
|
||||
onCellChange(row, col);
|
||||
else
|
||||
|
@ -704,7 +711,7 @@ public:
|
|||
bool found = false;
|
||||
for (int c = 0; c < m_colCount; c++) {
|
||||
TXshColumn *column = xsh->getColumn(m_c0 + c);
|
||||
if (column && column->getSoundColumn()) continue;
|
||||
if (!column || column->getSoundColumn()) continue;
|
||||
if (!column->isCellEmpty(emptyRow)) {
|
||||
emptyRow += 1;
|
||||
found = true;
|
||||
|
@ -725,7 +732,7 @@ public:
|
|||
// clear cells
|
||||
for (int c = 0; c < m_colCount; c++) {
|
||||
TXshColumn *column = xsh->getColumn(m_c0 + c);
|
||||
if (column && column->getSoundColumn()) continue;
|
||||
if (!column || column->getSoundColumn()) continue;
|
||||
xsh->clearCells(m_r0, m_c0 + c, dr);
|
||||
}
|
||||
}
|
||||
|
@ -733,7 +740,7 @@ public:
|
|||
else {
|
||||
for (int c = 0; c < m_colCount; c++) {
|
||||
TXshColumn *column = xsh->getColumn(m_c0 + c);
|
||||
if (column && column->getSoundColumn()) continue;
|
||||
if (!column || column->getSoundColumn()) continue;
|
||||
for (int r = r0; r <= m_r0 - 1; r++) {
|
||||
xsh->setCell(r, m_c0 + c, m_columns[c].generate(r));
|
||||
}
|
||||
|
@ -744,7 +751,8 @@ public:
|
|||
m_c0 + m_colCount - 1);
|
||||
}
|
||||
|
||||
void onRelease(int row, int col) override {
|
||||
void onRelease(const CellPosition &pos) override {
|
||||
int row = pos.frame(), col = pos.layer();
|
||||
int delta = m_r1 - (m_r0 + m_rowCount - 1);
|
||||
if (delta == 0)
|
||||
delete m_undo;
|
||||
|
@ -883,9 +891,9 @@ public:
|
|||
return soundColumn;
|
||||
}
|
||||
|
||||
void onClick(int row, int col) override {
|
||||
m_firstRow = row;
|
||||
m_col = col;
|
||||
void onClick(const CellPosition &pos) override {
|
||||
m_firstRow = pos.frame();
|
||||
m_col = pos.layer();
|
||||
TXshSoundColumn *soundColumn = getColumn();
|
||||
if (!soundColumn) return;
|
||||
m_oldColumn = dynamic_cast<TXshSoundColumn *>(soundColumn->clone());
|
||||
|
@ -893,8 +901,8 @@ public:
|
|||
getViewer()->update();
|
||||
}
|
||||
|
||||
void onDrag(int row, int col) override {
|
||||
onChange(row);
|
||||
void onDrag(const CellPosition &pos) override {
|
||||
onChange(pos.frame());
|
||||
refreshCellsArea();
|
||||
}
|
||||
|
||||
|
@ -922,7 +930,8 @@ public:
|
|||
TApp::instance()->getCurrentXsheet()->notifyXsheetSoundChanged();
|
||||
}
|
||||
|
||||
void onRelease(int row, int col) override {
|
||||
void onRelease(const CellPosition &pos) override {
|
||||
int row = pos.frame();
|
||||
if (row - m_firstRow == 0) {
|
||||
m_undo = 0;
|
||||
return;
|
||||
|
@ -985,10 +994,11 @@ public:
|
|||
LevelMoverTool::onDrag(e);
|
||||
if (m_validPos) m_keyframeMoverTool->onDrag(e);
|
||||
}
|
||||
void onRelease(int row, int col) override {
|
||||
void onRelease(const CellPosition &pos) override {
|
||||
int row = pos.frame(), col = pos.layer();
|
||||
TUndoManager::manager()->beginBlock();
|
||||
LevelMoverTool::onRelease(row, col);
|
||||
m_keyframeMoverTool->onRelease(row, col);
|
||||
LevelMoverTool::onRelease(pos);
|
||||
m_keyframeMoverTool->onRelease(pos);
|
||||
TUndoManager::manager()->endBlock();
|
||||
}
|
||||
|
||||
|
@ -1089,7 +1099,8 @@ public:
|
|||
, m_r1(0)
|
||||
, m_enable(true) {}
|
||||
|
||||
void onClick(int row, int col) override {
|
||||
void onClick(const CellPosition &pos) override {
|
||||
int row = pos.frame(), col = pos.layer();
|
||||
m_r0 = m_r1 = row;
|
||||
TXsheet *xsh = getViewer()->getXsheet();
|
||||
TStageObjectId cameraId = xsh->getStageObjectTree()->getCurrentCameraId();
|
||||
|
@ -1105,7 +1116,8 @@ public:
|
|||
m_undo = new KeyFrameHandleUndo(objId, m_startRow);
|
||||
}
|
||||
|
||||
void onDrag(int row, int col) override {
|
||||
void onDrag(const CellPosition &pos) override {
|
||||
int row = pos.frame(), col = pos.layer();
|
||||
if (!m_enable) return;
|
||||
m_r1 = row;
|
||||
onCellChange(row, col);
|
||||
|
@ -1127,7 +1139,8 @@ public:
|
|||
m_stageObject->setKeyframeWithoutUndo(m_startRow, m_k);
|
||||
}
|
||||
|
||||
void onRelease(int row, int col) override {
|
||||
void onRelease(const CellPosition &pos) override {
|
||||
int row = pos.frame(), col = pos.layer();
|
||||
if (!m_enable) return;
|
||||
if (m_r0 == m_r1)
|
||||
delete m_undo;
|
||||
|
@ -1175,21 +1188,22 @@ public:
|
|||
m_startCol = notes->getNoteCol(currentIndex);
|
||||
QPoint p = e->pos();
|
||||
TPointD mousePos(p.x(), p.y());
|
||||
TPointD cellTopLeft(getViewer()->columnToX(m_startCol),
|
||||
getViewer()->rowToY(m_startRow));
|
||||
QPoint xy = getViewer()->positionToXY(CellPosition(m_startRow, m_startCol));
|
||||
TPointD cellTopLeft(xy.x(), xy.y());
|
||||
m_delta = mousePos - (cellTopLeft + m_startPos);
|
||||
}
|
||||
|
||||
void onChange(TPointD pos) {
|
||||
pos = pos - m_delta;
|
||||
int row = getViewer()->yToRow(pos.y);
|
||||
int col = getViewer()->xToColumn(pos.x);
|
||||
pos = pos - m_delta;
|
||||
CellPosition cellPosition = getViewer()->xyToPosition(pos);
|
||||
int row = cellPosition.frame();
|
||||
int col = cellPosition.layer();
|
||||
|
||||
if (row < 0) row = 0;
|
||||
if (col < 0) col = 0;
|
||||
|
||||
TPointD newPos =
|
||||
pos - TPointD(getViewer()->columnToX(col), getViewer()->rowToY(row));
|
||||
QPoint xy = getViewer()->positionToXY(CellPosition(row, col));
|
||||
TPointD newPos = pos - TPointD(xy.x(), xy.y());
|
||||
|
||||
if (newPos.x < 0) newPos.x = 0;
|
||||
if (newPos.y < 0) newPos.y = 0;
|
||||
|
@ -1252,14 +1266,16 @@ public:
|
|||
TApp::instance()->getCurrentFrame()->getFrame())
|
||||
, m_isFos(isFos) {}
|
||||
|
||||
void onClick(int row, int col) override {
|
||||
void onClick(const CellPosition &pos) override {
|
||||
int row = pos.frame();
|
||||
OnionSkinMask mask = m_modifier.getMask();
|
||||
TApp::instance()->getCurrentOnionSkin()->setOnionSkinMask(mask);
|
||||
m_modifier.click(row, m_isFos);
|
||||
TApp::instance()->getCurrentOnionSkin()->notifyOnionSkinMaskChanged();
|
||||
}
|
||||
|
||||
void onDrag(int row, int col) override {
|
||||
void onDrag(const CellPosition &pos) override {
|
||||
int row = pos.frame();
|
||||
if (row < 0) row = 0;
|
||||
onRowChange(row);
|
||||
TApp::instance()->getCurrentOnionSkin()->notifyOnionSkinMaskChanged();
|
||||
|
@ -1271,7 +1287,8 @@ public:
|
|||
TApp::instance()->getCurrentOnionSkin()->setOnionSkinMask(mask);
|
||||
}
|
||||
|
||||
void onRelease(int row, int col) override {
|
||||
void onRelease(const CellPosition &pos) override {
|
||||
int row = pos.frame();
|
||||
m_modifier.release(row);
|
||||
OnionSkinMask mask = m_modifier.getMask();
|
||||
TApp::instance()->getCurrentOnionSkin()->setOnionSkinMask(mask);
|
||||
|
@ -1302,12 +1319,14 @@ class CurrentFrameModifier final : public XsheetGUI::DragTool {
|
|||
public:
|
||||
CurrentFrameModifier(XsheetViewer *viewer) : DragTool(viewer) {}
|
||||
|
||||
void onClick(int row, int col) override {
|
||||
void onClick(const CellPosition &pos) override {
|
||||
int row = pos.frame();
|
||||
TApp::instance()->getCurrentFrame()->setFrame(row);
|
||||
refreshRowsArea();
|
||||
}
|
||||
|
||||
void onDrag(int row, int col) override {
|
||||
void onDrag(const CellPosition &pos) override {
|
||||
int row = pos.frame();
|
||||
if (row < 0) row = 0;
|
||||
int lastRow = TApp::instance()->getCurrentFrame()->getFrameIndex();
|
||||
if (lastRow == row) return;
|
||||
|
@ -1322,7 +1341,7 @@ public:
|
|||
app->getCurrentFrame()->scrubXsheet(row, row, getViewer()->getXsheet());
|
||||
}
|
||||
|
||||
void onRelease(int row, int col) override {
|
||||
void onRelease(const CellPosition &pos) override {
|
||||
getViewer()->getXsheet()->stopScrub();
|
||||
}
|
||||
};
|
||||
|
@ -1354,14 +1373,16 @@ public:
|
|||
PlayRangeModifier(XsheetViewer *viewer)
|
||||
: DragTool(viewer), m_movingFirst(false) {}
|
||||
|
||||
void onClick(int row, int col) override {
|
||||
void onClick(const CellPosition &pos) override {
|
||||
int row = pos.frame();
|
||||
XsheetGUI::getPlayRange(m_oldR0, m_oldR1, m_oldStep);
|
||||
assert(m_oldR0 == row || m_oldR1 == row);
|
||||
m_movingFirst = m_oldR0 == row;
|
||||
refreshRowsArea();
|
||||
}
|
||||
|
||||
void onDrag(int row, int col) override {
|
||||
void onDrag(const CellPosition &pos) override {
|
||||
int row = pos.frame();
|
||||
if (row < 0) row = 0;
|
||||
onRowChange(row);
|
||||
refreshRowsArea();
|
||||
|
@ -1391,7 +1412,8 @@ public:
|
|||
XsheetGUI::setPlayRange(r0, r1, step, false);
|
||||
}
|
||||
|
||||
void onRelease(int row, int col) override {
|
||||
void onRelease(const CellPosition &pos) override {
|
||||
int row = pos.frame();
|
||||
int newR0, newR1, newStep;
|
||||
XsheetGUI::getPlayRange(newR0, newR1, newStep);
|
||||
if (m_oldR0 != newR0 || m_oldR1 != newR1) {
|
||||
|
@ -1428,7 +1450,8 @@ public:
|
|||
|
||||
void onClick(const QMouseEvent *event) override {
|
||||
TColumnSelection *selection = getViewer()->getColumnSelection();
|
||||
int col = getViewer()->xToColumn(event->pos().x());
|
||||
CellPosition cellPosition = getViewer()->xyToPosition(event->pos());
|
||||
int col = cellPosition.layer();
|
||||
m_firstColumn = col;
|
||||
bool isSelected = selection->isColumnSelected(col);
|
||||
if (event->modifiers() & Qt::ControlModifier) {
|
||||
|
@ -1453,7 +1476,8 @@ public:
|
|||
getViewer()->update();
|
||||
}
|
||||
|
||||
void onDrag(int row, int col) override {
|
||||
void onDrag(const CellPosition &pos) override {
|
||||
int col = pos.layer();
|
||||
if (!m_enabled) return;
|
||||
if (col < 0) return;
|
||||
TColumnSelection *selection = getViewer()->getColumnSelection();
|
||||
|
@ -1465,7 +1489,7 @@ public:
|
|||
refreshCellsArea();
|
||||
return;
|
||||
}
|
||||
void onRelease(int row, int col) override {
|
||||
void onRelease(const CellPosition &pos) override {
|
||||
TSelectionHandle::getCurrent()->notifySelectionChanged();
|
||||
}
|
||||
};
|
||||
|
@ -1559,7 +1583,8 @@ public:
|
|||
, m_lastCol(-1)
|
||||
, m_offset(0) {}
|
||||
|
||||
void onClick(int row, int col) override {
|
||||
void onClick(const CellPosition &pos) override {
|
||||
int col = pos.layer();
|
||||
TColumnSelection *selection = getViewer()->getColumnSelection();
|
||||
if (!selection->isColumnSelected(col)) {
|
||||
selection->selectNone();
|
||||
|
@ -1574,7 +1599,8 @@ public:
|
|||
assert(m_lastCol == *indices.begin());
|
||||
getViewer()->update();
|
||||
}
|
||||
void onDrag(int row, int col) override {
|
||||
void onDrag(const CellPosition &pos) override {
|
||||
int col = pos.layer();
|
||||
TColumnSelection *selection = getViewer()->getColumnSelection();
|
||||
std::set<int> indices = selection->getIndices();
|
||||
if (indices.empty()) return;
|
||||
|
@ -1595,7 +1621,7 @@ public:
|
|||
++it)
|
||||
selection->selectColumn(*it + dCol, true);
|
||||
}
|
||||
void onRelease(int row, int col) override {
|
||||
void onRelease(const CellPosition &pos) override {
|
||||
int delta = m_lastCol - m_firstCol;
|
||||
if (delta == 0) return;
|
||||
TColumnSelection *selection = getViewer()->getColumnSelection();
|
||||
|
@ -1657,9 +1683,11 @@ public:
|
|||
ChangePegbarParentDragTool(XsheetViewer *viewer)
|
||||
: XsheetGUI::DragTool(viewer), m_firstCol(-1), m_lastCol(-1) {}
|
||||
|
||||
void onClick(int row, int col) override { m_firstCol = m_lastCol = col; }
|
||||
void onDrag(int row, int col) override { m_lastCol = col; }
|
||||
void onRelease(int row, int col) override {
|
||||
void onClick(const CellPosition &pos) override {
|
||||
m_firstCol = m_lastCol = pos.layer();
|
||||
}
|
||||
void onDrag(const CellPosition &pos) override { m_lastCol = pos.layer(); }
|
||||
void onRelease(const CellPosition &pos) override {
|
||||
// TUndoManager::manager()->add(new ColumnMoveUndo(indices, delta));
|
||||
TXsheet *xsh = TApp::instance()->getCurrentXsheet()->getXsheet();
|
||||
TStageObjectId columnId(getViewer()->getObjectId(m_firstCol));
|
||||
|
@ -1732,9 +1760,14 @@ public:
|
|||
|
||||
void onDrag(const QMouseEvent *event) override {
|
||||
if (!m_enabled) return;
|
||||
double v =
|
||||
(double)(60 - (event->pos().y() - (XsheetGUI::RowHeight * 2 + 4))) /
|
||||
60.0;
|
||||
|
||||
const Orientation *o = getViewer()->orientation();
|
||||
QRect track = o->rect(PredefinedRect::VOLUME_TRACK);
|
||||
NumberRange range = o->frameSide(track);
|
||||
int frameAxis = o->frameAxis(event->pos());
|
||||
double v = range.ratio(frameAxis);
|
||||
if (o->flipVolume()) v = 1 - v;
|
||||
|
||||
TXsheet *xsh = getViewer()->getXsheet();
|
||||
TXshColumn *column = xsh->getColumn(m_index);
|
||||
if (!column) return;
|
||||
|
@ -1782,7 +1815,8 @@ public:
|
|||
, m_oldRow(0)
|
||||
, m_timerId(0) {}
|
||||
|
||||
void onClick(int row, int col) override {
|
||||
void onClick(const CellPosition &pos) override {
|
||||
int row = pos.frame(), col = pos.layer();
|
||||
TColumnSelection *selection = getViewer()->getColumnSelection();
|
||||
selection->selectNone();
|
||||
m_startRow = row;
|
||||
|
@ -1790,7 +1824,10 @@ public:
|
|||
getViewer()->updateCells();
|
||||
}
|
||||
|
||||
void onDrag(int row, int col) override { onCellChange(row, col); }
|
||||
void onDrag(const CellPosition &pos) override {
|
||||
int row = pos.frame(), col = pos.layer();
|
||||
onCellChange(row, col);
|
||||
}
|
||||
|
||||
void onCellChange(int row, int col) {
|
||||
assert(m_startRow >= 0);
|
||||
|
@ -1798,9 +1835,9 @@ public:
|
|||
getViewer()->updateCells();
|
||||
}
|
||||
|
||||
void onRelease(int row, int col) override {
|
||||
int r0 = std::min(row, m_startRow);
|
||||
int r1 = std::max(row, m_startRow);
|
||||
void onRelease(const CellPosition &pos) override {
|
||||
int r0 = std::min(pos.frame(), m_startRow);
|
||||
int r1 = std::max(pos.frame(), m_startRow);
|
||||
assert(m_soundColumn);
|
||||
TApp *app = TApp::instance();
|
||||
ToonzScene *scene = app->getCurrentScene()->getScene();
|
||||
|
@ -1870,7 +1907,7 @@ enum CellMovementType { NO_MOVEMENT, INSERT_CELLS, OVERWRITE_CELLS };
|
|||
class DataDragTool final : public XsheetGUI::DragTool {
|
||||
DragAndDropData *m_data;
|
||||
bool m_valid;
|
||||
TPoint m_curPos;
|
||||
TPoint m_curPos; // screen xy of drag begin
|
||||
CellMovementType m_type;
|
||||
|
||||
protected:
|
||||
|
@ -1928,8 +1965,9 @@ public:
|
|||
}
|
||||
void onDrag(const QDropEvent *e) override {
|
||||
TPoint pos(e->pos().x(), e->pos().y());
|
||||
int row = getViewer()->yToRow(pos.y);
|
||||
int col = getViewer()->xToColumn(pos.x);
|
||||
CellPosition cellPosition = getViewer()->xyToPosition(e->pos());
|
||||
int row = cellPosition.frame();
|
||||
int col = cellPosition.layer();
|
||||
|
||||
m_valid = true;
|
||||
if (e->keyboardModifiers() & Qt::ShiftModifier)
|
||||
|
@ -1943,8 +1981,9 @@ public:
|
|||
}
|
||||
void onRelease(const QDropEvent *e) override {
|
||||
TPoint pos(e->pos().x(), e->pos().y());
|
||||
int row = getViewer()->yToRow(pos.y);
|
||||
int col = getViewer()->xToColumn(pos.x);
|
||||
CellPosition cellPosition = getViewer()->xyToPosition(e->pos());
|
||||
int row = cellPosition.frame();
|
||||
int col = cellPosition.layer();
|
||||
if (m_type != NO_MOVEMENT && !m_valid) return;
|
||||
|
||||
bool insert = m_type == INSERT_CELLS;
|
||||
|
@ -1973,24 +2012,23 @@ public:
|
|||
refreshCellsArea();
|
||||
}
|
||||
void drawCellsArea(QPainter &p) override {
|
||||
TPoint pos(getViewer()->xToColumn(m_curPos.x),
|
||||
getViewer()->yToRow(m_curPos.y));
|
||||
TRect rect = m_data->getLevelFrameRect();
|
||||
CellPosition beginDragPosition = getViewer()->xyToPosition(m_curPos);
|
||||
TPoint pos(beginDragPosition.layer(),
|
||||
beginDragPosition.frame()); // row and cell coordinates
|
||||
TRect rect = m_data->getLevelFrameRect(); // row and cell coordinates
|
||||
if (rect.isEmpty()) return;
|
||||
rect += pos;
|
||||
if (rect.x1 < 0 || rect.y1 < 0) return;
|
||||
if (rect.x0 < 0) rect.x0 = 0;
|
||||
if (rect.y0 < 0) rect.y0 = 0;
|
||||
int x0, y0, x1, y1;
|
||||
x0 = getViewer()->columnToX(rect.x0);
|
||||
x1 = getViewer()->columnToX(rect.x1 + 1);
|
||||
y0 = getViewer()->rowToY(rect.y0);
|
||||
y1 = getViewer()->rowToY(rect.y1 + 1);
|
||||
int x = x1 - x0;
|
||||
int y = y1 - y0;
|
||||
QRect screenCell = getViewer()->rangeToXYRect(
|
||||
CellRange(CellPosition(rect.y0, rect.x0),
|
||||
CellPosition(rect.y1 + 1, rect.x1 + 1)));
|
||||
p.setPen(m_valid ? QColor(190, 220, 255) : QColor(255, 0, 0));
|
||||
int i;
|
||||
for (i = 0; i < 3; i++) p.drawRect(x0 + i, y0 + i, x - 2 * i, y - 2 * i);
|
||||
for (i = 0; i < 3; i++) // thick border within cell
|
||||
p.drawRect(QRect(screenCell.topLeft() + QPoint(i, i),
|
||||
screenCell.size() - QSize(2 * i, 2 * i)));
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#define XSHEET_DRAG_TOOL_H
|
||||
|
||||
#include "tgeometry.h"
|
||||
#include "cellposition.h"
|
||||
|
||||
// forward declaration
|
||||
class QPainter;
|
||||
|
@ -28,9 +29,9 @@ public:
|
|||
void refreshRowsArea();
|
||||
void refreshColumnsArea();
|
||||
|
||||
virtual void onClick(int row, int col) {}
|
||||
virtual void onDrag(int row, int col) {}
|
||||
virtual void onRelease(int row, int col) {}
|
||||
virtual void onClick(const CellPosition &pos) {}
|
||||
virtual void onDrag(const CellPosition &pos) {}
|
||||
virtual void onRelease(const CellPosition &pos) {}
|
||||
|
||||
virtual void onClick(const QMouseEvent *event);
|
||||
virtual void onDrag(const QMouseEvent *event);
|
||||
|
|
|
@ -48,8 +48,10 @@ TEnv::IntVar FrameDisplayStyleInXsheetRowArea(
|
|||
namespace XsheetGUI {
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
const int ColumnWidth = 74;
|
||||
const int RowHeight = 20;
|
||||
const int ColumnWidth = 74;
|
||||
const int RowHeight = 20;
|
||||
const int SCROLLBAR_WIDTH = 16;
|
||||
const int TOOLBAR_HEIGHT = 30;
|
||||
|
||||
} // namespace XsheetGUI
|
||||
|
||||
|
@ -139,14 +141,6 @@ XsheetViewer::XsheetViewer(QWidget *parent, Qt::WindowFlags flags)
|
|||
XsheetViewer::XsheetViewer(QWidget *parent, Qt::WFlags flags)
|
||||
#endif
|
||||
: QFrame(parent)
|
||||
, m_x0(XsheetGUI::ColumnWidth + 1)
|
||||
#ifndef LINETEST
|
||||
, m_y0(XsheetGUI::RowHeight * 3 +
|
||||
60) // Per tab il numero delle righe era 8 perche c'e' il linkBox
|
||||
#else
|
||||
, m_y0(XsheetGUI::RowHeight * 8 +
|
||||
5) // Per tab il numero delle righe era 8 perche c'e' il linkBox
|
||||
#endif
|
||||
, m_timerId(0)
|
||||
, m_autoPanSpeed(0, 0)
|
||||
, m_dragTool(0)
|
||||
|
@ -161,28 +155,31 @@ XsheetViewer::XsheetViewer(QWidget *parent, Qt::WFlags flags)
|
|||
, m_isComputingSize(false)
|
||||
, m_currentNoteIndex(0)
|
||||
, m_qtModifiers(0)
|
||||
, m_toolbarHeight(30)
|
||||
, m_frameDisplayStyle(to_enum(FrameDisplayStyleInXsheetRowArea)) {
|
||||
, m_frameDisplayStyle(to_enum(FrameDisplayStyleInXsheetRowArea))
|
||||
, m_orientation(nullptr) {
|
||||
|
||||
setFocusPolicy(Qt::StrongFocus);
|
||||
|
||||
setFrameStyle(QFrame::StyledPanel);
|
||||
setObjectName("XsheetViewer");
|
||||
|
||||
m_orientation = Orientations::topToBottom();
|
||||
|
||||
m_cellKeyframeSelection->setXsheetHandle(
|
||||
TApp::instance()->getCurrentXsheet());
|
||||
|
||||
|
||||
m_toolbarScrollArea = new XsheetScrollArea(this);
|
||||
m_toolbarScrollArea->setFixedSize(m_x0 * 12, m_toolbarHeight);
|
||||
m_toolbarScrollArea->setFixedSize(m_orientation->cellWidth() * 12, XsheetGUI::TOOLBAR_HEIGHT);
|
||||
m_toolbarScrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
||||
m_toolbarScrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
||||
m_toolbar = new XsheetGUI::Toolbar(this);
|
||||
m_toolbar->setFixedSize(m_x0 * 12, m_toolbarHeight);
|
||||
m_toolbar->setFixedSize(m_orientation->cellWidth() * 12, XsheetGUI::TOOLBAR_HEIGHT);
|
||||
m_toolbarScrollArea->setWidget(m_toolbar);
|
||||
|
||||
m_noteArea = new XsheetGUI::NoteArea(this);
|
||||
m_noteArea->setFixedSize(m_x0 + 1, m_y0 - 3);
|
||||
QRect noteArea(0, 0, 75, 120);
|
||||
m_noteArea = new XsheetGUI::NoteArea(this);
|
||||
m_noteScrollArea = new XsheetScrollArea(this);
|
||||
m_noteScrollArea->setFixedSize(m_x0 + 1, m_y0 - 3);
|
||||
m_noteScrollArea->setObjectName("xsheetArea");
|
||||
m_noteScrollArea->setWidget(m_noteArea);
|
||||
m_noteScrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
||||
m_noteScrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
||||
|
@ -193,8 +190,6 @@ XsheetViewer::XsheetViewer(QWidget *parent, Qt::WFlags flags)
|
|||
m_cellScrollArea->setWidget(m_cellArea);
|
||||
m_cellScrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
|
||||
m_cellScrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
|
||||
// m_cellScrollArea->horizontalScrollBar()->setObjectName("XsheetScrollBar");
|
||||
// m_cellScrollArea->verticalScrollBar()->setObjectName("XsheetScrollBar");
|
||||
|
||||
m_columnArea = new XsheetGUI::ColumnArea(this);
|
||||
m_columnScrollArea = new XsheetScrollArea(this);
|
||||
|
@ -210,19 +205,16 @@ XsheetViewer::XsheetViewer(QWidget *parent, Qt::WFlags flags)
|
|||
m_rowScrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
||||
m_rowScrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
||||
|
||||
connect(m_rowScrollArea->verticalScrollBar(), SIGNAL(valueChanged(int)),
|
||||
m_cellScrollArea->verticalScrollBar(), SLOT(setValue(int)));
|
||||
connect(m_cellScrollArea->verticalScrollBar(), SIGNAL(valueChanged(int)),
|
||||
m_rowScrollArea->verticalScrollBar(), SLOT(setValue(int)));
|
||||
connect(m_columnScrollArea->horizontalScrollBar(), SIGNAL(valueChanged(int)),
|
||||
m_cellScrollArea->horizontalScrollBar(), SLOT(setValue(int)));
|
||||
connect(m_cellScrollArea->horizontalScrollBar(), SIGNAL(valueChanged(int)),
|
||||
m_columnScrollArea->horizontalScrollBar(), SLOT(setValue(int)));
|
||||
m_frameScroller.setFrameScrollArea(m_cellScrollArea);
|
||||
connect(&m_frameScroller, &Spreadsheet::FrameScroller::prepareToScrollOffset,
|
||||
this, &XsheetViewer::onPrepareToScrollOffset);
|
||||
|
||||
connect(m_cellScrollArea->verticalScrollBar(), SIGNAL(valueChanged(int)),
|
||||
SLOT(updateCellRowAree()));
|
||||
connect(m_cellScrollArea->horizontalScrollBar(), SIGNAL(valueChanged(int)),
|
||||
SLOT(updateCellColumnAree()));
|
||||
connectScrollBars();
|
||||
|
||||
connect(this, &XsheetViewer::orientationChanged, this,
|
||||
&XsheetViewer::onOrientationChanged);
|
||||
|
||||
emit orientationChanged(orientation());
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -284,6 +276,115 @@ void XsheetViewer::dragToolLeave(QEvent *e) {
|
|||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
const Orientation *XsheetViewer::orientation() const {
|
||||
if (!m_orientation) throw std::runtime_error("!m_orientation");
|
||||
return m_orientation;
|
||||
}
|
||||
|
||||
void XsheetViewer::flipOrientation() {
|
||||
m_orientation = orientation()->next();
|
||||
emit orientationChanged(orientation());
|
||||
}
|
||||
|
||||
void XsheetViewer::onOrientationChanged(const Orientation *newOrientation) {
|
||||
disconnectScrollBars();
|
||||
|
||||
positionSections();
|
||||
m_frameScroller.setOrientation(newOrientation);
|
||||
refreshContentSize(0, 0);
|
||||
|
||||
connectScrollBars();
|
||||
|
||||
update();
|
||||
}
|
||||
|
||||
void XsheetViewer::positionSections() {
|
||||
const Orientation *o = orientation();
|
||||
QRect size = QRect(QPoint(0, 0), geometry().size());
|
||||
NumberRange allLayer = o->layerSide(size);
|
||||
NumberRange allFrame = o->frameSide(size);
|
||||
|
||||
NumberRange headerLayer = o->range(PredefinedRange::HEADER_LAYER);
|
||||
NumberRange headerFrame = o->range(PredefinedRange::HEADER_FRAME);
|
||||
NumberRange bodyLayer(headerLayer.to(), allLayer.to());
|
||||
NumberRange bodyFrame(headerFrame.to(), allFrame.to());
|
||||
|
||||
if (Preferences::instance()->isShowXSheetToolbarEnabled()) {
|
||||
m_toolbar->showToolbar(true);
|
||||
|
||||
int w = geometry().size().width();
|
||||
m_toolbarScrollArea->setGeometry(0, 0, w, XsheetGUI::TOOLBAR_HEIGHT);
|
||||
|
||||
if (o->isVerticalTimeline()) {
|
||||
headerFrame = headerFrame.adjusted(XsheetGUI::TOOLBAR_HEIGHT, XsheetGUI::TOOLBAR_HEIGHT);
|
||||
bodyFrame = bodyFrame.adjusted(XsheetGUI::TOOLBAR_HEIGHT, 0);
|
||||
}
|
||||
else {
|
||||
headerLayer = headerLayer.adjusted(XsheetGUI::TOOLBAR_HEIGHT, XsheetGUI::TOOLBAR_HEIGHT);
|
||||
bodyLayer = bodyLayer.adjusted(XsheetGUI::TOOLBAR_HEIGHT, 0);
|
||||
}
|
||||
}
|
||||
else {
|
||||
m_toolbar->showToolbar(false);
|
||||
}
|
||||
|
||||
m_noteScrollArea->setGeometry(o->frameLayerRect(headerFrame, headerLayer));
|
||||
m_cellScrollArea->setGeometry(o->frameLayerRect(bodyFrame, bodyLayer));
|
||||
m_columnScrollArea->setGeometry(o->frameLayerRect(
|
||||
headerFrame.adjusted(-1,-1), bodyLayer.adjusted(0, -XsheetGUI::SCROLLBAR_WIDTH)));
|
||||
m_rowScrollArea->setGeometry(o->frameLayerRect(
|
||||
bodyFrame.adjusted(0, -XsheetGUI::SCROLLBAR_WIDTH), headerLayer));
|
||||
}
|
||||
|
||||
void XsheetViewer::disconnectScrollBars() {
|
||||
connectOrDisconnectScrollBars(false);
|
||||
}
|
||||
void XsheetViewer::connectScrollBars() { connectOrDisconnectScrollBars(true); }
|
||||
|
||||
void XsheetViewer::connectOrDisconnectScrollBars(bool toConnect) {
|
||||
const Orientation *o = orientation();
|
||||
bool isVertical = o->isVerticalTimeline();
|
||||
QWidget *scrolledVertically =
|
||||
(isVertical ? m_rowScrollArea : m_columnScrollArea)->verticalScrollBar();
|
||||
QWidget *scrolledHorizontally =
|
||||
(isVertical ? m_columnScrollArea : m_rowScrollArea)
|
||||
->horizontalScrollBar();
|
||||
|
||||
connectOrDisconnect(toConnect, scrolledVertically, SIGNAL(valueChanged(int)),
|
||||
m_cellScrollArea->verticalScrollBar(),
|
||||
SLOT(setValue(int)));
|
||||
connectOrDisconnect(toConnect, m_cellScrollArea->verticalScrollBar(),
|
||||
SIGNAL(valueChanged(int)), scrolledVertically,
|
||||
SLOT(setValue(int)));
|
||||
|
||||
connectOrDisconnect(
|
||||
toConnect, scrolledHorizontally, SIGNAL(valueChanged(int)),
|
||||
m_cellScrollArea->horizontalScrollBar(), SLOT(setValue(int)));
|
||||
connectOrDisconnect(toConnect, m_cellScrollArea->horizontalScrollBar(),
|
||||
SIGNAL(valueChanged(int)), scrolledHorizontally,
|
||||
SLOT(setValue(int)));
|
||||
|
||||
connectOrDisconnect(
|
||||
toConnect, m_cellScrollArea->verticalScrollBar(),
|
||||
SIGNAL(valueChanged(int)), this,
|
||||
isVertical ? SLOT(updateCellRowAree()) : SLOT(updateCellColumnAree()));
|
||||
connectOrDisconnect(
|
||||
toConnect, m_cellScrollArea->horizontalScrollBar(),
|
||||
SIGNAL(valueChanged(int)), this,
|
||||
isVertical ? SLOT(updateCellColumnAree()) : SLOT(updateCellRowAree()));
|
||||
}
|
||||
|
||||
void XsheetViewer::connectOrDisconnect(bool toConnect, QWidget *sender,
|
||||
const char *signal, QWidget *receiver,
|
||||
const char *slot) {
|
||||
if (toConnect)
|
||||
connect(sender, signal, receiver, slot);
|
||||
else
|
||||
disconnect(sender, signal, receiver, slot);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
TXsheet *XsheetViewer::getXsheet() const {
|
||||
return TApp::instance()->getCurrentXsheet()->getXsheet();
|
||||
}
|
||||
|
@ -361,8 +462,7 @@ frameHandle->setFrame(row);*/
|
|||
void XsheetViewer::scroll(QPoint delta) {
|
||||
int x = delta.x();
|
||||
int y = delta.y();
|
||||
prepareToScroll(y);
|
||||
|
||||
|
||||
int valueH = m_cellScrollArea->horizontalScrollBar()->value() + x;
|
||||
int valueV = m_cellScrollArea->verticalScrollBar()->value() + y;
|
||||
int maxValueH = m_cellScrollArea->horizontalScrollBar()->maximum();
|
||||
|
@ -391,7 +491,9 @@ void XsheetViewer::scroll(QPoint delta) {
|
|||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void XsheetViewer::onPrepareToScroll(int dy) { refreshContentSize(0, dy); }
|
||||
void XsheetViewer::onPrepareToScrollOffset(const QPoint &offset) {
|
||||
refreshContentSize(offset.x(), offset.y());
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
@ -445,18 +547,20 @@ void XsheetViewer::timerEvent(QTimerEvent *) {
|
|||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
// adjust sizes after scrolling event
|
||||
bool XsheetViewer::refreshContentSize(int dx, int dy) {
|
||||
QSize viewportSize = m_cellScrollArea->viewport()->size();
|
||||
QPoint offset = m_cellArea->pos();
|
||||
offset = QPoint(qMin(0, offset.x() - dx), qMin(0, offset.y() - dy));
|
||||
offset = QPoint(qMin(0, offset.x() - dx), qMin(0, offset.y() - dy)); // what?
|
||||
|
||||
TXsheet *xsh = getXsheet();
|
||||
int frameCount = xsh ? xsh->getFrameCount() : 0;
|
||||
int columnCount = xsh ? xsh->getColumnCount() : 0;
|
||||
QSize contentSize(columnToX(columnCount + 1), rowToY(frameCount + 1));
|
||||
QPoint contentSize =
|
||||
positionToXY(CellPosition(frameCount + 1, columnCount + 1));
|
||||
|
||||
QSize actualSize(contentSize);
|
||||
int x = viewportSize.width() - offset.x();
|
||||
QSize actualSize(contentSize.x(), contentSize.y());
|
||||
int x = viewportSize.width() - offset.x(); // wtf is going on
|
||||
int y = viewportSize.height() - offset.y();
|
||||
if (x > actualSize.width()) actualSize.setWidth(x);
|
||||
if (y > actualSize.height()) actualSize.setHeight(y);
|
||||
|
@ -464,10 +568,17 @@ bool XsheetViewer::refreshContentSize(int dx, int dy) {
|
|||
if (actualSize == m_cellArea->size())
|
||||
return false;
|
||||
else {
|
||||
const Orientation *o = orientation();
|
||||
NumberRange allLayer = o->layerSide(QRect(QPoint(0, 0), actualSize));
|
||||
NumberRange allFrame = o->frameSide(QRect(QPoint(0, 0), actualSize));
|
||||
NumberRange headerLayer = o->range(PredefinedRange::HEADER_LAYER);
|
||||
NumberRange headerFrame = o->range(PredefinedRange::HEADER_FRAME);
|
||||
|
||||
m_isComputingSize = true;
|
||||
m_noteArea->setFixedSize(o->rect(PredefinedRect::NOTE_AREA).size());
|
||||
m_cellArea->setFixedSize(actualSize);
|
||||
m_rowArea->setFixedSize(m_x0, actualSize.height());
|
||||
m_columnArea->setFixedSize(actualSize.width(), m_y0);
|
||||
m_rowArea->setFixedSize(o->frameLayerRect(allFrame, headerLayer).size());
|
||||
m_columnArea->setFixedSize(o->frameLayerRect(headerFrame, allLayer).size());
|
||||
m_isComputingSize = false;
|
||||
return true;
|
||||
}
|
||||
|
@ -475,43 +586,92 @@ bool XsheetViewer::refreshContentSize(int dx, int dy) {
|
|||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
// call when in doubt
|
||||
void XsheetViewer::updateAreeSize() {
|
||||
int w = m_cellScrollArea->width() - 15;
|
||||
int h = m_cellScrollArea->height() - 15;
|
||||
const Orientation *o = orientation();
|
||||
QRect viewArea(QPoint(0, 0), m_cellScrollArea->geometry()
|
||||
.adjusted(0, 0, -XsheetGUI::SCROLLBAR_WIDTH,
|
||||
-XsheetGUI::SCROLLBAR_WIDTH)
|
||||
.size());
|
||||
|
||||
TXsheet *xsh = getXsheet();
|
||||
int frameCount = xsh ? xsh->getFrameCount() : 0;
|
||||
int hCounted = (XsheetGUI::RowHeight) * (frameCount + 1);
|
||||
if (h < hCounted) h = hCounted;
|
||||
QPoint areaFilled(0, 0);
|
||||
TXsheet *xsh = getXsheet();
|
||||
if (xsh)
|
||||
areaFilled = positionToXY(
|
||||
CellPosition(xsh->getFrameCount() + 1, xsh->getColumnCount() + 1));
|
||||
if (viewArea.right() < areaFilled.x()) viewArea.setRight(areaFilled.x());
|
||||
if (viewArea.bottom() < areaFilled.y()) viewArea.setBottom(areaFilled.y());
|
||||
|
||||
int columnCount = xsh ? xsh->getColumnCount() : 0;
|
||||
int wCounted = (XsheetGUI::ColumnWidth) * (columnCount + 1);
|
||||
if (w < wCounted) w = wCounted;
|
||||
NumberRange allLayer = o->layerSide(viewArea);
|
||||
NumberRange allFrame = o->frameSide(viewArea);
|
||||
NumberRange headerLayer = o->range(PredefinedRange::HEADER_LAYER);
|
||||
NumberRange headerFrame = o->range(PredefinedRange::HEADER_FRAME);
|
||||
|
||||
m_cellArea->setFixedSize(w, h);
|
||||
m_rowArea->setFixedSize(m_x0, h);
|
||||
m_columnArea->setFixedSize(w, m_y0);
|
||||
m_cellArea->setFixedSize(viewArea.size());
|
||||
m_rowArea->setFixedSize(o->frameLayerRect(allFrame, headerLayer).size());
|
||||
m_columnArea->setFixedSize(o->frameLayerRect(headerFrame, allLayer).size());
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
int XsheetViewer::xToColumn(int x) const {
|
||||
return getXsheet()->getColumnFan()->xToCol(x);
|
||||
CellPosition XsheetViewer::xyToPosition(const QPoint &point) const {
|
||||
const Orientation *o = orientation();
|
||||
return o->xyToPosition(point, getXsheet()->getColumnFan(o));
|
||||
}
|
||||
CellPosition XsheetViewer::xyToPosition(const TPoint &point) const {
|
||||
return xyToPosition(QPoint(point.x, point.y));
|
||||
}
|
||||
CellPosition XsheetViewer::xyToPosition(const TPointD &point) const {
|
||||
return xyToPosition(QPoint((int)point.x, (int)point.y));
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
int XsheetViewer::yToRow(int y) const { return y / XsheetGUI::RowHeight; }
|
||||
QPoint XsheetViewer::positionToXY(const CellPosition &pos) const {
|
||||
const Orientation *o = orientation();
|
||||
return o->positionToXY(pos, getXsheet()->getColumnFan(o));
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
int XsheetViewer::columnToX(int col) const {
|
||||
return getXsheet()->getColumnFan()->colToX(col);
|
||||
int XsheetViewer::columnToLayerAxis(int layer) const {
|
||||
const Orientation *o = orientation();
|
||||
return o->colToLayerAxis(layer, getXsheet()->getColumnFan(o));
|
||||
}
|
||||
int XsheetViewer::rowToFrameAxis(int frame) const {
|
||||
return orientation()->rowToFrameAxis(frame);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
int XsheetViewer::rowToY(int row) const { return row * XsheetGUI::RowHeight; }
|
||||
CellRange XsheetViewer::xyRectToRange(const QRect &rect) const {
|
||||
CellPosition topLeft = xyToPosition(rect.topLeft());
|
||||
CellPosition bottomRight = xyToPosition(rect.bottomRight());
|
||||
return CellRange(topLeft, bottomRight);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
QRect XsheetViewer::rangeToXYRect(const CellRange &range) const {
|
||||
QPoint from = positionToXY(range.from());
|
||||
QPoint to = positionToXY(range.to());
|
||||
QPoint topLeft = QPoint(min(from.x(), to.x()), min(from.y(), to.y()));
|
||||
QPoint bottomRight = QPoint(max(from.x(), to.x()), max(from.y(), to.y()));
|
||||
return QRect(topLeft, bottomRight);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void XsheetViewer::drawPredefinedPath(QPainter &p, PredefinedPath which,
|
||||
const CellPosition &pos,
|
||||
optional<QColor> fill,
|
||||
optional<QColor> outline) const {
|
||||
QPoint xy = positionToXY(pos);
|
||||
QPainterPath path = orientation()->path(which).translated(xy);
|
||||
if (fill) p.fillPath(path, QBrush(*fill));
|
||||
if (outline) {
|
||||
p.setPen(*outline);
|
||||
p.drawPath(path);
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
@ -590,7 +750,7 @@ bool XsheetViewer::isScrubHighlighted(int row, int col) {
|
|||
//-----------------------------------------------------------------------------
|
||||
|
||||
void XsheetViewer::showEvent(QShowEvent *) {
|
||||
registerFrameScroller();
|
||||
m_frameScroller.registerFrameScroller();
|
||||
if (m_isCurrentFrameSwitched) onCurrentFrameSwitched();
|
||||
if (m_isCurrentColumnSwitched) onCurrentColumnSwitched();
|
||||
m_isCurrentFrameSwitched = false;
|
||||
|
@ -651,7 +811,7 @@ void XsheetViewer::showEvent(QShowEvent *) {
|
|||
//-----------------------------------------------------------------------------
|
||||
|
||||
void XsheetViewer::hideEvent(QHideEvent *) {
|
||||
unregisterFrameScroller();
|
||||
m_frameScroller.unregisterFrameScroller();
|
||||
|
||||
TApp *app = TApp::instance();
|
||||
|
||||
|
@ -704,39 +864,13 @@ void XsheetViewer::paintEvent(QPaintEvent*)
|
|||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void XsheetViewer::updatePanelsSizes() {
|
||||
int w = width();
|
||||
int h = height();
|
||||
int scrollBarWidth = 16;
|
||||
if (Preferences::instance()->isShowXSheetToolbarEnabled()) {
|
||||
m_toolbar->showToolbar(true);
|
||||
m_toolbarScrollArea->setGeometry(1, 1, m_x0 * 12, m_y0 - 3);
|
||||
m_noteScrollArea->setGeometry(3, m_toolbarHeight + 1, m_x0 - 4, m_y0 - 3);
|
||||
m_cellScrollArea->setGeometry(m_x0, m_y0 + m_toolbarHeight, w - m_x0,
|
||||
h - m_y0 - m_toolbarHeight);
|
||||
m_columnScrollArea->setGeometry(m_x0, m_toolbarHeight + 1,
|
||||
w - m_x0 - scrollBarWidth, m_y0 - 3);
|
||||
m_rowScrollArea->setGeometry(1, m_y0 + m_toolbarHeight, m_x0 - 1,
|
||||
h - m_y0 - scrollBarWidth - m_toolbarHeight);
|
||||
} else {
|
||||
m_toolbar->showToolbar(false);
|
||||
m_toolbarScrollArea->setGeometry(3, 1, m_x0 - 4, m_y0 - 3);
|
||||
m_noteScrollArea->setGeometry(3, 1, m_x0 - 4, m_y0 - 3);
|
||||
m_cellScrollArea->setGeometry(m_x0, m_y0, w - m_x0, h - m_y0);
|
||||
m_columnScrollArea->setGeometry(m_x0, 1, w - m_x0 - scrollBarWidth,
|
||||
m_y0 - 3);
|
||||
m_rowScrollArea->setGeometry(1, m_y0, m_x0 - 1, h - m_y0 - scrollBarWidth);
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void XsheetViewer::resizeEvent(QResizeEvent *event) {
|
||||
updatePanelsSizes();
|
||||
//(Nuovo Layout Manager) Reintrodotto per il refresh automatico
|
||||
positionSections();
|
||||
|
||||
//(New Layout Manager) introduced automatic refresh
|
||||
refreshContentSize(
|
||||
0,
|
||||
0); // Non updateAreeSize() perche' si deve tener conto degli scrollbar.
|
||||
0); // Don't updateAreeSize because you have to account scrollbars
|
||||
updateAllAree();
|
||||
}
|
||||
|
||||
|
@ -751,13 +885,19 @@ void XsheetViewer::wheelEvent(QWheelEvent *event) {
|
|||
->getScene()
|
||||
->getProperties()
|
||||
->getMarkers(markerDistance, markerOffset);
|
||||
|
||||
if (event->angleDelta().x() == 0) { // vertical scroll
|
||||
if (!orientation()->isVerticalTimeline())
|
||||
markerDistance = 1;
|
||||
int scrollPixels = (event->angleDelta().y() > 0 ? 1 : -1) *
|
||||
markerDistance * XsheetGUI::RowHeight;
|
||||
markerDistance * orientation()->cellHeight();
|
||||
scroll(QPoint(0, -scrollPixels));
|
||||
} else { // horizontal scroll
|
||||
if (orientation()->isVerticalTimeline())
|
||||
markerDistance = 1;
|
||||
int scrollPixels =
|
||||
(event->angleDelta().x() > 0 ? 1 : -1) * XsheetGUI::ColumnWidth;
|
||||
(event->angleDelta().x() > 0 ? 1 : -1) *
|
||||
markerDistance * orientation()->cellWidth();
|
||||
scroll(QPoint(-scrollPixels, 0));
|
||||
}
|
||||
break;
|
||||
|
@ -806,9 +946,10 @@ void XsheetViewer::keyPressEvent(QKeyEvent *event) {
|
|||
if (changeFrameSkippingHolds(event)) return;
|
||||
|
||||
int frameCount = getXsheet()->getFrameCount();
|
||||
int row = getCurrentRow(), col = getCurrentColumn();
|
||||
CellPosition now(getCurrentRow(), getCurrentColumn());
|
||||
CellPosition shift = orientation()->arrowShift(event->key());
|
||||
CellPosition stride(1, 1); // stride in row and column axes
|
||||
|
||||
int rowStride = 1;
|
||||
TCellSelection *cellSel =
|
||||
dynamic_cast<TCellSelection *>(TSelection::getCurrent());
|
||||
// Use arrow keys to shift the cell selection. Ctrl + arrow keys to resize the
|
||||
|
@ -817,77 +958,62 @@ void XsheetViewer::keyPressEvent(QKeyEvent *event) {
|
|||
cellSel && !cellSel->isEmpty()) {
|
||||
int r0, c0, r1, c1;
|
||||
cellSel->getSelectedCells(r0, c0, r1, c1);
|
||||
rowStride = cellSel->getSelectedCells().getRowCount();
|
||||
QPoint offset(0, 0);
|
||||
switch (int key = event->key()) {
|
||||
case Qt::Key_Up:
|
||||
offset.setY(-1);
|
||||
break;
|
||||
case Qt::Key_Down:
|
||||
offset.setY(1);
|
||||
break;
|
||||
case Qt::Key_Left:
|
||||
offset.setX(-1);
|
||||
break;
|
||||
case Qt::Key_Right:
|
||||
offset.setX(1);
|
||||
break;
|
||||
}
|
||||
if (m_cellArea->isControlPressed()) {
|
||||
if (r0 == r1 && offset.y() == -1) return;
|
||||
if (c0 == c1 && offset.x() == -1) return;
|
||||
cellSel->selectCells(r0, c0, r1 + offset.y(), c1 + offset.x());
|
||||
stride.setFrame(cellSel->getSelectedCells().getRowCount());
|
||||
|
||||
if (m_cellArea->isControlPressed()) { // resize
|
||||
if (r0 == r1 && shift.frame() < 0) return;
|
||||
if (c0 == c1 && shift.layer() < 0) return;
|
||||
cellSel->selectCells(r0, c0, r1 + shift.frame(), c1 + shift.layer());
|
||||
updateCells();
|
||||
TApp::instance()->getCurrentSelection()->notifySelectionChanged();
|
||||
return;
|
||||
} else {
|
||||
offset.setY(offset.y() * rowStride);
|
||||
if (r0 + offset.y() < 0) offset.setY(-r0);
|
||||
if (c0 + offset.x() < 0) return;
|
||||
cellSel->selectCells(r0 + offset.y(), c0 + offset.x(), r1 + offset.y(),
|
||||
c1 + offset.x());
|
||||
} else { // shift
|
||||
CellPosition offset(shift * stride);
|
||||
int movedR0 = std::max(0, r0 + offset.frame());
|
||||
int movedC0 = std::max(0, c0 + offset.layer());
|
||||
int diffFrame = movedR0 - r0;
|
||||
int diffLayer = movedC0 - c0;
|
||||
cellSel->selectCells(r0 + diffFrame, c0 + diffLayer, r1 + diffFrame,
|
||||
c1 + diffLayer);
|
||||
TApp::instance()->getCurrentSelection()->notifySelectionChanged();
|
||||
}
|
||||
}
|
||||
|
||||
if (shift) {
|
||||
now = now + shift * stride;
|
||||
now.ensureValid();
|
||||
setCurrentRow(now.frame());
|
||||
setCurrentColumn(now.layer());
|
||||
return;
|
||||
}
|
||||
|
||||
switch (int key = event->key()) {
|
||||
case Qt::Key_Up:
|
||||
setCurrentRow(std::max(row - rowStride, 0));
|
||||
break;
|
||||
case Qt::Key_Down:
|
||||
setCurrentRow(row + rowStride);
|
||||
break;
|
||||
case Qt::Key_Left:
|
||||
setCurrentColumn(std::max(col - 1, 0));
|
||||
break;
|
||||
case Qt::Key_Right:
|
||||
setCurrentColumn(col + 1);
|
||||
break;
|
||||
case Qt::Key_Control:
|
||||
// display the upper-directional smart tab only when the ctrl key is pressed
|
||||
m_cellArea->onControlPressed(true);
|
||||
break;
|
||||
m_columnArea->onControlPressed(true);
|
||||
break;
|
||||
|
||||
default: {
|
||||
QRect visibleRect = m_cellArea->visibleRegion().boundingRect();
|
||||
int visibleRowCount = visibleRect.height() / XsheetGUI::RowHeight;
|
||||
int visibleRowCount = visibleRect.height() / orientation()->cellHeight();
|
||||
|
||||
switch (key) {
|
||||
case Qt::Key_PageUp:
|
||||
locals.scrollTo(
|
||||
visibleRect.top() - visibleRowCount * XsheetGUI::RowHeight,
|
||||
visibleRect.top() - visibleRowCount * orientation()->cellHeight(),
|
||||
visibleRect);
|
||||
break;
|
||||
case Qt::Key_PageDown:
|
||||
locals.scrollTo(
|
||||
visibleRect.bottom() + visibleRowCount * XsheetGUI::RowHeight,
|
||||
visibleRect.bottom() + visibleRowCount * orientation()->cellHeight(),
|
||||
visibleRect);
|
||||
break;
|
||||
case Qt::Key_Home:
|
||||
locals.scrollTo(0, visibleRect);
|
||||
break;
|
||||
case Qt::Key_End:
|
||||
locals.scrollTo((frameCount + 1) * XsheetGUI::RowHeight, visibleRect);
|
||||
locals.scrollTo((frameCount + 1) * orientation()->cellHeight(), visibleRect);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
@ -898,18 +1024,24 @@ void XsheetViewer::keyPressEvent(QKeyEvent *event) {
|
|||
//-----------------------------------------------------------------------------
|
||||
// display the upper-directional smart tab only when the ctrl key is pressed
|
||||
void XsheetViewer::keyReleaseEvent(QKeyEvent *event) {
|
||||
if (event->key() == Qt::Key_Control) m_cellArea->onControlPressed(false);
|
||||
if (event->key() == Qt::Key_Control) {
|
||||
m_cellArea->onControlPressed(false);
|
||||
m_columnArea->onControlPressed(false);
|
||||
}
|
||||
}
|
||||
|
||||
void XsheetViewer::enterEvent(QEvent *) { m_cellArea->onControlPressed(false); }
|
||||
void XsheetViewer::enterEvent(QEvent *) {
|
||||
m_cellArea->onControlPressed(false);
|
||||
m_columnArea->onControlPressed(false);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/*! scroll the cell area to make a cell at (row,col) visible
|
||||
*/
|
||||
void XsheetViewer::scrollTo(int row, int col) {
|
||||
QRect visibleRect = m_cellArea->visibleRegion().boundingRect();
|
||||
QRect cellRect(columnToX(col), rowToY(row), XsheetGUI::ColumnWidth,
|
||||
XsheetGUI::RowHeight);
|
||||
QPoint topLeft = positionToXY(CellPosition(row, col));
|
||||
QRect cellRect(topLeft, QSize(orientation()->cellWidth(), orientation()->cellHeight()));
|
||||
|
||||
int deltaX = 0;
|
||||
int deltaY = 0;
|
||||
|
@ -949,7 +1081,10 @@ void XsheetViewer::onXsheetChanged() {
|
|||
//-----------------------------------------------------------------------------
|
||||
|
||||
void XsheetViewer::onPreferenceChanged(const QString &prefName) {
|
||||
if (prefName == "XSheetToolbar") updatePanelsSizes();
|
||||
if (prefName == "XSheetToolbar") {
|
||||
positionSections();
|
||||
refreshContentSize(0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -988,50 +1123,63 @@ void XsheetViewer::onCurrentColumnSwitched() {
|
|||
//-----------------------------------------------------------------------------
|
||||
|
||||
void XsheetViewer::scrollToColumn(int col) {
|
||||
int x0 = columnToX(col);
|
||||
int x1 = columnToX(col + 1);
|
||||
int x0 = columnToLayerAxis(col);
|
||||
int x1 = columnToLayerAxis(col + 1);
|
||||
|
||||
scrollToHorizontalRange(x0, x1);
|
||||
if (orientation()->isVerticalTimeline())
|
||||
scrollToHorizontalRange(x0, x1);
|
||||
else
|
||||
scrollToVerticalRange(x0, x1);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void XsheetViewer::scrollToHorizontalRange(int x0, int x1) {
|
||||
QRect visibleRect = m_cellArea->visibleRegion().boundingRect();
|
||||
int visibleLeft = visibleRect.left();
|
||||
int visibleRight = visibleRect.right();
|
||||
if (visibleRect.isEmpty()) return;
|
||||
int visibleLeft = visibleRect.left();
|
||||
int visibleRight = visibleRect.right();
|
||||
|
||||
if (visibleLeft > x1) { // Se sono fuori dalla regione visibile in alto
|
||||
if (visibleLeft > x0) { // If they are out of left visible region
|
||||
int deltaX = x0 - visibleLeft;
|
||||
scroll(QPoint(deltaX, 0));
|
||||
return;
|
||||
}
|
||||
if (visibleRight < x1) { // Se sono fuori dalla regione visibile in basso
|
||||
if (visibleRight < x1) { // If they are out of right visible region
|
||||
int deltaX = x1 + 2 - visibleRight;
|
||||
scroll(QPoint(deltaX, 0));
|
||||
return;
|
||||
}
|
||||
updateCellColumnAree();
|
||||
if (orientation()->isVerticalTimeline())
|
||||
updateCellColumnAree();
|
||||
else
|
||||
updateCellRowAree();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void XsheetViewer::scrollToRow(int row) {
|
||||
int y0 = rowToY(row);
|
||||
int y1 = rowToY(row + 1);
|
||||
int y0 = rowToFrameAxis(row);
|
||||
int y1 = rowToFrameAxis(row + 1);
|
||||
|
||||
scrollToVerticalRange(y0, y1);
|
||||
if (orientation()->isVerticalTimeline())
|
||||
scrollToVerticalRange(y0, y1);
|
||||
else
|
||||
scrollToHorizontalRange(y0, y1);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void XsheetViewer::scrollToVerticalRange(int y0, int y1) {
|
||||
int yMin = min(y0, y1);
|
||||
int yMax = max(y0, y1);
|
||||
QRect visibleRect = m_cellArea->visibleRegion().boundingRect();
|
||||
if (visibleRect.isEmpty()) return;
|
||||
int visibleTop = visibleRect.top();
|
||||
int visibleBottom = visibleRect.bottom();
|
||||
|
||||
if (visibleTop > y0) { // Se sono fuori dalla regione visibile in alto
|
||||
int deltaY = y0 - visibleTop;
|
||||
if (visibleTop > yMin) { // If they are out of top visible region
|
||||
int deltaY = yMin - visibleTop;
|
||||
if (!TApp::instance()->getCurrentFrame()->isPlaying() ||
|
||||
Preferences::instance()->isXsheetAutopanEnabled()) {
|
||||
scroll(QPoint(0, deltaY));
|
||||
|
@ -1039,16 +1187,18 @@ void XsheetViewer::scrollToVerticalRange(int y0, int y1) {
|
|||
}
|
||||
}
|
||||
|
||||
if (visibleBottom < y1) { // Se sono fuori dalla regione visibile in basso
|
||||
int deltaY = y1 + 2 - visibleBottom;
|
||||
if (visibleBottom < yMax) { // If they are out of bottom visible region
|
||||
int deltaY = yMax + 2 - visibleBottom;
|
||||
if (!TApp::instance()->getCurrentFrame()->isPlaying() ||
|
||||
Preferences::instance()->isXsheetAutopanEnabled()) {
|
||||
scroll(QPoint(0, deltaY));
|
||||
return;
|
||||
}
|
||||
}
|
||||
m_rowArea->update(m_rowArea->visibleRegion());
|
||||
m_cellArea->update(m_cellArea->visibleRegion());
|
||||
if (orientation()->isVerticalTimeline())
|
||||
updateCellRowAree();
|
||||
else
|
||||
updateCellColumnAree();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -1089,6 +1239,7 @@ void XsheetViewer::updateAllAree(bool isDragging) {
|
|||
m_rowArea->update(m_rowArea->visibleRegion());
|
||||
m_columnArea->update(m_columnArea->visibleRegion());
|
||||
}
|
||||
m_toolbar->update(m_toolbar->visibleRegion());
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -1166,12 +1317,12 @@ void XsheetViewer::setCurrentNoteIndex(int currentNoteIndex) {
|
|||
int col = notes->getNoteCol(currentNoteIndex);
|
||||
TPointD pos = notes->getNotePos(currentNoteIndex);
|
||||
|
||||
int x0 = columnToX(col) + pos.x;
|
||||
int x1 = x0 + XsheetGUI::NoteWidth;
|
||||
scrollToHorizontalRange(x0, x1);
|
||||
int y0 = rowToY(row) + pos.y;
|
||||
int y1 = y0 + XsheetGUI::NoteHeight;
|
||||
scrollToVerticalRange(y0, y1);
|
||||
QPoint topLeft = positionToXY(CellPosition(row, col)) +
|
||||
QPoint(pos.x, pos.y); // actually xy
|
||||
QSize size(XsheetGUI::NoteWidth, XsheetGUI::NoteHeight);
|
||||
QRect noteRect(topLeft, size);
|
||||
scrollToHorizontalRange(noteRect.left(), noteRect.right());
|
||||
scrollToVerticalRange(noteRect.top(), noteRect.bottom());
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -1295,6 +1446,19 @@ void XsheetViewer::setFrameDisplayStyle(FrameDisplayStyle style) {
|
|||
FrameDisplayStyleInXsheetRowArea = (int)style;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void XsheetViewer::save(QSettings &settings) const {
|
||||
settings.setValue("orientation", orientation()->name());
|
||||
}
|
||||
void XsheetViewer::load(QSettings &settings) {
|
||||
QVariant name = settings.value("orientation");
|
||||
if (!name.canConvert(QVariant::String)) return;
|
||||
|
||||
m_orientation = Orientations::byName(name.toString());
|
||||
emit orientationChanged(orientation());
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/*
|
||||
TPanel *createXsheetViewer(QWidget *parent)
|
||||
|
|
|
@ -12,7 +12,12 @@
|
|||
#include "xshnoteviewer.h"
|
||||
#include "xshtoolbar.h"
|
||||
#include "cellkeyframeselection.h"
|
||||
#include "saveloadqsettings.h"
|
||||
#include "toonzqt/spreadsheetviewer.h"
|
||||
#include "orientation.h"
|
||||
#include <boost/optional.hpp>
|
||||
|
||||
using boost::optional;
|
||||
|
||||
#define XSHEET_FONT_PX_SIZE 12
|
||||
#define H_ADJUST 2
|
||||
|
@ -150,7 +155,7 @@ protected:
|
|||
//! Note: some refactoring is needed. XsheetViewer is going to derive from
|
||||
//! SpreadsheetViewer.
|
||||
|
||||
class XsheetViewer final : public QFrame, public Spreadsheet::FrameScroller {
|
||||
class XsheetViewer final : public QFrame, public SaveLoadQSettings {
|
||||
Q_OBJECT
|
||||
|
||||
QColor m_lightLightBgColor;
|
||||
|
@ -322,7 +327,8 @@ class XsheetViewer final : public QFrame, public Spreadsheet::FrameScroller {
|
|||
XsheetGUI::NoteArea *m_noteArea;
|
||||
XsheetGUI::Toolbar *m_toolbar;
|
||||
|
||||
int m_x0, m_y0, m_toolbarHeight;
|
||||
Spreadsheet::FrameScroller m_frameScroller;
|
||||
|
||||
int m_timerId;
|
||||
QPoint m_autoPanSpeed;
|
||||
QPoint m_lastAutoPanPos;
|
||||
|
@ -344,6 +350,8 @@ class XsheetViewer final : public QFrame, public Spreadsheet::FrameScroller {
|
|||
|
||||
Qt::KeyboardModifiers m_qtModifiers;
|
||||
|
||||
const Orientation *m_orientation;
|
||||
|
||||
public:
|
||||
enum FrameDisplayStyle { Frame = 0, SecAndFrame, SixSecSheet, ThreeSecSheet };
|
||||
|
||||
|
@ -417,7 +425,6 @@ public:
|
|||
void setCurrentRow(int row);
|
||||
|
||||
void scroll(QPoint delta);
|
||||
void onPrepareToScroll(int dy) override;
|
||||
|
||||
void setAutoPanSpeed(const QPoint &speed);
|
||||
void setAutoPanSpeed(const QRect &widgetBounds, const QPoint &mousePos);
|
||||
|
@ -426,22 +433,33 @@ public:
|
|||
return m_autoPanSpeed.x() != 0 || m_autoPanSpeed.y() != 0;
|
||||
}
|
||||
|
||||
int xToColumn(int x) const;
|
||||
int yToRow(int y) const;
|
||||
int columnToX(int col) const;
|
||||
int rowToY(int row) const;
|
||||
//-------
|
||||
const Orientation *orientation() const;
|
||||
void flipOrientation();
|
||||
|
||||
CellPosition xyToPosition(const QPoint &point) const;
|
||||
CellPosition xyToPosition(const TPoint &point) const;
|
||||
CellPosition xyToPosition(const TPointD &point) const;
|
||||
QPoint positionToXY(const CellPosition &pos) const;
|
||||
|
||||
int columnToLayerAxis(int layer) const;
|
||||
int rowToFrameAxis(int frame) const;
|
||||
|
||||
CellRange xyRectToRange(const QRect &rect) const;
|
||||
QRect rangeToXYRect(const CellRange &range) const;
|
||||
|
||||
void drawPredefinedPath(QPainter &p, PredefinedPath which,
|
||||
const CellPosition &pos, optional<QColor> fill,
|
||||
optional<QColor> outline) const;
|
||||
//---------
|
||||
|
||||
void updateCells() { m_cellArea->update(m_cellArea->visibleRegion()); }
|
||||
void updateRows() { m_rowArea->update(m_rowArea->visibleRegion()); }
|
||||
void updateColumns() { m_columnArea->update(m_columnArea->visibleRegion()); }
|
||||
void updatePanelsSizes();
|
||||
bool refreshContentSize(int scrollDx, int scrollDy);
|
||||
|
||||
void updateAreeSize();
|
||||
|
||||
// provvisorio
|
||||
QScrollArea *getFrameScrollArea() const override { return m_cellScrollArea; }
|
||||
|
||||
QList<XsheetGUI::NoteWidget *> getNotesWidget() const;
|
||||
void addNoteWidget(XsheetGUI::NoteWidget *w);
|
||||
int getCurrentNoteIndex() const;
|
||||
|
@ -660,6 +678,10 @@ public:
|
|||
void setFrameDisplayStyle(FrameDisplayStyle style);
|
||||
FrameDisplayStyle getFrameDisplayStyle() { return m_frameDisplayStyle; }
|
||||
|
||||
// SaveLoadQSettings
|
||||
virtual void save(QSettings &settings) const override;
|
||||
virtual void load(QSettings &settings) override;
|
||||
|
||||
protected:
|
||||
void scrollToColumn(int col);
|
||||
void scrollToHorizontalRange(int x0, int x1);
|
||||
|
@ -676,6 +698,15 @@ protected:
|
|||
void wheelEvent(QWheelEvent *event) override;
|
||||
void timerEvent(QTimerEvent *) override;
|
||||
|
||||
void positionSections();
|
||||
void disconnectScrollBars();
|
||||
void connectScrollBars();
|
||||
void connectOrDisconnectScrollBars(bool toConnect);
|
||||
void connectOrDisconnect(bool toConnect, QWidget *sender, const char *signal,
|
||||
QWidget *receiver, const char *slot);
|
||||
signals:
|
||||
void orientationChanged(const Orientation *newOrientation);
|
||||
|
||||
public slots:
|
||||
void onSceneSwitched();
|
||||
void onXsheetChanged();
|
||||
|
@ -697,6 +728,9 @@ public slots:
|
|||
void changeWindowTitle();
|
||||
|
||||
void resetXsheetNotes();
|
||||
|
||||
void onOrientationChanged(const Orientation *newOrientation);
|
||||
void onPrepareToScrollOffset(const QPoint &offset);
|
||||
};
|
||||
|
||||
#endif // XSHEETVIEWER_H
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
#include "toonz/txshnoteset.h"
|
||||
#include "toonz/sceneproperties.h"
|
||||
#include "toonz/txsheethandle.h"
|
||||
#include "orientation.h"
|
||||
|
||||
// Qt includes
|
||||
#include <QVariant>
|
||||
|
@ -372,7 +373,7 @@ NoteWidget::NoteWidget(XsheetViewer *parent, int noteIndex)
|
|||
|
||||
void NoteWidget::paint(QPainter *painter, QPoint pos, bool isCurrent) {
|
||||
painter->translate(pos);
|
||||
QRect rect(0, 0, width(), height());
|
||||
QRect rect = m_viewer->orientation()->rect(PredefinedRect::NOTE_ICON);
|
||||
|
||||
TXshNoteSet *notes = m_viewer->getXsheet()->getNotes();
|
||||
TSceneProperties *sp = m_viewer->getXsheet()->getScene()->getProperties();
|
||||
|
@ -450,23 +451,38 @@ NoteArea::NoteArea(XsheetViewer *parent, Qt::WindowFlags flags)
|
|||
#else
|
||||
NoteArea::NoteArea(XsheetViewer *parent, Qt::WFlags flags)
|
||||
#endif
|
||||
: QFrame(parent), m_viewer(parent) {
|
||||
: QFrame(parent)
|
||||
, m_viewer(parent)
|
||||
, m_flipOrientationButton(nullptr)
|
||||
, m_noteButton(nullptr)
|
||||
, m_precNoteButton(nullptr)
|
||||
, m_nextNoteButton(nullptr)
|
||||
, m_frameDisplayStyleCombo(nullptr)
|
||||
, m_layerHeaderPanel(nullptr) {
|
||||
|
||||
setFrameStyle(QFrame::StyledPanel);
|
||||
setObjectName("cornerWidget");
|
||||
|
||||
QToolButton *toolButton = new QToolButton(this);
|
||||
m_flipOrientationButton =
|
||||
new QPushButton(m_viewer->orientation()->name(), this);
|
||||
m_noteButton = new QToolButton(this);
|
||||
m_precNoteButton = new QToolButton(this);
|
||||
m_nextNoteButton = new QToolButton(this);
|
||||
m_frameDisplayStyleCombo = new QComboBox(this);
|
||||
m_layerHeaderPanel = new LayerHeaderPanel(m_viewer, this);
|
||||
|
||||
//-----
|
||||
|
||||
toolButton->setObjectName("ToolbarToolButton");
|
||||
toolButton->setFixedSize(44, 26);
|
||||
toolButton->setIconSize(QSize(38, 20));
|
||||
QIcon addNoteIcon = createQIcon("newmemo");
|
||||
m_flipOrientationButton->setObjectName("flipOrientationButton");
|
||||
m_flipOrientationButton->setFocusPolicy(Qt::FocusPolicy::NoFocus);
|
||||
|
||||
m_noteButton->setObjectName("ToolbarToolButton");
|
||||
m_noteButton->setFixedSize(44, 26);
|
||||
m_noteButton->setIconSize(QSize(38, 20));
|
||||
QIcon addNoteIcon = createQIconPNG("newmemo");
|
||||
addNoteIcon.addFile(QString(":Resources/newmemo_disabled.svg"), QSize(),
|
||||
QIcon::Disabled);
|
||||
toolButton->setIcon(addNoteIcon);
|
||||
m_noteButton->setIcon(addNoteIcon);
|
||||
|
||||
m_precNoteButton->setObjectName("ToolbarToolButton");
|
||||
m_precNoteButton->setFixedSize(22, 22);
|
||||
|
@ -492,35 +508,14 @@ NoteArea::NoteArea(XsheetViewer *parent, Qt::WFlags flags)
|
|||
(int)m_viewer->getFrameDisplayStyle());
|
||||
|
||||
// layout
|
||||
QVBoxLayout *mainLay = new QVBoxLayout();
|
||||
mainLay->setMargin(0);
|
||||
mainLay->setSpacing(5);
|
||||
{
|
||||
mainLay->addStretch(1);
|
||||
|
||||
mainLay->addWidget(toolButton, 0, Qt::AlignHCenter);
|
||||
|
||||
QHBoxLayout *noteLay = new QHBoxLayout();
|
||||
noteLay->setMargin(0);
|
||||
noteLay->setSpacing(0);
|
||||
{
|
||||
noteLay->addStretch(1);
|
||||
noteLay->addWidget(m_precNoteButton, 0);
|
||||
noteLay->addWidget(m_nextNoteButton, 0);
|
||||
noteLay->addStretch(1);
|
||||
}
|
||||
mainLay->addLayout(noteLay, 0);
|
||||
|
||||
mainLay->addStretch(1);
|
||||
|
||||
mainLay->addWidget(m_frameDisplayStyleCombo, 0);
|
||||
}
|
||||
setLayout(mainLay);
|
||||
createLayout();
|
||||
|
||||
// signal-slot connections
|
||||
bool ret = true;
|
||||
ret = ret && connect(m_flipOrientationButton, SIGNAL(clicked()),
|
||||
SLOT(flipOrientation()));
|
||||
|
||||
ret = ret && connect(toolButton, SIGNAL(clicked()), SLOT(toggleNewNote()));
|
||||
ret = ret && connect(m_noteButton, SIGNAL(clicked()), SLOT(toggleNewNote()));
|
||||
ret = ret &&
|
||||
connect(m_precNoteButton, SIGNAL(clicked()), this, SLOT(precNote()));
|
||||
ret = ret &&
|
||||
|
@ -530,6 +525,9 @@ NoteArea::NoteArea(XsheetViewer *parent, Qt::WFlags flags)
|
|||
ret && connect(m_frameDisplayStyleCombo, SIGNAL(currentIndexChanged(int)),
|
||||
this, SLOT(onFrameDisplayStyleChanged(int)));
|
||||
|
||||
ret = ret && connect(m_viewer, &XsheetViewer::orientationChanged, this,
|
||||
&NoteArea::onXsheetOrientationChanged);
|
||||
|
||||
updateButtons();
|
||||
|
||||
assert(ret);
|
||||
|
@ -537,6 +535,69 @@ NoteArea::NoteArea(XsheetViewer *parent, Qt::WFlags flags)
|
|||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void NoteArea::removeLayout() {
|
||||
QLayout *currentLayout = layout();
|
||||
if (!currentLayout) return;
|
||||
|
||||
currentLayout->removeWidget(m_flipOrientationButton);
|
||||
currentLayout->removeWidget(m_noteButton);
|
||||
currentLayout->removeWidget(m_precNoteButton);
|
||||
currentLayout->removeWidget(m_nextNoteButton);
|
||||
currentLayout->removeWidget(m_frameDisplayStyleCombo);
|
||||
currentLayout->removeWidget(m_layerHeaderPanel);
|
||||
delete currentLayout;
|
||||
}
|
||||
|
||||
void NoteArea::createLayout() {
|
||||
const Orientation *o = m_viewer->orientation();
|
||||
QRect rect = o->rect(PredefinedRect::NOTE_AREA);
|
||||
|
||||
setFixedSize(rect.size());
|
||||
|
||||
// has two elements: main layout and header panel
|
||||
QVBoxLayout *panelLayout = new QVBoxLayout();
|
||||
panelLayout->setMargin(1);
|
||||
panelLayout->setSpacing(0);
|
||||
{
|
||||
QBoxLayout *mainLayout = new QBoxLayout(QBoxLayout::Direction(
|
||||
o->dimension(PredefinedDimension::QBOXLAYOUT_DIRECTION)));
|
||||
Qt::AlignmentFlag centerAlign =
|
||||
Qt::AlignmentFlag(o->dimension(PredefinedDimension::CENTER_ALIGN));
|
||||
mainLayout->setMargin(1);
|
||||
mainLayout->setSpacing(0);
|
||||
{
|
||||
mainLayout->addWidget(m_flipOrientationButton, 0, centerAlign);
|
||||
|
||||
mainLayout->addStretch(1);
|
||||
|
||||
mainLayout->addWidget(m_noteButton, 0, centerAlign);
|
||||
|
||||
QHBoxLayout *buttonsLayout = new QHBoxLayout();
|
||||
buttonsLayout->setMargin(0);
|
||||
buttonsLayout->setSpacing(0);
|
||||
{
|
||||
buttonsLayout->addStretch(1);
|
||||
buttonsLayout->addWidget(m_precNoteButton, 0);
|
||||
buttonsLayout->addWidget(m_nextNoteButton, 0);
|
||||
buttonsLayout->addStretch(1);
|
||||
}
|
||||
mainLayout->addLayout(buttonsLayout, 0);
|
||||
|
||||
mainLayout->addStretch(1);
|
||||
|
||||
mainLayout->addWidget(m_frameDisplayStyleCombo, 0);
|
||||
}
|
||||
panelLayout->addLayout(mainLayout);
|
||||
|
||||
panelLayout->addWidget(m_layerHeaderPanel);
|
||||
}
|
||||
setLayout(panelLayout);
|
||||
|
||||
m_layerHeaderPanel->showOrHide(o);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void NoteArea::updateButtons() {
|
||||
TXshNoteSet *notes = m_viewer->getXsheet()->getNotes();
|
||||
|
||||
|
@ -555,6 +616,16 @@ void NoteArea::updateButtons() {
|
|||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void NoteArea::flipOrientation() { m_viewer->flipOrientation(); }
|
||||
|
||||
void NoteArea::onXsheetOrientationChanged(const Orientation *newOrientation) {
|
||||
m_flipOrientationButton->setText(newOrientation->caption());
|
||||
removeLayout();
|
||||
createLayout();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void NoteArea::toggleNewNote() {
|
||||
if (!m_newNotePopup)
|
||||
m_newNotePopup.reset(new XsheetGUI::NotePopup(m_viewer, -1));
|
||||
|
|
|
@ -13,6 +13,8 @@
|
|||
#include <QFrame>
|
||||
#include <QScrollArea>
|
||||
|
||||
#include "layerheaderpanel.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
// forward declaration
|
||||
|
@ -22,6 +24,7 @@ class TColorStyle;
|
|||
class QToolButton;
|
||||
class QPushButton;
|
||||
class QComboBox;
|
||||
class Orientation;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
@ -117,11 +120,16 @@ class NoteArea final : public QFrame {
|
|||
std::unique_ptr<NotePopup> m_newNotePopup; // Popup used to create new note
|
||||
XsheetViewer *m_viewer;
|
||||
|
||||
QPushButton *m_flipOrientationButton;
|
||||
|
||||
QToolButton *m_noteButton;
|
||||
QToolButton *m_nextNoteButton;
|
||||
QToolButton *m_precNoteButton;
|
||||
|
||||
QComboBox *m_frameDisplayStyleCombo;
|
||||
|
||||
LayerHeaderPanel *m_layerHeaderPanel;
|
||||
|
||||
public:
|
||||
#if QT_VERSION >= 0x050500
|
||||
NoteArea(XsheetViewer *parent = 0, Qt::WindowFlags flags = 0);
|
||||
|
@ -133,11 +141,17 @@ public:
|
|||
void updateButtons();
|
||||
|
||||
protected slots:
|
||||
void flipOrientation();
|
||||
void toggleNewNote();
|
||||
void nextNote();
|
||||
void precNote();
|
||||
|
||||
void onFrameDisplayStyleChanged(int id);
|
||||
void onXsheetOrientationChanged(const Orientation *orientation);
|
||||
|
||||
protected:
|
||||
void removeLayout();
|
||||
void createLayout();
|
||||
};
|
||||
|
||||
} // namespace XsheetGUI;
|
||||
|
|
|
@ -46,7 +46,6 @@ RowArea::RowArea(XsheetViewer *parent, Qt::WFlags flags)
|
|||
#endif
|
||||
: QWidget(parent, flags)
|
||||
, m_viewer(parent)
|
||||
, m_xa(ColumnWidth / 2 - 12)
|
||||
, m_row(-1)
|
||||
, m_showOnionToSet(None)
|
||||
, m_pos(-1, -1)
|
||||
|
@ -108,20 +107,23 @@ void RowArea::drawRows(QPainter &p, int r0, int r1) {
|
|||
|
||||
QRect visibleRect = visibleRegion().boundingRect();
|
||||
|
||||
int x0 = visibleRect.left();
|
||||
int x1 = visibleRect.right();
|
||||
int y0 = visibleRect.top();
|
||||
int y1 = visibleRect.bottom();
|
||||
int x0 = visibleRect.left();
|
||||
int x1 = visibleRect.right();
|
||||
int y0 = visibleRect.top();
|
||||
int y1 = visibleRect.bottom();
|
||||
NumberRange layerSide = m_viewer->orientation()->layerSide(visibleRect);
|
||||
|
||||
for (int r = r0; r <= r1; r++) {
|
||||
int y = m_viewer->rowToY(r);
|
||||
int frameAxis = m_viewer->rowToFrameAxis(r);
|
||||
|
||||
//--- draw horizontal line
|
||||
QColor color = ((r - offset) % distance != 0)
|
||||
? m_viewer->getLightLineColor()
|
||||
: m_viewer->getMarkerLineColor();
|
||||
QColor color = ((r - offset) % distance == 0 && r != 0)
|
||||
? m_viewer->getMarkerLineColor()
|
||||
: m_viewer->getLightLineColor();
|
||||
p.setPen(color);
|
||||
p.drawLine(x0, y, x1, y);
|
||||
QLine horizontalLine =
|
||||
m_viewer->orientation()->horizontalLine(frameAxis, layerSide);
|
||||
p.drawLine(horizontalLine);
|
||||
|
||||
// draw frame text
|
||||
if (playR0 <= r && r <= playR1) {
|
||||
|
@ -132,6 +134,13 @@ void RowArea::drawRows(QPainter &p, int r0, int r1) {
|
|||
else
|
||||
p.setPen(m_viewer->getTextColor());
|
||||
|
||||
QPoint basePoint = m_viewer->positionToXY(CellPosition(r, 0));
|
||||
QRect labelRect = m_viewer->orientation()
|
||||
->rect(PredefinedRect::FRAME_LABEL)
|
||||
.translated(basePoint);
|
||||
int align = m_viewer->orientation()->dimension(
|
||||
PredefinedDimension::FRAME_LABEL_ALIGN);
|
||||
// display time and/or frame number
|
||||
switch (m_viewer->getFrameDisplayStyle()) {
|
||||
case XsheetViewer::SecAndFrame: {
|
||||
int frameRate = TApp::instance()
|
||||
|
@ -152,16 +161,14 @@ void RowArea::drawRows(QPainter &p, int r0, int r1) {
|
|||
str = QString("%1\"").arg(QString::number(koma).rightJustified(2, '0'));
|
||||
}
|
||||
|
||||
p.drawText(QRect(width() / 2 - 15, y + 1, width() / 2 + 7, RowHeight - 2),
|
||||
Qt::AlignRight | Qt::AlignBottom, str);
|
||||
p.drawText(labelRect, align, str);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case XsheetViewer::Frame: {
|
||||
QString number = QString::number(r + 1);
|
||||
p.drawText(QRect(width() / 2 - 2, y + 1, width() / 2, RowHeight - 2),
|
||||
Qt::AlignHCenter | Qt::AlignBottom, number);
|
||||
p.drawText(labelRect, align, number);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -177,15 +184,14 @@ void RowArea::drawRows(QPainter &p, int r0, int r1) {
|
|||
int koma = (r + 1) % (frameRate * 6);
|
||||
if ((r + 1) % frameRate == 1) {
|
||||
int page = (r + 1) / (frameRate * 6) + 1;
|
||||
str = QString("p%1 %2")
|
||||
str = QString("p%1 %2")
|
||||
.arg(QString::number(page))
|
||||
.arg(QString::number(koma).rightJustified(3, '0'));
|
||||
} else {
|
||||
if (koma == 0) koma = frameRate * 6;
|
||||
str = QString("%1").arg(QString::number(koma).rightJustified(3, '0'));
|
||||
}
|
||||
p.drawText(QRect(width() / 2 - 21, y + 1, width() / 2 + 7, RowHeight - 2),
|
||||
Qt::AlignRight | Qt::AlignBottom, str);
|
||||
p.drawText(labelRect, align, str);
|
||||
break;
|
||||
}
|
||||
// 3 second sheet (72frames per page)
|
||||
|
@ -200,25 +206,18 @@ void RowArea::drawRows(QPainter &p, int r0, int r1) {
|
|||
int koma = (r + 1) % (frameRate * 3);
|
||||
if ((r + 1) % frameRate == 1) {
|
||||
int page = (r + 1) / (frameRate * 3) + 1;
|
||||
str = QString("p%1 %2")
|
||||
str = QString("p%1 %2")
|
||||
.arg(QString::number(page))
|
||||
.arg(QString::number(koma).rightJustified(2, '0'));
|
||||
} else {
|
||||
if (koma == 0) koma = frameRate * 3;
|
||||
str = QString("%1").arg(QString::number(koma).rightJustified(2, '0'));
|
||||
}
|
||||
p.drawText(QRect(width() / 2 - 21, y + 1, width() / 2 + 7, RowHeight - 2),
|
||||
Qt::AlignRight | Qt::AlignBottom, str);
|
||||
p.drawText(labelRect, align, str);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// hide the top-most horizontal line
|
||||
if (r0 == 0) {
|
||||
p.setPen(m_viewer->getLightLineColor());
|
||||
p.drawLine(x0, m_viewer->rowToY(0), x1, m_viewer->rowToY(0));
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -243,28 +242,29 @@ void RowArea::drawPlayRange(QPainter &p, int r0, int r1) {
|
|||
QColor ArrowColor = (playRangeEnabled) ? QColor(255, 255, 255) : grey150;
|
||||
p.setBrush(QBrush(ArrowColor));
|
||||
|
||||
if (m_r0 > r0 - 1 && r1 + 1 > m_r0) {
|
||||
int y0 = m_viewer->rowToY(m_r0);
|
||||
drawArrow(p, QPointF(m_xa, y0 + 1), QPointF(m_xa + 10, y0 + 1),
|
||||
QPointF(m_xa, y0 + 11), true, ArrowColor);
|
||||
}
|
||||
if (m_r0 > r0 - 1 && r1 + 1 > m_r0)
|
||||
m_viewer->drawPredefinedPath(p, PredefinedPath::BEGIN_PLAY_RANGE,
|
||||
CellPosition(m_r0, 0), ArrowColor,
|
||||
QColor(Qt::black));
|
||||
|
||||
if (m_r1 > r0 - 1 && r1 + 1 > m_r1) {
|
||||
int y1 = m_viewer->rowToY(m_r1 + 1) - 12;
|
||||
drawArrow(p, QPointF(m_xa, y1 + 1), QPointF(m_xa + 10, y1 + 11),
|
||||
QPointF(m_xa, y1 + 11), true, ArrowColor);
|
||||
}
|
||||
if (m_r1 > r0 - 1 && r1 + 1 > m_r1)
|
||||
m_viewer->drawPredefinedPath(p, PredefinedPath::END_PLAY_RANGE,
|
||||
CellPosition(m_r1, 0), ArrowColor,
|
||||
QColor(Qt::black));
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void RowArea::drawCurrentRowGadget(QPainter &p, int r0, int r1) {
|
||||
int currentRow = m_viewer->getCurrentRow();
|
||||
int y = m_viewer->rowToY(currentRow);
|
||||
if (currentRow < r0 || r1 < currentRow) return;
|
||||
|
||||
p.fillRect(1, y + 1, width() - 4, RowHeight - 1,
|
||||
m_viewer->getCurrentRowBgColor());
|
||||
QPoint topLeft = m_viewer->positionToXY(CellPosition(currentRow, 0));
|
||||
QRect header = m_viewer->orientation()
|
||||
->rect(PredefinedRect::FRAME_HEADER)
|
||||
.translated(topLeft)
|
||||
.adjusted(1, 1, 0, 0);
|
||||
p.fillRect(header, m_viewer->getCurrentRowBgColor());
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -282,12 +282,9 @@ void RowArea::drawOnionSkinSelection(QPainter &p) {
|
|||
bool inksOnly;
|
||||
Preferences::instance()->getOnionData(frontPixel, backPixel, inksOnly);
|
||||
QColor frontColor((int)frontPixel.r, (int)frontPixel.g, (int)frontPixel.b,
|
||||
128);
|
||||
QColor backColor((int)backPixel.r, (int)backPixel.g, (int)backPixel.b, 128);
|
||||
|
||||
int onionDotDiam = 8;
|
||||
int onionHandleDiam = RowHeight - 1;
|
||||
int onionDotYPos = (RowHeight - onionDotDiam) / 2;
|
||||
128);
|
||||
QColor backColor((int)backPixel.r, (int)backPixel.g, (int)backPixel.b,
|
||||
128);
|
||||
|
||||
// If the onion skin is disabled, draw dash line instead.
|
||||
if (osMask.isEnabled())
|
||||
|
@ -299,14 +296,11 @@ void RowArea::drawOnionSkinSelection(QPainter &p) {
|
|||
p.setPen(currentPen);
|
||||
}
|
||||
|
||||
// Draw onion skin extender handles.
|
||||
QRectF handleRect(3, m_viewer->rowToY(currentRow) + 1, onionHandleDiam,
|
||||
onionHandleDiam);
|
||||
int angle180 = 16 * 180;
|
||||
p.setBrush(QBrush(backColor));
|
||||
p.drawChord(handleRect, 0, angle180);
|
||||
p.setBrush(QBrush(frontColor));
|
||||
p.drawChord(handleRect, angle180, angle180);
|
||||
QRect onionRect = m_viewer->orientation()->rect(PredefinedRect::ONION);
|
||||
int onionCenter_frame =
|
||||
m_viewer->orientation()->frameSide(onionRect).middle();
|
||||
int onionCenter_layer =
|
||||
m_viewer->orientation()->layerSide(onionRect).middle();
|
||||
|
||||
//-- draw movable onions
|
||||
|
||||
|
@ -322,18 +316,43 @@ void RowArea::drawOnionSkinSelection(QPainter &p) {
|
|||
p.setBrush(Qt::NoBrush);
|
||||
if (minMos < 0) // previous frames
|
||||
{
|
||||
int y0 =
|
||||
m_viewer->rowToY(currentRow + minMos) + onionDotYPos + onionDotDiam;
|
||||
int y1 = m_viewer->rowToY(currentRow);
|
||||
p.drawLine(onionDotDiam * 1.5, y0, onionDotDiam * 1.5, y1);
|
||||
int layerAxis = onionCenter_layer;
|
||||
int fromFrameAxis =
|
||||
m_viewer->rowToFrameAxis(currentRow + minMos) + onionCenter_frame;
|
||||
int toFrameAxis = m_viewer->rowToFrameAxis(currentRow) + onionCenter_frame;
|
||||
QLine verticalLine = m_viewer->orientation()->verticalLine(
|
||||
layerAxis, NumberRange(fromFrameAxis, toFrameAxis));
|
||||
if (m_viewer->orientation()->isVerticalTimeline())
|
||||
p.drawLine(verticalLine.x1() + 1, verticalLine.y1() + 4, verticalLine.x2() + 1, verticalLine.y2() - 10);
|
||||
else
|
||||
p.drawLine(verticalLine.x1() + 4, verticalLine.y1() + 1, verticalLine.x2() - 10, verticalLine.y2() + 1);
|
||||
}
|
||||
if (maxMos > 0) // foward frames
|
||||
if (maxMos > 0) // forward frames
|
||||
{
|
||||
int y0 = m_viewer->rowToY(currentRow + 1);
|
||||
int y1 = m_viewer->rowToY(currentRow + maxMos) + onionDotYPos;
|
||||
p.drawLine(onionDotDiam * 1.5, y0, onionDotDiam * 1.5, y1);
|
||||
int layerAxis = onionCenter_layer;
|
||||
int fromFrameAxis =
|
||||
m_viewer->rowToFrameAxis(currentRow) + onionCenter_frame;
|
||||
int toFrameAxis =
|
||||
m_viewer->rowToFrameAxis(currentRow + maxMos) + onionCenter_frame;
|
||||
QLine verticalLine = m_viewer->orientation()->verticalLine(
|
||||
layerAxis, NumberRange(fromFrameAxis, toFrameAxis));
|
||||
if (m_viewer->orientation()->isVerticalTimeline())
|
||||
p.drawLine(verticalLine.x1() + 1, verticalLine.y1() + 10, verticalLine.x2() + 1, verticalLine.y2() - 4);
|
||||
else
|
||||
p.drawLine(verticalLine.x1() + 10, verticalLine.y1() + 1, verticalLine.x2() - 4, verticalLine.y2() + 1);
|
||||
}
|
||||
|
||||
// Draw onion skin main handle
|
||||
QPoint handleTopLeft = m_viewer->positionToXY(CellPosition(currentRow, 0));
|
||||
QRect handleRect = onionRect.translated(handleTopLeft);
|
||||
int angle180 = 16 * 180;
|
||||
int turn =
|
||||
m_viewer->orientation()->dimension(PredefinedDimension::ONION_TURN) * 16;
|
||||
p.setBrush(QBrush(backColor));
|
||||
p.drawChord(handleRect, turn, angle180);
|
||||
p.setBrush(QBrush(frontColor));
|
||||
p.drawChord(handleRect, turn + angle180, angle180);
|
||||
|
||||
// draw onion skin dots
|
||||
p.setPen(Qt::red);
|
||||
for (int i = 0; i < mosCount; i++) {
|
||||
|
@ -341,13 +360,16 @@ void RowArea::drawOnionSkinSelection(QPainter &p) {
|
|||
int mos = osMask.getMos(i);
|
||||
// skip drawing if the frame is under the mouse cursor
|
||||
if (m_showOnionToSet == Mos && currentRow + mos == m_row) continue;
|
||||
int y = m_viewer->rowToY(currentRow + mos) + onionDotYPos;
|
||||
|
||||
if (osMask.isEnabled())
|
||||
p.setBrush(mos < 0 ? backColor : frontColor);
|
||||
else
|
||||
p.setBrush(Qt::NoBrush);
|
||||
p.drawEllipse(onionDotDiam, y, onionDotDiam, onionDotDiam);
|
||||
QPoint topLeft = m_viewer->positionToXY(CellPosition(currentRow + mos, 0));
|
||||
QRect dotRect = m_viewer->orientation()
|
||||
->rect(PredefinedRect::ONION_DOT)
|
||||
.translated(topLeft);
|
||||
p.drawEllipse(dotRect);
|
||||
}
|
||||
|
||||
//-- draw fixed onions
|
||||
|
@ -356,22 +378,29 @@ void RowArea::drawOnionSkinSelection(QPainter &p) {
|
|||
if (fos == currentRow) continue;
|
||||
// skip drawing if the frame is under the mouse cursor
|
||||
if (m_showOnionToSet == Fos && fos == m_row) continue;
|
||||
int y = m_viewer->rowToY(fos) + onionDotYPos;
|
||||
|
||||
if (osMask.isEnabled())
|
||||
p.setBrush(QBrush(QColor(0, 255, 255, 128)));
|
||||
else
|
||||
p.setBrush(Qt::NoBrush);
|
||||
p.drawEllipse(0, y, onionDotDiam, onionDotDiam);
|
||||
QPoint topLeft = m_viewer->positionToXY(CellPosition(fos, 0));
|
||||
QRect dotRect = m_viewer->orientation()
|
||||
->rect(PredefinedRect::ONION_DOT_FIXED)
|
||||
.translated(topLeft);
|
||||
p.drawEllipse(dotRect);
|
||||
}
|
||||
|
||||
//-- draw highlighted onion
|
||||
//-- onion placement hint under mouse
|
||||
if (m_showOnionToSet != None) {
|
||||
int y = m_viewer->rowToY(m_row) + onionDotYPos;
|
||||
int xPos = (m_showOnionToSet == Fos) ? 0 : onionDotDiam;
|
||||
p.setPen(QColor(255, 128, 0));
|
||||
p.setBrush(QBrush(QColor(255, 255, 0, 200)));
|
||||
p.drawEllipse(xPos, y, onionDotDiam, onionDotDiam);
|
||||
p.setBrush(QBrush(QColor(255, 255, 0)));
|
||||
QPoint topLeft = m_viewer->positionToXY(CellPosition(m_row, 0));
|
||||
QRect dotRect =
|
||||
m_viewer->orientation()
|
||||
->rect(m_showOnionToSet == Fos ? PredefinedRect::ONION_DOT_FIXED
|
||||
: PredefinedRect::ONION_DOT)
|
||||
.translated(topLeft);
|
||||
p.drawEllipse(dotRect);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -416,7 +445,8 @@ void RowArea::drawPinnedCenterKeys(QPainter &p, int r0, int r1) {
|
|||
int columnCount = xsh->getColumnCount();
|
||||
int prev_pinnedCol = -2;
|
||||
|
||||
QRect keyRect(30, 5, 10, 10);
|
||||
QRect keyRect =
|
||||
m_viewer->orientation()->rect(PredefinedRect::PINNED_CENTER_KEY);
|
||||
p.setPen(Qt::black);
|
||||
|
||||
r1 = (r1 < xsh->getFrameCount() - 1) ? xsh->getFrameCount() - 1 : r1;
|
||||
|
@ -430,21 +460,22 @@ void RowArea::drawPinnedCenterKeys(QPainter &p, int r0, int r1) {
|
|||
if (tmp_pinnedCol != prev_pinnedCol) {
|
||||
prev_pinnedCol = tmp_pinnedCol;
|
||||
if (r != r0 - 1) {
|
||||
if (m_pos.x() >= 30 && m_pos.x() <= 40 && m_row == r)
|
||||
QPoint mouseInCell = m_pos - m_viewer->positionToXY(CellPosition(r, 0));
|
||||
if (keyRect.contains(mouseInCell))
|
||||
p.setBrush(QColor(30, 210, 255));
|
||||
else
|
||||
p.setBrush(QColor(0, 175, 255));
|
||||
|
||||
int y = m_viewer->rowToY(r);
|
||||
QRect tmpKeyRect = keyRect.translated(0, y);
|
||||
p.drawRect(tmpKeyRect);
|
||||
QPoint topLeft = m_viewer->positionToXY(CellPosition(r, 0));
|
||||
QRect adjusted = keyRect.translated(topLeft);
|
||||
p.drawRect(adjusted);
|
||||
|
||||
QFont font = p.font();
|
||||
font.setPixelSize(8);
|
||||
font.setBold(false);
|
||||
p.setFont(font);
|
||||
p.drawText(
|
||||
tmpKeyRect, Qt::AlignCenter,
|
||||
adjusted, Qt::AlignCenter,
|
||||
QString::number((tmp_pinnedCol == -1) ? ancestorId.getIndex() + 1
|
||||
: tmp_pinnedCol + 1));
|
||||
}
|
||||
|
@ -459,9 +490,10 @@ void RowArea::paintEvent(QPaintEvent *event) {
|
|||
|
||||
QPainter p(this);
|
||||
|
||||
int r0, r1; // range di righe visibili
|
||||
r0 = m_viewer->yToRow(toBeUpdated.top());
|
||||
r1 = m_viewer->yToRow(toBeUpdated.bottom());
|
||||
CellRange cellRange = m_viewer->xyRectToRange(toBeUpdated);
|
||||
int r0, r1; // range of visible rows
|
||||
r0 = cellRange.from().frame();
|
||||
r1 = cellRange.to().frame();
|
||||
|
||||
p.setClipRect(toBeUpdated);
|
||||
|
||||
|
@ -487,6 +519,8 @@ void RowArea::paintEvent(QPaintEvent *event) {
|
|||
//-----------------------------------------------------------------------------
|
||||
|
||||
void RowArea::mousePressEvent(QMouseEvent *event) {
|
||||
const Orientation *o = m_viewer->orientation();
|
||||
|
||||
m_viewer->setQtModifiers(event->modifiers());
|
||||
if (event->button() == Qt::LeftButton) {
|
||||
bool frameAreaIsClicked = false;
|
||||
|
@ -496,22 +530,28 @@ void RowArea::mousePressEvent(QMouseEvent *event) {
|
|||
TPoint pos(event->pos().x(), event->pos().y());
|
||||
int currentFrame = TApp::instance()->getCurrentFrame()->getFrame();
|
||||
|
||||
int row = m_viewer->yToRow(pos.y);
|
||||
int row = m_viewer->xyToPosition(pos).frame();
|
||||
QPoint topLeft = m_viewer->positionToXY(CellPosition(row, 0));
|
||||
QPoint mouseInCell = event->pos() - topLeft;
|
||||
|
||||
int onionDotDiam = 8;
|
||||
if (Preferences::instance()->isOnionSkinEnabled() &&
|
||||
((row == currentFrame && pos.x < RowHeight + 2) ||
|
||||
(pos.x < onionDotDiam * 2))) {
|
||||
o->rect(PredefinedRect::ONION_AREA).contains(mouseInCell)) {
|
||||
if (row == currentFrame) {
|
||||
setDragTool(
|
||||
XsheetGUI::DragTool::makeCurrentFrameModifierTool(m_viewer));
|
||||
frameAreaIsClicked = true;
|
||||
} else if (pos.x <= onionDotDiam)
|
||||
} else if (o->rect(PredefinedRect::ONION_FIXED_DOT_AREA)
|
||||
.contains(mouseInCell))
|
||||
setDragTool(XsheetGUI::DragTool::makeKeyOnionSkinMaskModifierTool(
|
||||
m_viewer, true));
|
||||
else
|
||||
else if (o->rect(PredefinedRect::ONION_DOT_AREA).contains(mouseInCell))
|
||||
setDragTool(XsheetGUI::DragTool::makeKeyOnionSkinMaskModifierTool(
|
||||
m_viewer, false));
|
||||
else {
|
||||
setDragTool(
|
||||
XsheetGUI::DragTool::makeCurrentFrameModifierTool(m_viewer));
|
||||
frameAreaIsClicked = true;
|
||||
}
|
||||
} else {
|
||||
int playR0, playR1, step;
|
||||
XsheetGUI::getPlayRange(playR0, playR1, step);
|
||||
|
@ -527,7 +567,7 @@ void RowArea::mousePressEvent(QMouseEvent *event) {
|
|||
setDragTool(
|
||||
XsheetGUI::DragTool::makeCurrentFrameModifierTool(m_viewer));
|
||||
frameAreaIsClicked = true;
|
||||
} else if (m_xa <= pos.x && pos.x <= m_xa + 10 &&
|
||||
} else if (o->rect(PredefinedRect::PLAY_RANGE).contains(mouseInCell) &&
|
||||
(row == playR0 || row == playR1)) {
|
||||
if (!playRangeEnabled) XsheetGUI::setPlayRange(playR0, playR1, step);
|
||||
setDragTool(XsheetGUI::DragTool::makePlayRangeModifierTool(m_viewer));
|
||||
|
@ -566,24 +606,31 @@ void RowArea::mousePressEvent(QMouseEvent *event) {
|
|||
//-----------------------------------------------------------------------------
|
||||
|
||||
void RowArea::mouseMoveEvent(QMouseEvent *event) {
|
||||
const Orientation *o = m_viewer->orientation();
|
||||
m_viewer->setQtModifiers(event->modifiers());
|
||||
QPoint pos = event->pos();
|
||||
|
||||
// pan by middle-drag
|
||||
if (m_isPanning) {
|
||||
QPoint delta = m_pos - pos;
|
||||
delta.setX(0);
|
||||
m_viewer->scroll(delta);
|
||||
if (o->isVerticalTimeline())
|
||||
delta.setX(0);
|
||||
else
|
||||
delta.setY(0);
|
||||
m_viewer->scroll(delta);
|
||||
return;
|
||||
}
|
||||
|
||||
m_row = m_viewer->yToRow(pos.y());
|
||||
m_row = m_viewer->xyToPosition(pos).frame();
|
||||
int x = pos.x();
|
||||
|
||||
if ((event->buttons() & Qt::LeftButton) != 0 &&
|
||||
!visibleRegion().contains(pos)) {
|
||||
QRect bounds = visibleRegion().boundingRect();
|
||||
m_viewer->setAutoPanSpeed(bounds, QPoint(bounds.left(), pos.y()));
|
||||
if(o->isVerticalTimeline())
|
||||
m_viewer->setAutoPanSpeed(bounds, QPoint(bounds.left(), pos.y()));
|
||||
else
|
||||
m_viewer->setAutoPanSpeed(bounds, QPoint(pos.x(), bounds.top()));
|
||||
} else
|
||||
m_viewer->stopAutoPan();
|
||||
|
||||
|
@ -596,14 +643,15 @@ void RowArea::mouseMoveEvent(QMouseEvent *event) {
|
|||
if (getDragTool()) return;
|
||||
|
||||
int currentRow = TApp::instance()->getCurrentFrame()->getFrame();
|
||||
int row = m_viewer->yToRow(m_pos.y());
|
||||
int row = m_viewer->xyToPosition(m_pos).frame();
|
||||
QPoint mouseInCell =
|
||||
event->pos() - m_viewer->positionToXY(CellPosition(row, 0));
|
||||
if (row < 0) return;
|
||||
// "decide" se mostrare la possibilita' di settare l'onion skin
|
||||
if (Preferences::instance()->isOnionSkinEnabled()) {
|
||||
int onionDotDiam = 8;
|
||||
if (x <= onionDotDiam && row != currentRow)
|
||||
// whether to show ability to set onion marks
|
||||
if (Preferences::instance()->isOnionSkinEnabled() && row != currentRow) {
|
||||
if (o->rect(PredefinedRect::ONION_FIXED_DOT_AREA).contains(mouseInCell))
|
||||
m_showOnionToSet = Fos;
|
||||
else if (x <= onionDotDiam * 2 && row != currentRow)
|
||||
else if (o->rect(PredefinedRect::ONION_DOT_AREA).contains(mouseInCell))
|
||||
m_showOnionToSet = Mos;
|
||||
}
|
||||
|
||||
|
@ -612,7 +660,7 @@ void RowArea::mouseMoveEvent(QMouseEvent *event) {
|
|||
bool isRootBonePinned;
|
||||
int pinnedCenterColumnId = -1;
|
||||
if (TApp::instance()->getCurrentTool()->getTool()->getName() == T_Skeleton &&
|
||||
x >= 30 && x <= 40) {
|
||||
o->rect(PredefinedRect::PINNED_CENTER_KEY).contains(mouseInCell)) {
|
||||
int col = m_viewer->getCurrentColumn();
|
||||
TXsheet *xsh = m_viewer->getXsheet();
|
||||
if (col >= 0 && xsh && !xsh->isColumnEmpty(col)) {
|
||||
|
@ -635,27 +683,27 @@ void RowArea::mouseMoveEvent(QMouseEvent *event) {
|
|||
|
||||
update();
|
||||
|
||||
int y0 = m_viewer->rowToY(m_r0);
|
||||
int y1 = m_viewer->rowToY(m_r1 + 1) - 12;
|
||||
QPolygon startArrow, endArrow;
|
||||
startArrow << QPoint(m_xa, y0 + 1) << QPoint(m_xa + 10, y0 + 1)
|
||||
<< QPoint(m_xa, y0 + 11);
|
||||
endArrow << QPoint(m_xa, y1 + 1) << QPoint(m_xa + 10, y1 + 11)
|
||||
<< QPoint(m_xa, y1 + 11);
|
||||
QPoint base0 = m_viewer->positionToXY(CellPosition(m_r0, 0));
|
||||
QPoint base1 = m_viewer->positionToXY(CellPosition(m_r1, 0));
|
||||
QPainterPath startArrow =
|
||||
o->path(PredefinedPath::BEGIN_PLAY_RANGE).translated(base0);
|
||||
QPainterPath endArrow =
|
||||
o->path(PredefinedPath::END_PLAY_RANGE).translated(base1);
|
||||
|
||||
if (startArrow.containsPoint(m_pos, Qt::OddEvenFill))
|
||||
if (startArrow.contains(m_pos))
|
||||
m_tooltip = tr("Playback Start Marker");
|
||||
else if (endArrow.containsPoint(m_pos, Qt::OddEvenFill))
|
||||
else if (endArrow.contains(m_pos))
|
||||
m_tooltip = tr("Playback End Marker");
|
||||
else if (isOnPinnedCenterKey)
|
||||
m_tooltip = tr("Pinned Center : Col%1%2")
|
||||
.arg(pinnedCenterColumnId + 1)
|
||||
.arg((isRootBonePinned) ? " (Root)" : "");
|
||||
else if (row == currentRow) {
|
||||
if (Preferences::instance()->isOnionSkinEnabled() && x < RowHeight + 2)
|
||||
if (Preferences::instance()->isOnionSkinEnabled() &&
|
||||
o->rect(PredefinedRect::ONION).contains(mouseInCell))
|
||||
m_tooltip = tr("Double Click to Toggle Onion Skin");
|
||||
else
|
||||
m_tooltip = tr("Curren Frame");
|
||||
m_tooltip = tr("Current Frame");
|
||||
} else if (m_showOnionToSet == Fos)
|
||||
m_tooltip = tr("Fixed Onion Skin Toggle");
|
||||
else if (m_showOnionToSet == Mos)
|
||||
|
@ -674,7 +722,7 @@ void RowArea::mouseReleaseEvent(QMouseEvent *event) {
|
|||
|
||||
TPoint pos(event->pos().x(), event->pos().y());
|
||||
|
||||
int row = m_viewer->yToRow(pos.y);
|
||||
int row = m_viewer->xyToPosition(pos).frame();
|
||||
if (m_playRangeActiveInMousePress && row == m_mousePressRow &&
|
||||
(13 <= pos.x && pos.x <= 26 && (row == m_r0 || row == m_r1)))
|
||||
onRemoveMarkers();
|
||||
|
@ -756,11 +804,15 @@ int RowArea::getNonEmptyCell(int row, int column, Direction direction) {
|
|||
|
||||
void RowArea::mouseDoubleClickEvent(QMouseEvent *event) {
|
||||
int currentFrame = TApp::instance()->getCurrentFrame()->getFrame();
|
||||
int row = m_viewer->yToRow(event->pos().y());
|
||||
int row = m_viewer->xyToPosition(event->pos()).frame();
|
||||
QPoint mouseInCell =
|
||||
event->pos() - m_viewer->positionToXY(CellPosition(row, 0));
|
||||
if (TApp::instance()->getCurrentFrame()->isEditingScene() &&
|
||||
event->buttons() & Qt::LeftButton &&
|
||||
Preferences::instance()->isOnionSkinEnabled() && row == currentFrame &&
|
||||
event->pos().x() < RowHeight + 2) {
|
||||
m_viewer->orientation()
|
||||
->rect(PredefinedRect::ONION)
|
||||
.contains(mouseInCell)) {
|
||||
TOnionSkinMaskHandle *osmh = TApp::instance()->getCurrentOnionSkin();
|
||||
OnionSkinMask osm = osmh->getOnionSkinMask();
|
||||
osm.enable(!osm.isEnabled());
|
||||
|
|
|
@ -21,7 +21,6 @@ class DragTool;
|
|||
class RowArea final : public QWidget {
|
||||
Q_OBJECT
|
||||
XsheetViewer *m_viewer;
|
||||
int m_xa;
|
||||
int m_row;
|
||||
|
||||
enum ShowOnionToSetFlag {
|
||||
|
|
|
@ -152,6 +152,7 @@ set(MOC_HEADERS
|
|||
sandor_fxs/YOMBParam.h
|
||||
texturemanager.h
|
||||
imagebuilders.h
|
||||
../include/orientation.h
|
||||
)
|
||||
|
||||
set(HEADERS ${MOC_HEADERS})
|
||||
|
@ -161,6 +162,7 @@ set(SOURCES
|
|||
autoclose.cpp
|
||||
autopos.cpp
|
||||
captureparameters.cpp
|
||||
cellpositionratio.cpp
|
||||
childstack.cpp
|
||||
cleanupcolorstyles.cpp
|
||||
cleanuppalette.cpp
|
||||
|
@ -193,6 +195,7 @@ set(SOURCES
|
|||
Naa2TlvConverter.cpp
|
||||
observer.cpp
|
||||
onionskinmask.cpp
|
||||
orientation.cpp
|
||||
outputproperties.cpp
|
||||
preferences.cpp
|
||||
rasterbrush.cpp
|
||||
|
|
66
toonz/sources/toonzlib/cellpositionratio.cpp
Normal file
66
toonz/sources/toonzlib/cellpositionratio.cpp
Normal file
|
@ -0,0 +1,66 @@
|
|||
#include "toonz/cellpositionratio.h"
|
||||
|
||||
#include <stdexcept>
|
||||
#include <algorithm>
|
||||
|
||||
// Euclid's algorithm
|
||||
int greatestCommonDivisor(int a, int b) {
|
||||
a = std::abs(a);
|
||||
b = std::abs(b);
|
||||
int c = std::max(a, b);
|
||||
int d = std::min(a, b);
|
||||
while (d) {
|
||||
int q = c / d;
|
||||
int r = c % d;
|
||||
c = d;
|
||||
d = r;
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
int leastCommonMultiple(int a, int b) {
|
||||
return a * b / greatestCommonDivisor(a, b);
|
||||
}
|
||||
|
||||
void Ratio::normalize() {
|
||||
int gcd = greatestCommonDivisor(m_num, m_denom);
|
||||
if (m_denom < 0) gcd = -gcd;
|
||||
m_num /= gcd;
|
||||
m_denom /= gcd;
|
||||
}
|
||||
|
||||
Ratio Ratio::normalized() const {
|
||||
Ratio copy(*this);
|
||||
copy.normalize();
|
||||
return copy;
|
||||
}
|
||||
|
||||
Ratio::Ratio(int num, int denom) : m_num(num), m_denom(denom) {
|
||||
if (!denom) throw std::runtime_error("ratio with denominator == 0");
|
||||
normalize();
|
||||
}
|
||||
|
||||
Ratio operator*(const Ratio &a, const Ratio &b) {
|
||||
return Ratio(a.m_num * b.m_num, a.m_denom * b.m_denom);
|
||||
}
|
||||
Ratio operator/(const Ratio &a, const Ratio &b) {
|
||||
return Ratio(a.m_num * b.m_denom, a.m_denom * b.m_num);
|
||||
}
|
||||
|
||||
Ratio operator+(const Ratio &a, const Ratio &b) {
|
||||
int gcd = greatestCommonDivisor(a.m_denom, b.m_denom);
|
||||
int denom = a.m_denom * b.m_denom / gcd;
|
||||
int aMult = b.m_denom * gcd;
|
||||
int bMult = a.m_denom * gcd;
|
||||
return Ratio(a.m_num * aMult + b.m_num * bMult, denom);
|
||||
}
|
||||
|
||||
Ratio operator-(const Ratio &a, const Ratio &b) {
|
||||
int gcd = greatestCommonDivisor(a.m_denom, b.m_denom);
|
||||
int denom = a.m_denom * b.m_denom / gcd;
|
||||
int aMult = b.m_denom * gcd;
|
||||
int bMult = a.m_denom * gcd;
|
||||
return Ratio(a.m_num * aMult - b.m_num * bMult, denom);
|
||||
}
|
||||
|
||||
int operator*(const Ratio &a, int b) { return a.m_num * b / a.m_denom; }
|
|
@ -8,37 +8,40 @@
|
|||
// STD includss
|
||||
#include <assert.h>
|
||||
|
||||
//=============================================================================
|
||||
|
||||
const int colWidth = 74;
|
||||
const int colSkip = 9;
|
||||
|
||||
//=============================================================================
|
||||
// ColumnFan
|
||||
|
||||
ColumnFan::ColumnFan() : m_firstFreePos(0) {}
|
||||
ColumnFan::ColumnFan() : m_firstFreePos(0), m_unfolded(74), m_folded(9) {}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void ColumnFan::setDimension(int unfolded) {
|
||||
m_unfolded = unfolded;
|
||||
// folded always 9
|
||||
update();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void ColumnFan::update() {
|
||||
int lastPos = -colWidth;
|
||||
int lastPos = -m_unfolded;
|
||||
bool lastActive = true;
|
||||
int m = m_columns.size();
|
||||
int i;
|
||||
for (i = 0; i < m; i++) {
|
||||
bool active = m_columns[i].m_active;
|
||||
if (lastActive)
|
||||
lastPos += colWidth;
|
||||
lastPos += m_unfolded;
|
||||
else if (active)
|
||||
lastPos += colSkip;
|
||||
lastPos += m_folded;
|
||||
m_columns[i].m_pos = lastPos;
|
||||
lastActive = active;
|
||||
}
|
||||
m_firstFreePos = lastPos + (lastActive ? colWidth : colSkip);
|
||||
m_firstFreePos = lastPos + (lastActive ? m_unfolded : m_folded);
|
||||
m_table.clear();
|
||||
for (i = 0; i < m; i++)
|
||||
if (m_columns[i].m_active)
|
||||
m_table[m_columns[i].m_pos + colWidth - 1] = i;
|
||||
m_table[m_columns[i].m_pos + m_unfolded - 1] = i;
|
||||
else if (i + 1 < m && m_columns[i + 1].m_active)
|
||||
m_table[m_columns[i + 1].m_pos - 1] = i;
|
||||
else if (i + 1 == m)
|
||||
|
@ -47,24 +50,24 @@ void ColumnFan::update() {
|
|||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
int ColumnFan::xToCol(int x) const {
|
||||
if (x < m_firstFreePos) {
|
||||
std::map<int, int>::const_iterator it = m_table.lower_bound(x);
|
||||
int ColumnFan::layerAxisToCol(int coord) const {
|
||||
if (coord < m_firstFreePos) {
|
||||
std::map<int, int>::const_iterator it = m_table.lower_bound(coord);
|
||||
if (it == m_table.end()) return -3;
|
||||
assert(it != m_table.end());
|
||||
return it->second;
|
||||
} else
|
||||
return m_columns.size() + (x - m_firstFreePos) / colWidth;
|
||||
return m_columns.size() + (coord - m_firstFreePos) / m_unfolded;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
int ColumnFan::colToX(int col) const {
|
||||
int ColumnFan::colToLayerAxis(int col) const {
|
||||
int m = m_columns.size();
|
||||
if (col >= 0 && col < m)
|
||||
return m_columns[col].m_pos;
|
||||
else
|
||||
return m_firstFreePos + (col - m) * colWidth;
|
||||
return m_firstFreePos + (col - m) * m_unfolded;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -106,7 +109,15 @@ bool ColumnFan::isEmpty() const { return m_columns.empty(); }
|
|||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void ColumnFan::saveData(TOStream &os) {
|
||||
void ColumnFan::copyFoldedStateFrom(const ColumnFan &from) {
|
||||
for (int i = 0, n = (int)from.m_columns.size(); i < n; i++)
|
||||
if (!from.isActive(i)) deactivate(i);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void ColumnFan::saveData(
|
||||
TOStream &os) { // only saves indices of folded columns
|
||||
int index, n = (int)m_columns.size();
|
||||
for (index = 0; index < n;) {
|
||||
while (index < n && m_columns[index].m_active) index++;
|
||||
|
|
706
toonz/sources/toonzlib/orientation.cpp
Normal file
706
toonz/sources/toonzlib/orientation.cpp
Normal file
|
@ -0,0 +1,706 @@
|
|||
#include "orientation.h"
|
||||
#include "toonz/columnfan.h"
|
||||
|
||||
#include <QPainterPath>
|
||||
#include <QBoxLayout>
|
||||
#include <math.h>
|
||||
|
||||
using std::pair;
|
||||
|
||||
namespace {
|
||||
const int KEY_ICON_WIDTH = 11;
|
||||
const int KEY_ICON_HEIGHT = 13;
|
||||
const int EASE_TRIANGLE_SIZE = 4;
|
||||
const int PLAY_MARKER_SIZE = 10;
|
||||
const int ONION_SIZE = 19;
|
||||
const int ONION_DOT_SIZE = 8;
|
||||
const int PINNED_SIZE = 10;
|
||||
}
|
||||
|
||||
class TopToBottomOrientation : public Orientation {
|
||||
const int CELL_WIDTH = 74;
|
||||
const int CELL_HEIGHT = 20;
|
||||
const int CELL_DRAG_WIDTH = 7;
|
||||
const int EXTENDER_WIDTH = 18;
|
||||
const int EXTENDER_HEIGHT = 8;
|
||||
const int SOUND_PREVIEW_WIDTH = 7;
|
||||
const int LAYER_HEADER_HEIGHT = CELL_HEIGHT * 3 + 60;
|
||||
const int FOLDED_LAYER_HEADER_HEIGHT = LAYER_HEADER_HEIGHT;
|
||||
const int FOLDED_LAYER_HEADER_WIDTH = 8;
|
||||
const int FRAME_HEADER_WIDTH = CELL_WIDTH;
|
||||
const int PLAY_RANGE_X = FRAME_HEADER_WIDTH / 2 - PLAY_MARKER_SIZE;
|
||||
const int ONION_X = 0, ONION_Y = 0;
|
||||
const int ICON_WIDTH = CELL_HEIGHT;
|
||||
|
||||
public:
|
||||
TopToBottomOrientation();
|
||||
|
||||
virtual CellPosition xyToPosition(const QPoint &xy,
|
||||
const ColumnFan *fan) const override;
|
||||
virtual QPoint positionToXY(const CellPosition &position,
|
||||
const ColumnFan *fan) const override;
|
||||
virtual CellPositionRatio xyToPositionRatio(const QPoint &xy) const override;
|
||||
virtual QPoint positionRatioToXY(
|
||||
const CellPositionRatio &ratio) const override;
|
||||
|
||||
virtual int colToLayerAxis(int layer, const ColumnFan *fan) const override;
|
||||
virtual int rowToFrameAxis(int frame) const override;
|
||||
|
||||
virtual QPoint frameLayerToXY(int frameAxis, int layerAxis) const override;
|
||||
virtual int layerAxis(const QPoint &xy) const override;
|
||||
virtual int frameAxis(const QPoint &xy) const override;
|
||||
|
||||
virtual NumberRange layerSide(const QRect &area) const override;
|
||||
virtual NumberRange frameSide(const QRect &area) const override;
|
||||
virtual QPoint topRightCorner(const QRect &area) const override;
|
||||
|
||||
virtual CellPosition arrowShift(int direction) const override;
|
||||
|
||||
virtual QString name() const override { return "TopToBottom"; }
|
||||
virtual QString caption() const override { return "Xsheet"; }
|
||||
virtual const Orientation *next() const override {
|
||||
return Orientations::leftToRight();
|
||||
}
|
||||
|
||||
virtual bool isVerticalTimeline() const override { return true; }
|
||||
virtual bool flipVolume() const override { return true; }
|
||||
|
||||
virtual int cellWidth() const override { return CELL_WIDTH; }
|
||||
virtual int cellHeight() const override { return CELL_HEIGHT; }
|
||||
};
|
||||
|
||||
class LeftToRightOrientation : public Orientation {
|
||||
const int CELL_WIDTH = 50;
|
||||
const int CELL_HEIGHT = 20;
|
||||
const int CELL_DRAG_HEIGHT = 5;
|
||||
const int EXTENDER_WIDTH = 8;
|
||||
const int EXTENDER_HEIGHT = 12;
|
||||
const int SOUND_PREVIEW_HEIGHT = 6;
|
||||
const int FRAME_HEADER_HEIGHT = 50;
|
||||
const int ONION_X = (CELL_WIDTH - ONION_SIZE) / 2, ONION_Y = 0;
|
||||
const int PLAY_RANGE_Y = ONION_SIZE;
|
||||
const int ICON_WIDTH = CELL_HEIGHT;
|
||||
const int ICON_OFFSET = ICON_WIDTH;
|
||||
const int ICONS_WIDTH = ICON_OFFSET * 3; // 88
|
||||
const int LAYER_NUMBER_WIDTH = 20;
|
||||
const int LAYER_NAME_WIDTH = 170;
|
||||
const int LAYER_HEADER_WIDTH =
|
||||
ICONS_WIDTH + LAYER_NUMBER_WIDTH + LAYER_NAME_WIDTH;
|
||||
const int FOLDED_LAYER_HEADER_HEIGHT = 8;
|
||||
const int FOLDED_LAYER_HEADER_WIDTH = LAYER_HEADER_WIDTH;
|
||||
|
||||
public:
|
||||
LeftToRightOrientation();
|
||||
|
||||
virtual CellPosition xyToPosition(const QPoint &xy,
|
||||
const ColumnFan *fan) const override;
|
||||
virtual QPoint positionToXY(const CellPosition &position,
|
||||
const ColumnFan *fan) const override;
|
||||
virtual CellPositionRatio xyToPositionRatio(const QPoint &xy) const override;
|
||||
virtual QPoint positionRatioToXY(
|
||||
const CellPositionRatio &ratio) const override;
|
||||
|
||||
virtual int colToLayerAxis(int layer, const ColumnFan *fan) const override;
|
||||
virtual int rowToFrameAxis(int frame) const override;
|
||||
|
||||
virtual QPoint frameLayerToXY(int frameAxis, int layerAxis) const override;
|
||||
virtual int layerAxis(const QPoint &xy) const override;
|
||||
virtual int frameAxis(const QPoint &xy) const override;
|
||||
|
||||
virtual NumberRange layerSide(const QRect &area) const override;
|
||||
virtual NumberRange frameSide(const QRect &area) const override;
|
||||
virtual QPoint topRightCorner(const QRect &area) const override;
|
||||
|
||||
virtual CellPosition arrowShift(int direction) const override;
|
||||
|
||||
virtual QString name() const override { return "LeftToRight"; }
|
||||
virtual QString caption() const override { return "Timeline"; }
|
||||
virtual const Orientation *next() const override {
|
||||
return Orientations::topToBottom();
|
||||
}
|
||||
|
||||
virtual bool isVerticalTimeline() const override { return false; }
|
||||
virtual bool flipVolume() const override { return false; }
|
||||
|
||||
virtual int cellWidth() const override { return CELL_WIDTH; }
|
||||
virtual int cellHeight() const override { return CELL_HEIGHT; }
|
||||
};
|
||||
|
||||
/// -------------------------------------------------------------------------------
|
||||
|
||||
int NumberRange::weight(double toWeight) const { // weight ranging 0..1
|
||||
return _from + (_to - _from) * toWeight;
|
||||
}
|
||||
|
||||
NumberRange NumberRange::adjusted(int addFrom, int addTo) const {
|
||||
return NumberRange(_from + addFrom, _to + addTo);
|
||||
}
|
||||
|
||||
double NumberRange::ratio(int at) const {
|
||||
double result = ((double)at - _from) / (_to - _from);
|
||||
if (result < 0) result = 0;
|
||||
if (result > 1) result = 1;
|
||||
return result;
|
||||
}
|
||||
|
||||
/// -------------------------------------------------------------------------------
|
||||
|
||||
// const int Orientations::COUNT = 2;
|
||||
|
||||
Orientations::Orientations() : _topToBottom(nullptr), _leftToRight(nullptr) {
|
||||
_topToBottom = new TopToBottomOrientation();
|
||||
_leftToRight = new LeftToRightOrientation();
|
||||
|
||||
_all.push_back(_topToBottom);
|
||||
_all.push_back(_leftToRight);
|
||||
}
|
||||
Orientations::~Orientations() {
|
||||
delete _topToBottom;
|
||||
_topToBottom = nullptr;
|
||||
delete _leftToRight;
|
||||
_leftToRight = nullptr;
|
||||
}
|
||||
|
||||
const Orientations &Orientations::instance() {
|
||||
static Orientations singleton;
|
||||
return singleton;
|
||||
}
|
||||
|
||||
const Orientation *Orientations::topToBottom() {
|
||||
return instance()._topToBottom;
|
||||
}
|
||||
const Orientation *Orientations::leftToRight() {
|
||||
return instance()._leftToRight;
|
||||
}
|
||||
const vector<const Orientation *> &Orientations::all() {
|
||||
return instance()._all;
|
||||
}
|
||||
const Orientation *Orientations::byName(const QString &name) {
|
||||
vector<const Orientation *> m_all = all();
|
||||
for (auto it = m_all.begin(); it != m_all.end(); it++)
|
||||
if ((*it)->name() == name) return *it;
|
||||
throw std::runtime_error(
|
||||
(QString("no such orientation: ") + name).toStdString().c_str());
|
||||
}
|
||||
|
||||
/// -------------------------------------------------------------------------------
|
||||
|
||||
QLine Orientation::verticalLine(int layerAxis,
|
||||
const NumberRange &frameAxis) const {
|
||||
QPoint first = frameLayerToXY(frameAxis.from(), layerAxis);
|
||||
QPoint second = frameLayerToXY(frameAxis.to(), layerAxis);
|
||||
return QLine(first, second);
|
||||
}
|
||||
QLine Orientation::horizontalLine(int frameAxis,
|
||||
const NumberRange &layerAxis) const {
|
||||
QPoint first = frameLayerToXY(frameAxis, layerAxis.from());
|
||||
QPoint second = frameLayerToXY(frameAxis, layerAxis.to());
|
||||
return QLine(first, second);
|
||||
}
|
||||
QRect Orientation::frameLayerRect(const NumberRange &frameAxis,
|
||||
const NumberRange &layerAxis) const {
|
||||
QPoint topLeft = frameLayerToXY(frameAxis.from(), layerAxis.from());
|
||||
QPoint bottomRight = frameLayerToXY(frameAxis.to(), layerAxis.to());
|
||||
return QRect(topLeft, bottomRight);
|
||||
}
|
||||
|
||||
QRect Orientation::foldedRectangle(int layerAxis, const NumberRange &frameAxis,
|
||||
int i) const {
|
||||
QPoint topLeft = frameLayerToXY(frameAxis.from(), layerAxis + 1 + i * 3);
|
||||
QPoint size = frameLayerToXY(frameAxis.length(), 2);
|
||||
return QRect(topLeft, QSize(size.x(), size.y()));
|
||||
}
|
||||
QLine Orientation::foldedRectangleLine(int layerAxis,
|
||||
const NumberRange &frameAxis,
|
||||
int i) const {
|
||||
return verticalLine(layerAxis + i * 3, frameAxis);
|
||||
}
|
||||
|
||||
void Orientation::addRect(PredefinedRect which, const QRect &rect) {
|
||||
_rects.insert(pair<PredefinedRect, QRect>(which, rect));
|
||||
}
|
||||
void Orientation::addLine(PredefinedLine which, const QLine &line) {
|
||||
_lines.insert(pair<PredefinedLine, QLine>(which, line));
|
||||
}
|
||||
void Orientation::addDimension(PredefinedDimension which, int dimension) {
|
||||
_dimensions.insert(pair<PredefinedDimension, int>(which, dimension));
|
||||
}
|
||||
void Orientation::addPath(PredefinedPath which, const QPainterPath &path) {
|
||||
_paths.insert(pair<PredefinedPath, QPainterPath>(which, path));
|
||||
}
|
||||
void Orientation::addPoint(PredefinedPoint which, const QPoint &point) {
|
||||
_points.insert(pair<PredefinedPoint, QPoint>(which, point));
|
||||
}
|
||||
void Orientation::addRange(PredefinedRange which, const NumberRange &range) {
|
||||
_ranges.insert(pair<PredefinedRange, NumberRange>(which, range));
|
||||
}
|
||||
|
||||
/// -------------------------------------------------------------------------------
|
||||
|
||||
TopToBottomOrientation::TopToBottomOrientation() {
|
||||
//
|
||||
// Area rectangles
|
||||
//
|
||||
|
||||
// Cell viewer
|
||||
QRect cellRect(0, 0, CELL_WIDTH, CELL_HEIGHT);
|
||||
addRect(PredefinedRect::CELL, cellRect);
|
||||
addRect(PredefinedRect::DRAG_HANDLE_CORNER, QRect(0, 0, CELL_DRAG_WIDTH, CELL_HEIGHT));
|
||||
QRect keyRect(CELL_WIDTH - KEY_ICON_WIDTH, (CELL_HEIGHT - KEY_ICON_HEIGHT) / 2, KEY_ICON_WIDTH, KEY_ICON_HEIGHT);
|
||||
addRect(PredefinedRect::KEY_ICON, keyRect);
|
||||
QRect nameRect = cellRect.adjusted(8, 0, -6, 0);
|
||||
addRect(PredefinedRect::CELL_NAME, nameRect);
|
||||
addRect(PredefinedRect::CELL_NAME_WITH_KEYFRAME, nameRect.adjusted(0, 0, -KEY_ICON_WIDTH, 0));
|
||||
addRect(PredefinedRect::END_EXTENDER, QRect(-EXTENDER_WIDTH - KEY_ICON_WIDTH, 0, EXTENDER_WIDTH, EXTENDER_HEIGHT));
|
||||
addRect(PredefinedRect::BEGIN_EXTENDER, QRect(-EXTENDER_WIDTH - KEY_ICON_WIDTH, -EXTENDER_HEIGHT, EXTENDER_WIDTH, EXTENDER_HEIGHT));
|
||||
addRect(PredefinedRect::KEYFRAME_AREA, QRect(CELL_WIDTH - KEY_ICON_WIDTH, 0, KEY_ICON_WIDTH, CELL_HEIGHT));
|
||||
addRect(PredefinedRect::DRAG_AREA, QRect(0, 0, CELL_DRAG_WIDTH, CELL_HEIGHT));
|
||||
QRect soundRect(CELL_DRAG_WIDTH, 0, CELL_WIDTH - CELL_DRAG_WIDTH - SOUND_PREVIEW_WIDTH, CELL_HEIGHT);
|
||||
addRect(PredefinedRect::SOUND_TRACK, soundRect);
|
||||
addRect(PredefinedRect::PREVIEW_TRACK, QRect(CELL_WIDTH - SOUND_PREVIEW_WIDTH + 1, 0, SOUND_PREVIEW_WIDTH, CELL_HEIGHT));
|
||||
addRect(PredefinedRect::BEGIN_SOUND_EDIT, QRect(CELL_DRAG_WIDTH, 0, CELL_WIDTH - CELL_DRAG_WIDTH, 2));
|
||||
addRect(PredefinedRect::END_SOUND_EDIT, QRect(CELL_DRAG_WIDTH, CELL_HEIGHT - 2, CELL_WIDTH - CELL_DRAG_WIDTH, 2));
|
||||
addRect(PredefinedRect::LOOP_ICON, QRect(keyRect.left(), 0, 10, 11));
|
||||
|
||||
// Note viewer
|
||||
addRect(PredefinedRect::NOTE_AREA, QRect(QPoint(0, 0), QSize(FRAME_HEADER_WIDTH, LAYER_HEADER_HEIGHT - 1)));
|
||||
addRect(PredefinedRect::NOTE_ICON, QRect(QPoint(0, 0), QSize(CELL_WIDTH - 2, CELL_HEIGHT - 2)));
|
||||
addRect(PredefinedRect::LAYER_HEADER_PANEL, QRect(0, 0, -1, -1)); // hide
|
||||
|
||||
// Row viewer
|
||||
addRect(PredefinedRect::FRAME_LABEL, QRect(CELL_WIDTH / 2, 1, CELL_WIDTH / 2, CELL_HEIGHT - 2));
|
||||
addRect(PredefinedRect::FRAME_HEADER, QRect(0, 0, FRAME_HEADER_WIDTH - 1, CELL_HEIGHT));
|
||||
addRect(PredefinedRect::PLAY_RANGE, QRect(PLAY_RANGE_X, 0, PLAY_MARKER_SIZE, CELL_HEIGHT));
|
||||
addRect(PredefinedRect::ONION, QRect(ONION_X + (3 * ONION_DOT_SIZE - ONION_SIZE) / 2, ONION_Y, ONION_SIZE, ONION_SIZE));
|
||||
int adjustOnion = (ONION_SIZE - ONION_DOT_SIZE) / 2;
|
||||
addRect(PredefinedRect::ONION_DOT, QRect(ONION_X + ONION_DOT_SIZE, ONION_Y + adjustOnion, ONION_DOT_SIZE, ONION_DOT_SIZE));
|
||||
addRect(PredefinedRect::ONION_DOT_FIXED, QRect(ONION_X, ONION_Y + adjustOnion, ONION_DOT_SIZE, ONION_DOT_SIZE));
|
||||
addRect(PredefinedRect::ONION_AREA, QRect(ONION_X, ONION_Y, PLAY_RANGE_X, CELL_HEIGHT));
|
||||
addRect(PredefinedRect::ONION_FIXED_DOT_AREA, QRect(ONION_X, ONION_Y, ONION_DOT_SIZE, CELL_HEIGHT));
|
||||
addRect(PredefinedRect::ONION_DOT_AREA, QRect(ONION_X + ONION_DOT_SIZE, ONION_Y, ONION_DOT_SIZE, CELL_HEIGHT));
|
||||
addRect(PredefinedRect::PINNED_CENTER_KEY, QRect((FRAME_HEADER_WIDTH - PINNED_SIZE) / 2, (CELL_HEIGHT - PINNED_SIZE) / 2, PINNED_SIZE, PINNED_SIZE));
|
||||
|
||||
// Column viewer
|
||||
static int INDENT = 9;
|
||||
static int HDRROW1 = 6; // Name/eye
|
||||
static int HDRROW2 = HDRROW1 + CELL_HEIGHT; // lock, preview
|
||||
static int HDRROW3 = HDRROW2 + CELL_HEIGHT + 1; // thumbnail
|
||||
static int HDRROW4 = HDRROW3 + 48; // pegbar, parenthandle
|
||||
|
||||
addRect(PredefinedRect::LAYER_HEADER, QRect(0, 1, CELL_WIDTH, LAYER_HEADER_HEIGHT - 3));
|
||||
addRect(PredefinedRect::DRAG_LAYER, QRect(0, 0, CELL_DRAG_WIDTH, LAYER_HEADER_HEIGHT - 3));
|
||||
addRect(PredefinedRect::FOLDED_LAYER_HEADER, QRect(0, 1, FOLDED_LAYER_HEADER_WIDTH, FOLDED_LAYER_HEADER_HEIGHT - 3));
|
||||
|
||||
addRect(PredefinedRect::RENAME_COLUMN, QRect(0, 6, CELL_WIDTH, CELL_HEIGHT - 3));
|
||||
|
||||
QRect layername(INDENT, HDRROW1, CELL_WIDTH - 11, CELL_HEIGHT - 3);
|
||||
addRect(PredefinedRect::LAYER_NAME, layername);
|
||||
addRect(PredefinedRect::LAYER_NUMBER, QRect(0, 0, -1, -1)); // hide
|
||||
|
||||
QRect eyeArea(INDENT, HDRROW1, CELL_WIDTH - 11, CELL_HEIGHT - 3);
|
||||
addRect(PredefinedRect::EYE_AREA, eyeArea);
|
||||
QRect eye(eyeArea.right() - 18, HDRROW1, 18, 15);
|
||||
addRect(PredefinedRect::EYE, eye);
|
||||
|
||||
QRect previewArea(INDENT, HDRROW2, CELL_WIDTH - 11, CELL_HEIGHT - 3);
|
||||
addRect(PredefinedRect::PREVIEW_LAYER_AREA, previewArea);
|
||||
QRect preview(previewArea.right() - 18, HDRROW2, 18, 15);
|
||||
addRect(PredefinedRect::PREVIEW_LAYER, preview);
|
||||
|
||||
QRect lockArea(INDENT, HDRROW2, 16, 16);
|
||||
addRect(PredefinedRect::LOCK_AREA, lockArea);
|
||||
QRect lock(INDENT, HDRROW2, 16, 16);
|
||||
addRect(PredefinedRect::LOCK, lock);
|
||||
|
||||
QRect thumbnailArea(INDENT, HDRROW3, CELL_WIDTH - 11, 42);
|
||||
addRect(PredefinedRect::THUMBNAIL_AREA, thumbnailArea);
|
||||
QRect thumbnail(INDENT, HDRROW3, CELL_WIDTH - 11, 42);
|
||||
addRect(PredefinedRect::THUMBNAIL, thumbnail);
|
||||
addRect(PredefinedRect::FILTER_COLOR, QRect(thumbnailArea.right() - 14, thumbnailArea.top() + 3, 12, 12));
|
||||
addRect(PredefinedRect::SOUND_ICON, QRect(thumbnailArea.right() - 40, 3 * CELL_HEIGHT + 4, 40, 30));
|
||||
int trackLen = 60;
|
||||
QRect volumeArea(thumbnailArea.left(), thumbnailArea.top() + 1, 29 - CELL_DRAG_WIDTH, trackLen + 7);
|
||||
addRect(PredefinedRect::VOLUME_AREA, volumeArea);
|
||||
QPoint soundTopLeft(volumeArea.left() + 12, volumeArea.top() + 4);
|
||||
addRect(PredefinedRect::VOLUME_TRACK, QRect(soundTopLeft, QSize(3, trackLen)));
|
||||
|
||||
QRect pegbarname(INDENT, HDRROW4, CELL_WIDTH - 11, CELL_HEIGHT - 3);
|
||||
addRect(PredefinedRect::PEGBAR_NAME, pegbarname);
|
||||
addRect(PredefinedRect::PARENT_HANDLE_NAME, QRect(INDENT + pegbarname.width() - 20, HDRROW4, 20, CELL_HEIGHT - 3));
|
||||
|
||||
//
|
||||
// Lines
|
||||
//
|
||||
addLine(PredefinedLine::LOCKED, verticalLine((CELL_DRAG_WIDTH + 1) / 2, NumberRange(0, CELL_HEIGHT)));
|
||||
addLine(PredefinedLine::SEE_MARKER_THROUGH, horizontalLine(0, NumberRange(0, CELL_DRAG_WIDTH)));
|
||||
addLine(PredefinedLine::CONTINUE_LEVEL, verticalLine(CELL_WIDTH / 2, NumberRange(0, CELL_HEIGHT)));
|
||||
addLine(PredefinedLine::CONTINUE_LEVEL_WITH_NAME, verticalLine(CELL_WIDTH - 11, NumberRange(0, CELL_HEIGHT)));
|
||||
addLine(PredefinedLine::EXTENDER_LINE, horizontalLine(0, NumberRange(-EXTENDER_WIDTH - KEY_ICON_WIDTH, 0)));
|
||||
|
||||
//
|
||||
// Dimensions
|
||||
//
|
||||
addDimension(PredefinedDimension::LAYER, CELL_WIDTH);
|
||||
addDimension(PredefinedDimension::FRAME, CELL_HEIGHT);
|
||||
addDimension(PredefinedDimension::INDEX, 0);
|
||||
addDimension(PredefinedDimension::SOUND_AMPLITUDE, int(sqrt(CELL_HEIGHT * soundRect.width()) / 2));
|
||||
addDimension(PredefinedDimension::FRAME_LABEL_ALIGN, Qt::AlignCenter);
|
||||
addDimension(PredefinedDimension::ONION_TURN, 0);
|
||||
addDimension(PredefinedDimension::QBOXLAYOUT_DIRECTION, QBoxLayout::Direction::TopToBottom);
|
||||
addDimension(PredefinedDimension::CENTER_ALIGN, Qt::AlignHCenter);
|
||||
|
||||
//
|
||||
// Paths
|
||||
//
|
||||
QPainterPath corner(QPointF(0, CELL_HEIGHT));
|
||||
corner.lineTo(QPointF(CELL_DRAG_WIDTH, CELL_HEIGHT));
|
||||
corner.lineTo(QPointF(CELL_DRAG_WIDTH, CELL_HEIGHT - CELL_DRAG_WIDTH));
|
||||
corner.lineTo(QPointF(0, CELL_HEIGHT));
|
||||
addPath(PredefinedPath::DRAG_HANDLE_CORNER, corner);
|
||||
|
||||
QPainterPath fromTriangle(QPointF(0, EASE_TRIANGLE_SIZE / 2));
|
||||
fromTriangle.lineTo(QPointF(EASE_TRIANGLE_SIZE, -EASE_TRIANGLE_SIZE / 2));
|
||||
fromTriangle.lineTo(QPointF(-EASE_TRIANGLE_SIZE, -EASE_TRIANGLE_SIZE / 2));
|
||||
fromTriangle.lineTo(QPointF(0, EASE_TRIANGLE_SIZE / 2));
|
||||
fromTriangle.translate(keyRect.center());
|
||||
addPath(PredefinedPath::BEGIN_EASE_TRIANGLE, fromTriangle);
|
||||
|
||||
QPainterPath toTriangle(QPointF(0, -EASE_TRIANGLE_SIZE / 2));
|
||||
toTriangle.lineTo(QPointF(EASE_TRIANGLE_SIZE, EASE_TRIANGLE_SIZE / 2));
|
||||
toTriangle.lineTo(QPointF(-EASE_TRIANGLE_SIZE, EASE_TRIANGLE_SIZE / 2));
|
||||
toTriangle.lineTo(QPointF(0, -EASE_TRIANGLE_SIZE / 2));
|
||||
toTriangle.translate(keyRect.center());
|
||||
addPath(PredefinedPath::END_EASE_TRIANGLE, toTriangle);
|
||||
|
||||
QPainterPath playFrom(QPointF(0, 0));
|
||||
playFrom.lineTo(QPointF(PLAY_MARKER_SIZE, 0));
|
||||
playFrom.lineTo(QPointF(0, PLAY_MARKER_SIZE));
|
||||
playFrom.lineTo(QPointF(0, 0));
|
||||
playFrom.translate(PLAY_RANGE_X, 1);
|
||||
addPath(PredefinedPath::BEGIN_PLAY_RANGE, playFrom);
|
||||
|
||||
QPainterPath playTo(QPointF(0, 0));
|
||||
playTo.lineTo(QPointF(PLAY_MARKER_SIZE, 0));
|
||||
playTo.lineTo(QPointF(0, -PLAY_MARKER_SIZE));
|
||||
playTo.lineTo(QPointF(0, 0));
|
||||
playTo.translate(PLAY_RANGE_X, CELL_HEIGHT - 1);
|
||||
addPath(PredefinedPath::END_PLAY_RANGE, playTo);
|
||||
|
||||
QPainterPath track(QPointF(0, 0));
|
||||
track.lineTo(QPointF(1, 1));
|
||||
track.lineTo(QPointF(1, trackLen - 1));
|
||||
track.lineTo(QPointF(0, trackLen));
|
||||
track.lineTo(QPointF(-1, trackLen - 1));
|
||||
track.lineTo(QPointF(-1, 1));
|
||||
track.lineTo(QPointF(0, 0));
|
||||
track.translate(soundTopLeft);
|
||||
addPath(PredefinedPath::VOLUME_SLIDER_TRACK, track);
|
||||
|
||||
QPainterPath head(QPointF(0, 0));
|
||||
head.lineTo(QPointF(4, 4));
|
||||
head.lineTo(QPointF(8, 4));
|
||||
head.lineTo(QPointF(8, -4));
|
||||
head.lineTo(QPointF(4, -4));
|
||||
head.lineTo(QPointF(0, 0));
|
||||
addPath(PredefinedPath::VOLUME_SLIDER_HEAD, head);
|
||||
|
||||
//
|
||||
// Points
|
||||
//
|
||||
addPoint(PredefinedPoint::KEY_HIDDEN, QPoint(KEY_ICON_WIDTH, 0));
|
||||
addPoint(PredefinedPoint::EXTENDER_XY_RADIUS, QPoint(30, 75));
|
||||
addPoint(PredefinedPoint::VOLUME_DIVISIONS_TOP_LEFT, soundTopLeft - QPoint(5, 0));
|
||||
|
||||
//
|
||||
// Ranges
|
||||
//
|
||||
addRange(PredefinedRange::HEADER_LAYER, NumberRange(0, FRAME_HEADER_WIDTH));
|
||||
addRange(PredefinedRange::HEADER_FRAME, NumberRange(0, LAYER_HEADER_HEIGHT));
|
||||
}
|
||||
|
||||
CellPosition TopToBottomOrientation::xyToPosition(const QPoint &xy,
|
||||
const ColumnFan *fan) const {
|
||||
int layer = fan->layerAxisToCol(xy.x());
|
||||
int frame = xy.y() / CELL_HEIGHT;
|
||||
return CellPosition(frame, layer);
|
||||
}
|
||||
QPoint TopToBottomOrientation::positionToXY(const CellPosition &position,
|
||||
const ColumnFan *fan) const {
|
||||
int x = colToLayerAxis(position.layer(), fan);
|
||||
int y = rowToFrameAxis(position.frame());
|
||||
return QPoint(x, y);
|
||||
}
|
||||
CellPositionRatio TopToBottomOrientation::xyToPositionRatio(
|
||||
const QPoint &xy) const {
|
||||
Ratio frame{xy.y(), CELL_HEIGHT};
|
||||
Ratio layer{xy.x(), CELL_WIDTH};
|
||||
return CellPositionRatio{frame, layer};
|
||||
}
|
||||
QPoint TopToBottomOrientation::positionRatioToXY(
|
||||
const CellPositionRatio &ratio) const {
|
||||
int x = ratio.layer() * CELL_WIDTH;
|
||||
int y = ratio.frame() * CELL_HEIGHT;
|
||||
return QPoint(x, y);
|
||||
}
|
||||
|
||||
int TopToBottomOrientation::colToLayerAxis(int layer,
|
||||
const ColumnFan *fan) const {
|
||||
return fan->colToLayerAxis(layer);
|
||||
}
|
||||
int TopToBottomOrientation::rowToFrameAxis(int frame) const {
|
||||
return frame * CELL_HEIGHT;
|
||||
}
|
||||
QPoint TopToBottomOrientation::frameLayerToXY(int frameAxis,
|
||||
int layerAxis) const {
|
||||
return QPoint(layerAxis, frameAxis);
|
||||
}
|
||||
int TopToBottomOrientation::layerAxis(const QPoint &xy) const { return xy.x(); }
|
||||
int TopToBottomOrientation::frameAxis(const QPoint &xy) const { return xy.y(); }
|
||||
NumberRange TopToBottomOrientation::layerSide(const QRect &area) const {
|
||||
return NumberRange(area.left(), area.right());
|
||||
}
|
||||
NumberRange TopToBottomOrientation::frameSide(const QRect &area) const {
|
||||
return NumberRange(area.top(), area.bottom());
|
||||
}
|
||||
QPoint TopToBottomOrientation::topRightCorner(const QRect &area) const {
|
||||
return area.topRight();
|
||||
}
|
||||
|
||||
CellPosition TopToBottomOrientation::arrowShift(int direction) const {
|
||||
switch (direction) {
|
||||
case Qt::Key_Up:
|
||||
return CellPosition(-1, 0);
|
||||
case Qt::Key_Down:
|
||||
return CellPosition(1, 0);
|
||||
case Qt::Key_Left:
|
||||
return CellPosition(0, -1);
|
||||
case Qt::Key_Right:
|
||||
return CellPosition(0, 1);
|
||||
default:
|
||||
return CellPosition(0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
/// --------------------------------------------------------------------------------
|
||||
|
||||
LeftToRightOrientation::LeftToRightOrientation() {
|
||||
//
|
||||
// Ranges
|
||||
//
|
||||
|
||||
// Cell viewer
|
||||
QRect cellRect(0, 0, CELL_WIDTH, CELL_HEIGHT);
|
||||
addRect(PredefinedRect::CELL, cellRect);
|
||||
addRect(PredefinedRect::DRAG_HANDLE_CORNER, QRect(0, 0, CELL_WIDTH, CELL_DRAG_HEIGHT));
|
||||
QRect keyRect((CELL_WIDTH - KEY_ICON_WIDTH) / 2, CELL_HEIGHT - KEY_ICON_HEIGHT, KEY_ICON_WIDTH, KEY_ICON_HEIGHT);
|
||||
addRect(PredefinedRect::KEY_ICON, keyRect);
|
||||
QRect nameRect = cellRect.adjusted(4, 4, -6, 0);
|
||||
addRect(PredefinedRect::CELL_NAME, nameRect);
|
||||
addRect(PredefinedRect::CELL_NAME_WITH_KEYFRAME, nameRect);
|
||||
addRect(PredefinedRect::END_EXTENDER, QRect(0, -EXTENDER_HEIGHT - 10, EXTENDER_WIDTH, EXTENDER_HEIGHT));
|
||||
addRect(PredefinedRect::BEGIN_EXTENDER, QRect(-EXTENDER_WIDTH, -EXTENDER_HEIGHT - 10, EXTENDER_WIDTH, EXTENDER_HEIGHT));
|
||||
addRect(PredefinedRect::KEYFRAME_AREA, keyRect);
|
||||
addRect(PredefinedRect::DRAG_AREA, QRect(0, 0, CELL_WIDTH, CELL_DRAG_HEIGHT));
|
||||
QRect soundRect(0, CELL_DRAG_HEIGHT, CELL_WIDTH, CELL_HEIGHT - CELL_DRAG_HEIGHT - SOUND_PREVIEW_HEIGHT);
|
||||
addRect(PredefinedRect::SOUND_TRACK, soundRect);
|
||||
addRect(PredefinedRect::PREVIEW_TRACK, QRect(0, CELL_HEIGHT - SOUND_PREVIEW_HEIGHT + 1, CELL_WIDTH, SOUND_PREVIEW_HEIGHT));
|
||||
addRect(PredefinedRect::BEGIN_SOUND_EDIT, QRect(0, CELL_DRAG_HEIGHT, 2, CELL_HEIGHT - CELL_DRAG_HEIGHT));
|
||||
addRect(PredefinedRect::END_SOUND_EDIT, QRect(CELL_WIDTH - 2, CELL_DRAG_HEIGHT, 2, CELL_HEIGHT - CELL_DRAG_HEIGHT));
|
||||
addRect(PredefinedRect::LOOP_ICON, QRect(0, keyRect.top(), 10, 11));
|
||||
|
||||
// Notes viewer
|
||||
addRect(PredefinedRect::NOTE_AREA, QRect(QPoint(0, 0), QSize(LAYER_HEADER_WIDTH - 1, FRAME_HEADER_HEIGHT)));
|
||||
addRect(PredefinedRect::NOTE_ICON, QRect(QPoint(0, 0), QSize(CELL_WIDTH - 2, CELL_HEIGHT - 2)));
|
||||
addRect(PredefinedRect::LAYER_HEADER_PANEL, QRect(0, FRAME_HEADER_HEIGHT - CELL_HEIGHT, LAYER_HEADER_WIDTH, CELL_HEIGHT));
|
||||
|
||||
// Row viewer
|
||||
addRect(PredefinedRect::FRAME_LABEL, QRect(CELL_WIDTH / 4, 1, CELL_WIDTH / 2, FRAME_HEADER_HEIGHT - 2));
|
||||
addRect(PredefinedRect::FRAME_HEADER, QRect(0, 0, CELL_WIDTH, FRAME_HEADER_HEIGHT - 1));
|
||||
addRect(PredefinedRect::PLAY_RANGE, QRect(0, PLAY_RANGE_Y, CELL_WIDTH, PLAY_MARKER_SIZE));
|
||||
addRect(PredefinedRect::ONION, QRect(ONION_X, ONION_Y + (3 * ONION_DOT_SIZE - ONION_SIZE) / 2, ONION_SIZE, ONION_SIZE));
|
||||
int adjustOnion = (ONION_SIZE - ONION_DOT_SIZE) / 2;
|
||||
addRect(PredefinedRect::ONION_DOT, QRect(ONION_X + adjustOnion, ONION_Y + ONION_DOT_SIZE, ONION_DOT_SIZE, ONION_DOT_SIZE));
|
||||
addRect(PredefinedRect::ONION_DOT_FIXED, QRect(ONION_X + adjustOnion, ONION_Y, ONION_DOT_SIZE, ONION_DOT_SIZE));
|
||||
addRect(PredefinedRect::ONION_AREA, QRect(ONION_X, ONION_Y, CELL_WIDTH, ONION_SIZE));
|
||||
addRect(PredefinedRect::ONION_FIXED_DOT_AREA, QRect(ONION_X, ONION_Y, CELL_WIDTH, ONION_DOT_SIZE));
|
||||
addRect(PredefinedRect::ONION_DOT_AREA, QRect(ONION_X, ONION_Y + ONION_DOT_SIZE, CELL_WIDTH, ONION_DOT_SIZE));
|
||||
addRect(PredefinedRect::PINNED_CENTER_KEY, QRect((CELL_WIDTH - PINNED_SIZE) / 2, (FRAME_HEADER_HEIGHT - PINNED_SIZE) / 2, PINNED_SIZE, PINNED_SIZE));
|
||||
|
||||
// Column viewer
|
||||
addRect(PredefinedRect::LAYER_HEADER, QRect(1, 0, LAYER_HEADER_WIDTH - 3, CELL_HEIGHT));
|
||||
addRect(PredefinedRect::FOLDED_LAYER_HEADER, QRect(1, 0, FOLDED_LAYER_HEADER_WIDTH - 3, FOLDED_LAYER_HEADER_HEIGHT));
|
||||
QRect columnName(ICONS_WIDTH + 1, 0, LAYER_NAME_WIDTH + LAYER_NUMBER_WIDTH - 3, CELL_HEIGHT);
|
||||
addRect(PredefinedRect::RENAME_COLUMN, columnName);
|
||||
QRect eye(1, 0, ICON_WIDTH, CELL_HEIGHT);
|
||||
addRect(PredefinedRect::EYE_AREA, eye);
|
||||
addRect(PredefinedRect::EYE, eye.adjusted(1, 1, 0, 0));
|
||||
addRect(PredefinedRect::PREVIEW_LAYER_AREA, eye.translated(ICON_OFFSET, 0));
|
||||
addRect(PredefinedRect::PREVIEW_LAYER, eye.translated(ICON_OFFSET + 1, 0).adjusted(-1, 1, -1, 0));
|
||||
addRect(PredefinedRect::LOCK_AREA, eye.translated(2 * ICON_OFFSET, 0));
|
||||
addRect(PredefinedRect::LOCK, eye.translated(2 * ICON_OFFSET + 1, 0).adjusted(-1, 1, -1, 0));
|
||||
addRect(PredefinedRect::DRAG_LAYER, QRect(ICONS_WIDTH + 1, 0, LAYER_HEADER_WIDTH - ICONS_WIDTH - 3, CELL_DRAG_HEIGHT));
|
||||
addRect(PredefinedRect::LAYER_NAME, columnName);
|
||||
addRect(PredefinedRect::LAYER_NUMBER, QRect(ICONS_WIDTH + 1, 0, LAYER_NUMBER_WIDTH, CELL_HEIGHT));
|
||||
addRect(PredefinedRect::THUMBNAIL_AREA, QRect(0, 0, -1, -1)); // hide
|
||||
addRect(PredefinedRect::FILTER_COLOR, QRect(LAYER_HEADER_WIDTH - 17, 6, 12, 12));
|
||||
addRect(PredefinedRect::PEGBAR_NAME, QRect(0, 0, -1, -1)); // hide
|
||||
addRect(PredefinedRect::PARENT_HANDLE_NAME, QRect(0, 0, -1, -1)); // hide
|
||||
|
||||
int trackLen = 60;
|
||||
QRect volumeArea(QRect(columnName.topRight(), QSize(trackLen + 8, columnName.height())).adjusted(-97, 0, -97, 0));
|
||||
addRect(PredefinedRect::VOLUME_AREA, volumeArea);
|
||||
QPoint soundTopLeft(volumeArea.left() + 4, volumeArea.top() + 12);
|
||||
addRect(PredefinedRect::VOLUME_TRACK, QRect(soundTopLeft, QSize(trackLen, 3)));
|
||||
addRect(PredefinedRect::SOUND_ICON, QRect(columnName.topRight(), QSize(27, columnName.height())).adjusted(-28, 0, -28, 0));
|
||||
|
||||
//
|
||||
// Lines
|
||||
//
|
||||
addLine(PredefinedLine::LOCKED, verticalLine(CELL_DRAG_HEIGHT / 2, NumberRange(0, CELL_WIDTH)));
|
||||
addLine(PredefinedLine::SEE_MARKER_THROUGH, horizontalLine(0, NumberRange(0, CELL_DRAG_HEIGHT)));
|
||||
addLine(PredefinedLine::CONTINUE_LEVEL, verticalLine(CELL_HEIGHT / 2, NumberRange(0, CELL_WIDTH)));
|
||||
addLine(PredefinedLine::CONTINUE_LEVEL_WITH_NAME, verticalLine(CELL_HEIGHT / 2, NumberRange(0, CELL_WIDTH)));
|
||||
addLine(PredefinedLine::EXTENDER_LINE, horizontalLine(0, NumberRange(-EXTENDER_WIDTH - KEY_ICON_WIDTH, 0)));
|
||||
|
||||
//
|
||||
// Dimensions
|
||||
//
|
||||
addDimension(PredefinedDimension::LAYER, CELL_HEIGHT);
|
||||
addDimension(PredefinedDimension::FRAME, CELL_WIDTH);
|
||||
addDimension(PredefinedDimension::INDEX, 1);
|
||||
addDimension(PredefinedDimension::SOUND_AMPLITUDE, soundRect.height() / 2);
|
||||
addDimension(PredefinedDimension::FRAME_LABEL_ALIGN, Qt::AlignHCenter | Qt::AlignBottom | Qt::TextWordWrap);
|
||||
addDimension(PredefinedDimension::ONION_TURN, 90);
|
||||
addDimension(PredefinedDimension::QBOXLAYOUT_DIRECTION, QBoxLayout::Direction::LeftToRight);
|
||||
addDimension(PredefinedDimension::CENTER_ALIGN, Qt::AlignVCenter);
|
||||
|
||||
//
|
||||
// Paths
|
||||
//
|
||||
QPainterPath corner(QPointF(CELL_WIDTH, 0));
|
||||
corner.lineTo(QPointF(CELL_WIDTH, CELL_DRAG_HEIGHT));
|
||||
corner.lineTo(QPointF(CELL_WIDTH - CELL_DRAG_HEIGHT, CELL_DRAG_HEIGHT));
|
||||
corner.lineTo(QPointF(CELL_WIDTH, 0));
|
||||
addPath(PredefinedPath::DRAG_HANDLE_CORNER, corner);
|
||||
|
||||
QPainterPath fromTriangle(QPointF(EASE_TRIANGLE_SIZE / 2, 0));
|
||||
fromTriangle.lineTo(QPointF(-EASE_TRIANGLE_SIZE / 2, EASE_TRIANGLE_SIZE));
|
||||
fromTriangle.lineTo(QPointF(-EASE_TRIANGLE_SIZE / 2, -EASE_TRIANGLE_SIZE));
|
||||
fromTriangle.lineTo(QPointF(EASE_TRIANGLE_SIZE / 2, 0));
|
||||
fromTriangle.translate(keyRect.center());
|
||||
addPath(PredefinedPath::BEGIN_EASE_TRIANGLE, fromTriangle);
|
||||
|
||||
QPainterPath toTriangle(QPointF(-EASE_TRIANGLE_SIZE / 2, 0));
|
||||
toTriangle.lineTo(QPointF(EASE_TRIANGLE_SIZE / 2, EASE_TRIANGLE_SIZE));
|
||||
toTriangle.lineTo(QPointF(EASE_TRIANGLE_SIZE / 2, -EASE_TRIANGLE_SIZE));
|
||||
toTriangle.lineTo(QPointF(-EASE_TRIANGLE_SIZE / 2, 0));
|
||||
toTriangle.translate(keyRect.center());
|
||||
addPath(PredefinedPath::END_EASE_TRIANGLE, toTriangle);
|
||||
|
||||
QPainterPath playFrom(QPointF(0, 0));
|
||||
playFrom.lineTo(QPointF(PLAY_MARKER_SIZE, 0));
|
||||
playFrom.lineTo(QPointF(0, PLAY_MARKER_SIZE));
|
||||
playFrom.lineTo(QPointF(0, 0));
|
||||
playFrom.translate(1, PLAY_RANGE_Y);
|
||||
addPath(PredefinedPath::BEGIN_PLAY_RANGE, playFrom);
|
||||
|
||||
QPainterPath playTo(QPointF(0, 0));
|
||||
playTo.lineTo(QPointF(-PLAY_MARKER_SIZE, 0));
|
||||
playTo.lineTo(QPointF(0, PLAY_MARKER_SIZE));
|
||||
playTo.lineTo(QPointF(0, 0));
|
||||
playTo.translate(CELL_WIDTH - 1, PLAY_RANGE_Y);
|
||||
addPath(PredefinedPath::END_PLAY_RANGE, playTo);
|
||||
|
||||
QPainterPath track(QPointF(0, 0));
|
||||
track.lineTo(QPointF(1, 1));
|
||||
track.lineTo(QPointF(trackLen - 1, 1));
|
||||
track.lineTo(QPointF(trackLen, 0));
|
||||
track.lineTo(QPointF(trackLen - 1, -1));
|
||||
track.lineTo(QPointF(1, -1));
|
||||
track.lineTo(QPointF(0, 0));
|
||||
track.translate(soundTopLeft);
|
||||
addPath(PredefinedPath::VOLUME_SLIDER_TRACK, track);
|
||||
|
||||
QPainterPath head(QPointF(0, 0));
|
||||
head.lineTo(QPointF(4, -4));
|
||||
head.lineTo(QPointF(4, -8));
|
||||
head.lineTo(QPointF(-4, -8));
|
||||
head.lineTo(QPointF(-4, -4));
|
||||
head.lineTo(QPointF(0, 0));
|
||||
addPath(PredefinedPath::VOLUME_SLIDER_HEAD, head);
|
||||
|
||||
//
|
||||
// Points
|
||||
//
|
||||
addPoint(PredefinedPoint::KEY_HIDDEN, QPoint(0, 10));
|
||||
addPoint(PredefinedPoint::EXTENDER_XY_RADIUS, QPoint(75, 30));
|
||||
addPoint(PredefinedPoint::VOLUME_DIVISIONS_TOP_LEFT, soundTopLeft + QPoint(0, 3));
|
||||
|
||||
//
|
||||
// Ranges
|
||||
//
|
||||
addRange(PredefinedRange::HEADER_LAYER, NumberRange(0, FRAME_HEADER_HEIGHT));
|
||||
addRange(PredefinedRange::HEADER_FRAME, NumberRange(0, LAYER_HEADER_WIDTH));
|
||||
}
|
||||
|
||||
CellPosition LeftToRightOrientation::xyToPosition(const QPoint &xy,
|
||||
const ColumnFan *fan) const {
|
||||
int layer = fan->layerAxisToCol(xy.y());
|
||||
int frame = xy.x() / CELL_WIDTH;
|
||||
return CellPosition(frame, layer);
|
||||
}
|
||||
QPoint LeftToRightOrientation::positionToXY(const CellPosition &position,
|
||||
const ColumnFan *fan) const {
|
||||
int y = colToLayerAxis(position.layer(), fan);
|
||||
int x = rowToFrameAxis(position.frame());
|
||||
return QPoint(x, y);
|
||||
}
|
||||
CellPositionRatio LeftToRightOrientation::xyToPositionRatio(
|
||||
const QPoint &xy) const {
|
||||
Ratio frame{xy.x(), CELL_WIDTH};
|
||||
Ratio layer{xy.y(), CELL_HEIGHT};
|
||||
return CellPositionRatio{frame, layer};
|
||||
}
|
||||
QPoint LeftToRightOrientation::positionRatioToXY(
|
||||
const CellPositionRatio &ratio) const {
|
||||
int x = ratio.frame() * CELL_WIDTH;
|
||||
int y = ratio.layer() * CELL_HEIGHT;
|
||||
return QPoint(x, y);
|
||||
}
|
||||
|
||||
int LeftToRightOrientation::colToLayerAxis(int layer,
|
||||
const ColumnFan *fan) const {
|
||||
return fan->colToLayerAxis(layer);
|
||||
}
|
||||
int LeftToRightOrientation::rowToFrameAxis(int frame) const {
|
||||
return frame * CELL_WIDTH;
|
||||
}
|
||||
QPoint LeftToRightOrientation::frameLayerToXY(int frameAxis,
|
||||
int layerAxis) const {
|
||||
return QPoint(frameAxis, layerAxis);
|
||||
}
|
||||
int LeftToRightOrientation::layerAxis(const QPoint &xy) const { return xy.y(); }
|
||||
int LeftToRightOrientation::frameAxis(const QPoint &xy) const { return xy.x(); }
|
||||
NumberRange LeftToRightOrientation::layerSide(const QRect &area) const {
|
||||
return NumberRange(area.top(), area.bottom());
|
||||
}
|
||||
NumberRange LeftToRightOrientation::frameSide(const QRect &area) const {
|
||||
return NumberRange(area.left(), area.right());
|
||||
}
|
||||
QPoint LeftToRightOrientation::topRightCorner(const QRect &area) const {
|
||||
return area.bottomLeft();
|
||||
}
|
||||
CellPosition LeftToRightOrientation::arrowShift(int direction) const {
|
||||
switch (direction) {
|
||||
case Qt::Key_Up:
|
||||
return CellPosition(0, -1);
|
||||
case Qt::Key_Down:
|
||||
return CellPosition(0, 1);
|
||||
case Qt::Key_Left:
|
||||
return CellPosition(-1, 0);
|
||||
case Qt::Key_Right:
|
||||
return CellPosition(1, 0);
|
||||
default:
|
||||
return CellPosition(0, 0);
|
||||
}
|
||||
}
|
|
@ -310,7 +310,8 @@ Preferences::Preferences()
|
|||
, m_useNumpadForSwitchingStyles(true)
|
||||
, m_showXSheetToolbar(false)
|
||||
, m_expandFunctionHeader(false)
|
||||
, m_useArrowKeyToShiftCellSelection(false)
|
||||
, m_showColumnNumbers(false)
|
||||
, m_useArrowKeyToShiftCellSelection(false)
|
||||
, m_inputCellsWithoutDoubleClickingEnabled(false)
|
||||
, m_importPolicy(0)
|
||||
, m_watchFileSystem(true) {
|
||||
|
@ -589,6 +590,7 @@ Preferences::Preferences()
|
|||
m_useNumpadForSwitchingStyles);
|
||||
getValue(*m_settings, "showXSheetToolbar", m_showXSheetToolbar);
|
||||
getValue(*m_settings, "expandFunctionHeader", m_expandFunctionHeader);
|
||||
getValue(*m_settings, "showColumnNumbers", m_showColumnNumbers);
|
||||
getValue(*m_settings, "useArrowKeyToShiftCellSelection",
|
||||
m_useArrowKeyToShiftCellSelection);
|
||||
getValue(*m_settings, "inputCellsWithoutDoubleClickingEnabled",
|
||||
|
@ -1389,6 +1391,11 @@ void Preferences::enableExpandFunctionHeader(bool on) {
|
|||
m_settings->setValue("expandFunctionHeader", on ? "1" : "0");
|
||||
}
|
||||
|
||||
void Preferences::enableShowColumnNumbers(bool on) {
|
||||
m_showColumnNumbers = on;
|
||||
m_settings->setValue("showColumnNumbers", on ? "1" : "0");
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------
|
||||
|
||||
void Preferences::enableUseArrowKeyToShiftCellSelection(bool on) {
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
#include "toonz/stage.h"
|
||||
#include "toonz/textureutils.h"
|
||||
#include "xshhandlemanager.h"
|
||||
#include "orientation.h"
|
||||
|
||||
#include "toonz/txsheet.h"
|
||||
|
||||
|
@ -92,7 +93,7 @@ struct TXsheet::TXsheetImp {
|
|||
int m_viewColumn;
|
||||
|
||||
TSoundTrackP m_mixedSound;
|
||||
ColumnFan m_columnFan;
|
||||
ColumnFan m_columnFans[Orientations::COUNT];
|
||||
XshHandleManager *m_handleManager;
|
||||
ToonzScene *m_scene;
|
||||
|
||||
|
@ -105,7 +106,11 @@ public:
|
|||
return ++currentId;
|
||||
}
|
||||
|
||||
void copyFoldedState();
|
||||
|
||||
private:
|
||||
void initColumnFans();
|
||||
|
||||
// not implemented
|
||||
TXsheetImp(const TXsheetImp &);
|
||||
TXsheetImp &operator=(const TXsheetImp &);
|
||||
|
@ -144,7 +149,9 @@ TXsheet::TXsheetImp::TXsheetImp()
|
|||
, m_soloColumn(-1)
|
||||
, m_viewColumn(-1)
|
||||
, m_mixedSound(0)
|
||||
, m_scene(0) {}
|
||||
, m_scene(0) {
|
||||
initColumnFans();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
@ -157,6 +164,20 @@ TXsheet::TXsheetImp::~TXsheetImp() {
|
|||
delete m_handleManager;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void TXsheet::TXsheetImp::initColumnFans() {
|
||||
for (auto o : Orientations::all()) {
|
||||
int index = o->dimension(PredefinedDimension::INDEX);
|
||||
m_columnFans[index].setDimension(o->dimension(PredefinedDimension::LAYER));
|
||||
}
|
||||
}
|
||||
|
||||
void TXsheet::TXsheetImp::copyFoldedState() {
|
||||
for (int i = 1; i < Orientations::COUNT; i++)
|
||||
m_columnFans[i].copyFoldedStateFrom(m_columnFans[0]);
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
// TXsheet
|
||||
|
||||
|
@ -193,12 +214,17 @@ int TXsheet::getFrameCount() const { return m_imp->m_frameCount; }
|
|||
//-----------------------------------------------------------------------------
|
||||
|
||||
const TXshCell &TXsheet::getCell(int row, int col) const {
|
||||
return getCell(CellPosition(row, col));
|
||||
}
|
||||
|
||||
const TXshCell &TXsheet::getCell(const CellPosition &pos) const {
|
||||
static const TXshCell emptyCell;
|
||||
TXshColumnP column = m_imp->m_columnSet.getColumn(col);
|
||||
|
||||
TXshColumnP column = m_imp->m_columnSet.getColumn(pos.layer());
|
||||
if (!column) return emptyCell;
|
||||
TXshCellColumn *xshColumn = column->getCellColumn();
|
||||
if (!xshColumn) return emptyCell;
|
||||
return xshColumn->getCell(row);
|
||||
return xshColumn->getCell(pos.frame());
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -590,8 +616,8 @@ void TXsheet::reverseCells(int r0, int c0, int r1, int c1) {
|
|||
for (int j = c0; j <= c1; j++) {
|
||||
int i1, i2;
|
||||
for (i1 = r0, i2 = r1; i1 < i2; i1++, i2--) {
|
||||
TXshCell app1 = getCell(i1, j);
|
||||
TXshCell app2 = getCell(i2, j);
|
||||
TXshCell app1 = getCell(CellPosition(i1, j));
|
||||
TXshCell app2 = getCell(CellPosition(i2, j));
|
||||
setCell(i1, j, app2);
|
||||
setCell(i2, j, app1);
|
||||
}
|
||||
|
@ -608,7 +634,7 @@ void TXsheet::swingCells(int r0, int c0, int r1, int c1) {
|
|||
|
||||
for (int j = c0; j <= c1; j++) {
|
||||
for (int i1 = r0Mod, i2 = r1 - 1; i2 >= r0; i1++, i2--) {
|
||||
TXshCell cell = getCell(i2, j);
|
||||
TXshCell cell = getCell(CellPosition(i2, j));
|
||||
setCell(i1, j, cell);
|
||||
}
|
||||
}
|
||||
|
@ -620,49 +646,52 @@ bool TXsheet::incrementCells(int r0, int c0, int r1, int c1,
|
|||
vector<std::pair<TRect, TXshCell>> &forUndo) {
|
||||
for (int j = c0; j <= c1; j++) {
|
||||
int i = r0;
|
||||
while (getCell(i, j).isEmpty() && i <= r1 - 1) i++;
|
||||
while (getCell(CellPosition(i, j)).isEmpty() && i <= r1 - 1) i++;
|
||||
|
||||
for (; i <= r1 - 1; i++) {
|
||||
if (getCell(i + 1, j).isEmpty()) break;
|
||||
const TXshCell &ce1 = getCell(i, j), &ce2 = getCell(i + 1, j);
|
||||
if (getCell(CellPosition(i + 1, j)).isEmpty()) break;
|
||||
const TXshCell &ce1 = getCell(CellPosition(i, j)),
|
||||
&ce2 = getCell(CellPosition(i + 1, j));
|
||||
if (ce2.getSimpleLevel() != ce1.getSimpleLevel() ||
|
||||
ce2.getFrameId().getNumber() < ce1.getFrameId().getNumber())
|
||||
return false;
|
||||
}
|
||||
i = r0;
|
||||
while (getCell(i, j).isEmpty() && i <= r1 - 1) i++;
|
||||
while (getCell(CellPosition(i, j)).isEmpty() && i <= r1 - 1) i++;
|
||||
int count;
|
||||
for (; i <= r1 - 1; i++) {
|
||||
count = 1;
|
||||
if (getCell(i + 1, j).isEmpty()) continue;
|
||||
if (getCell(CellPosition(i + 1, j)).isEmpty()) continue;
|
||||
|
||||
int frame1 = getCell(i, j).getFrameId().getNumber();
|
||||
int frame1 = getCell(CellPosition(i, j)).getFrameId().getNumber();
|
||||
if (frame1 == -1) break;
|
||||
while (!getCell(i + 1, j).isEmpty() &&
|
||||
getCell(i + 1, j).getFrameId().getNumber() ==
|
||||
getCell(i, j).getFrameId().getNumber())
|
||||
while (!getCell(CellPosition(i + 1, j)).isEmpty() &&
|
||||
getCell(CellPosition(i + 1, j)).getFrameId().getNumber() ==
|
||||
getCell(CellPosition(i, j)).getFrameId().getNumber())
|
||||
i++, count++;
|
||||
|
||||
int frame2 = getCell(i + 1, j).getFrameId().getNumber();
|
||||
int frame2 = getCell(CellPosition(i + 1, j)).getFrameId().getNumber();
|
||||
if (frame2 == -1) break;
|
||||
|
||||
if (frame1 + count == frame2)
|
||||
continue;
|
||||
else if (frame1 + count < frame2) // aggiungo
|
||||
else if (frame1 + count < frame2) // add
|
||||
{
|
||||
int numCells = frame2 - frame1 - count;
|
||||
insertCells(i + 1, j, numCells);
|
||||
forUndo.push_back(std::pair<TRect, TXshCell>(
|
||||
TRect(i + 1, j, i + 1 + numCells - 1, j), TXshCell()));
|
||||
for (int k = 1; k <= numCells; k++) setCell(i + k, j, getCell(i, j));
|
||||
for (int k = 1; k <= numCells; k++)
|
||||
setCell(i + k, j, getCell(CellPosition(i, j)));
|
||||
i += numCells;
|
||||
r1 += numCells;
|
||||
} else // tolgo
|
||||
} else // remove
|
||||
{
|
||||
int numCells = count - frame2 + frame1;
|
||||
i = i - numCells;
|
||||
forUndo.push_back(std::pair<TRect, TXshCell>(
|
||||
TRect(i + 1, j, i + 1 + numCells - 1, j), getCell(i + 1, j)));
|
||||
forUndo.push_back(
|
||||
std::pair<TRect, TXshCell>(TRect(i + 1, j, i + 1 + numCells - 1, j),
|
||||
getCell(CellPosition(i + 1, j))));
|
||||
removeCells(i + 1, j, numCells);
|
||||
r1 -= numCells;
|
||||
}
|
||||
|
@ -680,7 +709,7 @@ void TXsheet::duplicateCells(int r0, int c0, int r1, int c1, int upTo) {
|
|||
for (int j = c0; j <= c1; j++) {
|
||||
insertCells(r1 + 1, j, upTo - (r1 + 1) + 1);
|
||||
for (int i = r1 + 1; i <= upTo; i++)
|
||||
setCell(i, j, getCell(r0 + ((i - (r1 + 1)) % chunk), j));
|
||||
setCell(i, j, getCell(CellPosition(r0 + ((i - (r1 + 1)) % chunk), j)));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -697,7 +726,7 @@ void TXsheet::stepCells(int r0, int c0, int r1, int c1, int type) {
|
|||
int k = 0;
|
||||
for (int r = r0; r <= r1; r++)
|
||||
for (int c = c0; c <= c1; c++) {
|
||||
cells[k++] = getCell(r, c);
|
||||
cells[k++] = getCell(CellPosition(r, c));
|
||||
}
|
||||
|
||||
int nrows = nr * (type - 1);
|
||||
|
@ -726,13 +755,13 @@ void TXsheet::increaseStepCells(int r0, int c0, int &r1, int c1) {
|
|||
for (c = c0; c <= c1; c++) {
|
||||
int r = r0, i = 0, rEnd = r1;
|
||||
while (r <= rEnd) {
|
||||
TXshCell cell = getCell(r, c);
|
||||
TXshCell cell = getCell(CellPosition(r, c));
|
||||
if (!cell.isEmpty()) {
|
||||
insertCells(r, c);
|
||||
setCell(r, c, cell);
|
||||
rEnd++;
|
||||
r++;
|
||||
while (cell == getCell(r, c) && r <= rEnd) r++;
|
||||
while (cell == getCell(CellPosition(r, c)) && r <= rEnd) r++;
|
||||
} else
|
||||
r++;
|
||||
i++;
|
||||
|
@ -755,11 +784,11 @@ void TXsheet::decreaseStepCells(int r0, int c0, int &r1, int c1) {
|
|||
for (c = c0; c <= c1; c++) {
|
||||
int r = r0, i = 0, rEnd = r1;
|
||||
while (r <= rEnd) {
|
||||
TXshCell cell = getCell(r, c);
|
||||
TXshCell cell = getCell(CellPosition(r, c));
|
||||
if (!cell.isEmpty()) {
|
||||
r++;
|
||||
bool removed = false;
|
||||
while (cell == getCell(r, c) && r <= rEnd) {
|
||||
while (cell == getCell(CellPosition(r, c)) && r <= rEnd) {
|
||||
if (!removed) {
|
||||
removed = true;
|
||||
removeCells(r, c);
|
||||
|
@ -799,7 +828,7 @@ void TXsheet::eachCells(int r0, int c0, int r1, int c1, int type) {
|
|||
for (j = r0, i = 0; i < size;
|
||||
j += type) // in cells copio il contenuto delle celle che mi interessano
|
||||
{
|
||||
for (k = c0; k <= c1; k++, i++) cells[i] = getCell(j, k);
|
||||
for (k = c0; k <= c1; k++, i++) cells[i] = getCell(CellPosition(j, k));
|
||||
}
|
||||
|
||||
int c;
|
||||
|
@ -831,8 +860,8 @@ int TXsheet::reframeCells(int r0, int r1, int col, int type) {
|
|||
cells.clear();
|
||||
|
||||
for (int r = r0; r <= r1; r++) {
|
||||
if (cells.size() == 0 || cells.last() != getCell(r, col))
|
||||
cells.push_back(getCell(r, col));
|
||||
if (cells.size() == 0 || cells.last() != getCell(CellPosition(r, col)))
|
||||
cells.push_back(getCell(CellPosition(r, col)));
|
||||
}
|
||||
|
||||
if (cells.empty()) return 0;
|
||||
|
@ -871,9 +900,9 @@ void TXsheet::resetStepCells(int r0, int c0, int r1, int c1) {
|
|||
TXshCell *cells = new TXshCell[size];
|
||||
while (r <= r1) {
|
||||
// mi prendo le celle che mi servono
|
||||
cells[i] = getCell(r, c);
|
||||
cells[i] = getCell(CellPosition(r, c));
|
||||
r++;
|
||||
while (cells[i] == getCell(r, c) && r <= r1) r++;
|
||||
while (cells[i] == getCell(CellPosition(r, c)) && r <= r1) r++;
|
||||
i++;
|
||||
}
|
||||
|
||||
|
@ -899,7 +928,7 @@ void TXsheet::rollupCells(int r0, int c0, int r1, int c1) {
|
|||
|
||||
// in cells copio il contenuto delle celle che mi interessano
|
||||
int k;
|
||||
for (k = c0; k <= c1; k++) cells[k - c0] = getCell(r0, k);
|
||||
for (k = c0; k <= c1; k++) cells[k - c0] = getCell(CellPosition(r0, k));
|
||||
|
||||
for (k = c0; k <= c1; k++) removeCells(r0, k, 1);
|
||||
|
||||
|
@ -922,7 +951,7 @@ void TXsheet::rolldownCells(int r0, int c0, int r1, int c1) {
|
|||
|
||||
// in cells copio il contenuto delle celle che mi interessano
|
||||
int k;
|
||||
for (k = c0; k <= c1; k++) cells[k - c0] = getCell(r1, k);
|
||||
for (k = c0; k <= c1; k++) cells[k - c0] = getCell(CellPosition(r1, k));
|
||||
|
||||
for (k = c0; k <= c1; k++) removeCells(r1, k, 1);
|
||||
|
||||
|
@ -1188,7 +1217,8 @@ void TXsheet::loadData(TIStream &is) {
|
|||
TFxSet fxSet;
|
||||
fxSet.loadData(is);
|
||||
} else if (tagName == "columnFan") {
|
||||
m_imp->m_columnFan.loadData(is);
|
||||
m_imp->m_columnFans[0].loadData(is);
|
||||
m_imp->copyFoldedState();
|
||||
} else if (tagName == "noteSet") {
|
||||
m_notes->loadData(is);
|
||||
} else {
|
||||
|
@ -1218,7 +1248,8 @@ void TXsheet::saveData(TOStream &os) {
|
|||
fxDag->saveData(os, getFirstFreeColumnIndex());
|
||||
os.closeChild();
|
||||
|
||||
ColumnFan *columnFan = getColumnFan();
|
||||
// does not matter which Orientation to take, as all fans share folded data
|
||||
ColumnFan *columnFan = getColumnFan(Orientations::topToBottom());
|
||||
if (!columnFan->isEmpty()) {
|
||||
os.openChild("columnFan");
|
||||
columnFan->saveData(os);
|
||||
|
@ -1439,7 +1470,10 @@ FxDag *TXsheet::getFxDag() const { return m_imp->m_fxDag; }
|
|||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
ColumnFan *TXsheet::getColumnFan() const { return &m_imp->m_columnFan; }
|
||||
ColumnFan *TXsheet::getColumnFan(const Orientation *o) const {
|
||||
int index = o->dimension(PredefinedDimension::INDEX);
|
||||
return &m_imp->m_columnFans[index];
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
@ -1504,7 +1538,7 @@ TRectD TXsheet::getBBox(int r) const {
|
|||
struct locals {
|
||||
static TRectD getBBox(const TXsheet *xsh, int r, int c) {
|
||||
// Discriminate cell content
|
||||
const TXshCell &cell = xsh->getCell(r, c);
|
||||
const TXshCell &cell = xsh->getCell(CellPosition(r, c));
|
||||
if (cell.isEmpty()) return voidRect;
|
||||
|
||||
if (TXshChildLevel *cl = cell.getChildLevel())
|
||||
|
@ -1570,11 +1604,10 @@ TRectD TXsheet::getBBox(int r) const {
|
|||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
bool TXsheet::isRectEmpty(int r0, int c0, int r1, int c1) const {
|
||||
for (int r = r0; r <= r1; r++) {
|
||||
for (int c = c0; c <= c1; c++) {
|
||||
if (!getCell(r, c).isEmpty()) return false;
|
||||
}
|
||||
}
|
||||
bool TXsheet::isRectEmpty(const CellPosition &pos0,
|
||||
const CellPosition &pos1) const {
|
||||
for (int frame = pos0.frame(); frame <= pos1.frame(); frame++)
|
||||
for (int layer = pos0.layer(); layer <= pos1.layer(); layer++)
|
||||
if (!getCell(CellPosition(frame, layer)).isEmpty()) return false;
|
||||
return true;
|
||||
}
|
|
@ -145,9 +145,13 @@ void TXshSoundLevel::saveData(TOStream &os) {
|
|||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void TXshSoundLevel::computeValues(int frameHeight) {
|
||||
void TXshSoundLevel::computeValuesFor(const Orientation *o) {
|
||||
int frameHeight = o->dimension(PredefinedDimension::FRAME); // time axis
|
||||
int index = o->dimension(PredefinedDimension::INDEX);
|
||||
map<int, DoublePair> &values = m_values[index];
|
||||
|
||||
if (frameHeight == 0) frameHeight = 1;
|
||||
m_values.clear();
|
||||
values.clear();
|
||||
if (!m_soundTrack) {
|
||||
m_frameSoundCount = 0;
|
||||
m_samplePerFrame = 0;
|
||||
|
@ -174,7 +178,9 @@ void TXshSoundLevel::computeValues(int frameHeight) {
|
|||
if (absMaxPressure <= 0) return;
|
||||
|
||||
// Adjusting using a fixed scaleFactor
|
||||
double weightA = 20.0 / absMaxPressure;
|
||||
int desiredAmplitude = o->dimension(PredefinedDimension::SOUND_AMPLITUDE);
|
||||
// results will be in range -desiredAmplitude .. +desiredAmplitude
|
||||
double weightA = desiredAmplitude / absMaxPressure;
|
||||
|
||||
long i = 0, j;
|
||||
long p = 0; // se p parte da zero notazione per pixel,
|
||||
|
@ -187,7 +193,7 @@ void TXshSoundLevel::computeValues(int frameHeight) {
|
|||
(TINT32)(i * m_samplePerFrame + j * samplePerPixel),
|
||||
(TINT32)(i * m_samplePerFrame + (j + 1) * samplePerPixel - 1),
|
||||
TSound::MONO, min, max);
|
||||
m_values.insert(std::pair<int, std::pair<double, double>>(
|
||||
values.insert(std::pair<int, std::pair<double, double>>(
|
||||
p + j, std::pair<double, double>(min * weightA, max * weightA)));
|
||||
}
|
||||
|
||||
|
@ -196,7 +202,7 @@ void TXshSoundLevel::computeValues(int frameHeight) {
|
|||
m_soundTrack->getMinMaxPressure(
|
||||
(TINT32)(i * m_samplePerFrame + j * samplePerPixel),
|
||||
(TINT32)((i + 1) * m_samplePerFrame - 1), TSound::MONO, min, max);
|
||||
m_values.insert(std::pair<int, std::pair<double, double>>(
|
||||
values.insert(std::pair<int, std::pair<double, double>>(
|
||||
p + j, std::pair<double, double>(min * weightA, max * weightA)));
|
||||
|
||||
++i;
|
||||
|
@ -206,9 +212,17 @@ void TXshSoundLevel::computeValues(int frameHeight) {
|
|||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void TXshSoundLevel::getValueAtPixel(int pixel, DoublePair &values) const {
|
||||
std::map<int, DoublePair>::const_iterator it = m_values.find(pixel);
|
||||
if (it != m_values.end()) values = it->second;
|
||||
void TXshSoundLevel::computeValues() {
|
||||
for (auto o : Orientations::all()) computeValuesFor(o);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void TXshSoundLevel::getValueAtPixel(const Orientation *o, int pixel,
|
||||
DoublePair &values) const {
|
||||
int index = o->dimension(PredefinedDimension::INDEX);
|
||||
std::map<int, DoublePair>::const_iterator it = m_values[index].find(pixel);
|
||||
if (it != m_values[index].end()) values = it->second;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
|
|
@ -251,12 +251,10 @@ void FunctionSheetColumnHeadViewer::paintEvent(QPaintEvent *e) {
|
|||
QRect toBeUpdated = e->rect();
|
||||
painter.setClipRect(toBeUpdated);
|
||||
|
||||
int x0 = toBeUpdated.left();
|
||||
int x1 = toBeUpdated.right();
|
||||
|
||||
// visible columns range
|
||||
int c0 = getViewer()->xToColumn(x0);
|
||||
int c1 = getViewer()->xToColumn(x1);
|
||||
CellRange visible = getViewer()->xyRectToRange(toBeUpdated);
|
||||
int c0 = visible.from().layer();
|
||||
int c1 = visible.to().layer();
|
||||
|
||||
if (c0 > c1) return;
|
||||
|
||||
|
@ -264,7 +262,8 @@ void FunctionSheetColumnHeadViewer::paintEvent(QPaintEvent *e) {
|
|||
|
||||
FunctionTreeModel::ChannelGroup *currentGroup = 0;
|
||||
|
||||
/*--- 表示範囲+左右1カラムの範囲で、ChannelGroupを格納。無ければ0を入れる
|
||||
/*--- Display range + right and left 1 column range ChannelGroup. If there is
|
||||
* none, put 0
|
||||
* ---*/
|
||||
std::vector<FunctionTreeModel::ChannelGroup *> channelGroups(n);
|
||||
for (int i = 0; i < n; ++i) {
|
||||
|
@ -281,11 +280,11 @@ void FunctionSheetColumnHeadViewer::paintEvent(QPaintEvent *e) {
|
|||
}
|
||||
|
||||
int y0 = 0;
|
||||
int y1 = 17;
|
||||
int y1 = 17; // needs work
|
||||
int y2 = 34;
|
||||
int y3 = 53;
|
||||
|
||||
/*--- Channelの有る範囲内を明るめのグレーで塗る ---*/
|
||||
/*--- Fill header with background color ---*/
|
||||
for (int c = c0; c <= c1; c++) {
|
||||
FunctionTreeModel::Channel *channel = m_sheet->getChannel(c);
|
||||
if (!channel) continue;
|
||||
|
@ -301,16 +300,18 @@ void FunctionSheetColumnHeadViewer::paintEvent(QPaintEvent *e) {
|
|||
FunctionTreeModel::Channel *channel = m_sheet->getChannel(c);
|
||||
if (!channel) continue;
|
||||
int i = c - c0 + 1;
|
||||
/*---- 現在のColumnと前後のColumnのChannelGroup ---*/
|
||||
/*---- Channel Column of the current Column and the preceding and following
|
||||
* Columns ---*/
|
||||
FunctionTreeModel::ChannelGroup *prevGroup = channelGroups[c - c0],
|
||||
*group = channelGroups[c - c0 + 1],
|
||||
*nextGroup = channelGroups[c - c0 + 2];
|
||||
|
||||
/*---- 前後とグループが違ってた場合、それぞれフラグを立てる ---*/
|
||||
/*---- If the group is different from the before and after, flags are set
|
||||
* respectively ---*/
|
||||
bool firstGroupColumn = prevGroup != group;
|
||||
bool lastGroupColumn = nextGroup != group;
|
||||
|
||||
/*--- 現在のカラムの左右座標 ---*/
|
||||
/*--- The left and right coordinates of the current column ---*/
|
||||
int x0 = getViewer()->columnToX(c);
|
||||
int x1 = getViewer()->columnToX(c + 1) - 1;
|
||||
// Column width
|
||||
|
@ -380,7 +381,7 @@ void FunctionSheetColumnHeadViewer::mouseMoveEvent(QMouseEvent *e) {
|
|||
}
|
||||
|
||||
// get the column under the cursor
|
||||
int col = getViewer()->xToColumn(e->pos().x());
|
||||
int col = getViewer()->xyToPosition(e->pos()).layer();
|
||||
FunctionTreeModel::Channel *channel = m_sheet->getChannel(col);
|
||||
if (!channel) {
|
||||
setToolTip(QString(""));
|
||||
|
@ -392,7 +393,7 @@ void FunctionSheetColumnHeadViewer::mouseMoveEvent(QMouseEvent *e) {
|
|||
|
||||
void FunctionSheetColumnHeadViewer::mousePressEvent(QMouseEvent *e) {
|
||||
QPoint pos = e->pos();
|
||||
int currentC = getViewer()->xToColumn(pos.x());
|
||||
int currentC = getViewer()->xyToPosition(pos).layer();
|
||||
FunctionTreeModel::Channel *channel;
|
||||
for (int c = 0; c <= m_sheet->getChannelCount(); c++) {
|
||||
channel = m_sheet->getChannel(c);
|
||||
|
@ -428,7 +429,7 @@ void FunctionSheetColumnHeadViewer::mousePressEvent(QMouseEvent *e) {
|
|||
void FunctionSheetColumnHeadViewer::contextMenuEvent(QContextMenuEvent *ce) {
|
||||
// First, select column under cursor
|
||||
const QPoint &pos = ce->pos();
|
||||
int cursorCol = getViewer()->xToColumn(pos.x());
|
||||
int cursorCol = getViewer()->xyToPosition(pos).layer();
|
||||
|
||||
if (cursorCol < 0 || cursorCol >= m_sheet->getChannelCount()) return;
|
||||
|
||||
|
@ -510,10 +511,11 @@ FunctionSheetCellViewer::FunctionSheetCellViewer(FunctionSheet *parent)
|
|||
/*! Called when the cell panel is left/right-clicked
|
||||
*/
|
||||
Spreadsheet::DragTool *FunctionSheetCellViewer::createDragTool(QMouseEvent *e) {
|
||||
int row = getViewer()->yToRow(e->pos().y());
|
||||
int col = getViewer()->xToColumn(e->pos().x());
|
||||
bool isEmpty = true;
|
||||
TDoubleParam *curve = m_sheet->getCurve(col);
|
||||
CellPosition cellPosition = getViewer()->xyToPosition(e->pos());
|
||||
int row = cellPosition.frame();
|
||||
int col = cellPosition.layer();
|
||||
bool isEmpty = true;
|
||||
TDoubleParam *curve = m_sheet->getCurve(col);
|
||||
if (curve) {
|
||||
int kCount = curve->getKeyframeCount();
|
||||
if (kCount > 0) {
|
||||
|
@ -665,8 +667,9 @@ void FunctionSheetCellViewer::drawCells(QPainter &painter, int r0, int c0,
|
|||
//-----------------------------------------------------------------------------
|
||||
|
||||
void FunctionSheetCellViewer::mouseDoubleClickEvent(QMouseEvent *e) {
|
||||
int row = getViewer()->yToRow(e->pos().y());
|
||||
int col = getViewer()->xToColumn(e->pos().x());
|
||||
CellPosition cellPosition = getViewer()->xyToPosition(e->pos());
|
||||
int row = cellPosition.frame();
|
||||
int col = cellPosition.layer();
|
||||
int x0, y0, x1, y1;
|
||||
x0 = getViewer()->columnToX(col);
|
||||
x1 = getViewer()->columnToX(col + 1) - 1;
|
||||
|
@ -737,8 +740,6 @@ void FunctionSheetCellViewer::mousePressEvent(QMouseEvent *e) {
|
|||
if (e->button() == Qt::LeftButton || e->button() == Qt::MidButton)
|
||||
Spreadsheet::CellPanel::mousePressEvent(e);
|
||||
else if (e->button() == Qt::RightButton) {
|
||||
int row = getViewer()->yToRow(e->pos().y());
|
||||
int col = getViewer()->xToColumn(e->pos().x());
|
||||
update();
|
||||
openContextMenu(e);
|
||||
}
|
||||
|
@ -749,8 +750,9 @@ void FunctionSheetCellViewer::mousePressEvent(QMouseEvent *e) {
|
|||
void FunctionSheetCellViewer::mouseReleaseEvent(QMouseEvent *e) {
|
||||
Spreadsheet::CellPanel::mouseReleaseEvent(e);
|
||||
/*
|
||||
int row = getViewer()->yToRow(e->pos().y());
|
||||
int col = getViewer()->xToColumn(e->pos().x());
|
||||
CellPosition cellPosition = getViewer ()->xyToPosition (e->pos ());
|
||||
int row = cellPosition.frame ();
|
||||
int col = cellPosition.layer ();
|
||||
FunctionSheet::DragTool *dragTool = m_sheet->getDragTool();
|
||||
if(dragTool) dragTool->release(row,col);
|
||||
m_sheet->setDragTool(0);
|
||||
|
@ -792,9 +794,10 @@ void FunctionSheetCellViewer::openContextMenu(QMouseEvent *e) {
|
|||
QAction setStep3Action(tr("Step 3"), 0);
|
||||
QAction setStep4Action(tr("Step 4"), 0);
|
||||
|
||||
int row = getViewer()->yToRow(e->pos().y());
|
||||
int col = getViewer()->xToColumn(e->pos().x());
|
||||
TDoubleParam *curve = m_sheet->getCurve(col);
|
||||
CellPosition cellPosition = getViewer()->xyToPosition(e->pos());
|
||||
int row = cellPosition.frame();
|
||||
int col = cellPosition.layer();
|
||||
TDoubleParam *curve = m_sheet->getCurve(col);
|
||||
if (!curve) return;
|
||||
|
||||
bool isEmpty = true;
|
||||
|
@ -947,14 +950,14 @@ void FunctionSheet::setSelection(FunctionSelection *selection) {
|
|||
//-----------------------------------------------------------------------------
|
||||
|
||||
void FunctionSheet::showEvent(QShowEvent *e) {
|
||||
registerFrameScroller();
|
||||
m_frameScroller.registerFrameScroller();
|
||||
SpreadsheetViewer::showEvent(e);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void FunctionSheet::hideEvent(QHideEvent *e) {
|
||||
unregisterFrameScroller();
|
||||
m_frameScroller.unregisterFrameScroller();
|
||||
SpreadsheetViewer::hideEvent(e);
|
||||
}
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#include "toonzqt/gutil.h"
|
||||
|
||||
#include "toonz/tframehandle.h"
|
||||
#include "orientation.h"
|
||||
|
||||
#include <QKeyEvent>
|
||||
#include <QWheelEvent>
|
||||
|
@ -21,60 +22,109 @@
|
|||
namespace Spreadsheet {
|
||||
|
||||
//=============================================================================
|
||||
FrameScroller::FrameScroller() {}
|
||||
FrameScroller::FrameScroller()
|
||||
: m_orientation(Orientations::topToBottom())
|
||||
, m_scrollArea(nullptr)
|
||||
, m_lastX(0)
|
||||
, m_lastY(0)
|
||||
,m_syncing(false){}
|
||||
|
||||
FrameScroller::~FrameScroller() {}
|
||||
|
||||
void FrameScroller::connectScroller(FrameScroller *scroller) {
|
||||
if (scroller != this && !m_connectedScrollers.contains(scroller)) {
|
||||
m_connectedScrollers.append(scroller);
|
||||
scroller->connectScroller(this);
|
||||
QScrollBar *sb0 = getFrameScrollArea()->verticalScrollBar();
|
||||
QScrollBar *sb1 = scroller->getFrameScrollArea()->verticalScrollBar();
|
||||
QObject::connect(sb0, SIGNAL(valueChanged(int)), sb1, SLOT(setValue(int)));
|
||||
QObject::connect(sb1, SIGNAL(valueChanged(int)), sb0, SLOT(setValue(int)));
|
||||
}
|
||||
void FrameScroller::setFrameScrollArea(QScrollArea *scrollArea) {
|
||||
disconnectScrollbars();
|
||||
m_scrollArea = scrollArea;
|
||||
connectScrollbars();
|
||||
}
|
||||
|
||||
void FrameScroller::disconnectScroller(FrameScroller *scroller) {
|
||||
if (m_connectedScrollers.contains(scroller)) {
|
||||
m_connectedScrollers.removeAll(scroller);
|
||||
scroller->disconnectScroller(this);
|
||||
QScrollBar *sb0 = getFrameScrollArea()->verticalScrollBar();
|
||||
QScrollBar *sb1 = scroller->getFrameScrollArea()->verticalScrollBar();
|
||||
QObject::disconnect(sb0, SIGNAL(valueChanged(int)), sb1,
|
||||
SLOT(setValue(int)));
|
||||
QObject::disconnect(sb1, SIGNAL(valueChanged(int)), sb0,
|
||||
SLOT(setValue(int)));
|
||||
}
|
||||
void FrameScroller::disconnectScrollbars() {
|
||||
if (!m_scrollArea) return;
|
||||
disconnect(m_scrollArea->verticalScrollBar(), &QScrollBar::valueChanged, this,
|
||||
&FrameScroller::onVScroll);
|
||||
disconnect(m_scrollArea->horizontalScrollBar(), &QScrollBar::valueChanged,
|
||||
this, &FrameScroller::onHScroll);
|
||||
}
|
||||
|
||||
bool FrameScroller::isScrollerConnected(FrameScroller *scroller) {
|
||||
return m_connectedScrollers.contains(scroller);
|
||||
void FrameScroller::connectScrollbars() {
|
||||
if (!m_scrollArea) return;
|
||||
m_lastX = m_scrollArea->horizontalScrollBar()->value();
|
||||
m_lastY = m_scrollArea->verticalScrollBar()->value();
|
||||
connect(m_scrollArea->verticalScrollBar(), &QScrollBar::valueChanged, this,
|
||||
&FrameScroller::onVScroll);
|
||||
connect(m_scrollArea->horizontalScrollBar(), &QScrollBar::valueChanged, this,
|
||||
&FrameScroller::onHScroll);
|
||||
}
|
||||
|
||||
void FrameScroller::onVScroll(int y) {
|
||||
QPoint offset(0, y - m_lastY);
|
||||
if (isSyncing()) return;
|
||||
m_lastY = y;
|
||||
setSyncing(true);
|
||||
handleScroll(offset);
|
||||
setSyncing(false);
|
||||
}
|
||||
void FrameScroller::onHScroll(int x) {
|
||||
QPoint offset(x - m_lastX, 0);
|
||||
if (isSyncing()) return;
|
||||
m_lastX = x;
|
||||
setSyncing(true);
|
||||
handleScroll(offset);
|
||||
setSyncing(false);
|
||||
}
|
||||
|
||||
static QList<FrameScroller *> frameScrollers;
|
||||
|
||||
void FrameScroller::handleScroll(const QPoint &offset) const {
|
||||
CellPositionRatio ratio = orientation()->xyToPositionRatio(offset);
|
||||
if( (m_orientation->isVerticalTimeline() && offset.x())
|
||||
|| (!m_orientation->isVerticalTimeline() && offset.y())) // only synchronize changes by frames axis
|
||||
return;
|
||||
|
||||
for (int i = 0; i < frameScrollers.size(); i++)
|
||||
if (frameScrollers[i] != this)
|
||||
{
|
||||
if (!frameScrollers[i]->isSyncing())
|
||||
{
|
||||
frameScrollers[i]->onScroll(ratio);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void adjustScrollbar(QScrollBar *scrollBar, int add);
|
||||
|
||||
void FrameScroller::onScroll(const CellPositionRatio &ratio) {
|
||||
QPoint offset = orientation()->positionRatioToXY(ratio);
|
||||
if (offset.x())
|
||||
adjustScrollbar(m_scrollArea->horizontalScrollBar(),
|
||||
offset.x());
|
||||
if (offset.y())
|
||||
adjustScrollbar(m_scrollArea->verticalScrollBar(),
|
||||
offset.y());
|
||||
|
||||
emit prepareToScrollOffset(offset);
|
||||
}
|
||||
void adjustScrollbar(QScrollBar *scrollBar, int add) {
|
||||
scrollBar->setValue(scrollBar->value() + add);
|
||||
}
|
||||
|
||||
void FrameScroller::registerFrameScroller() {
|
||||
if (!frameScrollers.contains(this)) {
|
||||
for (int i = 0; i < frameScrollers.size(); i++)
|
||||
connectScroller(frameScrollers[i]);
|
||||
frameScrollers.append(this);
|
||||
}
|
||||
if (!frameScrollers.contains(this)) frameScrollers.append(this);
|
||||
}
|
||||
|
||||
void FrameScroller::unregisterFrameScroller() {
|
||||
if (frameScrollers.contains(this)) {
|
||||
frameScrollers.removeAll(this);
|
||||
for (int i = 0; i < frameScrollers.size(); i++)
|
||||
disconnectScroller(frameScrollers[i]);
|
||||
}
|
||||
if (frameScrollers.contains(this)) frameScrollers.removeAll(this);
|
||||
}
|
||||
|
||||
void FrameScroller::prepareToScroll(int dy) {
|
||||
if (dy == 0) return;
|
||||
void FrameScroller::prepareToScrollOthers(const QPoint &offset) {
|
||||
CellPositionRatio ratio = orientation()->xyToPositionRatio(offset);
|
||||
for (int i = 0; i < frameScrollers.size(); i++)
|
||||
if (frameScrollers[i] != this) frameScrollers[i]->onPrepareToScroll(dy);
|
||||
if (frameScrollers[i] != this)
|
||||
frameScrollers[i]->prepareToScrollRatio(ratio);
|
||||
}
|
||||
void FrameScroller::prepareToScrollRatio(const CellPositionRatio &ratio) {
|
||||
QPoint offset = orientation()->positionRatioToXY(ratio);
|
||||
emit prepareToScrollOffset(offset);
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
|
@ -188,14 +238,16 @@ void GenericPanel::mousePressEvent(QMouseEvent *e) {
|
|||
else
|
||||
m_dragTool = createDragTool(e);
|
||||
|
||||
int row = getViewer()->yToRow(e->pos().y());
|
||||
int col = getViewer()->xToColumn(e->pos().x());
|
||||
CellPosition cellPosition = getViewer()->xyToPosition(e->pos());
|
||||
int row = cellPosition.frame();
|
||||
int col = cellPosition.layer();
|
||||
if (m_dragTool) m_dragTool->click(row, col, e);
|
||||
}
|
||||
|
||||
void GenericPanel::mouseReleaseEvent(QMouseEvent *e) {
|
||||
int row = getViewer()->yToRow(e->pos().y());
|
||||
int col = getViewer()->xToColumn(e->pos().x());
|
||||
CellPosition cellPosition = getViewer()->xyToPosition(e->pos());
|
||||
int row = cellPosition.frame();
|
||||
int col = cellPosition.layer();
|
||||
m_viewer->stopAutoPan();
|
||||
if (m_dragTool) {
|
||||
m_dragTool->release(row, col, e);
|
||||
|
@ -205,8 +257,9 @@ void GenericPanel::mouseReleaseEvent(QMouseEvent *e) {
|
|||
}
|
||||
|
||||
void GenericPanel::mouseMoveEvent(QMouseEvent *e) {
|
||||
int row = getViewer()->yToRow(e->pos().y());
|
||||
int col = getViewer()->xToColumn(e->pos().x());
|
||||
CellPosition cellPosition = getViewer()->xyToPosition(e->pos());
|
||||
int row = cellPosition.frame();
|
||||
int col = cellPosition.layer();
|
||||
if (e->buttons() != 0 && m_dragTool != 0) {
|
||||
if ((e->buttons() & Qt::LeftButton) != 0 &&
|
||||
!visibleRegion().contains(e->pos())) {
|
||||
|
@ -289,9 +342,10 @@ void RowPanel::paintEvent(QPaintEvent *e) {
|
|||
QRect toBeUpdated = e->rect();
|
||||
QPainter p(this);
|
||||
|
||||
// range di righe visibili
|
||||
int r0 = getViewer()->yToRow(toBeUpdated.top());
|
||||
int r1 = getViewer()->yToRow(toBeUpdated.bottom());
|
||||
CellRange visible = getViewer()->xyRectToRange(toBeUpdated);
|
||||
// range of visible rows
|
||||
int r0 = visible.from().frame();
|
||||
int r1 = visible.to().frame();
|
||||
|
||||
p.setClipRect(toBeUpdated);
|
||||
p.fillRect(toBeUpdated, QBrush(getViewer()->getLightLightBGColor()));
|
||||
|
@ -324,13 +378,15 @@ void CellPanel::paintEvent(QPaintEvent *e) {
|
|||
int y0 = toBeUpdated.top();
|
||||
int x1 = toBeUpdated.right(), y1 = toBeUpdated.bottom();
|
||||
|
||||
QRect alteredRect(QPoint(x0, y0), QPoint(x1, y1));
|
||||
CellRange cellRange = getViewer()->xyRectToRange(alteredRect);
|
||||
// visible rows range
|
||||
int r0 = getViewer()->yToRow(y0);
|
||||
int r1 = getViewer()->yToRow(y1);
|
||||
int r0 = cellRange.from().frame();
|
||||
int r1 = cellRange.to().frame();
|
||||
|
||||
// visible columns range
|
||||
int c0 = getViewer()->xToColumn(x0);
|
||||
int c1 = getViewer()->xToColumn(x1);
|
||||
int c0 = cellRange.from().layer();
|
||||
int c1 = cellRange.to().layer();
|
||||
|
||||
// cambia colore alle celle prima di rowCount()
|
||||
int rowCount = getViewer()->getRowCount();
|
||||
|
@ -389,7 +445,10 @@ SpreadsheetViewer::SpreadsheetViewer(QWidget *parent)
|
|||
, m_currentRow(0)
|
||||
, m_markRowDistance(6)
|
||||
, m_markRowOffset(0)
|
||||
, m_isComputingSize(false) {
|
||||
, m_isComputingSize(false)
|
||||
, m_frameScroller() {
|
||||
// m_orientation = Orientations::topToBottom ();
|
||||
|
||||
setFocusPolicy(Qt::NoFocus);
|
||||
|
||||
setFrameStyle(QFrame::StyledPanel);
|
||||
|
@ -427,6 +486,10 @@ SpreadsheetViewer::SpreadsheetViewer(QWidget *parent)
|
|||
m_columnScrollArea->setFixedHeight(m_rowHeight * 3 - 3);
|
||||
// m_columnScrollArea->setFixedHeight(m_rowHeight * 3 + 60 - 63);
|
||||
|
||||
m_frameScroller.setFrameScrollArea(m_cellScrollArea);
|
||||
connect(&m_frameScroller, &Spreadsheet::FrameScroller::prepareToScrollOffset,
|
||||
this, &SpreadsheetViewer::onPrepareToScrollOffset);
|
||||
|
||||
//---- layout
|
||||
QGridLayout *layout = new QGridLayout();
|
||||
layout->setMargin(0);
|
||||
|
@ -520,7 +583,6 @@ void SpreadsheetViewer::setColumnCount(int columnCount) {
|
|||
void SpreadsheetViewer::scroll(QPoint delta) {
|
||||
int x = delta.x();
|
||||
int y = delta.y();
|
||||
prepareToScroll(y);
|
||||
|
||||
QScrollBar *hSc = m_cellScrollArea->horizontalScrollBar();
|
||||
QScrollBar *vSc = m_cellScrollArea->verticalScrollBar();
|
||||
|
@ -547,6 +609,10 @@ void SpreadsheetViewer::scroll(QPoint delta) {
|
|||
vSc->setValue(valueV);
|
||||
}
|
||||
|
||||
void SpreadsheetViewer::onPrepareToScrollOffset(const QPoint &offset) {
|
||||
refreshContentSize(offset.x(), offset.y());
|
||||
}
|
||||
|
||||
void SpreadsheetViewer::setAutoPanSpeed(const QPoint &speed) {
|
||||
bool wasAutoPanning = isAutoPanning();
|
||||
m_autoPanSpeed = speed;
|
||||
|
@ -583,21 +649,42 @@ void SpreadsheetViewer::setAutoPanSpeed(const QRect &widgetBounds,
|
|||
m_lastAutoPanPos = mousePos;
|
||||
}
|
||||
|
||||
/*!Shift is a consequence of style sheet border.*/
|
||||
int SpreadsheetViewer::xToColumn(int x) const {
|
||||
return (x + 1) / m_columnWidth;
|
||||
CellPosition pos = xyToPosition(QPoint(x, 0));
|
||||
return pos.layer();
|
||||
}
|
||||
int SpreadsheetViewer::yToRow(int y) const {
|
||||
CellPosition pos = xyToPosition(QPoint(0, y));
|
||||
return pos.frame();
|
||||
}
|
||||
|
||||
/*!Shift is a consequence of style sheet border.*/
|
||||
int SpreadsheetViewer::columnToX(int col) const {
|
||||
return (col * m_columnWidth) - 1;
|
||||
QPoint xy = positionToXY(CellPosition(0, col));
|
||||
return xy.x();
|
||||
}
|
||||
int SpreadsheetViewer::rowToY(int row) const {
|
||||
QPoint xy = positionToXY(CellPosition(row, 0));
|
||||
return xy.y();
|
||||
}
|
||||
|
||||
/*!Shift is a consequence of style sheet border.*/
|
||||
int SpreadsheetViewer::yToRow(int y) const { return (y + 1) / m_rowHeight; }
|
||||
CellPosition SpreadsheetViewer::xyToPosition(const QPoint &point) const {
|
||||
int row = (point.y() + 1) / m_rowHeight;
|
||||
int col = (point.x() + 1) / m_columnWidth;
|
||||
return CellPosition(row, col);
|
||||
}
|
||||
|
||||
/*!Shift is a consequence of style sheet border.*/
|
||||
int SpreadsheetViewer::rowToY(int row) const { return (row * m_rowHeight) - 1; }
|
||||
QPoint SpreadsheetViewer::positionToXY(const CellPosition &pos) const {
|
||||
int x = (pos.layer() * m_columnWidth) - 1;
|
||||
int y = (pos.frame() * m_rowHeight) - 1;
|
||||
return QPoint(x, y);
|
||||
}
|
||||
|
||||
CellRange SpreadsheetViewer::xyRectToRange(const QRect &rect) const {
|
||||
CellPosition topLeft = xyToPosition(rect.topLeft());
|
||||
CellPosition bottomRight = xyToPosition(rect.bottomRight());
|
||||
return CellRange(topLeft, bottomRight);
|
||||
}
|
||||
|
||||
bool SpreadsheetViewer::refreshContentSize(int scrollDx, int scrollDy) {
|
||||
QSize viewportSize = m_cellScrollArea->viewport()->size();
|
||||
|
|
Loading…
Reference in a new issue