Initial implementation of I-Beam tool. Needs more work

This commit is contained in:
Joel Holdsworth 2008-08-07 20:27:41 +01:00
parent 45ca590c38
commit 2082f0843b
12 changed files with 428 additions and 133 deletions

View file

@ -21,8 +21,6 @@
* *****************************************************/
#include "timeline-widget.hpp"
#include "timeline/timeline-arrow-tool.hpp"
#include "timeline/timeline-ibeam-tool.hpp"
#include <boost/foreach.hpp>
@ -46,14 +44,17 @@ TimelineWidget::TimelineWidget() :
totalHeight(0),
horizontalAdjustment(0, 0, 0),
verticalAdjustment(0, 0, 0),
selectionStart(0),
selectionEnd(0),
horizontalScroll(horizontalAdjustment),
verticalScroll(verticalAdjustment),
tool(NULL)
verticalScroll(verticalAdjustment)
{
body = new TimelineBody(this);
ENSURE(body != NULL);
headerContainer = new HeaderContainer(this);
ENSURE(headerContainer != NULL);
ruler = new TimelineRuler(this);
ENSURE(ruler != NULL);
horizontalAdjustment.signal_value_changed().connect( sigc::mem_fun(
this, &TimelineWidget::on_scroll) );
@ -63,9 +64,10 @@ TimelineWidget::TimelineWidget() :
this, &TimelineWidget::on_motion_in_body_notify_event) );
set_time_scale(GAVL_TIME_SCALE / 200);
set_selection(2000000, 4000000);
attach(*body, 1, 2, 1, 2, FILL|EXPAND, FILL|EXPAND);
attach(ruler, 1, 2, 0, 1, FILL|EXPAND, SHRINK);
attach(*ruler, 1, 2, 0, 1, FILL|EXPAND, SHRINK);
attach(*headerContainer, 0, 1, 1, 2, SHRINK, FILL|EXPAND);
attach(horizontalScroll, 1, 2, 2, 3, FILL|EXPAND, SHRINK);
attach(verticalScroll, 2, 3, 1, 2, SHRINK, FILL|EXPAND);
@ -87,10 +89,10 @@ TimelineWidget::~TimelineWidget()
REQUIRE(headerContainer != NULL);
if(headerContainer != NULL)
headerContainer->unreference();
REQUIRE(tool != NULL);
if(tool != NULL)
delete tool;
REQUIRE(ruler != NULL);
if(ruler != NULL)
ruler->unreference();
}
gavl_time_t
@ -102,9 +104,11 @@ TimelineWidget::get_time_offset() const
void
TimelineWidget::set_time_offset(gavl_time_t time_offset)
{
REQUIRE(ruler != NULL);
timeOffset = time_offset;
horizontalAdjustment.set_value(time_offset);
ruler.set_time_offset(time_offset);
ruler->update_view();
}
int64_t
@ -116,11 +120,14 @@ TimelineWidget::get_time_scale() const
void
TimelineWidget::set_time_scale(int64_t time_scale)
{
REQUIRE(ruler != NULL);
timeScale = time_scale;
ruler.set_time_scale(time_scale);
const int view_width = body->get_allocation().get_width();
horizontalAdjustment.set_page_size(timeScale * view_width);
ruler->update_view();
}
void
@ -163,49 +170,56 @@ TimelineWidget::shift_view(int shift_size)
shift_size * timeScale * view_width / 16);
}
gavl_time_t
TimelineWidget::get_selection_start() const
{
return selectionStart;
}
gavl_time_t
TimelineWidget::get_selection_end() const
{
return selectionEnd;
}
void
TimelineWidget::set_selection(gavl_time_t start, gavl_time_t end)
{
if(start < end)
{
selectionStart = start;
selectionEnd = end;
}
else
{
// The selection is back-to-front, flip it round
selectionStart = end;
selectionEnd = start;
}
ruler->queue_draw();
body->queue_draw();
}
ToolType
TimelineWidget::get_tool() const
{
REQUIRE(tool != NULL);
if(tool != NULL)
return tool->get_type();
return None;
REQUIRE(body != NULL);
return body->get_tool();
}
void
TimelineWidget::set_tool(ToolType tool_type)
{
// Tidy up old tool
if(tool != NULL)
{
// Do we need to change tools?
if(tool->get_type() == tool_type)
return;
delete tool;
}
// Create the new tool
switch(tool_type)
{
case timeline::Arrow:
tool = new timeline::ArrowTool(this);
break;
case timeline::IBeam:
tool = new timeline::IBeamTool(this);
break;
}
// Apply the cursor if possible
tool->apply_cursor();
REQUIRE(body != NULL);
body->set_tool(tool_type);
}
void
TimelineWidget::on_scroll()
{
timeOffset = horizontalAdjustment.get_value();
ruler.set_time_offset(timeOffset);
ruler->update_view();
}
void
@ -216,6 +230,18 @@ TimelineWidget::on_size_allocate(Allocation& allocation)
update_scroll();
}
int
TimelineWidget::time_to_x(gavl_time_t time) const
{
return (int)((time - timeOffset) / timeScale);
}
gavl_time_t
TimelineWidget::x_to_time(int x) const
{
return (gavl_time_t)((int64_t)x * timeScale + timeOffset);
}
void
TimelineWidget::update_tracks()
{
@ -282,7 +308,7 @@ bool
TimelineWidget::on_motion_in_body_notify_event(GdkEventMotion *event)
{
REQUIRE(event != NULL);
ruler.set_mouse_chevron_offset(event->x);
ruler->set_mouse_chevron_offset(event->x);
return true;
}

View file

@ -31,6 +31,8 @@
#include "timeline/timeline-body.hpp"
#include "timeline/timeline-ruler.hpp"
#include "timeline/timeline-tool.hpp"
#include "timeline/timeline-arrow-tool.hpp"
#include "timeline/timeline-ibeam-tool.hpp"
#include "timeline/track.hpp"
namespace lumiera {
@ -96,18 +98,30 @@ public:
**/
void shift_view(int shift_size);
gavl_time_t get_selection_start() const;
gavl_time_t get_selection_end() const;
void set_selection(gavl_time_t start, gavl_time_t end);
timeline::ToolType get_tool() const;
void set_tool(timeline::ToolType tool_type);
/* ===== Events ===== */
protected:
void on_scroll();
void on_size_allocate(Gtk::Allocation& allocation);
/* ===== Utilities ===== */
protected:
int time_to_x(gavl_time_t time) const;
gavl_time_t x_to_time(int x) const;
/* ===== Internals ===== */
protected:
private:
void update_tracks();
@ -118,8 +132,14 @@ protected:
bool on_motion_in_body_notify_event(GdkEventMotion *event);
protected:
// View State
gavl_time_t timeOffset;
int64_t timeScale;
// Selection State
gavl_time_t selectionStart;
gavl_time_t selectionEnd;
int totalHeight;
@ -129,13 +149,11 @@ protected:
timeline::HeaderContainer *headerContainer;
timeline::TimelineBody *body;
timeline::TimelineRuler ruler;
timeline::TimelineRuler *ruler;
Gtk::Adjustment horizontalAdjustment, verticalAdjustment;
Gtk::HScrollbar horizontalScroll;
Gtk::VScrollbar verticalScroll;
timeline::Tool *tool;
/* ===== Constants ===== */
public:
@ -148,7 +166,10 @@ protected:
friend class timeline::TimelineBody;
friend class timeline::HeaderContainer;
friend class timeline::TimelineRuler;
friend class timeline::Tool;
friend class timeline::ArrowTool;
friend class timeline::IBeamTool;
};
} // namespace widgets

View file

@ -27,8 +27,8 @@ namespace gui {
namespace widgets {
namespace timeline {
ArrowTool::ArrowTool(TimelineWidget *timeline_widget) :
Tool(timeline_widget)
ArrowTool::ArrowTool(TimelineBody *timeline_body) :
Tool(timeline_body)
{
}
@ -45,6 +45,24 @@ ArrowTool::get_cursor() const
return Gdk::Cursor(Gdk::ARROW);
}
void
ArrowTool::on_button_press_event(GdkEventButton* event)
{
Tool::on_button_press_event(event);
}
void
ArrowTool::on_button_release_event(GdkEventButton* event)
{
Tool::on_button_release_event(event);
}
void
ArrowTool::on_motion_notify_event(GdkEventMotion *event)
{
Tool::on_motion_notify_event(event);
}
} // namespace timeline
} // namespace widgets
} // namespace gui

View file

@ -37,12 +37,17 @@ namespace timeline {
class ArrowTool : public Tool
{
public:
ArrowTool(TimelineWidget *timeline_widget);
ArrowTool(TimelineBody *timeline_body);
ToolType get_type() const;
protected:
Gdk::Cursor get_cursor() const;
protected:
void on_button_press_event(GdkEventButton* event);
void on_button_release_event(GdkEventButton* event);
void on_motion_notify_event(GdkEventMotion *event);
};
} // namespace timeline

View file

@ -27,6 +27,9 @@
#include "../timeline-widget.hpp"
#include "../../window-manager.hpp"
#include "timeline-arrow-tool.hpp"
#include "timeline-ibeam-tool.hpp"
using namespace Gtk;
using namespace std;
using namespace lumiera::gui;
@ -38,8 +41,10 @@ namespace gui {
namespace widgets {
namespace timeline {
TimelineBody::TimelineBody(lumiera::gui::widgets::TimelineWidget *timeline_widget) :
TimelineBody::TimelineBody(lumiera::gui::widgets::TimelineWidget
*timeline_widget) :
Glib::ObjectBase("TimelineBody"),
tool(NULL),
dragType(None),
mouseDownX(0),
mouseDownY(0),
@ -63,6 +68,51 @@ TimelineBody::TimelineBody(lumiera::gui::widgets::TimelineWidget *timeline_widge
GDK_TYPE_COLOR, G_PARAM_READABLE));
}
TimelineBody::~TimelineBody()
{
REQUIRE(tool != NULL);
if(tool != NULL)
delete tool;
}
ToolType
TimelineBody::get_tool() const
{
REQUIRE(tool != NULL);
if(tool != NULL)
return tool->get_type();
return lumiera::gui::widgets::timeline::None;
}
void
TimelineBody::set_tool(timeline::ToolType tool_type)
{
// Tidy up old tool
if(tool != NULL)
{
// Do we need to change tools?
if(tool->get_type() == tool_type)
return;
delete tool;
}
// Create the new tool
switch(tool_type)
{
case timeline::Arrow:
tool = new ArrowTool(this);
break;
case timeline::IBeam:
tool = new IBeamTool(this);
break;
}
// Apply the cursor if possible
tool->apply_cursor();
}
void
TimelineBody::on_realize()
{
@ -76,7 +126,7 @@ TimelineBody::on_realize()
Gdk::BUTTON_RELEASE_MASK);
// Apply the cursor if possible
timelineWidget->tool->apply_cursor();
tool->apply_cursor();
}
void
@ -138,7 +188,12 @@ TimelineBody::on_button_press_event(GdkEventButton* event)
default:
dragType = None;
break;
}
}
// Forward the event to the tool
tool->on_button_press_event(event);
return true;
}
bool
@ -146,11 +201,16 @@ TimelineBody::on_button_release_event(GdkEventButton* event)
{
// Terminate any drags
dragType = None;
// Forward the event to the tool
tool->on_button_release_event(event);
return true;
}
bool
TimelineBody::on_motion_notify_event(GdkEventMotion *event)
{
{
REQUIRE(event != NULL);
switch(dragType)
@ -168,6 +228,9 @@ TimelineBody::on_motion_notify_event(GdkEventMotion *event)
}
}
// Forward the event to the tool
tool->on_motion_notify_event(event);
// false so that the message is passed up to the owner TimelineWidget
return false;
}
@ -175,6 +238,8 @@ TimelineBody::on_motion_notify_event(GdkEventMotion *event)
bool
TimelineBody::on_expose_event(GdkEventExpose* event)
{
Cairo::Matrix view_matrix;
REQUIRE(event != NULL);
REQUIRE(timelineWidget != NULL);
@ -196,6 +261,7 @@ TimelineBody::on_expose_event(GdkEventExpose* event)
// Translate the view by the scroll distance
cairo->translate(0, -get_vertical_offset());
cairo->get_matrix(view_matrix);
// Interate drawing each track
BOOST_FOREACH( Track* track, timelineWidget->tracks )
@ -217,8 +283,44 @@ TimelineBody::on_expose_event(GdkEventExpose* event)
// Shift for the next track
cairo->translate(0, height + TimelineWidget::TrackPadding);
}
}
//----- Draw the selection -----//
const int start_x = timelineWidget->time_to_x(
timelineWidget->get_selection_start());
const int end_x = timelineWidget->time_to_x(
timelineWidget->get_selection_end());
cairo->set_matrix(view_matrix);
// Draw the cover
if(end_x > 0 && start_x < allocation.get_width())
{
cairo->set_source_rgba(1.0, 0, 0, 0.5);
cairo->rectangle(start_x + 0.5, 0,
end_x - start_x, allocation.get_height());
cairo->fill();
}
cairo->set_source_rgb(1.0, 0, 0);
cairo->set_line_width(1);
// Draw the start
if(start_x >= 0 && start_x < allocation.get_width())
{
cairo->move_to(start_x + 0.5, 0);
cairo->line_to(start_x + 0.5, allocation.get_height());
cairo->stroke_preserve();
}
// Draw the end
if(end_x >= 0 && end_x < allocation.get_width())
{
cairo->move_to(end_x + 0.5, 0);
cairo->line_to(end_x + 0.5, allocation.get_height());
cairo->stroke_preserve();
}
return true;
}

View file

@ -27,6 +27,7 @@
#define TIMELINE_BODY_HPP
#include "../../gtk-lumiera.hpp"
#include "timeline-tool.hpp"
namespace lumiera {
namespace gui {
@ -40,6 +41,12 @@ class TimelineBody : public Gtk::DrawingArea
{
public:
TimelineBody(lumiera::gui::widgets::TimelineWidget *timeline_widget);
~TimelineBody();
ToolType get_tool() const;
void set_tool(ToolType tool_type);
/* ===== Events ===== */
protected:
@ -76,15 +83,20 @@ private:
Shift
};
// UI State Data
DragType dragType;
timeline::Tool *tool;
double mouseDownX, mouseDownY;
// Scroll State
DragType dragType;
gavl_time_t beginShiftTimeOffset;
int beginShiftVerticalOffset;
int beginShiftVerticalOffset;
GdkColor background;
lumiera::gui::widgets::TimelineWidget *timelineWidget;
friend class ArrowTool;
friend class IBeamTool;
};
} // namespace timeline

View file

@ -21,14 +21,15 @@
* *****************************************************/
#include "timeline-ibeam-tool.hpp"
#include "../timeline-widget.hpp"
namespace lumiera {
namespace gui {
namespace widgets {
namespace timeline {
IBeamTool::IBeamTool(TimelineWidget *timeline_widget) :
Tool(timeline_widget)
IBeamTool::IBeamTool(TimelineBody *timeline_body) :
Tool(timeline_body)
{
}
@ -44,6 +45,55 @@ IBeamTool::get_cursor() const
return Gdk::Cursor(Gdk::XTERM);
}
void
IBeamTool::on_button_press_event(GdkEventButton* event)
{
Tool::on_button_press_event(event);
REQUIRE(timelineBody != NULL);
lumiera::gui::widgets::TimelineWidget *timeline_widget =
timelineBody->timelineWidget;
REQUIRE(timeline_widget != NULL);
if(event->button == 1)
{
drag_start_time = timeline_widget->x_to_time(event->x);
timeline_widget->set_selection(drag_start_time, drag_start_time);
}
}
void
IBeamTool::on_button_release_event(GdkEventButton* event)
{
Tool::on_button_release_event(event);
if(event->button == 1)
set_leading_x(event->x);
}
void
IBeamTool::on_motion_notify_event(GdkEventMotion *event)
{
Tool::on_motion_notify_event(event);
if(isDragging)
set_leading_x(event->x);
}
void IBeamTool::set_leading_x(const int x)
{
REQUIRE(timelineBody != NULL);
lumiera::gui::widgets::TimelineWidget *timeline_widget =
timelineBody->timelineWidget;
REQUIRE(timeline_widget != NULL);
const gavl_time_t time = timeline_widget->x_to_time(x);
if(time > drag_start_time)
timeline_widget->set_selection(drag_start_time, time);
else
timeline_widget->set_selection(time, drag_start_time);
}
} // namespace timeline
} // namespace widgets
} // namespace gui

View file

@ -38,12 +38,24 @@ namespace timeline {
class IBeamTool : public Tool
{
public:
IBeamTool(TimelineWidget *timeline_widget);
IBeamTool(TimelineBody *timeline_body);
ToolType get_type() const;
protected:
Gdk::Cursor get_cursor() const;
protected:
void on_button_press_event(GdkEventButton* event);
void on_button_release_event(GdkEventButton* event);
void on_motion_notify_event(GdkEventMotion *event);
private:
void set_leading_x(const int x);
protected:
//----- Internals -----//
gavl_time_t drag_start_time;
};
} // namespace timeline

View file

@ -23,6 +23,7 @@
#include <cairomm-1.0/cairomm/cairomm.h>
#include "timeline-ruler.hpp"
#include "../timeline-widget.hpp"
#include "../../window-manager.hpp"
extern "C" {
@ -41,39 +42,24 @@ namespace gui {
namespace widgets {
namespace timeline {
TimelineRuler::TimelineRuler() :
TimelineRuler::TimelineRuler(
lumiera::gui::widgets::TimelineWidget *timeline_widget) :
Glib::ObjectBase("TimelineRuler"),
timeOffset(-1),
timeScale(1),
mouseChevronOffset(0),
annotationHorzMargin(0),
annotationVertMargin(0),
majorTickHeight(0),
minorLongTickHeight(0),
minorShortTickHeight(0),
minDivisionWidth(100)
{
minDivisionWidth(100),
timelineWidget(timeline_widget)
{
REQUIRE(timelineWidget != NULL);
// Install style properties
register_styles();
}
void
TimelineRuler::set_time_offset(gavl_time_t time_offset)
{
timeOffset = time_offset;
rulerImage.clear();
queue_draw();
}
void
TimelineRuler::set_time_scale(int64_t time_scale)
{
REQUIRE(time_scale > 0);
timeScale = time_scale;
rulerImage.clear();
queue_draw();
}
void
TimelineRuler::set_mouse_chevron_offset(int offset)
{
@ -81,6 +67,13 @@ TimelineRuler::set_mouse_chevron_offset(int offset)
queue_draw();
}
void
TimelineRuler::update_view()
{
rulerImage.clear();
queue_draw();
}
void
TimelineRuler::on_realize()
{
@ -132,8 +125,9 @@ TimelineRuler::on_expose_event(GdkEventExpose* event)
cairo->set_source(rulerImage, 0, 0);
cairo->paint();
// Draw the mouse chevron
// Draw the overlays
draw_mouse_chevron(cairo, allocation);
draw_selection(cairo, allocation);
return true;
}
@ -168,11 +162,15 @@ TimelineRuler::on_size_allocate(Gtk::Allocation& allocation)
void
TimelineRuler::draw_ruler(Cairo::RefPtr<Cairo::Context> cairo,
Gdk::Rectangle ruler_rect)
const Gdk::Rectangle ruler_rect)
{
REQUIRE(cairo);
REQUIRE(ruler_rect.get_width() > 0);
REQUIRE(ruler_rect.get_height() > 0);
REQUIRE(timelineWidget != NULL);
const gavl_time_t left_offset = timelineWidget->timeOffset;
const int64_t time_scale = timelineWidget->timeScale;
// Preparation steps
const int height = ruler_rect.get_height();
@ -187,7 +185,7 @@ TimelineRuler::draw_ruler(Cairo::RefPtr<Cairo::Context> cairo,
cairo->clip();
// Make sure we don't have impossible zoom
if(timeScale <= 0)
if(time_scale <= 0)
return;
// Render ruler annotations
@ -196,16 +194,16 @@ TimelineRuler::draw_ruler(Cairo::RefPtr<Cairo::Context> cairo,
const gavl_time_t major_spacing = calculate_major_spacing();
const gavl_time_t minor_spacing = major_spacing / 10;
int64_t time_offset = timeOffset - timeOffset % major_spacing;
if(timeOffset < 0)
int64_t time_offset = left_offset - left_offset % major_spacing;
if(left_offset < 0)
time_offset -= major_spacing;
int x = 0;
const int64_t x_offset = timeOffset / timeScale;
const int64_t x_offset = left_offset / time_scale;
do
{
x = (int)(time_offset / timeScale - x_offset);
x = (int)(time_offset / time_scale - x_offset);
cairo->set_line_width(1);
@ -241,7 +239,7 @@ TimelineRuler::draw_ruler(Cairo::RefPtr<Cairo::Context> cairo,
void
TimelineRuler::draw_mouse_chevron(Cairo::RefPtr<Cairo::Context> cairo,
Gdk::Rectangle ruler_rect)
const Gdk::Rectangle ruler_rect)
{
REQUIRE(cairo);
REQUIRE(ruler_rect.get_width() > 0);
@ -258,19 +256,55 @@ TimelineRuler::draw_mouse_chevron(Cairo::RefPtr<Cairo::Context> cairo,
cairo->move_to(mouseChevronOffset + 0.5,
ruler_rect.get_height());
cairo->line_to(mouseChevronOffset + mouseChevronSize + 0.5,
ruler_rect.get_height() - mouseChevronSize);
cairo->line_to(mouseChevronOffset - mouseChevronSize + 0.5,
ruler_rect.get_height() - mouseChevronSize);
cairo->rel_line_to(-mouseChevronSize, -mouseChevronSize);
cairo->rel_line_to(2 * mouseChevronSize, 0);
cairo->fill();
}
void
TimelineRuler::draw_selection(Cairo::RefPtr<Cairo::Context> cairo,
const Gdk::Rectangle ruler_rect)
{
REQUIRE(cairo);
REQUIRE(ruler_rect.get_width() > 0);
REQUIRE(ruler_rect.get_height() > 0);
REQUIRE(timelineWidget != NULL);
Glib::RefPtr<Style> style = get_style();
Gdk::Cairo::set_source_color(cairo, style->get_fg(STATE_NORMAL));
// Draw the selection start chevron
const int a = timelineWidget->time_to_x(
timelineWidget->selectionStart) + 1;
if(a >= 0 && a < ruler_rect.get_width())
{
cairo->move_to(a, ruler_rect.get_height());
cairo->rel_line_to(0, -mouseChevronSize);
cairo->rel_line_to(-mouseChevronSize, 0);
cairo->fill();
}
// Draw the selection end chevron
const int b = timelineWidget->time_to_x(
timelineWidget->selectionEnd);
if(b >= 0 && b < ruler_rect.get_width())
{
cairo->move_to(b, ruler_rect.get_height());
cairo->rel_line_to(0, -mouseChevronSize);
cairo->rel_line_to(mouseChevronSize, 0);
cairo->fill();
}
}
gavl_time_t
TimelineRuler::calculate_major_spacing() const
{
int i = 0;
int i;
REQUIRE(timelineWidget != NULL);
const int64_t time_scale = timelineWidget->timeScale;
const gavl_time_t major_spacings[] = {
GAVL_TIME_SCALE / 1000,
GAVL_TIME_SCALE / 400,
@ -298,7 +332,7 @@ TimelineRuler::calculate_major_spacing() const
for(i = 0; i < sizeof(major_spacings) / sizeof(gavl_time_t); i++)
{
const int64_t division_width = major_spacings[i] / timeScale;
const int64_t division_width = major_spacings[i] / time_scale;
if(division_width > minDivisionWidth)
break;

View file

@ -32,26 +32,16 @@
namespace lumiera {
namespace gui {
namespace widgets {
class TimelineWidget;
namespace timeline {
class TimelineRuler : public Gtk::DrawingArea
{
public:
TimelineRuler();
/**
* Sets the time offset. This is the time value displaid at the
* left-hand edge of the ruler.
*/
void set_time_offset(gavl_time_t time_offset);
/**
* Sets the time scale value.
* @param time_scale The scale factor, which is the number of
* microseconds per screen pixel. This value must be greater than
* zero.
*/
void set_time_scale(int64_t time_scale);
TimelineRuler(
lumiera::gui::widgets::TimelineWidget *timeline_widget);
/**
* Sets the offset of the mouse chevron in pixels from the left
@ -59,6 +49,8 @@ public:
* width, the chevron will not be visible.
*/
void set_mouse_chevron_offset(int offset);
void update_view();
/* ===== Events ===== */
protected:
@ -76,10 +68,13 @@ protected:
/* ===== Internals ===== */
private:
void draw_ruler(Cairo::RefPtr<Cairo::Context> cairo,
Gdk::Rectangle ruler_rect);
const Gdk::Rectangle ruler_rect);
void draw_mouse_chevron(Cairo::RefPtr<Cairo::Context> cairo,
Gdk::Rectangle ruler_rect);
const Gdk::Rectangle ruler_rect);
void draw_selection(Cairo::RefPtr<Cairo::Context> cairo,
const Gdk::Rectangle ruler_rect);
gavl_time_t calculate_major_spacing() const;
@ -88,9 +83,6 @@ private:
void read_styles();
private:
// View values
gavl_time_t timeOffset;
int64_t timeScale;
// Indicated values
int mouseChevronOffset;
@ -104,6 +96,9 @@ private:
int minDivisionWidth;
int mouseChevronSize;
// Owner
lumiera::gui::widgets::TimelineWidget *timelineWidget;
// Cached ruler image
Cairo::RefPtr<Cairo::ImageSurface> rulerImage;
};

View file

@ -28,23 +28,20 @@ namespace gui {
namespace widgets {
namespace timeline {
Tool::Tool(TimelineWidget *timeline_widget) :
timelineWidget(timeline_widget)
Tool::Tool(TimelineBody *timeline_body) :
timelineBody(timeline_body),
isDragging(false)
{
REQUIRE(timeline_widget != NULL);
REQUIRE(timeline_widget->body != NULL);
REQUIRE(timeline_body != NULL);
}
bool
Tool::apply_cursor()
{
REQUIRE(timelineWidget != NULL);
if(timelineWidget->body == NULL)
return false;
REQUIRE(timelineBody != NULL);
Glib::RefPtr<Gdk::Window> window =
timelineWidget->body->get_window();
timelineBody->get_window();
if(!window)
return false;
@ -53,6 +50,24 @@ Tool::apply_cursor()
return true;
}
void
Tool::on_button_press_event(GdkEventButton* event)
{
REQUIRE(event != NULL);
if(event->button == 1)
isDragging = true;
}
void
Tool::on_button_release_event(GdkEventButton* event)
{
REQUIRE(event != NULL);
if(event->button == 1)
isDragging = false;
}
} // namespace timeline
} // namespace widgets
} // namespace gui

View file

@ -32,11 +32,10 @@
namespace lumiera {
namespace gui {
namespace widgets {
class TimelineWidget;
namespace timeline {
class TimelineBody;
enum ToolType
{
None,
@ -47,18 +46,24 @@ enum ToolType
class Tool
{
protected:
Tool(TimelineWidget *timeline_widget);
Tool(TimelineBody *timeline_body);
public:
virtual ToolType get_type() const = 0;
bool apply_cursor();
protected:
virtual Gdk::Cursor get_cursor() const = 0;
virtual void on_button_press_event(GdkEventButton* event);
virtual void on_button_release_event(GdkEventButton* event);
virtual void on_motion_notify_event(GdkEventMotion *event) {}
protected:
TimelineWidget *timelineWidget;
virtual Gdk::Cursor get_cursor() const = 0;
protected:
bool isDragging;
TimelineBody *timelineBody;
};