Merge from proc (draft imp of pull() call)

This commit is contained in:
Fischlurch 2008-08-17 18:35:49 +02:00
commit c5778f1540
84 changed files with 8548 additions and 70 deletions

View file

@ -1,5 +1,6 @@
# Copyright (C) Lumiera.org
# 2007, Christian Thaeter <ct@pipapo.org>
# 2008, Joel Holdsworth <joel@airwebreathe.org.uk>
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
@ -38,9 +39,15 @@ include $(top_srcdir)/src/common/Makefile.am
include $(top_srcdir)/src/lib/Makefile.am
include $(top_srcdir)/src/backend/Makefile.am
# gui
include $(top_srcdir)/src/gui/Makefile.am
# plugins
#include $(top_srcdir)/src...
# resources
include $(top_srcdir)/icons/Makefile.am
# tests
include $(top_srcdir)/tests/common/Makefile.am
include $(top_srcdir)/tests/components/Makefile.am

View file

@ -291,6 +291,15 @@ def defineBuildTargets(env, artifacts):
artifacts['lumiera'] = env.Program('$BINDIR/lumiera', ['$SRCDIR/main.cpp']+ core )
artifacts['plugins'] = env.SharedLibrary('$BINDIR/lumiera-plugin', objplug)
# the Lumiera GTK GUI
envgtk = env.Clone().mergeConf(['gtkmm-2.4','cairomm-1.0','gdl-1.0','xv','xext','sm'])
objgui = srcSubtree(envgtk,'$SRCDIR/gui')
artifacts['lumigui'] = ( envgtk.Program('$BINDIR/lumigui', objgui + core)
+ env.Install('$BINDIR', env.Glob('$ICONDIR/*.png'))
+ env.Install('$BINDIR', env.Glob('$SRCDIR/gui/*.rc'))
)
# call subdir SConscript(s) for independent components
SConscript(dirs=[SRCDIR+'/tool'], exports='env artifacts core')
SConscript(dirs=[TESTDIR], exports='env artifacts core')
@ -305,7 +314,7 @@ def definePostBuildTargets(env, artifacts):
il = env.Alias('install-lib', '$DESTDIR/lib')
env.Alias('install', [ib, il])
build = env.Alias('build', artifacts['lumiera']+artifacts['plugins']+artifacts['tools'])
build = env.Alias('build', artifacts['lumiera']+artifacts['lumigui']+artifacts['plugins']+artifacts['tools'])
allbu = env.Alias('allbuild', build+artifacts['testsuite'])
env.Default('build')
# additional files to be cleaned when cleaning 'build'

View file

@ -22,3 +22,7 @@ vgsuppression_SOURCES = $(admin_srcdir)/vgsuppression.c
vgsuppression_CPPFLAGS = $(AM_CPPFLAGS) -std=gnu99 -Wall -Werror -I$(top_srcdir)/src/
vgsuppression_LDADD = liblumi.a -lnobugmt -lpthread -ldl
noinst_PROGRAMS += rsvg-convert
rsvg_convert_SOURCES = $(admin_srcdir)/rsvg-convert.c
rsvg_convert_CPPFLAGS = $(AM_CPPFLAGS) -std=gnu99 -Wall -Werror
rsvg_convert_LDADD = -lcairo -lglib-2.0 -lgthread-2.0 -lrsvg-2

167
admin/render-icon.py Executable file
View file

@ -0,0 +1,167 @@
#!/usr/bin/python
# render-icons.py - Icon rendering utility script
#
# Copyright (C) Lumiera.org
# 2008, Joel Holdsworth <joel@airwebreathe.org.uk>
#
# 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 2 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, write to the Free Software
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
import sys
import getopt
from xml.dom import minidom
import os
import shutil
#svgDir = "svg"
#prerenderedDir = "prerendered"
inkscapePath = "/usr/bin/inkscape"
rsvgPath = "./rsvg-convert"
artworkLayerPrefix = "artwork:"
def createDirectory( name ):
if os.path.exists(name) == False:
os.mkdir(name)
def copyMergeDirectory( src, dst ):
listing = os.listdir(src)
for file_name in listing:
src_file_path = os.path.join(src, file_name)
dst_file_path = os.path.join(dst, file_name)
shutil.copyfile(src_file_path, dst_file_path)
def getDocumentSize( svg_element ):
width = float(svg_element.getAttribute("width"))
height = float(svg_element.getAttribute("height"))
return [width, height]
def findChildLayerElement( parent_element ):
for node in parent_element.childNodes:
if node.nodeType == minidom.Node.ELEMENT_NODE:
if node.tagName == "g":
if node.getAttribute("inkscape:groupmode") == "layer":
return node
return None
def parsePlateLayer( layer ):
rectangles = []
for node in layer.childNodes:
if node.nodeType == minidom.Node.ELEMENT_NODE:
if node.tagName == "rect":
x = float(node.getAttribute("x"))
y = float(node.getAttribute("y"))
width = float(node.getAttribute("width"))
height = float(node.getAttribute("height"))
rectangles.append([x, y, width, height])
return rectangles
def parseSVG( file_path ):
print "Rendering " + file_path
svgdoc = minidom.parse(file_path)
for root_node in svgdoc.childNodes:
if root_node.nodeType == minidom.Node.ELEMENT_NODE:
if root_node.tagName == "svg":
size = getDocumentSize( root_node )
layer = findChildLayerElement( root_node )
if layer != None:
layer_name = layer.getAttribute("inkscape:label")
if layer_name[:len(artworkLayerPrefix)] == artworkLayerPrefix:
artwork_name = layer_name[len(artworkLayerPrefix):]
plate = findChildLayerElement( layer )
if plate != None:
return artwork_name, size, parsePlateLayer( plate )
return None
def renderSvgInkscape(file_path, out_dir, artwork_name, rectangle, doc_size):
# Calculate the rendering rectangle
x1 = rectangle[0]
y1 = doc_size[1] - rectangle[1] - rectangle[3]
x2 = x1 + rectangle[2]
y2 = y1 + rectangle[3]
# Call Inkscape to do the render
os.spawnlp(os.P_WAIT, inkscapePath, inkscapePath,
file_path,
"-z",
"-a %g:%g:%g:%g" % (x1, y1, x2, y2),
"-w %g" % (rectangle[2]), "-h %g" % (rectangle[3]),
"--export-png=" + os.path.join(out_dir, "%gx%g/%s.png" % (rectangle[2], rectangle[3], artwork_name)))
def renderSvgRsvg(file_path, out_dir, artwork_name, rectangle, doc_size):
# Prepare a Cairo context
width = int(rectangle[2])
height = int(rectangle[3])
os.spawnlp(os.P_WAIT, rsvgPath, rsvgPath,
"--source-rect=%g:%g:%g:%g" % (rectangle[0], rectangle[1], rectangle[2], rectangle[3]),
"--output=" + os.path.join(out_dir, "%gx%g/%s.png" % (rectangle[2], rectangle[3], artwork_name)),
file_path)
def renderSvgIcon(file_path, out_dir):
artwork_name, doc_size, rectangles = parseSVG(file_path)
for rectangle in rectangles:
renderSvgRsvg(file_path, out_dir, artwork_name, rectangle, doc_size)
#def renderSvgIcons():
# listing = os.listdir(svgDir)
# for file_path in listing:
# [root, extension] = os.path.splitext(file_path)
# if extension.lower() == ".svg":
# renderSvgIcon(os.path.join(svgDir, file_path))
#def copyPrerenderedIcons():
# listing = os.listdir(prerenderedDir)
# for list_item in listing:
# src_dir = os.path.join(prerenderedDir, list_item)
# copyMergeDirectory(src_dir, list_item)
def printHelp():
print "render-icon.py - An icon rendering utility script for lumiera"
def parseArguments(argv):
optlist, args = getopt.getopt(argv, "")
if len(args) == 2:
return args[0], args[1]
printHelp()
return None, None
def main(argv):
in_path, out_dir = parseArguments(argv)
if in_path == None or out_dir == None:
return
if os.path.exists(out_dir) == False:
print "Directory not found: " + out_dir
return
# Create the icons folders
createDirectory(os.path.join(out_dir, "48x48"))
createDirectory(os.path.join(out_dir, "32x32"))
createDirectory(os.path.join(out_dir, "24x24"))
createDirectory(os.path.join(out_dir, "22x22"))
createDirectory(os.path.join(out_dir, "16x16"))
renderSvgIcon(in_path, out_dir)
# Copy in prerendered icons
#copyPrerenderedIcons()
if __name__=="__main__":
main(sys.argv[1:])

219
admin/rsvg-convert.c Normal file
View file

@ -0,0 +1,219 @@
/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*-
rsvg-convert.c: Command line utility for exercising rsvg with cairo.
Copyright (C) 2005 Red Hat, Inc.
Copyright (C) 2005 Dom Lachowicz <cinamod@hotmail.com>
Copyright (C) 2005 Caleb Moore <c.moore@student.unsw.edu.au>
Copyright (C) 2008 Joel Holdsworth <joel@airwebreathe.org.uk>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 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
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this program; if not, write to the
Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA.
Authors: Carl Worth <cworth@cworth.org>,
Caleb Moore <c.moore@student.unsw.edu.au>,
Dom Lachowicz <cinamod@hotmail.com>,
Joel Holdsworth <joel@airwebreathe.org.uk>
*/
#ifndef N_
#define N_(X) X
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <librsvg-2/librsvg/rsvg.h>
#include <librsvg-2/librsvg/rsvg-cairo.h>
#ifdef CAIRO_HAS_PS_SURFACE
#include <cairo-ps.h>
#endif
#ifdef CAIRO_HAS_PDF_SURFACE
#include <cairo-pdf.h>
#endif
#ifdef CAIRO_HAS_SVG_SURFACE
#include <cairo-svg.h>
#endif
#ifndef _
#define _(X) X
#endif
struct RsvgSizeCallbackData {
gint width;
gint height;
};
struct RsvgSourceRectangle {
double left;
double top;
double width;
double height;
};
static void
display_error (GError * err)
{
if (err) {
g_print ("%s", err->message);
g_error_free (err);
}
}
static void
rsvg_cairo_size_callback (int *width, int *height, gpointer data)
{
RsvgDimensionData *dimensions = data;
*width = dimensions->width;
*height = dimensions->height;
}
static cairo_status_t
rsvg_cairo_write_func (void *closure, const unsigned char *data, unsigned int length)
{
fwrite (data, 1, length, (FILE *) closure);
return CAIRO_STATUS_SUCCESS;
}
int
main (int argc, char **argv)
{
GOptionContext *g_option_context;
int width = -1;
int height = -1;
char *source_rect_string = NULL;
char *output = NULL;
GError *error = NULL;
char *filename = NULL;
char **args = NULL;
RsvgHandle *rsvg;
cairo_surface_t *surface = NULL;
cairo_t *cr = NULL;
RsvgDimensionData dimensions;
FILE *output_file = stdout;
struct RsvgSourceRectangle source_rect = {0, 0, 0, 0};
GOptionEntry options_table[] = {
{"width", 'w', 0, G_OPTION_ARG_INT, &width,
N_("width [optional; defaults to the SVG's width]"), N_("<int>")},
{"height", 'h', 0, G_OPTION_ARG_INT, &height,
N_("height [optional; defaults to the SVG's height]"), N_("<int>")},
{"source-rect", 'r', 0, G_OPTION_ARG_STRING, &source_rect_string,
N_("source rectangle [optional; defaults to rectangle of the SVG document]"), N_("left:top:width:height")},
{"output", 'o', 0, G_OPTION_ARG_STRING, &output,
N_("output filename"), NULL},
{G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_FILENAME_ARRAY, &args, NULL, N_("FILE")},
{NULL}
};
g_thread_init(NULL);
g_option_context = g_option_context_new (_("- SVG Converter"));
g_option_context_add_main_entries (g_option_context, options_table, NULL);
g_option_context_set_help_enabled (g_option_context, TRUE);
if (!g_option_context_parse (g_option_context, &argc, &argv, &error)) {
display_error (error);
exit (1);
}
g_option_context_free (g_option_context);
if (output != NULL) {
output_file = fopen (output, "wb");
if (!output_file) {
fprintf (stderr, _("Error saving to file: %s\n"), output);
exit (1);
}
}
if (args[0] != NULL) {
filename = args[0];
}
/* Parse the source rect */
if(source_rect_string != NULL) {
const int n = sscanf(source_rect_string, "%lg:%lg:%lg:%lg",
&source_rect.left, &source_rect.top,
&source_rect.width, &source_rect.height);
if(n != 4 || source_rect.width <= 0.0 || source_rect.height < 0.0) {
fprintf (stderr, _("Invalid source rect: %s\n"), source_rect_string);
exit(1);
}
}
rsvg_init ();
rsvg = rsvg_handle_new_from_file (filename, &error);
if (!rsvg) {
fprintf (stderr, _("Error reading SVG:"));
display_error (error);
fprintf (stderr, "\n");
exit (1);
}
/* if the user did not specify a source rectangle, get the page size from the SVG */
if(source_rect_string == NULL) {
rsvg_handle_set_size_callback (rsvg, rsvg_cairo_size_callback, &dimensions, NULL);
source_rect.left = 0;
source_rect.top = 0;
source_rect.width = dimensions.width;
source_rect.height = dimensions.height;
}
rsvg_handle_get_dimensions (rsvg, &dimensions);
if(width != -1 && height != -1) {
dimensions.width = width;
dimensions.height = height;
} else if(source_rect_string != NULL) {
dimensions.width = source_rect.width;
dimensions.height = source_rect.height;
}
surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
dimensions.width, dimensions.height);
cr = cairo_create (surface);
cairo_translate(cr, -source_rect.left, -source_rect.top);
if(width != -1 && height != -1 && source_rect_string != NULL) {
cairo_scale(cr, (double)dimensions.width / (double)source_rect.width,
(double)dimensions.height / (double)source_rect.height);
}
rsvg_handle_render_cairo (rsvg, cr);
cairo_surface_write_to_png_stream (surface, rsvg_cairo_write_func, output_file);
g_object_unref (G_OBJECT (rsvg));
cairo_destroy (cr);
cairo_surface_destroy (surface);
fclose (output_file);
rsvg_term ();
return 0;
}

View file

@ -7,6 +7,7 @@ AC_PREREQ(2.59)
AC_COPYRIGHT([
Copyright (C) Lumiera.org
2008, Christian Thaeter <ct@pipapo.org>
Joel Holdsworth <joel@airwebreathe.org.uk>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
@ -120,6 +121,52 @@ AC_CHECK_HEADER([boost/regex.hpp],
AC_LANG_POP([C++])
############## Internatinalization
#GETTEXT_PACKAGE=gtk-lumiera
#AC_SUBST(GETTEXT_PACKAGE)
#AC_DEFINE_UNQUOTED(GETTEXT_PACKAGE,"$GETTEXT_PACKAGE", [GETTEXT package name])
#AM_GLIB_GNU_GETTEXT
#IT_PROG_INTLTOOL([0.35.0])
# END Internatinalization
############## X11 Dependancies
AC_PATH_X
AC_PATH_XTRA
# CFLAGS="$CFLAGS $X_CFLAGS"
LIBS="$LIBS $X_PRE_LIBS $X_LIBS $X_EXTRA_LIBS"
AC_CHECK_HEADERS([X11/Xlib.h X11/Xutil.h],[],
[AC_MSG_ERROR([Xlib.h or Xutil.h not found install xdevel])])
AC_CHECK_HEADERS([sys/ipc.h sys/shm.h],,
[AC_MSG_ERROR([Required header not found. Please check that it is installed])]
)
AC_CHECK_HEADERS([X11/extensions/Xvlib.h X11/extensions/XShm.h],,
[AC_MSG_ERROR([Required xvideo (Xv) extension to X not found. Please check that it is installed.])],
[#include <X11/Xlib.h>]
)
AC_CHECK_LIB(Xext, XInitExtension, ,
[AC_MSG_ERROR([Could not link with libXext. Check that you have libXext installed])], -lX11
)
AC_CHECK_LIB(Xv, XvQueryAdaptors, ,
[AC_MSG_ERROR([Could not link with libXv. Check that you have libXv installed])]
)
# END X11 Dependancies
############## Pkg Dependancies
PKG_CHECK_MODULES(GTK_LUMIERA, [
gtkmm-2.4 >= 2.8 gdl-1.0 >= 0.6.1 cairomm-1.0 >= 0.6.0
gavl >= 0.2.5 librsvg-2.0 >= 2.18.1])
AC_SUBST(GTK_LUMIERA_CFLAGS)
AC_SUBST(GTK_LUMIERA_LIBS)
# END Gtk Dependancies
# Print a summary
AC_MSG_RESULT([

View file

@ -1,14 +1,14 @@
# Doxyfile 1.5.1
# Doxyfile 1.5.5
#---------------------------------------------------------------------------
# Project related configuration options
#---------------------------------------------------------------------------
DOXYFILE_ENCODING = UTF-8
PROJECT_NAME = Lumiera
PROJECT_NUMBER = 3.0+alpha
OUTPUT_DIRECTORY =
CREATE_SUBDIRS = YES
OUTPUT_LANGUAGE = English
USE_WINDOWS_ENCODING = NO
BRIEF_MEMBER_DESC = YES
REPEAT_BRIEF = NO
ABBREVIATE_BRIEF = "The $name class" \
@ -30,6 +30,7 @@ STRIP_FROM_PATH = ../../src/ \
STRIP_FROM_INC_PATH =
SHORT_NAMES = NO
JAVADOC_AUTOBRIEF = YES
QT_AUTOBRIEF = NO
MULTILINE_CPP_IS_BRIEF = NO
DETAILS_AT_TOP = NO
INHERIT_DOCS = YES
@ -38,9 +39,14 @@ TAB_SIZE = 4
ALIASES =
OPTIMIZE_OUTPUT_FOR_C = NO
OPTIMIZE_OUTPUT_JAVA = NO
OPTIMIZE_FOR_FORTRAN = NO
OPTIMIZE_OUTPUT_VHDL = NO
BUILTIN_STL_SUPPORT = YES
CPP_CLI_SUPPORT = NO
SIP_SUPPORT = NO
DISTRIBUTE_GROUP_DOC = NO
SUBGROUPING = YES
TYPEDEF_HIDES_STRUCT = NO
#---------------------------------------------------------------------------
# Build related configuration options
#---------------------------------------------------------------------------
@ -49,6 +55,7 @@ EXTRACT_PRIVATE = YES
EXTRACT_STATIC = YES
EXTRACT_LOCAL_CLASSES = YES
EXTRACT_LOCAL_METHODS = NO
EXTRACT_ANON_NSPACES = NO
HIDE_UNDOC_MEMBERS = NO
HIDE_UNDOC_CLASSES = NO
HIDE_FRIEND_COMPOUNDS = NO
@ -60,6 +67,7 @@ SHOW_INCLUDE_FILES = YES
INLINE_INFO = YES
SORT_MEMBER_DOCS = YES
SORT_BRIEF_DOCS = YES
SORT_GROUP_NAMES = NO
SORT_BY_SCOPE_NAME = NO
GENERATE_TODOLIST = YES
GENERATE_TESTLIST = YES
@ -79,12 +87,13 @@ WARN_IF_UNDOCUMENTED = NO
WARN_IF_DOC_ERROR = YES
WARN_NO_PARAMDOC = YES
WARN_FORMAT = "$file:$line: $text"
WARN_LOGFILE =
WARN_LOGFILE = warnings.txt
#---------------------------------------------------------------------------
# configuration options related to the input files
#---------------------------------------------------------------------------
INPUT = ../../src/ \
../../tests/
INPUT_ENCODING = UTF-8
FILE_PATTERNS = *.c \
*.cc \
*.cxx \
@ -130,6 +139,7 @@ RECURSIVE = YES
EXCLUDE =
EXCLUDE_SYMLINKS = YES
EXCLUDE_PATTERNS =
EXCLUDE_SYMBOLS =
EXAMPLE_PATH =
EXAMPLE_PATTERNS = *
EXAMPLE_RECURSIVE = NO
@ -168,6 +178,10 @@ HTML_FOOTER =
HTML_STYLESHEET =
HTML_ALIGN_MEMBERS = YES
GENERATE_HTMLHELP = NO
GENERATE_DOCSET = NO
DOCSET_FEEDNAME = "Doxygen generated docs"
DOCSET_BUNDLE_ID = org.doxygen.Project
HTML_DYNAMIC_SECTIONS = NO
CHM_FILE =
HHC_LOCATION =
GENERATE_CHI = NO
@ -251,6 +265,7 @@ PERL_PATH = /usr/bin/perl
# Configuration options related to the dot tool
#---------------------------------------------------------------------------
CLASS_DIAGRAMS = YES
MSCGEN_PATH =
HIDE_UNDOC_RELATIONS = YES
HAVE_DOT = YES
CLASS_GRAPH = YES
@ -267,8 +282,7 @@ DIRECTORY_GRAPH = YES
DOT_IMAGE_FORMAT = png
DOT_PATH =
DOTFILE_DIRS =
MAX_DOT_GRAPH_WIDTH = 1024
MAX_DOT_GRAPH_HEIGHT = 1024
DOT_GRAPH_MAX_NODES = 50
MAX_DOT_GRAPH_DEPTH = 1000
DOT_TRANSPARENT = NO
DOT_MULTI_TARGETS = YES

65
icons/Makefile.am Normal file
View file

@ -0,0 +1,65 @@
# Copyright (C) Lumiera.org
# 2008, Joel Holdsworth <joel@airwebreathe.org.uk>
#
# 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 2 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, write to the Free Software
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
svgdir = $(top_srcdir)/icons/svg
prerendereddir = $(top_srcdir)/icons/prerendered
icondir = $(top_builddir)
iconcommand = python $(top_srcdir)/admin/render-icon.py
16x16 = $(icondir)/16x16
22x22 = $(icondir)/22x22
24x24 = $(icondir)/24x24
32x32 = $(icondir)/32x32
48x48 = $(icondir)/48x48
16x16pre = $(prerendereddir)/16x16
22x22pre = $(prerendereddir)/22x22
24x24pre = $(prerendereddir)/24x24
32x32pre = $(prerendereddir)/32x32
48x48pre = $(prerendereddir)/48x48
lumigui_DEPENDENCIES += \
rsvg-convert \
$(16x16)/tool-arrow.png $(22x22)/tool-arrow.png $(24x24)/tool-arrow.png $(32x32)/tool-arrow.png $(48x48)/tool-arrow.png \
$(16x16)/tool-i-beam.png $(22x22)/tool-i-beam.png $(24x24)/tool-i-beam.png $(32x32)/tool-i-beam.png $(48x48)/tool-i-beam.png \
$(16x16)/panel-assets.png $(22x22)/panel-assets.png $(32x32)/panel-assets.png \
$(16x16)/panel-timeline.png \
$(16x16)/panel-viewer.png $(22x22)/panel-viewer.png $(32x32)/panel-viewer.png
$(16x16)/tool-arrow.png $(22x22)/tool-arrow.png $(24x24)/tool-arrow.png $(32x32)/tool-arrow.png $(48x48)/tool-arrow.png : $(svgdir)/tool-arrow.svg
$(iconcommand) $< $(icondir)
$(16x16)/tool-i-beam.png $(22x22)/tool-i-beam.png $(24x24)/tool-i-beam.png $(32x32)/tool-i-beam.png $(48x48)/tool-i-beam.png : $(svgdir)/tool-i-beam.svg
$(iconcommand) $< $(icondir)
$(16x16)/panel-assets.png:
cp $(16x16pre)/panel-assets.png $(16x16)
$(22x22)/panel-assets.png:
cp $(22x22pre)/panel-assets.png $(22x22)
$(32x32)/panel-assets.png:
cp $(32x32pre)/panel-assets.png $(32x32)
$(16x16)/panel-timeline.png:
cp $(16x16pre)/panel-timeline.png $(16x16)
$(16x16)/panel-viewer.png:
cp $(16x16pre)/panel-viewer.png $(16x16)
$(22x22)/panel-viewer.png:
cp $(22x22pre)/panel-viewer.png $(22x22)
$(32x32)/panel-viewer.png:
cp $(32x32pre)/panel-viewer.png $(32x32)

Binary file not shown.

After

Width:  |  Height:  |  Size: 540 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 453 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 631 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 695 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 788 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

732
icons/svg/tool-arrow.svg Normal file
View file

@ -0,0 +1,732 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="150"
height="100"
id="svg2"
sodipodi:version="0.32"
inkscape:version="0.46"
version="1.0"
sodipodi:docname="tool-arrow.svg"
inkscape:output_extension="org.inkscape.output.svg.inkscape">
<defs
id="defs4">
<linearGradient
inkscape:collect="always"
id="linearGradient10554">
<stop
style="stop-color:white;stop-opacity:1;"
offset="0"
id="stop10556" />
<stop
style="stop-color:white;stop-opacity:0;"
offset="1"
id="stop10558" />
</linearGradient>
<linearGradient
id="linearGradient124">
<stop
style="stop-color:#ffffff;stop-opacity:1.0000000;"
offset="0.0000000"
id="stop125" />
<stop
style="stop-color:silver;stop-opacity:1;"
offset="1"
id="stop126" />
</linearGradient>
<linearGradient
inkscape:collect="always"
id="linearGradient8773">
<stop
style="stop-color:black;stop-opacity:0.3137255"
offset="0"
id="stop8775" />
<stop
style="stop-color:black;stop-opacity:0;"
offset="1"
id="stop8777" />
</linearGradient>
<inkscape:perspective
sodipodi:type="inkscape:persp3d"
inkscape:vp_x="0 : 526.18109 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_z="744.09448 : 526.18109 : 1"
inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
id="perspective10" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient124"
id="linearGradient14467"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.559542,1.292457,-0.3231142,0.1398855,-29.871557,-250.82036)"
x1="253.75711"
y1="-129.52815"
x2="252.00447"
y2="-135.47408" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient124"
id="radialGradient14469"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.5869533,0,0,0.8448423,-29.87156,-250.82036)"
cx="307.7507"
cy="361.47824"
fx="307.7507"
fy="361.47824"
r="12.509617" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient10554"
id="linearGradient14471"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.7041896,0,0,0.7041896,-18.406429,-249.43017)"
x1="240.9062"
y1="425.18195"
x2="248.28683"
y2="437.96558" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient10554"
id="linearGradient14473"
gradientUnits="userSpaceOnUse"
gradientTransform="translate(-137.34366,-352.57235)"
x1="240.9062"
y1="425.18195"
x2="248.28683"
y2="437.96558" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient124"
id="linearGradient14475"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(2,0,0,0.5,-20.55174,-11.55357)"
x1="253.75711"
y1="-129.52815"
x2="252.00447"
y2="-135.47408" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient124"
id="radialGradient14477"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.833516,0,0,1.199737,2.4375,-23.45032)"
cx="307.7507"
cy="361.47824"
fx="307.7507"
fy="361.47824"
r="12.509617" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient8773"
id="radialGradient14479"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.234973,0,18.5877)"
cx="-57.850174"
cy="24.296782"
fx="-58.028885"
fy="27.01318"
r="8.087534" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient10554"
id="linearGradient14481"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.125001,0,0,1.125001,-202.51184,-408.14432)"
x1="240.9062"
y1="425.18195"
x2="248.28683"
y2="437.96558" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient124"
id="radialGradient14483"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9377063,0,0,1.3497053,-220.82833,-410.36528)"
cx="307.7507"
cy="361.47824"
fx="307.7507"
fy="361.47824"
r="12.509617" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient124"
id="linearGradient14485"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.8939146,2.0648066,-0.5162016,0.2234786,-220.82833,-410.36529)"
x1="253.75711"
y1="-129.52815"
x2="252.00447"
y2="-135.47408" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient8773"
id="radialGradient14487"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.234973,0,18.5877)"
cx="-57.850174"
cy="24.296782"
fx="-58.028885"
fy="27.01318"
r="8.087534" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient10554"
id="linearGradient14489"
gradientUnits="userSpaceOnUse"
gradientTransform="translate(-144.34366,-395.57235)"
x1="240.9062"
y1="425.18195"
x2="248.28683"
y2="437.96558" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient124"
id="radialGradient14491"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.6670334,0,0,2.399476,-491.25039,-801.09382)"
cx="307.7507"
cy="361.47824"
fx="307.7507"
fy="361.47824"
r="12.509617" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient124"
id="linearGradient14493"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.5891814,3.6707672,-0.9176918,0.3972953,-491.25038,-801.09383)"
x1="253.75711"
y1="-129.52815"
x2="252.00447"
y2="-135.47408" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient8773"
id="radialGradient14495"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.234973,0,18.5877)"
cx="-57.850174"
cy="24.296782"
fx="-58.028885"
fy="27.01318"
r="8.087534" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient8773"
id="radialGradient7954"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.234973,0,18.5877)"
cx="-57.850174"
cy="24.296782"
fx="-58.028885"
fy="27.01318"
r="8.087534" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient10554"
id="linearGradient7960"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.3333333,0,0,1.3333333,-220.12487,-531.76312)"
x1="240.9062"
y1="425.18195"
x2="248.28683"
y2="437.96558" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient124"
id="radialGradient7963"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.1113546,0,0,1.5996493,-241.83329,-534.39538)"
cx="307.7507"
cy="361.47824"
fx="307.7507"
fy="361.47824"
r="12.509617" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient124"
id="linearGradient7966"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.0594534,2.447176,-0.611794,0.2648633,-241.83329,-534.39539)"
x1="253.75711"
y1="-129.52815"
x2="252.00447"
y2="-135.47408" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient8773"
id="radialGradient8746"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.234973,0,18.5877)"
cx="-57.850174"
cy="24.296782"
fx="-58.028885"
fy="27.01318"
r="8.087534" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient124"
id="linearGradient8748"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.0594534,2.447176,-0.611794,0.2648633,-241.83329,-534.39539)"
x1="253.75711"
y1="-129.52815"
x2="252.00447"
y2="-135.47408" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient124"
id="radialGradient8750"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.1113546,0,0,1.5996493,-241.83329,-534.39538)"
cx="307.7507"
cy="361.47824"
fx="307.7507"
fy="361.47824"
r="12.509617" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient10554"
id="linearGradient8752"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.3333333,0,0,1.3333333,-220.12487,-531.76312)"
x1="240.9062"
y1="425.18195"
x2="248.28683"
y2="437.96558" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient10554"
id="linearGradient8755"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.3333333,0,0,1.3333333,-220.1248,-531.60971)"
x1="240.9062"
y1="425.18195"
x2="248.28683"
y2="437.96558" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient124"
id="radialGradient8758"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.1113546,0,0,1.5996493,-241.83322,-534.24197)"
cx="307.7507"
cy="361.47824"
fx="307.7507"
fy="361.47824"
r="12.509617" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient124"
id="linearGradient8761"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.0594534,2.447176,-0.611794,0.2648633,-241.83322,-534.24198)"
x1="253.75711"
y1="-129.52815"
x2="252.00447"
y2="-135.47408" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient124"
id="linearGradient8771"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.0594534,2.447176,-0.611794,0.2648633,-241.83322,-534.24198)"
x1="253.75711"
y1="-129.52815"
x2="252.00447"
y2="-135.47408" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient124"
id="radialGradient8773"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.1113546,0,0,1.5996493,-241.83322,-534.24197)"
cx="307.7507"
cy="361.47824"
fx="307.7507"
fy="361.47824"
r="12.509617" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient10554"
id="linearGradient8775"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.3333333,0,0,1.3333333,-220.1248,-531.60971)"
x1="240.9062"
y1="425.18195"
x2="248.28683"
y2="437.96558" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient10554"
id="linearGradient8778"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.3333333,0,0,1.3333333,-220.3124,-531.60971)"
x1="240.9062"
y1="425.18195"
x2="248.28683"
y2="437.96558" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient124"
id="radialGradient8781"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.1113546,0,0,1.5996493,-242.02082,-534.24197)"
cx="307.7507"
cy="361.47824"
fx="307.7507"
fy="361.47824"
r="12.509617" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient124"
id="linearGradient8784"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.0594534,2.447176,-0.611794,0.2648633,-242.02082,-534.24198)"
x1="253.75711"
y1="-129.52815"
x2="252.00447"
y2="-135.47408" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient8773"
id="radialGradient8830"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.234973,0,18.5877)"
cx="-57.850174"
cy="24.296782"
fx="-58.028885"
fy="27.01318"
r="8.087534" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient124"
id="linearGradient8832"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.5891814,3.6707672,-0.9176918,0.3972953,-491.25038,-801.09383)"
x1="253.75711"
y1="-129.52815"
x2="252.00447"
y2="-135.47408" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient124"
id="radialGradient8834"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.6670334,0,0,2.399476,-491.25039,-801.09382)"
cx="307.7507"
cy="361.47824"
fx="307.7507"
fy="361.47824"
r="12.509617" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient10554"
id="linearGradient8836"
gradientUnits="userSpaceOnUse"
gradientTransform="translate(-144.34366,-395.57235)"
x1="240.9062"
y1="425.18195"
x2="248.28683"
y2="437.96558" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient8773"
id="radialGradient8838"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.234973,0,18.5877)"
cx="-57.850174"
cy="24.296782"
fx="-58.028885"
fy="27.01318"
r="8.087534" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient124"
id="linearGradient8840"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.0594534,2.447176,-0.611794,0.2648633,-242.02082,-534.24198)"
x1="253.75711"
y1="-129.52815"
x2="252.00447"
y2="-135.47408" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient124"
id="radialGradient8842"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.1113546,0,0,1.5996493,-242.02082,-534.24197)"
cx="307.7507"
cy="361.47824"
fx="307.7507"
fy="361.47824"
r="12.509617" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient10554"
id="linearGradient8844"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.3333333,0,0,1.3333333,-220.3124,-531.60971)"
x1="240.9062"
y1="425.18195"
x2="248.28683"
y2="437.96558" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient10554"
id="linearGradient8855"
gradientUnits="userSpaceOnUse"
gradientTransform="translate(-144.34366,-395.57235)"
x1="240.9062"
y1="425.18195"
x2="248.28683"
y2="437.96558" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient124"
id="radialGradient8858"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.6670334,0,0,2.399476,-491.25039,-801.09382)"
cx="307.7507"
cy="361.47824"
fx="307.7507"
fy="361.47824"
r="12.509617" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient124"
id="linearGradient8861"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.5891814,3.6707672,-0.9176918,0.3972953,-491.25038,-801.09383)"
x1="253.75711"
y1="-129.52815"
x2="252.00447"
y2="-135.47408" />
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
gridtolerance="10000"
guidetolerance="10"
objecttolerance="10"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="5.6568543"
inkscape:cx="64.614973"
inkscape:cy="46.534319"
inkscape:document-units="px"
inkscape:current-layer="layer3"
showgrid="true"
inkscape:snap-nodes="false"
inkscape:snap-bbox="true"
inkscape:snap-global="true"
showguides="true"
inkscape:guide-bbox="true"
inkscape:window-width="1679"
inkscape:window-height="977"
inkscape:window-x="1281"
inkscape:window-y="48">
<inkscape:grid
type="xygrid"
id="grid13478"
visible="true"
enabled="true"
spacingx="0.5px"
spacingy="0.5px"
empspacing="2" />
</sodipodi:namedview>
<metadata
id="metadata7">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:groupmode="layer"
id="layer3"
inkscape:label="artwork:tool-arrow"
style="display:inline">
<path
transform="matrix(0.989175,0,0,1.31555,167.22388,56.536408)"
d="M -49.76264,24.296782 A 8.087534,1.9003495 0 1 1 -65.937708,24.296782 A 8.087534,1.9003495 0 1 1 -49.76264,24.296782 z"
sodipodi:ry="1.9003495"
sodipodi:rx="8.087534"
sodipodi:cy="24.296782"
sodipodi:cx="-57.850174"
id="path8771"
style="opacity:0.7;fill:url(#radialGradient14479);fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;display:inline"
sodipodi:type="arc" />
<g
style="display:inline"
id="g79"
transform="translate(-156.06247,-331.09622)">
<path
sodipodi:nodetypes="cccccccc"
style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#888a85;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
d="M 258.57812,401.60617 L 258.57812,417.04968 L 263.125,414.04968 L 265.90625,420.48718 L 268.1875,419.48718 L 265.46875,413.20593 L 269.56185,412.76843 L 258.57812,401.60617 z"
id="rect16" />
<path
sodipodi:nodetypes="ccccccccc"
id="rect91"
d="M 481.01295,-78.954349 L 484.11717,-79.645589 L 484.52504,-78.954349 L 491.01295,-78.954349 L 491.01998,-77.463121 L 484.28372,-77.462474 L 483.9729,-76.666406 L 481.00254,-77.462159 L 481.01295,-78.954349 z"
style="fill:url(#linearGradient14475);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.24999988;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1"
transform="matrix(0.397295,0.917691,-0.917691,0.397295,0,0)" />
<path
style="fill:url(#radialGradient14477);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.25;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1"
d="M 268.45834,412.37995 L 264.03447,412.8429 L 259.08804,416.09773 L 259.07888,402.85299 L 268.45834,412.37995 z"
id="path15"
sodipodi:nodetypes="ccccc" />
</g>
<path
style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient14473);stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;display:inline"
d="M 111.38437,80.978458 L 107.31977,81.366268 L 103.50867,84.146458 L 103.49998,72.973838 L 111.38437,80.978458 z"
id="path7947"
sodipodi:nodetypes="ccccc" />
<g
style="display:inline"
id="g14435"
transform="translate(-22.000014,29.000022)">
<path
sodipodi:nodetypes="cccccccc"
style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#888a85;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
d="M 150.5,48.5 L 150.5,59.5 L 153.5,57.5 L 155.5,61.5 L 157.5,60.5 L 155.5,56.5 L 158.5,56.5 L 150.5,48.5 z"
id="path14451" />
<path
sodipodi:nodetypes="ccccccccc"
id="path14453"
d="M 154.008,54.448252 L 155.59103,55.96514 L 155.06871,56.768088 L 156.83361,60.279957 L 155.71008,60.83563 L 154.0092,57.369925 L 153.22923,57.090442 L 153.04079,54.858996 L 154.008,54.448252 z"
style="fill:url(#linearGradient14467);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.24999988;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1" />
<path
style="fill:url(#radialGradient14469);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.25;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1"
d="M 157.29014,55.997498 L 154.8557,55.999843 L 151.00417,58.559717 L 151.0033,49.735141 L 157.29014,55.997498 z"
id="path14455"
sodipodi:nodetypes="ccccc" />
<path
sodipodi:nodetypes="ccccc"
id="path14457"
d="M 156.09792,55.503506 L 154.63636,55.542223 L 151.51178,57.639513 L 151.50565,50.893522 L 156.09792,55.503506 z"
style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient14471);stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;display:inline" />
</g>
<g
inkscape:groupmode="layer"
id="layer4"
inkscape:label="plate#1"
style="display:none">
<rect
y="69"
x="97"
height="22"
width="22"
id="rect14465"
style="fill:#000000;fill-opacity:0.50196078;fill-rule:evenodd;stroke:none;stroke-width:3.7750001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1;display:inline" />
<rect
style="fill:#000000;fill-opacity:0.50196078;fill-rule:evenodd;stroke:none;stroke-width:3.7750001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1;display:inline"
id="rect72"
width="24"
height="24"
x="96"
y="68" />
<rect
y="76"
x="124"
height="16"
width="16"
id="rect14403"
style="fill:#000000;fill-opacity:0.50196078;fill-rule:evenodd;stroke:none;stroke-width:3.7750001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1;display:inline" />
<rect
y="60"
x="60"
height="32"
width="32"
id="rect7952"
style="fill:#000000;fill-opacity:0.50196078;fill-rule:evenodd;stroke:none;stroke-width:3.7750001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1;display:inline" />
<rect
style="fill:#000000;fill-opacity:0.50196078;fill-rule:evenodd;stroke:none;stroke-width:3.7750001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1;display:inline"
id="rect14367"
width="48"
height="48"
x="8"
y="44" />
</g>
<g
style="display:inline"
id="g8787"
transform="translate(-31,31)">
<path
transform="matrix(1.3189,0,0,1.7540667,185.96524,13.868621)"
d="M -49.76264,24.296782 A 8.087534,1.9003495 0 1 1 -65.937708,24.296782 A 8.087534,1.9003495 0 1 1 -49.76264,24.296782 z"
sodipodi:ry="1.9003495"
sodipodi:rx="8.087534"
sodipodi:cy="24.296782"
sodipodi:cx="-57.850174"
id="path7938"
style="opacity:0.7;fill:url(#radialGradient8838);fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;display:inline"
sodipodi:type="arc" />
<path
id="path7942"
d="M 99.5,32.5 L 99.5,53.5 L 105.5,49.5 L 109.5,57.5 L 112.5,56 L 108.5,48.5 L 114.5,47.5 L 99.5,32.5 z"
style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#888a85;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
sodipodi:nodetypes="cccccccc" />
<path
style="fill:url(#linearGradient8840);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
d="M 106.14218,43.762567 L 108.68314,47.878279 L 108.0534,48.743512 L 111.81444,55.783603 L 109.72399,56.828242 L 105.89701,49.207272 L 104.7583,49.248655 L 104.31084,44.540282 L 106.14218,43.762567 z"
id="path7944"
sodipodi:nodetypes="ccccccccc" />
<path
sodipodi:nodetypes="ccccc"
id="path7946"
d="M 113.46659,47.173634 L 106.30247,48.357306 L 100.0002,52.575985 L 99.998595,33.713208 L 113.46659,47.173634 z"
style="fill:url(#radialGradient8842);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
<path
style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient8844);stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;display:inline"
d="M 112.42262,46.84474 L 106.10081,47.889164 L 100.50373,51.642958 L 100.52338,34.953163 L 112.42262,46.84474 z"
id="path7948"
sodipodi:nodetypes="ccccc" />
</g>
<path
transform="matrix(1.9783517,0,0,2.6311023,150.44787,21.072802)"
d="M -49.76264,24.296782 A 8.087534,1.9003495 0 1 1 -65.937708,24.296782 A 8.087534,1.9003495 0 1 1 -49.76264,24.296782 z"
sodipodi:ry="1.9003495"
sodipodi:rx="8.087534"
sodipodi:cy="24.296782"
sodipodi:cx="-57.850174"
id="path14357"
style="opacity:0.7;fill:url(#radialGradient8830);fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;display:inline"
sodipodi:type="arc" />
<path
id="path14359"
d="M 21.0313,49.019882 L 21.0313,79.906929 L 30.125067,73.906919 L 35.687572,86.781929 L 40.250076,84.781929 L 34.812571,72.219419 L 42.998778,71.344419 L 21.0313,49.019882 z"
style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#888a85;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;display:inline"
sodipodi:nodetypes="cccccccc" />
<path
style="fill:url(#linearGradient8861);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.24999988;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1;display:inline"
d="M 30.994554,65.913749 L 35.187554,71.393389 L 34.416573,72.549189 L 39.58759,84.520119 L 35.94075,86.096749 L 30.602775,73.733639 L 29.099899,73.732579 L 28.247541,67.080319 L 30.994554,65.913749 z"
id="path14361"
sodipodi:nodetypes="ccccccccc" />
<path
sodipodi:nodetypes="ccccc"
id="path14363"
d="M 41.928178,70.962049 L 32.149196,71.998439 L 21.514496,79.013179 L 21.543527,50.266617 L 41.928178,70.962049 z"
style="fill:url(#radialGradient8858);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.25;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1;display:inline" />
<path
style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient8855);stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;display:inline"
d="M 40.852205,70.572499 L 31.965383,71.521739 L 22.007218,78.076499 L 22.08452,51.595929 L 40.852205,70.572499 z"
id="path14365"
sodipodi:nodetypes="ccccc" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 29 KiB

690
icons/svg/tool-i-beam.svg Normal file
View file

@ -0,0 +1,690 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="150"
height="100"
id="svg2"
sodipodi:version="0.32"
inkscape:version="0.46"
version="1.0"
sodipodi:docname="tool-i-beam.svg"
inkscape:output_extension="org.inkscape.output.svg.inkscape">
<defs
id="defs4">
<linearGradient
inkscape:collect="always"
id="linearGradient10554">
<stop
style="stop-color:white;stop-opacity:1;"
offset="0"
id="stop10556" />
<stop
style="stop-color:white;stop-opacity:0;"
offset="1"
id="stop10558" />
</linearGradient>
<linearGradient
id="linearGradient124">
<stop
style="stop-color:#ffffff;stop-opacity:1.0000000;"
offset="0.0000000"
id="stop125" />
<stop
style="stop-color:silver;stop-opacity:1;"
offset="1"
id="stop126" />
</linearGradient>
<linearGradient
inkscape:collect="always"
id="linearGradient8773">
<stop
style="stop-color:black;stop-opacity:0.3137255"
offset="0"
id="stop8775" />
<stop
style="stop-color:black;stop-opacity:0;"
offset="1"
id="stop8777" />
</linearGradient>
<inkscape:perspective
sodipodi:type="inkscape:persp3d"
inkscape:vp_x="0 : 526.18109 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_z="744.09448 : 526.18109 : 1"
inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
id="perspective10" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient10554"
id="linearGradient14473"
gradientUnits="userSpaceOnUse"
gradientTransform="translate(-137.34366,-352.57235)"
x1="240.9062"
y1="425.18195"
x2="248.28683"
y2="437.96558" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient124"
id="linearGradient14475"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(2,0,0,0.5,-20.55174,-11.55357)"
x1="253.75711"
y1="-129.52815"
x2="252.00447"
y2="-135.47408" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient124"
id="radialGradient14477"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.833516,0,0,1.199737,2.4375,-23.45032)"
cx="307.7507"
cy="361.47824"
fx="307.7507"
fy="361.47824"
r="12.509617" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient8773"
id="radialGradient14479"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.234973,0,18.5877)"
cx="-57.850174"
cy="24.296782"
fx="-58.028885"
fy="27.01318"
r="8.087534" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient10554"
id="linearGradient14481"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.125001,0,0,1.125001,-202.51184,-408.14432)"
x1="240.9062"
y1="425.18195"
x2="248.28683"
y2="437.96558" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient124"
id="radialGradient14483"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9377063,0,0,1.3497053,-220.82833,-410.36528)"
cx="307.7507"
cy="361.47824"
fx="307.7507"
fy="361.47824"
r="12.509617" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient124"
id="linearGradient14485"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.8939146,2.0648066,-0.5162016,0.2234786,-220.82833,-410.36529)"
x1="253.75711"
y1="-129.52815"
x2="252.00447"
y2="-135.47408" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient8773"
id="radialGradient14487"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.234973,0,18.5877)"
cx="-57.850174"
cy="24.296782"
fx="-58.028885"
fy="27.01318"
r="8.087534" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient10554"
id="linearGradient14489"
gradientUnits="userSpaceOnUse"
gradientTransform="translate(-144.34366,-395.57235)"
x1="240.9062"
y1="425.18195"
x2="248.28683"
y2="437.96558" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient124"
id="radialGradient14491"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.6670334,0,0,2.399476,-491.25039,-801.09382)"
cx="307.7507"
cy="361.47824"
fx="307.7507"
fy="361.47824"
r="12.509617" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient124"
id="linearGradient14493"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.5891814,3.6707672,-0.9176918,0.3972953,-491.25038,-801.09383)"
x1="253.75711"
y1="-129.52815"
x2="252.00447"
y2="-135.47408" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient8773"
id="radialGradient14495"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.234973,0,18.5877)"
cx="-57.850174"
cy="24.296782"
fx="-58.028885"
fy="27.01318"
r="8.087534" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient8773"
id="radialGradient7954"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.234973,0,18.5877)"
cx="-57.850174"
cy="24.296782"
fx="-58.028885"
fy="27.01318"
r="8.087534" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient10554"
id="linearGradient7960"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.3333333,0,0,1.3333333,-220.12487,-531.76312)"
x1="240.9062"
y1="425.18195"
x2="248.28683"
y2="437.96558" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient124"
id="radialGradient7963"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.1113546,0,0,1.5996493,-241.83329,-534.39538)"
cx="307.7507"
cy="361.47824"
fx="307.7507"
fy="361.47824"
r="12.509617" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient124"
id="linearGradient7966"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.0594534,2.447176,-0.611794,0.2648633,-241.83329,-534.39539)"
x1="253.75711"
y1="-129.52815"
x2="252.00447"
y2="-135.47408" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient8773"
id="radialGradient8746"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.234973,0,18.5877)"
cx="-57.850174"
cy="24.296782"
fx="-58.028885"
fy="27.01318"
r="8.087534" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient124"
id="linearGradient8748"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.0594534,2.447176,-0.611794,0.2648633,-241.83329,-534.39539)"
x1="253.75711"
y1="-129.52815"
x2="252.00447"
y2="-135.47408" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient124"
id="radialGradient8750"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.1113546,0,0,1.5996493,-241.83329,-534.39538)"
cx="307.7507"
cy="361.47824"
fx="307.7507"
fy="361.47824"
r="12.509617" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient10554"
id="linearGradient8752"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.3333333,0,0,1.3333333,-220.12487,-531.76312)"
x1="240.9062"
y1="425.18195"
x2="248.28683"
y2="437.96558" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient10554"
id="linearGradient8755"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.3333333,0,0,1.3333333,-220.1248,-531.60971)"
x1="240.9062"
y1="425.18195"
x2="248.28683"
y2="437.96558" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient124"
id="radialGradient8758"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.1113546,0,0,1.5996493,-241.83322,-534.24197)"
cx="307.7507"
cy="361.47824"
fx="307.7507"
fy="361.47824"
r="12.509617" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient124"
id="linearGradient8761"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.0594534,2.447176,-0.611794,0.2648633,-241.83322,-534.24198)"
x1="253.75711"
y1="-129.52815"
x2="252.00447"
y2="-135.47408" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient124"
id="linearGradient8771"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.0594534,2.447176,-0.611794,0.2648633,-241.83322,-534.24198)"
x1="253.75711"
y1="-129.52815"
x2="252.00447"
y2="-135.47408" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient124"
id="radialGradient8773"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.1113546,0,0,1.5996493,-241.83322,-534.24197)"
cx="307.7507"
cy="361.47824"
fx="307.7507"
fy="361.47824"
r="12.509617" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient10554"
id="linearGradient8775"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.3333333,0,0,1.3333333,-220.1248,-531.60971)"
x1="240.9062"
y1="425.18195"
x2="248.28683"
y2="437.96558" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient10554"
id="linearGradient8778"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.3333333,0,0,1.3333333,-220.3124,-531.60971)"
x1="240.9062"
y1="425.18195"
x2="248.28683"
y2="437.96558" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient124"
id="radialGradient8781"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.1113546,0,0,1.5996493,-242.02082,-534.24197)"
cx="307.7507"
cy="361.47824"
fx="307.7507"
fy="361.47824"
r="12.509617" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient124"
id="linearGradient8784"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.0594534,2.447176,-0.611794,0.2648633,-242.02082,-534.24198)"
x1="253.75711"
y1="-129.52815"
x2="252.00447"
y2="-135.47408" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient8773"
id="radialGradient8830"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.234973,0,18.5877)"
cx="-57.850174"
cy="24.296782"
fx="-58.028885"
fy="27.01318"
r="8.087534" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient124"
id="linearGradient8832"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.5891814,3.6707672,-0.9176918,0.3972953,-491.25038,-801.09383)"
x1="253.75711"
y1="-129.52815"
x2="252.00447"
y2="-135.47408" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient124"
id="radialGradient8834"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.6670334,0,0,2.399476,-491.25039,-801.09382)"
cx="307.7507"
cy="361.47824"
fx="307.7507"
fy="361.47824"
r="12.509617" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient10554"
id="linearGradient8836"
gradientUnits="userSpaceOnUse"
gradientTransform="translate(-144.34366,-395.57235)"
x1="240.9062"
y1="425.18195"
x2="248.28683"
y2="437.96558" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient8773"
id="radialGradient8838"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.234973,0,18.5877)"
cx="-57.850174"
cy="24.296782"
fx="-58.028885"
fy="27.01318"
r="8.087534" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient124"
id="linearGradient8840"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.0594534,2.447176,-0.611794,0.2648633,-242.02082,-534.24198)"
x1="253.75711"
y1="-129.52815"
x2="252.00447"
y2="-135.47408" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient124"
id="radialGradient8842"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.1113546,0,0,1.5996493,-242.02082,-534.24197)"
cx="307.7507"
cy="361.47824"
fx="307.7507"
fy="361.47824"
r="12.509617" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient10554"
id="linearGradient8844"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.3333333,0,0,1.3333333,-220.3124,-531.60971)"
x1="240.9062"
y1="425.18195"
x2="248.28683"
y2="437.96558" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient10554"
id="linearGradient8855"
gradientUnits="userSpaceOnUse"
gradientTransform="translate(-144.34366,-395.57235)"
x1="240.9062"
y1="425.18195"
x2="248.28683"
y2="437.96558" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient124"
id="radialGradient8858"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.6670334,0,0,2.399476,-491.25039,-801.09382)"
cx="307.7507"
cy="361.47824"
fx="307.7507"
fy="361.47824"
r="12.509617" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient124"
id="linearGradient8861"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.5891814,3.6707672,-0.9176918,0.3972953,-491.25038,-801.09383)"
x1="253.75711"
y1="-129.52815"
x2="252.00447"
y2="-135.47408" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient124"
id="linearGradient8753"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(2,0,0,0.5,-20.55174,-11.55357)"
x1="253.75711"
y1="-129.52815"
x2="252.00447"
y2="-135.47408" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient124"
id="radialGradient8755"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.833516,0,0,1.199737,2.4375,-23.45032)"
cx="307.7507"
cy="361.47824"
fx="307.7507"
fy="361.47824"
r="12.509617" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient10554"
id="linearGradient8757"
gradientUnits="userSpaceOnUse"
gradientTransform="translate(-137.34366,-378.85608)"
x1="240.9062"
y1="425.18195"
x2="248.28683"
y2="437.96558" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient8773"
id="radialGradient8767"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.234973,0,18.5877)"
cx="-57.850174"
cy="24.296782"
fx="-58.028885"
fy="27.01318"
r="8.087534" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient8773"
id="radialGradient8778"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.234973,0,18.5877)"
cx="-57.850174"
cy="24.296782"
fx="-58.028885"
fy="27.01318"
r="8.087534" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient8773"
id="radialGradient8788"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.234973,0,18.5877)"
cx="-57.850174"
cy="24.296782"
fx="-58.028885"
fy="27.01318"
r="8.087534" />
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
gridtolerance="10000"
guidetolerance="10"
objecttolerance="10"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="32"
inkscape:cx="135.70823"
inkscape:cy="18.300078"
inkscape:document-units="px"
inkscape:current-layer="layer4"
showgrid="true"
inkscape:snap-nodes="false"
inkscape:snap-bbox="true"
inkscape:snap-global="true"
showguides="true"
inkscape:guide-bbox="true"
inkscape:window-width="1670"
inkscape:window-height="973"
inkscape:window-x="1285"
inkscape:window-y="48">
<inkscape:grid
type="xygrid"
id="grid13478"
visible="true"
enabled="true"
spacingx="0.5px"
spacingy="0.5px"
empspacing="2" />
</sodipodi:namedview>
<metadata
id="metadata7">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:groupmode="layer"
id="layer3"
inkscape:label="artwork:tool-i-beam"
style="display:inline">
<path
transform="matrix(0.989175,0,0,1.31555,164.72395,56.536408)"
d="M -49.76264,24.296782 A 8.087534,1.9003495 0 1 1 -65.937708,24.296782 A 8.087534,1.9003495 0 1 1 -49.76264,24.296782 z"
sodipodi:ry="1.9003495"
sodipodi:rx="8.087534"
sodipodi:cy="24.296782"
sodipodi:cx="-57.850174"
id="path8771"
style="opacity:0.7;fill:url(#radialGradient14479);fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;display:inline"
sodipodi:type="arc" />
<g
inkscape:groupmode="layer"
id="layer4"
inkscape:label="plate#1"
style="display:none"
sodipodi:insensitive="true">
<rect
style="fill:#000000;fill-opacity:0.50196078;fill-rule:evenodd;stroke:none;stroke-width:3.7750001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1;display:inline"
id="rect72"
width="24"
height="24"
x="96"
y="68" />
<rect
y="69"
x="97"
height="22"
width="22"
id="rect14465"
style="fill:#000000;fill-opacity:0.50196078;fill-rule:evenodd;stroke:none;stroke-width:3.7750001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1;display:inline" />
<rect
style="fill:#000000;fill-opacity:0.50196078;fill-rule:evenodd;stroke:none;stroke-width:3.7750001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1;display:inline"
id="rect7973"
width="16"
height="16"
x="124"
y="76.009514" />
<rect
y="60"
x="60"
height="32"
width="32"
id="rect8763"
style="fill:#000000;fill-opacity:0.50196078;fill-rule:evenodd;stroke:none;stroke-width:3.7750001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1;display:inline" />
<rect
y="44"
x="8"
height="48"
width="48"
id="rect8782"
style="fill:#000000;fill-opacity:0.50196078;fill-rule:evenodd;stroke:none;stroke-width:3.7750001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1;display:inline" />
</g>
<path
style="fill:#eeeeec;fill-rule:evenodd;stroke:#888a85;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
d="M 104.5,71.505242 C 104,71.505242 103.5,72.005242 103.5,72.5 C 103.5,73.005242 104,73.505242 104.5,73.505242 L 105.5,73.505242 C 106,73.505242 106.5,74.005242 106.5,74.505242 L 106.5,85.5 C 106.5,86 106,86.5 105.5,86.5 L 104.5,86.5 C 104,86.5 103.5,87 103.5,87.5 C 103.5,88.008876 104,88.5 104.5,88.5 L 106.5,88.5 C 107.02152,88.521523 107.5,88 107.5,87.5 C 107.5,88 108,88.5 108.5,88.5 L 110.5,88.490485 C 110.99999,88.488106 111.5,87.990485 111.5,87.5 C 111.5,86.990485 110.99998,86.485728 110.5,86.490485 L 109.5,86.5 C 109,86.5 108.5,86 108.5,85.5 L 108.5,74.505242 C 108.5,74.005242 109,73.505242 109.5,73.505242 L 110.5,73.5 C 110.99999,73.497379 111.5,73 111.5,72.515625 C 111.5,72 111,71.49869 110.5,71.5 L 108.5,71.505242 C 108,71.505242 107.5,72.005242 107.5,72.505242 C 107.5,72.005242 107,71.505242 106.5,71.505242 L 104.5,71.505242 z"
id="path7969"
sodipodi:nodetypes="cssccccssscccsssccccssscccs" />
<path
sodipodi:nodetypes="cssccccssscccsssccccssscccs"
id="path7977"
d="M 130.5,77.5 C 129.99037,77.5 129.5,78 129.5,78.5 C 129.5,79 130,79.5 130.5,79.5 L 130.5,79.5 C 131,79.5 131.5,80 131.5,80.5 L 131.5,87.5 C 131.5,88 131,88.5 130.5,88.5 L 130.5,88.5 C 130,88.5 129.5,89 129.5,89.5 C 129.5,90 130,90.5 130.5,90.5 L 131.5,90.5 C 132,90.5 132.5,90 132.5,89.5 C 132.5,90 133,90.5 133.5,90.5 L 134.5,90.5 C 135,90.5 135.5,90 135.5,89.5 C 135.5,89 135,88.5 134.5,88.5 L 134.5,88.5 C 134,88.5 133.5,88 133.5,87.5 L 133.5,80.5 C 133.5,80 134,79.5 134.5,79.5 L 134.5,79.5 C 135,79.5 135.5,79 135.5,78.5 C 135.5,78 135,77.5 134.5,77.5 L 133.5,77.5 C 133,77.5 132.5,78 132.5,78.5 C 132.5,78 132,77.5 131.5,77.5 L 130.5,77.5 z"
style="fill:#eeeeec;fill-rule:evenodd;stroke:#888a85;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<path
sodipodi:type="arc"
style="opacity:0.7;fill:url(#radialGradient8778);fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;display:inline"
id="path8759"
sodipodi:cx="-57.850174"
sodipodi:cy="24.296782"
sodipodi:rx="8.087534"
sodipodi:ry="1.9003495"
d="M -49.76264,24.296782 A 8.087534,1.9003495 0 1 1 -65.937708,24.296782 A 8.087534,1.9003495 0 1 1 -49.76264,24.296782 z"
transform="matrix(1.3189,0,0,1.7540667,152.29859,44.715211)" />
<path
sodipodi:nodetypes="cssccccssscccsssccccssscccs"
id="path8765"
d="M 71.5,64.5 C 71,64.498835 70,65 70,66 C 70,67 71,67.5 71.5,67.5 L 73.5,67.5 C 74,67.5 74.5,68 74.5,68.506989 L 74.5,83.166666 C 74.5,83.833333 73.83333,84.5 73.16667,84.5 L 71.5,84.5 C 71,84.5 70,85 70,86 C 70,87 71,87.5 71.5,87.5 L 74.5,87.5 C 75.5,87.5 76,86.5 76,86 C 76,86.5 76.5,87.5 77.5,87.5 L 80.5,87.5 C 81,87.5 82,87 82,86 C 82,85 81,84.5 80.5,84.5 L 78.5,84.5 C 77.83333,84.5 77.5,83.826344 77.5,83.159677 L 77.5,68.5 C 77.5,68 78,67.5 78.5,67.5 L 80.5,67.5 C 81,67.5 82,67 82,66 C 82,65 81,64.5 80.5,64.5 L 77.5,64.5 C 76.5,64.5 76,65.5 76,66 C 76,65.5 75.5,64.5 74.5,64.506989 L 71.5,64.5 z"
style="fill:#eeeeec;fill-rule:evenodd;stroke:#888a85;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<path
sodipodi:type="arc"
style="opacity:0.7;fill:url(#radialGradient8788);fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;display:inline"
id="path8780"
sodipodi:cx="-57.850174"
sodipodi:cy="24.296782"
sodipodi:rx="8.087534"
sodipodi:ry="1.9003495"
d="M -49.76264,24.296782 A 8.087534,1.9003495 0 1 1 -65.937708,24.296782 A 8.087534,1.9003495 0 1 1 -49.76264,24.296782 z"
transform="matrix(1.97835,0,0,2.6311,145.94789,21.072816)" />
<path
sodipodi:nodetypes="cssccccssscccsssccccssscccs"
id="path8786"
d="M 25.5,50.509196 C 24.5,50.509196 23.5,51.509196 23.5,52.498712 C 23.5,53.509196 24.5,54.509196 25.5,54.509196 L 27.5,54.509196 C 28.5,54.509196 29.5,55.509196 29.5,56.509196 L 29.5,78.498712 C 29.5,79.498712 28.5,80.498712 27.5,80.498712 L 25.5,80.498712 C 24.5,80.498712 23.5,81.498712 23.5,82.498712 C 23.5,83.516464 24.5,84.498712 25.5,84.498712 L 29.5,84.498712 C 30.54304,84.541758 31.5,83.498712 31.5,82.498712 C 31.5,83.498712 32.5,84.498712 33.5,84.498712 L 37.5,84.479682 C 38.49998,84.474924 39.5,83.479682 39.5,82.498712 C 39.5,81.479682 38.49996,80.470168 37.5,80.479682 L 35.5,80.498712 C 34.5,80.498712 33.5,79.498712 33.5,78.498712 L 33.5,56.509196 C 33.5,55.509196 34.5,54.509196 35.5,54.509196 L 37.5,54.498712 C 38.49998,54.49347 39.5,53.498712 39.5,52.529962 C 39.5,51.498712 38.5,50.496092 37.5,50.498712 L 33.5,50.509196 C 32.5,50.509196 31.5,51.509196 31.5,52.509196 C 31.5,51.509196 30.5,50.509196 29.5,50.509196 L 25.5,50.509196 z"
style="fill:#eeeeec;fill-rule:evenodd;stroke:#888a85;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 26 KiB

467
icons/timeline-panel.svg Normal file
View file

@ -0,0 +1,467 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="16"
height="16"
id="svg2677"
sodipodi:version="0.32"
inkscape:version="0.46"
sodipodi:docname="timeline-panel.svg"
version="1.0"
inkscape:output_extension="org.inkscape.output.svg.inkscape"
inkscape:export-filename="/home/joel/workspace/lumiera/lumiera/icons/timeline.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90">
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
gridtolerance="10000"
guidetolerance="10"
objecttolerance="10"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="31.678384"
inkscape:cx="7.0051041"
inkscape:cy="8.0063517"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="true"
inkscape:window-width="1263"
inkscape:window-height="839"
inkscape:window-x="6"
inkscape:window-y="46"
showguides="true"
inkscape:guide-bbox="true">
<inkscape:grid
type="xygrid"
id="grid3237"
visible="true"
enabled="true"
dotted="true"
originy="1px"
originx="1px"
spacingx="0.5px"
spacingy="0.5px"
empspacing="2"
empcolor="#ff00ff"
empopacity="0.25098039" />
<sodipodi:guide
orientation="1,0"
position="-4.7666573,8.4284603"
id="guide5650" />
</sodipodi:namedview>
<defs
id="defs2679">
<linearGradient
inkscape:collect="always"
id="linearGradient5654">
<stop
style="stop-color:#000000;stop-opacity:1"
offset="0"
id="stop5656" />
<stop
id="stop5664"
offset="0.12824202"
style="stop-color:#ffffff;stop-opacity:1" />
<stop
id="stop5662"
offset="0.87204576"
style="stop-color:#ffffff;stop-opacity:1" />
<stop
style="stop-color:#000000;stop-opacity:1"
offset="1"
id="stop5658" />
</linearGradient>
<linearGradient
inkscape:collect="always"
id="linearGradient5633">
<stop
style="stop-color:#2e3436;stop-opacity:1"
offset="0"
id="stop5635" />
<stop
style="stop-color:#555753;stop-opacity:1"
offset="1"
id="stop5637" />
</linearGradient>
<linearGradient
inkscape:collect="always"
id="linearGradient5580">
<stop
style="stop-color:#ad7fa8;stop-opacity:1"
offset="0"
id="stop5582" />
<stop
style="stop-color:#5c3566;stop-opacity:1"
offset="1"
id="stop5584" />
</linearGradient>
<linearGradient
inkscape:collect="always"
id="linearGradient5572">
<stop
style="stop-color:#888a85;stop-opacity:1"
offset="0"
id="stop5574" />
<stop
style="stop-color:#555753;stop-opacity:1"
offset="1"
id="stop5576" />
</linearGradient>
<inkscape:perspective
id="perspective2685"
inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
inkscape:vp_z="744.09448 : 526.18109 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_x="0 : 526.18109 : 1"
sodipodi:type="inkscape:persp3d" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient5572"
id="linearGradient5578"
x1="0"
y1="4.5"
x2="16"
y2="4.5"
gradientUnits="userSpaceOnUse"
gradientTransform="translate(0,1)" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient5580"
id="linearGradient5586"
x1="5"
y1="5"
x2="11"
y2="10"
gradientUnits="userSpaceOnUse"
gradientTransform="translate(0,1)" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient5580"
id="linearGradient5590"
gradientUnits="userSpaceOnUse"
x1="5"
y1="5"
x2="11"
y2="10"
gradientTransform="translate(7,1)" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient5580"
id="linearGradient5594"
gradientUnits="userSpaceOnUse"
x1="5"
y1="5"
x2="11"
y2="10"
gradientTransform="translate(-7,1)" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient5633"
id="linearGradient5639"
x1="16"
y1="2.5"
x2="0"
y2="2.5"
gradientUnits="userSpaceOnUse"
gradientTransform="translate(0,1)" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient5654"
id="linearGradient5660"
x1="0"
y1="9"
x2="16"
y2="9"
gradientUnits="userSpaceOnUse" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient5654"
id="linearGradient5682"
gradientUnits="userSpaceOnUse"
x1="0"
y1="9"
x2="16"
y2="9" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient5654"
id="linearGradient5685"
gradientUnits="userSpaceOnUse"
x1="0"
y1="9"
x2="16"
y2="9" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient5580"
id="linearGradient5687"
gradientUnits="userSpaceOnUse"
gradientTransform="translate(7,1)"
x1="5"
y1="5"
x2="11"
y2="9.5" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient5572"
id="linearGradient5689"
gradientUnits="userSpaceOnUse"
gradientTransform="translate(0,1)"
x1="0"
y1="4.5"
x2="16"
y2="4.5" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient5580"
id="linearGradient5691"
gradientUnits="userSpaceOnUse"
gradientTransform="translate(-7,1)"
x1="5"
y1="5"
x2="11"
y2="10" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient5633"
id="linearGradient5693"
gradientUnits="userSpaceOnUse"
gradientTransform="translate(0,1)"
x1="16"
y1="2.5"
x2="0"
y2="2.5" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient5633"
id="linearGradient5696"
gradientUnits="userSpaceOnUse"
gradientTransform="translate(0,1)"
x1="16"
y1="2.5"
x2="0"
y2="2.5" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient5580"
id="linearGradient5699"
gradientUnits="userSpaceOnUse"
gradientTransform="translate(-7,1)"
x1="5"
y1="5"
x2="11"
y2="10" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient5580"
id="linearGradient5702"
gradientUnits="userSpaceOnUse"
gradientTransform="translate(7,1)"
x1="5"
y1="5"
x2="11"
y2="9.5" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient5572"
id="linearGradient5707"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.8888889,0,1.3333333)"
x1="0"
y1="4.5"
x2="16"
y2="4.5" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient5580"
id="linearGradient5711"
gradientUnits="userSpaceOnUse"
gradientTransform="translate(1,1)"
x1="5"
y1="5"
x2="11"
y2="9.5" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient5580"
id="linearGradient5715"
gradientUnits="userSpaceOnUse"
gradientTransform="translate(-5,1)"
x1="5"
y1="5"
x2="11"
y2="9.5" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient5580"
id="linearGradient5734"
gradientUnits="userSpaceOnUse"
gradientTransform="translate(1,1)"
x1="5"
y1="5"
x2="11"
y2="9.5" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient5580"
id="linearGradient5738"
gradientUnits="userSpaceOnUse"
gradientTransform="translate(-5,1)"
x1="5"
y1="5"
x2="11"
y2="9.5" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient5654"
id="linearGradient5753"
gradientUnits="userSpaceOnUse"
x1="0"
y1="9"
x2="16"
y2="9" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient5654"
id="linearGradient2427"
gradientUnits="userSpaceOnUse"
x1="0"
y1="9"
x2="16"
y2="9" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient5580"
id="linearGradient2430"
gradientUnits="userSpaceOnUse"
gradientTransform="translate(-5,1)"
x1="5"
y1="5"
x2="11"
y2="9.5" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient5580"
id="linearGradient2433"
gradientUnits="userSpaceOnUse"
gradientTransform="translate(1,1)"
x1="5"
y1="5"
x2="11"
y2="9.5" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient5633"
id="linearGradient2436"
gradientUnits="userSpaceOnUse"
gradientTransform="translate(0,1)"
x1="16"
y1="2.5"
x2="0"
y2="2.5" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient5580"
id="linearGradient2439"
gradientUnits="userSpaceOnUse"
gradientTransform="translate(7,1)"
x1="5"
y1="5"
x2="11"
y2="9.5" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient5572"
id="linearGradient2444"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.8888889,0,1.3333333)"
x1="0"
y1="4.5"
x2="16"
y2="4.5" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient5654"
id="linearGradient2467"
gradientUnits="userSpaceOnUse"
x1="0"
y1="9"
x2="16"
y2="9" />
<mask
maskUnits="userSpaceOnUse"
id="mask2463">
<rect
style="fill:url(#linearGradient2467);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:1, 1;stroke-dashoffset:0"
id="rect2465"
width="16"
height="16"
x="0"
y="0" />
</mask>
</defs>
<metadata
id="metadata2682">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
</cc:Work>
</rdf:RDF>
</metadata>
<g
id="layer1"
inkscape:groupmode="layer"
inkscape:label="Layer 1">
<g
id="g2456"
mask="url(#mask2463)">
<path
id="rect3249"
d="M 0 4 L 0 5 L 0 6 L 0 10 L 0 11 L 0 12 L 16 12 L 16 11 L 15 11 L 15 10 L 16 10 L 16 6 L 15 6 L 15 5 L 16 5 L 16 4 L 0 4 z M 1 5 L 2 5 L 2 6 L 1 6 L 1 5 z M 3 5 L 4 5 L 4 6 L 3 6 L 3 5 z M 5 5 L 6 5 L 6 6 L 5 6 L 5 5 z M 7 5 L 8 5 L 8 6 L 7 6 L 7 5 z M 9 5 L 10 5 L 10 6 L 9 6 L 9 5 z M 11 5 L 12 5 L 12 6 L 11 6 L 11 5 z M 13 5 L 14 5 L 14 6 L 13 6 L 13 5 z M 1 10 L 2 10 L 2 11 L 1 11 L 1 10 z M 3 10 L 4 10 L 4 11 L 3 11 L 3 10 z M 5 10 L 6 10 L 6 11 L 5 11 L 5 10 z M 7 10 L 8 10 L 8 11 L 7 11 L 7 10 z M 9 10 L 10 10 L 10 11 L 9 11 L 9 10 z M 11 10 L 12 10 L 12 11 L 11 11 L 11 10 z M 13 10 L 14 10 L 14 11 L 13 11 L 13 10 z "
style="fill:url(#linearGradient2444);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none" />
<rect
style="fill:url(#linearGradient2439);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none"
id="rect5588"
width="5"
height="4"
x="12"
y="6"
ry="0" />
<path
sodipodi:nodetypes="cccccccccc"
d="M 0,3 L 0,4 L 16,4 L 16,3 L 0,3 z M 0,12 L 0,13 L 16,13 L 16,12 L 0,12 z"
style="fill:url(#linearGradient2436);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
id="path5616" />
<rect
ry="0"
y="6"
x="6"
height="4"
width="5"
id="rect5732"
style="fill:url(#linearGradient2433);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none" />
<rect
style="fill:url(#linearGradient2430);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none"
id="rect5736"
width="5"
height="4"
x="0"
y="6"
ry="0" />
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 14 KiB

0
po/ChangeLog Normal file
View file

2
po/LINGUAS Normal file
View file

@ -0,0 +1,2 @@
# please keep this list sorted alphabetically
#

12
po/POTFILES.in Normal file
View file

@ -0,0 +1,12 @@
# List of source files containing translatable strings.
src/gtk-lumiera.cpp
src/workspace/actions.cpp
src/dialogs/preferences-dialog.cpp
src/dialogs/render.cpp
src/panels/assets-panel.cpp
src/panels/timeline-panel.cpp
src/panels/viewer-panel.cpp

View file

@ -25,7 +25,7 @@ liblumicommon_a_CXXFLAGS = $(CXXFLAGS) -Wall
liblumicommon_a_CPPFLAGS = -I$(top_srcdir)/src/
liblumicommon_a_SOURCES = \
$(liblumicommon_a_srcdir)/time.cpp \
$(liblumicommon_a_srcdir)/lumitime.cpp \
$(liblumicommon_a_srcdir)/util.cpp \
$(liblumicommon_a_srcdir)/visitor.cpp \
$(liblumicommon_a_srcdir)/cmdline.cpp \
@ -40,11 +40,11 @@ liblumicommon_a_SOURCES = \
noinst_HEADERS += \
$(liblumicommon_a_srcdir)/cmdline.hpp \
$(liblumicommon_a_srcdir)/factory.hpp \
$(liblumicommon_a_srcdir)/frameid.hpp \
$(liblumicommon_a_srcdir)/singleton.hpp \
$(liblumicommon_a_srcdir)/singletonpolicies.hpp \
$(liblumicommon_a_srcdir)/singletonpreconfigure.hpp \
$(liblumicommon_a_srcdir)/time.hpp \
$(liblumicommon_a_srcdir)/typelist.hpp \
$(liblumicommon_a_srcdir)/lumitime.hpp \
$(liblumicommon_a_srcdir)/visitor.hpp \
$(liblumicommon_a_srcdir)/visitordispatcher.hpp \
$(liblumicommon_a_srcdir)/visitorpolicies.hpp \
@ -56,7 +56,10 @@ noinst_HEADERS += \
$(liblumicommon_a_srcdir)/query/mockconfigrules.hpp \
$(liblumicommon_a_srcdir)/singletonfactory.hpp \
$(liblumicommon_a_srcdir)/singletonsubclass.hpp \
$(liblumicommon_a_srcdir)/typelistutil.hpp \
$(liblumicommon_a_srcdir)/meta/typelist.hpp \
$(liblumicommon_a_srcdir)/meta/configflags.hpp \
$(liblumicommon_a_srcdir)/meta/generator.hpp \
$(liblumicommon_a_srcdir)/meta/typelistutil.hpp \
$(liblumicommon_a_srcdir)/util.hpp \
$(liblumicommon_a_srcdir)/test/mockinjector.hpp \
$(liblumicommon_a_srcdir)/test/suite.hpp \

View file

@ -27,7 +27,9 @@
#include "proc/nobugcfg.hpp"
#include <boost/regex.hpp>
#include <boost/algorithm/string.hpp>
#include <boost/algorithm/string/split.hpp>
#include <boost/algorithm/string/join.hpp>
#include <boost/algorithm/string/classification.hpp>
using boost::algorithm::split;
using boost::algorithm::join;

View file

@ -21,7 +21,7 @@
* *****************************************************/
#include "common/time.hpp"
#include "common/lumitime.hpp"
#include <limits>

View file

@ -1,5 +1,5 @@
/*
TIME.hpp - unified representation of a time point, including conversion functions
LUMITIME.hpp - unified representation of a time point, including conversion functions
Copyright (C) Lumiera.org
2008, Hermann Vosseler <Ichthyostega@web.de>
@ -21,8 +21,8 @@
*/
#ifndef LUMIERA_TIME_H
#define LUMIERA_TIME_H
#ifndef LUMIERA_LUMITIME_H
#define LUMIERA_LUMITIME_H
#include <boost/operators.hpp>

90
src/gui/Makefile.am Normal file
View file

@ -0,0 +1,90 @@
# Copyright (C) Lumiera.org
# 2007, Joel Holdsworth <joel@airwebreathe.org.uk>
#
# 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 2 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, write to the Free Software
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
lumigui_srcdir = $(top_srcdir)/src/gui
#noinst_LIBRARIES += liblumigui.a
#lumigui_CFLAGS = $(CFLAGS) -std=gnu99 -Wall -Werror
#lumigui_CPPFLAGS = -I$(top_srcdir)/src/
INCLUDES = \
-DPACKAGE_LOCALE_DIR=\""$(prefix)/$(DATADIRNAME)/locale"\" \
-DPACKAGE_SRC_DIR=\""$(srcdir)"\" \
-DPACKAGE_DATA_DIR=\""$(datadir)"\" \
$(GTK_LUMIERA_CFLAGS)
bin_PROGRAMS += lumigui
lumigui_SOURCES = \
$(lumigui_srcdir)/gtk-lumiera.cpp \
$(lumigui_srcdir)/gtk-lumiera.hpp \
$(lumigui_srcdir)/window-manager.cpp \
$(lumigui_srcdir)/window-manager.hpp \
$(lumigui_srcdir)/workspace/actions.cpp \
$(lumigui_srcdir)/workspace/actions.hpp \
$(lumigui_srcdir)/workspace/workspace-window.cpp \
$(lumigui_srcdir)/workspace/workspace-window.hpp \
$(lumigui_srcdir)/dialogs/render.cpp \
$(lumigui_srcdir)/dialogs/render.hpp \
$(lumigui_srcdir)/dialogs/preferences-dialog.cpp \
$(lumigui_srcdir)/dialogs/preferences-dialog.hpp \
$(lumigui_srcdir)/panels/panel.cpp \
$(lumigui_srcdir)/panels/panel.hpp \
$(lumigui_srcdir)/panels/timeline-panel.cpp \
$(lumigui_srcdir)/panels/timeline-panel.hpp \
$(lumigui_srcdir)/panels/viewer-panel.cpp \
$(lumigui_srcdir)/panels/viewer-panel.hpp \
$(lumigui_srcdir)/panels/assets-panel.cpp \
$(lumigui_srcdir)/panels/asset-panels.hpp \
$(lumigui_srcdir)/widgets/video-display-widget.cpp \
$(lumigui_srcdir)/widgets/video-display-widget.hpp \
$(lumigui_srcdir)/widgets/timeline-widget.cpp \
$(lumigui_srcdir)/widgets/timeline-widget.hpp \
$(lumigui_srcdir)/widgets/timeline/header-container.cpp \
$(lumigui_srcdir)/widgets/timeline/header-container.hpp \
$(lumigui_srcdir)/widgets/timeline/track.cpp \
$(lumigui_srcdir)/widgets/timeline/track.hpp \
$(lumigui_srcdir)/widgets/timeline/timeline-body.cpp \
$(lumigui_srcdir)/widgets/timeline/timeline-body.hpp \
$(lumigui_srcdir)/widgets/timeline/timeline-ruler.cpp \
$(lumigui_srcdir)/widgets/timeline/timeline-ruler.hpp \
$(lumigui_srcdir)/widgets/timeline/timeline-tool.cpp \
$(lumigui_srcdir)/widgets/timeline/timeline-tool.hpp \
$(lumigui_srcdir)/widgets/timeline/timeline-arrow-tool.cpp \
$(lumigui_srcdir)/widgets/timeline/timeline-arrow-tool.hpp \
$(lumigui_srcdir)/widgets/timeline/timeline-ibeam-tool.cpp \
$(lumigui_srcdir)/widgets/timeline/timeline-ibeam-tool.hpp \
$(lumigui_srcdir)/model/project.cpp \
$(lumigui_srcdir)/model/project.hpp \
$(lumigui_srcdir)/output/displayer.cpp \
$(lumigui_srcdir)/output/displayer.hpp \
$(lumigui_srcdir)/output/gdkdisplayer.cpp \
$(lumigui_srcdir)/output/gdkdisplayer.hpp \
$(lumigui_srcdir)/output/xvdisplayer.cpp \
$(lumigui_srcdir)/output/xvdisplayer.hpp
lumigui_LDFLAGS =
lumigui_LDADD = $(GTK_LUMIERA_LIBS) liblumicommon.a liblumi.a
lumigui_DEPENDENCIES = \
$(top_builddir)/lumiera_ui.rc \
$(top_builddir)/liblumicommon.a \
$(top_builddir)/liblumi.a
$(top_builddir)/lumiera_ui.rc:
cp $(lumigui_srcdir)/lumiera_ui.rc $(top_builddir)

View file

@ -0,0 +1,61 @@
/*
preferences-dialog.cpp - Implementation of the application preferences dialog
Copyright (C) Lumiera.org
2008, Joel Holdsworth <joel@airwebreathe.org.uk>
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 2 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, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
* *****************************************************/
#include "../gtk-lumiera.hpp"
#include "preferences-dialog.hpp"
using namespace Gtk;
namespace lumiera {
namespace gui {
namespace dialogs {
PreferencesDialog::PreferencesDialog(Window &parent) :
Dialog(_("Preferences"), parent, true)
{
VBox *v_box = get_vbox();
g_assert(v_box != NULL);
interfaceBox.pack_start(interfaceThemeCombo, PACK_SHRINK);
interfaceBox.set_spacing(4);
interfaceBox.set_border_width(5);
notebook.append_page(interfaceBox, _("Interface"));
v_box->pack_start(notebook);
// Configure the dialog
v_box->set_spacing(4);
set_border_width(5);
set_resizable(false);
// Configure the Cancel and OK buttons
add_button(Stock::CANCEL, RESPONSE_CANCEL);
add_button(Stock::OK, RESPONSE_OK);
show_all_children();
}
} // namespace dialogs
} // namespace gui
} // namespace lumiera

View file

@ -0,0 +1,61 @@
/*
preferences-dialog.hpp - Definition of the application preferences dialog
Copyright (C) Lumiera.org
2008, Joel Holdsworth <joel@airwebreathe.org.uk>
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 2 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, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/** @file render.hpp
** This file contains the definition of the application preferences dialog
**
*/
#ifndef PREFERENCES_DIALOG_HPP
#define PREFERENCES_DIALOG_HPP
#include <gtkmm.h>
using namespace Gtk;
namespace lumiera {
namespace gui {
namespace dialogs {
/**
* The defintion of render output dialog class
*/
class PreferencesDialog : public Dialog
{
public:
PreferencesDialog(Window &parent);
protected:
protected:
Notebook notebook;
VBox interfaceBox;
ComboBox interfaceThemeCombo;
};
} // namespace dialogs
} // namespace gui
} // namespace lumiera
#endif // PREFERENCES_DIALOG_HPP

101
src/gui/dialogs/render.cpp Normal file
View file

@ -0,0 +1,101 @@
/*
render.cpp - Definition of the main workspace window object
Copyright (C) Lumiera.org
2008, Joel Holdsworth <joel@airwebreathe.org.uk>
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 2 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, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
* *****************************************************/
#include "../gtk-lumiera.hpp"
#include "render.hpp"
using namespace Gtk;
namespace lumiera {
namespace gui {
namespace dialogs {
Render::Render(Window &parent) :
Dialog(_("Render"), parent, true),
outputFileLabel(_("Output File:")),
browseButtonImage(StockID(Stock::INDEX), ICON_SIZE_BUTTON),
outputFileBrowseButton(_("_Browse...")),
containerFormatLabel(_("Container Format:")),
renderButtonImage(StockID(Stock::OK), ICON_SIZE_BUTTON),
audioFrame(_("Audio")),
videoFrame(_("Video"))
{
VBox *v_box = get_vbox();
ASSERT(v_box != NULL);
// The Output File Row
outputFileHBox.pack_start(outputFileLabel, PACK_SHRINK);
outputFileHBox.pack_start(outputFilePathEntry);
outputFileBrowseButton.set_image(browseButtonImage);
outputFileBrowseButton.signal_clicked().connect(
sigc::mem_fun(*this, &Render::on_button_browse));
outputFileHBox.pack_start(outputFileBrowseButton, PACK_SHRINK);
outputFileHBox.set_spacing(4);
v_box->pack_start(outputFileHBox, PACK_SHRINK);
// The Container Format Row
containerFormatHBox.pack_start(containerFormatLabel, PACK_SHRINK);
containerFormatHBox.pack_start(containerFormat);
containerFormatHBox.set_spacing(4);
v_box->pack_start(containerFormatHBox, PACK_SHRINK);
v_box->pack_start(audioFrame);
v_box->pack_start(videoFrame);
// Configure the dialog
v_box->set_spacing(4);
set_border_width(5);
set_resizable(false);
// Configure the Cancel and Render buttons
add_button(Stock::CANCEL, RESPONSE_CANCEL);
Button *render_button = add_button(Stock::OK, RESPONSE_OK);
render_button->set_label(_("_Render"));
render_button->set_image(renderButtonImage);
render_button->set_flags(Gtk::CAN_DEFAULT);
render_button->grab_default();
show_all_children();
}
void Render::on_button_browse()
{
FileChooserDialog dialog(*this, _("Select a File Name for Rendering"),
FILE_CHOOSER_ACTION_SAVE);
// Add response buttons the the dialog:
dialog.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
dialog.add_button(Gtk::Stock::SAVE, Gtk::RESPONSE_OK);
int result = dialog.run();
INFO(gui, "%d", result);
if(result == RESPONSE_OK)
INFO(gui, "%d", "RESPONSE_OK");
}
} // namespace dialogs
} // namespace gui
} // namespace lumiera

View file

@ -0,0 +1,72 @@
/*
render.hpp - Definition of the render output dialog
Copyright (C) Lumiera.org
2008, Joel Holdsworth <joel@airwebreathe.org.uk>
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 2 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, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/** @file render.hpp
** This file contains the definition of the render output dialog
**
*/
#ifndef RENDER_H
#define RENDER_H
#include <gtkmm.h>
using namespace Gtk;
namespace lumiera {
namespace gui {
namespace dialogs {
/**
* The defintion of render output dialog class
*/
class Render : public Dialog
{
public:
Render(Window &parent);
protected:
void on_button_browse();
protected:
HBox outputFileHBox;
Label outputFileLabel;
Entry outputFilePathEntry;
Image browseButtonImage;
Button outputFileBrowseButton;
HBox containerFormatHBox;
Label containerFormatLabel;
ComboBox containerFormat;
Frame audioFrame;
Frame videoFrame;
Image renderButtonImage;
};
} // namespace dialogs
} // namespace gui
} // namespace lumiera
#endif // RENDER_H

92
src/gui/gtk-lumiera.cpp Normal file
View file

@ -0,0 +1,92 @@
/*
gtk-lumiera.cpp - The entry point for the GTK GUI application
Copyright (C) Lumiera.org
2008, Joel Holdsworth <joel@airwebreathe.org.uk>
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 2 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, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
* *****************************************************/
#include <gtkmm.h>
#include <nobug.h>
#ifdef ENABLE_NLS
# include <libintl.h>
#endif
#include "gtk-lumiera.hpp"
#include "window-manager.hpp"
#include "workspace/workspace-window.hpp"
#include "model/project.hpp"
NOBUG_CPP_DEFINE_FLAG(gui);
using namespace Gtk;
using namespace Glib;
using namespace lumiera::gui;
using namespace lumiera::gui::workspace;
using namespace lumiera::gui::model;
GtkLumiera the_application;
int
main (int argc, char *argv[])
{
return the_application.main(argc, argv);
}
namespace lumiera {
namespace gui {
int
GtkLumiera::main(int argc, char *argv[])
{
NOBUG_INIT;
Main kit(argc, argv);
Glib::set_application_name(AppTitle);
Project project;
WindowManager window_manager;
window_manager.set_theme("lumiera_ui.rc");
WorkspaceWindow main_window(&project);
kit.run(main_window);
}
Glib::ustring
GtkLumiera::get_home_data_path()
{
const ustring app_name("lumiera");
const ustring path(Glib::get_home_dir());
return ustring::compose("%1/.%2", path, app_name);
}
GtkLumiera&
application()
{
return the_application;
}
} // namespace gui
} // namespace lumiera

142
src/gui/gtk-lumiera.hpp Normal file
View file

@ -0,0 +1,142 @@
/*
gtk-lumiera.hpp - Application wide global definitions
Copyright (C) Lumiera.org
2008, Joel Holdsworth <joel@airwebreathe.org.uk>
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 2 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, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/** @file gtk-lumiera.hpp
** This file contains application wide global definitions
** user actions.
** @see gtk-lumiera.cpp
*/
#ifndef GTK_LUMIERA_HPP
#define GTK_LUMIERA_HPP
#include <gtkmm.h>
#include <nobug.h>
#include <vector>
extern "C" {
#include <gavl/gavltime.h>
}
NOBUG_DECLARE_FLAG(gui);
#ifdef ENABLE_NLS
# include <libintl.h>
# define _(String) gettext (String)
# define gettext_noop(String) String
# define N_(String) gettext_noop (String)
#else
# define _(String) (String)
# define N_(String) String
# define textdomain(Domain)
# define bindtextdomain(Package, Directory)
#endif
namespace lumiera {
/**
* The namespace of all GUI code.
*/
namespace gui {
/* ===== Global Constants ===== */
/**
* The name of the application
*/
static const gchar* AppTitle = "Lumiera";
/**
* The version number of the application
*/
static const gchar* AppVersion = N_("0.1-dev");
/**
* The copyright of the application
*/
static const gchar* AppCopyright = N_("© 2008 The Lumiera Team");
/**
* The website of the application
*/
static const gchar* AppWebsite = "www.lumiera.org";
/**
* An alphabetical list of the application's authors
*/
static const gchar* AppAuthors[] = {
"Joel Holdsworth",
"Christian Thaeter",
"Hermann Vosseler",
"<Other Authors Here>"};
/* ===== The Application Class ===== */
/**
* The main application class.
*/
class GtkLumiera
{
public:
int main(int argc, char *argv[]);
static Glib::ustring get_home_data_path();
};
/**
* Returns a reference to the global application object
*/
GtkLumiera& application();
/* ===== Namespace Definitions ===== */
/**
* The namespace of all dialog box classes.
*/
namespace dialogs {}
/**
* The namespace of all video output implementations.
*/
namespace output {}
/**
* The namespace of all docking panel classes.
*/
namespace panels {}
/**
* The namespace of all Lumiera custom widgets.
*/
namespace widgets {}
/**
* The namespace of the workspace window, and it's helper classes.
*/
namespace workspace {}
} // namespace gui
} // namespace lumiera
#endif // GTK_LUMIERA_HPP

View file

@ -124,6 +124,8 @@ class "GtkProgressBar" style:highest "lumiera_progressbars"
style "timeline_body"
{
gtkmm__CustomObject_TimelineBody::background = "#7E838B"
gtkmm__CustomObject_TimelineBody::selection = "#2D2D90"
gtkmm__CustomObject_TimelineBody::selection_alpha = 0.5
}
style "timeline_ruler" = "default_base"
@ -137,6 +139,7 @@ style "timeline_ruler" = "default_base"
gtkmm__CustomObject_TimelineRuler::annotation_vert_margin = 0
gtkmm__CustomObject_TimelineRuler::min_division_width = 100
gtkmm__CustomObject_TimelineRuler::mouse_chevron_size = 5
gtkmm__CustomObject_TimelineRuler::selection_chevron_size = 5
}
style "timeline_header_base" = "default_base"

38
src/gui/model/project.cpp Normal file
View file

@ -0,0 +1,38 @@
/*
panel.cpp - Implementation of the Project class
Copyright (C) Lumiera.org
2008, Joel Holdsworth <joel@airwebreathe.org.uk>
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 2 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, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
* *****************************************************/
#include "project.hpp"
namespace lumiera {
namespace gui {
namespace model {
Project::Project()
{
}
} // namespace model
} // namespace gui
} // namespace lumiera

44
src/gui/model/project.hpp Normal file
View file

@ -0,0 +1,44 @@
/*
project.hpp - Definition of the Project class
Copyright (C) Lumiera.org
2008, Joel Holdsworth <joel@airwebreathe.org.uk>
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 2 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, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/** @file project.hpp
** This file contains the definition of Project, a class which
** store project data, and wraps proc layer data
*/
#ifndef PROJECT_HPP
#define PROJECT_HPP
namespace lumiera {
namespace gui {
namespace model {
class Project
{
public:
Project();
};
} // namespace model
} // namespace gui
} // namespace lumiera
#endif // PROJECT_HPP

View file

@ -0,0 +1,86 @@
/*
displayer.cpp - Implements the base class for displaying video
Copyright (C) Lumiera.org
2000, Arne Schirmacher <arne@schirmacher.de>
2001-2007, Dan Dennedy <dan@dennedy.org>
2008, Joel Holdsworth <joel@airwebreathe.org.uk>
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 2 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, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
* *****************************************************/
#include "../gtk-lumiera.hpp"
#include "displayer.hpp"
#include "xvdisplayer.hpp"
#include "gdkdisplayer.hpp"
namespace lumiera {
namespace gui {
namespace output {
bool
Displayer::usable()
{
return false;
}
DisplayerInput
Displayer::format()
{
return DISPLAY_NONE;
}
int
Displayer::preferredWidth()
{
return imageWidth;
}
int
Displayer::preferredHeight()
{
return imageHeight;
}
void
Displayer::calculateVideoLayout(
int widget_width, int widget_height,
int image_width, int image_height,
int &video_x, int &video_y, int &video_width, int &video_height )
{
REQUIRE(widget_width >= 0);
REQUIRE(widget_height >= 0);
REQUIRE(image_width >= 0);
REQUIRE(image_height >= 0);
double ratio_width = ( double ) widget_width / ( double ) image_width;
double ratio_height = ( double ) widget_height / ( double ) image_height;
double ratio_constant = ratio_height < ratio_width ?
ratio_height : ratio_width;
video_width = ( int ) ( image_width * ratio_constant + 0.5 );
video_height = ( int ) ( image_height * ratio_constant + 0.5 );
video_x = ( widget_width - video_width ) / 2;
video_y = ( widget_height - video_height ) / 2;
ENSURE(video_x >= 0 && video_x < widget_width)
ENSURE(video_y >= 0 && video_y < widget_height)
ENSURE(video_width <= widget_width)
ENSURE(video_width <= widget_width)
}
} // namespace output
} // namespace gui
} // namespace lumiera

View file

@ -0,0 +1,135 @@
/*
displayer.hpp - Defines the base class for displaying video
Copyright (C) Lumiera.org
2000, Arne Schirmacher <arne@schirmacher.de>
2001-2007, Dan Dennedy <dan@dennedy.org>
2008, Joel Holdsworth <joel@airwebreathe.org.uk>
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 2 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, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/** @file displayer.hpp
** This file contains the defintion of Displayer; the base class
** of all video display implementations
** @see displayer.cpp
*/
#ifndef DISPLAYER_HPP
#define DISPLAYER_HPP
namespace lumiera {
namespace gui {
namespace output {
#define MAX_WIDTH 720
#define MAX_HEIGHT 576
/** Supported Displayer formats
*/
typedef enum {
DISPLAY_NONE,
DISPLAY_YUV,
DISPLAY_RGB,
DISPLAY_BGR,
DISPLAY_BGR0,
DISPLAY_RGB16
}
DisplayerInput;
/**
* A Displayer is a class which is responsible for rendering an image
* in some way (ie: Xvideo, GDK, OpenGL etc).
*
* @remarks All Displayer classes must extend the Displayer class and
* minimally rewrite:
*
* + usable() - to indicate if the object can be used,
* + format() - to indicate what type of input the put method expects
* + put( void * ) - deal with an image of the expected type and size
*
* By default, all images will be delivered to the put method in a
* resolution of IMG_WIDTH * IMG_HEIGHT. If another size is required,
* then the rewrite the methods:
*
* + preferredWidth
* + preferredHeight
*
* If the widget being written to doesn't need a fixed size, then
* rewrite the two other put methods as required.
*/
class Displayer
{
public:
/**
* Indicates if an object can be used to render images on the
* running system.
*/
virtual bool usable();
/**
* Indicates the format required by the abstract put method.
*/
virtual DisplayerInput format();
/**
* Expected width of input to put.
*/
virtual int preferredWidth();
/**
* Expected height of input to put.
*/
virtual int preferredHeight();
/**
* Put an image of a given width and height with the expected input
* format (as indicated by the format method).
*/
virtual void put( void * ) = 0;
protected:
/**
* Calculates the coordinates for placing a video image inside a
* widget
*
* @param[in] widget_width The width of the display widget.
* @param[in] widget_height The height of the display widget.
* @param[in] image_width The width of the video image.
* @param[in] image_height The height of the video image.
* @param[out] video_x The x-coordinate of the top left
* corner of the scaled video image.
* @param[out] video_y The y-coordinate of the top left
* corner of the scaled video image.
* @param[out] video_width The width of the scale video image.
* @param[out] video_height The height of the scale video image.
*/
static void calculateVideoLayout(
int widget_width, int widget_height,
int image_width, int image_height,
int &video_x, int &video_y, int &video_width, int &video_height );
protected:
int imageWidth;
int imageHeight;
};
} // namespace output
} // namespace gui
} // namespace lumiera
#endif // DISPLAYER_HPP

View file

@ -0,0 +1,86 @@
/*
gdkdisplayer.cpp - Implements the class for displaying video via GDK
Copyright (C) Lumiera.org
2000, Arne Schirmacher <arne@schirmacher.de>
2001-2007, Dan Dennedy <dan@dennedy.org>
2008, Joel Holdsworth <joel@airwebreathe.org.uk>
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 2 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, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
* *****************************************************/
#include "../gtk-lumiera.hpp"
#include <gdk/gdkx.h>
#include <iostream>
using std::cerr;
using std::endl;
#include "gdkdisplayer.hpp"
namespace lumiera {
namespace gui {
namespace output {
GdkDisplayer::GdkDisplayer( Gtk::Widget *drawing_area, int width, int height ) :
drawingArea( drawing_area )
{
REQUIRE(drawing_area != NULL);
REQUIRE(width > 0);
REQUIRE(height > 0);
imageWidth = width, imageHeight = height;
}
bool
GdkDisplayer::usable()
{
return true;
}
void
GdkDisplayer::put( void *image )
{
int video_x = 0, video_y = 0, video_width = 0, video_height = 0;
calculateVideoLayout(
drawingArea->get_width(),
drawingArea->get_height(),
preferredWidth(), preferredHeight(),
video_x, video_y, video_width, video_height );
GdkWindow *window = drawingArea->get_window()->gobj();
ASSERT(window != NULL);
GdkGC *gc = gdk_gc_new( window );
ASSERT(gc != NULL);
GdkPixbuf *pixbuf = gdk_pixbuf_new_from_data( (const guchar*)image, GDK_COLORSPACE_RGB, FALSE, 8,
preferredWidth(), preferredHeight(), preferredWidth() * 3, NULL, NULL );
ASSERT(pixbuf != NULL);
GdkPixbuf *scaled_image = gdk_pixbuf_scale_simple( pixbuf, video_width, video_height, GDK_INTERP_NEAREST );
ASSERT(scaled_image != NULL);
gdk_draw_pixbuf( window, gc, scaled_image, 0, 0, video_x, video_y, -1, -1, GDK_RGB_DITHER_NORMAL, 0, 0 );
g_object_unref( scaled_image );
g_object_unref( pixbuf );
g_object_unref( gc );
}
} // namespace output
} // namespace gui
} // namespace lumiera

View file

@ -0,0 +1,62 @@
/*
gdkdisplayer.hpp - Defines the class for displaying video via GDK
Copyright (C) Lumiera.org
2000, Arne Schirmacher <arne@schirmacher.de>
2001-2007, Dan Dennedy <dan@dennedy.org>
2008, Joel Holdsworth <joel@airwebreathe.org.uk>
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 2 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, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/** @file gdkdisplayer.hpp
** This file contains the definition of XvDisplayer, the XVideo
** video output implementation
** @see gdkdisplayer.cpp
** @see displayer.hpp
*/
#include "displayer.hpp"
#ifndef GDKDISPLAYER_HPP
#define GDKDISPLAYER_HPP
namespace Gtk {
class Widget;
}
namespace lumiera {
namespace gui {
namespace output {
class GdkDisplayer : public Displayer
{
public:
GdkDisplayer( Gtk::Widget *drawing_area, int width, int height );
void put( void *image );
protected:
bool usable();
private:
Gtk::Widget *drawingArea;
};
} // namespace output
} // namespace gui
} // namespace lumiera
#endif // GDKDISPLAYER_HPP

View file

@ -0,0 +1,226 @@
/*
xvdisplayer.cpp - Implements the base class for XVideo display
Copyright (C) Lumiera.org
2000, Arne Schirmacher <arne@schirmacher.de>
2001-2007, Dan Dennedy <dan@dennedy.org>
2008, Joel Holdsworth <joel@airwebreathe.org.uk>
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 2 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, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
* *****************************************************/
#include "../gtk-lumiera.hpp"
#include <gdk/gdkx.h>
#include "xvdisplayer.hpp"
namespace lumiera {
namespace gui {
namespace output {
XvDisplayer::XvDisplayer( Gtk::Widget *drawing_area, int width, int height ) :
xvImage( NULL ),
drawingArea( drawing_area ),
gotPort( false )
{
INFO(gui, "Trying XVideo at %d x %d", width, height);
imageWidth = width, imageHeight = height;
shmInfo.shmaddr = NULL;
Glib::RefPtr<Gdk::Window> area_window = drawing_area->get_window();
window = gdk_x11_drawable_get_xid( area_window->gobj() );
display = gdk_x11_drawable_get_xdisplay( area_window->gobj() );
unsigned int count;
XvAdaptorInfo *adaptorInfo;
if ( XvQueryAdaptors( display, window, &count, &adaptorInfo ) == Success )
{
INFO(gui, "XvQueryAdaptors count: %d", count);
for ( unsigned int n = 0; gotPort == false && n < count; ++n )
{
// Diagnostics
INFO(gui, "%s, %d, %d, %d", adaptorInfo[ n ].name,
adaptorInfo[ n ].base_id, adaptorInfo[ n ].num_ports - 1);
for ( port = adaptorInfo[ n ].base_id;
port < adaptorInfo[ n ].base_id + adaptorInfo[ n ].num_ports;
port ++ )
{
if ( XvGrabPort( display, port, CurrentTime ) == Success )
{
int formats;
XvImageFormatValues *list;
list = XvListImageFormats( display, port, &formats );
INFO(gui, "formats supported: %d", formats);
for ( int i = 0; i < formats; i ++ )
{
INFO(gui, "0x%x (%c%c%c%c) %s",
list[ i ].id,
( list[ i ].id ) & 0xff,
( list[ i ].id >> 8 ) & 0xff,
( list[ i ].id >> 16 ) & 0xff,
( list[ i ].id >> 24 ) & 0xff,
( list[ i ].format == XvPacked ) ? "packed" : "planar" );
if ( list[ i ].id == 0x32595559 && !gotPort )
gotPort = true;
}
if ( !gotPort )
{
XvUngrabPort( display, port, CurrentTime );
}
else
{
grabbedPort = port;
break;
}
}
}
}
if ( gotPort )
{
int num;
unsigned int unum;
XvEncodingInfo *enc;
XvQueryEncodings( display, grabbedPort, &unum, &enc );
for ( unsigned int index = 0; index < unum; index ++ )
{
INFO(gui, "%d: %s, %ldx%ld rate = %d/%d", index, enc->name,
enc->width, enc->height, enc->rate.numerator,
enc->rate.denominator );
}
XvAttribute *xvattr = XvQueryPortAttributes( display, port, &num );
for ( int k = 0; k < num; k++ )
{
if ( xvattr[k].flags & XvSettable )
{
if ( strcmp( xvattr[k].name, "XV_AUTOPAINT_COLORKEY") == 0 )
{
Atom val_atom = XInternAtom( display, xvattr[k].name, False );
if ( XvSetPortAttribute( display, port, val_atom, 1 ) != Success )
ERROR(gui, "Couldn't set Xv attribute %s\n", xvattr[k].name);
}
else if ( strcmp( xvattr[k].name, "XV_COLORKEY") == 0 )
{
Atom val_atom = XInternAtom( display, xvattr[k].name, False );
if ( XvSetPortAttribute( display, port, val_atom, 0x010102 ) != Success )
ERROR(gui, "Couldn't set Xv attribute %s\n", xvattr[k].name);
}
}
}
}
if ( gotPort )
{
gc = XCreateGC( display, window, 0, &values );
xvImage = ( XvImage * ) XvShmCreateImage( display, port, 0x32595559, 0, width, height, &shmInfo );
shmInfo.shmid = shmget( IPC_PRIVATE, xvImage->data_size, IPC_CREAT | 0777 );
if (shmInfo.shmid < 0) {
perror("shmget");
gotPort = false;
}
else
{
shmInfo.shmaddr = ( char * ) shmat( shmInfo.shmid, 0, 0 );
xvImage->data = shmInfo.shmaddr;
shmInfo.readOnly = 0;
if ( !XShmAttach( gdk_display, &shmInfo ) )
{
gotPort = false;
}
XSync( display, false );
shmctl( shmInfo.shmid, IPC_RMID, 0 );
#if 0
xvImage = ( XvImage * ) XvCreateImage( display, port, 0x32595559, pix, width , height );
#endif
}
}
}
else
{
gotPort = false;
}
}
XvDisplayer::~XvDisplayer()
{
ERROR(gui, "Destroying XV Displayer");
if ( gotPort )
{
XvUngrabPort( display, grabbedPort, CurrentTime );
}
//if ( xvImage != NULL )
// XvStopVideo( display, port, window );
if ( shmInfo.shmaddr != NULL )
{
XShmDetach( display, &shmInfo );
shmctl( shmInfo.shmid, IPC_RMID, 0 );
shmdt( shmInfo.shmaddr );
}
if ( xvImage != NULL )
XFree( xvImage );
}
bool
XvDisplayer::usable()
{
return gotPort;
}
void
XvDisplayer::put( void *image )
{
REQUIRE(image != NULL);
ASSERT(drawingArea != NULL);
if(xvImage != NULL)
{
int video_x = 0, video_y = 0, video_width = 0, video_height = 0;
calculateVideoLayout(
drawingArea->get_width(),
drawingArea->get_height(),
preferredWidth(), preferredHeight(),
video_x, video_y, video_width, video_height );
memcpy( xvImage->data, image, xvImage->data_size );
XvShmPutImage( display, port, window, gc, xvImage,
0, 0, preferredWidth(), preferredHeight(),
video_x, video_y, video_width, video_height, false );
}
}
} // namespace output
} // namespace gui
} // namespace lumiera

View file

@ -0,0 +1,79 @@
/*
xvdisplayer.hpp - Defines the base class for XVideo display
Copyright (C) Lumiera.org
2000, Arne Schirmacher <arne@schirmacher.de>
2001-2007, Dan Dennedy <dan@dennedy.org>
2008, Joel Holdsworth <joel@airwebreathe.org.uk>
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 2 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, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/** @file xvdisplayer.hpp
** This file contains the definition of XvDisplayer, the XVideo
** video output implementation
** @see xvdisplayer.cpp
** @see displayer.hpp
*/
#include <X11/Xlib.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <X11/extensions/XShm.h>
#include <X11/extensions/Xvlib.h>
#include "displayer.hpp"
#ifndef XVDISPLAYER_HPP
#define XVDISPLAYER_HPP
namespace Gtk {
class Widget;
}
namespace lumiera {
namespace gui {
namespace output {
class XvDisplayer : public Displayer
{
public:
XvDisplayer( Gtk::Widget *drawing_area, int width, int height );
~XvDisplayer();
void put( void *image );
protected:
bool usable();
private:
bool gotPort;
int grabbedPort;
Gtk::Widget *drawingArea;
Display *display;
Window window;
GC gc;
XGCValues values;
XvImage *xvImage;
unsigned int port;
XShmSegmentInfo shmInfo;
char pix[ MAX_WIDTH * MAX_HEIGHT * 4 ];
};
} // namespace output
} // namespace gui
} // namespace lumiera
#endif // XVDISPLAYER_HPP

View file

@ -0,0 +1,39 @@
/*
assets-panel.cpp - Implementation of the assets panel
Copyright (C) Lumiera.org
2008, Joel Holdsworth <joel@airwebreathe.org.uk>
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 2 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, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
* *****************************************************/
#include "../gtk-lumiera.hpp"
#include "assets-panel.hpp"
namespace lumiera {
namespace gui {
namespace panels {
AssetsPanel::AssetsPanel() :
Panel("assets", _("Assets"), "panel_assets"),
placeholder("Placeholder label. Is this supposed to be titled assets\nas in the proc layer? or resources\nas in cinelerra?")
{
pack_start(placeholder);
}
} // namespace panels
} // namespace gui
} // namespace lumiera

View file

@ -0,0 +1,48 @@
/*
assets-panel.hpp - Definition of the assets panel
Copyright (C) Lumiera.org
2008, Joel Holdsworth <joel@airwebreathe.org.uk>
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 2 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, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/** @file assets-panel.hpp
** This file contains the definition of the assets panel
*/
#ifndef ASSETS_PANEL_HPP
#define ASSETS_PANEL_HPP
#include "panel.hpp"
namespace lumiera {
namespace gui {
namespace panels {
class AssetsPanel : public Panel
{
public:
AssetsPanel();
protected:
Gtk::Label placeholder;
};
} // namespace panels
} // namespace gui
} // namespace lumiera
#endif // ASSETS_PANEL_HPP

93
src/gui/panels/panel.cpp Normal file
View file

@ -0,0 +1,93 @@
/*
panel.cpp - Implementation of Panel, the base class for docking panels
Copyright (C) Lumiera.org
2008, Joel Holdsworth <joel@airwebreathe.org.uk>
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 2 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, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
* *****************************************************/
#include "panel.hpp"
#include "../gtk-lumiera.hpp"
namespace lumiera {
namespace gui {
namespace panels {
Panel::Panel(const gchar *name, const gchar *long_name,
GdlDockItemBehavior behavior)
{
dock_item = (GdlDockItem*)gdl_dock_item_new (
name, long_name, behavior);
internal_setup();
ENSURE(dock_item != NULL);
}
Panel::Panel(const gchar *name, const gchar *long_name, const gchar *stock_id,
GdlDockItemBehavior behavior)
{
dock_item = (GdlDockItem*)gdl_dock_item_new_with_stock (
name, long_name, stock_id, behavior);
g_object_ref(dock_item);
internal_setup();
ENSURE(dock_item != NULL);
}
Panel::~Panel()
{
REQUIRE(dock_item != NULL);
g_object_unref(dock_item);
dock_item = NULL;
}
GdlDockItem*
Panel::get_dock_item() const
{
return dock_item;
}
void
Panel::show(bool show)
{
REQUIRE(dock_item != NULL);
if(show) gdl_dock_item_show_item (dock_item);
else gdl_dock_item_hide_item (dock_item);
}
bool
Panel::is_shown() const
{
REQUIRE(dock_item != NULL);
return GTK_WIDGET_VISIBLE((GtkWidget*)dock_item);
}
void
Panel::internal_setup()
{
REQUIRE(dock_item != NULL);
REQUIRE(gobj() != NULL);
gdl_dock_item_hide_grip(dock_item);
gtk_container_add ((GtkContainer*)dock_item, (GtkWidget*)gobj());
gtk_widget_show ((GtkWidget*)dock_item);
}
} // namespace panels
} // namespace gui
} // namespace lumiera

97
src/gui/panels/panel.hpp Normal file
View file

@ -0,0 +1,97 @@
/*
panel.hpp - Definition of Panel, the base class for docking panels
Copyright (C) Lumiera.org
2008, Joel Holdsworth <joel@airwebreathe.org.uk>
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 2 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, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/** @file panel.hpp
** This file contains the definition of Panel; the base class
** for all docking panels
*/
#ifndef PANEL_HPP
#define PANEL_HPP
#include "../gtk-lumiera.hpp"
#include <libgdl-1.0/gdl/gdl-dock-item.h>
namespace lumiera {
namespace gui {
namespace panels {
/**
* The main lumiera panel window
*/
class Panel : public Gtk::VBox
{
protected:
/**
* Constructs a panel object
* @param name The internal name of this panel
* @param long_name The name to display on the caption
* @param behavior The GDL behaviour of this item
*/
Panel(const gchar *name, const gchar *long_name,
GdlDockItemBehavior behavior = GDL_DOCK_ITEM_BEH_NORMAL);
/**
* Constructs a panel object with a stock item for a caption
* @param name The internal name of this panel
* @param long_name The name to display on the caption
* @param stock_id The id of the stock item to display on the caption
* @param behavior The GDL behaviour of this item
*/
Panel(const gchar *name, const gchar *long_name, const gchar *stock_id,
GdlDockItemBehavior behavior = GDL_DOCK_ITEM_BEH_NORMAL);
~Panel();
public:
/**
* Returns a pointer to the underlying GdlDockItem structure
*/
GdlDockItem* get_dock_item() const;
/**
* Shows or hides the panel.
* @param show A value of true will show the panel,
* false will hide it. */
void show(bool show = true);
/**
* Returns true if the panel is currently visible.
*/
bool is_shown() const;
private:
/**
* @internal Used by both constructors
* The internal constructor for this class, whose purpose
* is to set up the internal container widgets.
*/
void internal_setup();
protected:
GdlDockItem* dock_item;
};
} // namespace panels
} // namespace gui
} // namespace lumiera
#endif // PANEL_HPP

View file

@ -0,0 +1,118 @@
/*
timeline-panel.cpp - Implementation of the timeline panel
Copyright (C) Lumiera.org
2008, Joel Holdsworth <joel@airwebreathe.org.uk>
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 2 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, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
* *****************************************************/
#include "../gtk-lumiera.hpp"
#include "timeline-panel.hpp"
using namespace Gtk;
using namespace sigc;
using namespace lumiera::gui::widgets;
namespace lumiera {
namespace gui {
namespace panels {
const int TimelinePanel::ZoomToolSteps = 2; // 2 seems comfortable
TimelinePanel::TimelinePanel() :
Panel("timeline", _("Timeline"), "panel_timeline"),
arrowTool(Gtk::StockID("tool_arrow")),
iBeamTool(Gtk::StockID("tool_i_beam")),
zoomIn(Stock::ZOOM_IN),
zoomOut(Stock::ZOOM_OUT),
updatingToolbar(false)
{
// Setup the toolbar
toolbar.append(arrowTool, mem_fun(this,
&TimelinePanel::on_arrow_tool));
toolbar.append(iBeamTool, mem_fun(this,
&TimelinePanel::on_ibeam_tool));
toolbar.append(seperator1);
toolbar.append(zoomIn, mem_fun(this, &TimelinePanel::on_zoom_in));
toolbar.append(zoomOut, mem_fun(this, &TimelinePanel::on_zoom_out));
toolbar.set_icon_size(IconSize(ICON_SIZE_LARGE_TOOLBAR));
toolbar.set_toolbar_style(TOOLBAR_ICONS);
// Add the toolbar
pack_start(toolbar, PACK_SHRINK);
pack_start(timelineWidget, PACK_EXPAND_WIDGET);
update_tool_buttons();
update_zoom_buttons();
}
void
TimelinePanel::on_arrow_tool()
{
if(updatingToolbar) return;
timelineWidget.set_tool(timeline::Arrow);
update_tool_buttons();
}
void
TimelinePanel::on_ibeam_tool()
{
if(updatingToolbar) return;
timelineWidget.set_tool(timeline::IBeam);
update_tool_buttons();
}
void
TimelinePanel::on_zoom_in()
{
timelineWidget.zoom_view(ZoomToolSteps);
update_zoom_buttons();
}
void
TimelinePanel::on_zoom_out()
{
timelineWidget.zoom_view(-ZoomToolSteps);
update_zoom_buttons();
}
void
TimelinePanel::update_tool_buttons()
{
if(!updatingToolbar)
{
updatingToolbar = true;
const timeline::ToolType tool = timelineWidget.get_tool();
arrowTool.set_active(tool == timeline::Arrow);
iBeamTool.set_active(tool == timeline::IBeam);
updatingToolbar = false;
}
}
void
TimelinePanel::update_zoom_buttons()
{
zoomIn.set_sensitive(timelineWidget.get_time_scale() != 1);
zoomOut.set_sensitive(timelineWidget.get_time_scale() !=
TimelineWidget::MaxScale);
}
} // namespace panels
} // namespace gui
} // namespace lumiera

View file

@ -0,0 +1,90 @@
/*
timeline-panel.hpp - Definition of the timeline panel
Copyright (C) Lumiera.org
2008, Joel Holdsworth <joel@airwebreathe.org.uk>
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 2 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, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/** @file timeline-panel.hpp
** This file contains the definition of the timeline panel
*/
#ifndef TIMELINE_PANEL_HPP
#define TIMELINE_PANEL_HPP
#include "panel.hpp"
#include "../widgets/timeline-widget.hpp"
using namespace lumiera::gui::widgets;
namespace lumiera {
namespace gui {
namespace panels {
/**
* The definition of the timeline panel class, which holds timeline
* widgets.
*/
class TimelinePanel : public Panel
{
public:
/**
* Constructor
*/
TimelinePanel();
private:
//----- Event Handlers -----//
void on_arrow_tool();
void on_ibeam_tool();
void on_zoom_in();
void on_zoom_out();
private:
void update_tool_buttons();
void update_zoom_buttons();
private:
//----- Data -----//
// Widgets
Gtk::Toolbar toolbar;
TimelineWidget timelineWidget;
// Toolbar Widgets
Gtk::ToggleToolButton arrowTool;
Gtk::ToggleToolButton iBeamTool;
Gtk::SeparatorToolItem seperator1;
Gtk::ToolButton zoomIn;
Gtk::ToolButton zoomOut;
// Internals
bool updatingToolbar;
//----- Constants -----//
static const int ZoomToolSteps;
};
} // namespace panels
} // namespace gui
} // namespace lumiera
#endif // TIMELINE_PANEL_H

View file

@ -0,0 +1,59 @@
/*
viewer-panel.cpp - Implementation of the viewer panel
Copyright (C) Lumiera.org
2008, Joel Holdsworth <joel@airwebreathe.org.uk>
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 2 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, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
* *****************************************************/
#include "../gtk-lumiera.hpp"
#include "viewer-panel.hpp"
using namespace lumiera::gui::widgets;
using namespace Gtk;
namespace lumiera {
namespace gui {
namespace panels {
ViewerPanel::ViewerPanel() :
Panel("viewer", _("Viewer"), "panel_viewer"),
previousButton(Stock::MEDIA_PREVIOUS),
rewindButton(Stock::MEDIA_REWIND),
playPauseButton(Stock::MEDIA_PLAY),
forwardButton(Stock::MEDIA_FORWARD),
nextButton(Stock::MEDIA_NEXT)
{
//----- Set up the Tool Bar -----//
// Add the commands
toolBar.append(previousButton);
toolBar.append(rewindButton);
toolBar.append(playPauseButton);
toolBar.append(forwardButton);
toolBar.append(nextButton);
// Configure the toolbar
toolBar.set_toolbar_style(TOOLBAR_ICONS);
//----- Pack in the Widgets -----//
pack_start(display, PACK_EXPAND_WIDGET);
pack_start(toolBar, PACK_SHRINK);
}
} // namespace panels
} // namespace gui
} // namespace lumiera

View file

@ -0,0 +1,62 @@
/*
viewer-panel.hpp - Definition of the viewer panel
Copyright (C) Lumiera.org
2008, Joel Holdsworth <joel@airwebreathe.org.uk>
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 2 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, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/** @file viewer-panel.hpp
** This file contains the definition of the viewer panel
*/
#ifndef VIEWER_PANEL_HPP
#define VIEWER_PANEL_HPP
#include <gtkmm.h>
#include "panel.hpp"
#include "../widgets/video-display-widget.hpp"
using namespace lumiera::gui::widgets;
using namespace Gtk;
namespace lumiera {
namespace gui {
namespace panels {
class ViewerPanel : public Panel
{
public:
ViewerPanel();
protected:
ToolButton previousButton;
ToolButton rewindButton;
ToolButton playPauseButton;
ToolButton forwardButton;
ToolButton nextButton;
VideoDisplayWidget display;
Toolbar toolBar;
};
} // namespace panels
} // namespace gui
} // namespace lumiera
#endif // VIEWER_PANEL_HPP

View file

@ -0,0 +1,317 @@
/*
timeline-widget.cpp - Implementation of the timeline widget
Copyright (C) Lumiera.org
2008, Joel Holdsworth <joel@airwebreathe.org.uk>
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 2 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, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
* *****************************************************/
#include "timeline-widget.hpp"
#include <boost/foreach.hpp>
using namespace Gtk;
using namespace std;
using namespace lumiera::gui::widgets::timeline;
namespace lumiera {
namespace gui {
namespace widgets {
const int TimelineWidget::TrackPadding = 1;
const int TimelineWidget::HeaderWidth = 100;
const double TimelineWidget::ZoomIncrement = 1.25;
const int64_t TimelineWidget::MaxScale = 30000000;
TimelineWidget::TimelineWidget() :
Table(2, 2),
timeOffset(0),
timeScale(1),
totalHeight(0),
horizontalAdjustment(0, 0, 0),
verticalAdjustment(0, 0, 0),
selectionStart(0),
selectionEnd(0),
horizontalScroll(horizontalAdjustment),
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) );
verticalAdjustment.signal_value_changed().connect( sigc::mem_fun(
this, &TimelineWidget::on_scroll) );
body->signal_motion_notify_event().connect( sigc::mem_fun(
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(*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);
tracks.push_back(&video1);
tracks.push_back(&video2);
update_tracks();
set_tool(timeline::Arrow);
}
TimelineWidget::~TimelineWidget()
{
REQUIRE(body != NULL);
if(body != NULL)
body->unreference();
REQUIRE(headerContainer != NULL);
if(headerContainer != NULL)
headerContainer->unreference();
REQUIRE(ruler != NULL);
if(ruler != NULL)
ruler->unreference();
}
gavl_time_t
TimelineWidget::get_time_offset() const
{
return timeOffset;
}
void
TimelineWidget::set_time_offset(gavl_time_t time_offset)
{
REQUIRE(ruler != NULL);
timeOffset = time_offset;
horizontalAdjustment.set_value(time_offset);
ruler->update_view();
}
int64_t
TimelineWidget::get_time_scale() const
{
return timeScale;
}
void
TimelineWidget::set_time_scale(int64_t time_scale)
{
REQUIRE(ruler != NULL);
timeScale = time_scale;
const int view_width = body->get_allocation().get_width();
horizontalAdjustment.set_page_size(timeScale * view_width);
ruler->update_view();
}
void
TimelineWidget::zoom_view(int zoom_size)
{
const Allocation allocation = body->get_allocation();
zoom_view(allocation.get_width() / 2, zoom_size);
}
void
TimelineWidget::zoom_view(int point, int zoom_size)
{
int64_t new_time_scale = (double)timeScale * pow(1.25, -zoom_size);
// Limit zooming in too close
if(new_time_scale < 1) new_time_scale = 1;
// Nudge zoom problems caused by integer rounding
if(new_time_scale == timeScale && zoom_size < 0)
new_time_scale++;
// Limit zooming out too far
if(new_time_scale > MaxScale)
new_time_scale = MaxScale;
// The view must be shifted so that the zoom is centred on the cursor
set_time_offset(get_time_offset() +
(timeScale - new_time_scale) * point);
// Apply the new scale
set_time_scale(new_time_scale);
}
void
TimelineWidget::shift_view(int shift_size)
{
const int view_width = body->get_allocation().get_width();
set_time_offset(get_time_offset() +
shift_size * timeScale * view_width / 256);
}
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(body != NULL);
return body->get_tool();
}
void
TimelineWidget::set_tool(ToolType tool_type)
{
REQUIRE(body != NULL);
body->set_tool(tool_type);
}
void
TimelineWidget::on_scroll()
{
timeOffset = horizontalAdjustment.get_value();
ruler->update_view();
}
void
TimelineWidget::on_size_allocate(Allocation& allocation)
{
Widget::on_size_allocate(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()
{
ASSERT(headerContainer != NULL);
headerContainer->update_headers();
// Recalculate the total height of the timeline scrolled area
totalHeight = 0;
BOOST_FOREACH( Track* track, tracks )
{
ASSERT(track != NULL);
totalHeight += track->get_height() + TrackPadding;
}
}
void
TimelineWidget::update_scroll()
{
ASSERT(body != NULL);
const Allocation body_allocation = body->get_allocation();
//----- Horizontal Scroll ------//
// TEST CODE
horizontalAdjustment.set_upper(1000 * GAVL_TIME_SCALE / 200);
horizontalAdjustment.set_lower(-1000 * GAVL_TIME_SCALE / 200);
// Set the page size
horizontalAdjustment.set_page_size(
timeScale * body_allocation.get_width());
//----- Vertical Scroll -----//
// Calculate the vertical length that can be scrolled:
// the total height of all the tracks minus one screenful
int y_scroll_length = totalHeight - body_allocation.get_height();
if(y_scroll_length < 0) y_scroll_length = 0;
// If by resizing we're now over-scrolled, scroll back to
// maximum distance
if((int)verticalAdjustment.get_value() > y_scroll_length)
verticalAdjustment.set_value(y_scroll_length);
verticalAdjustment.set_upper(y_scroll_length);
// Hide the scrollbar if no scrolling is possible
#if 0
// Having this code included seems to cause a layout loop as the
// window is shrunk
if(y_scroll_length <= 0 && verticalScroll.is_visible())
verticalScroll.hide();
else if(y_scroll_length > 0 && !verticalScroll.is_visible())
verticalScroll.show();
#endif
}
int
TimelineWidget::get_y_scroll_offset() const
{
return (int)verticalAdjustment.get_value();
}
bool
TimelineWidget::on_motion_in_body_notify_event(GdkEventMotion *event)
{
REQUIRE(event != NULL);
ruler->set_mouse_chevron_offset(event->x);
return true;
}
} // namespace widgets
} // namespace gui
} // namespace lumiera

View file

@ -0,0 +1,205 @@
/*
timeline-widget.hpp - Declaration of the timeline widget
Copyright (C) Lumiera.org
2008, Joel Holdsworth <joel@airwebreathe.org.uk>
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 2 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, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/** @file timeline-widget.hpp
** This file contains the definition of timeline widget
*/
#ifndef TIMELINE_WIDGET_HPP
#define TIMELINE_WIDGET_HPP
#include "../gtk-lumiera.hpp"
#include "timeline/header-container.hpp"
#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 {
namespace gui {
namespace widgets {
/**
* The namespace of all timeline widget helper classes.
*/
namespace timeline {}
/**
* The timeline widget class.
* @remarks This widget is a composite of several widgets contained
* within the timeline namespace.
*/
class TimelineWidget : public Gtk::Table
{
public:
TimelineWidget();
~TimelineWidget();
/* ===== Data Access ===== */
public:
/**
* Gets the time offset. This is the time value displaid at the
* left-hand edge of the timeline body area.
*/
gavl_time_t get_time_offset() const;
/**
* Sets the time offset. This is the time value displaid at the
* left-hand edge of the timeline body area.
*/
void set_time_offset(gavl_time_t time_offset);
/**
* Gets the time scale value.
* @return The scale factor, which is the number of microseconds per
* screen pixel.
*/
int64_t get_time_scale() const;
/**
* 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);
/**
* Zooms the view in or out as by a number of steps while keeping
* centre of the view still.
* @param zoom_size The number of steps to zoom by. The scale factor
* is 1.25^(-zoom_size).
**/
void zoom_view(int zoom_size);
/**
* Zooms the view in or out as by a number of steps while keeping a
* given point on the timeline still.
* @param zoom_size The number of steps to zoom by. The scale factor
* is 1.25^(-zoom_size).
**/
void zoom_view(int point, int zoom_size);
/**
* Scrolls the view horizontally as a proportion of the view area.
* @param shift_size The size of the shift in 1/256ths of the view
* width.
**/
void shift_view(int shift_size);
/**
* Gets the time at which the selection begins.
*/
gavl_time_t get_selection_start() const;
/**
* Gets the time at which the selection begins.
*/
gavl_time_t get_selection_end() const;
/**
* Sets the period of the selection.
*/
void set_selection(gavl_time_t start, gavl_time_t end);
/**
* Gets the type of the tool currently active.
*/
timeline::ToolType get_tool() const;
/**
* Sets the type of the tool currently active.
*/
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 ===== */
private:
void update_tracks();
void update_scroll();
int get_y_scroll_offset() const;
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;
timeline::Track video1;
timeline::Track video2;
std::vector<timeline::Track*> tracks;
timeline::HeaderContainer *headerContainer;
timeline::TimelineBody *body;
timeline::TimelineRuler *ruler;
Gtk::Adjustment horizontalAdjustment, verticalAdjustment;
Gtk::HScrollbar horizontalScroll;
Gtk::VScrollbar verticalScroll;
/* ===== Constants ===== */
public:
static const int64_t MaxScale;
protected:
static const int TrackPadding;
static const int HeaderWidth;
static const double ZoomIncrement;
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
} // namespace gui
} // namespace lumiera
#endif // TIMELINE_WIDGET_HPP

View file

@ -0,0 +1,199 @@
/*
header-container.cpp - Implementation of the header container widget
Copyright (C) Lumiera.org
2008, Joel Holdsworth <joel@airwebreathe.org.uk>
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 2 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, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
* *****************************************************/
#include <boost/foreach.hpp>
#include "header-container.hpp"
#include "track.hpp"
#include "../timeline-widget.hpp"
using namespace Gtk;
using namespace std;
namespace lumiera {
namespace gui {
namespace widgets {
namespace timeline {
HeaderContainer::HeaderContainer(lumiera::gui::widgets::TimelineWidget *timeline_widget) :
timelineWidget(timeline_widget)
{
REQUIRE(timeline_widget != NULL);
// 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,
// so that we get notified when the view shifts
timelineWidget->verticalAdjustment.signal_value_changed().connect(
sigc::mem_fun(this, &HeaderContainer::on_scroll) );
}
void
HeaderContainer::update_headers()
{
ASSERT(timelineWidget != NULL);
BOOST_FOREACH( Track* track, timelineWidget->tracks )
{
ASSERT(track != NULL);
Glib::RefPtr<Gtk::Frame> headerFrame(new Gtk::Frame());
headerFrame->add(track->get_header_widget());
headerFrame->set_shadow_type (Gtk::SHADOW_ETCHED_OUT);
headerFrame->set_name ("TimelineHeaderBaseUnselected");
headerFrame->set_parent(*this);
headerFrame->show();
const RootHeader header = { headerFrame, track };
rootHeaders.push_back(header);
}
layout_headers();
}
void
HeaderContainer::on_realize()
{
set_flags(Gtk::NO_WINDOW);
ensure_style();
// Call base class:
Gtk::Widget::on_realize();
// Create the GdkWindow:
GdkWindowAttr attributes;
memset(&attributes, 0, sizeof(attributes));
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(), &attributes,
GDK_WA_X | GDK_WA_Y);
unset_flags(Gtk::NO_WINDOW);
set_window(gdkWindow);
// Unset the background so as to make the colour match the parent window
unset_bg(STATE_NORMAL);
// Make the widget receive expose events
gdkWindow->set_user_data(gobj());
}
void
HeaderContainer::on_unrealize()
{
// Unreference any window we may have created
gdkWindow.clear();
// Call base class:
Gtk::Widget::on_unrealize();
}
void
HeaderContainer::on_size_request (Requisition* requisition)
{
// Initialize the output parameter:
*requisition = Gtk::Requisition();
requisition->width = TimelineWidget::HeaderWidth;
requisition->height = 0;
}
void
HeaderContainer::on_size_allocate (Allocation& allocation)
{
// Use the offered allocation for this container:
set_allocation(allocation);
// Resize the widget's window
if(gdkWindow)
gdkWindow->resize(allocation.get_width(), allocation.get_height());
// Relayout the child widgets of the headers
layout_headers();
}
void
HeaderContainer::forall_vfunc(gboolean /* include_internals */,
GtkCallback callback, gpointer callback_data)
{
BOOST_FOREACH( RootHeader &header, rootHeaders )
{
ASSERT(header.widget);
callback(header.widget->gobj(), callback_data);
}
}
void
HeaderContainer::on_scroll()
{
// If the scroll has changed, we will have to shift all the
// header widgets
layout_headers();
}
void
HeaderContainer::layout_headers()
{
ASSERT(timelineWidget != NULL);
int offset = 0;
const int y_scroll_offset = timelineWidget->get_y_scroll_offset();
const Allocation container_allocation = get_allocation();
BOOST_FOREACH( RootHeader &header, rootHeaders )
{
ASSERT(header.widget);
ASSERT(header.track != NULL);
const int height = header.track->get_height();
ASSERT(height >= 0);
Gtk::Allocation header_allocation;
header_allocation.set_x (0);
header_allocation.set_y (offset - y_scroll_offset);
header_allocation.set_width (container_allocation.get_width ());
header_allocation.set_height (height);
header.widget->size_allocate(header_allocation);
offset += height + TimelineWidget::TrackPadding;
}
}
} // namespace timeline
} // namespace widgets
} // namespace gui
} // namespace lumiera

View file

@ -0,0 +1,155 @@
/*
header-container.hpp - Declaration of the header container widget
Copyright (C) Lumiera.org
2008, Joel Holdsworth <joel@airwebreathe.org.uk>
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 2 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, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/** @file header-container.hpp
** This file contains the definition of the header container
** widget
*/
#ifndef HEADER_CONTAINER_HPP
#define HEADER_CONTAINER_HPP
#include "../../gtk-lumiera.hpp"
#include <vector>
namespace lumiera {
namespace gui {
namespace widgets {
class TimelineWidget;
namespace timeline {
class Track;
/**
* A helper class for the TimelineWidget. HeaderContainer is
* container widget for all the left-hand-side header widgets
* 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:
/**
* And event handler for the window realized signal.
*/
void on_realize();
/**
* And event handler for the window unrealized signal.
*/
void on_unrealize();
/**
* An event handler that is called to notify this widget to allocate
* a given area for itself.
* @param allocation The area to allocate for this widget.
*/
void on_size_allocate (Gtk::Allocation& allocation);
/**
* An event handler that is called to offer an allocation to this
* widget.
* @param requisition The area offered for this widget.
*/
void on_size_request (Gtk::Requisition* requisition);
/**
* Applies a given function to all the widgets in the container.
**/
void forall_vfunc(gboolean include_internals, GtkCallback callback,
gpointer callback_data);
/* ===== Events ===== */
private:
/**
* This event is called when the scroll bar moves.
*/
void on_scroll();
/* ===== Internals ===== */
private:
/**
* Moves all the header widgets to the correct position
* given scroll, stacking etc.
*/
void layout_headers();
private:
/**
* The owner TimelineWidget of which this class is a helper
*/
lumiera::gui::widgets::TimelineWidget *timelineWidget;
/**
* 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
} // namespace gui
} // namespace lumiera
#endif // HEADER_CONTAINER_HPP

View file

@ -0,0 +1,70 @@
/*
timeline-arrow-tool.cpp - Implementation of the ArrowTool class
Copyright (C) Lumiera.org
2008, Joel Holdsworth <joel@airwebreathe.org.uk>
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 2 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, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
* *****************************************************/
#include "timeline-arrow-tool.hpp"
namespace lumiera {
namespace gui {
namespace widgets {
namespace timeline {
ArrowTool::ArrowTool(TimelineBody *timeline_body) :
Tool(timeline_body)
{
}
ToolType
ArrowTool::get_type() const
{
return Arrow;
}
Gdk::Cursor
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
} // namespace lumiera

View file

@ -0,0 +1,83 @@
/*
timeline-arrow-tool.hpp - Declaration of the ArrowTool class
Copyright (C) Lumiera.org
2008, Joel Holdsworth <joel@airwebreathe.org.uk>
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 2 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, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/** @file timeline-arrow-tool.hpp
** This file contains the definition of the arrow tool class
*/
#ifndef TIMELINE_ARROW_TOOL_HPP
#define TIMELINE_ARROW_TOOL_HPP
#include <gtkmm.h>
#include "timeline-tool.hpp"
namespace lumiera {
namespace gui {
namespace widgets {
namespace timeline {
/**
* A helper class to implement the timeline i-beam tool
*/
class ArrowTool : public Tool
{
public:
/**
* Constructor
* @param timeline_body The owner timeline body object
*/
ArrowTool(TimelineBody *timeline_body);
/**
* Gets the type of tool represented by this class
*/
ToolType get_type() const;
protected:
/**
* Gets the cursor to display for this tool at this moment.
*/
Gdk::Cursor get_cursor() const;
protected:
/**
* The event handler for button press events.
*/
void on_button_press_event(GdkEventButton* event);
/**
* The event handler for button release events.
*/
void on_button_release_event(GdkEventButton* event);
/**
* The event handler for mouse move events.
*/
void on_motion_notify_event(GdkEventMotion *event);
};
} // namespace timeline
} // namespace widgets
} // namespace gui
} // namespace lumiera
#endif // TIMELINE_ARROW_TOOL_HPP

View file

@ -0,0 +1,387 @@
/*
timeline.cpp - Implementation of the timeline widget
Copyright (C) Lumiera.org
2008, Joel Holdsworth <joel@airwebreathe.org.uk>
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 2 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, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
* *****************************************************/
#include <cairomm-1.0/cairomm/cairomm.h>
#include <boost/foreach.hpp>
#include "timeline-body.hpp"
#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;
using namespace lumiera::gui::widgets;
using namespace lumiera::gui::widgets::timeline;
namespace lumiera {
namespace gui {
namespace widgets {
namespace timeline {
TimelineBody::TimelineBody(lumiera::gui::widgets::TimelineWidget
*timeline_widget) :
Glib::ObjectBase("TimelineBody"),
tool(NULL),
dragType(None),
mouseDownX(0),
mouseDownY(0),
beginShiftTimeOffset(0),
selectionAlpha(0.5),
timelineWidget(timeline_widget)
{
REQUIRE(timelineWidget != NULL);
// Connect up some events
timelineWidget->horizontalAdjustment.signal_value_changed().connect(
sigc::mem_fun(this, &TimelineBody::on_scroll) );
timelineWidget->verticalAdjustment.signal_value_changed().connect(
sigc::mem_fun(this, &TimelineBody::on_scroll) );
// Install style properties
register_styles();
}
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()
{
Widget::on_realize();
// 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
tool->apply_cursor();
}
void
TimelineBody::on_scroll()
{
queue_draw();
}
bool
TimelineBody::on_scroll_event (GdkEventScroll* event)
{
REQUIRE(event != NULL);
REQUIRE(timelineWidget != NULL);
if(event->state & GDK_CONTROL_MASK)
{
switch(event->direction)
{
case GDK_SCROLL_UP:
// User scrolled up. Zoom in
timelineWidget->zoom_view(event->x, 16);
break;
case GDK_SCROLL_DOWN:
// User scrolled down. Zoom out
timelineWidget->zoom_view(event->x, -16);
break;
}
}
else
{
switch(event->direction)
{
case GDK_SCROLL_UP:
// User scrolled up. Shift 1/16th left
timelineWidget->shift_view(-16);
break;
case GDK_SCROLL_DOWN:
// User scrolled down. Shift 1/16th right
timelineWidget->shift_view(16);
break;
}
}
}
bool
TimelineBody::on_button_press_event(GdkEventButton* event)
{
mouseDownX = event->x;
mouseDownY = event->y;
switch(event->button)
{
case 2:
begin_shift_drag();
break;
default:
dragType = None;
break;
}
// Forward the event to the tool
tool->on_button_press_event(event);
return true;
}
bool
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)
{
case Shift:
{
const int64_t scale = timelineWidget->get_time_scale();
gavl_time_t offset = beginShiftTimeOffset +
(int64_t)(mouseDownX - event->x) * scale;
timelineWidget->set_time_offset(offset);
set_vertical_offset((int)(mouseDownY - event->y) +
beginShiftVerticalOffset);
break;
}
}
// 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;
}
bool
TimelineBody::on_expose_event(GdkEventExpose* event)
{
Cairo::Matrix view_matrix;
REQUIRE(event != NULL);
REQUIRE(timelineWidget != NULL);
// This is where we draw on the window
Glib::RefPtr<Gdk::Window> window = get_window();
if(!window)
return false;
// Makes sure the widget styles have been loaded
read_styles();
// Prepare to render via cairo
Glib::RefPtr<Style> style = get_style();
const Allocation allocation = get_allocation();
Cairo::RefPtr<Cairo::Context> cr = window->create_cairo_context();
REQUIRE(style);
REQUIRE(cr);
// Translate the view by the scroll distance
cr->translate(0, -get_vertical_offset());
cr->get_matrix(view_matrix);
// Interate drawing each track
BOOST_FOREACH( Track* track, timelineWidget->tracks )
{
ASSERT(track != NULL);
const int height = track->get_height();
ASSERT(height >= 0);
// Draw the track background
cr->rectangle(0, 0, allocation.get_width(), height);
gdk_cairo_set_source_color(cr->cobj(), &backgroundColour);
cr->fill();
// Render the track
cr->save();
track->draw_track(cr);
cr->restore();
// Shift for the next track
cr->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());
cr->set_matrix(view_matrix);
// Draw the cover
if(end_x > 0 && start_x < allocation.get_width())
{
cr->set_source_rgba(
(float)selectionColour.red / 0xFFFF,
(float)selectionColour.green / 0xFFFF,
(float)selectionColour.blue / 0xFFFF,
selectionAlpha);
cr->rectangle(start_x + 0.5, 0,
end_x - start_x, allocation.get_height());
cr->fill();
}
gdk_cairo_set_source_color(cr->cobj(), &selectionColour);
cr->set_line_width(1);
// Draw the start
if(start_x >= 0 && start_x < allocation.get_width())
{
cr->move_to(start_x + 0.5, 0);
cr->line_to(start_x + 0.5, allocation.get_height());
cr->stroke_preserve();
}
// Draw the end
if(end_x >= 0 && end_x < allocation.get_width())
{
cr->move_to(end_x + 0.5, 0);
cr->line_to(end_x + 0.5, allocation.get_height());
cr->stroke_preserve();
}
return true;
}
void
TimelineBody::begin_shift_drag()
{
dragType = Shift;
beginShiftTimeOffset = timelineWidget->get_time_offset();
beginShiftVerticalOffset = get_vertical_offset();
}
int
TimelineBody::get_vertical_offset() const
{
return (int)timelineWidget->verticalAdjustment.get_value();
}
void
TimelineBody::set_vertical_offset(int offset)
{
timelineWidget->verticalAdjustment.set_value(offset);
}
void
TimelineBody::register_styles() const
{
GtkWidgetClass *klass = GTK_WIDGET_CLASS(G_OBJECT_GET_CLASS(gobj()));
gtk_widget_class_install_style_property(
GTK_WIDGET_CLASS(G_OBJECT_GET_CLASS(gobj())),
g_param_spec_boxed("background",
"Track Background",
"The background colour of timeline tracks",
GDK_TYPE_COLOR, G_PARAM_READABLE));
gtk_widget_class_install_style_property(
GTK_WIDGET_CLASS(G_OBJECT_GET_CLASS(gobj())),
g_param_spec_boxed("selection",
"End lines of a selection",
"The colour of selection limit lines",
GDK_TYPE_COLOR, G_PARAM_READABLE));
gtk_widget_class_install_style_property(klass,
g_param_spec_float("selection_alpha",
"Selection Alpha",
"The transparency of the selection marque.",
0, 1.0, 0.5, G_PARAM_READABLE));
}
void
TimelineBody::read_styles()
{
backgroundColour = WindowManager::read_style_colour_property(
*this, "background", 0, 0, 0);
selectionColour = WindowManager::read_style_colour_property(
*this, "selection", 0, 0, 0);
get_style_property("selection_alpha", selectionAlpha);
}
} // namespace timeline
} // namespace widgets
} // namespace gui
} // namespace lumiera

View file

@ -0,0 +1,113 @@
/*
timeline-body.hpp - Declaration of the timeline body widget
Copyright (C) Lumiera.org
2008, Joel Holdsworth <joel@airwebreathe.org.uk>
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 2 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, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/** @file timeline-body.hpp
** This file contains the definition of timeline body widget
*/
#ifndef TIMELINE_BODY_HPP
#define TIMELINE_BODY_HPP
#include "../../gtk-lumiera.hpp"
#include "timeline-tool.hpp"
namespace lumiera {
namespace gui {
namespace widgets {
class TimelineWidget;
namespace timeline {
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:
void on_realize();
void on_scroll();
bool on_scroll_event(GdkEventScroll* event);
bool on_button_press_event (GdkEventButton* event);
bool on_button_release_event (GdkEventButton* event);
bool on_motion_notify_event(GdkEventMotion *event);
bool on_expose_event(GdkEventExpose* event);
/* ===== Internals ===== */
private:
void begin_shift_drag();
int get_vertical_offset() const;
void set_vertical_offset(int offset);
void register_styles() const;
void read_styles();
private:
// Internal structures
enum DragType
{
None,
Shift
};
timeline::Tool *tool;
double mouseDownX, mouseDownY;
// Scroll State
DragType dragType;
gavl_time_t beginShiftTimeOffset;
int beginShiftVerticalOffset;
// Style properties
GdkColor backgroundColour;
GdkColor selectionColour;
float selectionAlpha;
lumiera::gui::widgets::TimelineWidget *timelineWidget;
friend class Tool;
friend class ArrowTool;
friend class IBeamTool;
};
} // namespace timeline
} // namespace widgets
} // namespace gui
} // namespace lumiera
#endif // TIMELINE_BODY_HPP

View file

@ -0,0 +1,238 @@
/*
timeline-ibeam-tool.cpp - Implementation of the IBeamTool class
Copyright (C) Lumiera.org
2008, Joel Holdsworth <joel@airwebreathe.org.uk>
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 2 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, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
* *****************************************************/
#include "timeline-ibeam-tool.hpp"
#include "../timeline-widget.hpp"
using namespace lumiera::gui::widgets;
namespace lumiera {
namespace gui {
namespace widgets {
namespace timeline {
// ===== Constants ===== //
const int IBeamTool::DragZoneWidth = 5;
const int IBeamTool::ScrollSlideRateDivisor = 16;
const int IBeamTool::ScrollSlideEventInterval = 40;
// ===== Implementation ===== //
IBeamTool::IBeamTool(TimelineBody *timeline_body) :
dragType(None),
pinnedDragTime(0),
scrollSlideRate(0),
Tool(timeline_body)
{
}
IBeamTool::~IBeamTool()
{
end_scroll_slide();
}
ToolType
IBeamTool::get_type() const
{
return IBeam;
}
Gdk::Cursor
IBeamTool::get_cursor() const
{
// Are we dragging?
// Make the cursor indicate that type of drag
switch(dragType)
{
case Selection:
return Gdk::Cursor(Gdk::XTERM);
case GrabStart:
return Gdk::Cursor(Gdk::LEFT_SIDE);
case GrabEnd:
return Gdk::Cursor(Gdk::RIGHT_SIDE);
}
// Are we hovering over the ends of the selection?
// Make the cursor indicate that the user can resize the selection.
if(is_mouse_in_start_drag_zone())
return Gdk::Cursor(Gdk::LEFT_SIDE);
if(is_mouse_in_end_drag_zone())
return Gdk::Cursor(Gdk::RIGHT_SIDE);
// By default return an I-beam cursor
return Gdk::Cursor(Gdk::XTERM);
}
void
IBeamTool::on_button_press_event(GdkEventButton* event)
{
Tool::on_button_press_event(event);
TimelineWidget *timeline_widget = get_timeline_widget();
if(event->button == 1)
{
const gavl_time_t time = timeline_widget->x_to_time(event->x);
if(is_mouse_in_start_drag_zone())
{
// User began to drag the start of the selection
dragType = GrabStart;
pinnedDragTime = timeline_widget->get_selection_end();
}
else if(is_mouse_in_end_drag_zone())
{
// User began to drag the end of the selection
dragType = GrabEnd;
pinnedDragTime = timeline_widget->get_selection_start();
}
else
{
// User began the drag in clear space, begin a Select drag
dragType = Selection;
pinnedDragTime = time;
timeline_widget->set_selection(time, time);
}
}
}
void
IBeamTool::on_button_release_event(GdkEventButton* event)
{
// Ensure that we can't get a mixed up state
ENSURE(isDragging == (dragType != None));
ENSURE(isDragging == (event->button == 1));
if(event->button == 1)
{
set_leading_x(event->x);
// Terminate the drag now the button is released
dragType = None;
// If there was a scroll slide, terminate it
end_scroll_slide();
// Apply the cursor - there are some corner cases where it can
// change by the end of the drag
apply_cursor();
}
Tool::on_button_release_event(event);
}
void
IBeamTool::on_motion_notify_event(GdkEventMotion *event)
{
Tool::on_motion_notify_event(event);
// Ensure that we can't get a mixed up state
ENSURE(isDragging == (dragType != None));
if(isDragging)
{
set_leading_x(event->x);
// Is the mouse out of bounds? if so we must begin scrolling
const Gdk::Rectangle body_rect(get_body_rectangle());
if(event->x < 0)
begin_scroll_slide(
event->x / ScrollSlideRateDivisor);
else if(event->x > body_rect.get_width())
begin_scroll_slide(
(event->x - body_rect.get_width()) / ScrollSlideRateDivisor);
else end_scroll_slide();
}
apply_cursor();
}
bool
IBeamTool::on_scroll_slide_timer()
{
get_timeline_widget()->shift_view(scrollSlideRate);
// Return true to keep the timer going
return true;
}
void
IBeamTool::set_leading_x(const int x)
{
TimelineWidget *timeline_widget = get_timeline_widget();
const gavl_time_t time = timeline_widget->x_to_time(x);
if(time > pinnedDragTime)
timeline_widget->set_selection(pinnedDragTime, time);
else
timeline_widget->set_selection(time, pinnedDragTime);
}
void
IBeamTool::begin_scroll_slide(int scroll_slide_rate)
{
scrollSlideRate = scroll_slide_rate;
if(!scrollSlideEvent.connected())
scrollSlideEvent = Glib::signal_timeout().connect(
sigc::mem_fun(this, &IBeamTool::on_scroll_slide_timer),
ScrollSlideEventInterval);
}
void
IBeamTool::end_scroll_slide()
{
scrollSlideRate = 0;
if(scrollSlideEvent.connected())
scrollSlideEvent.disconnect();
}
bool
IBeamTool::is_mouse_in_start_drag_zone() const
{
TimelineWidget *timeline_widget = get_timeline_widget();
const int start_x = timeline_widget->time_to_x(
timeline_widget->get_selection_start());
return (mousePoint.get_x() <= start_x &&
mousePoint.get_x() > start_x - DragZoneWidth);
}
bool
IBeamTool::is_mouse_in_end_drag_zone() const
{
TimelineWidget *timeline_widget = get_timeline_widget();
const int end_x = timeline_widget->time_to_x(
timeline_widget->get_selection_end());
return (mousePoint.get_x() >= end_x &&
mousePoint.get_x() < end_x + DragZoneWidth);
}
} // namespace timeline
} // namespace widgets
} // namespace gui
} // namespace lumiera

View file

@ -0,0 +1,211 @@
/*
timeline-ibeam-tool.hpp - Declaration of the ArrowTool class
Copyright (C) Lumiera.org
2008, Joel Holdsworth <joel@airwebreathe.org.uk>
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 2 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, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/** @file timeline-ibeam-tool.hpp
** This file contains the definition of ibeam tool class
** tool objects
*/
#ifndef TIMELINE_IBEAM_TOOL_HPP
#define TIMELINE_IBEAM_TOOL_HPP
#include <gtkmm.h>
#include "timeline-tool.hpp"
namespace lumiera {
namespace gui {
namespace widgets {
namespace timeline {
/**
* A helper class to implement the timeline i-beam tool
*/
class IBeamTool : public Tool
{
public:
/**
* Constructor
* @param timeline_body The owner timeline body object
*/
IBeamTool(TimelineBody *timeline_body);
/**
* Gets the type of tool represented by this class
*/
ToolType get_type() const;
protected:
/**
* Destructor
*/
~IBeamTool();
/**
* Gets the cursor to display for this tool at this moment.
*/
Gdk::Cursor get_cursor() const;
protected:
/**
* The event handler for button press events.
*/
void on_button_press_event(GdkEventButton* event);
/**
* The event handler for button release events.
*/
void on_button_release_event(GdkEventButton* event);
/**
* The event handler for mouse move events.
*/
void on_motion_notify_event(GdkEventMotion *event);
private:
/* ===== Internal Event Handlers ===== */
/**
* An internal event handler, which is called when the scroll slide
* timer calls it.
*/
bool on_scroll_slide_timer();
private:
/* ===== Internal Methods ===== */
/**
* As the user drags, this function is called to update the position
* of the moving end of the selection.
*/
void set_leading_x(const int x);
/**
* Begins, or continues a scroll slide at a given rate
* @param scroll_slide_rate The distance to slide every timer event
* in units of 1/256th of the view width.
*/
void begin_scroll_slide(int scroll_slide_rate);
/**
* Ends a scroll slide, and disconnects the slide timer
*/
void end_scroll_slide();
/**
* Determines if the cursor is hovering over the start of the
* selection.
*/
bool is_mouse_in_start_drag_zone() const;
/**
* Determines if the cursor is hovering over the end of the
* selection.
*/
bool is_mouse_in_end_drag_zone() const;
private:
/* ==== Enums ===== */
/**
* An enum used to represent the type of drag currently take place.
*/
enum DragType
{
/**
* No drag is occuring
*/
None,
/**
* A selection drag is occuring.
* @remarks The position of one end of the selection was set at
* mouse-down of the drag, and the other end is set by
* drag-release.
*/
Selection,
/**
* The start of the selection is being dragged.
*/
GrabStart,
/**
* The end of the selection is being dragged.
*/
GrabEnd
};
/* ==== Internals ===== */
/**
* Specifies the type of drag currently taking place.
*/
DragType dragType;
/**
* During a selection drag, one end of the selection is moving with
* the mouse, the other is pinned. pinnedDragTime specifies the time
* of that point.
*/
gavl_time_t pinnedDragTime;
/**
* This connection is used to represent the timer which causes scroll
* sliding to occur.
* @remarks Scroll sliding is an animated scroll which occurs when
* the user drags a selection outside the area of the timeline body.
*/
sigc::connection scrollSlideEvent;
/**
* Specifies the rate at which scroll sliding is currently taking
* place.
*/
int scrollSlideRate;
/* ===== Constants ===== */
/**
* DragZoneSize defines the width of the zone near to the end of the
* selection in which dragging will cause the selection to resize.
* @remarks The selection marque can be resized by dragging the ends
* of it. Special cursors are shown when the mouse is in this region.
*/
static const int DragZoneWidth;
/**
* The amount to divide the mouse overshoot by to produce the slide
* scroll rate.
* @remarks Smaller values cause faster scrolling.
*/
static const int ScrollSlideRateDivisor;
/**
* The interval between scroll slide events in ms.
*/
static const int ScrollSlideEventInterval;
};
} // namespace timeline
} // namespace widgets
} // namespace gui
} // namespace lumiera
#endif // TIMELINE_IBEAM_TOOL_HPP

View file

@ -0,0 +1,423 @@
/*
timeline-ruler.cpp - Implementation of the time ruler widget
Copyright (C) Lumiera.org
2008, Joel Holdsworth <joel@airwebreathe.org.uk>
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 2 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, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
* *****************************************************/
#include <cairomm-1.0/cairomm/cairomm.h>
#include "timeline-ruler.hpp"
#include "../timeline-widget.hpp"
#include "../../window-manager.hpp"
extern "C" {
#include "../../../lib/time.h"
}
using namespace Gtk;
using namespace Cairo;
using namespace std;
using namespace lumiera::gui;
using namespace lumiera::gui::widgets;
using namespace lumiera::gui::widgets::timeline;
namespace lumiera {
namespace gui {
namespace widgets {
namespace timeline {
TimelineRuler::TimelineRuler(
lumiera::gui::widgets::TimelineWidget *timeline_widget) :
Glib::ObjectBase("TimelineRuler"),
mouseChevronOffset(0),
annotationHorzMargin(0),
annotationVertMargin(0),
majorTickHeight(0),
minorLongTickHeight(0),
minorShortTickHeight(0),
minDivisionWidth(100),
mouseChevronSize(5),
selectionChevronSize(5),
timelineWidget(timeline_widget)
{
REQUIRE(timelineWidget != NULL);
// Install style properties
register_styles();
}
void
TimelineRuler::set_mouse_chevron_offset(int offset)
{
mouseChevronOffset = offset;
queue_draw();
}
void
TimelineRuler::update_view()
{
rulerImage.clear();
queue_draw();
}
void
TimelineRuler::on_realize()
{
Widget::on_realize();
// Set event notifications
add_events(Gdk::POINTER_MOTION_MASK | Gdk::SCROLL_MASK);
// Load styles
read_styles();
}
bool
TimelineRuler::on_expose_event(GdkEventExpose* event)
{
REQUIRE(event != NULL);
// This is where we draw on the window
Glib::RefPtr<Gdk::Window> window = get_window();
if(!window)
return false;
// Prepare to render via cairo
const Allocation allocation = get_allocation();
Cairo::RefPtr<Context> cr = window->create_cairo_context();
REQUIRE(cr);
// Draw the ruler
if(!rulerImage)
{
// We have no cached rendering - it must be redrawn
// but do we need ro allocate a new image?
if(!rulerImage ||
rulerImage->get_width() != allocation.get_width() ||
rulerImage->get_height() != allocation.get_height())
rulerImage = ImageSurface::create(FORMAT_RGB24,
allocation.get_width(), allocation.get_height());
ENSURE(rulerImage);
Cairo::RefPtr<Context> image_cairo = Context::create(rulerImage);
ENSURE(image_cairo);
draw_ruler(image_cairo, allocation);
}
// Draw the cached ruler image
cr->set_source(rulerImage, 0, 0);
cr->paint();
// Draw the overlays
draw_mouse_chevron(cr, allocation);
draw_selection(cr, allocation);
return true;
}
bool
TimelineRuler::on_motion_notify_event(GdkEventMotion *event)
{
REQUIRE(event != NULL);
set_mouse_chevron_offset(event->x);
return true;
}
void
TimelineRuler::on_size_request (Gtk::Requisition *requisition)
{
REQUIRE(requisition != NULL);
// Initialize the output parameter
*requisition = Gtk::Requisition();
requisition->width = 0;
get_style_property("height", requisition->height);
}
void
TimelineRuler::on_size_allocate(Gtk::Allocation& allocation)
{
Widget::on_size_allocate(allocation);
rulerImage.clear(); // The widget has changed size - redraw
}
void
TimelineRuler::draw_ruler(Cairo::RefPtr<Cairo::Context> cr,
const Gdk::Rectangle ruler_rect)
{
REQUIRE(cr);
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();
Glib::RefPtr<Pango::Layout> pango_layout = create_pango_layout("");
Glib::RefPtr<Style> style = get_style();
// Render the background, and clip inside the area
Gdk::Cairo::set_source_color(cr, style->get_bg(STATE_NORMAL));
cr->rectangle(0, 0,
ruler_rect.get_width(), ruler_rect.get_height());
cr->fill_preserve();
cr->clip();
// Make sure we don't have impossible zoom
if(time_scale <= 0)
return;
// Render ruler annotations
Gdk::Cairo::set_source_color(cr, style->get_fg(STATE_NORMAL));
const gavl_time_t major_spacing = calculate_major_spacing();
const gavl_time_t minor_spacing = major_spacing / 10;
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 = left_offset / time_scale;
do
{
x = (int)(time_offset / time_scale - x_offset);
cr->set_line_width(1);
if(time_offset % major_spacing == 0)
{
// Draw the major grid-line
cr->move_to(x + 0.5, height - majorTickHeight);
cr->line_to(x + 0.5, height);
cr->stroke();
// Draw the text
pango_layout->set_text(lumiera_tmpbuf_print_time(time_offset));
cr->move_to(annotationHorzMargin + x, annotationVertMargin);
pango_layout->add_to_cairo_context(cr);
cr->fill();
}
else
{
// Draw the long or short minor grid-line
if(time_offset % (minor_spacing * 2) == 0)
cr->move_to(x + 0.5, height - minorLongTickHeight);
else
cr->move_to(x + 0.5, height - minorShortTickHeight);
cr->line_to(x + 0.5, height);
cr->stroke();
}
time_offset += minor_spacing;
}
while(x < ruler_rect.get_width());
}
void
TimelineRuler::draw_mouse_chevron(Cairo::RefPtr<Cairo::Context> cr,
const Gdk::Rectangle ruler_rect)
{
REQUIRE(cr);
REQUIRE(ruler_rect.get_width() > 0);
REQUIRE(ruler_rect.get_height() > 0);
// Is the mouse chevron in view?
if(mouseChevronOffset < 0 ||
mouseChevronOffset >= ruler_rect.get_width())
return;
// Set the source colour
Glib::RefPtr<Style> style = get_style();
Gdk::Cairo::set_source_color(cr, style->get_fg(STATE_NORMAL));
cr->move_to(mouseChevronOffset + 0.5,
ruler_rect.get_height());
cr->rel_line_to(-mouseChevronSize, -mouseChevronSize);
cr->rel_line_to(2 * mouseChevronSize, 0);
cr->fill();
}
void
TimelineRuler::draw_selection(Cairo::RefPtr<Cairo::Context> cr,
const Gdk::Rectangle ruler_rect)
{
REQUIRE(cr);
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(cr, 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())
{
cr->move_to(a, ruler_rect.get_height());
cr->rel_line_to(0, -selectionChevronSize);
cr->rel_line_to(-selectionChevronSize, 0);
cr->fill();
}
// Draw the selection end chevron
const int b = timelineWidget->time_to_x(
timelineWidget->selectionEnd);
if(b >= 0 && b < ruler_rect.get_width())
{
cr->move_to(b, ruler_rect.get_height());
cr->rel_line_to(0, -selectionChevronSize);
cr->rel_line_to(selectionChevronSize, 0);
cr->fill();
}
}
gavl_time_t
TimelineRuler::calculate_major_spacing() const
{
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,
GAVL_TIME_SCALE / 200,
GAVL_TIME_SCALE / 100,
GAVL_TIME_SCALE / 40,
GAVL_TIME_SCALE / 20,
GAVL_TIME_SCALE / 10,
GAVL_TIME_SCALE / 4,
GAVL_TIME_SCALE / 2,
GAVL_TIME_SCALE,
2l * GAVL_TIME_SCALE,
5l * GAVL_TIME_SCALE,
10l * GAVL_TIME_SCALE,
15l * GAVL_TIME_SCALE,
30l * GAVL_TIME_SCALE,
60l * GAVL_TIME_SCALE,
2l * 60l * GAVL_TIME_SCALE,
5l * 60l * GAVL_TIME_SCALE,
10l * 60l * GAVL_TIME_SCALE,
15l * 60l * GAVL_TIME_SCALE,
30l * 60l * GAVL_TIME_SCALE,
60l * 60l * GAVL_TIME_SCALE
};
for(i = 0; i < sizeof(major_spacings) / sizeof(gavl_time_t); i++)
{
const int64_t division_width = major_spacings[i] / time_scale;
if(division_width > minDivisionWidth)
break;
}
return major_spacings[i];
}
void
TimelineRuler::register_styles() const
{
GtkWidgetClass *klass = GTK_WIDGET_CLASS(G_OBJECT_GET_CLASS(gobj()));
gtk_widget_class_install_style_property(klass,
g_param_spec_int("height",
"Height of the Ruler Widget",
"The height of the ruler widget in pixels.",
0, G_MAXINT, 18, G_PARAM_READABLE));
gtk_widget_class_install_style_property(klass,
g_param_spec_int("major_tick_height",
"Height of Major Ticks",
"The length of major ticks in pixels.",
0, G_MAXINT, 18, G_PARAM_READABLE));
gtk_widget_class_install_style_property(klass,
g_param_spec_int("minor_long_tick_height",
"Height of Long Minor Ticks",
"The length of long minor ticks in pixels.",
0, G_MAXINT, 6, G_PARAM_READABLE));
gtk_widget_class_install_style_property(klass,
g_param_spec_int("minor_short_tick_height",
"Height of Short Minor Ticks",
"The length of short minor ticks in pixels.",
0, G_MAXINT, 3, G_PARAM_READABLE));
gtk_widget_class_install_style_property(klass,
g_param_spec_int("annotation_horz_margin",
"Horizontal margin around annotation text",
"The horizontal margin around the annotation text in pixels.",
0, G_MAXINT, 3,
G_PARAM_READABLE));
gtk_widget_class_install_style_property(klass,
g_param_spec_int("annotation_vert_margin",
"Vertical margin around annotation text",
"The vertical margin around the annotation text in pixels.",
0, G_MAXINT, 0, G_PARAM_READABLE));
gtk_widget_class_install_style_property(klass,
g_param_spec_int("min_division_width",
"Minimum Division Width",
"The minimum distance in pixels that two major division may approach.",
0, G_MAXINT, 100, G_PARAM_READABLE));
gtk_widget_class_install_style_property(klass,
g_param_spec_int("mouse_chevron_size",
"Mouse Chevron Size",
"The height of the mouse chevron in pixels.",
0, G_MAXINT, 5, G_PARAM_READABLE));
gtk_widget_class_install_style_property(klass,
g_param_spec_int("selection_chevron_size",
"Selection Chevron Size",
"The height of the selection chevrons in pixels.",
0, G_MAXINT, 5, G_PARAM_READABLE));
}
void
TimelineRuler::read_styles()
{
get_style_property("annotation_horz_margin", annotationHorzMargin);
get_style_property("annotation_vert_margin", annotationVertMargin);
get_style_property("major_tick_height", majorTickHeight);
get_style_property("minor_long_tick_height", minorLongTickHeight);
get_style_property("minor_short_tick_height", minorShortTickHeight);
get_style_property("min_division_width", minDivisionWidth);
get_style_property("mouse_chevron_size", mouseChevronSize);
get_style_property("selection_chevron_size", selectionChevronSize);
}
} // namespace timeline
} // namespace widgets
} // namespace gui
} // namespace lumiera

View file

@ -0,0 +1,113 @@
/*
timeline-ruler.hpp - Declaration of the time ruler widget
Copyright (C) Lumiera.org
2008, Joel Holdsworth <joel@airwebreathe.org.uk>
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 2 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, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/** @file timeline-ruler.hpp
** This file contains the declaration of the time ruler widget
** widget
*/
#ifndef TIMELINE_RULER_HPP
#define TIMELINE_RULER_HPP
#include "../../gtk-lumiera.hpp"
namespace lumiera {
namespace gui {
namespace widgets {
class TimelineWidget;
namespace timeline {
class TimelineRuler : public Gtk::DrawingArea
{
public:
TimelineRuler(
lumiera::gui::widgets::TimelineWidget *timeline_widget);
/**
* Sets the offset of the mouse chevron in pixels from the left
* edge of the widget. If offset is less than 0 or greater than the
* width, the chevron will not be visible.
*/
void set_mouse_chevron_offset(int offset);
void update_view();
/* ===== Events ===== */
protected:
void on_realize();
bool on_expose_event(GdkEventExpose *event);
bool on_motion_notify_event(GdkEventMotion *event);
void on_size_request(Gtk::Requisition *requisition);
void on_size_allocate(Gtk::Allocation& allocation);
/* ===== Internals ===== */
private:
void draw_ruler(Cairo::RefPtr<Cairo::Context> cairo,
const Gdk::Rectangle ruler_rect);
void draw_mouse_chevron(Cairo::RefPtr<Cairo::Context> cr,
const Gdk::Rectangle ruler_rect);
void draw_selection(Cairo::RefPtr<Cairo::Context> cr,
const Gdk::Rectangle ruler_rect);
gavl_time_t calculate_major_spacing() const;
void register_styles() const;
void read_styles();
private:
// Indicated values
int mouseChevronOffset;
// Style values
int annotationHorzMargin;
int annotationVertMargin;
int majorTickHeight;
int minorLongTickHeight;
int minorShortTickHeight;
int minDivisionWidth;
int mouseChevronSize;
int selectionChevronSize;
// Owner
lumiera::gui::widgets::TimelineWidget *timelineWidget;
// Cached ruler image
Cairo::RefPtr<Cairo::ImageSurface> rulerImage;
};
} // namespace timeline
} // namespace widgets
} // namespace gui
} // namespace lumiera
#endif // TIMELINE_RULER_HPP

View file

@ -0,0 +1,100 @@
/*
timeline-tool.hpp - Implementation of the Tool class
Copyright (C) Lumiera.org
2008, Joel Holdsworth <joel@airwebreathe.org.uk>
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 2 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, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
* *****************************************************/
#include "timeline-tool.hpp"
#include "../timeline-widget.hpp"
using namespace Gdk;
namespace lumiera {
namespace gui {
namespace widgets {
namespace timeline {
Tool::Tool(TimelineBody *timeline_body) :
timelineBody(timeline_body),
isDragging(false)
{
REQUIRE(timeline_body != NULL);
}
bool
Tool::apply_cursor()
{
REQUIRE(timelineBody != NULL);
Glib::RefPtr<Window> window =
timelineBody->get_window();
if(!window)
return false;
window->set_cursor(get_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;
}
void
Tool::on_motion_notify_event(GdkEventMotion *event)
{
mousePoint = Point(event->x, event->y);
}
lumiera::gui::widgets::TimelineWidget*
Tool::get_timeline_widget() const
{
REQUIRE(timelineBody != NULL);
lumiera::gui::widgets::TimelineWidget *timeline_widget =
timelineBody->timelineWidget;
REQUIRE(timeline_widget != NULL);
return timeline_widget;
}
Gdk::Rectangle
Tool::get_body_rectangle() const
{
REQUIRE(timelineBody != NULL);
return timelineBody->get_allocation();
}
} // namespace timeline
} // namespace widgets
} // namespace gui
} // namespace lumiera

View file

@ -0,0 +1,144 @@
/*
timeline-tool.hpp - Declaration of the Tool class
Copyright (C) Lumiera.org
2008, Joel Holdsworth <joel@airwebreathe.org.uk>
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 2 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, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/** @file timeline-tool.hpp
** This file contains the definition of base class for timeline
** tool objects
*/
#ifndef TIMELINE_TOOL_HPP
#define TIMELINE_TOOL_HPP
#include "../../gtk-lumiera.hpp"
namespace lumiera {
namespace gui {
namespace widgets {
class TimelineWidget;
namespace timeline {
class TimelineBody;
/**
* Specifies the types of different timeline tool classes.
*/
enum ToolType
{
None,
Arrow,
IBeam
};
/**
* The base class of all timeline tools.
*/
class Tool
{
protected:
/**
* Constructor
* @param timeline_body The owner timeline body object
*/
Tool(TimelineBody *timeline_body);
public:
/**
* Destructor to be overriden by derived classes.
* @remarks If this were not present, derrived class destructors
* would not be called.
*/
virtual ~Tool() {};
/**
* Gets the type of tool represented by this class.
* @remarks This must be implemented by all timeline tool classes.
*/
virtual ToolType get_type() const = 0;
/**
* Reaplies the cursor for the current tool at the current moment.
*/
bool apply_cursor();
public:
/* ===== Event Handlers ===== */
/**
* The event handler for button press events.
* @remarks This can be overriden by the derrived classes, but
* Tool::on_button_press_event must be called <b>at the start</b>
* of the derrived class's override.
*/
virtual void on_button_press_event(GdkEventButton* event);
/**
* The event handler for button release events.
* @remarks This can be overriden by the derrived classes, but
* Tool::on_button_release_event must be called <b>at the end</b> of
* the derrived class's override.
*/
virtual void on_button_release_event(GdkEventButton* event);
/**
* The event handler for mouse move events.
* @remarks This can be overriden by the derrived classes, but
* Tool::on_motion_notify_event must be called <b>at the start</b> of
* the derrived class's override.
*/
virtual void on_motion_notify_event(GdkEventMotion *event);
protected:
/* ===== Internal Overrides ===== */
/**
* Gets the cursor to display for this tool at this moment.
* @remarks This must be implemented by all timeline tool classes.
*/
virtual Gdk::Cursor get_cursor() const = 0;
protected:
/* ===== Utilities ===== */
/**
* Helper function which retrieves the pointer to owner timeline
* widget object, which is the owner of the timeline body.
*/
lumiera::gui::widgets::TimelineWidget *get_timeline_widget() const;
/**
* Helper function which retrieves the rectangle of the timeline
* body.
*/
Gdk::Rectangle get_body_rectangle() const;
protected:
bool isDragging;
Gdk::Point mousePoint;
TimelineBody *timelineBody;
};
} // namespace timeline
} // namespace widgets
} // namespace gui
} // namespace lumiera
#endif // TIMELINE_TOOL_HPP

View file

@ -0,0 +1,64 @@
/*
track.cpp - Implementation of the timeline track object
Copyright (C) Lumiera.org
2008, Joel Holdsworth <joel@airwebreathe.org.uk>
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 2 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, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
* *****************************************************/
#include "track.hpp"
namespace lumiera {
namespace gui {
namespace widgets {
namespace timeline {
Track::Track() :
label("XHeaderTest")
{
headerWidget.pack_start(label);
}
Gtk::Widget&
Track::get_header_widget()
{
return headerWidget;
}
Glib::ustring
Track::get_title()
{
return "Hello";
}
int
Track::get_height()
{
return 100;
}
void
Track::draw_track(Cairo::RefPtr<Cairo::Context> cairo)
{
}
} // namespace timeline
} // namespace widgets
} // namespace gui
} // namespace lumiera

View file

@ -0,0 +1,60 @@
/*
track.hpp - Declaration of the timeline track object
Copyright (C) Lumiera.org
2008, Joel Holdsworth <joel@airwebreathe.org.uk>
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 2 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, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/** @file timeline/track.hpp
** This file contains the definition of timeline track object
*/
#ifndef TRACK_HPP
#define TRACK_HPP
#include "../../gtk-lumiera.hpp"
namespace lumiera {
namespace gui {
namespace widgets {
namespace timeline {
class Track
{
public:
Track();
Glib::ustring get_title();
Gtk::Widget& get_header_widget();
int get_height();
void draw_track(Cairo::RefPtr<Cairo::Context> cairo);
protected:
Gtk::VBox headerWidget;
Gtk::Label label;
};
} // namespace timeline
} // namespace widgets
} // namespace gui
} // namespace lumiera
#endif // TRACK_HPP

View file

@ -0,0 +1,104 @@
/*
video-display-widget.cpp - Implementation of the video viewer widget
Copyright (C) Lumiera.org
2008, Joel Holdsworth <joel@airwebreathe.org.uk>
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 2 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, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
* *****************************************************/
#include <gdkmm/drawable.h>
#include <gdkmm/general.h>
#include <cairomm-1.0/cairomm/cairomm.h>
#include "../gtk-lumiera.hpp"
#include "../output/xvdisplayer.hpp"
#include "../output/gdkdisplayer.hpp"
#include "video-display-widget.hpp"
namespace lumiera {
namespace gui {
namespace widgets {
VideoDisplayWidget::VideoDisplayWidget() :
displayer(NULL)
{
}
VideoDisplayWidget::~VideoDisplayWidget()
{
if(displayer != NULL)
delete displayer;
}
void
VideoDisplayWidget::on_realize()
{
// Call base class:
Gtk::Widget::on_realize();
// Set colors
modify_bg(Gtk::STATE_NORMAL, Gdk::Color("black"));
if(displayer != NULL)
delete displayer;
displayer = createDisplayer(this, 320, 240);
add_events(Gdk::ALL_EVENTS_MASK);
}
bool
VideoDisplayWidget::on_button_press_event (GdkEventButton* event)
{
unsigned char buffer[320 * 240 * 4];
for(int i = 0; i < 320*240*4; i++)
buffer[i] = rand();
displayer->put((void*)buffer);
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;
}
if ( displayer == NULL )
{
displayer = new GdkDisplayer( drawingArea, width, height );
}
return displayer;
}
} // namespace widgets
} // namespace gui
} // namespace lumiera

View file

@ -0,0 +1,67 @@
/*
video-display-widget.hpp - Declaration of the video viewer widget
Copyright (C) Lumiera.org
2008, Joel Holdsworth <joel@airwebreathe.org.uk>
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 2 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, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/** @file video-display-widget.hpp
** This file contains the definition of video viewer widget
*/
#ifndef VIDEO_DISPLAY_WIDGET_HPP
#define VIDEO_DISPLAY_WIDGET_HPP
#include <gtkmm.h>
#include "../output/displayer.hpp"
using namespace lumiera::gui::output;
namespace lumiera {
namespace gui {
namespace widgets {
class VideoDisplayWidget : public Gtk::DrawingArea
{
public:
VideoDisplayWidget();
~VideoDisplayWidget();
/* ===== Overrides ===== */
private:
virtual void on_realize();
// TEST CODE!!!!
virtual bool on_button_press_event (GdkEventButton* event);
/* ===== Internals ===== */
private:
static Displayer*
createDisplayer( Gtk::Widget *drawingArea, int width, int height );
private:
Displayer *displayer;
};
} // namespace widgets
} // namespace gui
} // namespace lumiera
#endif // VIDEO_DISPLAY_WIDGET_HPP

168
src/gui/window-manager.cpp Normal file
View file

@ -0,0 +1,168 @@
/*
window-manager.cpp - Defines the global UI Manager class
Copyright (C) Lumiera.org
2008, Joel Holdsworth <joel@airwebreathe.org.uk>
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 2 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, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
* *****************************************************/
#include "window-manager.hpp"
using namespace Gtk;
using namespace Glib;
namespace lumiera {
namespace gui {
WindowManager::WindowManager()
{
register_stock_items();
}
bool
WindowManager::set_theme(Glib::ustring path)
{
if(access(path.c_str(), R_OK))
{
ERROR(gui, "WindowManger: Unable to load rc file \"%s\"",
path.c_str());
return false;
}
gtk_rc_parse(path.c_str());
gtk_rc_reset_styles (gtk_settings_get_default());
return true;
}
GdkColor
WindowManager::read_style_colour_property(
Gtk::Widget &widget, const gchar *property_name,
guint16 red, guint16 green, guint16 blue)
{
GdkColor *colour;
gtk_widget_style_get(widget.gobj(), property_name, &colour, NULL);
// Did the color load successfully?
if(colour != NULL)
return *colour;
else
{
WARN(gui, "%s style value failed to load", property_name);
GdkColor default_colour;
default_colour.red = red;
default_colour.green = green;
default_colour.blue = blue;
return default_colour;
}
}
void
WindowManager::register_stock_items()
{
RefPtr<IconFactory> factory = IconFactory::create();
add_stock_item_set(factory, "panel-assets", "panel_assets", _("_Assets"));
add_stock_item_set(factory, "panel-timeline", "panel_timeline", _("_Timeline"));
add_stock_item_set(factory, "panel-viewer", "panel_viewer", _("_Viewer"));
add_stock_item_set(factory, "tool-arrow", "tool_arrow", _("_Arrow"));
add_stock_item_set(factory, "tool-i-beam", "tool_i_beam", _("_I-Beam"));
factory->add_default(); //Add factory to list of factories.
}
bool
WindowManager::add_stock_item_set(
const Glib::RefPtr<IconFactory>& factory,
const Glib::ustring& icon_name,
const Glib::ustring& id,
const Glib::ustring& label)
{
Gtk::IconSet icon_set;
add_stock_icon(icon_set, icon_name, 16);
add_stock_icon(icon_set, icon_name, 22);
add_stock_icon(icon_set, icon_name, 24);
add_stock_icon(icon_set, icon_name, 32);
add_stock_icon(icon_set, icon_name, 48);
if(!icon_set.get_sizes().empty())
{
const Gtk::StockID stock_id(id);
factory->add(stock_id, icon_set);
Gtk::Stock::add(Gtk::StockItem(stock_id, label));
return true;
}
ERROR(gui, "Unable to load icon \"%s\"", icon_name.c_str());
return false;
}
bool
WindowManager::add_stock_icon(Gtk::IconSet &icon_set,
const Glib::ustring& icon_name, int size)
{
// Try the ~/.lumiera/icons folder
if(add_stock_icon_source(icon_set, ustring::compose("%1/%2",
GtkLumiera::get_home_data_path(), ustring("icons")),
icon_name, size))
return true;
if(add_stock_icon_source(
icon_set, get_current_dir(), icon_name, size))
return true;
return false;
}
bool
WindowManager::add_stock_icon_source(Gtk::IconSet &icon_set,
const Glib::ustring& base_dir, const Glib::ustring& icon_name,
int size)
{
Gtk::IconSource source;
try
{
ustring path = ustring::compose("%1/%2x%2/%3.png",
base_dir, size, icon_name);
g_message("%s", path.c_str());
// This throws an exception if the file is not found:
source.set_pixbuf(Gdk::Pixbuf::create_from_file(path));
}
catch(const Glib::Exception& ex)
{
g_message("Failed");
return false;
}
source.set_size(IconSize(size));
//source.set_size_wildcarded(); // Icon may be scaled.
icon_set.add_source(source);
return true;
}
} // namespace gui
} // namespace lumiera

View file

@ -0,0 +1,71 @@
/*
window-manager.hpp - Defines the global UI Manager class
Copyright (C) Lumiera.org
2008, Joel Holdsworth <joel@airwebreathe.org.uk>
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 2 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, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/** @file window-manager.hpp
** This file contains the defintion of global UI Manager class
** user actions.
** @see window-manager.cpp
** @see gtk-lumiera.hpp
*/
#ifndef WINDOW_MANAGER_HPP
#define WINDOW_MANAGER_HPP
#include "gtk-lumiera.hpp"
namespace lumiera {
namespace gui {
class WindowManager
{
public:
WindowManager();
bool set_theme(Glib::ustring path);
static GdkColor read_style_colour_property(
Gtk::Widget &widget, const gchar *property_name,
guint16 red, guint16 green, guint16 blue);
private:
/**
* Registers application stock items: icons and
* labels associated with IDs */
static void register_stock_items();
static bool add_stock_item_set(
const Glib::RefPtr<Gtk::IconFactory>& factory,
const Glib::ustring& icon_name,
const Glib::ustring& id,
const Glib::ustring& label);
static bool add_stock_icon(Gtk::IconSet &icon_set,
const Glib::ustring& icon_name, int size);
static bool add_stock_icon_source(Gtk::IconSet &icon_set,
const Glib::ustring& base_dir,
const Glib::ustring& icon_name, int size);
};
} // namespace gui
} // namespace lumiera
#endif // WINDOW_MANAGER_HPP

View file

@ -0,0 +1,201 @@
/*
Actions.cpp - Definition of the main workspace window object
Copyright (C) Lumiera.org
2008, Joel Holdsworth <joel@airwebreathe.org.uk>
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 2 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, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
* *****************************************************/
#include "actions.hpp"
#include "workspace-window.hpp"
#include "../dialogs/render.hpp"
#include "../dialogs/preferences-dialog.hpp"
using namespace Gtk;
using namespace Glib;
using namespace sigc;
using namespace lumiera::gui;
namespace lumiera {
namespace gui {
namespace workspace {
Actions::Actions(WorkspaceWindow &workspace_window) :
workspaceWindow(workspace_window),
is_updating_action_state(false)
{
workspace_window.signal_show ().connect_notify(mem_fun(this, &Actions::update_action_state));
//----- Create the Action Group -----//
actionGroup = ActionGroup::create();
// File menu
actionGroup->add(Action::create("FileMenu", _("_File")));
actionGroup->add(Action::create("FileNewProject", Stock::NEW, _("_New Project...")),
sigc::mem_fun(*this, &Actions::on_menu_file_new_project));
actionGroup->add(Action::create("FileOpenProject", Stock::OPEN, _("_Open Project...")),
sigc::mem_fun(*this, &Actions::on_menu_file_open_project));
actionGroup->add(Action::create("FileRender", _("_Render...")),
Gtk::AccelKey("<shift>R"),
sigc::mem_fun(*this, &Actions::on_menu_file_render));
actionGroup->add(Action::create("FileQuit", Stock::QUIT),
sigc::mem_fun(*this, &Actions::on_menu_file_quit));
// Edit menu
actionGroup->add(Action::create("EditMenu", _("_Edit")));
actionGroup->add(Action::create("EditCopy", Stock::COPY),
sigc::mem_fun(*this, &Actions::on_menu_others));
actionGroup->add(Action::create("EditPaste", Stock::PASTE),
sigc::mem_fun(*this, &Actions::on_menu_others));
actionGroup->add(Action::create("EditPreferences", Stock::PREFERENCES),
sigc::mem_fun(*this, &Actions::on_menu_edit_preferences));
// View Menu
actionGroup->add(Action::create("ViewMenu", _("_View")));
assetsPanelAction = ToggleAction::create("ViewAssets",
Gtk::StockID("panel_assets"));
assetsPanelAction->signal_toggled().connect(
sigc::mem_fun(*this, &Actions::on_menu_view_assets));
actionGroup->add(assetsPanelAction);
timelinePanelAction = ToggleAction::create("ViewTimeline",
Gtk::StockID("panel_timeline"));
timelinePanelAction->signal_toggled().connect(
sigc::mem_fun(*this, &Actions::on_menu_view_timeline));
actionGroup->add(timelinePanelAction);
viewerPanelAction = ToggleAction::create("ViewViewer",
Gtk::StockID("panel_viewer"));
viewerPanelAction->signal_toggled().connect(
sigc::mem_fun(*this, &Actions::on_menu_view_viewer));
actionGroup->add(viewerPanelAction);
// Help Menu
actionGroup->add(Action::create("HelpMenu", _("_Help")) );
actionGroup->add(Action::create("HelpAbout", Stock::ABOUT),
sigc::mem_fun(*this, &Actions::on_menu_help_about) );
}
void
Actions::update_action_state()
{
REQUIRE(workspaceWindow.assets_panel != NULL);
REQUIRE(workspaceWindow.timeline_panel != NULL);
REQUIRE(workspaceWindow.viewer_panel != NULL);
is_updating_action_state = true;
assetsPanelAction->set_active(workspaceWindow.assets_panel->is_shown());
timelinePanelAction->set_active(workspaceWindow.timeline_panel->is_shown());
viewerPanelAction->set_active(workspaceWindow.viewer_panel->is_shown());
is_updating_action_state = false;
}
/* ===== File Menu Event Handlers ===== */
void
Actions::on_menu_file_new_project()
{
g_message("A File|New menu item was selecteda.");
}
void
Actions::on_menu_file_open_project()
{
g_message("A File|Open menu item was selecteda.");
}
void
Actions::on_menu_file_render()
{
dialogs::Render dialog(workspaceWindow);
dialog.run();
}
void
Actions::on_menu_file_quit()
{
workspaceWindow.hide(); // Closes the main window to stop the Gtk::Main::run().
}
/* ===== Edit Menu Event Handlers ===== */
void
Actions::on_menu_edit_preferences()
{
dialogs::PreferencesDialog dialog(workspaceWindow);
dialog.run();
}
/* ===== View Menu Event Handlers ===== */
void
Actions::on_menu_view_assets()
{
if(!is_updating_action_state)
workspaceWindow.assets_panel->show(assetsPanelAction->get_active());
}
void
Actions::on_menu_view_timeline()
{
if(!is_updating_action_state)
workspaceWindow.timeline_panel->show(timelinePanelAction->get_active());
}
void
Actions::on_menu_view_viewer()
{
if(!is_updating_action_state)
workspaceWindow.viewer_panel->show(viewerPanelAction->get_active());
}
void
Actions::on_menu_help_about()
{
// Configure the about dialog
AboutDialog dialog;
//dialog.set_program_name(AppTitle);
dialog.set_version(AppVersion);
//dialog.set_version(Appconfig::get("version"));
dialog.set_copyright(AppCopyright);
dialog.set_website(AppWebsite);
dialog.set_authors(StringArrayHandle(AppAuthors,
sizeof(AppAuthors) / sizeof(gchar*),
OWNERSHIP_NONE));
dialog.set_transient_for(workspaceWindow);
// Show the about dialog
dialog.run();
}
//----- Temporary junk
void
Actions::on_menu_others()
{
g_message("A menu item was selected.");
}
} // namespace workspace
} // namespace gui
} // namespace lumiera

View file

@ -0,0 +1,99 @@
/*
ACTIONS.hpp - Definition of a helper class for user actions
Copyright (C) Lumiera.org
2008, Joel Holdsworth <joel@airwebreathe.org.uk>
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 2 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, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/** @file actions.hpp
** This file contains the definition of a helper class for the
** main workspace window object, which registers and handles
** user actions.
** @see mainwindow.hpp
*/
#ifndef ACTIONS_HPP
#define ACTIONS_HPP
#include "../gtk-lumiera.hpp"
namespace lumiera {
namespace gui {
namespace workspace {
class WorkspaceWindow;
/**
* A helper class which registers and handles
* user action events.
*/
class Actions
{
private:
Actions(WorkspaceWindow &workspace_window);
/* ===== Internals ===== */
private:
/**
* Updates the state of the menu/toolbar actions
* to reflect the current state of the workspace */
void update_action_state();
/**
* A reference to the MainWindow which owns
* this helper */
WorkspaceWindow &workspaceWindow;
/* ===== Event Handlers ===== */
private:
void on_menu_file_new_project();
void on_menu_file_open_project();
void on_menu_file_render();
void on_menu_file_quit();
void on_menu_edit_preferences();
void on_menu_view_assets();
void on_menu_view_timeline();
void on_menu_view_viewer();
void on_menu_help_about();
// Temporary Junk
void on_menu_others();
/* ===== Actions ===== */
private:
Glib::RefPtr<Gtk::ActionGroup> actionGroup;
Glib::RefPtr<Gtk::ToggleAction> assetsPanelAction;
Glib::RefPtr<Gtk::ToggleAction> timelinePanelAction;
Glib::RefPtr<Gtk::ToggleAction> viewerPanelAction;
/* ===== Internals ===== */
private:
bool is_updating_action_state;
friend class WorkspaceWindow;
};
} // namespace workspace
} // namespace gui
} // namespace lumiera
#endif // ACTIONS_H

View file

@ -0,0 +1,186 @@
/*
workspace-window.cpp - Definition of the main workspace window object
Copyright (C) Lumiera.org
2008, Joel Holdsworth <joel@airwebreathe.org.uk>
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 2 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, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
* *****************************************************/
#include <gtkmm/stock.h>
#ifdef ENABLE_NLS
# include <libintl.h>
#endif
#include <libgdl-1.0/gdl/gdl-tools.h>
#include <libgdl-1.0/gdl/gdl-dock.h>
#include <libgdl-1.0/gdl/gdl-dock-item.h>
#include <libgdl-1.0/gdl/gdl-dock-placeholder.h>
#include <libgdl-1.0/gdl/gdl-dock-bar.h>
#include "../gtk-lumiera.hpp"
#include "workspace-window.hpp"
using namespace Gtk;
using namespace lumiera::gui::model;
namespace lumiera {
namespace gui {
namespace workspace {
WorkspaceWindow::WorkspaceWindow(Project *source_project) :
project(source_project),
actions(*this)
{
REQUIRE(source_project != NULL);
layout = NULL;
assets_panel = NULL;
viewer_panel = NULL;
timeline_panel = NULL;
create_ui();
}
WorkspaceWindow::~WorkspaceWindow()
{
REQUIRE(layout != NULL);
g_object_unref(layout);
REQUIRE(assets_panel != NULL);
assets_panel->unreference();
REQUIRE(viewer_panel != NULL);
viewer_panel->unreference();
REQUIRE(timeline_panel != NULL);
timeline_panel->unreference();
}
void
WorkspaceWindow::create_ui()
{
//----- Configure the Window -----//
set_title(AppTitle);
set_default_size(1024, 768);
//----- Set up the UI Manager -----//
// The UI will be nested within a VBox
add(base_container);
uiManager = Gtk::UIManager::create();
uiManager->insert_action_group(actions.actionGroup);
add_accel_group(uiManager->get_accel_group());
//Layout the actions in a menubar and toolbar:
Glib::ustring ui_info =
"<ui>"
" <menubar name='MenuBar'>"
" <menu action='FileMenu'>"
" <menuitem action='FileNewProject'/>"
" <menuitem action='FileOpenProject'/>"
" <separator/>"
" <menuitem action='FileRender'/>"
" <separator/>"
" <menuitem action='FileQuit'/>"
" </menu>"
" <menu action='EditMenu'>"
" <menuitem action='EditCopy'/>"
" <menuitem action='EditPaste'/>"
" <separator/>"
" <menuitem action='EditPreferences'/>"
" </menu>"
" <menu action='ViewMenu'>"
" <menuitem action='ViewAssets'/>"
" <menuitem action='ViewTimeline'/>"
" <menuitem action='ViewViewer'/>"
" </menu>"
" <menu action='HelpMenu'>"
" <menuitem action='HelpAbout'/>"
" </menu>"
" </menubar>"
" <toolbar name='ToolBar'>"
" <toolitem action='FileNewProject'/>"
" <toolitem action='FileOpenProject'/>"
" </toolbar>"
"</ui>";
try
{
uiManager->add_ui_from_string(ui_info);
}
catch(const Glib::Error& ex)
{
ERROR(gui, "Building menus failed: %s", ex.what().data());
return;
}
//----- Set up the Menu Bar -----//
Gtk::Widget* menu_bar = uiManager->get_widget("/MenuBar");
ASSERT(menu_bar != NULL);
base_container.pack_start(*menu_bar, Gtk::PACK_SHRINK);
//----- Set up the Tool Bar -----//
Gtk::Toolbar* toolbar = dynamic_cast<Gtk::Toolbar*>(uiManager->get_widget("/ToolBar"));
ASSERT(toolbar != NULL);
toolbar->set_toolbar_style(TOOLBAR_ICONS);
base_container.pack_start(*toolbar, Gtk::PACK_SHRINK);
//----- Create the Panels -----//
assets_panel = new AssetsPanel();
ENSURE(assets_panel != NULL);
viewer_panel = new ViewerPanel();
ENSURE(viewer_panel != NULL);
timeline_panel = new TimelinePanel();
ENSURE(timeline_panel != NULL);
//----- Create the Dock -----//
dock = Glib::wrap(gdl_dock_new());
layout = gdl_dock_layout_new((GdlDock*)dock->gobj());
dockbar = Glib::wrap(gdl_dock_bar_new ((GdlDock*)dock->gobj()));
dock_container.pack_start(*dockbar, PACK_SHRINK);
dock_container.pack_end(*dock, PACK_EXPAND_WIDGET);
base_container.pack_start(dock_container, PACK_EXPAND_WIDGET);
gdl_dock_add_item ((GdlDock*)dock->gobj(), assets_panel->get_dock_item(), GDL_DOCK_LEFT);
gdl_dock_add_item ((GdlDock*)dock->gobj(), viewer_panel->get_dock_item(), GDL_DOCK_RIGHT);
gdl_dock_add_item ((GdlDock*)dock->gobj(), timeline_panel->get_dock_item(), GDL_DOCK_BOTTOM);
// Manually dock and move around some of the items
gdl_dock_item_dock_to (timeline_panel->get_dock_item(),
assets_panel->get_dock_item(), GDL_DOCK_BOTTOM, -1);
gdl_dock_item_dock_to (viewer_panel->get_dock_item(),
assets_panel->get_dock_item(), GDL_DOCK_RIGHT, -1);
show_all_children();
gchar ph1[] = "ph1";
gdl_dock_placeholder_new (ph1, (GdlDockObject*)dock->gobj(), GDL_DOCK_TOP, FALSE);
gchar ph2[] = "ph2";
gdl_dock_placeholder_new (ph2, (GdlDockObject*)dock->gobj(), GDL_DOCK_BOTTOM, FALSE);
gchar ph3[] = "ph3";
gdl_dock_placeholder_new (ph3, (GdlDockObject*)dock->gobj(), GDL_DOCK_LEFT, FALSE);
gchar ph4[] = "ph4";
gdl_dock_placeholder_new (ph4, (GdlDockObject*)dock->gobj(), GDL_DOCK_RIGHT, FALSE);
}
} // namespace workspace
} // namespace gui
} // namespace lumiera

View file

@ -0,0 +1,98 @@
/*
workspace-window.hpp - Definition of the main workspace window object
Copyright (C) Lumiera.org
2008, Joel Holdsworth <joel@airwebreathe.org.uk>
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 2 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, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/** @file workspace-window.hpp
** This file contains the definition of the main workspace window
** parent, which is the toplevel parent of the whole workspace.
**
** @see actions.hpp
*/
#ifndef WORKSPACE_WINDOW_HPP
#define WORKSPACE_WINDOW_HPP
#include <gtkmm.h>
#include <libgdl-1.0/gdl/gdl-dock-layout.h>
#include "actions.hpp"
#include "../panels/assets-panel.hpp"
#include "../panels/viewer-panel.hpp"
#include "../panels/timeline-panel.hpp"
using namespace lumiera::gui::panels;
namespace lumiera {
namespace gui {
namespace model {
class Project;
} // model
namespace workspace {
/**
* The main lumiera workspace window
*/
class WorkspaceWindow : public Gtk::Window
{
public:
WorkspaceWindow(lumiera::gui::model::Project *source_project);
virtual ~WorkspaceWindow();
private:
void create_ui();
/* ===== Model ===== */
private:
lumiera::gui::model::Project *project;
/* ===== UI ===== */
private:
Glib::RefPtr<Gtk::UIManager> uiManager;
Gtk::VBox base_container;
Gtk::HBox dock_container;
Gtk::Widget *dock;
Gtk::Widget *dockbar;
GdlDockLayout *layout;
/* ===== Panels ===== */
private:
AssetsPanel *assets_panel;
ViewerPanel *viewer_panel;
TimelinePanel *timeline_panel;
/* ===== Helpers ===== */
private:
/**
* The instantiation of the actions helper class, which
* registers and handles user action events */
Actions actions;
friend class Actions;
};
} // namespace workspace
} // namespace gui
} // namespace lumiera
#endif // WORKSPACE_WINDOW_HPP

View file

@ -32,6 +32,7 @@ liblumi_a_SOURCES = \
$(liblumi_a_srcdir)/safeclib.c \
$(liblumi_a_srcdir)/cuckoo.c \
$(liblumi_a_srcdir)/mrucache.c \
$(liblumi_a_srcdir)/time.c \
$(liblumi_a_srcdir)/appconfig.cpp
noinst_HEADERS += \
@ -46,5 +47,7 @@ noinst_HEADERS += \
$(liblumi_a_srcdir)/safeclib.h \
$(liblumi_a_srcdir)/cuckoo.h \
$(liblumi_a_srcdir)/mrucache.h \
$(liblumi_a_srcdir)/time.h \
$(liblumi_a_srcdir)/appconfig.hpp \
$(liblumi_a_srcdir)/lifecycleregistry.hpp

55
src/lib/time.c Normal file
View file

@ -0,0 +1,55 @@
/*
time.c - Utilities for handling time
Copyright (C) Lumiera.org
2008, Christian Thaeter <ct@pipapo.org>
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 2 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, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <nobug.h>
#include "lib/time.h"
#include "lib/safeclib.h"
char*
lumiera_tmpbuf_print_time (gavl_time_t time)
{
int milliseconds, seconds, minutes, hours;
int negative;
if(time < 0)
{
negative = 1;
time = -time;
}
else negative = 0;
time /= GAVL_TIME_SCALE / 1000;
milliseconds = time % 1000;
time /= 1000;
seconds = time % 60;
time /= 60;
minutes = time % 60;
time /= 60;
hours = time;
char *buffer = lumiera_tmpbuf_snprintf(64, "%s%02d:%02d:%02d.%03d",
negative ? "-" : "", hours, minutes, seconds, milliseconds);
ENSURE(buffer != NULL);
return buffer;
}

38
src/lib/time.h Normal file
View file

@ -0,0 +1,38 @@
/*
time.h - Utilities for handling time
Copyright (C) Lumiera.org
2008, Christian Thaeter <ct@pipapo.org>
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 2 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, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef LUMIERA_TIME_H
#define LUMIERA_TIME_H
#include <inttypes.h>
#include <gavl/gavl.h>
/**
* Formats a time in a safeclib tmpbuf in HH:MM:SS:mmm format.
* @param size maximal length for the string
* @param the time value to print
* @return safeclib temporary buffer containing the constructed of the string
*/
char*
lumiera_tmpbuf_print_time (gavl_time_t time);
#endif

View file

@ -25,9 +25,8 @@ liblumiproc_a_CXXFLAGS = $(CXXFLAGS) -Wall
liblumiproc_a_CPPFLAGS = -I$(top_srcdir)/src/
liblumiproc_a_SOURCES = \
$(liblumiproc_a_srcdir)/controllerfacade.cpp \
$(liblumiproc_a_srcdir)/frame.cpp \
$(liblumiproc_a_srcdir)/stateproxy.cpp \
$(liblumiproc_a_srcdir)/controllerfacade.cpp \
$(liblumiproc_a_srcdir)/state.cpp \
$(liblumiproc_a_srcdir)/asset.cpp \
$(liblumiproc_a_srcdir)/assetmanager.cpp \
$(liblumiproc_a_srcdir)/nobugcfg.cpp
@ -66,25 +65,19 @@ liblumiprocengine_a_CXXFLAGS = $(CXXFLAGS) -Wall
liblumiprocengine_a_CPPFLAGS = -I$(top_srcdir)/src/
liblumiprocengine_a_SOURCES = \
$(liblumiprocengine_a_srcdir)/aframe.cpp \
$(liblumiprocengine_a_srcdir)/arender.cpp \
$(liblumiprocengine_a_srcdir)/codecadapter.cpp \
$(liblumiprocengine_a_srcdir)/exitnode.cpp \
$(liblumiprocengine_a_srcdir)/glbuf.cpp \
$(liblumiprocengine_a_srcdir)/glpipe.cpp \
$(liblumiprocengine_a_srcdir)/glrender.cpp \
$(liblumiprocengine_a_srcdir)/hub.cpp \
$(liblumiprocengine_a_srcdir)/buffhandle.cpp \
$(liblumiprocengine_a_srcdir)/link.cpp \
$(liblumiprocengine_a_srcdir)/mask.cpp \
$(liblumiprocengine_a_srcdir)/nodefactory.cpp \
$(liblumiprocengine_a_srcdir)/nodewiring.cpp \
$(liblumiprocengine_a_srcdir)/pluginadapter.cpp \
$(liblumiprocengine_a_srcdir)/processor.cpp \
$(liblumiprocengine_a_srcdir)/procnode.cpp \
$(liblumiprocengine_a_srcdir)/projector.cpp \
$(liblumiprocengine_a_srcdir)/renderengine.cpp \
$(liblumiprocengine_a_srcdir)/source.cpp \
$(liblumiprocengine_a_srcdir)/trafo.cpp \
$(liblumiprocengine_a_srcdir)/vframe.cpp \
$(liblumiprocengine_a_srcdir)/vrender.cpp
$(liblumiprocengine_a_srcdir)/source.cpp \
$(liblumiprocengine_a_srcdir)/stateproxy.cpp \
$(liblumiprocengine_a_srcdir)/trafo.cpp
@ -113,7 +106,7 @@ liblumiprocmobjectbuilder_a_CPPFLAGS = -I$(top_srcdir)/src/
liblumiprocmobjectbuilder_a_SOURCES = \
$(liblumiprocmobjectbuilder_a_srcdir)/assembler.cpp \
$(liblumiprocmobjectbuilder_a_srcdir)/conmanager.cpp \
$(liblumiprocmobjectbuilder_a_srcdir)/nodecreatertool.cpp \
$(liblumiprocmobjectbuilder_a_srcdir)/nodecreatortool.cpp \
$(liblumiprocmobjectbuilder_a_srcdir)/segmentationtool.cpp \
$(liblumiprocmobjectbuilder_a_srcdir)/toolfactory.cpp
@ -125,8 +118,7 @@ liblumiprocmobjectcontroller_a_CXXFLAGS = $(CXXFLAGS) -Wall
liblumiprocmobjectcontroller_a_CPPFLAGS = -I$(top_srcdir)/src/
liblumiprocmobjectcontroller_a_SOURCES = \
$(liblumiprocmobjectcontroller_a_srcdir)/pathmanager.cpp \
$(liblumiprocmobjectcontroller_a_srcdir)/renderstate.cpp
$(liblumiprocmobjectcontroller_a_srcdir)/pathmanager.cpp
liblumiprocmobjectsession_a_srcdir = $(top_srcdir)/src/proc/mobject/session
@ -139,9 +131,12 @@ liblumiprocmobjectsession_a_SOURCES = \
$(liblumiprocmobjectsession_a_srcdir)/abstractmo.cpp \
$(liblumiprocmobjectsession_a_srcdir)/allocation.cpp \
$(liblumiprocmobjectsession_a_srcdir)/auto.cpp \
$(liblumiprocmobjectsession_a_srcdir)/compoundclip.cpp \
$(liblumiprocmobjectsession_a_srcdir)/clip.cpp \
$(liblumiprocmobjectsession_a_srcdir)/compoundclip.cpp \
$(liblumiprocmobjectsession_a_srcdir)/constraint.cpp \
$(liblumiprocmobjectsession_a_srcdir)/defsmanager.cpp \
$(liblumiprocmobjectsession_a_srcdir)/effect.cpp \
$(liblumiprocmobjectsession_a_srcdir)/fixedlocation.cpp \
$(liblumiprocmobjectsession_a_srcdir)/fixedlocation.cpp \
$(liblumiprocmobjectsession_a_srcdir)/label.cpp \
$(liblumiprocmobjectsession_a_srcdir)/meta.cpp \
$(liblumiprocmobjectsession_a_srcdir)/relativelocation.cpp \
@ -153,9 +148,6 @@ liblumiprocmobjectsession_a_SOURCES = \
$(liblumiprocmobjectsession_a_srcdir)/edl.cpp \
$(liblumiprocmobjectsession_a_srcdir)/session.cpp \
$(liblumiprocmobjectsession_a_srcdir)/track.cpp \
$(liblumiprocmobjectsession_a_srcdir)/clip.cpp \
$(liblumiprocmobjectsession_a_srcdir)/constraint.cpp \
$(liblumiprocmobjectsession_a_srcdir)/defsmanager.cpp \
$(liblumiprocmobjectsession_a_srcdir)/fixture.cpp \
$(liblumiprocmobjectsession_a_srcdir)/locatingpin.cpp \
$(liblumiprocmobjectsession_a_srcdir)/mobjectfactory.cpp \
@ -243,7 +235,6 @@ noinst_HEADERS += \
$(liblumiproc_a_srcdir)/mobject/mobject.hpp \
$(liblumiproc_a_srcdir)/mobject/placement.hpp \
$(liblumiproc_a_srcdir)/mobject/session.hpp \
$(liblumiproc_a_srcdir)/stateproxy.hpp \
$(liblumiproc_a_srcdir)/asset.hpp \
$(liblumiproc_a_srcdir)/assetmanager.hpp \
$(liblumiproc_a_srcdir)/lumiera.hpp \

View file

@ -32,7 +32,7 @@
#include "common/p.hpp"
#include "common/util.hpp"
#include "common/time.hpp"
#include "common/lumitime.hpp"
#include "common/error.hpp" ///< pulls in NoBug via nobugcfg.hpp
#include "lib/appconfig.hpp"

View file

@ -21,7 +21,7 @@
* *****************************************************/
#include "proc/mobject/builder/nodecreatertool.hpp"
#include "proc/mobject/builder/nodecreatortool.hpp"
#include "proc/mobject/session/clip.hpp"
#include "proc/mobject/session/effect.hpp"
#include "proc/mobject/session/auto.hpp"

View file

@ -29,7 +29,7 @@
#include "common/factory.hpp"
//#include "common/util.hpp"
#include <boost/algorithm/string.hpp>
#include <boost/algorithm/string/join.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/format.hpp>
#include <iostream>

View file

@ -747,19 +747,19 @@ config.macros.timeline.handler = function(place,macroName,params,wikifier,paramS
}
//}}}</pre>
</div>
<div title="BuildDependencies" modifier="Ichthyostega" modified="200804120311" created="200803261326" changecount="7">
<div title="BuildDependencies" modifier="Ichthyostega" modified="200807110148" created="200803261326" changecount="13">
<pre>! Programming Languages
* C
** a C99 compatible compiler, some GCC extensions are used, most are optional.
* C++
** C++98
** std::tr1 (for &lt;std::tr1::memory&gt;)
** BOOST ~~(below are the DEBIAN package names)~~
*** libboost-dev (=1.34.1-2)
*** libboost-program-options-dev (=1.34.1-2)
*** libboost-program-options1.34.1 (=1.34.1-2) ''NOTE: binary lib dependency''
*** libboost-regex-dev (=1.34.1-2)
*** libboost-regex1.34.1 (=1.34.1-2) ''binary lib depenency''
* BOOST ~~(listed below are the DEBIAN package names)~~
** libboost-dev (&gt;=1.34.1-2)
** libboost-program-options-dev (&gt;=1.34.1-2)
** libboost-program-options1.34.1 (&gt;=1.34.1-2) ''NOTE: binary dependency''
** libboost-regex-dev (&gt;=1.34.1-2)
** libboost-regex1.34.1 (&gt;=1.34.1-2) ''binary..''
** //usually, newer versions are OK//
* bash
@ -769,7 +769,8 @@ config.macros.timeline.handler = function(place,macroName,params,wikifier,paramS
* autotools
* SCons
** //need either autotools or scons//
** SCons (0.96.90), Python (2.3)
** SCons (0.96), Python (2.4)
** pkg-config
* Doxygen
* test.sh (included)
@ -778,9 +779,18 @@ config.macros.timeline.handler = function(place,macroName,params,wikifier,paramS
* bouml
! Libraries
* boost (see above)
* boost (see above, version 1.35 works too)
* NoBug
* gavl
* [[GAVL|http://gmerlin.sourceforge.net/gavl.html]] (1.0.0)
* for the GUI: gtkmm-2.4 gdl-1.0 cairomm-1.0 xv
** libgtkmm-2.4-dev (&gt;=2.8)
** libcairomm-1.0-dev (&gt;=0.6.0)
** libgdl-1-dev (&gt;=0.6.1)
*** libbonoboui2-dev (&gt;=2.14.0)
** libxv-dev ~~(1.0.2 is known to work)~~
//usually, newer versions are OK//
</pre>
</div>
<div title="ColorPalette" modifier="CehTeh" modified="200803261254" created="200803261252" changecount="5">

View file

@ -759,21 +759,30 @@ config.macros.timeline.handler = function(place,macroName,params,wikifier,paramS
}
//}}}</pre>
</div>
<div title="BuildDependenceis" modifier="Ichthyostega" modified="200708210341" created="200708120103" tags="organization buildsys" changecount="7">
<div title="BuildDependenceis" modifier="Ichthyostega" modified="200807110146" created="200708120103" tags="organization buildsys" changecount="15">
<pre>for __Building__
* gcc (4.1), glibc6 (2.3), libstdc++6 (4.1)
* [[build system|BuildSystem]] dependencies: SCons (0.96.90), Python (2.3)
* [[build system|BuildSystem]] dependencies: SCons (0.96.90), Python (2.4), pkg-config
* [[GAVL|http://gmerlin.sourceforge.net/gavl.html]] (1.0.0)
* NoBug for Logging, Tracing, Asserting (can be obtained from [[Pipapo.org|http://www.pipapo.org/pipawiki/NoBug]])
* ~NoBug needs [[valgrind|Valgrind]] (3.2), execinfo.h and libpthread (&amp;rarr; glibc)
* std::tr1 &amp;mdash; esp. for the former BOOST::shared_ptr (which is now proposed standard)
* BOOST ~~(below are the DEBIAN package names)~~
** libboost-dev (=1.34.1-2)
** libboost-program-options-dev (=1.34.1-2)
** libboost-program-options1.34.1 (=1.34.1-2) ''NOTE: binary dependency''
** libboost-regex-dev (=1.34.1-2)
** libboost-regex1.34.1 (=1.34.1-2) ''binary..''
* BOOST ~~(listed below are the DEBIAN package names)~~
** libboost-dev (&gt;=1.34.1-2)
** libboost-program-options-dev (&gt;=1.34.1-2)
** libboost-program-options1.34.1 (&gt;=1.34.1-2) ''NOTE: binary dependency''
** libboost-regex-dev (&gt;=1.34.1-2)
** libboost-regex1.34.1 (&gt;=1.34.1-2) ''binary..''
* for the GUI: gtkmm-2.4 gdl-1.0 cairomm-1.0 xv
** libgtkmm-2.4-dev (&gt;=2.8)
** libcairomm-1.0-dev (&gt;=0.6.0)
** libgdl-1-dev (&gt;=0.6.1)
*** libbonoboui2-dev (&gt;=2.14.0)
** libxv-dev (&gt;=1.0.2)
//usually, newer versions are OK//
boost 1.35 works too.
for __Running__</pre>
</div>
<div title="BuildSystem" modifier="Ichthyostega" modified="200708120101" created="200708051532" tags="organization buildsys" changecount="4">
@ -942,9 +951,10 @@ git push git://git.pipapo.org/lumiera/mob
lumiera/mob is an anonymous account at pipapo.org where everyone can commit changes. </pre>
</div>
<div title="IRC-Transcripts" modifier="Ichthyostega" modified="200806211625" created="200708120209" tags="discuss irclog" changecount="10">
<div title="IRC-Transcripts" modifier="Ichthyostega" modified="200807072122" created="200708120209" tags="discuss irclog" changecount="11">
<pre>We keep a protocol or short summary of each important discussion. The summaries of the monthly developer meetings are posted to the Mailinglist and can be found on pipapo.org too
* [[06-08 developer meeting 5.Jun.2008|IRC_2008-06-05]]
* [[05-08 developer meeting 8.May.2008|IRC_2008-05-08]]
* [[04-08 developer meeting 3.Apr.2008|IRC_2008-04-03]]
* [[03-08 developer meeting 6.Mar.2008|IRC_2008-03-06]]
@ -952,7 +962,8 @@ lumiera/mob is an anonymous account at pipapo.org where everyone can commit chan
* [[informal developer meeting 10.Aug.2007|IRC_2007-08-10]]
!talks about specific topics
* [[buffer allocation for render nodes (6/08)|IRC_log_BufferAllocation_2008-06]]</pre>
* [[buffer allocation for render nodes (6/08)|IRC_log_BufferAllocation_2008-06]]
</pre>
</div>
<div title="IRC_2007-08-10" modifier="Ichthyostega" created="200802021815" tags="irclog" changecount="1">
<pre>!10/11 aug 2007
@ -1590,6 +1601,75 @@ Ichthyo explains that the builder needs to detect cycles and check if the high l
Next meeting is on thursday 5th June 21:00 UTC
</pre>
</div>
<div title="IRC_2008-06-05" modifier="Ichthyostega" modified="200807072133" created="200807072132" tags="irclog excludeMissing" changecount="2">
<pre>! 5.June 2008 on #lumiera
21:00 -23:15 UTC. __Participants__:
* cehteh
* ichthyo
* joelholdsworth
* rcbarnes
* raffa
//Protocol written by ichthyo//
! Left over from the last meeting
//Nothing left over and no urgent topics.//
Seemingly, work is proceeding in all parts of the application.
! Discuss Ideas and Drafts in design process
//There are no new design proposals and no proposals that can be finalized.//
Ichthyo points out that he's about to work out the details of some of his proposals, which are currently in &quot;idea&quot; state. Following that, most of the meeting is spent on discussing the details of two of these proposals.
!!! Idea: Design the Render Nodes interface
[[Design of the render nodes interface|http://www.pipapo.org/pipawiki/Lumiera/DesignProcess/DesignRenderNodesInterface]]
''Cehteh'' points out that, as we are in the pre-alpha phase, interfaces may be growing on-demand. Later on, interface versions will be numbered. If needed, we could add a special &quot;draft&quot; or &quot;experimental&quot; tag, or, alternatively, use the common numbering scheme, where odd major version numbers denote the development line of an interface.
''Ichthyo'' agrees, but adds he also meant &quot;interface&quot; in this proposal in a wider sense, like in &quot;what do we need and require from a processing node&quot;. Knowing how generally Lumiera will handle the processing nodes while rendering helps him with defining and implementing the builder
__Conclusion__: &quot;currently in work&quot;. For now, grow interfaces on demand.
-----
!!! Idea: Placement Metaphor used within the high-level view of Proc-Layer
[[Placement Metaphor in the Proc-Layer|http://www.pipapo.org/pipawiki/Lumiera/DesignProcess/ProcPlacementMetaphor]]
In the course of the discussion, ''Ichthyo'' explains the rationale
* one common mechanism for sticking objects together and putting them into the session
* either specify the &quot;placement&quot;-parameters (time, output destination, track) directly, link to another object's parameters, or derive some or all of those values from the context (up the tree of tracks)
* ability to build a system of high-level media objects (clips, effects...) which re-adjust automatically on change
* extensible to handle or derive some parameters based on conditions and rules, e.g. for semi-automatic wiring of the output destination based on tags
''Joelholdsworth'' is concerned that this proposal may go too far and tries to tie things together which aren't really connected. While basically it's no problem having the time position of a clip either absolute, or derived by a link to another object, he can't see a clear benefit of controlling sound pan or video layer order from the placement. Pan, for example, is just an parameter value or interpolated curve, similar to colour correction or gamma adjustment. For the gui, he points out, it's probably better to stick to the object metaphor, so start time, output, layer number or sound pan would be properties of the object.
But that's exactly what Ichthyo wants to avoid. Obviously, this would be the standard solution employed by most current editing apps, and works reasonably well in average cases. But he is looking for a solution which covers this standard case, but also doesn't get into the way when dealing with advanced compositing, working with spatial sound systems (Ambisonics, Wave Field Synthesis) or stereoscopic (3D) video.
//On the whole, there is no conclusion yet.// Certainly, this proposal needs more discussion, parts need to be defined much more clear (esp. the &quot;Pro&quot; arguments), maybe parts of the functionality should be separated out.
While in this discussion, several aspects of the cooperation of GUI and Proc layer are considered.
* it is not necessary to make all of the Placement proposal visible to the GUI (and the user). Proc layer may as well provide a simplyfied and hard wired API for the most common properties (layer index, pan) and only use this part of the Placement concept for building and wiring the nodes.
* the adjustment of objects linked together by a placement can be handled as follows:
*# GUI notifies Proc of a position/parameter change of one object and gets immediate, synchronous feedback (OK or fail)
*# Proc detects the other linked objects affected by the change and notifies GUI (both synchronous and asynchronous is possible) to update information regarding those objects
*# GUI pulls the necessary properties by calling Proc on a per object base.
* as a rule of thumb, GUI &lt;-&gt; Proc is mostly synchronous, while Backend &lt;-&gt; GUI is often asynchronous, but there are exceptions from the rule
* we have general //parameters//, which are automatible. These are represented as //control data connections between the nodes.// We certainly don't want to represent some things in this way, though. For example, the in/out points of clips are fixed values.
* in Ichthyo's concept, the Placement doesn't itself provide such parameter values/sources, rather it can be used to //find// or //derive// parameter sources.
* the node graph is built bottom up, starting at the source, then via the effects attached locally to a clip, further on upwards (directed by the tree of tracks) to be finally connected via global busses to the output ports. Rendering pulls from these output ports.
* Joelholdsworth, Cehteh, Ichthyo and Rcbarnes agree that the plain //node-editor// approach is problematic in the context of a NLE. It shows too much details and fails to capture the temporal aspect. We strive at having node-like features and flexibility, but rather within the timeline.
* especially, the topology of the node graph isn't constant over the whole timeline. But it's the job of the builder in the Proc layer to deal with these complexities, the user shouldn't be overwhelmed with all those details.
-----
! Next meeting
* some people in europe complained that 21:00 UTC is too late, esp. with daylight saving
* there was the proposal to alternate between the current schedule, and sunday 16:00 UTC
* but Joel can't attend on sunday afternoon for now
* so we settle down on thursday, 16:30
Next meeting: ''Thursday 3.July 2008 16:30 UTC''
</pre>
</div>
<div title="IRC_log_BufferAllocation_2008-06" modifier="Ichthyostega" created="200806211624" tags="irclog excludeMissing" changecount="1">
<pre>! 5.June 2008 on #lumiera
__cehteh__ and __ichthyo__

View file

@ -1889,18 +1889,18 @@ So, when creating a clip out of such a compound media asset, the clip has to be
<div title="NodeCreaterTool" modifier="Ichthyostega" created="200712100626" tags="def" changecount="1">
<pre>NodeCreaterTool is a [[visiting tool|VisitorUse]] used as second step in the [[Builder]]. Starting out from a [[Fixture]], the builder first [[divides the Timeline into segments|SegmentationTool]] and then processes each segment with the NodeCreaterTool to build a render nodes network (Render Engine) for this part of the timeline. While visiting individual Objects and Placements, the NodeCreaterTool creates and wires the necessary [[nodes|ProcNode]]</pre>
</div>
<div title="NodeOperationProtocol" modifier="Ichthyostega" modified="200806220134" created="200806010251" tags="Rendering dynamic" changecount="11">
<div title="NodeOperationProtocol" modifier="Ichthyostega" modified="200807072147" created="200806010251" tags="Rendering dynamic" changecount="15">
<pre>The [[nodes|ProcNode]] are wired to form a &quot;Directed Acyclic Graph&quot;; each node knows its predecessor(s), but not its successor(s). The RenderProcess is organized according to the ''pull principle'', thus we find an operation {{{pull()}}} at the core of this process. There is no such thing as an &quot;engine object&quot; calling nodes iteratively or table driven, rather, the nodes themselves issue recursive calls to their predecessor(s). For this to work, we need the nodes to adhere to a specific protocol:
# Node is pulled, with a StateProxy object as parameter (encapsulating the access to the frames or buffers)
# Node may now access current parameter values, using the state accessible via the StateProxy
# using it's //input-output descriptor,// the Node creates a StateAdapter wrapping the StateProxy for accessing the output to pull and probably the input needed to calculate this output
# using it's //input-output and wiring descriptor,// the Node creates a StateAdapter wrapping the StateProxy for allocating buffers and accessing the required input
# StateAdapter first tries to get the output frames from the Cache in the Backend. In case of failure, a {{{process()}}} call is prepared by generating {{{pull()}}} call(s) for the input
# as late as possible, typically on return, these recursive pull-calls have allocated a buffer containing the input data.
# after all input is ready and prior to the {{{process()}}} call, the output buffers will be allocated, either from the cache, or alternatively (if not caching) from the &quot;parent&quot; StateAdapter up the callstack.
# when input is ready prior to the {{{process()}}} call, output buffers will be allocated, either from the cache, or (if not caching) from the &quot;parent&quot; StateAdapter up the callstack.
# after all buffers are available, the StateAdapter issues the {{{process()}}} call back to the originating node, which now may dereference the frame pointers and do its calculations
# finally, when the {{{pull()}}} call returns, &quot;parent&quot; state originating the pull holds onto the buffers containing the calculated output result.
some points to note:
* the input descriptor is {{{const}}} and precalculated while building (remember another thread may call in parallel)
* the WiringDescriptor is {{{const}}} and precalculated while building (remember another thread may call in parallel)
* when a node is &quot;inplace-capable&quot;, input and output buffer may actually point to the same location
* but there is no guarantee for this to happen, because the cache may be involved (and we can't overwrite the contents of a cache frame)
* generally, a node may have N inputs and M output frames, which are expected to be processed in a single call
@ -2757,12 +2757,13 @@ Besides, they provide an important __inward interface__ for the [[ProcNode]]s, w
</pre>
</div>
<div title="ProcLayer and Engine" modifier="Ichthyostega" modified="200805250304" created="200706190056" tags="overview" changecount="10">
<div title="ProcLayer and Engine" modifier="Ichthyostega" modified="200807072140" created="200706190056" tags="overview" changecount="11">
<pre>The Render Engine is the part of the application doing the actual video calculations. Its operations are guided by the Objects and Parameters edited by the user in [[the EDL|EDL]] and it retrieves the raw audio and video data from the [[Data backend|backend.html]]. Because the inner workings of the Render Engine are closely related to the structures used in the EDL, this design covers [[the aspect of objects placed into the EDL|MObjects]] as well.
&lt;&lt;&lt;
''Status'': started out as design draft in summer '07, Ichthyo is now in the middle of a implementing the foundations and main structures in C++
* basic AssetManager working
* currently impmenenting the Builder (&amp;rarr;[[more|PlanningNodeCreatorTool]])
* basic [[AssetManager]] working
* [[Builder]] implementation is on the way (&amp;rarr;[[more|BuilderPrimitives]])
* made a first draft of how to wire and operate procesing nodes (&amp;rarr;[[more|RenderMechanics]])
&lt;&lt;&lt;
!Summary
@ -4660,7 +4661,7 @@ Because of this experience, ichthyo wants to support a more general case of tran
</div>
<div title="VirtualClip" modifier="Ichthyostega" modified="200808160257" created="200804110321" tags="def" changecount="13">
<pre>A ''~Meta-Clip'' or ''Virtual Clip'' (both are synonymous) denotes a clip which doesn't just pull media streams out of a source media asset, but rather provides the results of rendering a complete sub-network. In all other respects it behaves exactly like a &quot;real&quot; clip, i.e. it has [[source ports|ClipSourcePort]], can have attached effects (thus forming a local render pipe) and can be placed and combined with other clips. Depending on what is wired to the source ports, we get two flavours:
* a __placeholder clip__; has no &quot;embedded&quot; content. Rather, by virtue of placements and wiring requests, the output of some other pipe somewhere in the session will be wired to the clip's source ports. Thus, pulling data from this clip will effectively pull from these source pipes wired to it.
* a __placeholder clip__ has no &quot;embedded&quot; content. Rather, by virtue of placements and wiring requests, the output of some other pipe somewhere in the session will be wired to the clip's source ports. Thus, pulling data from this clip will effectively pull from these source pipes wired to it.
* a __nested EDL __ is like the other ~EDLs in the Session, just that any missing placement properties will be derived from the Virtual Clip, which is thought as to &quot;contain&quot; the objects of the nested EDL. Typically, this also [[configures the tracks|TrackHandling]] of the &quot;inner&quot; EDL such as to connect any output to the source ports of the Virtual Clip.
Like any &quot;real&quot; clip, Virtual Clips have a start offset and a length, which will simply translate into an offset of the frame number pulled from the Virtual Clip's source connection or embedded EDL, making it possible to cut, splice, trim and roll them as usual. This of course implies we can have several instances of the same virtual clip with different start offset and length placed differently. The only limitation is that we can't handle cyclic dependencies for pulling data (which has to be detected and flagged as an error by the builder)