/*** Olive - Non-Linear Video Editor Copyright (C) 2022 Olive Team Modifications Copyright (C) 2025 mikesolar This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . ***/ #ifndef POINTERTIMELINETOOL_H #define POINTERTIMELINETOOL_H #include "tool.h" namespace olive { class PointerTool : public TimelineTool { public: PointerTool(TimelineWidget *parent); virtual void MousePress(TimelineViewMouseEvent *event) override; virtual void MouseMove(TimelineViewMouseEvent *event) override; virtual void MouseRelease(TimelineViewMouseEvent *event) override; virtual void HoverMove(TimelineViewMouseEvent *event) override; protected: virtual void FinishDrag(TimelineViewMouseEvent *event); virtual void InitiateDrag(Block *clicked_item, Timeline::MovementMode trim_mode, Qt::KeyboardModifiers modifiers); TimelineViewGhostItem *GetExistingGhostFromBlock(Block *block); TimelineViewGhostItem *AddGhostFromBlock(Block *block, Timeline::MovementMode mode, bool check_if_exists = false); TimelineViewGhostItem *AddGhostFromNull(const rational &in, const rational &out, const Track::Reference &track, Timeline::MovementMode mode); /** * @brief Validates Ghosts that are getting their in points trimmed * * Assumes ghost->data() is a Block. Ensures no Ghost's in point becomes a negative timecode. Also ensures no * Ghost's length becomes 0 or negative. */ rational ValidateInTrimming(rational movement); /** * @brief Validates Ghosts that are getting their out points trimmed * * Assumes ghost->data() is a Block. Ensures no Ghost's in point becomes a negative timecode. Also ensures no * Ghost's length becomes 0 or negative. */ rational ValidateOutTrimming(rational movement); virtual void ProcessDrag(const TimelineCoordinate &mouse_pos); void InitiateDragInternal(Block *clicked_item, Timeline::MovementMode trim_mode, Qt::KeyboardModifiers modifiers, bool dont_roll_trims, bool allow_nongap_rolling, bool slide_instead_of_moving); const Timeline::MovementMode &drag_movement_mode() const { return drag_movement_mode_; } void set_drag_movement_mode(const Timeline::MovementMode &d) { drag_movement_mode_ = d; } static bool CanTransitionMove(TransitionBlock *transit, const QVector &clips); void SetMovementAllowed(bool e) { movement_allowed_ = e; } void SetTrimmingAllowed(bool e) { trimming_allowed_ = e; } void SetTrackMovementAllowed(bool e) { track_movement_allowed_ = e; } void SetGapTrimmingAllowed(bool e) { gap_trimming_allowed_ = e; } void SetClickedItem(Block *b) { clicked_item_ = b; } private: Timeline::MovementMode IsCursorInTrimHandle(Block *block, qreal cursor_x); void AddGhostInternal(TimelineViewGhostItem *ghost, Timeline::MovementMode mode); bool IsClipTrimmable(Block *clip, const QVector &items, const Timeline::MovementMode &mode); void ProcessGhostsForSliding(); void ProcessGhostsForRolling(); bool movement_allowed_; bool trimming_allowed_; bool track_movement_allowed_; bool gap_trimming_allowed_; bool can_rubberband_select_; bool rubberband_selecting_; Track::Type drag_track_type_; Timeline::MovementMode drag_movement_mode_; Block *clicked_item_; QPoint drag_global_start_; }; } #endif // POINTERTIMELINETOOL_H