Tidied and simplified video display widget, and added cursor support to
the ibeam and arrow tool
This commit is contained in:
parent
fdab62a5d8
commit
2ee6f6be62
15 changed files with 217 additions and 219 deletions
|
|
@ -38,7 +38,8 @@ TimelinePanel::TimelinePanel() :
|
|||
arrowTool(Gtk::StockID("arrow")),
|
||||
iBeamTool(Gtk::StockID("i_beam")),
|
||||
zoomIn(Stock::ZOOM_IN),
|
||||
zoomOut(Stock::ZOOM_OUT)
|
||||
zoomOut(Stock::ZOOM_OUT),
|
||||
updatingToolbar(false)
|
||||
{
|
||||
// Setup the toolbar
|
||||
toolbar.append(arrowTool, mem_fun(this,
|
||||
|
|
@ -63,6 +64,7 @@ TimelinePanel::TimelinePanel() :
|
|||
void
|
||||
TimelinePanel::on_arrow_tool()
|
||||
{
|
||||
if(updatingToolbar) return;
|
||||
timelineWidget.set_tool(timeline::Arrow);
|
||||
update_tool_buttons();
|
||||
}
|
||||
|
|
@ -70,6 +72,7 @@ TimelinePanel::on_arrow_tool()
|
|||
void
|
||||
TimelinePanel::on_ibeam_tool()
|
||||
{
|
||||
if(updatingToolbar) return;
|
||||
timelineWidget.set_tool(timeline::IBeam);
|
||||
update_tool_buttons();
|
||||
}
|
||||
|
|
@ -77,6 +80,7 @@ TimelinePanel::on_ibeam_tool()
|
|||
void
|
||||
TimelinePanel::on_zoom_in()
|
||||
{
|
||||
|
||||
timelineWidget.zoom_view(ZoomToolSteps);
|
||||
update_zoom_buttons();
|
||||
}
|
||||
|
|
@ -90,17 +94,14 @@ TimelinePanel::on_zoom_out()
|
|||
|
||||
void
|
||||
TimelinePanel::update_tool_buttons()
|
||||
{
|
||||
// This is included to prevent recursion
|
||||
static bool updating = false;
|
||||
|
||||
if(!updating)
|
||||
{
|
||||
if(!updatingToolbar)
|
||||
{
|
||||
updating = true;
|
||||
updatingToolbar = true;
|
||||
const timeline::ToolType tool = timelineWidget.get_tool();
|
||||
arrowTool.set_active(tool == timeline::Arrow);
|
||||
iBeamTool.set_active(tool == timeline::IBeam);
|
||||
updating = false;
|
||||
updatingToolbar = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -69,6 +69,9 @@ private:
|
|||
Gtk::ToolButton zoomIn;
|
||||
Gtk::ToolButton zoomOut;
|
||||
|
||||
// Internals
|
||||
bool updatingToolbar;
|
||||
|
||||
//----- Constants -----//
|
||||
static const int ZoomToolSteps;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -177,25 +177,28 @@ 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;
|
||||
}
|
||||
{
|
||||
// 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();
|
||||
tool = new timeline::ArrowTool(this);
|
||||
break;
|
||||
|
||||
case timeline::IBeam:
|
||||
tool = new timeline::IBeamTool();
|
||||
tool = new timeline::IBeamTool(this);
|
||||
break;
|
||||
}
|
||||
|
||||
// Apply the cursor if possible
|
||||
tool->apply_cursor();
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
|||
|
|
@ -148,6 +148,7 @@ protected:
|
|||
|
||||
friend class timeline::TimelineBody;
|
||||
friend class timeline::HeaderContainer;
|
||||
friend class timeline::Tool;
|
||||
};
|
||||
|
||||
} // namespace widgets
|
||||
|
|
|
|||
|
|
@ -39,7 +39,9 @@ HeaderContainer::HeaderContainer(lumiera::gui::widgets::TimelineWidget *timeline
|
|||
{
|
||||
REQUIRE(timeline_widget != NULL);
|
||||
|
||||
set_flags(Gtk::NO_WINDOW); // This widget will not have a window at first
|
||||
// This widget will not have a window at first
|
||||
set_flags(Gtk::NO_WINDOW);
|
||||
|
||||
set_redraw_on_allocate(false);
|
||||
|
||||
// Connect to the timeline widget's vertical scroll event,
|
||||
|
|
|
|||
|
|
@ -46,80 +46,80 @@ class Track;
|
|||
* associated with timeline tracks.
|
||||
*/
|
||||
class HeaderContainer : public Gtk::Container
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param[in] timeline_widget A pointer to the owner timeline widget
|
||||
*/
|
||||
HeaderContainer(lumiera::gui::widgets::TimelineWidget *timeline_widget);
|
||||
|
||||
/**
|
||||
* Attaches the header all the header widgets of root
|
||||
* tracks to this control.
|
||||
*
|
||||
* @note This must be called when the track list changes
|
||||
* to synchronise the headers with the timeline body and
|
||||
* the backend.
|
||||
*/
|
||||
void update_headers();
|
||||
|
||||
/* ===== Overrides ===== */
|
||||
private:
|
||||
void on_realize();
|
||||
void on_unrealize();
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param[in] timeline_widget A pointer to the owner timeline widget
|
||||
*/
|
||||
HeaderContainer(lumiera::gui::widgets::TimelineWidget *timeline_widget);
|
||||
|
||||
void on_size_allocate (Gtk::Allocation& allocation);
|
||||
void on_size_request (Gtk::Requisition* requisition);
|
||||
|
||||
void forall_vfunc(gboolean include_internals, GtkCallback callback,
|
||||
gpointer callback_data);
|
||||
|
||||
/* ===== Events ===== */
|
||||
private:
|
||||
void on_scroll();
|
||||
/**
|
||||
* Attaches the header all the header widgets of root
|
||||
* tracks to this control.
|
||||
*
|
||||
* @note This must be called when the track list changes
|
||||
* to synchronise the headers with the timeline body and
|
||||
* the backend.
|
||||
*/
|
||||
void update_headers();
|
||||
|
||||
/* ===== Overrides ===== */
|
||||
private:
|
||||
void on_realize();
|
||||
void on_unrealize();
|
||||
|
||||
void on_size_allocate (Gtk::Allocation& allocation);
|
||||
void on_size_request (Gtk::Requisition* requisition);
|
||||
|
||||
/* ===== Internals ===== */
|
||||
private:
|
||||
void forall_vfunc(gboolean include_internals, GtkCallback callback,
|
||||
gpointer callback_data);
|
||||
|
||||
/**
|
||||
* Moves all the header widgets to the correct position
|
||||
* given scroll, stacking etc.
|
||||
*/
|
||||
void layout_headers();
|
||||
/* ===== Events ===== */
|
||||
private:
|
||||
void on_scroll();
|
||||
|
||||
private:
|
||||
/* ===== Internals ===== */
|
||||
private:
|
||||
|
||||
/**
|
||||
* Moves all the header widgets to the correct position
|
||||
* given scroll, stacking etc.
|
||||
*/
|
||||
void layout_headers();
|
||||
|
||||
/**
|
||||
* The owner TimelineWidget of which this class is a helper
|
||||
*/
|
||||
lumiera::gui::widgets::TimelineWidget *timelineWidget;
|
||||
private:
|
||||
|
||||
/**
|
||||
* A structure to represent a header widget and it's
|
||||
* associated track
|
||||
*/
|
||||
struct RootHeader
|
||||
{
|
||||
Glib::RefPtr<Gtk::Widget> widget;
|
||||
Track *track;
|
||||
};
|
||||
|
||||
/**
|
||||
* Contains a list of the root currently present on
|
||||
* the timeline view
|
||||
*/
|
||||
std::vector< RootHeader > rootHeaders;
|
||||
/**
|
||||
* The owner TimelineWidget of which this class is a helper
|
||||
*/
|
||||
lumiera::gui::widgets::TimelineWidget *timelineWidget;
|
||||
|
||||
/**
|
||||
* The widget's window object.
|
||||
*
|
||||
* @note This is needed for the sake of clipping when
|
||||
* widgets are scrolled.
|
||||
*/
|
||||
Glib::RefPtr<Gdk::Window> gdkWindow;
|
||||
/**
|
||||
* A structure to represent a header widget and it's
|
||||
* associated track
|
||||
*/
|
||||
struct RootHeader
|
||||
{
|
||||
Glib::RefPtr<Gtk::Widget> widget;
|
||||
Track *track;
|
||||
};
|
||||
|
||||
/**
|
||||
* Contains a list of the root currently present on
|
||||
* the timeline view
|
||||
*/
|
||||
std::vector< RootHeader > rootHeaders;
|
||||
|
||||
/**
|
||||
* The widget's window object.
|
||||
*
|
||||
* @note This is needed for the sake of clipping when
|
||||
* widgets are scrolled.
|
||||
*/
|
||||
Glib::RefPtr<Gdk::Window> gdkWindow;
|
||||
};
|
||||
|
||||
} // namespace timeline
|
||||
} // namespace widgets
|
||||
|
|
|
|||
|
|
@ -27,7 +27,8 @@ namespace gui {
|
|||
namespace widgets {
|
||||
namespace timeline {
|
||||
|
||||
ArrowTool::ArrowTool()
|
||||
ArrowTool::ArrowTool(TimelineWidget *timeline_widget) :
|
||||
Tool(timeline_widget)
|
||||
{
|
||||
|
||||
}
|
||||
|
|
@ -38,6 +39,12 @@ ArrowTool::get_type() const
|
|||
return Arrow;
|
||||
}
|
||||
|
||||
Gdk::Cursor
|
||||
ArrowTool::get_cursor() const
|
||||
{
|
||||
return Gdk::Cursor(Gdk::ARROW);
|
||||
}
|
||||
|
||||
} // namespace timeline
|
||||
} // namespace widgets
|
||||
} // namespace gui
|
||||
|
|
|
|||
|
|
@ -37,9 +37,12 @@ namespace timeline {
|
|||
class ArrowTool : public Tool
|
||||
{
|
||||
public:
|
||||
ArrowTool();
|
||||
ArrowTool(TimelineWidget *timeline_widget);
|
||||
|
||||
ToolType get_type() const;
|
||||
|
||||
protected:
|
||||
Gdk::Cursor get_cursor() const;
|
||||
};
|
||||
|
||||
} // namespace timeline
|
||||
|
|
|
|||
|
|
@ -61,7 +61,6 @@ TimelineBody::TimelineBody(lumiera::gui::widgets::TimelineWidget *timeline_widge
|
|||
"Track Background",
|
||||
"The background colour of timeline tracks",
|
||||
GDK_TYPE_COLOR, G_PARAM_READABLE));
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -69,12 +68,15 @@ TimelineBody::on_realize()
|
|||
{
|
||||
Widget::on_realize();
|
||||
|
||||
// We wish to receive all event notifications
|
||||
// We wish to receive event notifications
|
||||
add_events(
|
||||
Gdk::POINTER_MOTION_MASK |
|
||||
Gdk::SCROLL_MASK |
|
||||
Gdk::BUTTON_PRESS_MASK |
|
||||
Gdk::BUTTON_RELEASE_MASK);
|
||||
|
||||
// Apply the cursor if possible
|
||||
timelineWidget->tool->apply_cursor();
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
|||
|
|
@ -27,9 +27,9 @@ namespace gui {
|
|||
namespace widgets {
|
||||
namespace timeline {
|
||||
|
||||
IBeamTool::IBeamTool()
|
||||
IBeamTool::IBeamTool(TimelineWidget *timeline_widget) :
|
||||
Tool(timeline_widget)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
ToolType
|
||||
|
|
@ -38,6 +38,12 @@ IBeamTool::get_type() const
|
|||
return IBeam;
|
||||
}
|
||||
|
||||
Gdk::Cursor
|
||||
IBeamTool::get_cursor() const
|
||||
{
|
||||
return Gdk::Cursor(Gdk::XTERM);
|
||||
}
|
||||
|
||||
} // namespace timeline
|
||||
} // namespace widgets
|
||||
} // namespace gui
|
||||
|
|
|
|||
|
|
@ -38,9 +38,12 @@ namespace timeline {
|
|||
class IBeamTool : public Tool
|
||||
{
|
||||
public:
|
||||
IBeamTool();
|
||||
IBeamTool(TimelineWidget *timeline_widget);
|
||||
|
||||
ToolType get_type() const;
|
||||
|
||||
protected:
|
||||
Gdk::Cursor get_cursor() const;
|
||||
};
|
||||
|
||||
} // namespace timeline
|
||||
|
|
|
|||
|
|
@ -21,15 +21,36 @@
|
|||
* *****************************************************/
|
||||
|
||||
#include "timeline-tool.hpp"
|
||||
#include "../timeline-widget.hpp"
|
||||
|
||||
namespace lumiera {
|
||||
namespace gui {
|
||||
namespace widgets {
|
||||
namespace timeline {
|
||||
|
||||
Tool::Tool()
|
||||
Tool::Tool(TimelineWidget *timeline_widget) :
|
||||
timelineWidget(timeline_widget)
|
||||
{
|
||||
REQUIRE(timeline_widget != NULL);
|
||||
REQUIRE(timeline_widget->body != NULL);
|
||||
}
|
||||
|
||||
bool
|
||||
Tool::apply_cursor()
|
||||
{
|
||||
REQUIRE(timelineWidget != NULL);
|
||||
|
||||
if(timelineWidget->body == NULL)
|
||||
return false;
|
||||
|
||||
Glib::RefPtr<Gdk::Window> window =
|
||||
timelineWidget->body->get_window();
|
||||
if(!window)
|
||||
return false;
|
||||
|
||||
window->set_cursor(get_cursor());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace timeline
|
||||
|
|
|
|||
|
|
@ -27,11 +27,14 @@
|
|||
#ifndef TIMELINE_TOOL_HPP
|
||||
#define TIMELINE_TOOL_HPP
|
||||
|
||||
#include <gtkmm.h>
|
||||
#include "../../gtk-lumiera.hpp"
|
||||
|
||||
namespace lumiera {
|
||||
namespace gui {
|
||||
namespace widgets {
|
||||
|
||||
class TimelineWidget;
|
||||
|
||||
namespace timeline {
|
||||
|
||||
enum ToolType
|
||||
|
|
@ -43,10 +46,19 @@ enum ToolType
|
|||
|
||||
class Tool
|
||||
{
|
||||
public:
|
||||
Tool();
|
||||
protected:
|
||||
Tool(TimelineWidget *timeline_widget);
|
||||
|
||||
public:
|
||||
virtual ToolType get_type() const = 0;
|
||||
|
||||
bool apply_cursor();
|
||||
|
||||
protected:
|
||||
virtual Gdk::Cursor get_cursor() const = 0;
|
||||
|
||||
protected:
|
||||
TimelineWidget *timelineWidget;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -36,128 +36,67 @@ namespace gui {
|
|||
namespace widgets {
|
||||
|
||||
VideoDisplayWidget::VideoDisplayWidget() :
|
||||
gdkWindow(NULL),
|
||||
displayer(NULL)
|
||||
{
|
||||
set_flags(Gtk::NO_WINDOW);
|
||||
}
|
||||
{
|
||||
}
|
||||
|
||||
VideoDisplayWidget::~VideoDisplayWidget()
|
||||
{
|
||||
if(displayer != NULL)
|
||||
delete displayer;
|
||||
}
|
||||
{
|
||||
if(displayer != NULL)
|
||||
delete displayer;
|
||||
}
|
||||
|
||||
void
|
||||
VideoDisplayWidget::on_realize()
|
||||
{
|
||||
set_flags(Gtk::NO_WINDOW);
|
||||
{
|
||||
// Call base class:
|
||||
Gtk::Widget::on_realize();
|
||||
|
||||
// Call base class:
|
||||
Gtk::Widget::on_realize();
|
||||
// Set colors
|
||||
modify_bg(Gtk::STATE_NORMAL, Gdk::Color("black"));
|
||||
|
||||
// Create the GdkWindow:
|
||||
GdkWindowAttr attributes;
|
||||
memset(&attributes, 0, sizeof(attributes));
|
||||
if(displayer != NULL)
|
||||
delete displayer;
|
||||
displayer = createDisplayer(this, 320, 240);
|
||||
|
||||
Gtk::Allocation allocation = get_allocation();
|
||||
|
||||
// Set initial position and size of the Gdk::Window:
|
||||
attributes.x = allocation.get_x();
|
||||
attributes.y = allocation.get_y();
|
||||
attributes.width = allocation.get_width();
|
||||
attributes.height = allocation.get_height();
|
||||
|
||||
attributes.event_mask = get_events () | Gdk::EXPOSURE_MASK;
|
||||
attributes.window_type = GDK_WINDOW_CHILD;
|
||||
attributes.wclass = GDK_INPUT_OUTPUT;
|
||||
|
||||
gdkWindow = Gdk::Window::create(get_window() /* parent */, &attributes,
|
||||
GDK_WA_X | GDK_WA_Y);
|
||||
unset_flags(Gtk::NO_WINDOW);
|
||||
set_window(gdkWindow);
|
||||
|
||||
// Set colors
|
||||
modify_bg(Gtk::STATE_NORMAL, Gdk::Color("black"));
|
||||
|
||||
// Make the widget receive expose events
|
||||
gdkWindow->set_user_data(gobj());
|
||||
|
||||
if(displayer != NULL)
|
||||
delete displayer;
|
||||
displayer = createDisplayer(this, 320, 240);
|
||||
|
||||
add_events(Gdk::ALL_EVENTS_MASK);
|
||||
}
|
||||
|
||||
void
|
||||
VideoDisplayWidget::on_unrealize()
|
||||
{
|
||||
gdkWindow.clear();
|
||||
|
||||
//Call base class:
|
||||
Gtk::Widget::on_unrealize();
|
||||
}
|
||||
add_events(Gdk::ALL_EVENTS_MASK);
|
||||
}
|
||||
|
||||
bool
|
||||
VideoDisplayWidget::on_button_press_event (GdkEventButton* event)
|
||||
{
|
||||
unsigned char buffer[320 * 240 * 4];
|
||||
{
|
||||
unsigned char buffer[320 * 240 * 4];
|
||||
|
||||
for(int i = 0; i < 320*240*4; i++)
|
||||
buffer[i] = rand();
|
||||
for(int i = 0; i < 320*240*4; i++)
|
||||
buffer[i] = rand();
|
||||
|
||||
displayer->put((void*)buffer);
|
||||
displayer->put((void*)buffer);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
VideoDisplayWidget::on_expose_event(GdkEventExpose* event)
|
||||
{
|
||||
// This is where we draw on the window
|
||||
/*Glib::RefPtr<Gdk::Window> window = get_window();
|
||||
if(window)
|
||||
{
|
||||
Cairo::RefPtr<Cairo::Context> cr = window->create_cairo_context();
|
||||
if(event)
|
||||
{
|
||||
// clip to the area that needs to be re-exposed so we don't draw any
|
||||
// more than we need to.
|
||||
cr->rectangle(event->area.x, event->area.y,
|
||||
event->area.width, event->area.height);
|
||||
cr->clip();
|
||||
}
|
||||
|
||||
// Paint the background
|
||||
cr->set_source_rgb(0.0, 0.0, 0.0);
|
||||
cr->paint();
|
||||
}*/
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
Displayer*
|
||||
VideoDisplayWidget::createDisplayer( Gtk::Widget *drawingArea, int width, int height )
|
||||
{
|
||||
REQUIRE(drawingArea != NULL);
|
||||
REQUIRE(width > 0 && height > 0);
|
||||
|
||||
Displayer *displayer = NULL;
|
||||
|
||||
displayer = new XvDisplayer( drawingArea, width, height );
|
||||
if ( !displayer->usable() )
|
||||
{
|
||||
delete displayer;
|
||||
displayer = NULL;
|
||||
}
|
||||
{
|
||||
REQUIRE(drawingArea != NULL);
|
||||
REQUIRE(width > 0 && height > 0);
|
||||
|
||||
Displayer *displayer = NULL;
|
||||
|
||||
displayer = new XvDisplayer( drawingArea, width, height );
|
||||
if ( !displayer->usable() )
|
||||
{
|
||||
delete displayer;
|
||||
displayer = NULL;
|
||||
}
|
||||
|
||||
if ( displayer == NULL )
|
||||
{
|
||||
displayer = new GdkDisplayer( drawingArea, width, height );
|
||||
}
|
||||
if ( displayer == NULL )
|
||||
{
|
||||
displayer = new GdkDisplayer( drawingArea, width, height );
|
||||
}
|
||||
|
||||
return displayer;
|
||||
}
|
||||
return displayer;
|
||||
}
|
||||
|
||||
} // namespace widgets
|
||||
} // namespace gui
|
||||
|
|
|
|||
|
|
@ -36,34 +36,29 @@ namespace lumiera {
|
|||
namespace gui {
|
||||
namespace widgets {
|
||||
|
||||
class VideoDisplayWidget : public Gtk::Widget
|
||||
{
|
||||
public:
|
||||
VideoDisplayWidget();
|
||||
class VideoDisplayWidget : public Gtk::DrawingArea
|
||||
{
|
||||
public:
|
||||
VideoDisplayWidget();
|
||||
|
||||
~VideoDisplayWidget();
|
||||
~VideoDisplayWidget();
|
||||
|
||||
/* ===== Overrides ===== */
|
||||
private:
|
||||
virtual void on_realize();
|
||||
/* ===== Overrides ===== */
|
||||
private:
|
||||
virtual void on_realize();
|
||||
|
||||
virtual void on_unrealize();
|
||||
|
||||
virtual bool on_expose_event(GdkEventExpose* event);
|
||||
// TEST CODE!!!!
|
||||
virtual bool on_button_press_event (GdkEventButton* event);
|
||||
|
||||
// TEST CODE!!!!
|
||||
virtual bool on_button_press_event (GdkEventButton* event);
|
||||
/* ===== Internals ===== */
|
||||
private:
|
||||
static Displayer*
|
||||
createDisplayer( Gtk::Widget *drawingArea, int width, int height );
|
||||
|
||||
/* ===== Internals ===== */
|
||||
private:
|
||||
static Displayer*
|
||||
createDisplayer( Gtk::Widget *drawingArea, int width, int height );
|
||||
private:
|
||||
|
||||
private:
|
||||
Glib::RefPtr<Gdk::Window> gdkWindow;
|
||||
|
||||
Displayer *displayer;
|
||||
};
|
||||
Displayer *displayer;
|
||||
};
|
||||
|
||||
} // namespace widgets
|
||||
} // namespace gui
|
||||
|
|
|
|||
Loading…
Reference in a new issue