Merge GUI loading and startup, incl opening of facade interface
This commit is contained in:
commit
e64e9a19b6
51 changed files with 5370 additions and 1007 deletions
|
|
@ -1,6 +1,7 @@
|
|||
AC_INIT(lumiera, 0.1pre)
|
||||
AC_CONFIG_SRCDIR(src/lib/luid.c)
|
||||
AC_CONFIG_AUX_DIR(scripts)
|
||||
AC_CONFIG_SRCDIR([src/lib/luid.c])
|
||||
AC_CONFIG_AUX_DIR([scripts])
|
||||
AC_CONFIG_MACRO_DIR([m4])
|
||||
AM_INIT_AUTOMAKE
|
||||
AC_PREREQ(2.59)
|
||||
|
||||
|
|
@ -123,7 +124,7 @@ AC_CHECK_HEADER([boost/regex.hpp],
|
|||
|
||||
AC_LANG_POP([C++])
|
||||
|
||||
PKG_CHECK_MODULES(LUMIERA_COMMON_LIBS, [sigc++-2.0 >= 2.0.18])
|
||||
PKG_CHECK_MODULES(LUMIERA_COMMON_LIBS, [sigc++-2.0 >= 2.0.17])
|
||||
|
||||
############## Internatinalization
|
||||
#GETTEXT_PACKAGE=gtk-lumiera
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@ iconcommand = python $(top_srcdir)/admin/render-icon.py
|
|||
48x48pre = $(prerendereddir)/48x48
|
||||
|
||||
dist_pkgdata_DATA += \
|
||||
$(16x16)/app-icon.png $(22x22)/app-icon.png $(24x24)/app-icon.png $(32x32)/app-icon.png $(48x48)/app-icon.png \
|
||||
$(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)/track-disabled.png \
|
||||
|
|
@ -48,6 +49,11 @@ clean-local:
|
|||
|
||||
# ========== SVG Icons ==========
|
||||
|
||||
# App Icon
|
||||
|
||||
$(16x16)/app-icon.png $(22x22)/app-icon.png $(24x24)/app-icon.png $(32x32)/app-icon.png $(48x48)/app-icon.png : $(svgdir)/app-icon.svg $(top_builddir)/rsvg-convert
|
||||
$(iconcommand) $< $(icondir)
|
||||
|
||||
# Timeline Tools
|
||||
|
||||
$(16x16)/tool-arrow.png $(22x22)/tool-arrow.png $(24x24)/tool-arrow.png $(32x32)/tool-arrow.png $(48x48)/tool-arrow.png : $(svgdir)/tool-arrow.svg $(top_builddir)/rsvg-convert
|
||||
|
|
|
|||
903
icons/svg/app-icon.svg
Normal file
903
icons/svg/app-icon.svg
Normal file
|
|
@ -0,0 +1,903 @@
|
|||
<?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="app-icon.svg"
|
||||
inkscape:output_extension="org.inkscape.output.svg.inkscape">
|
||||
<defs
|
||||
id="defs4">
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
id="linearGradient10047">
|
||||
<stop
|
||||
style="stop-color:#555753;stop-opacity:1"
|
||||
offset="0"
|
||||
id="stop10049" />
|
||||
<stop
|
||||
style="stop-color:#eeeeec;stop-opacity:1"
|
||||
offset="1"
|
||||
id="stop10051" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
id="linearGradient10027">
|
||||
<stop
|
||||
style="stop-color:#555753;stop-opacity:1"
|
||||
offset="0"
|
||||
id="stop10029" />
|
||||
<stop
|
||||
id="stop10045"
|
||||
offset="0.82309282"
|
||||
style="stop-color:#555753;stop-opacity:1" />
|
||||
<stop
|
||||
id="stop10035"
|
||||
offset="0.92868489"
|
||||
style="stop-color:#d3d7cf;stop-opacity:1" />
|
||||
<stop
|
||||
style="stop-color:#000000;stop-opacity:0;"
|
||||
offset="1"
|
||||
id="stop10031" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
id="linearGradient9856">
|
||||
<stop
|
||||
style="stop-color:#888a85;stop-opacity:1"
|
||||
offset="0"
|
||||
id="stop9858" />
|
||||
<stop
|
||||
id="stop9864"
|
||||
offset="0.04709055"
|
||||
style="stop-color:#888a85;stop-opacity:1" />
|
||||
<stop
|
||||
style="stop-color:#555753;stop-opacity:1"
|
||||
offset="0.23050508"
|
||||
id="stop9874" />
|
||||
<stop
|
||||
style="stop-color:#555753;stop-opacity:1"
|
||||
offset="1"
|
||||
id="stop9860" />
|
||||
</linearGradient>
|
||||
<inkscape:perspective
|
||||
sodipodi:type="inkscape:persp3d"
|
||||
inkscape:vp_x="0 : 50 : 1"
|
||||
inkscape:vp_y="0 : 1000 : 0"
|
||||
inkscape:vp_z="150 : 50 : 1"
|
||||
inkscape:persp3d-origin="75 : 33.333333 : 1"
|
||||
id="perspective59" />
|
||||
<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>
|
||||
<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="#linearGradient10554"
|
||||
id="linearGradient7968"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(1.3333333,0,0,1.3333333,-251.3124,-500.60971)"
|
||||
x1="240.9062"
|
||||
y1="425.18195"
|
||||
x2="248.28683"
|
||||
y2="437.96558" />
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient124"
|
||||
id="radialGradient7971"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(1.1113546,0,0,1.5996493,-273.02082,-503.24197)"
|
||||
cx="307.7507"
|
||||
cy="361.47824"
|
||||
fx="307.7507"
|
||||
fy="361.47824"
|
||||
r="12.509617" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient124"
|
||||
id="linearGradient7974"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(1.0594534,2.447176,-0.611794,0.2648633,-273.02082,-503.24198)"
|
||||
x1="253.75711"
|
||||
y1="-129.52815"
|
||||
x2="252.00447"
|
||||
y2="-135.47408" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient10554"
|
||||
id="linearGradient7986"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(0.7041896,0,0,0.7041896,-40.406443,-220.43015)"
|
||||
x1="240.9062"
|
||||
y1="425.18195"
|
||||
x2="248.28683"
|
||||
y2="437.96558" />
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient124"
|
||||
id="radialGradient7989"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(0.5869533,0,0,0.8448423,-51.871574,-221.82034)"
|
||||
cx="307.7507"
|
||||
cy="361.47824"
|
||||
fx="307.7507"
|
||||
fy="361.47824"
|
||||
r="12.509617" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient124"
|
||||
id="linearGradient7992"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(0.559542,1.292457,-0.3231142,0.1398855,-51.871571,-221.82034)"
|
||||
x1="253.75711"
|
||||
y1="-129.52815"
|
||||
x2="252.00447"
|
||||
y2="-135.47408" />
|
||||
<inkscape:perspective
|
||||
sodipodi:type="inkscape:persp3d"
|
||||
inkscape:vp_x="0 : 0.5 : 1"
|
||||
inkscape:vp_y="0 : 1000 : 0"
|
||||
inkscape:vp_z="1 : 0.5 : 1"
|
||||
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
|
||||
id="perspective16719" />
|
||||
<inkscape:perspective
|
||||
sodipodi:type="inkscape:persp3d"
|
||||
inkscape:vp_x="0 : 0.5 : 1"
|
||||
inkscape:vp_y="0 : 1000 : 0"
|
||||
inkscape:vp_z="1 : 0.5 : 1"
|
||||
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
|
||||
id="perspective16407" />
|
||||
<inkscape:perspective
|
||||
sodipodi:type="inkscape:persp3d"
|
||||
inkscape:vp_x="0 : 0.5 : 1"
|
||||
inkscape:vp_y="0 : 1000 : 0"
|
||||
inkscape:vp_z="1 : 0.5 : 1"
|
||||
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
|
||||
id="perspective16265" />
|
||||
<inkscape:perspective
|
||||
sodipodi:type="inkscape:persp3d"
|
||||
inkscape:vp_x="0 : 0.5 : 1"
|
||||
inkscape:vp_y="0 : 1000 : 0"
|
||||
inkscape:vp_z="1 : 0.5 : 1"
|
||||
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
|
||||
id="perspective16186" />
|
||||
<inkscape:perspective
|
||||
sodipodi:type="inkscape:persp3d"
|
||||
inkscape:vp_x="0 : 0.5 : 1"
|
||||
inkscape:vp_y="0 : 1000 : 0"
|
||||
inkscape:vp_z="1 : 0.5 : 1"
|
||||
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
|
||||
id="perspective11296-84" />
|
||||
<inkscape:perspective
|
||||
sodipodi:type="inkscape:persp3d"
|
||||
inkscape:vp_x="0 : 0.5 : 1"
|
||||
inkscape:vp_y="0 : 1000 : 0"
|
||||
inkscape:vp_z="1 : 0.5 : 1"
|
||||
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
|
||||
id="perspective11296-0" />
|
||||
<inkscape:perspective
|
||||
sodipodi:type="inkscape:persp3d"
|
||||
inkscape:vp_x="0 : 0.5 : 1"
|
||||
inkscape:vp_y="0 : 1000 : 0"
|
||||
inkscape:vp_z="1 : 0.5 : 1"
|
||||
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
|
||||
id="perspective11296-6" />
|
||||
<inkscape:perspective
|
||||
sodipodi:type="inkscape:persp3d"
|
||||
inkscape:vp_x="0 : 0.5 : 1"
|
||||
inkscape:vp_y="0 : 1000 : 0"
|
||||
inkscape:vp_z="1 : 0.5 : 1"
|
||||
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
|
||||
id="perspective11296-9" />
|
||||
<inkscape:perspective
|
||||
sodipodi:type="inkscape:persp3d"
|
||||
inkscape:vp_x="0 : 0.5 : 1"
|
||||
inkscape:vp_y="0 : 1000 : 0"
|
||||
inkscape:vp_z="1 : 0.5 : 1"
|
||||
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
|
||||
id="perspective11296-87" />
|
||||
<inkscape:perspective
|
||||
sodipodi:type="inkscape:persp3d"
|
||||
inkscape:vp_x="0 : 0.5 : 1"
|
||||
inkscape:vp_y="0 : 1000 : 0"
|
||||
inkscape:vp_z="1 : 0.5 : 1"
|
||||
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
|
||||
id="perspective11296-1" />
|
||||
<inkscape:perspective
|
||||
sodipodi:type="inkscape:persp3d"
|
||||
inkscape:vp_x="0 : 0.5 : 1"
|
||||
inkscape:vp_y="0 : 1000 : 0"
|
||||
inkscape:vp_z="1 : 0.5 : 1"
|
||||
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
|
||||
id="perspective11296-8" />
|
||||
<inkscape:perspective
|
||||
sodipodi:type="inkscape:persp3d"
|
||||
inkscape:vp_x="0 : 0.5 : 1"
|
||||
inkscape:vp_y="0 : 1000 : 0"
|
||||
inkscape:vp_z="1 : 0.5 : 1"
|
||||
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
|
||||
id="perspective11296" />
|
||||
<inkscape:perspective
|
||||
sodipodi:type="inkscape:persp3d"
|
||||
inkscape:vp_x="0 : 0.5 : 1"
|
||||
inkscape:vp_y="0 : 1000 : 0"
|
||||
inkscape:vp_z="1 : 0.5 : 1"
|
||||
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
|
||||
id="perspective11217" />
|
||||
<inkscape:perspective
|
||||
sodipodi:type="inkscape:persp3d"
|
||||
inkscape:vp_x="0 : 0.5 : 1"
|
||||
inkscape:vp_y="0 : 1000 : 0"
|
||||
inkscape:vp_z="1 : 0.5 : 1"
|
||||
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
|
||||
id="perspective11140" />
|
||||
<inkscape:perspective
|
||||
id="perspective8731"
|
||||
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
|
||||
inkscape:vp_z="1 : 0.5 : 1"
|
||||
inkscape:vp_y="0 : 1000 : 0"
|
||||
inkscape:vp_x="0 : 0.5 : 1"
|
||||
sodipodi:type="inkscape:persp3d" />
|
||||
<inkscape:perspective
|
||||
id="perspective8641"
|
||||
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
|
||||
inkscape:vp_z="1 : 0.5 : 1"
|
||||
inkscape:vp_y="0 : 1000 : 0"
|
||||
inkscape:vp_x="0 : 0.5 : 1"
|
||||
sodipodi:type="inkscape:persp3d" />
|
||||
<inkscape:perspective
|
||||
id="perspective8229"
|
||||
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
|
||||
inkscape:vp_z="1 : 0.5 : 1"
|
||||
inkscape:vp_y="0 : 1000 : 0"
|
||||
inkscape:vp_x="0 : 0.5 : 1"
|
||||
sodipodi:type="inkscape:persp3d" />
|
||||
<inkscape:perspective
|
||||
id="perspective8322"
|
||||
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
|
||||
inkscape:vp_z="1 : 0.5 : 1"
|
||||
inkscape:vp_y="0 : 1000 : 0"
|
||||
inkscape:vp_x="0 : 0.5 : 1"
|
||||
sodipodi:type="inkscape:persp3d" />
|
||||
<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="perspective9" />
|
||||
<inkscape:path-effect
|
||||
vertical="false"
|
||||
scale_y_rel="false"
|
||||
deactivate_knotholder="false"
|
||||
bendpath-nodetypes="cc"
|
||||
prop_scale="1"
|
||||
is_visible="true"
|
||||
bendpath="m 573.23098,118.10429 c 26.3574,9.12694 57.80555,27.44466 105.31044,26.93611"
|
||||
id="path-effect15992"
|
||||
effect="bend_path" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient9856"
|
||||
id="linearGradient9862"
|
||||
x1="108.5"
|
||||
y1="83.5"
|
||||
x2="108.5"
|
||||
y2="72"
|
||||
gradientUnits="userSpaceOnUse" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient10027"
|
||||
id="linearGradient10033"
|
||||
x1="33"
|
||||
y1="59"
|
||||
x2="33"
|
||||
y2="72"
|
||||
gradientUnits="userSpaceOnUse" />
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient10047"
|
||||
id="radialGradient10055"
|
||||
cx="33.1978"
|
||||
cy="73.593964"
|
||||
fx="33.1978"
|
||||
fy="73.593964"
|
||||
r="23.500003"
|
||||
gradientTransform="matrix(0.8936168,-2.1708241e-7,-6.9085817e-8,0.2127659,3.3338919,55.341721)"
|
||||
gradientUnits="userSpaceOnUse" />
|
||||
</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="1.8667619"
|
||||
inkscape:cx="-40.901668"
|
||||
inkscape:cy="27.979682"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="layer3"
|
||||
showgrid="false"
|
||||
inkscape:snap-nodes="false"
|
||||
inkscape:snap-bbox="false"
|
||||
inkscape:snap-global="true"
|
||||
showguides="true"
|
||||
inkscape:guide-bbox="true"
|
||||
inkscape:window-width="1407"
|
||||
inkscape:window-height="895"
|
||||
inkscape:window-x="1545"
|
||||
inkscape:window-y="63"
|
||||
inkscape:snap-intersection-line-segments="true"
|
||||
inkscape:object-paths="true"
|
||||
inkscape:object-nodes="true">
|
||||
<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:app-icon"
|
||||
style="display:inline">
|
||||
<path
|
||||
id="path14451"
|
||||
d="M 128.49999,77.500022 L 128.49999,88.500022 L 131.49999,86.500022 L 133.49999,90.500022 L 135.49999,89.500022 L 133.49999,85.500022 L 136.49999,85.500022 L 128.49999,77.500022 z"
|
||||
style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#555753;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(#linearGradient7992);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"
|
||||
d="M 132.00799,83.448274 L 133.59102,84.965162 L 133.0687,85.76811 L 134.8336,89.279979 L 133.71007,89.835652 L 132.00919,86.369947 L 131.22922,86.090464 L 131.04078,83.859018 L 132.00799,83.448274 z"
|
||||
id="path14453"
|
||||
sodipodi:nodetypes="ccccccccc" />
|
||||
<path
|
||||
sodipodi:nodetypes="ccccc"
|
||||
id="path14455"
|
||||
d="M 135.29013,84.99752 L 132.85569,84.999865 L 129.00416,87.559739 L 129.00329,78.735163 L 135.29013,84.99752 z"
|
||||
style="fill:url(#radialGradient7989);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" />
|
||||
<path
|
||||
style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient7986);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 134.09791,84.503528 L 132.63635,84.542245 L 129.51177,86.639535 L 129.50564,79.893544 L 134.09791,84.503528 z"
|
||||
id="path14457"
|
||||
sodipodi:nodetypes="ccccc" />
|
||||
<g
|
||||
id="g12580">
|
||||
<path
|
||||
transform="matrix(1.3189,0,0,1.7540667,154.96524,44.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 68.5,63.5 L 68.5,84.5 L 74.5,80.5 L 78.5,88.5 L 81.5,87 L 77.5,79.5 L 83.5,78.5 L 68.5,63.5 z"
|
||||
style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#555753;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(#linearGradient7974);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 75.14218,74.762567 L 77.68314,78.878279 L 77.0534,79.743512 L 80.81444,86.783603 L 78.72399,87.828242 L 74.89701,80.207272 L 73.7583,80.248655 L 73.31084,75.540282 L 75.14218,74.762567 z"
|
||||
id="path7944"
|
||||
sodipodi:nodetypes="ccccccccc" />
|
||||
<path
|
||||
sodipodi:nodetypes="ccccc"
|
||||
id="path7946"
|
||||
d="M 82.46659,78.173634 L 75.30247,79.357306 L 69.0002,83.575985 L 68.998595,64.713208 L 82.46659,78.173634 z"
|
||||
style="fill:url(#radialGradient7971);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(#linearGradient7968);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 81.42262,77.84474 L 75.10081,78.889164 L 69.50373,82.642958 L 69.52338,65.953163 L 81.42262,77.84474 z"
|
||||
id="path7948"
|
||||
sodipodi:nodetypes="ccccc" />
|
||||
</g>
|
||||
<g
|
||||
inkscape:groupmode="layer"
|
||||
id="layer4"
|
||||
inkscape:label="plate#1"
|
||||
style="display:none">
|
||||
<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
|
||||
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
|
||||
id="text3303"
|
||||
style="font-size:40px;font-style:normal;font-variant:normal;font-weight:200;font-stretch:normal;fill:#000000;fill-opacity:1;stroke:none;font-family:Army Wide"
|
||||
transform="translate(-2618.8726,-537.17629)" />
|
||||
<path
|
||||
style="opacity:1;fill:#cccccc;fill-opacity:1;fill-rule:nonzero;stroke:#800000;stroke-width:0.20000002;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
||||
d="M -377.05043,-90.740359 L -196.12853,-148.61145 L -30.894231,-89.084109 L -180.80043,-22.740369 L -276.80043,-47.240369 L -377.05043,-90.740359 z"
|
||||
id="path8852"
|
||||
sodipodi:nodetypes="cccccc" />
|
||||
<path
|
||||
sodipodi:nodetypes="ccccc"
|
||||
id="path16034"
|
||||
d="M -193.15013,-5.5642392 L -30.894531,-89.083969 C -80.368731,-71.113379 -133.83383,-36.013699 -192.03913,-50.120709 C -253.50783,-32.235689 -322.24963,-70.803649 -377.48563,-90.789219 L -193.15013,-5.5642392 z"
|
||||
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none" />
|
||||
<path
|
||||
id="path16036"
|
||||
d="M -197.36513,-142.05054 C -198.33013,-141.97191 -199.33683,-141.73522 -200.50833,-141.36724 L -209.61903,-138.54291 C -211.68723,-137.8933 -213.03393,-136.79809 -210.53013,-135.90081 L -199.41503,-131.93763 C -197.38093,-131.15999 -195.50513,-131.4558 -193.67533,-132.21096 L -183.19793,-135.67304 C -182.11303,-136.08816 -180.22063,-136.92123 -183.88123,-138.22404 L -192.90093,-141.41279 C -194.32343,-141.91908 -195.75683,-142.18156 -197.36513,-142.05054 L -197.36513,-142.05054 z"
|
||||
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none" />
|
||||
<path
|
||||
sodipodi:nodetypes="ccccccccc"
|
||||
id="path16038"
|
||||
d="M -176.97313,-126.61179 C -178.89403,-125.94373 -180.65223,-124.93698 -178.14193,-124.04897 L -167.00023,-120.12714 C -164.95543,-119.35666 -163.28663,-119.77258 -161.60693,-120.54545 L -151.78863,-123.99665 C -150.78903,-124.42203 -148.63503,-125.43233 -152.30413,-126.72149 L -161.40023,-130.02807 C -162.81743,-130.47213 -164.17673,-130.93888 -165.41173,-130.45167 L -176.97313,-126.61179 L -176.97313,-126.61179 z"
|
||||
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none" />
|
||||
<path
|
||||
sodipodi:nodetypes="ccccccccc"
|
||||
id="path16040"
|
||||
d="M -134.28393,-118.7459 L -144.79393,-114.84796 C -147.01353,-114.18419 -148.73263,-113.36134 -146.43293,-112.60983 L -134.70083,-108.36461 C -132.74053,-107.61519 -131.87633,-107.82479 -129.66003,-108.7035 L -119.51053,-112.60525 C -117.74783,-113.23175 -116.55423,-113.84588 -119.47813,-114.91271 L -130.61493,-118.86378 C -132.07073,-119.3767 -132.68873,-119.27841 -134.28393,-118.7459 L -134.28393,-118.7459 z"
|
||||
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none" />
|
||||
<path
|
||||
sodipodi:nodetypes="ccccscccc"
|
||||
id="path16042"
|
||||
d="M -362.02313,-88.976419 L -348.93583,-83.724919 C -346.22153,-82.721669 -345.67453,-82.641309 -343.44723,-83.239129 L -329.74543,-87.863209 C -328.12513,-88.330409 -327.96443,-89.467079 -330.74833,-90.409189 C -331.00283,-90.495309 -342.00733,-95.440269 -342.00733,-95.440269 C -344.23883,-95.903289 -344.81333,-95.831439 -346.68073,-95.153219 L -359.18403,-91.254149 C -361.31743,-90.614479 -363.39523,-89.810649 -362.02313,-88.976419 L -362.02313,-88.976419 z"
|
||||
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none" />
|
||||
<path
|
||||
sodipodi:nodetypes="csc"
|
||||
style="fill:none;stroke:#009fda;stroke-width:0.20000002;stroke-linecap:butt;stroke-linejoin:miter;marker:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
||||
d="M -183.21373,-47.939839 C -183.21373,-47.939839 -231.31963,-41.444529 -283.68793,-59.712569 C -348.20153,-82.217329 -363.25543,-89.550349 -363.25543,-89.550349"
|
||||
id="path16044" />
|
||||
<path
|
||||
sodipodi:nodetypes="csc"
|
||||
style="fill:none;stroke:#009fda;stroke-width:0.20000002;stroke-linecap:butt;stroke-linejoin:miter;marker:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
||||
d="M -345.59633,-97.060549 C -345.59633,-97.060549 -298.30243,-75.138909 -254.45913,-61.945339 C -210.61583,-48.751749 -161.29213,-46.316009 -161.29213,-46.316009"
|
||||
id="path16046" />
|
||||
<path
|
||||
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none"
|
||||
d="M -102.18463,-107.21142 L -112.50893,-103.19924 C -114.68643,-102.51602 -116.37843,-101.66905 -114.14813,-100.89553 L -102.51293,-96.684399 C -100.61373,-95.913019 -99.766731,-96.128759 -97.588531,-97.033209 L -87.616031,-101.04931 C -85.884931,-101.69418 -84.709431,-102.32631 -87.543231,-103.4244 L -98.602831,-107.33276 C -100.01393,-107.86072 -100.35453,-107.91804 -101.92053,-107.3699 L -102.18463,-107.21138 L -102.18463,-107.21142 z"
|
||||
id="path16048"
|
||||
sodipodi:nodetypes="cccccccccc" />
|
||||
<path
|
||||
sodipodi:nodetypes="ccccccccc"
|
||||
id="path16050"
|
||||
d="M -78.449131,-91.223529 C -80.626631,-90.540309 -82.318631,-89.693339 -80.088331,-88.919819 L -68.453131,-84.708689 C -66.553931,-83.937309 -65.707031,-84.153049 -63.528831,-85.057509 L -54.160131,-89.149089 C -52.429131,-89.793959 -51.253531,-90.426099 -54.087331,-91.524179 L -65.146931,-95.432539 C -66.558031,-95.960499 -66.898631,-96.017819 -68.464631,-95.469679 L -78.449131,-91.223529 L -78.449131,-91.223529 z"
|
||||
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none" />
|
||||
<path
|
||||
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none"
|
||||
d="M -327.52343,-75.526019 L -316.58783,-71.532029 C -313.82833,-70.528789 -313.29323,-70.448429 -311.27383,-71.046249 L -298.57023,-75.374429 C -297.10673,-75.841629 -297.14953,-76.978289 -299.96483,-77.920399 C -300.22223,-78.006529 -309.93393,-81.693979 -309.93393,-81.693979 C -312.14013,-82.156999 -312.67523,-82.085149 -314.33783,-81.406929 L -325.21053,-77.803739 C -327.13323,-77.164079 -328.97473,-76.360239 -327.52343,-75.526019 L -327.52343,-75.526019 z"
|
||||
id="path16052"
|
||||
sodipodi:nodetypes="ccccscccc" />
|
||||
<path
|
||||
sodipodi:nodetypes="cccsccccc"
|
||||
id="path16054"
|
||||
d="M -280.62953,-58.683949 C -277.87013,-57.909669 -276.40413,-58.086359 -274.50083,-58.697429 L -260.22793,-62.172579 C -258.84853,-62.649119 -259.41913,-63.548419 -262.10243,-64.382059 C -265.40173,-65.407069 -269.55583,-66.986049 -272.61993,-68.036939 C -274.69933,-68.929699 -276.53503,-69.203129 -278.10213,-68.514289 L -289.95603,-65.010719 C -292.50793,-64.284809 -293.59893,-63.120499 -291.22713,-62.295539 C -286.61193,-60.764989 -285.18543,-60.295279 -280.62953,-58.684299 L -280.62953,-58.683949 z"
|
||||
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none" />
|
||||
<path
|
||||
id="path16056"
|
||||
d="M -36.541731,-79.685619 C -36.541731,-79.685619 -52.455231,-73.718069 -105.31073,-56.099559 C -158.16623,-38.481049 -191.98243,-50.416169 -191.98243,-50.416169"
|
||||
style="fill:none;stroke:#009fda;stroke-width:0.20000002;stroke-linecap:butt;stroke-linejoin:miter;marker:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
|
||||
<g
|
||||
inkscape:path-effect="#path-effect15992"
|
||||
transform="matrix(1.4977647,0,0,1.4977647,-1232.0425,-263.18298)"
|
||||
id="g16058">
|
||||
<path
|
||||
inkscape:original-d="M 580.38105,116.25308 L 686.6293,116.25308"
|
||||
style="fill:none;stroke:#009fda;stroke-width:0.13353233;stroke-linecap:butt;stroke-linejoin:miter;marker:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
||||
d="M 580.38105,116.25308 L 686.6293,116.25308"
|
||||
id="path16060" />
|
||||
<path
|
||||
inkscape:original-d="M 580.57076,114.35579 L 580.57076,117.58119"
|
||||
style="fill:none;stroke:#009fda;stroke-width:0.13353233;stroke-linecap:butt;stroke-linejoin:miter;marker:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
||||
d="M 580.57076,114.35579 L 580.57076,117.58119"
|
||||
id="path16062" />
|
||||
<path
|
||||
inkscape:original-d="M 591.88662,114.35579 L 591.88662,117.58119"
|
||||
id="path16064"
|
||||
d="M 591.88662,114.35579 L 591.88662,117.58119"
|
||||
style="fill:none;stroke:#009fda;stroke-width:0.13353233;stroke-linecap:butt;stroke-linejoin:miter;marker:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
|
||||
<path
|
||||
inkscape:original-d="M 603.91289,114.35579 L 603.91289,117.58119"
|
||||
style="fill:none;stroke:#009fda;stroke-width:0.13353233;stroke-linecap:butt;stroke-linejoin:miter;marker:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
||||
d="M 603.91289,114.35579 L 603.91289,117.58119"
|
||||
id="path16066" />
|
||||
<path
|
||||
inkscape:original-d="M 614.85501,114.35579 L 614.85501,117.58119"
|
||||
id="path16068"
|
||||
d="M 614.85501,114.35579 L 614.85501,117.58119"
|
||||
style="fill:none;stroke:#009fda;stroke-width:0.13353233;stroke-linecap:butt;stroke-linejoin:miter;marker:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
|
||||
<path
|
||||
inkscape:original-d="M 626.47471,114.35579 L 626.47471,117.58119"
|
||||
style="fill:none;stroke:#009fda;stroke-width:0.13353233;stroke-linecap:butt;stroke-linejoin:miter;marker:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
||||
d="M 626.47471,114.35579 L 626.47471,117.58119"
|
||||
id="path16070" />
|
||||
<path
|
||||
inkscape:original-d="M 637.44964,114.35579 L 637.44964,117.58119"
|
||||
id="path16072"
|
||||
d="M 637.44964,114.35579 L 637.44964,117.58119"
|
||||
style="fill:none;stroke:#009fda;stroke-width:0.13353233;stroke-linecap:butt;stroke-linejoin:miter;marker:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
|
||||
<path
|
||||
inkscape:original-d="M 649.61143,114.35579 L 649.61143,117.58119"
|
||||
style="fill:none;stroke:#009fda;stroke-width:0.13353233;stroke-linecap:butt;stroke-linejoin:miter;marker:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
||||
d="M 649.61143,114.35579 L 649.61143,117.58119"
|
||||
id="path16074" />
|
||||
<path
|
||||
inkscape:original-d="M 660.82458,114.35579 L 660.82458,117.58119"
|
||||
id="path16076"
|
||||
d="M 660.82458,114.35579 L 660.82458,117.58119"
|
||||
style="fill:none;stroke:#009fda;stroke-width:0.13353233;stroke-linecap:butt;stroke-linejoin:miter;marker:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
|
||||
<path
|
||||
inkscape:original-d="M 684.57101,114.35579 L 684.57101,117.58119"
|
||||
id="path16078"
|
||||
d="M 684.57101,114.35579 L 684.57101,117.58119"
|
||||
style="fill:none;stroke:#009fda;stroke-width:0.13353233;stroke-linecap:butt;stroke-linejoin:miter;marker:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
|
||||
<path
|
||||
inkscape:original-d="M 673.6289,114.35579 L 673.6289,117.58119"
|
||||
style="fill:none;stroke:#009fda;stroke-width:0.13353233;stroke-linecap:butt;stroke-linejoin:miter;marker:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
||||
d="M 673.6289,114.35579 L 673.6289,117.58119"
|
||||
id="path16080" />
|
||||
</g>
|
||||
<path
|
||||
sodipodi:nodetypes="cc"
|
||||
id="path16086"
|
||||
d="M -150.48563,-135.24479 L -348.00773,-70.364849"
|
||||
style="fill:none;stroke:#009fda;stroke-width:0.20000002;stroke-linecap:butt;stroke-linejoin:miter;marker:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
|
||||
<path
|
||||
style="fill:none;stroke:#009fda;stroke-width:0.20000002;stroke-linecap:butt;stroke-linejoin:miter;marker:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
||||
d="M -135.46523,-129.5614 L -331.16053,-64.478489"
|
||||
id="path16088"
|
||||
sodipodi:nodetypes="cc" />
|
||||
<path
|
||||
sodipodi:nodetypes="cc"
|
||||
id="path16090"
|
||||
d="M -119.44063,-124.34166 C -181.50953,-101.00213 -242.93703,-77.364399 -313.18733,-58.487429"
|
||||
style="fill:none;stroke:#009fda;stroke-width:0.20000002;stroke-linecap:butt;stroke-linejoin:miter;marker:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
|
||||
<path
|
||||
style="fill:none;stroke:#009fda;stroke-width:0.20000002;stroke-linecap:butt;stroke-linejoin:miter;marker:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
||||
d="M -103.13853,-119.273 C -166.95293,-93.514039 -228.38923,-67.394169 -296.60113,-53.702939"
|
||||
id="path16092"
|
||||
sodipodi:nodetypes="cc" />
|
||||
<path
|
||||
sodipodi:nodetypes="cc"
|
||||
id="path16094"
|
||||
d="M -49.998831,-91.140229 C -107.01613,-64.405289 -149.26703,-48.913749 -219.59123,-44.893689"
|
||||
style="fill:none;stroke:#009fda;stroke-width:0.20000002;stroke-linecap:butt;stroke-linejoin:miter;marker:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
|
||||
<path
|
||||
style="fill:none;stroke:#009fda;stroke-width:0.20000002;stroke-linecap:butt;stroke-linejoin:miter;marker:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
||||
d="M -66.029831,-96.255279 C -118.11773,-74.246839 -183.85603,-52.781939 -235.91213,-46.094159"
|
||||
id="path16096"
|
||||
sodipodi:nodetypes="cc" />
|
||||
<path
|
||||
sodipodi:nodetypes="cc"
|
||||
id="path16098"
|
||||
d="M -99.967831,-108.35277 C -160.17473,-83.502629 -218.60583,-60.819869 -273.30073,-51.290399"
|
||||
style="fill:none;stroke:#009fda;stroke-width:0.20000002;stroke-linecap:butt;stroke-linejoin:miter;marker:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
|
||||
<path
|
||||
style="fill:none;stroke:#009fda;stroke-width:0.20000002;stroke-linecap:butt;stroke-linejoin:miter;marker:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
||||
d="M -83.729531,-102.4664 C -143.93653,-77.616269 -201.12483,-54.829949 -259.96213,-47.371679"
|
||||
id="path16100"
|
||||
sodipodi:nodetypes="cc" />
|
||||
<path
|
||||
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none"
|
||||
d="M -239.60523,-50.586589 L -226.16073,-53.336809 C -224.78133,-53.813359 -224.65853,-54.892269 -227.41383,-55.442749 L -236.89573,-57.337089 C -239.38943,-57.919159 -240.91443,-58.399719 -242.48153,-57.710889 L -255.68173,-54.932229 C -258.23363,-54.206329 -261.08513,-53.456239 -258.71333,-52.631289 L -246.97653,-50.366339 C -244.35653,-49.484159 -242.18103,-50.244269 -239.60523,-50.586589 z"
|
||||
id="path16102"
|
||||
sodipodi:nodetypes="ccscccccc" />
|
||||
<path
|
||||
style="fill:none;stroke:#009fda;stroke-width:0.20000002;stroke-linecap:butt;stroke-linejoin:miter;marker:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
||||
d="M -176.52363,-143.39639 L -374.24873,-80.140299"
|
||||
id="path8786"
|
||||
sodipodi:nodetypes="cc" />
|
||||
<g
|
||||
id="g8792"
|
||||
transform="translate(1669.1863,-717.32088)">
|
||||
<path
|
||||
sodipodi:nodetypes="cc"
|
||||
id="path8794"
|
||||
d="M -1859.2363,566.76341 L -2056.9614,630.01951"
|
||||
style="fill:none;stroke:#009fda;stroke-width:0.20000002;stroke-linecap:butt;stroke-linejoin:miter;marker:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
|
||||
<path
|
||||
style="fill:none;stroke:#009fda;stroke-width:0.20000002;stroke-linecap:butt;stroke-linejoin:miter;marker:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
||||
d="M -1845.7099,573.92448 L -2043.4349,637.18058"
|
||||
id="path8796"
|
||||
sodipodi:nodetypes="cc" />
|
||||
</g>
|
||||
<g
|
||||
id="g8818"
|
||||
transform="translate(1675.9495,-713.74034)">
|
||||
<path
|
||||
style="fill:none;stroke:#009fda;stroke-width:0.18846485;stroke-linecap:butt;stroke-linejoin:miter;marker:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
||||
d="M -1897.9293,561.76866 L -1722.3544,625.02476"
|
||||
id="path8800"
|
||||
sodipodi:nodetypes="cc" />
|
||||
<path
|
||||
style="fill:none;stroke:#009fda;stroke-width:0.18846485;stroke-linecap:butt;stroke-linejoin:miter;marker:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
||||
d="M -1909.2333,569.63684 L -1733.6585,632.89294"
|
||||
id="path8816"
|
||||
sodipodi:nodetypes="cc" />
|
||||
</g>
|
||||
<path
|
||||
style="fill:none;stroke:#009fda;stroke-width:0.18846485;stroke-linecap:butt;stroke-linejoin:miter;marker:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
||||
d="M -227.63173,-148.03759 L -52.056931,-84.781489"
|
||||
id="path8802"
|
||||
sodipodi:nodetypes="cc" />
|
||||
<path
|
||||
style="fill:none;stroke:#009fda;stroke-width:0.23206167;stroke-linecap:butt;stroke-linejoin:miter;marker:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
||||
d="M -216.30593,-155.88397 L -0.11603083,-77.995089"
|
||||
id="path8832"
|
||||
sodipodi:nodetypes="cc" />
|
||||
<path
|
||||
style="fill:none;stroke:#009fda;stroke-width:0.18846485;stroke-linecap:butt;stroke-linejoin:miter;marker:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
||||
d="M -227.63173,-148.03759 L -52.056931,-84.781489"
|
||||
id="path8834"
|
||||
sodipodi:nodetypes="cc" />
|
||||
<path
|
||||
style="fill:#888a85;fill-opacity:1;fill-rule:evenodd;stroke:#888a85;stroke-linejoin:round"
|
||||
d="M 108.82643,86.48326 L 118.49998,78.669124 L 108.5,75.399647 L 97.500002,78.478613 L 108.82643,86.48326 z"
|
||||
id="path8856"
|
||||
sodipodi:nodetypes="ccccc" />
|
||||
<path
|
||||
style="fill:url(#linearGradient9862);fill-opacity:1;fill-rule:nonzero;stroke:#2e3436;stroke-width:1;stroke-linecap:butt;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
||||
d="M 108.5,72 L 97.5625,78.511188 C 100.89874,80.755204 105.04827,84.991603 108.75,83.005637 C 112.27666,84.581681 115.50236,80.691736 118.5,78.684052 L 108.5,72 z"
|
||||
id="path8854" />
|
||||
<path
|
||||
style="fill:#2e3436;fill-opacity:1;fill-rule:evenodd;stroke:none"
|
||||
d="M 108.41352,72.751665 C 108.35505,72.760451 108.29405,72.786894 108.22307,72.828005 L 107.67105,73.143541 C 107.54574,73.216116 107.46414,73.338473 107.61585,73.438718 L 108.28931,73.881486 C 108.41256,73.968366 108.52621,73.935318 108.63708,73.850949 L 109.27191,73.464165 C 109.33764,73.417788 109.4523,73.324716 109.23051,73.179164 L 108.684,72.822916 C 108.59781,72.766354 108.51096,72.737029 108.41352,72.751665 L 108.41352,72.751665 z"
|
||||
id="path8858" />
|
||||
<path
|
||||
style="fill:#2e3436;fill-opacity:1;fill-rule:evenodd;stroke:none"
|
||||
d="M 109.64907,74.476494 C 109.53268,74.551128 109.42615,74.663603 109.57825,74.762813 L 110.25333,75.200962 C 110.37722,75.28704 110.47834,75.240574 110.58011,75.154229 L 111.175,74.768658 C 111.23557,74.721134 111.36608,74.608263 111.14377,74.464237 L 110.59263,74.094824 C 110.50676,74.045213 110.4244,73.993068 110.34958,74.047499 L 109.64907,74.476494 L 109.64907,74.476494 z"
|
||||
id="path8860"
|
||||
sodipodi:nodetypes="ccccccccc" />
|
||||
<path
|
||||
style="fill:#2e3436;fill-opacity:1;fill-rule:evenodd;stroke:none"
|
||||
d="M 112.23561,75.355274 L 111.59881,75.790755 C 111.46432,75.864912 111.36016,75.956841 111.4995,76.0408 L 112.21035,76.51508 C 112.32913,76.598805 112.38149,76.575387 112.51577,76.477218 L 113.13073,76.041312 C 113.23754,75.971319 113.30986,75.902708 113.1327,75.783522 L 112.45792,75.342105 C 112.36971,75.284801 112.33227,75.295783 112.23561,75.355274 L 112.23561,75.355274 z"
|
||||
id="path8862"
|
||||
sodipodi:nodetypes="ccccccccc" />
|
||||
<path
|
||||
style="fill:#2e3436;fill-opacity:1;fill-rule:evenodd;stroke:none"
|
||||
d="M 98.436876,78.68114 L 99.229836,79.26784 C 99.394296,79.379923 99.427439,79.388901 99.562391,79.322112 L 100.39258,78.805508 C 100.49076,78.753312 100.5005,78.626322 100.33182,78.52107 C 100.3164,78.511448 99.649635,77.958994 99.649635,77.958994 C 99.514428,77.907265 99.479619,77.915292 99.366473,77.991064 L 98.608897,78.426671 C 98.479634,78.498134 98.35374,78.587938 98.436876,78.68114 L 98.436876,78.68114 z"
|
||||
id="path8864"
|
||||
sodipodi:nodetypes="ccccscccc" />
|
||||
<path
|
||||
sodipodi:nodetypes="cccccccccc"
|
||||
id="path8870"
|
||||
d="M 114.18051,76.643913 L 113.55496,77.092158 C 113.42303,77.168487 113.32051,77.263111 113.45564,77.34953 L 114.16062,77.819998 C 114.27569,77.906178 114.32701,77.882076 114.45899,77.78103 L 115.06322,77.332348 C 115.16811,77.260303 115.23933,77.189682 115.06763,77.067002 L 114.39753,76.630357 C 114.31203,76.571373 114.2914,76.56497 114.19651,76.626208 L 114.18051,76.643919 L 114.18051,76.643913 z"
|
||||
style="fill:#2e3436;fill-opacity:1;fill-rule:evenodd;stroke:none" />
|
||||
<path
|
||||
style="fill:#2e3436;fill-opacity:1;fill-rule:evenodd;stroke:none"
|
||||
d="M 115.61865,78.430091 C 115.48671,78.50642 115.38419,78.601044 115.51933,78.687463 L 116.22431,79.157934 C 116.33938,79.244113 116.39069,79.22001 116.52267,79.118963 L 117.09032,78.661848 C 117.1952,78.589804 117.26643,78.51918 117.09473,78.396503 L 116.42463,77.959858 C 116.33913,77.900875 116.31849,77.894471 116.22361,77.955708 L 115.61865,78.430091 L 115.61865,78.430091 z"
|
||||
id="path8872"
|
||||
sodipodi:nodetypes="ccccccccc" />
|
||||
<path
|
||||
sodipodi:nodetypes="ccccscccc"
|
||||
id="path8874"
|
||||
d="M 100.52722,80.183826 L 101.1898,80.630038 C 101.357,80.74212 101.38942,80.751098 101.51178,80.684309 L 102.28149,80.200762 C 102.37017,80.148567 102.36757,80.021578 102.19699,79.916325 C 102.1814,79.906702 101.59296,79.494738 101.59296,79.494738 C 101.45929,79.44301 101.42687,79.451036 101.32613,79.526808 L 100.66735,79.929358 C 100.55086,80.000821 100.43928,80.090627 100.52722,80.183826 L 100.52722,80.183826 z"
|
||||
style="fill:#2e3436;fill-opacity:1;fill-rule:evenodd;stroke:none" />
|
||||
<path
|
||||
style="fill:#2e3436;fill-opacity:1;fill-rule:evenodd;stroke:none"
|
||||
d="M 103.36852,82.065434 C 103.53571,82.151935 103.62454,82.132197 103.73986,82.063927 L 104.60466,81.67568 C 104.68823,81.622442 104.65366,81.521971 104.49108,81.428837 C 104.29117,81.314321 104.03948,81.137918 103.85382,81.020511 C 103.72783,80.920772 103.61661,80.890224 103.52166,80.967182 L 102.80343,81.358602 C 102.64881,81.439701 102.5827,81.569779 102.72641,81.661944 C 103.00605,81.832937 103.09248,81.885414 103.36852,82.065393 L 103.36852,82.065434 z"
|
||||
id="path8876"
|
||||
sodipodi:nodetypes="cccsccccc" />
|
||||
<path
|
||||
sodipodi:nodetypes="ccscccccc"
|
||||
id="path8920"
|
||||
d="M 105.85419,82.970074 L 106.66879,82.662818 C 106.75237,82.609578 106.75981,82.489042 106.59286,82.427541 L 106.01835,82.215905 C 105.86726,82.150875 105.77486,82.097187 105.67991,82.174143 L 104.88011,82.484578 C 104.72549,82.565675 104.55272,82.649476 104.69642,82.74164 L 105.40756,82.994681 C 105.5663,83.09324 105.69812,83.00832 105.85419,82.970074 z"
|
||||
style="fill:#2e3436;fill-opacity:1;fill-rule:evenodd;stroke:none" />
|
||||
<path
|
||||
sodipodi:type="inkscape:offset"
|
||||
inkscape:radius="-1.0295589"
|
||||
inkscape:original="M 108.5 72 L 97.5625 78.5 C 100.89874 80.744019 105.04827 84.985966 108.75 83 C 112.27666 84.576043 115.50236 80.695184 118.5 78.6875 L 108.5 72 z "
|
||||
style="fill:none;fill-opacity:1;fill-rule:nonzero;stroke:#eeeeec;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.31451613000000000;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
||||
id="path9880"
|
||||
d="M 108.46875,73.21875 L 99.4375,78.5625 C 100.7958,79.566051 102.17635,80.665224 103.53125,81.4375 C 105.31813,82.456004 106.80945,82.8666 108.25,82.09375 C 108.53099,81.943716 108.86559,81.932178 109.15625,82.0625 C 110.52543,82.67438 111.78457,82.257565 113.28125,81.3125 C 114.39772,80.60752 115.57212,79.625252 116.75,78.71875 L 108.46875,73.21875 z" />
|
||||
<path
|
||||
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none"
|
||||
d="M -177.0341,282.31973 L -14.7785,198.8 L -184,164 L -361.3696,197.09475 L -177.0341,282.31973 z"
|
||||
id="path9886"
|
||||
sodipodi:nodetypes="ccccc" />
|
||||
<path
|
||||
style="opacity:1;fill:#cccccc;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.20000002000000000;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
||||
d="M -180 139.28125 L -360.9375 197.15625 L -359.34375 197.84375 C -304.45784 218.02169 -236.65904 255.41763 -175.9375 237.75 C -117.7322 251.85701 -64.25545 216.78309 -14.78125 198.8125 L -180 139.28125 z "
|
||||
id="path9884" />
|
||||
<path
|
||||
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none"
|
||||
d="M -181.2491,145.83343 C -182.2141,145.91206 -183.2208,146.14875 -184.3923,146.51673 L -193.503,149.34106 C -195.5712,149.99067 -196.9179,151.08588 -194.4141,151.98316 L -183.299,155.94634 C -181.2649,156.72398 -179.3891,156.42817 -177.5593,155.67301 L -167.0819,152.21093 C -165.997,151.79581 -164.1046,150.96274 -167.7652,149.65993 L -176.7849,146.47118 C -178.2074,145.96489 -179.6408,145.70241 -181.2491,145.83343 L -181.2491,145.83343 z"
|
||||
id="path9888" />
|
||||
<path
|
||||
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none"
|
||||
d="M -160.8571,161.27218 C -162.778,161.94024 -164.5362,162.94699 -162.0259,163.835 L -150.8842,167.75683 C -148.8394,168.52731 -147.1706,168.11139 -145.4909,167.33852 L -135.6726,163.88732 C -134.673,163.46194 -132.519,162.45164 -136.1881,161.16248 L -145.2842,157.8559 C -146.7014,157.41184 -148.0607,156.94509 -149.2957,157.4323 L -160.8571,161.27218 L -160.8571,161.27218 z"
|
||||
id="path9890"
|
||||
sodipodi:nodetypes="ccccccccc" />
|
||||
<path
|
||||
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none"
|
||||
d="M -118.1679,169.13807 L -128.6779,173.03601 C -130.8975,173.69978 -132.6166,174.52263 -130.3169,175.27414 L -118.5848,179.51936 C -116.6245,180.26878 -115.7603,180.05918 -113.544,179.18047 L -103.3945,175.27872 C -101.6318,174.65222 -100.4382,174.03809 -103.3621,172.97126 L -114.4989,169.02019 C -115.9547,168.50727 -116.5727,168.60556 -118.1679,169.13807 L -118.1679,169.13807 z"
|
||||
id="path9892"
|
||||
sodipodi:nodetypes="ccccccccc" />
|
||||
<path
|
||||
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none"
|
||||
d="M -345.9071,198.90755 L -332.8198,204.15905 C -330.1055,205.1623 -329.5585,205.24266 -327.3312,204.64484 L -313.6294,200.02076 C -312.0091,199.55356 -311.8484,198.41689 -314.6323,197.47478 C -314.8868,197.38866 -325.8913,192.4437 -325.8913,192.4437 C -328.1228,191.98068 -328.6973,192.05253 -330.5647,192.73075 L -343.068,196.62982 C -345.2014,197.26949 -347.2792,198.07332 -345.9071,198.90755 L -345.9071,198.90755 z"
|
||||
id="path9894"
|
||||
sodipodi:nodetypes="ccccscccc" />
|
||||
<path
|
||||
sodipodi:nodetypes="cccccccccc"
|
||||
id="path9900"
|
||||
d="M -86.068599,180.67255 L -96.392899,184.68473 C -98.570399,185.36795 -100.2624,186.21492 -98.032099,186.98844 L -86.396899,191.19957 C -84.497699,191.97095 -83.6507,191.75521 -81.4725,190.85076 L -71.5,186.83466 C -69.7689,186.18979 -68.5934,185.55766 -71.4272,184.45957 L -82.4868,180.55121 C -83.897899,180.02325 -84.238499,179.96593 -85.804499,180.51407 L -86.068599,180.67259 L -86.068599,180.67255 z"
|
||||
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none" />
|
||||
<path
|
||||
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none"
|
||||
d="M -62.3331,196.66044 C -64.5106,197.34366 -66.2026,198.19063 -63.9723,198.96415 L -52.3371,203.17528 C -50.4379,203.94666 -49.591,203.73092 -47.4128,202.82646 L -38.0441,198.73488 C -36.3131,198.09001 -35.1375,197.45787 -37.9713,196.35979 L -49.0309,192.45143 C -50.442,191.92347 -50.7826,191.86615 -52.3486,192.41429 L -62.3331,196.66044 L -62.3331,196.66044 z"
|
||||
id="path9902"
|
||||
sodipodi:nodetypes="ccccccccc" />
|
||||
<path
|
||||
sodipodi:nodetypes="ccccscccc"
|
||||
id="path9904"
|
||||
d="M -311.4074,212.35795 L -300.4718,216.35194 C -297.7123,217.35518 -297.1772,217.43554 -295.1578,216.83772 L -282.4542,212.50954 C -280.9907,212.04234 -281.0335,210.90568 -283.8488,209.96357 C -284.1062,209.87744 -293.8179,206.18999 -293.8179,206.18999 C -296.0241,205.72697 -296.5592,205.79882 -298.2218,206.47704 L -309.0945,210.08023 C -311.0172,210.71989 -312.8587,211.52373 -311.4074,212.35795 L -311.4074,212.35795 z"
|
||||
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none" />
|
||||
<path
|
||||
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none"
|
||||
d="M -264.5135,229.20002 C -261.7541,229.9743 -260.2881,229.79761 -258.3848,229.18654 L -244.1119,225.71139 C -242.7325,225.23485 -243.3031,224.33555 -245.9864,223.50191 C -249.2857,222.4769 -253.4398,220.89792 -256.5039,219.84703 C -258.5833,218.95427 -260.419,218.68084 -261.9861,219.36968 L -273.84,222.87325 C -276.3919,223.59916 -277.4829,224.76347 -275.1111,225.58843 C -270.4959,227.11898 -269.0694,227.58869 -264.5135,229.19967 L -264.5135,229.20002 z"
|
||||
id="path9906"
|
||||
sodipodi:nodetypes="cccsccccc" />
|
||||
<path
|
||||
sodipodi:nodetypes="ccscccccc"
|
||||
id="path9950"
|
||||
d="M -223.4892,237.29738 L -210.0447,234.54716 C -208.6653,234.07061 -208.5425,232.9917 -211.2978,232.44122 L -220.7797,230.54688 C -223.2734,229.96481 -224.7984,229.48425 -226.3655,230.17308 L -239.5657,232.95174 C -242.1176,233.67764 -244.9691,234.42773 -242.5973,235.25268 L -230.8605,237.51763 C -228.2405,238.39981 -226.065,237.6397 -223.4892,237.29738 z"
|
||||
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none" />
|
||||
<path
|
||||
sodipodi:nodetypes="ccccc"
|
||||
id="path9975"
|
||||
d="M 33.497089,77.698474 L 55.500003,66.372655 L 32.552468,61.653549 L 8.499997,66.141412 L 33.497089,77.698474 z"
|
||||
style="fill:url(#radialGradient10055);fill-opacity:1;fill-rule:evenodd;stroke:none" />
|
||||
<path
|
||||
id="path9977"
|
||||
d="M 33.094894,58.301526 L 8.5585926,66.149752 L 8.7747154,66.242982 C 16.217602,68.979241 25.41156,74.050374 33.645795,71.654529 C 41.538812,73.567531 48.790607,68.811279 55.49963,66.37435 L 33.094894,58.301526 z"
|
||||
style="fill:url(#linearGradient10033);fill-opacity:1;fill-rule:nonzero;stroke:#555753;stroke-width:1;stroke-linecap:butt;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:0.59999999999999998;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
|
||||
<path
|
||||
id="path9979"
|
||||
d="M 32.841904,59.994654 C 32.720064,60.004582 32.592959,60.034467 32.445047,60.080927 L 31.294741,60.437524 C 31.033613,60.519543 30.86358,60.657823 31.179707,60.771112 L 32.583086,61.271499 C 32.839909,61.369683 33.076746,61.332334 33.307773,61.236988 L 34.630637,60.79987 C 34.767615,60.747458 35.006547,60.642275 34.544365,60.477783 L 33.405548,60.075176 C 33.225945,60.011253 33.044966,59.978112 32.841904,59.994654 L 32.841904,59.994654 z"
|
||||
style="fill:#2e3436;fill-opacity:1;fill-rule:evenodd;stroke:none" />
|
||||
<path
|
||||
sodipodi:nodetypes="ccccccccc"
|
||||
id="path9981"
|
||||
d="M 35.416573,61.943932 C 35.174043,62.02828 34.952054,62.155392 35.269001,62.267511 L 36.675739,62.762677 C 36.933913,62.859956 37.144614,62.807442 37.356691,62.709861 L 38.596337,62.274117 C 38.722545,62.220409 38.994507,62.092849 38.531251,61.930082 L 37.382788,61.512597 C 37.203854,61.456531 37.03223,61.3976 36.876301,61.459113 L 35.416573,61.943932 L 35.416573,61.943932 z"
|
||||
style="fill:#2e3436;fill-opacity:1;fill-rule:evenodd;stroke:none" />
|
||||
<path
|
||||
sodipodi:nodetypes="ccccccccc"
|
||||
id="path9983"
|
||||
d="M 40.806459,62.93707 L 39.479479,63.429219 C 39.199236,63.513026 38.982184,63.616918 39.272541,63.711803 L 40.753822,64.247799 C 41.001327,64.342419 41.11044,64.315956 41.390267,64.205012 L 42.67173,63.712381 C 42.894287,63.633279 43.04499,63.55574 42.675821,63.421044 L 41.269703,62.922187 C 41.085895,62.857426 41.007867,62.869836 40.806459,62.93707 L 40.806459,62.93707 z"
|
||||
style="fill:#2e3436;fill-opacity:1;fill-rule:evenodd;stroke:none" />
|
||||
<path
|
||||
sodipodi:nodetypes="ccccscccc"
|
||||
id="path9985"
|
||||
d="M 13.324644,66.394404 L 14.977029,67.057452 C 15.319734,67.184122 15.388797,67.194267 15.670013,67.118788 L 17.399986,66.534956 C 17.604563,66.475969 17.624853,66.332454 17.273361,66.213504 C 17.241228,66.202631 15.851813,65.578287 15.851813,65.578287 C 15.570067,65.519826 15.497531,65.528898 15.261756,65.614529 L 13.683104,66.106821 C 13.413744,66.187584 13.151404,66.289075 13.324644,66.394404 L 13.324644,66.394404 z"
|
||||
style="fill:#2e3436;fill-opacity:1;fill-rule:evenodd;stroke:none" />
|
||||
<path
|
||||
style="fill:#2e3436;fill-opacity:1;fill-rule:evenodd;stroke:none"
|
||||
d="M 44.859277,64.393399 L 43.555744,64.899972 C 43.280816,64.986235 43.067186,65.093172 43.348781,65.190836 L 44.817826,65.722528 C 45.057617,65.819922 45.164559,65.792682 45.439575,65.678488 L 46.698691,65.171419 C 46.917257,65.089999 47.065675,65.010187 46.707883,64.871544 L 45.311511,64.378079 C 45.133347,64.31142 45.090344,64.304182 44.892623,64.373389 L 44.859277,64.393405 L 44.859277,64.393399 z"
|
||||
id="path9987"
|
||||
sodipodi:nodetypes="cccccccccc" />
|
||||
<path
|
||||
sodipodi:nodetypes="ccccccccc"
|
||||
id="path9989"
|
||||
d="M 47.856093,66.412011 C 47.581164,66.498273 47.367535,66.605211 47.649129,66.702874 L 49.118176,67.234567 C 49.357967,67.33196 49.464895,67.304721 49.739912,67.190525 L 50.922792,66.673927 C 51.141346,66.592506 51.289776,66.512694 50.931984,66.374051 L 49.535612,65.880586 C 49.357449,65.813927 49.314445,65.806689 49.116723,65.875897 L 47.856093,66.412011 L 47.856093,66.412011 z"
|
||||
style="fill:#2e3436;fill-opacity:1;fill-rule:evenodd;stroke:none" />
|
||||
<path
|
||||
style="fill:#2e3436;fill-opacity:1;fill-rule:evenodd;stroke:none"
|
||||
d="M 17.680533,68.092636 L 19.061249,68.596912 C 19.40966,68.723579 19.477221,68.733726 19.732187,68.658245 L 21.336129,68.111775 C 21.520908,68.052787 21.515504,67.909273 21.160048,67.790324 C 21.127549,67.779449 19.901362,67.313876 19.901362,67.313876 C 19.62281,67.255416 19.555249,67.264488 19.345331,67.350119 L 17.972557,67.805053 C 17.729799,67.885816 17.497293,67.987308 17.680533,68.092636 L 17.680533,68.092636 z"
|
||||
id="path9991"
|
||||
sodipodi:nodetypes="ccccscccc" />
|
||||
<path
|
||||
sodipodi:nodetypes="cccsccccc"
|
||||
id="path9993"
|
||||
d="M 23.6013,70.219095 C 23.949698,70.316854 24.134793,70.294546 24.375101,70.217393 L 26.17718,69.778624 C 26.351342,69.718457 26.279299,69.604912 25.940509,69.499658 C 25.523943,69.370242 24.999451,69.170881 24.612582,69.038197 C 24.350039,68.925478 24.118267,68.890956 23.920406,68.977928 L 22.423747,69.420285 C 22.101547,69.511937 21.963799,69.658941 22.263259,69.7631 C 22.845969,69.956345 23.026077,70.01565 23.6013,70.21905 L 23.6013,70.219095 z"
|
||||
style="fill:#2e3436;fill-opacity:1;fill-rule:evenodd;stroke:none" />
|
||||
<path
|
||||
style="fill:#2e3436;fill-opacity:1;fill-rule:evenodd;stroke:none"
|
||||
d="M 28.780977,71.241457 L 30.478464,70.894218 C 30.652625,70.834049 30.668129,70.697827 30.320249,70.628324 L 29.123075,70.389148 C 28.808224,70.315656 28.615679,70.254981 28.417819,70.341952 L 26.751179,70.692782 C 26.428978,70.784433 26.068951,70.879139 26.368412,70.983296 L 27.850286,71.269266 C 28.181084,71.380649 28.45576,71.284678 28.780977,71.241457 z"
|
||||
id="path9995"
|
||||
sodipodi:nodetypes="ccscccccc" />
|
||||
<path
|
||||
sodipodi:type="inkscape:offset"
|
||||
inkscape:radius="-0.98041552"
|
||||
inkscape:original="M 33.09375 58.3125 L 8.5625 66.15625 L 8.78125 66.25 C 16.224137 68.98626 25.422015 74.052095 33.65625 71.65625 C 41.549268 73.569255 48.790977 68.811929 55.5 66.375 L 33.09375 58.3125 z "
|
||||
style="fill:none;fill-opacity:1;fill-rule:nonzero;stroke:#eeeeec;stroke-width:1;stroke-linecap:butt;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:0.60000001999999997;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.75294119;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
||||
id="path10025"
|
||||
d="M 33.0625,59.375 L 11.53125,66.25 C 18.577761,69.042237 26.449669,72.733754 33.375,70.71875 C 33.538866,70.675541 33.711134,70.675541 33.875,70.71875 C 40.420693,72.305208 46.634312,68.967285 52.75,66.4375 L 33.0625,59.375 z" />
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 58 KiB |
|
|
@ -144,6 +144,8 @@ libgui_la_SOURCES = \
|
|||
$(lumigui_srcdir)/widgets/timeline/timeline-group-track.hpp \
|
||||
$(lumigui_srcdir)/widgets/timeline/timeline-clip.cpp \
|
||||
$(lumigui_srcdir)/widgets/timeline/timeline-clip.hpp \
|
||||
$(lumigui_srcdir)/widgets/timeline/timeline-layout-helper.cpp \
|
||||
$(lumigui_srcdir)/widgets/timeline/timeline-layout-helper.hpp \
|
||||
$(lumigui_srcdir)/model/project.cpp \
|
||||
$(lumigui_srcdir)/model/project.hpp \
|
||||
$(lumigui_srcdir)/model/track.cpp \
|
||||
|
|
|
|||
|
|
@ -54,12 +54,11 @@ protected:
|
|||
Gtk::HBox containerFormatHBox;
|
||||
Gtk::Label containerFormatLabel;
|
||||
Gtk::ComboBox containerFormat;
|
||||
|
||||
Gtk::Image renderButtonImage;
|
||||
|
||||
Gtk::Frame audioFrame;
|
||||
|
||||
Gtk::Frame videoFrame;
|
||||
|
||||
Gtk::Image renderButtonImage;
|
||||
};
|
||||
|
||||
} // namespace dialogs
|
||||
|
|
|
|||
|
|
@ -44,6 +44,7 @@ using namespace gui;
|
|||
using namespace gui::workspace;
|
||||
using namespace gui::model;
|
||||
|
||||
|
||||
GtkLumiera the_application;
|
||||
|
||||
|
||||
|
|
@ -66,7 +67,9 @@ GtkLumiera::main(int argc, char *argv[])
|
|||
|
||||
WorkspaceWindow main_window(&project);
|
||||
|
||||
kit.run(main_window);
|
||||
kit.run(main_window);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Glib::ustring
|
||||
|
|
@ -83,6 +86,20 @@ application()
|
|||
return the_application;
|
||||
}
|
||||
|
||||
/* ===== Constants ===== */
|
||||
|
||||
const gchar* GtkLumiera::AppTitle = "Lumiera";
|
||||
const gchar* GtkLumiera::AppVersion = _("0.1-dev");
|
||||
const gchar* GtkLumiera::AppCopyright =
|
||||
_("© 2008 The Lumiera Team");
|
||||
const gchar* GtkLumiera::AppWebsite = "www.lumiera.org";
|
||||
const gchar* GtkLumiera::AppAuthors[] = {
|
||||
"Joel Holdsworth",
|
||||
"Christian Thaeter",
|
||||
"Hermann Vosseler",
|
||||
"<Other Authors Here>"};
|
||||
const int GtkLumiera::AppAuthorCount = 4;
|
||||
|
||||
} // namespace gui
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -32,8 +32,10 @@
|
|||
#include <nobug.h> // need to include this after gtkmm.h, because types.h from GTK tries to shaddow the ERROR macro from windows, which kills NoBug's ERROR macro
|
||||
#include <vector>
|
||||
#include <boost/utility.hpp>
|
||||
#include <boost/optional.hpp>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <boost/weak_ptr.hpp>
|
||||
#include <boost/scoped_ptr.hpp>
|
||||
#include "lib/util.hpp"
|
||||
|
||||
extern "C" {
|
||||
|
|
@ -59,37 +61,6 @@ NOBUG_DECLARE_FLAG(gui);
|
|||
*/
|
||||
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 ===== */
|
||||
|
||||
/**
|
||||
|
|
@ -102,6 +73,38 @@ public:
|
|||
|
||||
static Glib::ustring get_home_data_path();
|
||||
|
||||
|
||||
public:
|
||||
/* ----- Constants ----- */
|
||||
/**
|
||||
* The name of the application
|
||||
*/
|
||||
static const gchar* AppTitle;
|
||||
|
||||
/**
|
||||
* The version number of the application
|
||||
*/
|
||||
static const gchar* AppVersion;
|
||||
|
||||
/**
|
||||
* The copyright of the application
|
||||
*/
|
||||
static const gchar* AppCopyright;
|
||||
|
||||
/**
|
||||
* The website of the application
|
||||
*/
|
||||
static const gchar* AppWebsite;
|
||||
|
||||
/**
|
||||
* An alphabetical list of the application's authors
|
||||
*/
|
||||
static const gchar* AppAuthors[];
|
||||
|
||||
/**
|
||||
* The number of authors in AppAuthors
|
||||
**/
|
||||
static const int AppAuthorCount;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -29,5 +29,15 @@ ClipTrack::ClipTrack()
|
|||
{
|
||||
}
|
||||
|
||||
std::string
|
||||
ClipTrack::print_track()
|
||||
{
|
||||
std::ostringstream os;
|
||||
|
||||
os << "ClipTrack\t\"" << get_name() << "\"";
|
||||
|
||||
return os.str();
|
||||
}
|
||||
|
||||
} // namespace model
|
||||
} // namespace gui
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ class ClipTrack : public Track
|
|||
public:
|
||||
ClipTrack();
|
||||
|
||||
|
||||
std::string print_track();
|
||||
|
||||
private:
|
||||
|
||||
|
|
|
|||
|
|
@ -28,6 +28,16 @@ namespace model {
|
|||
GroupTrack::GroupTrack()
|
||||
{
|
||||
}
|
||||
|
||||
std::string
|
||||
GroupTrack::print_track()
|
||||
{
|
||||
std::ostringstream os;
|
||||
|
||||
os << "GroupTrack\t\"" << get_name() << "\"";
|
||||
|
||||
return os.str();
|
||||
}
|
||||
|
||||
} // namespace model
|
||||
} // namespace gui
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@ class GroupTrack : public ParentTrack
|
|||
public:
|
||||
GroupTrack();
|
||||
|
||||
std::string print_track();
|
||||
};
|
||||
|
||||
} // namespace model
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@
|
|||
* *****************************************************/
|
||||
|
||||
#include "parent-track.hpp"
|
||||
#include <boost/foreach.hpp>
|
||||
|
||||
namespace gui {
|
||||
namespace model {
|
||||
|
|
@ -41,5 +42,27 @@ ParentTrack::get_child_track_list()
|
|||
return tracks;
|
||||
}
|
||||
|
||||
bool
|
||||
ParentTrack::remove_child_track(const boost::shared_ptr<Track> track)
|
||||
{
|
||||
REQUIRE(track);
|
||||
|
||||
BOOST_FOREACH(const boost::shared_ptr<Track> child_track, tracks)
|
||||
{
|
||||
REQUIRE(child_track);
|
||||
|
||||
if(track.get() == child_track.get())
|
||||
{
|
||||
tracks.remove(track);
|
||||
return true;
|
||||
}
|
||||
|
||||
if(child_track->remove_child_track(track))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
} // namespace model
|
||||
} // namespace gui
|
||||
|
|
|
|||
|
|
@ -39,14 +39,14 @@ class ParentTrack : public Track
|
|||
protected:
|
||||
ParentTrack();
|
||||
|
||||
public:
|
||||
virtual void add_child_track(Track* child) {};
|
||||
|
||||
public:
|
||||
std::list< boost::shared_ptr<Track> >
|
||||
get_child_tracks() const;
|
||||
|
||||
lumiera::observable_list< boost::shared_ptr<Track> >&
|
||||
get_child_track_list();
|
||||
|
||||
bool remove_child_track(const boost::shared_ptr<Track> track);
|
||||
|
||||
protected:
|
||||
lumiera::observable_list< boost::shared_ptr<Track> > tracks;
|
||||
|
|
|
|||
|
|
@ -33,21 +33,39 @@ Sequence::Sequence()
|
|||
static bool first = true;
|
||||
|
||||
shared_ptr<GroupTrack> group_track, group_track2;
|
||||
shared_ptr<ClipTrack> clip_track;
|
||||
tracks.push_back(group_track = shared_ptr<GroupTrack>(new GroupTrack()));
|
||||
group_track->set_name("Group Track");
|
||||
|
||||
/*if(first)
|
||||
|
||||
if(first)
|
||||
{
|
||||
group_track.add_child_track(shared_ptr<Track>(new ClipTrack()));
|
||||
group_track.add_child_track(
|
||||
group_track2 = shared_ptr<Track>(new GroupTrack()));
|
||||
group_track2.add_child_track(shared_ptr<Track>(new ClipTrack()));
|
||||
group_track->get_child_track_list().push_back(
|
||||
clip_track = shared_ptr<ClipTrack>(new ClipTrack()));
|
||||
group_track->get_child_track_list().push_back(
|
||||
group_track2 = shared_ptr<GroupTrack>(new GroupTrack()));
|
||||
group_track2->set_name("Group Track 2");
|
||||
group_track2->get_child_track_list().push_back(
|
||||
shared_ptr<ClipTrack>(new ClipTrack()));
|
||||
first = false;
|
||||
}*/
|
||||
}
|
||||
|
||||
tracks.push_back(shared_ptr<GroupTrack>(new GroupTrack()));
|
||||
|
||||
tracks.push_back(shared_ptr<Track>(new ClipTrack()));
|
||||
|
||||
// END TEST CODE
|
||||
|
||||
INFO(gui, "\n%s", print_branch().c_str());
|
||||
}
|
||||
|
||||
std::string
|
||||
Sequence::print_track()
|
||||
{
|
||||
std::ostringstream os;
|
||||
|
||||
os << "Sequence\t\"" << get_name() << "\"";
|
||||
|
||||
return os.str();
|
||||
}
|
||||
|
||||
} // namespace model
|
||||
|
|
|
|||
|
|
@ -43,7 +43,8 @@ class Sequence : public ParentTrack
|
|||
public:
|
||||
Sequence();
|
||||
|
||||
|
||||
std::string print_track();
|
||||
|
||||
private:
|
||||
|
||||
};
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@
|
|||
* *****************************************************/
|
||||
|
||||
#include "track.hpp"
|
||||
#include <boost/foreach.hpp>
|
||||
|
||||
namespace gui {
|
||||
namespace model {
|
||||
|
|
@ -38,17 +39,48 @@ Track::get_child_tracks() const
|
|||
return Track::NoChildren;
|
||||
}
|
||||
|
||||
const Glib::ustring
|
||||
const std::string
|
||||
Track::get_name() const
|
||||
{
|
||||
return name;
|
||||
}
|
||||
|
||||
void
|
||||
Track::set_name(const Glib::ustring &name)
|
||||
Track::set_name(const std::string &name)
|
||||
{
|
||||
this->name = name;
|
||||
}
|
||||
|
||||
bool
|
||||
Track::remove_child_track(const boost::shared_ptr<Track> track)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string
|
||||
Track::print_branch()
|
||||
{
|
||||
return print_branch_recursive(0);
|
||||
}
|
||||
|
||||
std::string
|
||||
Track::print_branch_recursive(const unsigned int indentation)
|
||||
{
|
||||
Glib::ustring str;
|
||||
|
||||
for(unsigned int i = 0; i < indentation; i++)
|
||||
str += " ";
|
||||
str += print_track();
|
||||
str += "\n";
|
||||
|
||||
BOOST_FOREACH(boost::shared_ptr<Track> track, get_child_tracks())
|
||||
{
|
||||
REQUIRE(track);
|
||||
str += track->print_branch_recursive(indentation + 1);
|
||||
}
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
} // namespace model
|
||||
} // namespace gui
|
||||
|
|
|
|||
|
|
@ -41,13 +41,24 @@ public:
|
|||
virtual std::list< boost::shared_ptr<Track> >
|
||||
get_child_tracks() const;
|
||||
|
||||
const Glib::ustring get_name() const;
|
||||
const std::string get_name() const;
|
||||
|
||||
void set_name(const Glib::ustring &name);
|
||||
|
||||
void set_name(const std::string &name);
|
||||
|
||||
virtual bool remove_child_track(const boost::shared_ptr<Track> track);
|
||||
|
||||
std::string print_branch();
|
||||
|
||||
virtual std::string print_track() = 0;
|
||||
|
||||
|
||||
|
||||
protected:
|
||||
std::string print_branch_recursive(const unsigned int indentation);
|
||||
|
||||
private:
|
||||
//----- Data -----//
|
||||
Glib::ustring name;
|
||||
std::string name;
|
||||
|
||||
protected:
|
||||
static const std::list< boost::shared_ptr<Track> > NoChildren;
|
||||
|
|
|
|||
|
|
@ -74,10 +74,10 @@ Displayer::calculateVideoLayout(
|
|||
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)
|
||||
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
|
||||
|
|
|
|||
|
|
@ -33,99 +33,97 @@
|
|||
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;
|
||||
|
||||
/** Supported Displayer formats
|
||||
/**
|
||||
* 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 this object can be used to render images on the
|
||||
* running system.
|
||||
*/
|
||||
typedef enum {
|
||||
DISPLAY_NONE,
|
||||
DISPLAY_YUV,
|
||||
DISPLAY_RGB,
|
||||
DISPLAY_BGR,
|
||||
DISPLAY_BGR0,
|
||||
DISPLAY_RGB16
|
||||
}
|
||||
DisplayerInput;
|
||||
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();
|
||||
|
||||
/**
|
||||
* 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.
|
||||
* Put an image of a given width and height with the expected input
|
||||
* format (as indicated by the format method).
|
||||
*/
|
||||
class Displayer
|
||||
{
|
||||
public:
|
||||
virtual void put( const void* ) = 0;
|
||||
|
||||
/**
|
||||
* 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:
|
||||
|
||||
protected:
|
||||
int imageWidth;
|
||||
int imageHeight;
|
||||
};
|
||||
/**
|
||||
* 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
|
||||
|
|
|
|||
|
|
@ -36,49 +36,49 @@ 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;
|
||||
}
|
||||
{
|
||||
REQUIRE(drawing_area != NULL);
|
||||
REQUIRE(width > 0);
|
||||
REQUIRE(height > 0);
|
||||
|
||||
imageWidth = width, imageHeight = height;
|
||||
}
|
||||
|
||||
bool
|
||||
GdkDisplayer::usable()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
{
|
||||
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 );
|
||||
GdkDisplayer::put( const 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();
|
||||
REQUIRE(window != NULL);
|
||||
|
||||
GdkGC *gc = gdk_gc_new( window );
|
||||
REQUIRE(gc != NULL);
|
||||
|
||||
GdkPixbuf *pixbuf = gdk_pixbuf_new_from_data( (const guchar*)image, GDK_COLORSPACE_RGB, FALSE, 8,
|
||||
preferredWidth(), preferredHeight(), preferredWidth() * 3, NULL, NULL );
|
||||
REQUIRE(pixbuf != NULL);
|
||||
|
||||
GdkPixbuf *scaled_image = gdk_pixbuf_scale_simple( pixbuf, video_width, video_height, GDK_INTERP_NEAREST );
|
||||
REQUIRE(scaled_image != NULL);
|
||||
|
||||
gdk_draw_pixbuf( window, gc, scaled_image, 0, 0, video_x, video_y, -1, -1, GDK_RGB_DITHER_NORMAL, 0, 0 );
|
||||
GdkWindow *window = drawingArea->get_window()->gobj();
|
||||
REQUIRE(window != NULL);
|
||||
|
||||
g_object_unref( scaled_image );
|
||||
g_object_unref( pixbuf );
|
||||
g_object_unref( gc );
|
||||
}
|
||||
GdkGC *gc = gdk_gc_new( window );
|
||||
REQUIRE(gc != NULL);
|
||||
|
||||
GdkPixbuf *pixbuf = gdk_pixbuf_new_from_data( (const guchar*)image, GDK_COLORSPACE_RGB, FALSE, 8,
|
||||
preferredWidth(), preferredHeight(), preferredWidth() * 3, NULL, NULL );
|
||||
REQUIRE(pixbuf != NULL);
|
||||
|
||||
GdkPixbuf *scaled_image = gdk_pixbuf_scale_simple( pixbuf, video_width, video_height, GDK_INTERP_NEAREST );
|
||||
REQUIRE(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
|
||||
|
|
|
|||
|
|
@ -40,19 +40,48 @@ namespace Gtk {
|
|||
namespace gui {
|
||||
namespace output {
|
||||
|
||||
/**
|
||||
* GdkDisplayer is a class which is responsible for rendering a video
|
||||
* image via GDK.
|
||||
**/
|
||||
class GdkDisplayer : public Displayer
|
||||
{
|
||||
public:
|
||||
GdkDisplayer( Gtk::Widget *drawing_area, int width, int height );
|
||||
{
|
||||
public:
|
||||
|
||||
void put( void *image );
|
||||
|
||||
protected:
|
||||
bool usable();
|
||||
/**
|
||||
* Constructor
|
||||
* @param[in] drawing_area The widget into which the video image will
|
||||
* be drawn. This value must not be NULL.
|
||||
* @param[in] width The width of the video image in pixels. This value
|
||||
* must be greater than zero.
|
||||
* @param[in] height The height of the video image in pixels. This
|
||||
* value must be greater than zero.
|
||||
**/
|
||||
GdkDisplayer( Gtk::Widget *drawing_area, int width, int height );
|
||||
|
||||
private:
|
||||
Gtk::Widget *drawingArea;
|
||||
};
|
||||
/**
|
||||
* Put an image of a given width and height with the expected input
|
||||
* format (as indicated by the format method).
|
||||
* @param[in] image The video image array to draw.
|
||||
*/
|
||||
void put( const void* image );
|
||||
|
||||
protected:
|
||||
|
||||
/**
|
||||
* Indicates if this object can be used to render images on the
|
||||
* running system.
|
||||
*/
|
||||
bool usable();
|
||||
|
||||
private:
|
||||
|
||||
/**
|
||||
* The widget that video will be drawn into.
|
||||
* @remarks This value must be a valid pointer.
|
||||
**/
|
||||
Gtk::Widget *drawingArea;
|
||||
};
|
||||
|
||||
} // namespace output
|
||||
} // namespace gui
|
||||
|
|
|
|||
|
|
@ -32,193 +32,195 @@ namespace gui {
|
|||
namespace output {
|
||||
|
||||
XvDisplayer::XvDisplayer( Gtk::Widget *drawing_area, int width, int height ) :
|
||||
xvImage( NULL ),
|
||||
gotPort( false ),
|
||||
drawingArea( drawing_area ),
|
||||
gotPort( false )
|
||||
{
|
||||
INFO(gui, "Trying XVideo at %d x %d", width, height);
|
||||
xvImage( NULL )
|
||||
{
|
||||
REQUIRE(drawing_area != NULL);
|
||||
REQUIRE(width > 0);
|
||||
REQUIRE(height > 0);
|
||||
|
||||
INFO(gui, "Trying XVideo at %d x %d", width, height);
|
||||
|
||||
imageWidth = width, imageHeight = height;
|
||||
imageWidth = width, imageHeight = height;
|
||||
|
||||
shmInfo.shmaddr = NULL;
|
||||
shmInfo.shmaddr = NULL;
|
||||
|
||||
Glib::RefPtr<Gdk::Window> area_window = drawing_area->get_window();
|
||||
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() );
|
||||
window = gdk_x11_drawable_get_xid( area_window->gobj() );
|
||||
display = gdk_x11_drawable_get_xdisplay( area_window->gobj() );
|
||||
|
||||
unsigned int count;
|
||||
XvAdaptorInfo *adaptorInfo;
|
||||
unsigned int count;
|
||||
XvAdaptorInfo *adaptorInfo;
|
||||
|
||||
if ( XvQueryAdaptors( display, window, &count, &adaptorInfo ) == Success )
|
||||
{
|
||||
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);
|
||||
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 ++ )
|
||||
for ( unsigned int 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, grabbedPort, &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, grabbedPort, 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, grabbedPort, val_atom, 0x010102 ) != Success )
|
||||
ERROR(gui, "Couldn't set Xv attribute %s\n", xvattr[k].name);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( gotPort )
|
||||
{
|
||||
XGCValues values;
|
||||
memset(&values, 0, sizeof(XGCValues));
|
||||
gc = XCreateGC( display, window, 0, NULL );
|
||||
|
||||
xvImage = ( XvImage * ) XvShmCreateImage( display, grabbedPort, 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 ) )
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
XSync( display, false );
|
||||
shmctl( shmInfo.shmid, IPC_RMID, 0 );
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
gotPort = false;
|
||||
}
|
||||
}
|
||||
|
||||
XvDisplayer::~XvDisplayer()
|
||||
{
|
||||
ERROR(gui, "Destroying XV Displayer");
|
||||
{
|
||||
ERROR(gui, "Destroying XV Displayer");
|
||||
|
||||
if ( gotPort )
|
||||
{
|
||||
XvUngrabPort( display, grabbedPort, CurrentTime );
|
||||
}
|
||||
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 );
|
||||
}
|
||||
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;
|
||||
}
|
||||
{
|
||||
return gotPort;
|
||||
}
|
||||
|
||||
void
|
||||
XvDisplayer::put( void *image )
|
||||
{
|
||||
REQUIRE(image != NULL);
|
||||
REQUIRE(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 );
|
||||
XvDisplayer::put( const void* image )
|
||||
{
|
||||
REQUIRE(image != NULL);
|
||||
REQUIRE(drawingArea != NULL);
|
||||
|
||||
if(xvImage != NULL)
|
||||
{
|
||||
REQUIRE(display != 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 );
|
||||
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 );
|
||||
}
|
||||
}
|
||||
XvShmPutImage( display, grabbedPort, window, gc, xvImage,
|
||||
0, 0, preferredWidth(), preferredHeight(),
|
||||
video_x, video_y, video_width, video_height, false );
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace output
|
||||
} // namespace gui
|
||||
|
|
|
|||
|
|
@ -46,30 +46,90 @@ namespace Gtk {
|
|||
namespace gui {
|
||||
namespace output {
|
||||
|
||||
class XvDisplayer : public Displayer
|
||||
{
|
||||
public:
|
||||
XvDisplayer( Gtk::Widget *drawing_area, int width, int height );
|
||||
~XvDisplayer();
|
||||
|
||||
void put( void *image );
|
||||
/**
|
||||
* XvDisplayer is a class which is responsible for rendering a video
|
||||
* image via XVideo.
|
||||
**/
|
||||
class XvDisplayer : public Displayer
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Constructor
|
||||
* @param drawing_area The widget into which the video image will be
|
||||
* drawn. This value must not be NULL.
|
||||
* @param width The width of the video image in pixels. This value
|
||||
* must be greater than zero.
|
||||
* @param height The height of the video image in pixels. This value
|
||||
* must be greater than zero.
|
||||
**/
|
||||
XvDisplayer( Gtk::Widget *drawing_area, int width, int height );
|
||||
|
||||
protected:
|
||||
bool usable();
|
||||
/**
|
||||
* Destructor
|
||||
**/
|
||||
~XvDisplayer();
|
||||
|
||||
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 ];
|
||||
};
|
||||
/**
|
||||
* Put an image of a given width and height with the expected input
|
||||
* format (as indicated by the format method).
|
||||
* @param[in] image The video image array to draw.
|
||||
*/
|
||||
void put( const void* image );
|
||||
|
||||
/**
|
||||
* Indicates if this object can be used to render images on the
|
||||
* running system.
|
||||
*/
|
||||
bool usable();
|
||||
|
||||
private:
|
||||
|
||||
/**
|
||||
* Specifies whether the object is currently attached to an XVideo
|
||||
* port.
|
||||
* @remarks This value is false until the constructor has finished
|
||||
* successfully.
|
||||
**/
|
||||
bool gotPort;
|
||||
|
||||
/**
|
||||
* The current port being used.
|
||||
* @remarks This value is meaninless unless gotPort is true.
|
||||
**/
|
||||
unsigned int grabbedPort;
|
||||
|
||||
/**
|
||||
* The widget that video will be drawn into.
|
||||
* @remarks This value must be a valid pointer.
|
||||
**/
|
||||
Gtk::Widget *drawingArea;
|
||||
|
||||
/**
|
||||
* The display that video will be drawn into.
|
||||
**/
|
||||
Display *display;
|
||||
|
||||
/**
|
||||
* The X11 window that video will be drawn into.
|
||||
**/
|
||||
Window window;
|
||||
|
||||
/**
|
||||
* The graphics context which will be used when rednering video.
|
||||
**/
|
||||
GC gc;
|
||||
|
||||
/**
|
||||
* The shared memory image object which video will be written into.
|
||||
**/
|
||||
XvImage *xvImage;
|
||||
|
||||
/**
|
||||
* Info about the shared memory segment.
|
||||
* @remarks shmInfo.shmaddr is set to NULL, when the SHM is detached.
|
||||
**/
|
||||
XShmSegmentInfo shmInfo;
|
||||
};
|
||||
|
||||
} // namespace output
|
||||
} // namespace gui
|
||||
|
|
|
|||
|
|
@ -45,6 +45,7 @@ const int TimelinePanel::ZoomToolSteps = 2; // 2 seems comfortable
|
|||
|
||||
TimelinePanel::TimelinePanel(model::Project *const owner_project) :
|
||||
Panel(owner_project, "timeline", _("Timeline"), "panel_timeline"),
|
||||
timeIndicator(),
|
||||
previousButton(Stock::MEDIA_PREVIOUS),
|
||||
rewindButton(Stock::MEDIA_REWIND),
|
||||
playPauseButton(Stock::MEDIA_PLAY),
|
||||
|
|
@ -55,7 +56,6 @@ TimelinePanel::TimelinePanel(model::Project *const owner_project) :
|
|||
iBeamTool(Gtk::StockID("tool_i_beam")),
|
||||
zoomIn(Stock::ZOOM_IN),
|
||||
zoomOut(Stock::ZOOM_OUT),
|
||||
timeIndicator(),
|
||||
updatingToolbar(false),
|
||||
currentTool(timeline::IBeam)
|
||||
{
|
||||
|
|
@ -191,7 +191,7 @@ TimelinePanel::on_page_switched(GtkNotebookPage*, guint)
|
|||
void
|
||||
TimelinePanel::on_mouse_hover(gavl_time_t time)
|
||||
{
|
||||
|
||||
(void)time;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@ namespace widgets {
|
|||
|
||||
const int TimelineWidget::TrackPadding = 1;
|
||||
const int TimelineWidget::HeaderWidth = 150;
|
||||
const int TimelineWidget::HeaderIndentWidth = 10;
|
||||
const double TimelineWidget::ZoomIncrement = 1.25;
|
||||
const int64_t TimelineWidget::MaxScale = 30000000;
|
||||
|
||||
|
|
@ -43,25 +44,25 @@ TimelineWidget::TimelineWidget(
|
|||
shared_ptr<model::Sequence> source_sequence) :
|
||||
Table(2, 2),
|
||||
sequence(source_sequence),
|
||||
layoutHelper(*this),
|
||||
viewWindow(this, 0, 1),
|
||||
totalHeight(0),
|
||||
horizontalAdjustment(0, 0, 0),
|
||||
verticalAdjustment(0, 0, 0),
|
||||
selectionStart(0),
|
||||
selectionEnd(0),
|
||||
playbackPeriodStart(0),
|
||||
playbackPeriodEnd(0),
|
||||
playbackPoint(GAVL_TIME_UNDEFINED),
|
||||
horizontalAdjustment(0, 0, 0),
|
||||
verticalAdjustment(0, 0, 0),
|
||||
horizontalScroll(horizontalAdjustment),
|
||||
verticalScroll(verticalAdjustment)
|
||||
{
|
||||
REQUIRE(sequence);
|
||||
|
||||
body = new TimelineBody(this);
|
||||
body = new TimelineBody(*this);
|
||||
ENSURE(body != NULL);
|
||||
headerContainer = new TimelineHeaderContainer(this);
|
||||
headerContainer = new TimelineHeaderContainer(*this);
|
||||
ENSURE(headerContainer != NULL);
|
||||
ruler = new TimelineRuler(this);
|
||||
ruler = new TimelineRuler(*this);
|
||||
ENSURE(ruler != NULL);
|
||||
|
||||
horizontalAdjustment.signal_value_changed().connect( sigc::mem_fun(
|
||||
|
|
@ -295,22 +296,9 @@ TimelineWidget::update_tracks()
|
|||
// Create timeline tracks from all the model tracks
|
||||
create_timeline_tracks();
|
||||
|
||||
// Update the header container
|
||||
REQUIRE(headerContainer != NULL);
|
||||
headerContainer->show_all_children();
|
||||
headerContainer->update_headers();
|
||||
|
||||
// Update the body
|
||||
body->queue_draw();
|
||||
|
||||
// Recalculate the total height of the timeline scrolled area
|
||||
totalHeight = 0;
|
||||
BOOST_FOREACH(shared_ptr<model::Track> track,
|
||||
sequence->get_child_tracks())
|
||||
{
|
||||
REQUIRE(track);
|
||||
totalHeight += measure_branch_height(track);
|
||||
}
|
||||
// Update the layout helper
|
||||
layoutHelper.clone_tree_from_sequence();
|
||||
layoutHelper.update_layout();
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -323,6 +311,10 @@ TimelineWidget::create_timeline_tracks()
|
|||
BOOST_FOREACH(shared_ptr<model::Track> child,
|
||||
sequence->get_child_tracks())
|
||||
create_timeline_tracks_from_branch(child);
|
||||
|
||||
// Update the header container
|
||||
REQUIRE(headerContainer != NULL);
|
||||
headerContainer->update_headers();
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -359,7 +351,7 @@ TimelineWidget::create_timeline_track_from_model_track(
|
|||
*this, model_track));
|
||||
else if(typeid(*model_track) == typeid(model::GroupTrack))
|
||||
return shared_ptr<timeline::Track>(new timeline::GroupTrack(
|
||||
*this, model_track));
|
||||
*this, dynamic_pointer_cast<model::GroupTrack>(model_track)));
|
||||
|
||||
ASSERT(NULL); // Unknown track type;
|
||||
return shared_ptr<timeline::Track>();
|
||||
|
|
@ -387,7 +379,7 @@ TimelineWidget::remove_orphaned_tracks()
|
|||
pair;
|
||||
BOOST_FOREACH( pair, orphan_track_map )
|
||||
{
|
||||
ENSURE(pair.first)
|
||||
ENSURE(pair.first);
|
||||
trackMap.erase(pair.first);
|
||||
}
|
||||
}
|
||||
|
|
@ -415,6 +407,9 @@ TimelineWidget::lookup_timeline_track(
|
|||
shared_ptr<model::Track> model_track) const
|
||||
{
|
||||
REQUIRE(sequence);
|
||||
REQUIRE(model_track);
|
||||
REQUIRE(model_track != sequence); // The sequence isn't really a track
|
||||
|
||||
std::map<shared_ptr<model::Track>, shared_ptr<timeline::Track> >::
|
||||
const_iterator iterator = trackMap.find(model_track);
|
||||
if(iterator == trackMap.end())
|
||||
|
|
@ -430,30 +425,15 @@ TimelineWidget::lookup_timeline_track(
|
|||
return iterator->second;
|
||||
}
|
||||
|
||||
boost::shared_ptr<model::Track>
|
||||
TimelineWidget::lookup_model_track(
|
||||
const timeline::Track *timeline_track) const
|
||||
void
|
||||
TimelineWidget::on_layout_changed()
|
||||
{
|
||||
REQUIRE(sequence);
|
||||
REQUIRE(headerContainer != NULL);
|
||||
REQUIRE(body != NULL);
|
||||
|
||||
std::pair<shared_ptr<model::Track>, shared_ptr<timeline::Track> >
|
||||
pair;
|
||||
BOOST_FOREACH( pair, trackMap )
|
||||
{
|
||||
if(pair.second.get() == timeline_track)
|
||||
{
|
||||
ENSURE(pair.first);
|
||||
return pair.first;
|
||||
}
|
||||
}
|
||||
|
||||
// The track is not present in the map
|
||||
// We are in an error condition if the timeline track is not found
|
||||
// - the timeline tracks must always be synchronous with the model
|
||||
// tracks.
|
||||
ENSURE(0);
|
||||
return shared_ptr<model::Track>();
|
||||
}
|
||||
headerContainer->on_layout_changed();
|
||||
body->queue_draw();
|
||||
}
|
||||
|
||||
void
|
||||
TimelineWidget::update_scroll()
|
||||
|
|
@ -475,7 +455,8 @@ TimelineWidget::update_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();
|
||||
int y_scroll_length = layoutHelper.get_total_height() -
|
||||
body_allocation.get_height();
|
||||
if(y_scroll_length < 0) y_scroll_length = 0;
|
||||
|
||||
// If by resizing we're now over-scrolled, scroll back to
|
||||
|
|
@ -497,29 +478,6 @@ TimelineWidget::update_scroll()
|
|||
|
||||
}
|
||||
|
||||
int
|
||||
TimelineWidget::measure_branch_height(
|
||||
shared_ptr<model::Track> model_track)
|
||||
{
|
||||
REQUIRE(model_track);
|
||||
|
||||
const shared_ptr<timeline::Track> timeline_track =
|
||||
lookup_timeline_track(model_track);
|
||||
ENSURE(timeline_track);
|
||||
|
||||
int height = timeline_track->get_height() + TrackPadding;
|
||||
|
||||
// Recurse through all the children
|
||||
BOOST_FOREACH( shared_ptr<model::Track> child,
|
||||
model_track->get_child_tracks() )
|
||||
{
|
||||
REQUIRE(child);
|
||||
height += measure_branch_height(child);
|
||||
}
|
||||
|
||||
return height;
|
||||
}
|
||||
|
||||
int
|
||||
TimelineWidget::get_y_scroll_offset() const
|
||||
{
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@
|
|||
#include "timeline/timeline-ibeam-tool.hpp"
|
||||
#include "timeline/timeline-group-track.hpp"
|
||||
#include "timeline/timeline-clip-track.hpp"
|
||||
#include "timeline/timeline-layout-helper.hpp"
|
||||
|
||||
#include "../model/sequence.hpp"
|
||||
|
||||
|
|
@ -216,24 +217,12 @@ private:
|
|||
**/
|
||||
boost::shared_ptr<timeline::Track> lookup_timeline_track(
|
||||
boost::shared_ptr<model::Track> model_track) const;
|
||||
|
||||
/**
|
||||
* Looks up a model track in trackMap that corresponds to a
|
||||
* given timeline track.
|
||||
* @param timeline_track The timeline UI track to look up.
|
||||
* @returns The model track found, or an empty shared_ptr if
|
||||
* timeline_track has no corresponding timeline UI track (this is an
|
||||
* error condition).
|
||||
**/
|
||||
boost::shared_ptr<model::Track> lookup_model_track(
|
||||
const timeline::Track *timeline_track) const;
|
||||
|
||||
// ----- Layout Functions ----- //
|
||||
|
||||
void update_scroll();
|
||||
void on_layout_changed();
|
||||
|
||||
int measure_branch_height(
|
||||
boost::shared_ptr<model::Track> model_track);
|
||||
void update_scroll();
|
||||
|
||||
int get_y_scroll_offset() const;
|
||||
|
||||
|
|
@ -276,6 +265,9 @@ protected:
|
|||
std::map<boost::shared_ptr<model::Track>,
|
||||
boost::shared_ptr<timeline::Track> >
|
||||
trackMap;
|
||||
|
||||
// Helper Classes
|
||||
timeline::TimelineLayoutHelper layoutHelper;
|
||||
|
||||
// View State
|
||||
timeline::TimelineViewWindow viewWindow;
|
||||
|
|
@ -289,8 +281,6 @@ protected:
|
|||
|
||||
boost::shared_ptr<timeline::Track> hoveringTrack;
|
||||
|
||||
int totalHeight;
|
||||
|
||||
// Child Widgets
|
||||
timeline::TimelineHeaderContainer *headerContainer;
|
||||
timeline::TimelineBody *body;
|
||||
|
|
@ -318,16 +308,19 @@ public:
|
|||
protected:
|
||||
static const int TrackPadding;
|
||||
static const int HeaderWidth;
|
||||
static const int HeaderIndentWidth;
|
||||
static const double ZoomIncrement;
|
||||
|
||||
friend class timeline::TimelineViewWindow;
|
||||
friend class timeline::TimelineBody;
|
||||
friend class timeline::TimelineHeaderContainer;
|
||||
friend class timeline::TimelineLayoutHelper;
|
||||
friend class timeline::TimelineRuler;
|
||||
friend class timeline::Tool;
|
||||
friend class timeline::ArrowTool;
|
||||
friend class timeline::IBeamTool;
|
||||
friend class timeline::Track;
|
||||
friend class timeline::GroupTrack;
|
||||
};
|
||||
|
||||
} // namespace widgets
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ namespace gui {
|
|||
namespace widgets {
|
||||
namespace timeline {
|
||||
|
||||
ArrowTool::ArrowTool(TimelineBody *timeline_body) :
|
||||
ArrowTool::ArrowTool(TimelineBody &timeline_body) :
|
||||
Tool(timeline_body)
|
||||
{
|
||||
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ public:
|
|||
* Constructor
|
||||
* @param timeline_body The owner timeline body object
|
||||
*/
|
||||
ArrowTool(TimelineBody *timeline_body);
|
||||
ArrowTool(TimelineBody &timeline_body);
|
||||
|
||||
/**
|
||||
* Gets the type of tool represented by this class
|
||||
|
|
|
|||
|
|
@ -38,21 +38,18 @@ namespace gui {
|
|||
namespace widgets {
|
||||
namespace timeline {
|
||||
|
||||
TimelineBody::TimelineBody(gui::widgets::TimelineWidget
|
||||
*timeline_widget) :
|
||||
TimelineBody::TimelineBody(TimelineWidget &timeline_widget) :
|
||||
Glib::ObjectBase("TimelineBody"),
|
||||
tool(NULL),
|
||||
dragType(None),
|
||||
mouseDownX(0),
|
||||
mouseDownY(0),
|
||||
dragType(None),
|
||||
beginShiftTimeOffset(0),
|
||||
selectionAlpha(0.5),
|
||||
timelineWidget(timeline_widget)
|
||||
{
|
||||
REQUIRE(timelineWidget != NULL);
|
||||
|
||||
{
|
||||
// Connect up some events
|
||||
timelineWidget->get_view_window().changed_signal().connect(
|
||||
timelineWidget.get_view_window().changed_signal().connect(
|
||||
sigc::mem_fun(this, &TimelineBody::on_update_view) );
|
||||
|
||||
// Install style properties
|
||||
|
|
@ -61,42 +58,39 @@ TimelineBody::TimelineBody(gui::widgets::TimelineWidget
|
|||
|
||||
TimelineBody::~TimelineBody()
|
||||
{
|
||||
REQUIRE(tool != NULL);
|
||||
if(tool != NULL)
|
||||
delete tool;
|
||||
WARN_IF(!tool, gui, "An invalid tool pointer is unexpected here");
|
||||
}
|
||||
|
||||
ToolType
|
||||
TimelineBody::get_tool() const
|
||||
{
|
||||
REQUIRE(tool != NULL);
|
||||
if(tool != NULL)
|
||||
return tool->get_type();
|
||||
return gui::widgets::timeline::None;
|
||||
REQUIRE(tool);
|
||||
return tool->get_type();
|
||||
}
|
||||
|
||||
void
|
||||
TimelineBody::set_tool(timeline::ToolType tool_type)
|
||||
{
|
||||
// Tidy up old tool
|
||||
if(tool != NULL)
|
||||
if(tool)
|
||||
{
|
||||
// Do we need to change tools?
|
||||
if(tool->get_type() == tool_type)
|
||||
return;
|
||||
|
||||
delete tool;
|
||||
}
|
||||
|
||||
// Create the new tool
|
||||
switch(tool_type)
|
||||
{
|
||||
case timeline::Arrow:
|
||||
tool = new ArrowTool(this);
|
||||
tool.reset(new ArrowTool(*this));
|
||||
break;
|
||||
|
||||
case timeline::IBeam:
|
||||
tool = new IBeamTool(this);
|
||||
tool.reset(new IBeamTool(*this));
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -130,7 +124,6 @@ bool
|
|||
TimelineBody::on_expose_event(GdkEventExpose* event)
|
||||
{
|
||||
REQUIRE(event != NULL);
|
||||
REQUIRE(timelineWidget != NULL);
|
||||
|
||||
// This is where we draw on the window
|
||||
Glib::RefPtr<Gdk::Window> window = get_window();
|
||||
|
|
@ -158,9 +151,8 @@ bool
|
|||
TimelineBody::on_scroll_event (GdkEventScroll* event)
|
||||
{
|
||||
REQUIRE(event != NULL);
|
||||
REQUIRE(timelineWidget != NULL);
|
||||
|
||||
TimelineViewWindow &window = timelineWidget->get_view_window();
|
||||
TimelineViewWindow &window = timelineWidget.get_view_window();
|
||||
|
||||
if(event->state & GDK_CONTROL_MASK)
|
||||
{
|
||||
|
|
@ -174,7 +166,10 @@ TimelineBody::on_scroll_event (GdkEventScroll* event)
|
|||
case GDK_SCROLL_DOWN:
|
||||
// User scrolled down. Zoom out
|
||||
window.zoom_view(event->x, -1);
|
||||
break;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
@ -189,9 +184,14 @@ TimelineBody::on_scroll_event (GdkEventScroll* event)
|
|||
case GDK_SCROLL_DOWN:
|
||||
// User scrolled down. Shift 1/16th right
|
||||
window.shift_view(16);
|
||||
break;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
|
|
@ -239,7 +239,7 @@ TimelineBody::on_motion_notify_event(GdkEventMotion *event)
|
|||
{
|
||||
case Shift:
|
||||
{
|
||||
TimelineViewWindow &window = timelineWidget->get_view_window();
|
||||
TimelineViewWindow &window = timelineWidget.get_view_window();
|
||||
|
||||
const int64_t scale = window.get_time_scale();
|
||||
gavl_time_t offset = beginShiftTimeOffset +
|
||||
|
|
@ -250,16 +250,19 @@ TimelineBody::on_motion_notify_event(GdkEventMotion *event)
|
|||
beginShiftVerticalOffset);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// Forward the event to the tool
|
||||
tool->on_motion_notify_event(event);
|
||||
|
||||
// See if the track that we're hovering over has changed
|
||||
shared_ptr<timeline::Track> new_hovering_track =
|
||||
track_from_point(event->y);
|
||||
if(timelineWidget->get_hovering_track() != new_hovering_track)
|
||||
timelineWidget->set_hovering_track(new_hovering_track);
|
||||
shared_ptr<timeline::Track> new_hovering_track(
|
||||
timelineWidget.layoutHelper.track_from_y(event->y));
|
||||
if(timelineWidget.get_hovering_track() != new_hovering_track)
|
||||
timelineWidget.set_hovering_track(new_hovering_track);
|
||||
|
||||
// false so that the message is passed up to the owner TimelineWidget
|
||||
return false;
|
||||
|
|
@ -269,39 +272,55 @@ void
|
|||
TimelineBody::draw_tracks(Cairo::RefPtr<Cairo::Context> cr)
|
||||
{
|
||||
REQUIRE(cr);
|
||||
REQUIRE(timelineWidget != NULL);
|
||||
REQUIRE(timelineWidget->sequence);
|
||||
REQUIRE(timelineWidget.sequence);
|
||||
|
||||
// Prepare
|
||||
TimelineLayoutHelper &layout_helper = timelineWidget.layoutHelper;
|
||||
const TimelineLayoutHelper::TrackTree &layout_tree =
|
||||
layout_helper.get_layout_tree();
|
||||
const Allocation allocation = get_allocation();
|
||||
|
||||
// Save the view matrix
|
||||
Cairo::Matrix view_matrix;
|
||||
cr->get_matrix(view_matrix);
|
||||
|
||||
// Translate the view by the scroll distance
|
||||
cr->translate(0, -get_vertical_offset());
|
||||
|
||||
// Interate drawing each track
|
||||
BOOST_FOREACH( shared_ptr<model::Track> model_track,
|
||||
timelineWidget->sequence->get_child_tracks() )
|
||||
draw_track_recursive(cr, model_track, allocation.get_width());
|
||||
// Iterate drawing each track
|
||||
TimelineLayoutHelper::TrackTree::pre_order_iterator iterator;
|
||||
for(iterator = ++layout_tree.begin(); // ++ so we skip the sequence root
|
||||
iterator != layout_tree.end();
|
||||
iterator++)
|
||||
{
|
||||
const shared_ptr<model::Track> model_track(*iterator);
|
||||
const shared_ptr<timeline::Track> timeline_track =
|
||||
timelineWidget.lookup_timeline_track(*iterator);
|
||||
|
||||
optional<Gdk::Rectangle> rect =
|
||||
layout_helper.get_track_header_rect(timeline_track);
|
||||
|
||||
// Is this track visible?
|
||||
if(rect)
|
||||
{
|
||||
// Translate to the top of the track
|
||||
cr->set_matrix(view_matrix);
|
||||
cr->translate(0, rect->get_y());
|
||||
|
||||
// Draw the track
|
||||
draw_track(cr, timeline_track, allocation.get_width());
|
||||
}
|
||||
}
|
||||
|
||||
// Restore the view matrix
|
||||
cr->set_matrix(view_matrix);
|
||||
}
|
||||
|
||||
void
|
||||
TimelineBody::draw_track_recursive(Cairo::RefPtr<Cairo::Context> cr,
|
||||
shared_ptr<model::Track> model_track, const int view_width) const
|
||||
TimelineBody::draw_track(Cairo::RefPtr<Cairo::Context> cr,
|
||||
shared_ptr<timeline::Track> timeline_track,
|
||||
const int view_width) const
|
||||
{
|
||||
REQUIRE(cr);
|
||||
REQUIRE(model_track != NULL);
|
||||
REQUIRE(timelineWidget != NULL);
|
||||
|
||||
shared_ptr<timeline::Track> timeline_track = timelineWidget->
|
||||
lookup_timeline_track(model_track);
|
||||
|
||||
REQUIRE(timeline_track != NULL);
|
||||
|
||||
const int height = timeline_track->get_height();
|
||||
REQUIRE(height >= 0);
|
||||
|
||||
|
|
@ -313,32 +332,23 @@ TimelineBody::draw_track_recursive(Cairo::RefPtr<Cairo::Context> cr,
|
|||
|
||||
// Render the track
|
||||
cr->save();
|
||||
timeline_track->draw_track(cr, &timelineWidget->get_view_window());
|
||||
timeline_track->draw_track(cr, &timelineWidget.get_view_window());
|
||||
cr->restore();
|
||||
|
||||
// Shift for the next track
|
||||
cr->translate(0, height + TimelineWidget::TrackPadding);
|
||||
|
||||
// Recurse drawing into children
|
||||
BOOST_FOREACH( shared_ptr<model::Track> child,
|
||||
model_track->get_child_tracks() )
|
||||
draw_track_recursive(cr, child, view_width);
|
||||
}
|
||||
|
||||
void
|
||||
TimelineBody::draw_selection(Cairo::RefPtr<Cairo::Context> cr)
|
||||
{
|
||||
REQUIRE(cr);
|
||||
REQUIRE(timelineWidget != NULL);
|
||||
|
||||
// Prepare
|
||||
const Allocation allocation = get_allocation();
|
||||
|
||||
const TimelineViewWindow &window = timelineWidget->get_view_window();
|
||||
const TimelineViewWindow &window = timelineWidget.get_view_window();
|
||||
const int start_x = window.time_to_x(
|
||||
timelineWidget->get_selection_start());
|
||||
timelineWidget.get_selection_start());
|
||||
const int end_x = window.time_to_x(
|
||||
timelineWidget->get_selection_end());
|
||||
timelineWidget.get_selection_end());
|
||||
|
||||
// Draw the cover
|
||||
if(end_x > 0 && start_x < allocation.get_width())
|
||||
|
|
@ -377,16 +387,15 @@ void
|
|||
TimelineBody::draw_playback_point(Cairo::RefPtr<Cairo::Context> cr)
|
||||
{
|
||||
REQUIRE(cr);
|
||||
REQUIRE(timelineWidget != NULL);
|
||||
|
||||
// Prepare
|
||||
const Allocation allocation = get_allocation();
|
||||
|
||||
const gavl_time_t point = timelineWidget->get_playback_point();
|
||||
if(point == GAVL_TIME_UNDEFINED)
|
||||
const gavl_time_t point = timelineWidget.get_playback_point();
|
||||
if(point == (gavl_time_t)GAVL_TIME_UNDEFINED)
|
||||
return;
|
||||
|
||||
const int x = timelineWidget->get_view_window().time_to_x(point);
|
||||
const int x = timelineWidget.get_view_window().time_to_x(point);
|
||||
|
||||
// Set source
|
||||
gdk_cairo_set_source_color(cr->cobj(), &playbackPointColour);
|
||||
|
|
@ -406,74 +415,20 @@ TimelineBody::begin_shift_drag()
|
|||
{
|
||||
dragType = Shift;
|
||||
beginShiftTimeOffset =
|
||||
timelineWidget->get_view_window().get_time_offset();
|
||||
timelineWidget.get_view_window().get_time_offset();
|
||||
beginShiftVerticalOffset = get_vertical_offset();
|
||||
}
|
||||
|
||||
int
|
||||
TimelineBody::get_vertical_offset() const
|
||||
{
|
||||
return (int)timelineWidget->verticalAdjustment.get_value();
|
||||
return (int)timelineWidget.verticalAdjustment.get_value();
|
||||
}
|
||||
|
||||
void
|
||||
TimelineBody::set_vertical_offset(int offset)
|
||||
{
|
||||
timelineWidget->verticalAdjustment.set_value(offset);
|
||||
}
|
||||
|
||||
shared_ptr<timeline::Track>
|
||||
TimelineBody::track_from_point(const int y) const
|
||||
{
|
||||
REQUIRE(timelineWidget != NULL);
|
||||
REQUIRE(timelineWidget->sequence);
|
||||
|
||||
int offset = -get_vertical_offset();
|
||||
|
||||
BOOST_FOREACH( shared_ptr<model::Track> model_track,
|
||||
timelineWidget->sequence->get_child_tracks() )
|
||||
{
|
||||
shared_ptr<timeline::Track> result = track_from_branch(
|
||||
model_track, y, offset);
|
||||
if(result)
|
||||
return result;
|
||||
}
|
||||
|
||||
// No track has been found with this point in it
|
||||
return boost::shared_ptr<timeline::Track>();
|
||||
}
|
||||
|
||||
shared_ptr<timeline::Track> TimelineBody::track_from_branch(
|
||||
shared_ptr<model::Track> model_track,
|
||||
const int y, int &offset) const
|
||||
{
|
||||
REQUIRE(timelineWidget != NULL);
|
||||
|
||||
shared_ptr<timeline::Track> timeline_track = timelineWidget->
|
||||
lookup_timeline_track(model_track);
|
||||
|
||||
const int height = timeline_track->get_height();
|
||||
REQUIRE(height >= 0);
|
||||
|
||||
// Does the point fall in this track?
|
||||
if(offset <= y && y < offset + height)
|
||||
return timeline_track;
|
||||
|
||||
// Add the height of this track to the accumulation
|
||||
offset += height;
|
||||
|
||||
// Recurse drawing into children
|
||||
BOOST_FOREACH( shared_ptr<model::Track> child,
|
||||
model_track->get_child_tracks() )
|
||||
{
|
||||
shared_ptr<timeline::Track> result =
|
||||
track_from_branch(child, y, offset);
|
||||
if(result != NULL)
|
||||
return result;
|
||||
}
|
||||
|
||||
// No track has been found in this branch
|
||||
return shared_ptr<timeline::Track>();
|
||||
timelineWidget.verticalAdjustment.set_value(offset);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
|||
|
|
@ -54,9 +54,10 @@ public:
|
|||
|
||||
/**
|
||||
* Constructor
|
||||
* @param timeline_widget The owner widget of this ruler.
|
||||
* @param timeline_widget A reference to the owner widget of this
|
||||
* ruler.
|
||||
*/
|
||||
TimelineBody(gui::widgets::TimelineWidget *timeline_widget);
|
||||
TimelineBody(gui::widgets::TimelineWidget &timeline_widget);
|
||||
|
||||
/**
|
||||
* Destructor
|
||||
|
|
@ -118,8 +119,9 @@ private:
|
|||
*/
|
||||
void draw_tracks(Cairo::RefPtr<Cairo::Context> cr);
|
||||
|
||||
void draw_track_recursive(Cairo::RefPtr<Cairo::Context> cr,
|
||||
boost::shared_ptr<model::Track> track, const int view_width) const;
|
||||
void draw_track(Cairo::RefPtr<Cairo::Context> cr,
|
||||
boost::shared_ptr<timeline::Track> timeline_track,
|
||||
const int view_width) const;
|
||||
|
||||
/**
|
||||
* Draws the selected timeline period.
|
||||
|
|
@ -138,14 +140,7 @@ private:
|
|||
int get_vertical_offset() const;
|
||||
|
||||
void set_vertical_offset(int offset);
|
||||
|
||||
boost::shared_ptr<timeline::Track> track_from_point(const int y)
|
||||
const;
|
||||
|
||||
boost::shared_ptr<timeline::Track> track_from_branch(
|
||||
boost::shared_ptr<model::Track> model_track,
|
||||
const int y, int &offset) const;
|
||||
|
||||
|
||||
/**
|
||||
* Registers all the styles that this class will respond to.
|
||||
*/
|
||||
|
|
@ -165,7 +160,7 @@ private:
|
|||
Shift
|
||||
};
|
||||
|
||||
timeline::Tool *tool;
|
||||
boost::scoped_ptr<timeline::Tool> tool;
|
||||
double mouseDownX, mouseDownY;
|
||||
|
||||
// Scroll State
|
||||
|
|
@ -179,7 +174,7 @@ private:
|
|||
float selectionAlpha;
|
||||
GdkColor playbackPointColour;
|
||||
|
||||
gui::widgets::TimelineWidget* const timelineWidget;
|
||||
gui::widgets::TimelineWidget &timelineWidget;
|
||||
|
||||
friend class Tool;
|
||||
friend class ArrowTool;
|
||||
|
|
|
|||
|
|
@ -21,24 +21,39 @@
|
|||
* *****************************************************/
|
||||
|
||||
#include "timeline-group-track.hpp"
|
||||
#include "../timeline-widget.hpp"
|
||||
|
||||
using namespace Gtk;
|
||||
using namespace boost;
|
||||
using namespace sigc;
|
||||
|
||||
namespace gui {
|
||||
namespace widgets {
|
||||
namespace timeline {
|
||||
|
||||
GroupTrack::GroupTrack(TimelineWidget &timeline_widget,
|
||||
boost::shared_ptr<model::Track> track) :
|
||||
shared_ptr<model::GroupTrack> track) :
|
||||
Track(timeline_widget, track)
|
||||
{
|
||||
REQUIRE(track);
|
||||
|
||||
// Receive notifications of changes to the tracks
|
||||
track->get_child_track_list().signal_changed().connect(
|
||||
sigc::mem_fun( this, &GroupTrack::on_child_list_changed ) );
|
||||
}
|
||||
|
||||
void
|
||||
GroupTrack::on_child_list_changed()
|
||||
{
|
||||
timelineWidget.on_track_list_changed();
|
||||
}
|
||||
|
||||
void
|
||||
GroupTrack::draw_track(Cairo::RefPtr<Cairo::Context> cairo,
|
||||
TimelineViewWindow* const window) const
|
||||
{
|
||||
|
||||
(void)cairo;
|
||||
(void)window;
|
||||
}
|
||||
|
||||
} // namespace timeline
|
||||
|
|
|
|||
|
|
@ -37,11 +37,14 @@ class GroupTrack : public timeline::Track
|
|||
{
|
||||
public:
|
||||
GroupTrack(TimelineWidget &timeline_widget,
|
||||
boost::shared_ptr<model::Track> track);
|
||||
boost::shared_ptr<model::GroupTrack> track);
|
||||
|
||||
void draw_track(Cairo::RefPtr<Cairo::Context> cairo,
|
||||
TimelineViewWindow* constwindow)
|
||||
const;
|
||||
|
||||
protected:
|
||||
void on_child_list_changed();
|
||||
};
|
||||
|
||||
} // namespace timeline
|
||||
|
|
|
|||
|
|
@ -37,14 +37,12 @@ namespace widgets {
|
|||
namespace timeline {
|
||||
|
||||
TimelineHeaderContainer::TimelineHeaderContainer(
|
||||
gui::widgets::TimelineWidget *timeline_widget) :
|
||||
gui::widgets::TimelineWidget &timeline_widget) :
|
||||
Glib::ObjectBase("TimelineHeaderContainer"),
|
||||
timelineWidget(timeline_widget),
|
||||
margin(-1),
|
||||
expand_button_size(12)
|
||||
{
|
||||
REQUIRE(timeline_widget != NULL);
|
||||
|
||||
// This widget will not have a window at first
|
||||
set_flags(Gtk::NO_WINDOW);
|
||||
|
||||
|
|
@ -52,12 +50,12 @@ TimelineHeaderContainer::TimelineHeaderContainer(
|
|||
|
||||
// Connect to the timeline widget's vertical scroll event,
|
||||
// so that we get notified when the view shifts
|
||||
timelineWidget->verticalAdjustment.signal_value_changed().connect(
|
||||
timelineWidget.verticalAdjustment.signal_value_changed().connect(
|
||||
sigc::mem_fun(this, &TimelineHeaderContainer::on_scroll) );
|
||||
|
||||
// Connect to the timeline widget's hover event,
|
||||
// so that we get notified when tracks are hovered on
|
||||
timelineWidget->hovering_track_changed_signal().connect(
|
||||
timelineWidget.hovering_track_changed_signal().connect(
|
||||
sigc::mem_fun(this,
|
||||
&TimelineHeaderContainer::on_hovering_track_changed) );
|
||||
|
||||
|
|
@ -69,14 +67,24 @@ TimelineHeaderContainer::TimelineHeaderContainer(
|
|||
|
||||
// Install style properties
|
||||
register_styles();
|
||||
|
||||
// Load the styles up
|
||||
read_styles();
|
||||
}
|
||||
|
||||
void
|
||||
TimelineHeaderContainer::update_headers()
|
||||
{
|
||||
// Add fresh headers
|
||||
BOOST_FOREACH( shared_ptr<model::Track> model_track, get_tracks() )
|
||||
set_parent_recursive(model_track);
|
||||
{
|
||||
// Ensure headers are parented correctly
|
||||
pair<shared_ptr<model::Track>, shared_ptr<timeline::Track> > pair;
|
||||
BOOST_FOREACH( pair, timelineWidget.trackMap )
|
||||
{
|
||||
REQUIRE(pair.second);
|
||||
Widget &widget = pair.second->get_header_widget();
|
||||
if(widget.get_parent() == NULL) // Is the header unparented?
|
||||
widget.set_parent(*this);
|
||||
ENSURE(widget.get_parent() == this);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -152,8 +160,9 @@ bool TimelineHeaderContainer::on_button_press_event (
|
|||
case 3: // Right Click
|
||||
{
|
||||
// Popup the context menu
|
||||
shared_ptr<Track> header = header_from_point(
|
||||
Gdk::Point(event->x, event->y));
|
||||
shared_ptr<Track> header(
|
||||
timelineWidget.layoutHelper.header_from_point(
|
||||
Gdk::Point(event->x, event->y)));
|
||||
|
||||
// Are we hovering on a header?
|
||||
if(header)
|
||||
|
|
@ -181,9 +190,11 @@ bool TimelineHeaderContainer::on_button_release_event (
|
|||
if(clickedExpander != NULL)
|
||||
{
|
||||
// Yes? The toggle the expanding
|
||||
clickedExpander->set_expanded(!clickedExpander->get_expanded());
|
||||
clickedExpander->expand_collapse(
|
||||
clickedExpander->get_expanded() ? Track::Collapse : Track::Expand);
|
||||
clickedExpander.reset();
|
||||
layout_headers();
|
||||
|
||||
timelineWidget.layoutHelper.update_layout();
|
||||
}
|
||||
|
||||
return Container::on_button_release_event(event);
|
||||
|
|
@ -213,8 +224,20 @@ TimelineHeaderContainer::on_size_request (Requisition* requisition)
|
|||
// We don't care about the size of all the child widgets, but if we
|
||||
// don't send the size request down the tree, some widgets fail to
|
||||
// calculate their text layout correctly.
|
||||
BOOST_FOREACH( shared_ptr<model::Track> model_track, get_tracks() )
|
||||
size_request_recursive(model_track);
|
||||
|
||||
const TimelineLayoutHelper::TrackTree &layout_tree =
|
||||
timelineWidget.layoutHelper.get_layout_tree();
|
||||
|
||||
TimelineLayoutHelper::TrackTree::pre_order_iterator iterator;
|
||||
for(iterator = ++layout_tree.begin(); // ++ so that we skip the sequence root
|
||||
iterator != layout_tree.end();
|
||||
iterator++)
|
||||
{
|
||||
Widget &widget =
|
||||
lookup_timeline_track(*iterator)->get_header_widget();
|
||||
if(widget.is_visible())
|
||||
widget.size_request();
|
||||
}
|
||||
|
||||
// Initialize the output parameter:
|
||||
*requisition = Gtk::Requisition();
|
||||
|
|
@ -246,35 +269,43 @@ TimelineHeaderContainer::forall_vfunc(gboolean /* include_internals */,
|
|||
{
|
||||
REQUIRE(callback != NULL);
|
||||
|
||||
BOOST_FOREACH( shared_ptr<model::Track> track, get_tracks() )
|
||||
pair<shared_ptr<model::Track>, shared_ptr<timeline::Track> > pair;
|
||||
BOOST_FOREACH( pair, timelineWidget.trackMap )
|
||||
{
|
||||
REQUIRE(track);
|
||||
forall_vfunc_recursive(track, callback, callback_data);
|
||||
REQUIRE(pair.second);
|
||||
callback(pair.second->get_header_widget().gobj(), callback_data);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
TimelineHeaderContainer::on_remove(Widget* widget)
|
||||
TimelineHeaderContainer::on_remove(Widget*)
|
||||
{
|
||||
// Do nothing - this is just to keep Gtk::Container happy
|
||||
}
|
||||
|
||||
void
|
||||
TimelineHeaderContainer::on_layout_changed()
|
||||
{
|
||||
layout_headers();
|
||||
}
|
||||
|
||||
bool
|
||||
TimelineHeaderContainer::on_expose_event(GdkEventExpose *event)
|
||||
{
|
||||
if(gdkWindow)
|
||||
{
|
||||
// Start at an offset from the scroll offset
|
||||
int offset = -timelineWidget->get_y_scroll_offset();
|
||||
|
||||
const Allocation container_allocation = get_allocation();
|
||||
|
||||
read_styles();
|
||||
|
||||
// Paint a border underneath all the root headers
|
||||
BOOST_FOREACH( shared_ptr<model::Track> model_track,
|
||||
get_tracks() )
|
||||
// Paint a border underneath all the headers
|
||||
const TimelineLayoutHelper::TrackTree &layout_tree =
|
||||
timelineWidget.layoutHelper.get_layout_tree();
|
||||
|
||||
TimelineLayoutHelper::TrackTree::pre_order_iterator iterator;
|
||||
for(iterator = ++layout_tree.begin(); // ++ so that we skip the sequence root
|
||||
iterator != layout_tree.end();
|
||||
iterator++)
|
||||
{
|
||||
shared_ptr<model::Track> model_track = *iterator;
|
||||
REQUIRE(model_track);
|
||||
|
||||
draw_header_decoration(model_track,
|
||||
|
|
@ -299,145 +330,66 @@ void
|
|||
TimelineHeaderContainer::on_hovering_track_changed(
|
||||
boost::shared_ptr<timeline::Track> hovering_track)
|
||||
{
|
||||
(void)hovering_track;
|
||||
|
||||
// The hovering track has changed, redraw so we can light the header
|
||||
queue_draw();
|
||||
}
|
||||
|
||||
void
|
||||
TimelineHeaderContainer::layout_headers()
|
||||
{
|
||||
{
|
||||
REQUIRE(margin >= 0); // read_styles must have been called before now
|
||||
|
||||
// We can't layout before the widget has been set up
|
||||
if(!gdkWindow)
|
||||
return;
|
||||
|
||||
// Make sure the style are loaded
|
||||
read_styles();
|
||||
|
||||
// Clear previously cached layout
|
||||
headerBoxes.clear();
|
||||
|
||||
// Start at minus-the-scroll offset
|
||||
int offset = -timelineWidget->get_y_scroll_offset();
|
||||
|
||||
const Allocation container_allocation = get_allocation();
|
||||
const int header_width = container_allocation.get_width();
|
||||
TimelineLayoutHelper &layout_helper =
|
||||
timelineWidget.layoutHelper;
|
||||
const TimelineLayoutHelper::TrackTree &layout_tree =
|
||||
layout_helper.get_layout_tree();
|
||||
|
||||
BOOST_FOREACH( shared_ptr<model::Track> model_track, get_tracks() )
|
||||
layout_headers_recursive(
|
||||
model_track, offset, header_width, 0, true);
|
||||
TimelineLayoutHelper::TrackTree::pre_order_iterator iterator;
|
||||
for(iterator = ++layout_tree.begin(); // ++ so that we skip the sequence root
|
||||
iterator != layout_tree.end();
|
||||
iterator++)
|
||||
{
|
||||
const shared_ptr<timeline::Track> timeline_track =
|
||||
lookup_timeline_track(*iterator);
|
||||
|
||||
Widget &widget = timeline_track->get_header_widget();
|
||||
|
||||
optional<Gdk::Rectangle> header_rect =
|
||||
layout_helper.get_track_header_rect(timeline_track);
|
||||
|
||||
if(header_rect)
|
||||
{
|
||||
REQUIRE(header_rect->get_width() >= 0);
|
||||
REQUIRE(header_rect->get_height() >= 0);
|
||||
|
||||
// Calculate the allocation of the header widget
|
||||
Allocation header_allocation(
|
||||
header_rect->get_x() + margin + expand_button_size, // x
|
||||
header_rect->get_y() + margin, // y
|
||||
max( header_rect->get_width() - expand_button_size -
|
||||
margin * 2, 0 ), // width
|
||||
header_rect->get_height() - margin * 2); // height
|
||||
|
||||
// Apply the allocation to the header
|
||||
widget.size_allocate (header_allocation);
|
||||
if(!widget.is_visible())
|
||||
widget.show();
|
||||
}
|
||||
else // No header rect, so the track must be hidden
|
||||
if(widget.is_visible())
|
||||
widget.hide();
|
||||
}
|
||||
|
||||
// Repaint the background of our parenting
|
||||
queue_draw ();
|
||||
}
|
||||
|
||||
void
|
||||
TimelineHeaderContainer::layout_headers_recursive(
|
||||
shared_ptr<model::Track> model_track, int &offset,
|
||||
const int header_width, const int depth, bool parent_expanded)
|
||||
{
|
||||
REQUIRE(depth >= 0);
|
||||
REQUIRE(model_track != NULL);
|
||||
|
||||
shared_ptr<timeline::Track> timeline_track =
|
||||
lookup_timeline_track(model_track);
|
||||
|
||||
const int indent = depth * 10;
|
||||
Widget &widget = timeline_track->get_header_widget();
|
||||
|
||||
if(parent_expanded)
|
||||
{
|
||||
const int track_height = timeline_track->get_height();
|
||||
|
||||
// Calculate the box of the header
|
||||
Gdk::Rectangle header_box(
|
||||
indent, // x
|
||||
offset, // y
|
||||
max( header_width - indent, 0 ), // width
|
||||
track_height); // height
|
||||
REQUIRE(header_box.get_height() >= 0);
|
||||
|
||||
// Cache the bounding box
|
||||
headerBoxes[timeline_track] = header_box;
|
||||
|
||||
// Calculate the allocation of the header widget
|
||||
Allocation header_allocation(
|
||||
header_box.get_x() + margin + expand_button_size, // x
|
||||
header_box.get_y() + margin, // y
|
||||
max( header_box.get_width() - expand_button_size -
|
||||
margin * 2, 0 ), // width
|
||||
header_box.get_height() - margin * 2); // height
|
||||
|
||||
// Apply the allocation to the header
|
||||
widget.size_allocate (header_allocation);
|
||||
if(!widget.is_visible())
|
||||
widget.show();
|
||||
|
||||
// Offset for the next header
|
||||
offset += track_height + TimelineWidget::TrackPadding;
|
||||
}
|
||||
else
|
||||
if(widget.is_visible())
|
||||
widget.hide();
|
||||
|
||||
// Recurse through all the children
|
||||
BOOST_FOREACH( boost::shared_ptr<model::Track> child,
|
||||
model_track->get_child_tracks() )
|
||||
layout_headers_recursive(
|
||||
child, offset, header_width, depth + 1,
|
||||
timeline_track->get_expanded() && parent_expanded);
|
||||
}
|
||||
|
||||
void
|
||||
TimelineHeaderContainer::set_parent_recursive(
|
||||
boost::shared_ptr<model::Track> model_track)
|
||||
{
|
||||
// Set the header's parent widget
|
||||
Widget &widget = lookup_timeline_track(model_track)->
|
||||
get_header_widget();
|
||||
|
||||
const Container *parent = widget.get_parent();
|
||||
if(parent == NULL) // Is the header unparented?
|
||||
widget.set_parent(*this);
|
||||
else if(parent != this) // The header is parented by another container
|
||||
widget.reparent(*this);
|
||||
|
||||
// Recurse through all the children
|
||||
BOOST_FOREACH( shared_ptr<model::Track> child,
|
||||
model_track->get_child_tracks() )
|
||||
set_parent_recursive(child);
|
||||
}
|
||||
|
||||
void
|
||||
TimelineHeaderContainer::size_request_recursive(
|
||||
shared_ptr<model::Track> const model_track)
|
||||
{
|
||||
Widget &widget =
|
||||
lookup_timeline_track(model_track)->get_header_widget();
|
||||
if(widget.is_visible())
|
||||
widget.size_request();
|
||||
|
||||
// Recurse through all the children
|
||||
BOOST_FOREACH( shared_ptr<model::Track> child,
|
||||
model_track->get_child_tracks() )
|
||||
size_request_recursive(child);
|
||||
}
|
||||
|
||||
void
|
||||
TimelineHeaderContainer::forall_vfunc_recursive(
|
||||
shared_ptr<model::Track> model_track, GtkCallback callback,
|
||||
gpointer callback_data)
|
||||
{
|
||||
REQUIRE(callback != NULL);
|
||||
|
||||
callback( lookup_timeline_track(model_track)->
|
||||
get_header_widget().gobj(), callback_data) ;
|
||||
|
||||
// Recurse through all the children
|
||||
BOOST_FOREACH( shared_ptr<model::Track> child,
|
||||
model_track->get_child_tracks() )
|
||||
forall_vfunc_recursive(child, callback, callback_data);
|
||||
}
|
||||
|
||||
void
|
||||
TimelineHeaderContainer::draw_header_decoration(
|
||||
shared_ptr<model::Track> model_track,
|
||||
|
|
@ -453,102 +405,90 @@ TimelineHeaderContainer::draw_header_decoration(
|
|||
shared_ptr<timeline::Track> timeline_track =
|
||||
lookup_timeline_track(model_track);
|
||||
|
||||
// Get the cached header box
|
||||
weak_ptr<timeline::Track> ptr(timeline_track);
|
||||
REQUIRE(contains(headerBoxes, ptr));
|
||||
const Gdk::Rectangle &box = headerBoxes[timeline_track];
|
||||
// Get the header box
|
||||
const optional<Gdk::Rectangle> &optional_box =
|
||||
timelineWidget.layoutHelper.get_track_header_rect(timeline_track);
|
||||
if(!optional_box)
|
||||
return;
|
||||
const Gdk::Rectangle box = *optional_box;
|
||||
|
||||
// Paint the box, if it will be visible
|
||||
if(box.get_x() < clip_rect.get_width() &&
|
||||
box.get_height() > 0 &&
|
||||
box.get_y() + box.get_height() > clip_rect.get_y() &&
|
||||
box.get_y() < clip_rect.get_y() + clip_rect.get_height())
|
||||
{
|
||||
// Use paint_box to draw a themed bevel around the header
|
||||
style->paint_box(gdkWindow, STATE_NORMAL,
|
||||
SHADOW_OUT, clip_rect, *this, "",
|
||||
box.get_x(), box.get_y(),
|
||||
box.get_width(), box.get_height());
|
||||
|
||||
// Paint the expander if there are child tracks
|
||||
StateType state_type = STATE_NORMAL;
|
||||
if(clickedExpander == timeline_track)
|
||||
state_type = STATE_SELECTED;
|
||||
else if(hoveringExpander == timeline_track)
|
||||
state_type = STATE_PRELIGHT;
|
||||
|
||||
const ExpanderStyle expander_style =
|
||||
timeline_track->get_expanded() ?
|
||||
EXPANDER_EXPANDED : EXPANDER_COLLAPSED;
|
||||
|
||||
if(!model_track->get_child_tracks().empty())
|
||||
style->paint_expander (gdkWindow,
|
||||
state_type,
|
||||
clip_rect, *this, "",
|
||||
box.get_x() + expand_button_size / 2 + margin,
|
||||
box.get_y() + box.get_height() / 2,
|
||||
expander_style);
|
||||
}
|
||||
|
||||
// Recurse through all the children
|
||||
if(timeline_track->get_expanded())
|
||||
BOOST_FOREACH( shared_ptr<model::Track> child,
|
||||
model_track->get_child_tracks() )
|
||||
draw_header_decoration(child, clip_rect);
|
||||
}
|
||||
// Don't paint the box, if it won't be visible
|
||||
if(box.get_x() >= clip_rect.get_width() ||
|
||||
box.get_height() <= 0 ||
|
||||
box.get_y() + box.get_height() <= clip_rect.get_y() ||
|
||||
box.get_y() >= clip_rect.get_y() + clip_rect.get_height())
|
||||
return;
|
||||
|
||||
boost::shared_ptr<timeline::Track>
|
||||
TimelineHeaderContainer::header_from_point(const Gdk::Point &point)
|
||||
{
|
||||
std::pair<shared_ptr<timeline::Track>, Gdk::Rectangle> pair;
|
||||
BOOST_FOREACH( pair, headerBoxes )
|
||||
{
|
||||
// Hit test the rectangle
|
||||
const Gdk::Rectangle &rect = pair.second;
|
||||
|
||||
if(point.get_x() >= rect.get_x() &&
|
||||
point.get_x() < rect.get_x() + rect.get_width() &&
|
||||
point.get_y() >= rect.get_y() &&
|
||||
point.get_y() < rect.get_y() + rect.get_height())
|
||||
return pair.first;
|
||||
}
|
||||
// Use paint_box to draw a themed bevel around the header
|
||||
style->paint_box(gdkWindow, STATE_NORMAL,
|
||||
SHADOW_OUT, clip_rect, *this, "",
|
||||
box.get_x(), box.get_y(),
|
||||
box.get_width(), box.get_height());
|
||||
|
||||
return shared_ptr<timeline::Track>();
|
||||
// Paint the expander if there are child tracks
|
||||
StateType state_type = STATE_NORMAL;
|
||||
if(clickedExpander == timeline_track)
|
||||
state_type = STATE_SELECTED;
|
||||
else if(hoveringExpander == timeline_track)
|
||||
state_type = STATE_PRELIGHT;
|
||||
|
||||
if(!model_track->get_child_tracks().empty())
|
||||
style->paint_expander (gdkWindow,
|
||||
state_type,
|
||||
clip_rect, *this, "",
|
||||
box.get_x() + expand_button_size / 2 + margin,
|
||||
box.get_y() + box.get_height() / 2,
|
||||
timeline_track->get_expander_style());
|
||||
}
|
||||
|
||||
shared_ptr<timeline::Track>
|
||||
TimelineHeaderContainer::expander_button_from_point(
|
||||
const Gdk::Point &point)
|
||||
{
|
||||
std::pair<shared_ptr<timeline::Track>, Gdk::Rectangle> pair;
|
||||
BOOST_FOREACH( pair, headerBoxes )
|
||||
{
|
||||
const TimelineLayoutHelper::TrackTree &layout_tree =
|
||||
timelineWidget.layoutHelper.get_layout_tree();
|
||||
|
||||
TimelineLayoutHelper::TrackTree::pre_order_iterator iterator;
|
||||
for(iterator = ++layout_tree.begin(); // ++ so we skip the sequence root
|
||||
iterator != layout_tree.end();
|
||||
iterator++)
|
||||
{
|
||||
// Hit test the rectangle
|
||||
const Gdk::Rectangle rect =
|
||||
get_expander_button_rectangle(pair.first);
|
||||
const shared_ptr<timeline::Track> timeline_track =
|
||||
lookup_timeline_track(*iterator);
|
||||
|
||||
if(point.get_x() >= rect.get_x() &&
|
||||
point.get_x() < rect.get_x() + rect.get_width() &&
|
||||
point.get_y() >= rect.get_y() &&
|
||||
point.get_y() < rect.get_y() + rect.get_height())
|
||||
return pair.first;
|
||||
// Hit test the rectangle
|
||||
const optional<Gdk::Rectangle> rect =
|
||||
get_expander_button_rectangle(timeline_track);
|
||||
|
||||
if(rect)
|
||||
{
|
||||
if(point.get_x() >= rect->get_x() &&
|
||||
point.get_x() < rect->get_x() + rect->get_width() &&
|
||||
point.get_y() >= rect->get_y() &&
|
||||
point.get_y() < rect->get_y() + rect->get_height())
|
||||
return timeline_track;
|
||||
}
|
||||
}
|
||||
|
||||
return shared_ptr<timeline::Track>();
|
||||
}
|
||||
|
||||
const Gdk::Rectangle
|
||||
const optional<Gdk::Rectangle>
|
||||
TimelineHeaderContainer::get_expander_button_rectangle(
|
||||
shared_ptr<Track> track)
|
||||
{
|
||||
REQUIRE(track != NULL);
|
||||
weak_ptr<timeline::Track> ptr(track);
|
||||
REQUIRE(contains(headerBoxes, ptr));
|
||||
|
||||
const Gdk::Rectangle &box = headerBoxes[track];
|
||||
return Gdk::Rectangle(
|
||||
margin + box.get_x(), margin + box.get_y(),
|
||||
expand_button_size, box.get_height() - margin * 2);
|
||||
optional<Gdk::Rectangle> box =
|
||||
timelineWidget.layoutHelper.get_track_header_rect(track);
|
||||
if(box)
|
||||
{
|
||||
return optional<Gdk::Rectangle>(Gdk::Rectangle(
|
||||
margin + box->get_x(), margin + box->get_y(),
|
||||
expand_button_size, box->get_height() - margin * 2));
|
||||
}
|
||||
|
||||
return optional<Gdk::Rectangle>();
|
||||
}
|
||||
|
||||
shared_ptr<timeline::Track>
|
||||
|
|
@ -556,23 +496,14 @@ TimelineHeaderContainer::lookup_timeline_track(
|
|||
shared_ptr<model::Track> model_track)
|
||||
{
|
||||
REQUIRE(model_track != NULL);
|
||||
REQUIRE(timelineWidget != NULL);
|
||||
|
||||
shared_ptr<timeline::Track> timeline_track =
|
||||
timelineWidget->lookup_timeline_track(model_track);
|
||||
timelineWidget.lookup_timeline_track(model_track);
|
||||
ENSURE(timeline_track);
|
||||
|
||||
return timeline_track;
|
||||
}
|
||||
|
||||
const std::list< boost::shared_ptr<model::Track> >
|
||||
TimelineHeaderContainer::get_tracks() const
|
||||
{
|
||||
REQUIRE(timelineWidget != NULL);
|
||||
REQUIRE(timelineWidget->sequence);
|
||||
return timelineWidget->sequence->get_child_tracks();
|
||||
}
|
||||
|
||||
void
|
||||
TimelineHeaderContainer::register_styles() const
|
||||
{
|
||||
|
|
@ -593,7 +524,13 @@ void
|
|||
TimelineHeaderContainer::read_styles()
|
||||
{
|
||||
if(margin <= 0)
|
||||
get_style_property("heading_margin", margin);
|
||||
{
|
||||
get_style_property("heading_margin", margin);
|
||||
margin = max(margin, 0);
|
||||
}
|
||||
else
|
||||
WARN(gui, "TimelineHeaderContainer::read_styles()"
|
||||
" should only be called once");
|
||||
}
|
||||
|
||||
} // namespace timeline
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
timeline-header-container.cpp - Declaration of the timeline
|
||||
timeline-header-container.hpp - Declaration of the timeline
|
||||
header container widget
|
||||
|
||||
Copyright (C) Lumiera.org
|
||||
|
|
@ -55,9 +55,10 @@ public:
|
|||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param[in] timeline_widget A pointer to the owner timeline widget
|
||||
* @param[in] timeline_widget A reference to the owner timeline widget
|
||||
*/
|
||||
TimelineHeaderContainer(gui::widgets::TimelineWidget* timeline_widget);
|
||||
TimelineHeaderContainer(
|
||||
gui::widgets::TimelineWidget &timeline_widget);
|
||||
|
||||
/**
|
||||
* Attaches the header all the header widgets of root
|
||||
|
|
@ -123,11 +124,13 @@ private:
|
|||
* An event handler that is called when a widget is removed from the
|
||||
* container.
|
||||
**/
|
||||
void on_remove(Widget* widget);
|
||||
void on_remove(Widget*);
|
||||
|
||||
/* ===== Events ===== */
|
||||
private:
|
||||
|
||||
void on_layout_changed();
|
||||
|
||||
/**
|
||||
* An event handler for when the window must be redrawn.
|
||||
*/
|
||||
|
|
@ -149,45 +152,7 @@ private:
|
|||
* stacking etc.
|
||||
*/
|
||||
void layout_headers();
|
||||
|
||||
/**
|
||||
* Recursively lays out all the controls in the header widget.
|
||||
* @param track The parent track object which will be recursed into.
|
||||
* @param offset A shared value used to accumulate the y-offset of
|
||||
* header widgets.
|
||||
* @param header_width The width of this widget in pixels.
|
||||
* @param depth The depth within the tree of track.
|
||||
**/
|
||||
void layout_headers_recursive(boost::shared_ptr<model::Track> track,
|
||||
int &offset, const int header_width, const int depth,
|
||||
bool parent_expanded);
|
||||
|
||||
/**
|
||||
* Recursively sets all the track header widgets to be child widgets
|
||||
* of this widget.
|
||||
* @param track The parent track object which will be recursed into.
|
||||
**/
|
||||
void set_parent_recursive(boost::shared_ptr<model::Track> const
|
||||
model_track);
|
||||
|
||||
/**
|
||||
* Recursively causes all the visible track header widgets in a branch
|
||||
* to call size_request( ).
|
||||
**/
|
||||
void size_request_recursive(
|
||||
boost::shared_ptr<model::Track> model_track);
|
||||
|
||||
/**
|
||||
* Recursively calls a callback on all the header widgets in a branch.
|
||||
* @param model_track The root track of the branch.
|
||||
* @param callback The callback to apply to the branch. This includes
|
||||
* model_track and all it's children.
|
||||
* @param callback_data The user data parameter for the callback.
|
||||
**/
|
||||
void forall_vfunc_recursive(
|
||||
boost::shared_ptr<model::Track> model_track,
|
||||
GtkCallback callback, gpointer callback_data);
|
||||
|
||||
|
||||
/**
|
||||
* Draws the border decoration around the track header.
|
||||
* @param model_track The track to draw the decoration for.
|
||||
|
|
@ -199,9 +164,6 @@ private:
|
|||
void draw_header_decoration(
|
||||
boost::shared_ptr<model::Track> model_track,
|
||||
const Gdk::Rectangle &clip_rect);
|
||||
|
||||
boost::shared_ptr<timeline::Track> header_from_point(
|
||||
const Gdk::Point &point);
|
||||
|
||||
/**
|
||||
* Given a point, expander_button_from_point finds the track of the
|
||||
|
|
@ -219,7 +181,7 @@ private:
|
|||
* @param track The track to get the expander button rectangle of.
|
||||
* @return Returns the rectangle of the expander button of track.
|
||||
**/
|
||||
const Gdk::Rectangle get_expander_button_rectangle(
|
||||
const boost::optional<Gdk::Rectangle> get_expander_button_rectangle(
|
||||
boost::shared_ptr<timeline::Track> track);
|
||||
|
||||
/**
|
||||
|
|
@ -234,17 +196,6 @@ private:
|
|||
**/
|
||||
boost::shared_ptr<timeline::Track> lookup_timeline_track(
|
||||
boost::shared_ptr<model::Track> model_track);
|
||||
|
||||
/**
|
||||
* A helper function which calls get_tracks within the sequence of the
|
||||
* parent timeline widget, but also applies lots of data consistency
|
||||
* checks in the process.
|
||||
* @param model_track The model track to look up in the parent widget.
|
||||
* @return Returns the track found, or returns NULL if no matching
|
||||
* track was found.
|
||||
**/
|
||||
const std::list< boost::shared_ptr<model::Track> >
|
||||
get_tracks() const;
|
||||
|
||||
/**
|
||||
* Registers all the styles that this class will respond to.
|
||||
|
|
@ -261,7 +212,7 @@ private:
|
|||
/**
|
||||
* The owner TimelineWidget of which this class is a helper
|
||||
*/
|
||||
gui::widgets::TimelineWidget* const timelineWidget;
|
||||
gui::widgets::TimelineWidget &timelineWidget;
|
||||
|
||||
/**
|
||||
* The widget's window object.
|
||||
|
|
@ -278,16 +229,7 @@ private:
|
|||
* click is not processed by track headers.
|
||||
**/
|
||||
Gtk::Menu contextMenu;
|
||||
|
||||
/**
|
||||
* A map of tracks to the rectangles of their headers.
|
||||
* @remarks This map is used as a cache, so that the rectangles don't
|
||||
* need to be perpetually recalculated. This cache is regenerated by
|
||||
* the layout_headers method.
|
||||
**/
|
||||
std::map<boost::weak_ptr<timeline::Track>, Gdk::Rectangle>
|
||||
headerBoxes;
|
||||
|
||||
|
||||
//----- User Interaction State -----//
|
||||
boost::shared_ptr<timeline::Track> hoveringExpander;
|
||||
|
||||
|
|
@ -307,6 +249,7 @@ private:
|
|||
**/
|
||||
int expand_button_size;
|
||||
|
||||
friend class gui::widgets::TimelineWidget;
|
||||
friend class timeline::Track;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -37,11 +37,11 @@ const int IBeamTool::ScrollSlideEventInterval = 40;
|
|||
|
||||
// ===== Implementation ===== //
|
||||
|
||||
IBeamTool::IBeamTool(TimelineBody *timeline_body) :
|
||||
IBeamTool::IBeamTool(TimelineBody &timeline_body) :
|
||||
Tool(timeline_body),
|
||||
dragType(None),
|
||||
pinnedDragTime(0),
|
||||
scrollSlideRate(0),
|
||||
Tool(timeline_body)
|
||||
scrollSlideRate(0)
|
||||
{
|
||||
|
||||
}
|
||||
|
|
@ -70,6 +70,8 @@ IBeamTool::get_cursor() const
|
|||
return Gdk::Cursor(Gdk::LEFT_SIDE);
|
||||
case GrabEnd:
|
||||
return Gdk::Cursor(Gdk::RIGHT_SIDE);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// Are we hovering over the ends of the selection?
|
||||
|
|
@ -88,32 +90,31 @@ IBeamTool::on_button_press_event(GdkEventButton* event)
|
|||
{
|
||||
Tool::on_button_press_event(event);
|
||||
|
||||
TimelineWidget *timeline_widget = get_timeline_widget();
|
||||
REQUIRE(timeline_widget != NULL);
|
||||
TimelineWidget &timeline_widget = get_timeline_widget();
|
||||
|
||||
if(event->button == 1)
|
||||
{
|
||||
const gavl_time_t time =
|
||||
get_timeline_widget()->get_view_window().x_to_time(event->x);
|
||||
timeline_widget.get_view_window().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();
|
||||
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();
|
||||
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);
|
||||
timeline_widget.set_selection(time, time);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -172,7 +173,7 @@ IBeamTool::on_motion_notify_event(GdkEventMotion *event)
|
|||
bool
|
||||
IBeamTool::on_scroll_slide_timer()
|
||||
{
|
||||
get_timeline_widget()->get_view_window().shift_view(scrollSlideRate);
|
||||
get_timeline_widget().get_view_window().shift_view(scrollSlideRate);
|
||||
|
||||
// Return true to keep the timer going
|
||||
return true;
|
||||
|
|
@ -181,17 +182,16 @@ IBeamTool::on_scroll_slide_timer()
|
|||
void
|
||||
IBeamTool::set_leading_x(const int x)
|
||||
{
|
||||
TimelineWidget *timeline_widget = get_timeline_widget();
|
||||
REQUIRE(timeline_widget != NULL);
|
||||
TimelineWidget &timeline_widget = get_timeline_widget();
|
||||
|
||||
const bool set_playback_period = dragType == Selection;
|
||||
const gavl_time_t time =
|
||||
timeline_widget->get_view_window().x_to_time(x);
|
||||
timeline_widget.get_view_window().x_to_time(x);
|
||||
if(time > pinnedDragTime)
|
||||
timeline_widget->set_selection(
|
||||
timeline_widget.set_selection(
|
||||
pinnedDragTime, time, set_playback_period);
|
||||
else
|
||||
timeline_widget->set_selection(
|
||||
timeline_widget.set_selection(
|
||||
time, pinnedDragTime, set_playback_period);
|
||||
}
|
||||
|
||||
|
|
@ -216,10 +216,10 @@ IBeamTool::end_scroll_slide()
|
|||
bool
|
||||
IBeamTool::is_mouse_in_start_drag_zone() const
|
||||
{
|
||||
TimelineWidget *timeline_widget = get_timeline_widget();
|
||||
TimelineWidget &timeline_widget = get_timeline_widget();
|
||||
|
||||
const int start_x = timeline_widget->get_view_window().time_to_x(
|
||||
timeline_widget->get_selection_start());
|
||||
const int start_x = timeline_widget.get_view_window().time_to_x(
|
||||
timeline_widget.get_selection_start());
|
||||
|
||||
return (mousePoint.get_x() <= start_x &&
|
||||
mousePoint.get_x() > start_x - DragZoneWidth);
|
||||
|
|
@ -228,10 +228,10 @@ IBeamTool::is_mouse_in_start_drag_zone() const
|
|||
bool
|
||||
IBeamTool::is_mouse_in_end_drag_zone() const
|
||||
{
|
||||
TimelineWidget *timeline_widget = get_timeline_widget();
|
||||
TimelineWidget &timeline_widget = get_timeline_widget();
|
||||
|
||||
const int end_x = timeline_widget->get_view_window().time_to_x(
|
||||
timeline_widget->get_selection_end());
|
||||
const int end_x = timeline_widget.get_view_window().time_to_x(
|
||||
timeline_widget.get_selection_end());
|
||||
|
||||
return (mousePoint.get_x() >= end_x &&
|
||||
mousePoint.get_x() < end_x + DragZoneWidth);
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ public:
|
|||
* Constructor
|
||||
* @param timeline_body The owner timeline body object
|
||||
*/
|
||||
IBeamTool(TimelineBody *timeline_body);
|
||||
IBeamTool(TimelineBody &timeline_body);
|
||||
|
||||
/**
|
||||
* Gets the type of tool represented by this class
|
||||
|
|
|
|||
290
src/gui/widgets/timeline/timeline-layout-helper.cpp
Normal file
290
src/gui/widgets/timeline/timeline-layout-helper.cpp
Normal file
|
|
@ -0,0 +1,290 @@
|
|||
/*
|
||||
timeline-layout-helper.cpp - Implementation of the timeline
|
||||
layout helper 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 <boost/foreach.hpp>
|
||||
|
||||
#include "timeline-layout-helper.hpp"
|
||||
#include "../timeline-widget.hpp"
|
||||
#include "../../model/sequence.hpp"
|
||||
|
||||
using namespace Gtk;
|
||||
using namespace std;
|
||||
using namespace boost;
|
||||
using namespace lumiera;
|
||||
using namespace util;
|
||||
|
||||
namespace gui {
|
||||
namespace widgets {
|
||||
namespace timeline {
|
||||
|
||||
TimelineLayoutHelper::TimelineLayoutHelper(TimelineWidget &owner) :
|
||||
timelineWidget(owner),
|
||||
totalHeight(0),
|
||||
animating(false)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
TimelineLayoutHelper::clone_tree_from_sequence()
|
||||
{
|
||||
const shared_ptr<model::Sequence> &sequence = timelineWidget.sequence;
|
||||
REQUIRE(sequence);
|
||||
|
||||
layoutTree.clear();
|
||||
TrackTree::iterator_base iterator = layoutTree.set_head(sequence);
|
||||
add_branch(iterator, sequence);
|
||||
}
|
||||
|
||||
TimelineLayoutHelper::TrackTree&
|
||||
TimelineLayoutHelper::get_layout_tree()
|
||||
{
|
||||
return layoutTree;
|
||||
}
|
||||
|
||||
void
|
||||
TimelineLayoutHelper::add_branch(
|
||||
TrackTree::iterator_base parent_iterator,
|
||||
shared_ptr<model::Track> parent)
|
||||
{
|
||||
BOOST_FOREACH(shared_ptr<model::Track> child,
|
||||
parent->get_child_tracks())
|
||||
{
|
||||
TrackTree::iterator_base child_iterator =
|
||||
layoutTree.append_child(parent_iterator, child);
|
||||
add_branch(child_iterator, child);
|
||||
}
|
||||
}
|
||||
|
||||
optional<Gdk::Rectangle>
|
||||
TimelineLayoutHelper::get_track_header_rect(
|
||||
boost::weak_ptr<timeline::Track> track)
|
||||
{
|
||||
if(contains(headerBoxes, track))
|
||||
{
|
||||
Gdk::Rectangle rect(headerBoxes[track]);
|
||||
rect.set_y(rect.get_y() - timelineWidget.get_y_scroll_offset());
|
||||
return optional<Gdk::Rectangle>(rect);
|
||||
}
|
||||
return optional<Gdk::Rectangle>();
|
||||
}
|
||||
|
||||
shared_ptr<timeline::Track>
|
||||
TimelineLayoutHelper::header_from_point(Gdk::Point point)
|
||||
{
|
||||
// Apply the scroll offset
|
||||
point.set_y(point.get_y() + timelineWidget.get_y_scroll_offset());
|
||||
|
||||
// Search the headers
|
||||
std::pair<weak_ptr<timeline::Track>, Gdk::Rectangle> pair;
|
||||
BOOST_FOREACH( pair, headerBoxes )
|
||||
{
|
||||
// Hit test the rectangle
|
||||
const Gdk::Rectangle &rect = pair.second;
|
||||
|
||||
if(point.get_x() >= rect.get_x() &&
|
||||
point.get_x() < rect.get_x() + rect.get_width() &&
|
||||
point.get_y() >= rect.get_y() &&
|
||||
point.get_y() < rect.get_y() + rect.get_height())
|
||||
return shared_ptr<timeline::Track>(pair.first);
|
||||
}
|
||||
|
||||
// No track was found - return an empty pointer
|
||||
return shared_ptr<timeline::Track>();
|
||||
}
|
||||
|
||||
boost::shared_ptr<timeline::Track>
|
||||
TimelineLayoutHelper::track_from_y(int y)
|
||||
{
|
||||
// Apply the scroll offset
|
||||
y += timelineWidget.get_y_scroll_offset();
|
||||
|
||||
// Search the tracks
|
||||
std::pair<weak_ptr<timeline::Track>, Gdk::Rectangle> pair;
|
||||
BOOST_FOREACH( pair, headerBoxes )
|
||||
{
|
||||
// Hit test the rectangle
|
||||
const Gdk::Rectangle &rect = pair.second;
|
||||
if(y >= rect.get_y() && y < rect.get_y() + rect.get_height())
|
||||
return shared_ptr<timeline::Track>(pair.first);
|
||||
}
|
||||
|
||||
// No track was found - return an empty pointer
|
||||
return shared_ptr<timeline::Track>();
|
||||
}
|
||||
|
||||
int
|
||||
TimelineLayoutHelper::get_total_height() const
|
||||
{
|
||||
ENSURE(totalHeight >= 0);
|
||||
return totalHeight;
|
||||
}
|
||||
|
||||
bool
|
||||
TimelineLayoutHelper::is_animating() const
|
||||
{
|
||||
return animating;
|
||||
}
|
||||
|
||||
void
|
||||
TimelineLayoutHelper::update_layout()
|
||||
{
|
||||
// Reset the animation state value, before it gets recalculated
|
||||
animating = false;
|
||||
|
||||
// Clear previously cached layout
|
||||
headerBoxes.clear();
|
||||
|
||||
// Do the layout
|
||||
const int header_width = TimelineWidget::HeaderWidth;
|
||||
const int indent_width = TimelineWidget::HeaderIndentWidth;
|
||||
totalHeight = layout_headers_recursive(layoutTree.begin(),
|
||||
0, header_width, indent_width, 0, true);
|
||||
|
||||
// Signal that the layout has changed
|
||||
timelineWidget.on_layout_changed();
|
||||
|
||||
// Begin animating as necessary
|
||||
if(animating && !animationTimer)
|
||||
begin_animation();
|
||||
}
|
||||
|
||||
int
|
||||
TimelineLayoutHelper::layout_headers_recursive(
|
||||
TrackTree::iterator_base parent_iterator,
|
||||
const int branch_offset, const int header_width,
|
||||
const int indent_width, const int depth, const bool parent_expanded)
|
||||
{
|
||||
REQUIRE(depth >= 0);
|
||||
|
||||
int child_offset = 0;
|
||||
|
||||
TrackTree::sibling_iterator iterator;
|
||||
for(iterator = layoutTree.begin(parent_iterator);
|
||||
iterator != layoutTree.end(parent_iterator);
|
||||
iterator++)
|
||||
{
|
||||
const shared_ptr<model::Track> &model_track = *iterator;
|
||||
REQUIRE(model_track);
|
||||
|
||||
shared_ptr<timeline::Track> timeline_track =
|
||||
lookup_timeline_track(model_track);
|
||||
|
||||
// Is the track going to be shown?
|
||||
if(parent_expanded)
|
||||
{
|
||||
// Calculate and store the box of the header
|
||||
const int track_height = timeline_track->get_height();
|
||||
const int indent = depth * indent_width;
|
||||
|
||||
headerBoxes[timeline_track] = Gdk::Rectangle(
|
||||
indent, // x
|
||||
branch_offset + child_offset, // y
|
||||
max( header_width - indent, 0 ), // width
|
||||
track_height); // height
|
||||
|
||||
// Offset for the next header
|
||||
child_offset += track_height + TimelineWidget::TrackPadding;
|
||||
}
|
||||
|
||||
// Is the track animating?
|
||||
const bool is_track_animating =
|
||||
timeline_track->is_expand_animating();
|
||||
animating |= is_track_animating;
|
||||
|
||||
// Recurse to children
|
||||
const bool expand_child =
|
||||
(animating || timeline_track->get_expanded())
|
||||
&& parent_expanded;
|
||||
|
||||
int child_branch_height = layout_headers_recursive(
|
||||
iterator, branch_offset + child_offset,
|
||||
header_width, indent_width, depth + 1, expand_child);
|
||||
|
||||
// Do collapse animation as necessary
|
||||
if(is_track_animating)
|
||||
{
|
||||
// Calculate the height of te area which will be
|
||||
// shown as expanded
|
||||
const float a = timeline_track->get_expand_animation_state();
|
||||
child_branch_height *= a * a;
|
||||
const int y_limit =
|
||||
branch_offset + child_offset + child_branch_height;
|
||||
|
||||
// Obscure tracks according to the animation state
|
||||
TrackTree::pre_order_iterator descendant_iterator(iterator);
|
||||
descendant_iterator++;
|
||||
TrackTree::sibling_iterator end(iterator);
|
||||
end++;
|
||||
|
||||
for(descendant_iterator = layoutTree.begin(parent_iterator);
|
||||
descendant_iterator != end;
|
||||
descendant_iterator++)
|
||||
{
|
||||
const weak_ptr<timeline::Track> track =
|
||||
lookup_timeline_track(*descendant_iterator);
|
||||
const Gdk::Rectangle &rect = headerBoxes[track];
|
||||
|
||||
if(rect.get_y() + rect.get_height() > y_limit)
|
||||
headerBoxes.erase(track);
|
||||
}
|
||||
|
||||
// Tick the track expand animation
|
||||
timeline_track->tick_expand_animation();
|
||||
}
|
||||
|
||||
child_offset += child_branch_height;
|
||||
}
|
||||
|
||||
return child_offset;
|
||||
}
|
||||
|
||||
shared_ptr<timeline::Track>
|
||||
TimelineLayoutHelper::lookup_timeline_track(
|
||||
shared_ptr<model::Track> model_track)
|
||||
{
|
||||
REQUIRE(model_track != NULL);
|
||||
shared_ptr<timeline::Track> timeline_track =
|
||||
timelineWidget.lookup_timeline_track(model_track);
|
||||
ENSURE(timeline_track);
|
||||
|
||||
return timeline_track;
|
||||
}
|
||||
|
||||
void
|
||||
TimelineLayoutHelper::begin_animation()
|
||||
{
|
||||
animationTimer = Glib::signal_idle().connect(
|
||||
sigc::mem_fun(this, &TimelineLayoutHelper::on_animation_tick),
|
||||
Glib::PRIORITY_DEFAULT);
|
||||
}
|
||||
|
||||
bool
|
||||
TimelineLayoutHelper::on_animation_tick()
|
||||
{
|
||||
update_layout();
|
||||
return animating;
|
||||
}
|
||||
|
||||
} // namespace timeline
|
||||
} // namespace widgets
|
||||
} // namespace gui
|
||||
251
src/gui/widgets/timeline/timeline-layout-helper.hpp
Normal file
251
src/gui/widgets/timeline/timeline-layout-helper.hpp
Normal file
|
|
@ -0,0 +1,251 @@
|
|||
/*
|
||||
timeline-layout-helper.hpp - Declaration of the timeline
|
||||
layout helper 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-layout-helper.cpp
|
||||
** This file contains the definition of the layout helpeer class
|
||||
*/
|
||||
|
||||
#ifndef TIMELINE_LAYOUT_HELPER_HPP
|
||||
#define TIMELINE_LAYOUT_HELPER_HPP
|
||||
|
||||
#include "../../gtk-lumiera.hpp"
|
||||
#include "../../../lib/tree.hpp"
|
||||
|
||||
namespace gui {
|
||||
|
||||
namespace model {
|
||||
class Track;
|
||||
}
|
||||
|
||||
namespace widgets {
|
||||
|
||||
class TimelineWidget;
|
||||
|
||||
namespace timeline {
|
||||
|
||||
class Track;
|
||||
|
||||
/**
|
||||
* A helper class for the TimelineWidget. TimelineLayoutHelper
|
||||
* is a class which calculates the layout of tracks in the timeline
|
||||
* track tree.
|
||||
* @see gui::widgets::TimelineWidget
|
||||
*/
|
||||
class TimelineLayoutHelper : public boost::noncopyable
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Definition of the layout track tree type.
|
||||
**/
|
||||
typedef lumiera::tree< boost::shared_ptr<model::Track> > TrackTree;
|
||||
|
||||
public:
|
||||
/**
|
||||
* Constructor.
|
||||
* @param owner The timeline widget which is the owner of this helper
|
||||
* class.
|
||||
**/
|
||||
TimelineLayoutHelper(TimelineWidget &owner);
|
||||
|
||||
/**
|
||||
* Clones the timelineWidget sequence's track tree to create a layout
|
||||
* tree which will be identitcal to it.
|
||||
* @remarks The current layout tree will be deleted and replaced with
|
||||
* the clone.
|
||||
* @see add_branch
|
||||
**/
|
||||
void clone_tree_from_sequence();
|
||||
|
||||
/**
|
||||
* Gets a reference to the helper's layout tree.
|
||||
* @return Returns a reference to the helper's layout tree.
|
||||
**/
|
||||
TrackTree& get_layout_tree();
|
||||
|
||||
/**
|
||||
* Recalculates the track layout from layoutTree.
|
||||
* @see layout_headers_recursive
|
||||
**/
|
||||
void update_layout();
|
||||
|
||||
/**
|
||||
* Get's the header rectangle of a given timeline track.
|
||||
* @param[in] track The track which will be looked up.
|
||||
* @return Returns the rectangle of the header offset by the y-scroll
|
||||
* offset, or if the track is hidden, or not present in the layout
|
||||
* tree, an empty optional will be returned.
|
||||
* @remarks This function is only usable after update_layout() has
|
||||
* been called on a valid tree of tracks.
|
||||
* @see update_layout()
|
||||
**/
|
||||
boost::optional<Gdk::Rectangle> get_track_header_rect(
|
||||
boost::weak_ptr<timeline::Track> track);
|
||||
|
||||
/**
|
||||
* Searches for a header which has the specified point inside of it.
|
||||
* @param[in] point The point to search with.
|
||||
* @return Returns the header which has been found, or if no header is
|
||||
* found, an empty shared pointer is returned.
|
||||
* @remarks The point specified is relative to the scroll offset, so
|
||||
* y = 0 is the top edge of the scroll view. This function is only
|
||||
* usable after update_layout() has been called on a valid tree of
|
||||
* tracks.
|
||||
* @see update_layout()
|
||||
**/
|
||||
boost::shared_ptr<timeline::Track> header_from_point(
|
||||
Gdk::Point point);
|
||||
|
||||
/**
|
||||
* Searches for a tack which has the specified y-offset inside of it.
|
||||
* @param[in] y The y-coordinate to search with.
|
||||
* @return Returns the track which has been found, or if no track is
|
||||
* found, an empty shared pointer is returned.
|
||||
* @remarks The point specified is relative to the scroll offset, so
|
||||
* y = 0 is the top edge of the scroll view. This function is only
|
||||
* usable after update_layout() has been called on a valid tree of
|
||||
* tracks.
|
||||
* @see update_layout()
|
||||
**/
|
||||
boost::shared_ptr<timeline::Track> track_from_y(int y);
|
||||
|
||||
/**
|
||||
* Returns the total height in pixels of the layout tree.
|
||||
* @remarks This function is only on returns a valid value fter
|
||||
* update_layout() has been called on a valid tree of tracks.
|
||||
* @see update_layout()
|
||||
**/
|
||||
int get_total_height() const;
|
||||
|
||||
bool is_animating() const;
|
||||
|
||||
protected:
|
||||
|
||||
/**
|
||||
* A helper function for clone_tree_from_sequence(). This function
|
||||
* clones a branch within the model tree into the specified point in
|
||||
* that layout tree.
|
||||
* @param[in] parent_iterator The iterator of the node in the tree
|
||||
* which will become the parent of any tracks added.
|
||||
* @param[in] parent A pointer to the model track whose children
|
||||
* will be added to the layout tree branch.
|
||||
* @see clone_tree_from_sequence()
|
||||
**/
|
||||
void add_branch(TrackTree::iterator_base parent_iterator,
|
||||
boost::shared_ptr<model::Track> parent);
|
||||
|
||||
/**
|
||||
* Recursively calculates the boxes for a given branch in the timeline
|
||||
* tree.
|
||||
* @param[in] parent_iterator The iterator of the parent of the branch
|
||||
* whose boxes will be laid out.
|
||||
* @param[in] branch_offset The y-coordinate of the start of this
|
||||
* branch as measured in pixels from the origin.
|
||||
* @param[in] header_width The width of the header container widget in
|
||||
* pixels.
|
||||
* @param[in] header_width The width of indentation per branch in
|
||||
* pixels.
|
||||
* @param[in] depth The depth within the tree of tracks. depth = 0 for
|
||||
* root tracks.
|
||||
* @param[in] parent_expanded This value is set to true if all of the
|
||||
* ancestors of this track, up to the root are expanded and visible,
|
||||
* false if any of them are collapsed.
|
||||
* @return Returns the height of the branch in pixels.
|
||||
* @see update_layout()
|
||||
**/
|
||||
int layout_headers_recursive(
|
||||
TrackTree::iterator_base parent_iterator, const int branch_offset,
|
||||
const int header_width, const int indent_width, const int depth,
|
||||
const bool parent_expanded);
|
||||
|
||||
/**
|
||||
* A helper function which calls lookup_timeline_track within the
|
||||
* parent timeline widget, but also applies lots of data consistency
|
||||
* checks in the process.
|
||||
* @param model_track The model track to look up in the parent widget.
|
||||
* @return Returns the track found, or returns NULL if no matching
|
||||
* track was found.
|
||||
* @remarks If the return value is going to be NULL, an ENSURE will
|
||||
* fail.
|
||||
**/
|
||||
boost::shared_ptr<timeline::Track> lookup_timeline_track(
|
||||
boost::shared_ptr<model::Track> model_track);
|
||||
|
||||
/**
|
||||
* A helper function which kicks off the animation timer.
|
||||
**/
|
||||
void begin_animation();
|
||||
|
||||
/**
|
||||
* The animation timer tick callback.
|
||||
**/
|
||||
bool on_animation_tick();
|
||||
|
||||
protected:
|
||||
|
||||
/**
|
||||
* The owner timeline widget as provided to the constructor.
|
||||
**/
|
||||
TimelineWidget &timelineWidget;
|
||||
|
||||
/**
|
||||
* The layout tree.
|
||||
**/
|
||||
TrackTree layoutTree;
|
||||
|
||||
/**
|
||||
* A map of tracks to the rectangles of their headers.
|
||||
* @remarks This map is used as a cache, so that the rectangles don't
|
||||
* need to be perpetually recalculated. This cache is regenerated by
|
||||
* the update_layout method.
|
||||
* @see update_layout()
|
||||
**/
|
||||
std::map<boost::weak_ptr<timeline::Track>, Gdk::Rectangle>
|
||||
headerBoxes;
|
||||
|
||||
/**
|
||||
* The total height of the track tree layout in pixels. This value
|
||||
* is only valid after layout_headers has been called.
|
||||
* @see update_layout()
|
||||
**/
|
||||
int totalHeight;
|
||||
|
||||
/**
|
||||
* The connection to the animation timer.
|
||||
* @see begin_animation()
|
||||
* @see on_animation_tick()
|
||||
**/
|
||||
sigc::connection animationTimer;
|
||||
|
||||
/**
|
||||
* This value is true if the layout animation should continue.
|
||||
* @remarks This value is recalculated by update_layout()
|
||||
* @see update_layout()
|
||||
* @see on_animation_tick()
|
||||
**/
|
||||
bool animating;
|
||||
};
|
||||
|
||||
} // namespace timeline
|
||||
} // namespace widgets
|
||||
} // namespace gui
|
||||
|
||||
#endif // TIMELINE_LAYOUT_HELPER_HPP
|
||||
|
|
@ -42,7 +42,7 @@ namespace widgets {
|
|||
namespace timeline {
|
||||
|
||||
TimelineRuler::TimelineRuler(
|
||||
gui::widgets::TimelineWidget *timeline_widget) :
|
||||
gui::widgets::TimelineWidget &timeline_widget) :
|
||||
Glib::ObjectBase("TimelineRuler"),
|
||||
isDragging(false),
|
||||
pinnedDragTime(0),
|
||||
|
|
@ -61,11 +61,9 @@ TimelineRuler::TimelineRuler(
|
|||
playbackPeriodArrowSize(10),
|
||||
playbackPeriodArrowStemSize(3),
|
||||
timelineWidget(timeline_widget)
|
||||
{
|
||||
REQUIRE(timelineWidget != NULL);
|
||||
|
||||
{
|
||||
// Connect event handlers
|
||||
timelineWidget->get_view_window().changed_signal().connect(
|
||||
timelineWidget.get_view_window().changed_signal().connect(
|
||||
sigc::mem_fun(this, &TimelineRuler::on_update_view) );
|
||||
|
||||
// Install style properties
|
||||
|
|
@ -157,7 +155,7 @@ TimelineRuler::on_button_press_event(GdkEventButton* event)
|
|||
if(event->button == 1)
|
||||
{
|
||||
pinnedDragTime =
|
||||
timelineWidget->get_view_window().x_to_time(event->x);
|
||||
timelineWidget.get_view_window().x_to_time(event->x);
|
||||
isDragging = true;
|
||||
}
|
||||
|
||||
|
|
@ -168,12 +166,11 @@ bool
|
|||
TimelineRuler::on_button_release_event(GdkEventButton* event)
|
||||
{
|
||||
REQUIRE(event != NULL);
|
||||
REQUIRE(timelineWidget != NULL);
|
||||
|
||||
if(event->button == 1)
|
||||
{
|
||||
isDragging = false;
|
||||
timelineWidget->on_playback_period_drag_released();
|
||||
timelineWidget.on_playback_period_drag_released();
|
||||
}
|
||||
|
||||
return true;
|
||||
|
|
@ -214,14 +211,12 @@ TimelineRuler::on_size_allocate(Gtk::Allocation& allocation)
|
|||
void
|
||||
TimelineRuler::set_leading_x(const int x)
|
||||
{
|
||||
REQUIRE(timelineWidget != NULL);
|
||||
|
||||
const gavl_time_t time =
|
||||
timelineWidget->get_view_window().x_to_time(x);
|
||||
timelineWidget.get_view_window().x_to_time(x);
|
||||
if(time > pinnedDragTime)
|
||||
timelineWidget->set_playback_period(pinnedDragTime, time);
|
||||
timelineWidget.set_playback_period(pinnedDragTime, time);
|
||||
else
|
||||
timelineWidget->set_playback_period(time, pinnedDragTime);
|
||||
timelineWidget.set_playback_period(time, pinnedDragTime);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -231,9 +226,8 @@ TimelineRuler::draw_ruler(Cairo::RefPtr<Cairo::Context> cr,
|
|||
REQUIRE(cr);
|
||||
REQUIRE(ruler_rect.get_width() > 0);
|
||||
REQUIRE(ruler_rect.get_height() > 0);
|
||||
REQUIRE(timelineWidget != NULL);
|
||||
|
||||
const TimelineViewWindow &window = timelineWidget->get_view_window();
|
||||
const TimelineViewWindow &window = timelineWidget.get_view_window();
|
||||
const gavl_time_t left_offset = window.get_time_offset();
|
||||
const int64_t time_scale = window.get_time_scale();
|
||||
|
||||
|
|
@ -334,15 +328,14 @@ TimelineRuler::draw_selection(Cairo::RefPtr<Cairo::Context> cr,
|
|||
REQUIRE(cr);
|
||||
REQUIRE(ruler_rect.get_width() > 0);
|
||||
REQUIRE(ruler_rect.get_height() > 0);
|
||||
REQUIRE(timelineWidget != NULL);
|
||||
|
||||
const TimelineViewWindow &window = timelineWidget->get_view_window();
|
||||
const TimelineViewWindow &window = timelineWidget.get_view_window();
|
||||
|
||||
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 = window.time_to_x(timelineWidget->selectionStart) + 1;
|
||||
const int a = window.time_to_x(timelineWidget.selectionStart) + 1;
|
||||
if(a >= 0 && a < ruler_rect.get_width())
|
||||
{
|
||||
cr->move_to(a, ruler_rect.get_height());
|
||||
|
|
@ -352,7 +345,7 @@ TimelineRuler::draw_selection(Cairo::RefPtr<Cairo::Context> cr,
|
|||
}
|
||||
|
||||
// Draw the selection end chevron
|
||||
const int b = window.time_to_x(timelineWidget->selectionEnd);
|
||||
const int b = window.time_to_x(timelineWidget.selectionEnd);
|
||||
if(b >= 0 && b < ruler_rect.get_width())
|
||||
{
|
||||
cr->move_to(b, ruler_rect.get_height());
|
||||
|
|
@ -369,18 +362,17 @@ TimelineRuler::draw_playback_period(Cairo::RefPtr<Cairo::Context> cr,
|
|||
REQUIRE(cr);
|
||||
REQUIRE(ruler_rect.get_width() > 0);
|
||||
REQUIRE(ruler_rect.get_height() > 0);
|
||||
REQUIRE(timelineWidget != NULL);
|
||||
|
||||
const TimelineViewWindow &window = timelineWidget->get_view_window();
|
||||
const TimelineViewWindow &window = timelineWidget.get_view_window();
|
||||
|
||||
// Calculate coordinates
|
||||
const float halfSize = playbackPeriodArrowSize / 2;
|
||||
|
||||
const float a = window.time_to_x(
|
||||
timelineWidget->playbackPeriodStart) + 1 + 0.5f;
|
||||
timelineWidget.playbackPeriodStart) + 1 + 0.5f;
|
||||
const float b = a + halfSize;
|
||||
const float d = window.time_to_x(
|
||||
timelineWidget->playbackPeriodEnd) + 0.5f;
|
||||
timelineWidget.playbackPeriodEnd) + 0.5f;
|
||||
const float c = d - halfSize;
|
||||
|
||||
const float e = ruler_rect.get_height() - playbackPeriodArrowSize
|
||||
|
|
@ -444,12 +436,11 @@ TimelineRuler::draw_playback_point(Cairo::RefPtr<Cairo::Context> cr,
|
|||
REQUIRE(cr);
|
||||
REQUIRE(ruler_rect.get_width() > 0);
|
||||
REQUIRE(ruler_rect.get_height() > 0);
|
||||
REQUIRE(timelineWidget != NULL);
|
||||
|
||||
const gavl_time_t point = timelineWidget->get_playback_point();
|
||||
if(point == GAVL_TIME_UNDEFINED)
|
||||
const gavl_time_t point = timelineWidget.get_playback_point();
|
||||
if(point == (gavl_time_t)GAVL_TIME_UNDEFINED)
|
||||
return;
|
||||
const int x = timelineWidget->get_view_window().time_to_x(point);
|
||||
const int x = timelineWidget.get_view_window().time_to_x(point);
|
||||
|
||||
cr->move_to(x + 0.5, ruler_rect.get_height());
|
||||
cr->rel_line_to(0, -playbackPointSize);
|
||||
|
|
@ -473,12 +464,10 @@ TimelineRuler::draw_playback_point(Cairo::RefPtr<Cairo::Context> cr,
|
|||
gavl_time_t
|
||||
TimelineRuler::calculate_major_spacing() const
|
||||
{
|
||||
int i;
|
||||
|
||||
REQUIRE(timelineWidget != NULL);
|
||||
unsigned int i;
|
||||
|
||||
const int64_t time_scale =
|
||||
timelineWidget->get_view_window().get_time_scale();
|
||||
timelineWidget.get_view_window().get_time_scale();
|
||||
const gavl_time_t major_spacings[] = {
|
||||
GAVL_TIME_SCALE / 1000,
|
||||
GAVL_TIME_SCALE / 400,
|
||||
|
|
|
|||
|
|
@ -45,10 +45,11 @@ class TimelineRuler : public Gtk::DrawingArea
|
|||
public:
|
||||
/**
|
||||
* Constructor
|
||||
* @param timeline_widget The owner widget of this ruler.
|
||||
* @param timeline_widget A reference to the owner widget of this
|
||||
* ruler.
|
||||
*/
|
||||
TimelineRuler(
|
||||
gui::widgets::TimelineWidget *timeline_widget);
|
||||
gui::widgets::TimelineWidget &timeline_widget);
|
||||
|
||||
/**
|
||||
* Sets offset of the mouse chevron
|
||||
|
|
@ -216,7 +217,7 @@ private:
|
|||
/**
|
||||
* The owner widget
|
||||
*/
|
||||
gui::widgets::TimelineWidget *timelineWidget;
|
||||
gui::widgets::TimelineWidget &timelineWidget;
|
||||
|
||||
/**
|
||||
* The caches image of the ruler, over which the chevrons etc. will
|
||||
|
|
|
|||
|
|
@ -29,20 +29,16 @@ namespace gui {
|
|||
namespace widgets {
|
||||
namespace timeline {
|
||||
|
||||
Tool::Tool(TimelineBody *timeline_body) :
|
||||
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();
|
||||
{
|
||||
Glib::RefPtr<Window> window = timelineBody.get_window();
|
||||
if(!window)
|
||||
return false;
|
||||
|
||||
|
|
@ -75,21 +71,18 @@ Tool::on_motion_notify_event(GdkEventMotion *event)
|
|||
mousePoint = Point(event->x, event->y);
|
||||
}
|
||||
|
||||
gui::widgets::TimelineWidget*
|
||||
gui::widgets::TimelineWidget&
|
||||
Tool::get_timeline_widget() const
|
||||
{
|
||||
REQUIRE(timelineBody != NULL);
|
||||
gui::widgets::TimelineWidget *timeline_widget =
|
||||
timelineBody->timelineWidget;
|
||||
REQUIRE(timeline_widget != NULL);
|
||||
gui::widgets::TimelineWidget &timeline_widget =
|
||||
timelineBody.timelineWidget;
|
||||
return timeline_widget;
|
||||
}
|
||||
|
||||
Gdk::Rectangle
|
||||
Tool::get_body_rectangle() const
|
||||
{
|
||||
REQUIRE(timelineBody != NULL);
|
||||
return timelineBody->get_allocation();
|
||||
return timelineBody.get_allocation();
|
||||
}
|
||||
|
||||
} // namespace timeline
|
||||
|
|
|
|||
|
|
@ -58,7 +58,7 @@ protected:
|
|||
* Constructor
|
||||
* @param timeline_body The owner timeline body object
|
||||
*/
|
||||
Tool(TimelineBody *timeline_body);
|
||||
Tool(TimelineBody &timeline_body);
|
||||
|
||||
public:
|
||||
/**
|
||||
|
|
@ -120,7 +120,7 @@ protected:
|
|||
* Helper function which retrieves the pointer to owner timeline
|
||||
* widget object, which is the owner of the timeline body.
|
||||
*/
|
||||
gui::widgets::TimelineWidget *get_timeline_widget() const;
|
||||
gui::widgets::TimelineWidget &get_timeline_widget() const;
|
||||
|
||||
/**
|
||||
* Helper function which retrieves the rectangle of the timeline
|
||||
|
|
@ -129,10 +129,10 @@ protected:
|
|||
Gdk::Rectangle get_body_rectangle() const;
|
||||
|
||||
protected:
|
||||
TimelineBody &timelineBody;
|
||||
|
||||
bool isDragging;
|
||||
Gdk::Point mousePoint;
|
||||
|
||||
TimelineBody *timelineBody;
|
||||
};
|
||||
|
||||
} // namespace timeline
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@
|
|||
|
||||
* *****************************************************/
|
||||
|
||||
#warning This header must soon be removed when we drop Etch compatibility
|
||||
// !!! This header must soon be removed when we drop Etch compatibility
|
||||
#include <gtk/gtktoolbar.h>
|
||||
|
||||
#include "timeline-track.hpp"
|
||||
|
|
@ -35,12 +35,15 @@ using namespace sigc;
|
|||
namespace gui {
|
||||
namespace widgets {
|
||||
namespace timeline {
|
||||
|
||||
const float Track::ExpandAnimationPeriod = 0.15;
|
||||
|
||||
Track::Track(TimelineWidget &timeline_widget,
|
||||
shared_ptr<model::Track> track) :
|
||||
timelineWidget(timeline_widget),
|
||||
model_track(track),
|
||||
expanded(true),
|
||||
expandDirection(None),
|
||||
enableButton(Gtk::StockID("track_enabled")),
|
||||
lockButton(Gtk::StockID("track_unlocked"))
|
||||
{
|
||||
|
|
@ -56,8 +59,8 @@ Track::Track(TimelineWidget &timeline_widget,
|
|||
#if 0
|
||||
buttonBar.set_icon_size(WindowManager::MenuIconSize);
|
||||
#else
|
||||
#warning This code soon be removed when we drop Etch compatibility
|
||||
|
||||
TODO("This code soon be removed when we drop Etch compatibility");
|
||||
|
||||
// Temporary bodge for etch compatibility - will be removed soon
|
||||
gtk_toolbar_set_icon_size (buttonBar.gobj(),
|
||||
(GtkIconSize)(int)WindowManager::MenuIconSize);
|
||||
|
|
@ -70,6 +73,10 @@ Track::Track(TimelineWidget &timeline_widget,
|
|||
Menu::MenuList& title_list = titleMenuButton.get_menu().items();
|
||||
title_list.push_back( Menu_Helpers::MenuElem(_("_Name..."),
|
||||
mem_fun(this, &Track::on_set_name) ) );
|
||||
title_list.push_back( Menu_Helpers::SeparatorElem() );
|
||||
title_list.push_back( Menu_Helpers::MenuElem(_("_Remove"),
|
||||
mem_fun(this, &Track::on_remove_track) ) );
|
||||
|
||||
update_name();
|
||||
|
||||
// Setup the context menu
|
||||
|
|
@ -86,6 +93,12 @@ Track::get_header_widget()
|
|||
return headerWidget;
|
||||
}
|
||||
|
||||
shared_ptr<model::Track>
|
||||
Track::get_model_track() const
|
||||
{
|
||||
return model_track;
|
||||
}
|
||||
|
||||
int
|
||||
Track::get_height() const
|
||||
{
|
||||
|
|
@ -99,9 +112,102 @@ Track::get_expanded() const
|
|||
}
|
||||
|
||||
void
|
||||
Track::set_expanded(bool expanded)
|
||||
Track::expand_collapse(ExpandDirection direction)
|
||||
{
|
||||
this->expanded = expanded;
|
||||
REQUIRE(direction != None);
|
||||
|
||||
expandDirection = direction;
|
||||
if(direction == Expand)
|
||||
{
|
||||
expanded = true;
|
||||
expandAnimationState = 0.0;
|
||||
}
|
||||
else
|
||||
{
|
||||
expanded = false;
|
||||
expandAnimationState = 1.0;
|
||||
}
|
||||
|
||||
// Create a timer if we don't already have one
|
||||
if(!expand_timer)
|
||||
{
|
||||
expand_timer.reset(new Glib::Timer());
|
||||
expand_timer->start();
|
||||
}
|
||||
else // Reset the timer if we do
|
||||
expand_timer->reset();
|
||||
}
|
||||
|
||||
float
|
||||
Track::get_expand_animation_state() const
|
||||
{
|
||||
ENSURE(expandAnimationState >= 0.0 &&
|
||||
expandAnimationState <= 1.0);
|
||||
return expandAnimationState;
|
||||
}
|
||||
|
||||
bool
|
||||
Track::is_expand_animating() const
|
||||
{
|
||||
return expandDirection != None;
|
||||
}
|
||||
|
||||
void
|
||||
Track::tick_expand_animation()
|
||||
{
|
||||
REQUIRE(expandDirection != None); // tick_expand_animation should not
|
||||
// be unless is_expand_animating
|
||||
// returns true
|
||||
REQUIRE(expand_timer);
|
||||
const float delta =
|
||||
(float)expand_timer->elapsed() / ExpandAnimationPeriod;
|
||||
expand_timer->reset(); // reset the timer to t=0
|
||||
|
||||
if(expandDirection == Expand)
|
||||
{
|
||||
expandAnimationState += delta;
|
||||
if(expandAnimationState >= 1.0)
|
||||
expandDirection = None;
|
||||
}
|
||||
else
|
||||
{
|
||||
expandAnimationState -= delta;
|
||||
if(expandAnimationState <= 0.0)
|
||||
expandDirection = None;
|
||||
}
|
||||
|
||||
if(expandDirection == None)
|
||||
expand_timer.reset(); // We've finished with the timer - delete it
|
||||
}
|
||||
|
||||
Gtk::ExpanderStyle
|
||||
Track::get_expander_style() const
|
||||
{
|
||||
if(expanded)
|
||||
{
|
||||
if(expandDirection == None)
|
||||
return EXPANDER_EXPANDED;
|
||||
else if(expandAnimationState >= 2.0 / 3.0)
|
||||
return EXPANDER_SEMI_EXPANDED;
|
||||
else if(expandAnimationState >= 1.0 / 3.0)
|
||||
return EXPANDER_SEMI_COLLAPSED;
|
||||
else
|
||||
return EXPANDER_COLLAPSED;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(expandDirection == None)
|
||||
return EXPANDER_COLLAPSED;
|
||||
else if(expandAnimationState >= 2.0 / 3.0)
|
||||
return EXPANDER_EXPANDED;
|
||||
else if(expandAnimationState >= 1.0 / 3.0)
|
||||
return EXPANDER_SEMI_EXPANDED;
|
||||
else
|
||||
return EXPANDER_SEMI_COLLAPSED;
|
||||
}
|
||||
|
||||
ERROR(gui, "Track::get_expander_style() final return reached");
|
||||
return EXPANDER_COLLAPSED; // This should never happen
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -142,7 +248,7 @@ Track::on_remove_track()
|
|||
REQUIRE(model_track);
|
||||
REQUIRE(timelineWidget.sequence);
|
||||
|
||||
timelineWidget.sequence->get_child_track_list().remove(model_track);
|
||||
timelineWidget.sequence->remove_child_track(model_track);
|
||||
}
|
||||
|
||||
} // namespace timeline
|
||||
|
|
|
|||
|
|
@ -37,25 +37,94 @@ namespace timeline {
|
|||
|
||||
class TimelineViewWindow;
|
||||
|
||||
class Track
|
||||
/**
|
||||
* Timeline tracks are created by the timeline widget to correspond to
|
||||
* model tracks. Timeline tracks are used to store UI specific state
|
||||
* data.
|
||||
**/
|
||||
class Track : public sigc::trackable
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* An enum used by the branch expand/collapse animation.
|
||||
* ExpandDirection represents whether the branch us being expanded or
|
||||
* collapsed, or neither.
|
||||
**/
|
||||
enum ExpandDirection
|
||||
{
|
||||
None,
|
||||
Expand,
|
||||
Collapse
|
||||
};
|
||||
|
||||
public:
|
||||
Track(TimelineWidget &timeline_widget,
|
||||
boost::shared_ptr<model::Track> track);
|
||||
|
||||
Gtk::Widget& get_header_widget();
|
||||
|
||||
boost::shared_ptr<model::Track> get_model_track() const;
|
||||
|
||||
int get_height() const;
|
||||
|
||||
/**
|
||||
* Gets whether the descendant tracks are expanded or collapsed.
|
||||
* @return Returns true if the branch is expanded, false if it's
|
||||
* collapsed.
|
||||
* @see expand_collapse
|
||||
**/
|
||||
bool get_expanded() const;
|
||||
|
||||
void set_expanded(bool expanded);
|
||||
/**
|
||||
* Expands or collapses this branch.
|
||||
* @param direction Specifies whether this branch should be expanded
|
||||
* or collapse. direction must not equal None
|
||||
**/
|
||||
void expand_collapse(ExpandDirection direction);
|
||||
|
||||
/**
|
||||
* The current expand state.
|
||||
* @return Returns the expand state value, this value is a number
|
||||
* between 0 and 1.0, and is recalculated by tick_expand_animation().
|
||||
* @remarks A value of 1.0 is given when the branch is fully expanded
|
||||
* (and animating), 0.0 is given when the branch is fully collapsed
|
||||
* (and animating). When the branch is not animating this value has
|
||||
* an indeterminate value.
|
||||
* @see tick_expand_animation
|
||||
**/
|
||||
float get_expand_animation_state() const;
|
||||
|
||||
/**
|
||||
* Gets whether the branch is animation.
|
||||
* @return Returns true if the branch is animating, false if not.
|
||||
**/
|
||||
bool is_expand_animating() const;
|
||||
|
||||
/**
|
||||
* When this track is being animated, tick_expand_animation must be
|
||||
* called repeatedly to cause the animation to progress.
|
||||
**/
|
||||
void tick_expand_animation();
|
||||
|
||||
/**
|
||||
* Calculates the expander style, given the animation state.
|
||||
**/
|
||||
Gtk::ExpanderStyle get_expander_style() const;
|
||||
|
||||
void show_header_context_menu(guint button, guint32 time);
|
||||
|
||||
virtual void draw_track(Cairo::RefPtr<Cairo::Context> cairo,
|
||||
TimelineViewWindow* const window)
|
||||
const = 0;
|
||||
|
||||
public:
|
||||
//----- Constants -----//
|
||||
|
||||
/**
|
||||
* Specifies the period of the expand animation in seconds.
|
||||
**/
|
||||
static const float ExpandAnimationPeriod;
|
||||
|
||||
private:
|
||||
//----- Internals -----//
|
||||
|
|
@ -68,13 +137,42 @@ private:
|
|||
|
||||
void on_remove_track();
|
||||
|
||||
|
||||
private:
|
||||
protected:
|
||||
|
||||
TimelineWidget &timelineWidget;
|
||||
boost::shared_ptr<model::Track> model_track;
|
||||
|
||||
private:
|
||||
|
||||
/**
|
||||
* This bool is true if this branch is expanded. false if it is
|
||||
* collapsed.
|
||||
**/
|
||||
bool expanded;
|
||||
|
||||
/**
|
||||
* This enum specifies which direction the expand/collapse animation
|
||||
* is moving - if any.
|
||||
* @remarks If no animation is occuring, expandDirection is set to
|
||||
* None.
|
||||
**/
|
||||
ExpandDirection expandDirection;
|
||||
|
||||
/**
|
||||
* The current expand state.
|
||||
* @remarks This value is a number between 0 and 1.0,
|
||||
* and is recalculated by tick_expand_animation(). This variable is
|
||||
* set to 1.0 when the branch is fully expanded (and animating) and
|
||||
* 0.0 when the branch is fully collapsed (and animating). When the
|
||||
* branch is not animating this value has an indeterminate value.
|
||||
* @see tick_expand_animation
|
||||
**/
|
||||
double expandAnimationState;
|
||||
|
||||
/**
|
||||
* An internal timer used for the expand/collapse animation.
|
||||
**/
|
||||
boost::scoped_ptr<Glib::Timer> expand_timer;
|
||||
|
||||
//----- Header Widgets ------//
|
||||
|
||||
|
|
|
|||
|
|
@ -64,6 +64,8 @@ VideoDisplayWidget::on_realize()
|
|||
bool
|
||||
VideoDisplayWidget::on_button_press_event (GdkEventButton* event)
|
||||
{
|
||||
(void)event;
|
||||
|
||||
unsigned char buffer[320 * 240 * 4];
|
||||
|
||||
for(int i = 0; i < 320*240*4; i++)
|
||||
|
|
|
|||
|
|
@ -68,10 +68,7 @@ WindowManager::read_style_colour_property(
|
|||
{
|
||||
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;
|
||||
const GdkColor default_colour = {0, red, green, blue};
|
||||
return default_colour;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -208,13 +208,12 @@ Actions::on_menu_help_about()
|
|||
AboutDialog dialog;
|
||||
|
||||
//dialog.set_program_name(AppTitle);
|
||||
dialog.set_version(AppVersion);
|
||||
dialog.set_version(GtkLumiera::AppVersion);
|
||||
//dialog.set_version(AppState::get("version"));
|
||||
dialog.set_copyright(AppCopyright);
|
||||
dialog.set_website(AppWebsite);
|
||||
dialog.set_authors(StringArrayHandle(AppAuthors,
|
||||
sizeof(AppAuthors) / sizeof(gchar*),
|
||||
OWNERSHIP_NONE));
|
||||
dialog.set_copyright(GtkLumiera::AppCopyright);
|
||||
dialog.set_website(GtkLumiera::AppWebsite);
|
||||
dialog.set_authors(StringArrayHandle(GtkLumiera::AppAuthors,
|
||||
GtkLumiera::AppAuthorCount, OWNERSHIP_NONE));
|
||||
|
||||
dialog.set_transient_for(workspaceWindow);
|
||||
|
||||
|
|
|
|||
|
|
@ -78,7 +78,7 @@ void
|
|||
WorkspaceWindow::create_ui()
|
||||
{
|
||||
//----- Configure the Window -----//
|
||||
set_title(AppTitle);
|
||||
set_title(GtkLumiera::AppTitle);
|
||||
set_default_size(1024, 768);
|
||||
|
||||
//----- Set up the UI Manager -----//
|
||||
|
|
|
|||
|
|
@ -86,6 +86,7 @@ noinst_HEADERS += \
|
|||
$(liblumiera_la_srcdir)/observable-list.hpp \
|
||||
$(liblumiera_la_srcdir)/sync.hpp \
|
||||
$(liblumiera_la_srcdir)/sync-classlock.hpp \
|
||||
$(liblumiera_la_srcdir)/tree.hpp \
|
||||
$(liblumiera_la_srcdir)/test/mockinjector.hpp \
|
||||
$(liblumiera_la_srcdir)/test/suite.hpp \
|
||||
$(liblumiera_la_srcdir)/test/testoption.hpp \
|
||||
|
|
|
|||
2709
src/lib/tree.hpp
Normal file
2709
src/lib/tree.hpp
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -48,7 +48,9 @@ TEST ("mmap_semantic")
|
|||
int fd = open (",mmaptest", O_RDWR|O_CREAT, 0666);
|
||||
printf ("got fd %d\n", fd);
|
||||
printf ("error %s\n", strerror (errno));
|
||||
ftruncate (fd, 8192);
|
||||
int dummy = ftruncate (fd, 8192);
|
||||
(void)dummy;
|
||||
TODO ("handle error case better");
|
||||
|
||||
void* addr = mmap (NULL,
|
||||
8192,
|
||||
|
|
|
|||
Loading…
Reference in a new issue