SG: merge 3.0 from 11783-12096

git-svn-id: svn://localhost/ardour2/branches/3.0-SG@12097 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
Paul Davis 2012-04-26 17:06:21 +00:00
parent 85a27910cb
commit 9c8b57aab0
385 changed files with 14193 additions and 18198 deletions

6
.gitignore vendored
View file

@ -125,4 +125,8 @@ gtk2_ardour/po/*.mo
libs/ardour/po/*.mo
gtk2_ardour/*.pot
libs/ardour/libardour.pot
.lock-wafbuild
GPATH
GRTAGS
GSYMS
GTAGS

451
doc/eventloop.svg Normal file
View file

@ -0,0 +1,451 @@
<?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:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="744.09448819"
height="1052.3622047"
id="svg2"
version="1.1"
inkscape:version="0.47 r22583"
sodipodi:docname="eventloop.svg">
<defs
id="defs4">
<inkscape:perspective
sodipodi:type="inkscape:persp3d"
inkscape:vp_x="0 : 526.18109 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_z="744.09448 : 526.18109 : 1"
inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
id="perspective10" />
<inkscape:perspective
id="perspective2828"
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="perspective2850"
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="perspective2850-0"
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="perspective2885"
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="perspective2907"
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="perspective2944"
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="perspective2968"
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" />
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="0.97837038"
inkscape:cx="194.04872"
inkscape:cy="530.56652"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="true"
inkscape:snap-grids="true"
inkscape:snap-to-guides="true"
inkscape:window-width="1540"
inkscape:window-height="1074"
inkscape:window-x="1600"
inkscape:window-y="0"
inkscape:window-maximized="0">
<inkscape:grid
type="xygrid"
id="grid2958" />
</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" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1">
<path
sodipodi:type="arc"
style="opacity:0.61851855;color:#000000;fill:#000000;fill-opacity:0;stroke:#000000;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
id="path2816"
sodipodi:cx="232.85715"
sodipodi:cy="305.21933"
sodipodi:rx="157.14285"
sodipodi:ry="140"
d="m 390,305.21933 a 157.14285,140 0 1 1 -314.285706,0 157.14285,140 0 1 1 314.285706,0 z" />
<rect
style="opacity:0.61851855;color:#000000;fill:#000000;fill-opacity:0;stroke:#000000;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
id="rect2818"
width="28.571428"
height="131.42857"
x="122.85714"
y="486.64789" />
<rect
style="opacity:0.61851855;color:#000000;fill:#000000;fill-opacity:0;stroke:#000000;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
id="rect2818-1"
width="28.571428"
height="131.42857"
x="172.85715"
y="486.64789" />
<rect
style="opacity:0.61851855;color:#000000;fill:#000000;fill-opacity:0;stroke:#000000;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
id="rect2818-1-5"
width="28.571428"
height="131.42857"
x="344.28571"
y="489.50507" />
<rect
style="opacity:0.61851855;color:#000000;fill:#000000;fill-opacity:0;stroke:#000000;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
id="rect2873"
width="41.42857"
height="38.57143"
x="478.57144"
y="283.79074" />
<path
sodipodi:type="arc"
style="opacity:0.61851855;color:#000000;fill:#000000;fill-opacity:0;stroke:#000000;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
id="path2875"
sodipodi:cx="162.85715"
sodipodi:cy="880.93359"
sodipodi:rx="107.14286"
sodipodi:ry="97.14286"
d="m 270.00001,880.93359 a 107.14286,97.14286 0 1 1 -214.285723,0 107.14286,97.14286 0 1 1 214.285723,0 z" />
<path
transform="translate(232.85714,-5.7142688)"
sodipodi:type="arc"
style="opacity:0.61851855;color:#000000;fill:#000000;fill-opacity:0;stroke:#000000;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
id="path2875-7"
sodipodi:cx="162.85715"
sodipodi:cy="880.93359"
sodipodi:rx="107.14286"
sodipodi:ry="97.14286"
d="m 270.00001,880.93359 a 107.14286,97.14286 0 1 1 -214.285723,0 107.14286,97.14286 0 1 1 214.285723,0 z" />
<path
transform="translate(458.57142,-8.5714113)"
sodipodi:type="arc"
style="opacity:0.61851855;color:#000000;fill:#000000;fill-opacity:0;stroke:#000000;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
id="path2875-7-5"
sodipodi:cx="162.85715"
sodipodi:cy="880.93359"
sodipodi:rx="107.14286"
sodipodi:ry="97.14286"
d="m 270.00001,880.93359 a 107.14286,97.14286 0 1 1 -214.285723,0 107.14286,97.14286 0 1 1 214.285723,0 z" />
<path
sodipodi:type="arc"
style="opacity:0.61851855;color:#000000;fill:#000000;fill-opacity:0;stroke:#000000;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
id="path2921"
sodipodi:cx="224.28572"
sodipodi:cy="543.79077"
sodipodi:rx="4.2857141"
sodipodi:ry="4.2857141"
d="m 228.57143,543.79077 a 4.2857141,4.2857141 0 1 1 -8.57142,0 4.2857141,4.2857141 0 1 1 8.57142,0 z"
transform="translate(-8.571435,8.5714111)" />
<path
transform="translate(31.428565,8.5714111)"
sodipodi:type="arc"
style="opacity:0.61851855;color:#000000;fill:#000000;fill-opacity:0;stroke:#000000;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
id="path2921-2"
sodipodi:cx="224.28572"
sodipodi:cy="543.79077"
sodipodi:rx="4.2857141"
sodipodi:ry="4.2857141"
d="m 228.57143,543.79077 a 4.2857141,4.2857141 0 1 1 -8.57142,0 4.2857141,4.2857141 0 1 1 8.57142,0 z" />
<path
transform="translate(71.428563,8.5714153)"
sodipodi:type="arc"
style="opacity:0.61851855;color:#000000;fill:#000000;fill-opacity:0;stroke:#000000;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
id="path2921-2-3"
sodipodi:cx="224.28572"
sodipodi:cy="543.79077"
sodipodi:rx="4.2857141"
sodipodi:ry="4.2857141"
d="m 228.57143,543.79077 a 4.2857141,4.2857141 0 1 1 -8.57142,0 4.2857141,4.2857141 0 1 1 8.57142,0 z" />
<text
xml:space="preserve"
style="font-size:24px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
x="160"
y="232.36218"
id="text2982"><tspan
sodipodi:role="line"
id="tspan2984"
x="160"
y="232.36218"
style="font-size:20">UI Event Loop</tspan><tspan
sodipodi:role="line"
x="160"
y="262.36218"
id="tspan2986"
style="font-size:20"> Thread</tspan></text>
<text
xml:space="preserve"
style="font-size:24px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
x="410"
y="262.36218"
id="text2988"><tspan
sodipodi:role="line"
id="tspan2990"
x="410"
y="262.36218"
style="font-size:20px">CrossThreadChannel</tspan></text>
<text
xml:space="preserve"
style="font-size:22px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
x="115"
y="882.36218"
id="text2992"><tspan
sodipodi:role="line"
id="tspan2994"
x="115"
y="882.36218">RT Thread</tspan></text>
<text
xml:space="preserve"
style="font-size:14px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
x="330"
y="877.36218"
id="text2996"><tspan
sodipodi:role="line"
id="tspan2998"
x="330"
y="877.36218"
style="font-size:22px">Freeze Thread</tspan></text>
<text
xml:space="preserve"
style="font-size:14px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
x="220"
y="692.36218"
id="text3006"><tspan
sodipodi:role="line"
x="220"
y="692.36218"
id="tspan3010"> Step One:</tspan><tspan
sodipodi:role="line"
x="220"
y="709.86218"
id="tspan3110">AbstractUI::get_request()</tspan><tspan
sodipodi:role="line"
x="220"
y="727.36218"
id="tspan3058">AbstractUI::send_request()</tspan></text>
<text
xml:space="preserve"
style="font-size:14px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
x="380"
y="512.36218"
id="text3012"><tspan
sodipodi:role="line"
id="tspan3014"
x="380"
y="512.36218">Generic </tspan><tspan
sodipodi:role="line"
x="380"
y="529.86218"
id="tspan3098">non-RT-safe </tspan><tspan
sodipodi:role="line"
x="380"
y="547.36218"
id="tspan3100">request queue</tspan></text>
<text
xml:space="preserve"
style="font-size:14px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
x="82.85714"
y="520.93359"
id="text3016"><tspan
sodipodi:role="line"
id="tspan3018"
x="82.85714"
y="520.93359">RT-safe per-thread request queues</tspan></text>
<path
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 130,482.36218 70,-100"
id="path3030"
inkscape:connector-type="polyline" />
<path
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="M 352.54324,485.6666 240,382.36218"
id="path3034"
inkscape:connector-type="polyline" />
<path
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 180,482.36218 40,-100"
id="path3038"
inkscape:connector-type="polyline" />
<text
xml:space="preserve"
style="font-size:14px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
x="140"
y="312.36218"
id="text3042"><tspan
sodipodi:role="line"
id="tspan3044"
x="140"
y="312.36218">while (1) </tspan><tspan
sodipodi:role="line"
x="140"
y="329.86218"
id="tspan3046"> if (channel.data_available()) {</tspan><tspan
sodipodi:role="line"
x="140"
y="347.36218"
id="tspan3048"> channel.drain();</tspan><tspan
sodipodi:role="line"
x="140"
y="364.86218"
id="tspan3050"> handle_ui_requests();</tspan><tspan
sodipodi:role="line"
x="140"
y="382.36218"
id="tspan3052"> }</tspan><tspan
sodipodi:role="line"
x="140"
y="399.86218"
id="tspan3054" /></text>
<path
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 140,777.36218 -5,-160"
id="path3062"
inkscape:connector-type="polyline" />
<path
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 185,617.36218 150,170"
id="path3066"
inkscape:connector-type="polyline" />
<path
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline"
d="m 365,617.36218 180,175"
id="path3070"
inkscape:connector-type="polyline" />
<text
xml:space="preserve"
style="font-size:14px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
x="530"
y="877.36218"
id="text3074"><tspan
sodipodi:role="line"
id="tspan3076"
x="530"
y="877.36218"
style="font-size:22px">J. Random Thread</tspan></text>
<path
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 410,777.36218 90,-80 0,-370 0,0"
id="path3080" />
<path
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 575,782.36218 -70,-85 0,-370 0,0"
id="path3084" />
<text
xml:space="preserve"
style="font-size:14px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
x="515.65338"
y="601.61261"
id="text3088"><tspan
sodipodi:role="line"
id="tspan3090"
x="515.65338"
y="601.61261"> Step Two:</tspan><tspan
sodipodi:role="line"
x="515.65338"
y="619.11261"
id="tspan3112">CrossThreadChannel::wakeup()</tspan></text>
<text
xml:space="preserve"
style="font-size:14px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
x="448.70532"
y="515.75555"
id="text3092"><tspan
sodipodi:role="line"
id="tspan3094"
x="448.70532"
y="515.75555"></tspan><tspan
sodipodi:role="line"
id="tspan3096" /></text>
<path
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 220,792.36218 c 5,0 275,-100 275,-100 l 0,-365"
id="path3104" />
<path
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 370,322.36218 105,-25"
id="path3106"
inkscape:connector-type="polyline" />
<text
xml:space="preserve"
style="font-size:14px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
x="636.26208"
y="791.72467"
id="text3114"><tspan
sodipodi:role="line"
id="tspan3116"
x="636.26208"
y="791.72467" /></text>
<rect
style="opacity:0.61851855000000000;color:#000000;fill:#000000;fill-opacity:0;stroke:#ed0000;stroke-width:2.09956263999999981;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
id="rect3139"
width="500"
height="540"
x="40"
y="122.36218"
ry="0" />
<text
xml:space="preserve"
style="font-size:14px;font-style:normal;font-weight:normal;fill:#db0000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
x="50"
y="152.36218"
id="text3141"><tspan
sodipodi:role="line"
id="tspan3143"
x="50"
y="152.36218"
style="font-size:24px;fill:#db0000;fill-opacity:1">AbstractUI IS-A BaseUI IS-A Event Loop</tspan></text>
</g>
</svg>

After

Width:  |  Height:  |  Size: 19 KiB

623
doc/region_read.svg Normal file
View file

@ -0,0 +1,623 @@
<?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:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="744.09448819"
height="1052.3622047"
id="svg5893"
version="1.1"
inkscape:version="0.48.2 r9819"
sodipodi:docname="region_read.svg">
<defs
id="defs5895">
<marker
inkscape:stockid="Arrow1Mend"
orient="auto"
refY="0.0"
refX="0.0"
id="Arrow1Mend"
style="overflow:visible;">
<path
id="path3960"
d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none;"
transform="scale(0.4) rotate(180) translate(10,0)" />
</marker>
<marker
inkscape:stockid="Arrow1Lend"
orient="auto"
refY="0.0"
refX="0.0"
id="Arrow1Lend"
style="overflow:visible;">
<path
id="path3954"
d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none;"
transform="scale(0.8) rotate(180) translate(12.5,0)" />
</marker>
<marker
inkscape:stockid="Arrow1Mstart"
orient="auto"
refY="0.0"
refX="0.0"
id="Arrow1Mstart"
style="overflow:visible">
<path
id="path3957"
d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none"
transform="scale(0.4) translate(10,0)" />
</marker>
<marker
inkscape:stockid="Arrow1Mstart"
orient="auto"
refY="0"
refX="0"
id="Arrow1Mstart-0"
style="overflow:visible">
<path
inkscape:connector-curvature="0"
id="path3957-9"
d="M 0,0 5,-5 -12.5,0 5,5 0,0 z"
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;marker-start:none"
transform="matrix(0.4,0,0,0.4,4,0)" />
</marker>
<marker
inkscape:stockid="Arrow1Mend"
orient="auto"
refY="0"
refX="0"
id="Arrow1Mend-0"
style="overflow:visible">
<path
inkscape:connector-curvature="0"
id="path3960-8"
d="M 0,0 5,-5 -12.5,0 5,5 0,0 z"
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;marker-start:none"
transform="matrix(-0.4,0,0,-0.4,-4,0)" />
</marker>
<marker
inkscape:stockid="Arrow1Mstart"
orient="auto"
refY="0"
refX="0"
id="Arrow1Mstart-9"
style="overflow:visible">
<path
inkscape:connector-curvature="0"
id="path3957-8"
d="M 0,0 5,-5 -12.5,0 5,5 0,0 z"
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;marker-start:none"
transform="matrix(0.4,0,0,0.4,4,0)" />
</marker>
<marker
inkscape:stockid="Arrow1Mend"
orient="auto"
refY="0"
refX="0"
id="Arrow1Mend-9"
style="overflow:visible">
<path
inkscape:connector-curvature="0"
id="path3960-0"
d="M 0,0 5,-5 -12.5,0 5,5 0,0 z"
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;marker-start:none"
transform="matrix(-0.4,0,0,-0.4,-4,0)" />
</marker>
<marker
inkscape:stockid="Arrow1Mstart"
orient="auto"
refY="0"
refX="0"
id="Arrow1Mstart-8"
style="overflow:visible">
<path
inkscape:connector-curvature="0"
id="path3957-5"
d="M 0,0 5,-5 -12.5,0 5,5 0,0 z"
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;marker-start:none"
transform="matrix(0.4,0,0,0.4,4,0)" />
</marker>
<marker
inkscape:stockid="Arrow1Mend"
orient="auto"
refY="0"
refX="0"
id="Arrow1Mend-1"
style="overflow:visible">
<path
inkscape:connector-curvature="0"
id="path3960-1"
d="M 0,0 5,-5 -12.5,0 5,5 0,0 z"
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;marker-start:none"
transform="matrix(-0.4,0,0,-0.4,-4,0)" />
</marker>
<marker
inkscape:stockid="Arrow1Mstart"
orient="auto"
refY="0"
refX="0"
id="Arrow1Mstart-5"
style="overflow:visible">
<path
inkscape:connector-curvature="0"
id="path3957-58"
d="M 0,0 5,-5 -12.5,0 5,5 0,0 z"
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;marker-start:none"
transform="matrix(0.4,0,0,0.4,4,0)" />
</marker>
<marker
inkscape:stockid="Arrow1Mend"
orient="auto"
refY="0"
refX="0"
id="Arrow1Mend-4"
style="overflow:visible">
<path
inkscape:connector-curvature="0"
id="path3960-4"
d="M 0,0 5,-5 -12.5,0 5,5 0,0 z"
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;marker-start:none"
transform="matrix(-0.4,0,0,-0.4,-4,0)" />
</marker>
<marker
inkscape:stockid="Arrow1Mstart"
orient="auto"
refY="0"
refX="0"
id="Arrow1Mstart-81"
style="overflow:visible">
<path
inkscape:connector-curvature="0"
id="path3957-57"
d="M 0,0 5,-5 -12.5,0 5,5 0,0 z"
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;marker-start:none"
transform="matrix(0.4,0,0,0.4,4,0)" />
</marker>
<marker
inkscape:stockid="Arrow1Mstart"
orient="auto"
refY="0"
refX="0"
id="Arrow1Mstart-4"
style="overflow:visible">
<path
inkscape:connector-curvature="0"
id="path3957-90"
d="M 0,0 5,-5 -12.5,0 5,5 0,0 z"
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;marker-start:none"
transform="matrix(0.4,0,0,0.4,4,0)" />
</marker>
<marker
inkscape:stockid="Arrow1Mend"
orient="auto"
refY="0"
refX="0"
id="Arrow1Mend-44"
style="overflow:visible">
<path
inkscape:connector-curvature="0"
id="path3960-5"
d="M 0,0 5,-5 -12.5,0 5,5 0,0 z"
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;marker-start:none"
transform="matrix(-0.4,0,0,-0.4,-4,0)" />
</marker>
<marker
inkscape:stockid="Arrow1Mstart"
orient="auto"
refY="0"
refX="0"
id="Arrow1Mstart-86"
style="overflow:visible">
<path
inkscape:connector-curvature="0"
id="path3957-0"
d="M 0,0 5,-5 -12.5,0 5,5 0,0 z"
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;marker-start:none"
transform="matrix(0.4,0,0,0.4,4,0)" />
</marker>
<marker
inkscape:stockid="Arrow1Mstart"
orient="auto"
refY="0"
refX="0"
id="marker7868"
style="overflow:visible">
<path
inkscape:connector-curvature="0"
id="path7870"
d="M 0,0 5,-5 -12.5,0 5,5 0,0 z"
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;marker-start:none"
transform="matrix(0.4,0,0,0.4,4,0)" />
</marker>
<marker
inkscape:stockid="Arrow1Mstart"
orient="auto"
refY="0"
refX="0"
id="Arrow1Mstart-7"
style="overflow:visible">
<path
inkscape:connector-curvature="0"
id="path3957-97"
d="M 0,0 5,-5 -12.5,0 5,5 0,0 z"
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;marker-start:none"
transform="matrix(0.4,0,0,0.4,4,0)" />
</marker>
<marker
inkscape:stockid="Arrow1Mend"
orient="auto"
refY="0"
refX="0"
id="Arrow1Mend-2"
style="overflow:visible">
<path
inkscape:connector-curvature="0"
id="path3960-6"
d="M 0,0 5,-5 -12.5,0 5,5 0,0 z"
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;marker-start:none"
transform="matrix(-0.4,0,0,-0.4,-4,0)" />
</marker>
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="1.2126703"
inkscape:cx="370.74302"
inkscape:cy="363.21379"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="false"
showguides="true"
inkscape:guide-bbox="true"
objecttolerance="20"
inkscape:window-width="1366"
inkscape:window-height="714"
inkscape:window-x="0"
inkscape:window-y="26"
inkscape:window-maximized="1" />
<metadata
id="metadata5898">
<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:label="Layer 1"
inkscape:groupmode="layer"
id="layer1">
<rect
style="color:#000000;fill:#f2f2f2;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.25000000000000000;stroke-miterlimit:4;stroke-dasharray:none;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
id="rect5901"
width="583"
height="145"
x="71"
y="364.36218" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:4, 0.5;stroke-dashoffset:0;marker-start:none"
d="m 70.875,509.65415 0,73.70803"
id="path6411"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
<text
xml:space="preserve"
style="font-size:10px;font-style:normal;font-variant:normal;font-weight:500;font-stretch:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Inconsolata;-inkscape-font-specification:Inconsolata Medium"
x="48.549999"
y="595.36218"
id="text6413"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan6415"
x="48.549999"
y="595.36218">_position</tspan></text>
<text
xml:space="preserve"
style="font-size:8px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
x="37.712891"
y="606.36218"
id="text6417"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan6419"
x="37.712891"
y="606.36218">(session frames)</tspan></text>
<path
style="fill:none;stroke:#ff0000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="M 71.070382,509.10042 228.41281,364.43905"
id="path6601"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#ff0000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="M 515.48919,364.4598 653.60885,509.25866"
id="path6603"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
<path
style="opacity:0.5186916;fill:#00ff00;stroke:#00ff00;stroke-width:2.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:3.70000005;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
d="m 181.33822,192.60503 0,392.78775"
id="path7188"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-start:url(#Arrow1Mstart);marker-end:url(#Arrow1Mend)"
d="m 72.373873,343.92168 153.967247,0"
id="path6605"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
<text
xml:space="preserve"
style="font-size:10px;font-style:normal;font-variant:normal;font-weight:500;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:125%;letter-spacing:0px;word-spacing:0px;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Inconsolata;-inkscape-font-specification:Inconsolata Medium"
x="114.3825"
y="339.81854"
id="text7165"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan7167"
x="114.3825"
y="339.81854">fade_in_length</tspan></text>
<text
xml:space="preserve"
style="font-size:10px;font-style:normal;font-variant:normal;font-weight:500;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:125%;letter-spacing:0px;word-spacing:0px;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Inconsolata;-inkscape-font-specification:Inconsolata Medium"
x="161.37723"
y="188.38692"
id="text7190"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan7192"
x="161.37723"
y="188.38692">position</tspan></text>
<path
style="opacity:0.5186916;fill:#00ff00;stroke:#00ff00;stroke-width:2.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:3.70000005;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
d="m 567.50406,202.50055 0,382.89223"
id="path7188-3"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-start:url(#Arrow1Mstart);marker-end:url(#Arrow1Mend)"
d="m 184.49301,533.71609 379.97457,0"
id="path6605-9"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
<g
id="g7330"
transform="translate(-62.085715,-64.181018)">
<text
sodipodi:linespacing="125%"
id="text7273"
y="593.84894"
x="392.74289"
style="font-size:10px;font-style:normal;font-variant:normal;font-weight:500;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:125%;letter-spacing:0px;word-spacing:0px;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Inconsolata;-inkscape-font-specification:Inconsolata Medium"
xml:space="preserve"><tspan
y="593.84894"
x="392.74289"
id="tspan7275"
sodipodi:role="line">cnt</tspan></text>
<text
sodipodi:linespacing="125%"
id="text7277"
y="593.84894"
x="445.35913"
style="font-size:10px;font-style:normal;font-variant:normal;font-weight:500;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:125%;letter-spacing:0px;word-spacing:0px;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Inconsolata;-inkscape-font-specification:Inconsolata Medium"
xml:space="preserve"><tspan
y="593.84894"
x="445.35913"
id="tspan7279"
sodipodi:role="line">to_read</tspan></text>
<text
sodipodi:linespacing="125%"
id="text7281"
y="593.84894"
x="419.73959"
style="font-size:8px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:125%;letter-spacing:0px;word-spacing:0px;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Sans;-inkscape-font-specification:Sans"
xml:space="preserve"><tspan
y="593.84894"
x="419.73959"
id="tspan7283"
sodipodi:role="line">and</tspan></text>
</g>
<text
xml:space="preserve"
style="font-size:10px;font-style:normal;font-variant:normal;font-weight:500;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:125%;letter-spacing:0px;word-spacing:0px;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Inconsolata;-inkscape-font-specification:Inconsolata Medium"
x="245.89932"
y="312.20105"
id="text7338"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan7340"
x="245.89932"
y="312.20105">fade_interval_start</tspan></text>
<path
style="color:#000000;fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:4, 0.5;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
d="m 515.73821,460.76182 0,-188.3422"
id="path7361"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#000000;stroke-width:0.50000000000000000;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;color:#000000;stroke-miterlimit:4;stroke-dasharray:4, 0.50000000000000000;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
d="m 227.99169,463.40636 0,-126.36082"
id="path7363"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
<path
style="color:#000000;fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:4, 0.5;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
d="m 71.006657,364.51538 0,-178.70316"
id="path7365"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-start:url(#Arrow1Mstart);marker-end:url(#Arrow1Mend)"
d="m 72.746267,316.79539 441.366113,0"
id="path6605-0"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
<text
xml:space="preserve"
style="font-size:10px;font-style:normal;font-variant:normal;font-weight:500;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:125%;letter-spacing:0px;word-spacing:0px;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Inconsolata;-inkscape-font-specification:Inconsolata Medium"
x="276.1167"
y="233.43596"
id="text7338-8"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan7340-9"
x="276.1167"
y="233.43596">fade_interval_end</tspan></text>
<path
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-start:url(#Arrow1Mstart);marker-end:url(#Arrow1Mend)"
d="m 72.883964,238.85491 491.555466,0"
id="path6605-0-5"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
<text
xml:space="preserve"
style="font-size:10px;font-style:normal;font-variant:normal;font-weight:500;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:125%;letter-spacing:0px;word-spacing:0px;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Inconsolata;-inkscape-font-specification:Inconsolata Medium"
x="169.82126"
y="468.99326"
id="text7503"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan7505"
x="169.82126"
y="468.99326">fade_in_limit</tspan></text>
<path
style="fill:none;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker-start:url(#Arrow1Mstart);marker-end:none"
d="m 229.69834,453.68338 17.07926,0"
id="path6605-8"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker-start:url(#Arrow1Mstart);marker-end:none"
d="m 178.20807,453.68338 -17.07926,0"
id="path6605-8-9"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-start:url(#Arrow1Mstart);marker-end:url(#Arrow1Mend)"
d="m 184.43048,282.98571 329.46521,0"
id="path6605-0-5-8"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
<text
xml:space="preserve"
style="font-size:10px;font-style:normal;font-variant:normal;font-weight:500;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:125%;letter-spacing:0px;word-spacing:0px;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Inconsolata;-inkscape-font-specification:Inconsolata Medium"
x="311.63309"
y="278.03796"
id="text7812"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan7814"
x="311.63309"
y="278.03796">fade_out_offset</tspan></text>
<text
xml:space="preserve"
style="font-size:10px;font-style:normal;font-variant:normal;font-weight:500;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:125%;letter-spacing:0px;word-spacing:0px;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Inconsolata;-inkscape-font-specification:Inconsolata Medium"
x="509.66217"
y="468.99326"
id="text7503-0"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan7505-5"
x="509.66217"
y="468.99326">fade_out_limit</tspan></text>
<path
style="fill:none;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker-start:url(#Arrow1Mstart);marker-end:none"
d="m 570.6613,453.68338 17.07926,0"
id="path6605-8-8"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker-start:url(#Arrow1Mstart);marker-end:none"
d="m 513.56056,453.68338 -17.07926,0"
id="path6605-8-9-1"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-start:url(#Arrow1Mstart);marker-end:url(#Arrow1Mend)"
d="m 72.680058,213.87052 105.576122,0"
id="path6605-7"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
<text
xml:space="preserve"
style="font-size:10px;font-style:normal;font-variant:normal;font-weight:500;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:125%;letter-spacing:0px;word-spacing:0px;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Inconsolata;-inkscape-font-specification:Inconsolata Medium"
x="89.543594"
y="209.7674"
id="text7165-4"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
x="89.543594"
y="209.7674"
id="tspan7936">internal_offset</tspan></text>
<rect
style="opacity:0.5186916;color:#000000;fill:#f2f2f2;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
id="rect7940"
width="36.283562"
height="32.160431"
x="90.708908"
y="684.5788" />
<text
xml:space="preserve"
style="font-size:12px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
x="141.83575"
y="703.96954"
id="text7959"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan7961"
x="141.83575"
y="703.96954">Region</tspan></text>
<path
style="opacity:0.5186916;color:#000000;fill:#00ff00;fill-opacity:1;fill-rule:nonzero;stroke:#00ff00;stroke-width:2.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:3.70000005;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
d="m 80.188387,745.73829 46.179083,0"
id="path7963"
inkscape:connector-curvature="0" />
<text
xml:space="preserve"
style="font-size:12px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
x="141.83575"
y="749.04883"
id="text7982"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan7984"
x="141.83575"
y="749.04883">Range being read</tspan></text>
<path
style="opacity:0.5186916;color:#000000;fill:none;stroke:#ff0000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
d="m 80.938388,776.11233 46.179082,0"
id="path7963-9"
inkscape:connector-curvature="0" />
<text
xml:space="preserve"
style="font-size:12px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
x="141.83575"
y="780.58594"
id="text8053"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan8055"
x="141.83575"
y="780.58594">Fade</tspan><tspan
sodipodi:role="line"
x="141.83575"
y="795.58594"
id="tspan8057" /></text>
</g>
</svg>

After

Width:  |  Height:  |  Size: 29 KiB

View file

@ -8,6 +8,7 @@ export ARDOUR_PATH=$TOP/gtk2_ardour/icons:$TOP/gtk2_ardour/pixmaps:$TOP/build/gt
export ARDOUR_SURFACES_PATH=$libs/surfaces/osc:$libs/surfaces/generic_midi:$libs/surfaces/tranzport:$libs/surfaces/powermate:$libs/surfaces/mackie
export ARDOUR_PANNER_PATH=$libs/panners/2in2out:$libs/panners/1in2out:$libs/panners/vbap
export ARDOUR_DATA_PATH=$TOP/gtk2_ardour:build/gtk2_ardour:.
export ARDOUR_MCP_PATH=$TOP/mcp:.
if test -d $HOME/gtk/inst ; then
export GTK_PATH=~/.ardour3:$libs/clearlooks-newer

View file

@ -10,6 +10,7 @@
<accelerator action='focus-on-clock'/>
<accelerator action='track-solo-toggle'/>
<accelerator action='track-mute-toggle'/>
<accelerator action='toggle-edit-mode'/>
<menubar name='Main' action='MainMenu'>
<menu name='Session' action='Session'>
@ -213,7 +214,6 @@
<menuitem action='cycle-edit-point'/>
<menuitem action='cycle-edit-point-with-marker'/>
</menu>
<menuitem action='toggle-edit-mode'/>
<separator/>
<menu action="TempoMenu">
<menuitem action='set-tempo-from-region'/>

View file

@ -75,10 +75,12 @@ ArdourButton::ArdourButton (Element e)
ArdourButton::ArdourButton (const std::string& str, Element e)
: _elements (e)
, _tweaks (Tweaks (0))
, _text_width (0)
, _text_height (0)
, _diameter (11.0)
, _corner_radius (9.0)
, _corner_mask (0xf)
, edge_pattern (0)
, active_pattern (0)
, inactive_pattern (0)

View file

@ -168,20 +168,8 @@ ARDOUR_UI::ARDOUR_UI (int *argcp, char **argvp[])
, _feedback_exists (false)
{
using namespace Gtk::Menu_Helpers;
Gtkmm2ext::init();
#ifdef TOP_MENUBAR
// _auto_display_errors = false;
/*
* This was commented out as it wasn't defined
* in A3 IIRC. If this is not needed it should
* be completely removed.
*/
#endif
about = 0;
splash = 0;
_startup = 0;
@ -252,7 +240,7 @@ ARDOUR_UI::ARDOUR_UI (int *argcp, char **argvp[])
/* handle dialog requests */
ARDOUR::Session::Dialog.connect (forever_connections, MISSING_INVALIDATOR, ui_bind (&ARDOUR_UI::session_dialog, this, _1), gui_context());
ARDOUR::Session::Dialog.connect (forever_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::session_dialog, this, _1), gui_context());
/* handle pending state with a dialog (PROBLEM: needs to return a value and thus cannot be x-thread) */
@ -264,12 +252,12 @@ ARDOUR_UI::ARDOUR_UI (int *argcp, char **argvp[])
/* handle requests to quit (coming from JACK session) */
ARDOUR::Session::Quit.connect (forever_connections, MISSING_INVALIDATOR, ui_bind (&ARDOUR_UI::finish, this), gui_context ());
ARDOUR::Session::Quit.connect (forever_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::finish, this), gui_context ());
/* tell the user about feedback */
ARDOUR::Session::FeedbackDetected.connect (forever_connections, MISSING_INVALIDATOR, ui_bind (&ARDOUR_UI::feedback_detected, this), gui_context ());
ARDOUR::Session::SuccessfulGraphSort.connect (forever_connections, MISSING_INVALIDATOR, ui_bind (&ARDOUR_UI::successful_graph_sort, this), gui_context ());
ARDOUR::Session::FeedbackDetected.connect (forever_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::feedback_detected, this), gui_context ());
ARDOUR::Session::SuccessfulGraphSort.connect (forever_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::successful_graph_sort, this), gui_context ());
/* handle requests to deal with missing files */
@ -360,7 +348,7 @@ ARDOUR_UI::run_startup (bool should_be_new, string load_template)
_startup->set_new_only (should_be_new);
if (!load_template.empty()) {
_startup->set_load_template( load_template );
_startup->set_load_template (load_template);
}
_startup->present ();
@ -397,7 +385,7 @@ ARDOUR_UI::create_engine ()
engine->Stopped.connect (forever_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::engine_stopped, this), gui_context());
engine->Running.connect (forever_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::engine_running, this), gui_context());
engine->SampleRateChanged.connect (forever_connections, MISSING_INVALIDATOR, ui_bind (&ARDOUR_UI::update_sample_rate, this, _1), gui_context());
engine->SampleRateChanged.connect (forever_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::update_sample_rate, this, _1), gui_context());
engine->Halted.connect_same_thread (forever_connections, boost::bind (&ARDOUR_UI::engine_halted, this, _1, false));
@ -483,7 +471,7 @@ ARDOUR_UI::post_engine ()
update_cpu_load ();
update_sample_rate (engine->frame_rate());
Config->ParameterChanged.connect (forever_connections, MISSING_INVALIDATOR, ui_bind (&ARDOUR_UI::parameter_changed, this, _1), gui_context());
Config->ParameterChanged.connect (forever_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::parameter_changed, this, _1), gui_context());
boost::function<void (string)> pc (boost::bind (&ARDOUR_UI::parameter_changed, this, _1));
Config->map_parameters (pc);
@ -530,7 +518,6 @@ ARDOUR_UI::configure_timeout ()
return true;
} else {
have_configure_timeout = false;
cerr << "config event-driven save\n";
save_ardour_state ();
return false;
}
@ -578,7 +565,6 @@ ARDOUR_UI::set_transport_controllable_state (const XMLNode& node)
if ((prop = node.property ("shuttle")) != 0) {
shuttle_box->controllable()->set_id (prop->value());
}
}
XMLNode&
@ -796,10 +782,10 @@ ARDOUR_UI::finish()
if (save_state_canfail ("")) {
/* failed - don't quit */
MessageDialog msg (*editor,
_("\
Ardour was unable to save your session.\n\n\
string_compose (_("\
%1 was unable to save your session.\n\n\
If you still wish to quit, please use the\n\n\
\"Just quit\" option."));
\"Just quit\" option."), PROGRAM_NAME));
pop_back_splash(msg);
msg.run ();
return;
@ -1112,15 +1098,6 @@ ARDOUR_UI::update_disk_space()
}
disk_space_label.set_markup (buf);
// An attempt to make the disk space label flash red when space has run out.
if (frames < fr * 60 * 5) {
/* disk_space_box.style ("disk_space_label_empty"); */
} else {
/* disk_space_box.style ("disk_space_label"); */
}
}
gint
@ -1155,7 +1132,7 @@ ARDOUR_UI::redisplay_recent_sessions ()
recent_session_display.set_model (recent_session_model);
return;
}
//
// sort them alphabetically
sort (rs.begin(), rs.end(), cmp);
@ -1174,12 +1151,12 @@ ARDOUR_UI::redisplay_recent_sessions ()
vector<string*>* states;
vector<const gchar*> item;
string fullpath = (*i).to_string();
string fullpath = i->to_string();
/* remove any trailing / */
if (fullpath[fullpath.length()-1] == '/') {
fullpath = fullpath.substr (0, fullpath.length()-1);
if (fullpath[fullpath.length() - 1] == '/') {
fullpath = fullpath.substr (0, fullpath.length() - 1);
}
/* check whether session still exists */
@ -1249,7 +1226,6 @@ ARDOUR_UI::build_session_selector ()
recent_session_display.show();
scroller->show();
//session_selector_window->get_vbox()->show();
}
void
@ -1416,11 +1392,7 @@ ARDOUR_UI::session_add_midi_route (bool disk, RouteGroup* route_group, uint32_t
}
}
} /*else {
if ((route = _session->new_midi_route ()) == 0) {
error << _("could not create new midi bus") << endmsg;
}
}*/
}
}
catch (...) {
@ -1612,7 +1584,6 @@ ARDOUR_UI::transport_record (bool roll)
_session->disable_record (false, true);
}
}
//cerr << "ARDOUR_UI::transport_record () called roll = " << roll << " _session->record_status() = " << _session->record_status() << endl;
}
void
@ -1787,35 +1758,34 @@ ARDOUR_UI::transport_rewind (int option)
void
ARDOUR_UI::transport_forward (int option)
{
float current_transport_speed;
if (!_session) {
return;
}
if (_session) {
current_transport_speed = _session->transport_speed();
float current_transport_speed = _session->transport_speed();
if (current_transport_speed <= 0.0f) {
switch (option) {
case 0:
_session->request_transport_speed (1.0f);
break;
case 1:
_session->request_transport_speed (4.0f);
break;
case -1:
_session->request_transport_speed (0.5f);
break;
}
} else {
/* speed up */
_session->request_transport_speed (current_transport_speed * 1.5f);
if (current_transport_speed <= 0.0f) {
switch (option) {
case 0:
_session->request_transport_speed (1.0f);
break;
case 1:
_session->request_transport_speed (4.0f);
break;
case -1:
_session->request_transport_speed (0.5f);
break;
}
} else {
/* speed up */
_session->request_transport_speed (current_transport_speed * 1.5f);
}
}
void
ARDOUR_UI::toggle_record_enable (uint32_t rid)
{
if (_session == 0) {
if (!_session) {
return;
}
@ -1829,9 +1799,6 @@ ARDOUR_UI::toggle_record_enable (uint32_t rid)
t->set_record_enabled (!t->record_enabled(), this);
}
}
if (_session == 0) {
return;
}
}
void
@ -2032,7 +1999,6 @@ ARDOUR_UI::stop_clocking ()
gint
ARDOUR_UI::_blink (void *arg)
{
((ARDOUR_UI *) arg)->blink ();
return TRUE;
@ -2424,27 +2390,9 @@ ARDOUR_UI::idle_load (const std::string& path)
/* /path/to/foo/foo.ardour => /path/to/foo, foo */
load_session (Glib::path_get_dirname (path), basename_nosuffix (path));
}
} else {
ARDOUR_COMMAND_LINE::session_name = path;
/*
* new_session_dialog doens't exist in A3
* Try to remove all references to it to
* see if it will compile. NOTE: this will
* likely cause a runtime issue is my somewhat
* uneducated guess.
*/
//if (new_session_dialog) {
/* make it break out of Dialog::run() and
start again.
*/
//new_session_dialog->response (1);
//}
}
}
@ -2850,7 +2798,7 @@ ARDOUR_UI::show_about ()
{
if (about == 0) {
about = new About;
about->signal_response().connect(sigc::mem_fun (*this, &ARDOUR_UI::about_signal_response) );
about->signal_response().connect (sigc::mem_fun (*this, &ARDOUR_UI::about_signal_response));
}
about->set_transient_for(*editor);
@ -3363,14 +3311,14 @@ ARDOUR_UI::pending_state_dialog ()
HBox* hbox = new HBox();
Image* image = new Image (Stock::DIALOG_QUESTION, ICON_SIZE_DIALOG);
ArdourDialog dialog (_("Crash Recovery"), true);
Label message (_("\
Label message (string_compose (_("\
This session appears to have been in\n\
middle of recording when ardour or\n\
the computer was shutdown.\n\
\n\
Ardour can recover any captured audio for\n\
%1 can recover any captured audio for\n\
you, or it can ignore it. Please decide\n\
what you would like to do.\n"));
what you would like to do.\n"), PROGRAM_NAME));
image->set_alignment(ALIGN_CENTER, ALIGN_TOP);
hbox->pack_start (*image, PACK_EXPAND_WIDGET, 12);
hbox->pack_end (message, PACK_EXPAND_PADDING, 12);
@ -3398,9 +3346,9 @@ ARDOUR_UI::sr_mismatch_dialog (framecnt_t desired, framecnt_t actual)
Image* image = new Image (Stock::DIALOG_QUESTION, ICON_SIZE_DIALOG);
ArdourDialog dialog (_("Sample Rate Mismatch"), true);
Label message (string_compose (_("\
This session was created with a sample rate of %1 Hz\n\
\n\
The audioengine is currently running at %2 Hz\n"), desired, actual));
This session was created with a sample rate of %1 Hz, but\n\
%2 is currently running at %3 Hz. If you load this session,\n\
audio may be played at the wrong sample rate.\n"), desired, PROGRAM_NAME, actual));
image->set_alignment(ALIGN_CENTER, ALIGN_TOP);
hbox->pack_start (*image, PACK_EXPAND_WIDGET, 12);
@ -3427,7 +3375,7 @@ void
ARDOUR_UI::disconnect_from_jack ()
{
if (engine) {
if( engine->disconnect_from_jack ()) {
if (engine->disconnect_from_jack ()) {
MessageDialog msg (*editor, _("Could not disconnect from JACK"));
msg.run ();
}
@ -3628,11 +3576,10 @@ ARDOUR_UI::TransportControllable::get_value (void) const
void
ARDOUR_UI::setup_profile ()
{
if (gdk_screen_width() < 1200) {
if (gdk_screen_width() < 1200 || getenv ("ARDOUR_NARROW_SCREEN")) {
Profile->set_small_screen ();
}
if (getenv ("ARDOUR_SAE")) {
Profile->set_sae ();
Profile->set_single_package ();
@ -3654,11 +3601,11 @@ ARDOUR_UI::toggle_translations ()
bool already_enabled = !ARDOUR::translations_are_disabled ();
if (ract->get_active ()) {
/* we don't care about errors */
/* we don't care about errors */
int fd = ::open (i18n_killer.c_str(), O_RDONLY|O_CREAT, 0644);
close (fd);
} else {
/* we don't care about errors */
/* we don't care about errors */
unlink (i18n_killer.c_str());
}

View file

@ -161,15 +161,15 @@ ARDOUR_UI::set_session (Session *s)
_session->TransportStateChange.connect (_session_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::map_transport_state, this), gui_context());
_session->DirtyChanged.connect (_session_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::update_autosave, this), gui_context());
_session->Xrun.connect (_session_connections, MISSING_INVALIDATOR, ui_bind (&ARDOUR_UI::xrun_handler, this, _1), gui_context());
_session->SoloActive.connect (_session_connections, MISSING_INVALIDATOR, ui_bind (&ARDOUR_UI::soloing_changed, this, _1), gui_context());
_session->AuditionActive.connect (_session_connections, MISSING_INVALIDATOR, ui_bind (&ARDOUR_UI::auditioning_changed, this, _1), gui_context());
_session->locations()->added.connect (_session_connections, MISSING_INVALIDATOR, ui_bind (&ARDOUR_UI::handle_locations_change, this, _1), gui_context());
_session->locations()->removed.connect (_session_connections, MISSING_INVALIDATOR, ui_bind (&ARDOUR_UI::handle_locations_change, this, _1), gui_context());
_session->config.ParameterChanged.connect (_session_connections, MISSING_INVALIDATOR, ui_bind (&ARDOUR_UI::session_parameter_changed, this, _1), gui_context ());
_session->Xrun.connect (_session_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::xrun_handler, this, _1), gui_context());
_session->SoloActive.connect (_session_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::soloing_changed, this, _1), gui_context());
_session->AuditionActive.connect (_session_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::auditioning_changed, this, _1), gui_context());
_session->locations()->added.connect (_session_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::handle_locations_change, this, _1), gui_context());
_session->locations()->removed.connect (_session_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::handle_locations_change, this, _1), gui_context());
_session->config.ParameterChanged.connect (_session_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::session_parameter_changed, this, _1), gui_context ());
#ifdef HAVE_JACK_SESSION
engine->JackSessionEvent.connect (*_session, MISSING_INVALIDATOR, ui_bind (&Session::jack_session_event, _session, _1), gui_context());
engine->JackSessionEvent.connect (*_session, MISSING_INVALIDATOR, boost::bind (&Session::jack_session_event, _session, _1), gui_context());
#endif
/* Clocks are on by default after we are connected to a session, so show that here.

View file

@ -293,7 +293,7 @@ ARDOUR_UI::toggle_editing_space()
void
ARDOUR_UI::setup_session_options ()
{
_session->config.ParameterChanged.connect (_session_connections, MISSING_INVALIDATOR, ui_bind (&ARDOUR_UI::parameter_changed, this, _1), gui_context());
_session->config.ParameterChanged.connect (_session_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::parameter_changed, this, _1), gui_context());
boost::function<void (std::string)> pc (boost::bind (&ARDOUR_UI::parameter_changed, this, _1));
_session->config.map_parameters (pc);
}

View file

@ -392,7 +392,12 @@ AUPluginUI::create_cocoa_view ()
// watch for size changes of the view
[[NSNotificationCenter defaultCenter] addObserver:_notify
selector:@selector(auViewResized:) name:NSWindowDidResizeNotification
selector:@selector(auViewResized:) name:NSViewBoundsDidChangeNotification
object:au_view];
[[NSNotificationCenter defaultCenter] addObserver:_notify
selector:@selector(auViewResized:) name:NSViewFrameDidChangeNotification
object:au_view];
// Get the size of the new AU View's frame
@ -410,6 +415,9 @@ void
AUPluginUI::cocoa_view_resized ()
{
NSRect packFrame = [au_view frame];
prefwidth = packFrame.size.width;
prefheight = packFrame.size.height;
low_box.set_size_request (prefwidth, prefheight);
}
int

View file

@ -46,7 +46,6 @@
#include "selection.h"
#include "public_editor.h"
#include "ardour_ui.h"
#include "crossfade_view.h"
#include "rgb_macros.h"
#include "gui_thread.h"
#include "utils.h"
@ -61,30 +60,10 @@ using namespace Editing;
AudioStreamView::AudioStreamView (AudioTimeAxisView& tv)
: StreamView (tv)
{
crossfades_visible = tv.session()->config.get_xfades_visible ();
color_handler ();
_amplitude_above_axis = 1.0;
Config->ParameterChanged.connect (*this, invalidator (*this), ui_bind (&AudioStreamView::parameter_changed, this, _1), gui_context());
}
AudioStreamView::~AudioStreamView ()
{
for (CrossfadeViewList::iterator xi = crossfade_views.begin(); xi != crossfade_views.end(); ++xi) {
delete xi->second;
}
}
int
AudioStreamView::set_samples_per_unit (gdouble spp)
{
StreamView::set_samples_per_unit(spp);
for (CrossfadeViewList::iterator xi = crossfade_views.begin(); xi != crossfade_views.end(); ++xi) {
xi->second->set_samples_per_unit (spp);
}
return 0;
Config->ParameterChanged.connect (*this, invalidator (*this), boost::bind (&AudioStreamView::parameter_changed, this, _1), gui_context());
}
int
@ -209,163 +188,10 @@ AudioStreamView::add_region_view_internal (boost::shared_ptr<Region> r, bool wai
return region_view;
}
void
AudioStreamView::remove_region_view (boost::weak_ptr<Region> weak_r)
{
ENSURE_GUI_THREAD (*this, &AudioStreamView::remove_region_view, weak_r);
boost::shared_ptr<Region> r (weak_r.lock());
if (!r) {
return;
}
if (!_trackview.session()->deletion_in_progress()) {
for (CrossfadeViewList::iterator i = crossfade_views.begin(); i != crossfade_views.end();) {
CrossfadeViewList::iterator tmp;
tmp = i;
++tmp;
boost::shared_ptr<AudioRegion> ar = boost::dynamic_pointer_cast<AudioRegion>(r);
if (ar && i->second->crossfade->involves (ar)) {
delete i->second;
crossfade_views.erase (i);
}
i = tmp;
}
}
StreamView::remove_region_view(r);
}
void
AudioStreamView::undisplay_track ()
{
StreamView::undisplay_track ();
for (CrossfadeViewList::iterator i = crossfade_views.begin(); i != crossfade_views.end(); ++i) {
delete i->second;
}
crossfade_views.clear ();
}
void
AudioStreamView::playlist_layered (boost::weak_ptr<Track> wtr)
{
boost::shared_ptr<Track> tr (wtr.lock());
if (!tr) {
return;
}
StreamView::playlist_layered (wtr);
/* make sure xfades are on top and all the regionviews are stacked correctly. */
for (CrossfadeViewList::iterator i = crossfade_views.begin(); i != crossfade_views.end(); ++i) {
i->second->get_canvas_group()->raise_to_top();
}
}
void
AudioStreamView::playlist_switched (boost::weak_ptr<Track> wtr)
{
boost::shared_ptr<Track> tr (wtr.lock());
if (!tr) {
return;
}
playlist_connections.drop_connections ();
StreamView::playlist_switched (tr);
boost::shared_ptr<AudioPlaylist> apl = boost::dynamic_pointer_cast<AudioPlaylist> (tr->playlist());
if (apl) {
apl->NewCrossfade.connect (playlist_connections, invalidator (*this), ui_bind (&AudioStreamView::add_crossfade, this, _1), gui_context());
}
}
void
AudioStreamView::add_crossfade (boost::weak_ptr<Crossfade> wc)
{
boost::shared_ptr<Crossfade> crossfade (wc.lock());
if (!crossfade) {
return;
}
AudioRegionView* lview = 0;
AudioRegionView* rview = 0;
/* first see if we already have a CrossfadeView for this Crossfade */
CrossfadeViewList::iterator i = crossfade_views.find (crossfade);
if (i != crossfade_views.end()) {
if (!crossfades_visible) {
i->second->hide();
} else {
i->second->show ();
}
i->second->set_valid (true);
return;
}
/* create a new one */
for (list<RegionView *>::iterator i = region_views.begin(); i != region_views.end(); ++i) {
AudioRegionView* arv = dynamic_cast<AudioRegionView*>(*i);
if (!lview && arv && (arv->region() == crossfade->out())) {
lview = arv;
}
if (!rview && arv && (arv->region() == crossfade->in())) {
rview = arv;
}
}
CrossfadeView *cv = new CrossfadeView (_trackview.canvas_display (),
_trackview,
crossfade,
_samples_per_unit,
region_color,
*lview, *rview);
cv->set_valid (true);
crossfade->Invalidated.connect (*this, invalidator (*this), ui_bind (&AudioStreamView::remove_crossfade, this, _1), gui_context());
crossfade_views[cv->crossfade] = cv;
if (!crossfades_visible) {
cv->hide ();
}
update_content_height (cv);
}
void
AudioStreamView::remove_crossfade (boost::shared_ptr<Region> r)
{
ENSURE_GUI_THREAD (*this, &AudioStreamView::remove_crossfade, r)
boost::shared_ptr<Crossfade> xfade = boost::dynamic_pointer_cast<Crossfade> (r);
for (CrossfadeViewList::iterator i = crossfade_views.begin(); i != crossfade_views.end(); ++i) {
if (i->second->crossfade == xfade) {
delete i->second;
crossfade_views.erase (i);
break;
}
}
}
void
AudioStreamView::redisplay_track ()
{
list<RegionView *>::iterator i;
CrossfadeViewList::iterator xi, tmpx;
// Flag region views as invalid and disable drawing
for (i = region_views.begin(); i != region_views.end(); ++i) {
@ -373,41 +199,11 @@ AudioStreamView::redisplay_track ()
(*i)->enable_display (false);
}
// Flag crossfade views as invalid
for (xi = crossfade_views.begin(); xi != crossfade_views.end(); ++xi) {
xi->second->set_valid (false);
if (xi->second->visible()) {
xi->second->show ();
}
}
// Add and display region and crossfade views, and flag them as valid
// Add and display views, and flag them as valid
if (_trackview.is_audio_track()) {
_trackview.track()->playlist()->foreach_region(
sigc::hide_return (sigc::mem_fun (*this, &StreamView::add_region_view))
);
boost::shared_ptr<AudioPlaylist> apl = boost::dynamic_pointer_cast<AudioPlaylist>(
_trackview.track()->playlist()
);
if (apl) {
apl->foreach_crossfade (sigc::mem_fun (*this, &AudioStreamView::add_crossfade));
}
}
// Remove invalid crossfade views
for (xi = crossfade_views.begin(); xi != crossfade_views.end();) {
tmpx = xi;
tmpx++;
if (!xi->second->valid()) {
delete xi->second;
crossfade_views.erase (xi);
}
xi = tmpx;
}
// Stack regions by layer, and remove invalid regions
@ -473,7 +269,7 @@ AudioStreamView::setup_rec_box ()
sources.push_back (src);
src->PeakRangeReady.connect (rec_data_ready_connections,
invalidator (*this),
ui_bind (&AudioStreamView::rec_peak_range_ready, this, _1, _2, boost::weak_ptr<Source>(src)),
boost::bind (&AudioStreamView::rec_peak_range_ready, this, _1, _2, boost::weak_ptr<Source>(src)),
gui_context());
}
}
@ -600,14 +396,6 @@ AudioStreamView::setup_rec_box ()
}
}
void
AudioStreamView::foreach_crossfadeview (void (CrossfadeView::*pmf)(void))
{
for (CrossfadeViewList::iterator i = crossfade_views.begin(); i != crossfade_views.end(); ++i) {
(i->second->*pmf) ();
}
}
void
AudioStreamView::rec_peak_range_ready (framepos_t start, framecnt_t cnt, boost::weak_ptr<Source> weak_src)
{
@ -744,40 +532,6 @@ AudioStreamView::hide_all_fades ()
}
}
void
AudioStreamView::show_all_xfades ()
{
foreach_crossfadeview (&CrossfadeView::show);
crossfades_visible = true;
}
void
AudioStreamView::hide_all_xfades ()
{
foreach_crossfadeview (&CrossfadeView::hide);
crossfades_visible = false;
}
void
AudioStreamView::hide_xfades_involving (AudioRegionView& rv)
{
for (CrossfadeViewList::iterator i = crossfade_views.begin(); i != crossfade_views.end(); ++i) {
if (i->second->crossfade->involves (rv.audio_region())) {
i->second->fake_hide ();
}
}
}
void
AudioStreamView::reveal_xfades_involving (AudioRegionView& rv)
{
for (CrossfadeViewList::iterator i = crossfade_views.begin(); i != crossfade_views.end(); ++i) {
if (i->second->crossfade->involves (rv.audio_region()) && i->second->visible()) {
i->second->show ();
}
}
}
void
AudioStreamView::color_handler ()
{
@ -796,45 +550,6 @@ AudioStreamView::color_handler ()
}
}
void
AudioStreamView::update_contents_height ()
{
StreamView::update_contents_height ();
for (CrossfadeViewList::iterator i = crossfade_views.begin(); i != crossfade_views.end(); ++i) {
update_content_height (i->second);
}
}
void
AudioStreamView::update_content_height (CrossfadeView* cv)
{
switch (_layer_display) {
case Overlaid:
cv->set_y (0);
cv->set_heights (height, height);
break;
case Stacked:
case Expanded:
layer_t const inl = cv->crossfade->in()->layer ();
layer_t const outl = cv->crossfade->out()->layer ();
layer_t const high = max (inl, outl);
layer_t const low = min (inl, outl);
const double h = child_height ();
if (_layer_display == Stacked) {
cv->set_y ((_layers - high - 1) * h);
cv->set_heights ((high - low + 1) * h, h);
} else {
cv->set_y (((_layers - high) * 2 - 1) * h);
cv->set_heights (((high - low) * 2 + 1) * h, h);
}
}
}
void
AudioStreamView::parameter_changed (string const & p)
{
@ -847,13 +562,3 @@ AudioStreamView::parameter_changed (string const & p)
}
}
void
AudioStreamView::horizontal_position_changed ()
{
/* we only `draw' the bit of the curve that is visible, so we need to update here */
for (CrossfadeViewList::iterator i = crossfade_views.begin(); i != crossfade_views.end(); ++i) {
i->second->horizontal_position_changed ();
}
}

View file

@ -36,7 +36,6 @@ namespace Gdk {
namespace ARDOUR {
class Route;
class Crossfade;
class PeakData;
class AudioRegion;
class Source;
@ -47,33 +46,21 @@ class Selectable;
class AudioTimeAxisView;
class AudioRegionView;
class RegionSelection;
class CrossfadeView;
class Selection;
class AudioStreamView : public StreamView
{
public:
AudioStreamView (AudioTimeAxisView&);
~AudioStreamView ();
int set_samples_per_unit (gdouble spp);
void horizontal_position_changed ();
int set_amplitude_above_axis (gdouble app);
gdouble get_amplitude_above_axis () { return _amplitude_above_axis; }
void set_show_waveforms (bool yn);
void foreach_crossfadeview (void (CrossfadeView::*pmf)(void));
void show_all_fades ();
void hide_all_fades ();
void show_all_xfades ();
void hide_all_xfades ();
void hide_xfades_involving (AudioRegionView&);
void reveal_xfades_involving (AudioRegionView&);
RegionView* create_region_view (boost::shared_ptr<ARDOUR::Region>, bool, bool);
private:
@ -82,32 +69,18 @@ class AudioStreamView : public StreamView
void update_rec_regions (ARDOUR::framepos_t, ARDOUR::framecnt_t);
RegionView* add_region_view_internal (boost::shared_ptr<ARDOUR::Region>, bool wait_for_waves, bool recording = false);
void remove_region_view (boost::weak_ptr<ARDOUR::Region> );
void remove_audio_region_view (boost::shared_ptr<ARDOUR::AudioRegion> );
void undisplay_track ();
void redisplay_track ();
void playlist_layered (boost::weak_ptr<ARDOUR::Track>);
void playlist_switched (boost::weak_ptr<ARDOUR::Track>);
void add_crossfade (boost::weak_ptr<ARDOUR::Crossfade>);
void remove_crossfade (boost::shared_ptr<ARDOUR::Region>);
void color_handler ();
void update_contents_height ();
void update_content_height (CrossfadeView *);
void parameter_changed (std::string const &);
void set_waveform_shape (ARDOUR::WaveformShape);
void set_waveform_scale (ARDOUR::WaveformScale);
double _amplitude_above_axis;
typedef std::map<boost::shared_ptr<ARDOUR::Crossfade>, CrossfadeView*> CrossfadeViewList;
CrossfadeViewList crossfade_views;
bool crossfades_visible;
std::map<boost::shared_ptr<ARDOUR::Source>, bool> rec_data_ready_map;
bool outline_region;

View file

@ -55,7 +55,6 @@
#include "audio_time_axis.h"
#include "automation_line.h"
#include "canvas_impl.h"
#include "crossfade_view.h"
#include "enums.h"
#include "gui_thread.h"
#include "automation_time_axis.h"
@ -176,22 +175,6 @@ AudioTimeAxisView::hide ()
TimeAxisView::hide ();
}
void
AudioTimeAxisView::append_extra_display_menu_items ()
{
using namespace Menu_Helpers;
MenuList& items = display_menu->items();
// crossfade stuff
if (!Profile->get_sae() && is_track ()) {
items.push_back (MenuElem (_("Hide All Crossfades"), sigc::bind (sigc::mem_fun(*this, &AudioTimeAxisView::hide_all_xfades), true)));
items.push_back (MenuElem (_("Show All Crossfades"), sigc::bind (sigc::mem_fun(*this, &AudioTimeAxisView::show_all_xfades), true)));
items.push_back (SeparatorElem ());
}
}
void
AudioTimeAxisView::create_automation_child (const Evoral::Parameter& param, bool show)
{
@ -365,54 +348,6 @@ AudioTimeAxisView::hide_all_automation (bool apply_to_selection)
}
}
void
AudioTimeAxisView::show_all_xfades (bool apply_to_selection)
{
if (apply_to_selection) {
_editor.get_selection().tracks.foreach_audio_time_axis (boost::bind (&AudioTimeAxisView::show_all_xfades, _1, false));
} else {
AudioStreamView* asv = audio_view ();
if (asv) {
asv->show_all_xfades ();
}
}
}
void
AudioTimeAxisView::hide_all_xfades (bool apply_to_selection)
{
if (apply_to_selection) {
_editor.get_selection().tracks.foreach_audio_time_axis (boost::bind (&AudioTimeAxisView::hide_all_xfades, _1, false));
} else {
AudioStreamView* asv = audio_view ();
if (asv) {
asv->hide_all_xfades ();
}
}
}
void
AudioTimeAxisView::hide_dependent_views (TimeAxisViewItem& tavi)
{
AudioStreamView* asv = audio_view();
AudioRegionView* rv;
if (asv && (rv = dynamic_cast<AudioRegionView*>(&tavi)) != 0) {
asv->hide_xfades_involving (*rv);
}
}
void
AudioTimeAxisView::reveal_dependent_views (TimeAxisViewItem& tavi)
{
AudioStreamView* asv = audio_view();
AudioRegionView* rv;
if (asv && (rv = dynamic_cast<AudioRegionView*>(&tavi)) != 0) {
asv->reveal_xfades_involving (*rv);
}
}
void
AudioTimeAxisView::route_active_changed ()
{

View file

@ -73,10 +73,6 @@ class AudioTimeAxisView : public RouteTimeAxisView
AudioStreamView* audio_view();
void set_show_waveforms_recording (bool yn);
void show_all_xfades (bool apply_to_selection = false);
void hide_all_xfades (bool apply_to_selection = false);
void hide_dependent_views (TimeAxisViewItem&);
void reveal_dependent_views (TimeAxisViewItem&);
/* Overridden from parent to store display state */
guint32 show_at (double y, int& nth, Gtk::VBox *parent);
@ -94,7 +90,6 @@ class AudioTimeAxisView : public RouteTimeAxisView
void route_active_changed ();
void append_extra_display_menu_items ();
Gtk::Menu* build_mode_menu();
void build_automation_action_menu (bool);

View file

@ -254,7 +254,7 @@ AutomationLine::modify_point_y (ControlPoint& cp, double y)
}
alist->freeze ();
sync_model_with_view_point (cp, false, 0);
sync_model_with_view_point (cp, 0);
alist->thaw ();
update_pending = false;
@ -277,255 +277,15 @@ AutomationLine::reset_line_coords (ControlPoint& cp)
}
void
AutomationLine::sync_model_with_view_points (list<ControlPoint*> cp, bool did_push, int64_t distance)
AutomationLine::sync_model_with_view_points (list<ControlPoint*> cp, int64_t distance)
{
update_pending = true;
for (list<ControlPoint*>::iterator i = cp.begin(); i != cp.end(); ++i) {
sync_model_with_view_point (**i, did_push, distance);
sync_model_with_view_point (**i, distance);
}
}
void
AutomationLine::model_representation (ControlPoint& cp, ModelRepresentation& mr)
{
/* part one: find out where the visual control point is.
initial results are in canvas units. ask the
line to convert them to something relevant.
*/
mr.xval = cp.get_x();
mr.yval = 1.0 - (cp.get_y() / _height);
/* if xval has not changed, set it directly from the model to avoid rounding errors */
if (mr.xval == trackview.editor().frame_to_unit(_time_converter->to((*cp.model())->when)) - _offset) {
mr.xval = (*cp.model())->when - _offset;
} else {
mr.xval = trackview.editor().unit_to_frame (mr.xval);
mr.xval = _time_converter->from (mr.xval + _offset);
}
/* convert y to model units; the x was already done above
*/
view_to_model_coord_y (mr.yval);
/* part 2: find out where the model point is now
*/
mr.xpos = (*cp.model())->when - _offset;
mr.ypos = (*cp.model())->value;
/* part 3: get the position of the visual control
points before and after us.
*/
ControlPoint* before;
ControlPoint* after;
if (cp.view_index()) {
before = nth (cp.view_index() - 1);
} else {
before = 0;
}
after = nth (cp.view_index() + 1);
if (before) {
mr.xmin = (*before->model())->when;
mr.ymin = (*before->model())->value;
mr.start = before->model();
++mr.start;
} else {
mr.xmin = mr.xpos;
mr.ymin = mr.ypos;
mr.start = cp.model();
}
if (after) {
mr.end = after->model();
} else {
mr.xmax = mr.xpos;
mr.ymax = mr.ypos;
mr.end = cp.model();
++mr.end;
}
}
/** @param points AutomationLine points to consider. These will correspond 1-to-1 to
* points in the AutomationList, but will have been transformed so that they are in pixels;
* the x coordinate being the pixel distance from the start of the line (0, or the start
* of the AutomationRegionView if we are in one).
*
* @param skipped Number of points in the AutomationList that were skipped before
* `points' starts.
*/
void
AutomationLine::determine_visible_control_points (ALPoints& points, int skipped)
{
uint32_t view_index, pi, n;
uint32_t npoints;
uint32_t this_rx = 0;
uint32_t prev_rx = 0;
uint32_t this_ry = 0;
uint32_t prev_ry = 0;
double* slope;
uint32_t box_size;
/* hide all existing points, and the line */
for (vector<ControlPoint*>::iterator i = control_points.begin(); i != control_points.end(); ++i) {
(*i)->hide();
}
line->hide ();
if (points.empty()) {
return;
}
npoints = points.size();
/* compute derivative/slope for the entire line */
slope = new double[npoints];
for (n = 0; n < npoints - 1; ++n) {
double xdelta = points[n+1].x - points[n].x;
double ydelta = points[n+1].y - points[n].y;
slope[n] = ydelta/xdelta;
}
box_size = (uint32_t) control_point_box_size ();
/* read all points and decide which ones to show as control points */
view_index = 0;
/* skip over unused AutomationList points before we start */
AutomationList::iterator model = alist->begin ();
for (int i = 0; i < skipped; ++i) {
++model;
}
for (pi = 0; pi < npoints; ++model, ++pi) {
/* If this line is in an AutomationRegionView, this is an offset from the region position, in pixels */
double tx = points[pi].x;
double ty = points[pi].y;
if (find (_always_in_view.begin(), _always_in_view.end(), (*model)->when) != _always_in_view.end()) {
add_visible_control_point (view_index, pi, tx, ty, model, npoints);
prev_rx = this_rx;
prev_ry = this_ry;
++view_index;
continue;
}
if (isnan (tx) || isnan (ty)) {
warning << string_compose (_("Ignoring illegal points on AutomationLine \"%1\""),
_name) << endmsg;
continue;
}
/* now ensure that the control_points vector reflects the current curve
state, but don't plot control points too close together. also, don't
plot a series of points all with the same value.
always plot the first and last points, of course.
*/
if (invalid_point (points, pi)) {
/* for some reason, we are supposed to ignore this point,
but still keep track of the model index.
*/
continue;
}
if (pi > 0 && pi < npoints - 1) {
if (slope[pi] == slope[pi-1]) {
/* no reason to display this point */
continue;
}
}
/* need to round here. the ultimate coordinates are integer
pixels, so tiny deltas in the coords will be eliminated
and we end up with "colinear" line segments. since the
line rendering code in libart doesn't like this very
much, we eliminate them here. don't do this for the first and last
points.
*/
this_rx = (uint32_t) rint (tx);
this_ry = (uint32_t) rint (ty);
if (view_index && pi != npoints && /* not the first, not the last */
(((this_rx == prev_rx) && (this_ry == prev_ry)) || /* same point */
(((this_rx - prev_rx) < (box_size + 2)) && /* not identical, but still too close horizontally */
(abs ((int)(this_ry - prev_ry)) < (int) (box_size + 2))))) { /* too close vertically */
continue;
}
/* ok, we should display this point */
add_visible_control_point (view_index, pi, tx, ty, model, npoints);
prev_rx = this_rx;
prev_ry = this_ry;
view_index++;
}
/* discard extra CP's to avoid confusing ourselves */
while (control_points.size() > view_index) {
ControlPoint* cp = control_points.back();
control_points.pop_back ();
delete cp;
}
if (!terminal_points_can_slide) {
control_points.back()->set_can_slide(false);
}
delete [] slope;
if (view_index > 1) {
npoints = view_index;
/* reset the line coordinates */
while (line_points.size() < npoints) {
line_points.push_back (Art::Point (0,0));
}
while (line_points.size() > npoints) {
line_points.pop_back ();
}
for (view_index = 0; view_index < npoints; ++view_index) {
line_points[view_index].set_x (control_points[view_index]->get_x());
line_points[view_index].set_y (control_points[view_index]->get_y());
}
line->property_points() = line_points;
if (_visible && alist->interpolation() != AutomationList::Discrete) {
line->show();
}
}
set_selected_points (trackview.editor().get_selection().points);
}
string
AutomationLine::get_verbose_cursor_string (double fraction) const
{
@ -589,19 +349,6 @@ AutomationLine::string_to_fraction (string const & s) const
return v;
}
bool
AutomationLine::invalid_point (ALPoints& p, uint32_t index)
{
return p[index].x == max_framepos && p[index].y == DBL_MAX;
}
void
AutomationLine::invalidate_point (ALPoints& p, uint32_t index)
{
p[index].x = max_framepos;
p[index].y = DBL_MAX;
}
/** Start dragging a single point, possibly adding others if the supplied point is selected and there
* are other selected points.
*
@ -705,7 +452,7 @@ AutomationLine::start_drag_common (double x, float fraction)
}
/** Should be called to indicate motion during a drag.
* @param x New x position of the drag in units, or undefined if ignore_x == true.
* @param x New x position of the drag in canvas units, or undefined if ignore_x == true.
* @param fraction New y fraction.
* @return x position and y fraction that were actually used (once clamped).
*/
@ -823,7 +570,7 @@ AutomationLine::end_drag ()
points.sort (ControlPointSorter ());
}
sync_model_with_view_points (points, did_push, rint (_drag_distance * trackview.editor().get_current_zoom ()));
sync_model_with_view_points (points, trackview.editor().unit_to_frame (_drag_distance));
alist->thaw ();
@ -834,72 +581,38 @@ AutomationLine::end_drag ()
);
trackview.editor().session()->set_dirty ();
did_push = false;
}
void
AutomationLine::sync_model_with_view_point (ControlPoint& cp, bool did_push, int64_t distance)
AutomationLine::sync_model_with_view_point (ControlPoint& cp, framecnt_t distance)
{
ModelRepresentation mr;
double ydelta;
model_representation (cp, mr);
/* how much are we changing the central point by */
ydelta = mr.yval - mr.ypos;
/*
apply the full change to the central point, and interpolate
on both axes to cover all model points represented
by the control point.
/* find out where the visual control point is.
initial results are in canvas units. ask the
line to convert them to something relevant.
*/
/* change all points before the primary point */
double view_x = cp.get_x();
double view_y = 1.0 - (cp.get_y() / _height);
for (AutomationList::iterator i = mr.start; i != cp.model(); ++i) {
/* if xval has not changed, set it directly from the model to avoid rounding errors */
double fract = ((*i)->when - mr.xmin) / (mr.xpos - mr.xmin);
double y_delta = ydelta * fract;
double x_delta = distance * fract;
/* interpolate */
if (y_delta || x_delta) {
alist->modify (i, (*i)->when + x_delta, mr.ymin + y_delta);
}
if (view_x == trackview.editor().frame_to_unit (_time_converter->to ((*cp.model())->when)) - _offset) {
view_x = (*cp.model())->when - _offset;
} else {
view_x = trackview.editor().unit_to_frame (view_x);
view_x = _time_converter->from (view_x + _offset);
}
/* change the primary point */
update_pending = true;
alist->modify (cp.model(), mr.xval, mr.yval);
/* change later points */
view_to_model_coord_y (view_y);
AutomationList::iterator i = cp.model();
++i;
while (i != mr.end) {
double delta = ydelta * (mr.xmax - (*i)->when) / (mr.xmax - mr.xpos);
/* all later points move by the same distance along the x-axis as the main point */
if (delta) {
alist->modify (i, (*i)->when + distance, (*i)->value + delta);
}
++i;
}
alist->modify (cp.model(), view_x, view_y);
if (did_push) {
/* move all points after the range represented by the view by the same distance
as the main point moved.
*/
alist->slide (mr.end, distance);
/* move all points after cp by the same distance */
alist->slide (cp.model()++, _time_converter->from (distance));
}
}
@ -934,13 +647,16 @@ AutomationLine::control_points_adjacent (double xval, uint32_t & before, uint32_
bool
AutomationLine::is_last_point (ControlPoint& cp)
{
ModelRepresentation mr;
model_representation (cp, mr);
// If the list is not empty, and the point is the last point in the list
if (!alist->empty() && mr.end == alist->end()) {
if (alist->empty()) {
return false;
}
AutomationList::const_iterator i = alist->end();
--i;
if (cp.model() == i) {
return true;
}
@ -950,13 +666,9 @@ AutomationLine::is_last_point (ControlPoint& cp)
bool
AutomationLine::is_first_point (ControlPoint& cp)
{
ModelRepresentation mr;
model_representation (cp, mr);
// If the list is not empty, and the point is the first point in the list
if (!alist->empty() && mr.start == alist->begin()) {
if (!alist->empty() && cp.model() == alist->begin()) {
return true;
}
@ -967,14 +679,10 @@ AutomationLine::is_first_point (ControlPoint& cp)
void
AutomationLine::remove_point (ControlPoint& cp)
{
ModelRepresentation mr;
model_representation (cp, mr);
trackview.editor().session()->begin_reversible_command (_("remove control point"));
XMLNode &before = alist->get_state();
alist->erase (mr.start, mr.end);
alist->erase (cp.model());
trackview.editor().session()->add_command(
new MementoCommand<AutomationList> (memento_command_binder (), &before, &alist->get_state())
@ -1021,38 +729,6 @@ AutomationLine::get_inverted_selectables (Selection&, list<Selectable*>& /*resul
// hmmm ....
}
/** Take a PointSelection and find ControlPoints that fall within it */
list<ControlPoint*>
AutomationLine::point_selection_to_control_points (PointSelection const & s)
{
list<ControlPoint*> cp;
for (PointSelection::const_iterator i = s.begin(); i != s.end(); ++i) {
if (i->track != &trackview) {
continue;
}
double const bot = (1 - i->high_fract) * trackview.current_height ();
double const top = (1 - i->low_fract) * trackview.current_height ();
for (vector<ControlPoint*>::iterator j = control_points.begin(); j != control_points.end(); ++j) {
double const rstart = trackview.editor().frame_to_unit (_time_converter->to (i->start) - _offset);
double const rend = trackview.editor().frame_to_unit (_time_converter->to (i->end) - _offset);
if ((*j)->get_x() >= rstart && (*j)->get_x() <= rend) {
if ((*j)->get_y() >= bot && (*j)->get_y() <= top) {
cp.push_back (*j);
}
}
}
}
return cp;
}
void
AutomationLine::set_selected_points (PointSelection const & points)
{
@ -1060,11 +736,8 @@ AutomationLine::set_selected_points (PointSelection const & points)
(*i)->set_selected (false);
}
if (!points.empty()) {
list<ControlPoint*> cp = point_selection_to_control_points (points);
for (list<ControlPoint*>::iterator i = cp.begin(); i != cp.end(); ++i) {
(*i)->set_selected (true);
}
for (PointSelection::const_iterator i = points.begin(); i != points.end(); ++i) {
(*i)->set_selected (true);
}
set_colors ();
@ -1087,10 +760,11 @@ AutomationLine::list_changed ()
void
AutomationLine::reset_callback (const Evoral::ControlList& events)
{
ALPoints tmp_points;
uint32_t npoints = events.size();
uint32_t vp = 0;
uint32_t pi = 0;
uint32_t np;
if (npoints == 0) {
if (events.empty()) {
for (vector<ControlPoint*>::iterator i = control_points.begin(); i != control_points.end(); ++i) {
delete *i;
}
@ -1099,26 +773,89 @@ AutomationLine::reset_callback (const Evoral::ControlList& events)
return;
}
AutomationList::const_iterator ai;
int skipped = 0;
/* hide all existing points, and the line */
for (ai = events.begin(); ai != events.end(); ++ai) {
for (vector<ControlPoint*>::iterator i = control_points.begin(); i != control_points.end(); ++i) {
(*i)->hide();
}
double translated_x = (*ai)->when;
double translated_y = (*ai)->value;
model_to_view_coord (translated_x, translated_y);
line->hide ();
np = events.size();
if (translated_x >= 0 && translated_x < _maximum_time) {
tmp_points.push_back (ALPoint (
trackview.editor().frame_to_unit (translated_x),
_height - (translated_y * _height))
);
} else if (translated_x < 0) {
++skipped;
Evoral::ControlList& e = const_cast<Evoral::ControlList&> (events);
for (AutomationList::iterator ai = e.begin(); ai != e.end(); ++ai, ++pi) {
double tx = (*ai)->when;
double ty = (*ai)->value;
/* convert from model coordinates to canonical view coordinates */
model_to_view_coord (tx, ty);
if (std::isnan (tx) || std::isnan (ty)) {
warning << string_compose (_("Ignoring illegal points on AutomationLine \"%1\""),
_name) << endmsg;
continue;
}
if (tx >= max_framepos || tx < 0 || tx >= _maximum_time) {
continue;
}
/* convert x-coordinate to a canvas unit coordinate (this takes
* zoom and scroll into account).
*/
tx = trackview.editor().frame_to_unit (tx);
/* convert from canonical view height (0..1.0) to actual
* height coordinates (using X11's top-left rooted system)
*/
ty = _height - (ty * _height);
add_visible_control_point (vp, pi, tx, ty, ai, np);
vp++;
}
/* discard extra CP's to avoid confusing ourselves */
while (control_points.size() > vp) {
ControlPoint* cp = control_points.back();
control_points.pop_back ();
delete cp;
}
if (!terminal_points_can_slide) {
control_points.back()->set_can_slide(false);
}
if (vp > 1) {
/* reset the line coordinates given to the CanvasLine */
while (line_points.size() < vp) {
line_points.push_back (Art::Point (0,0));
}
while (line_points.size() > vp) {
line_points.pop_back ();
}
for (uint32_t n = 0; n < vp; ++n) {
line_points[n].set_x (control_points[n]->get_x());
line_points[n].set_y (control_points[n]->get_y());
}
line->property_points() = line_points;
if (_visible && alist->interpolation() != AutomationList::Discrete) {
line->show();
}
}
determine_visible_control_points (tmp_points, skipped);
set_selected_points (trackview.editor().get_selection().points);
}
void
@ -1284,8 +1021,11 @@ AutomationLine::interpolation_changed (AutomationList::InterpolationStyle style)
}
void
AutomationLine::add_visible_control_point (uint32_t view_index, uint32_t pi, double tx, double ty, AutomationList::iterator model, uint32_t npoints)
AutomationLine::add_visible_control_point (uint32_t view_index, uint32_t pi, double tx, double ty,
AutomationList::iterator model, uint32_t npoints)
{
ControlPoint::ShapeType shape;
if (view_index >= control_points.size()) {
/* make sure we have enough control points */
@ -1296,25 +1036,23 @@ AutomationLine::add_visible_control_point (uint32_t view_index, uint32_t pi, dou
control_points.push_back (ncp);
}
ControlPoint::ShapeType shape;
if (!terminal_points_can_slide) {
if (pi == 0) {
control_points[view_index]->set_can_slide(false);
control_points[view_index]->set_can_slide (false);
if (tx == 0) {
shape = ControlPoint::Start;
} else {
shape = ControlPoint::Full;
}
} else if (pi == npoints - 1) {
control_points[view_index]->set_can_slide(false);
control_points[view_index]->set_can_slide (false);
shape = ControlPoint::End;
} else {
control_points[view_index]->set_can_slide(true);
control_points[view_index]->set_can_slide (true);
shape = ControlPoint::Full;
}
} else {
control_points[view_index]->set_can_slide(true);
control_points[view_index]->set_can_slide (true);
shape = ControlPoint::Full;
}
@ -1332,20 +1070,6 @@ AutomationLine::add_visible_control_point (uint32_t view_index, uint32_t pi, dou
}
}
void
AutomationLine::add_always_in_view (double x)
{
_always_in_view.push_back (x);
alist->apply_to_points (*this, &AutomationLine::reset_callback);
}
void
AutomationLine::clear_always_in_view ()
{
_always_in_view.clear ();
alist->apply_to_points (*this, &AutomationLine::reset_callback);
}
void
AutomationLine::connect_to_list ()
{
@ -1386,13 +1110,19 @@ AutomationLine::get_point_x_range () const
pair<framepos_t, framepos_t> r (max_framepos, 0);
for (AutomationList::const_iterator i = the_list()->begin(); i != the_list()->end(); ++i) {
r.first = min (r.first, _time_converter->to ((*i)->when) + _offset + _time_converter->origin_b ());
r.second = max (r.second, _time_converter->to ((*i)->when) + _offset + _time_converter->origin_b ());
r.first = min (r.first, session_position (i));
r.second = max (r.second, session_position (i));
}
return r;
}
framepos_t
AutomationLine::session_position (AutomationList::const_iterator p) const
{
return _time_converter->to ((*p)->when) + _offset + _time_converter->origin_b ();
}
void
AutomationLine::set_offset (framepos_t off)
{

View file

@ -66,7 +66,6 @@ class AutomationLine : public sigc::trackable, public PBD::StatefulDestructible
void reset ();
void clear ();
std::list<ControlPoint*> point_selection_to_control_points (PointSelection const &);
void set_selected_points (PointSelection const &);
void get_selectables (ARDOUR::framepos_t, ARDOUR::framepos_t, double, double, std::list<Selectable*>&);
void get_inverted_selectables (Selection&, std::list<Selectable*>& results);
@ -129,9 +128,6 @@ class AutomationLine : public sigc::trackable, public PBD::StatefulDestructible
void modify_point_y (ControlPoint&, double);
void add_always_in_view (double);
void clear_always_in_view ();
virtual MementoCommandBinder<ARDOUR::AutomationList>* memento_command_binder ();
const Evoral::TimeConverter<double, ARDOUR::framepos_t>& time_converter () const {
@ -148,6 +144,8 @@ class AutomationLine : public sigc::trackable, public PBD::StatefulDestructible
void set_offset (ARDOUR::framecnt_t);
void set_width (ARDOUR::framecnt_t);
framepos_t session_position (ARDOUR::AutomationList::const_iterator) const;
protected:
std::string _name;
@ -156,7 +154,7 @@ class AutomationLine : public sigc::trackable, public PBD::StatefulDestructible
boost::shared_ptr<ARDOUR::AutomationList> alist;
Evoral::TimeConverter<double, ARDOUR::framepos_t>* _time_converter;
/** true if _time_converter belongs to us (ie we should delete it) */
/** true if _time_converter belongs to us (ie we should delete it on destruction) */
bool _our_time_converter;
bool _visible : 1;
@ -174,20 +172,8 @@ class AutomationLine : public sigc::trackable, public PBD::StatefulDestructible
ArdourCanvas::Points line_points; /* coordinates for canvas line */
std::vector<ControlPoint*> control_points; /* visible control points */
struct ALPoint {
double x;
double y;
ALPoint (double xx, double yy) : x(xx), y(yy) {}
};
typedef std::vector<ALPoint> ALPoints;
static void invalidate_point (ALPoints&, uint32_t index);
static bool invalid_point (ALPoints&, uint32_t index);
void determine_visible_control_points (ALPoints &, int);
void sync_model_with_view_point (ControlPoint&, bool, int64_t);
void sync_model_with_view_points (std::list<ControlPoint*>, bool, int64_t);
void sync_model_with_view_point (ControlPoint&, ARDOUR::framecnt_t);
void sync_model_with_view_points (std::list<ControlPoint*>, ARDOUR::framecnt_t);
void start_drag_common (double, float);
virtual void change_model (ARDOUR::AutomationList::iterator, double x, double y);
@ -202,9 +188,8 @@ class AutomationLine : public sigc::trackable, public PBD::StatefulDestructible
std::list<ControlPoint*> _push_points; ///< additional points we are dragging if "push" is enabled
bool _drag_had_movement; ///< true if the drag has seen movement, otherwise false
double _drag_x; ///< last x position of the drag, in units
double _drag_distance; ///< total x movement of the drag, in units
double _drag_distance; ///< total x movement of the drag, in canvas units
double _last_drag_fraction; ///< last y position of the drag, as a fraction
std::list<double> _always_in_view;
/** offset from the start of the automation list to the start of the line, so that
* a +ve offset means that the 0 on the line is at _offset in the list
*/
@ -216,21 +201,6 @@ class AutomationLine : public sigc::trackable, public PBD::StatefulDestructible
void connect_to_list ();
void interpolation_changed (ARDOUR::AutomationList::InterpolationStyle);
struct ModelRepresentation {
ARDOUR::AutomationList::iterator start;
ARDOUR::AutomationList::iterator end;
double xpos;
double ypos;
double xmin;
double ymin;
double xmax;
double ymax;
double xval;
double yval;
};
void model_representation (ControlPoint&, ModelRepresentation&);
PBD::ScopedConnectionList _list_connections;
/** maximum time that a point on this line can be at, relative to the position of its region or start of its track */

View file

@ -1,51 +0,0 @@
/*
Copyright (C) 2000-2007 Paul Davis
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef __ardour_gtk_automation_range_h__
#define __ardour_gtk_automation_range_h__
class TimeAxisView;
/** A rectangular range of an automation line, used to express a selected area.
*
* x coordinates start/end are in AutomationList model coordinates.
* y coordinates are a expressed as a fraction of the AutomationTimeAxisView's height, where 0 is the
* bottom of the track, and 1 is the top.
*
* This representation falls between the visible GUI control points and
* the back-end "actual" automation points, some of which may not be
* visible; it is not trivial to convert from one of these to the
* other, so the AutomationSelectable is a kind of "best and worst of
* both worlds".
*
* It offers a zoom-independent representation of a selected area of automation.
*/
struct AutomationRange
{
double start;
double end;
double low_fract;
double high_fract;
TimeAxisView* track; // ref would be better, but ARDOUR::SessionHandlePtr is non-assignable
AutomationRange (double s, double e, double l, double h, TimeAxisView* atv)
: start (s), end (e), low_fract (l), high_fract (h), track (atv) {}
};
#endif /* __ardour_gtk_automation_range_h__ */

View file

@ -44,6 +44,7 @@
#include "rgb_macros.h"
#include "point_selection.h"
#include "canvas_impl.h"
#include "control_point.h"
#include "utils.h"
#include "i18n.h"
@ -226,7 +227,7 @@ AutomationTimeAxisView::AutomationTimeAxisView (
ColorsChanged.connect (sigc::mem_fun (*this, &AutomationTimeAxisView::color_handler));
_route->DropReferences.connect (
_route_connections, invalidator (*this), ui_bind (&AutomationTimeAxisView::route_going_away, this), gui_context ()
_route_connections, invalidator (*this), boost::bind (&AutomationTimeAxisView::route_going_away, this), gui_context ()
);
}
@ -592,172 +593,6 @@ AutomationTimeAxisView::add_automation_event (GdkEvent* event, framepos_t when,
_session->set_dirty ();
}
void
AutomationTimeAxisView::cut_copy_clear (Selection& selection, CutCopyOp op)
{
list<boost::shared_ptr<AutomationLine> > lines;
if (_line) {
lines.push_back (_line);
} else if (_view) {
lines = _view->get_lines ();
}
for (list<boost::shared_ptr<AutomationLine> >::iterator i = lines.begin(); i != lines.end(); ++i) {
cut_copy_clear_one (**i, selection, op);
}
}
void
AutomationTimeAxisView::cut_copy_clear_one (AutomationLine& line, Selection& selection, CutCopyOp op)
{
boost::shared_ptr<Evoral::ControlList> what_we_got;
boost::shared_ptr<AutomationList> alist (line.the_list());
XMLNode &before = alist->get_state();
/* convert time selection to automation list model coordinates */
const Evoral::TimeConverter<double, ARDOUR::framepos_t>& tc = line.time_converter ();
double const start = tc.from (selection.time.front().start - tc.origin_b ());
double const end = tc.from (selection.time.front().end - tc.origin_b ());
switch (op) {
case Delete:
if (alist->cut (start, end) != 0) {
_session->add_command(new MementoCommand<AutomationList>(*alist.get(), &before, &alist->get_state()));
}
break;
case Cut:
if ((what_we_got = alist->cut (start, end)) != 0) {
_editor.get_cut_buffer().add (what_we_got);
_session->add_command(new MementoCommand<AutomationList>(*alist.get(), &before, &alist->get_state()));
}
break;
case Copy:
if ((what_we_got = alist->copy (start, end)) != 0) {
_editor.get_cut_buffer().add (what_we_got);
}
break;
case Clear:
if ((what_we_got = alist->cut (start, end)) != 0) {
_session->add_command(new MementoCommand<AutomationList>(*alist.get(), &before, &alist->get_state()));
}
break;
}
if (what_we_got) {
for (AutomationList::iterator x = what_we_got->begin(); x != what_we_got->end(); ++x) {
double when = (*x)->when;
double val = (*x)->value;
line.model_to_view_coord (when, val);
(*x)->when = when;
(*x)->value = val;
}
}
}
void
AutomationTimeAxisView::reset_objects (PointSelection& selection)
{
list<boost::shared_ptr<AutomationLine> > lines;
if (_line) {
lines.push_back (_line);
} else if (_view) {
lines = _view->get_lines ();
}
for (list<boost::shared_ptr<AutomationLine> >::iterator i = lines.begin(); i != lines.end(); ++i) {
reset_objects_one (**i, selection);
}
}
void
AutomationTimeAxisView::reset_objects_one (AutomationLine& line, PointSelection& selection)
{
boost::shared_ptr<AutomationList> alist(line.the_list());
_session->add_command (new MementoCommand<AutomationList>(*alist.get(), &alist->get_state(), 0));
for (PointSelection::iterator i = selection.begin(); i != selection.end(); ++i) {
if ((*i).track != this) {
continue;
}
alist->reset_range ((*i).start, (*i).end);
}
}
void
AutomationTimeAxisView::cut_copy_clear_objects (PointSelection& selection, CutCopyOp op)
{
list<boost::shared_ptr<AutomationLine> > lines;
if (_line) {
lines.push_back (_line);
} else if (_view) {
lines = _view->get_lines ();
}
for (list<boost::shared_ptr<AutomationLine> >::iterator i = lines.begin(); i != lines.end(); ++i) {
cut_copy_clear_objects_one (**i, selection, op);
}
}
void
AutomationTimeAxisView::cut_copy_clear_objects_one (AutomationLine& line, PointSelection& selection, CutCopyOp op)
{
boost::shared_ptr<Evoral::ControlList> what_we_got;
boost::shared_ptr<AutomationList> alist(line.the_list());
XMLNode &before = alist->get_state();
for (PointSelection::iterator i = selection.begin(); i != selection.end(); ++i) {
if ((*i).track != this) {
continue;
}
switch (op) {
case Delete:
if (alist->cut ((*i).start, (*i).end) != 0) {
_session->add_command (new MementoCommand<AutomationList>(*alist.get(), new XMLNode (before), &alist->get_state()));
}
break;
case Cut:
if ((what_we_got = alist->cut ((*i).start, (*i).end)) != 0) {
_editor.get_cut_buffer().add (what_we_got);
_session->add_command (new MementoCommand<AutomationList>(*alist.get(), new XMLNode (before), &alist->get_state()));
}
break;
case Copy:
if ((what_we_got = alist->copy ((*i).start, (*i).end)) != 0) {
_editor.get_cut_buffer().add (what_we_got);
}
break;
case Clear:
if ((what_we_got = alist->cut ((*i).start, (*i).end)) != 0) {
_session->add_command (new MementoCommand<AutomationList>(*alist.get(), new XMLNode (before), &alist->get_state()));
}
break;
}
}
delete &before;
if (what_we_got) {
for (AutomationList::iterator x = what_we_got->begin(); x != what_we_got->end(); ++x) {
double when = (*x)->when;
double val = (*x)->value;
line.model_to_view_coord (when, val);
(*x)->when = when;
(*x)->value = val;
}
}
}
/** Paste a selection.
* @param pos Position to paste to (session frames).
* @param times Number of times to paste.
@ -794,25 +629,10 @@ AutomationTimeAxisView::paste_one (AutomationLine& line, framepos_t pos, float t
return false;
}
/* Make a copy of the list because we have to scale the
values from view coordinates to model coordinates, and we're
not supposed to modify the points in the selection.
*/
AutomationList copy (**p);
for (AutomationList::iterator x = copy.begin(); x != copy.end(); ++x) {
double when = (*x)->when;
double val = (*x)->value;
line.view_to_model_coord (when, val);
(*x)->when = when;
(*x)->value = val;
}
double const model_pos = line.time_converter().from (pos - line.time_converter().origin_b ());
XMLNode &before = alist->get_state();
alist->paste (copy, model_pos, times);
alist->paste (**p, model_pos, times);
_session->add_command (new MementoCommand<AutomationList>(*alist.get(), &before, &alist->get_state()));
return true;

View file

@ -91,10 +91,7 @@ class AutomationTimeAxisView : public TimeAxisView {
/* editing operations */
void cut_copy_clear (Selection&, Editing::CutCopyOp);
void cut_copy_clear_objects (PointSelection&, Editing::CutCopyOp);
bool paste (ARDOUR::framepos_t, float times, Selection&, size_t nth);
void reset_objects (PointSelection&);
int set_state (const XMLNode&, int version);
@ -169,10 +166,7 @@ class AutomationTimeAxisView : public TimeAxisView {
void build_display_menu ();
void cut_copy_clear_one (AutomationLine&, Selection&, Editing::CutCopyOp);
void cut_copy_clear_objects_one (AutomationLine&, PointSelection&, Editing::CutCopyOp);
bool paste_one (AutomationLine&, ARDOUR::framepos_t, float times, Selection&, size_t nth);
void reset_objects_one (AutomationLine&, PointSelection&);
void route_going_away ();
void set_automation_state (ARDOUR::AutoState);

View file

@ -26,6 +26,7 @@
#include <list>
#include "pbd/error.h"
#include "pbd/convert.h"
#include <gtkmm2ext/utils.h>
#include <gtkmm2ext/selector.h>
@ -74,14 +75,14 @@ bool
AxisView::marked_for_display () const
{
string const v = gui_property ("visible");
return (v == "" || string_is_affirmative (v));
return (v == "" || PBD::string_is_affirmative (v));
}
bool
AxisView::set_marked_for_display (bool yn)
{
string const v = gui_property ("visible");
if (v == "" || yn != string_is_affirmative (v)) {
if (v == "" || yn != PBD::string_is_affirmative (v)) {
set_gui_property ("visible", yn);
return true; // things changed
}

View file

@ -377,7 +377,7 @@ BundleManager::add_bundle (boost::shared_ptr<Bundle> b)
(*i)[_list_model_columns.name] = u->name ();
(*i)[_list_model_columns.bundle] = u;
u->Changed.connect (bundle_connections, invalidator (*this), ui_bind (&BundleManager::bundle_changed, this, _1, u), gui_context());
u->Changed.connect (bundle_connections, invalidator (*this), boost::bind (&BundleManager::bundle_changed, this, _1, u), gui_context());
}
void

View file

@ -13,21 +13,38 @@
using namespace Gtk;
ButtonJoiner::ButtonJoiner (const std::string& str, Gtk::Widget& lw, Gtk::Widget& rw)
ButtonJoiner::ButtonJoiner (const std::string& str, Gtk::Widget& lw, Gtk::Widget& rw, bool central_joiner)
: left (lw)
, right (rw)
, name (str)
, active_fill_pattern (0)
, inactive_fill_pattern (0)
, central_link (central_joiner)
{
packer.set_homogeneous (true);
if (central_link) {
packer.set_spacing (20);
}
packer.pack_start (left);
packer.pack_start (right);
packer.show ();
/* this alignment is how we position the box that holds the two widgets
within our allocation, and how we request more space around them.
*/
align.add (packer);
align.set (0.5, 1.0);
align.set_padding (9, 0, 9, 9);
if (!central_link) {
align.set (0.5, 1.0);
align.set_padding (9, 0, 9, 9);
} else {
align.set (0.5, 0.5);
align.set_padding (1, 1, 1, 1);
}
align.show ();
add (align);
@ -73,22 +90,44 @@ ButtonJoiner::render (cairo_t* cr)
cairo_set_source (cr, active_fill_pattern);
}
/* outer rect */
if (!central_link) {
/* outer rect */
Gtkmm2ext::rounded_top_rectangle (cr, 0, 0, get_width(), h, 12);
cairo_fill_preserve (cr);
Gtkmm2ext::rounded_top_rectangle (cr, 0, 0, get_width(), h, 8);
cairo_fill_preserve (cr);
/* outer edge */
/* outer edge */
cairo_set_line_width (cr, 1);
cairo_set_source_rgb (cr, border_r, border_g, border_b);
cairo_stroke (cr);
cairo_set_line_width (cr, 1.5);
cairo_set_source_rgb (cr, border_r, border_g, border_b);
cairo_stroke (cr);
/* inner "edge" */
/* inner "edge" */
Gtkmm2ext::rounded_top_rectangle (cr, 8, 8, get_width() - 16, h - 8, 10);
cairo_stroke (cr);
Gtkmm2ext::rounded_top_rectangle (cr, 8, 8, get_width() - 16, h - 8, 6);
cairo_stroke (cr);
} else {
if (get_active()) {
Gtkmm2ext::rounded_top_rectangle (cr, 0, 0, (get_width() - 20.0)/2.0 , h, 8);
cairo_fill_preserve (cr);
Gtkmm2ext::rounded_top_rectangle (cr, (get_width() - 20.)/2.0 + 20.0, 0.0,
(get_width() - 20.0)/2.0 , h, 8);
cairo_fill_preserve (cr);
cairo_move_to (cr, get_width()/2.0 - 10.0, h/2.0);
cairo_set_line_width (cr, 1.5);
cairo_rel_line_to (cr, 20.0, 0.0);
cairo_set_source (cr, active_fill_pattern);
cairo_stroke (cr);
} else {
cairo_arc (cr, get_width()/2.0, h/2.0, 6.0, 0, M_PI*2.0);
cairo_set_line_width (cr, 1.5);
cairo_fill_preserve (cr);
cairo_set_source_rgb (cr, border_r, border_g, border_b);
cairo_stroke (cr);
}
}
}
void

View file

@ -10,7 +10,7 @@
class ButtonJoiner : public CairoWidget, public Gtkmm2ext::Activatable {
public:
ButtonJoiner (const std::string&, Gtk::Widget&, Gtk::Widget&);
ButtonJoiner (const std::string&, Gtk::Widget&, Gtk::Widget&, bool central_link = false);
~ButtonJoiner ();
void set_related_action (Glib::RefPtr<Gtk::Action>);
@ -35,6 +35,7 @@ class ButtonJoiner : public CairoWidget, public Gtkmm2ext::Activatable {
std::string name;
cairo_pattern_t* active_fill_pattern;
cairo_pattern_t* inactive_fill_pattern;
bool central_link;
double border_r;
double border_g;
double border_b;

View file

@ -30,6 +30,8 @@ using namespace ARDOUR;
using namespace PBD;
using namespace Gnome; // for Canvas
PBD::Signal1<void, ControlPoint *> ControlPoint::CatchDeletion;
ControlPoint::ControlPoint (AutomationLine& al)
: _line (al)
{
@ -82,6 +84,8 @@ ControlPoint::ControlPoint (const ControlPoint& other, bool /*dummy_arg_to_force
ControlPoint::~ControlPoint ()
{
CatchDeletion (this); /* EMIT SIGNAL */
delete _item;
}

View file

@ -83,21 +83,21 @@ class ControlPoint : public Selectable
ARDOUR::AutomationList::iterator model() const { return _model; }
AutomationLine& line() const { return _line; }
static PBD::Signal1<void, ControlPoint *> CatchDeletion;
private:
ArdourCanvas::SimpleRect* _item;
AutomationLine& _line;
ArdourCanvas::SimpleRect* _item;
AutomationLine& _line;
ARDOUR::AutomationList::iterator _model;
uint32_t _view_index;
bool _can_slide;
uint32_t _view_index;
bool _can_slide;
double _x;
double _y;
double _size;
ShapeType _shape;
virtual bool event_handler (GdkEvent*);
double _x;
double _y;
double _size;
ShapeType _shape;
};

View file

@ -296,9 +296,9 @@ CrossfadeEditor::CrossfadeEditor (Session* s, boost::shared_ptr<Crossfade> xf, d
curve_select_clicked (In);
xfade->PropertyChanged.connect (state_connection, invalidator (*this), ui_bind (&CrossfadeEditor::xfade_changed, this, _1), gui_context());
xfade->PropertyChanged.connect (state_connection, invalidator (*this), boost::bind (&CrossfadeEditor::xfade_changed, this, _1), gui_context());
_session->AuditionActive.connect (_session_connections, invalidator (*this), ui_bind (&CrossfadeEditor::audition_state_changed, this, _1), gui_context());
_session->AuditionActive.connect (_session_connections, invalidator (*this), boost::bind (&CrossfadeEditor::audition_state_changed, this, _1), gui_context());
show_all_children();
}

View file

@ -1,302 +0,0 @@
/*
Copyright (C) 2003 Paul Davis
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 <algorithm>
#include "ardour/region.h"
#include <gtkmm2ext/doi.h>
#include "canvas-simplerect.h"
#include "canvas-curve.h"
#include "crossfade_view.h"
#include "global_signals.h"
#include "gui_thread.h"
#include "rgb_macros.h"
#include "audio_time_axis.h"
#include "public_editor.h"
#include "audio_region_view.h"
#include "utils.h"
#include "canvas_impl.h"
#include "ardour_ui.h"
using namespace ARDOUR;
using namespace PBD;
using namespace Editing;
using namespace Gnome;
using namespace Canvas;
PBD::Signal1<void,CrossfadeView*> CrossfadeView::CatchDeletion;
CrossfadeView::CrossfadeView (ArdourCanvas::Group *parent,
RouteTimeAxisView &tv,
boost::shared_ptr<Crossfade> xf,
double spu,
Gdk::Color& basic_color,
AudioRegionView& lview,
AudioRegionView& rview)
: TimeAxisViewItem ("xfade" /*xf.name()*/, *parent, tv, spu, basic_color, xf->position(),
xf->length(), false, false, TimeAxisViewItem::Visibility (TimeAxisViewItem::ShowFrame)),
crossfade (xf),
left_view (lview),
right_view (rview),
_all_in_view (false),
_child_height (0)
{
_valid = true;
_visible = true;
fade_in = new Line (*group);
fade_in->property_fill_color_rgba() = ARDOUR_UI::config()->canvasvar_CrossfadeLine.get();
fade_in->property_width_pixels() = 1;
fade_out = new Line (*group);
fade_out->property_fill_color_rgba() = ARDOUR_UI::config()->canvasvar_CrossfadeLine.get();
fade_out->property_width_pixels() = 1;
/* no frame around the xfade or overlap rects */
frame->property_outline_what() = 0;
/* never show the vestigial frame */
vestigial_frame->hide();
show_vestigial = false;
group->signal_event().connect (sigc::bind (sigc::mem_fun (tv.editor(), &PublicEditor::canvas_crossfade_view_event), group, this));
PropertyChange all_crossfade_properties;
all_crossfade_properties.add (ARDOUR::Properties::active);
all_crossfade_properties.add (ARDOUR::Properties::follow_overlap);
crossfade_changed (all_crossfade_properties);
crossfade->PropertyChanged.connect (*this, invalidator (*this), ui_bind (&CrossfadeView::crossfade_changed, this, _1), gui_context());
crossfade->FadesChanged.connect (*this, invalidator (*this), ui_bind (&CrossfadeView::crossfade_fades_changed, this), gui_context());
ColorsChanged.connect (sigc::mem_fun (*this, &CrossfadeView::color_handler));
}
CrossfadeView::~CrossfadeView ()
{
CatchDeletion (this) ; /* EMIT_SIGNAL */
}
void
CrossfadeView::reset_width_dependent_items (double pixel_width)
{
TimeAxisViewItem::reset_width_dependent_items (pixel_width);
active_changed ();
if (pixel_width < 5) {
fade_in->hide();
fade_out->hide();
}
}
void
CrossfadeView::set_heights (double fade_height, double child_height)
{
if (child_height > TimeAxisViewItem::NAME_HIGHLIGHT_THRESH) {
fade_height -= NAME_HIGHLIGHT_SIZE;
child_height -= NAME_HIGHLIGHT_SIZE;
}
TimeAxisViewItem::set_height (fade_height);
_child_height = child_height;
redraw_curves ();
}
void
CrossfadeView::crossfade_changed (const PropertyChange& what_changed)
{
bool need_redraw_curves = false;
if (what_changed.contains (ARDOUR::bounds_change)) {
set_position (crossfade->position(), this);
set_duration (crossfade->length(), this);
/* set_duration will call reset_width_dependent_items which in turn will call redraw_curves via active_changed,
so no need for us to call it */
need_redraw_curves = false;
}
if (what_changed.contains (ARDOUR::Properties::follow_overlap)) {
need_redraw_curves = true;
}
if (what_changed.contains (ARDOUR::Properties::active)) {
/* calls redraw_curves */
active_changed ();
} else if (need_redraw_curves) {
redraw_curves ();
}
}
/** Set up our fade_in and fade_out curves to contain points for the currently visible portion
* of the crossfade.
*/
void
CrossfadeView::redraw_curves ()
{
if (!crossfade->following_overlap()) {
/* curves should not be visible */
fade_in->hide ();
fade_out->hide ();
return;
}
if (_height < 0) {
/* no space allocated yet */
return;
}
PublicEditor& editor = get_time_axis_view().editor ();
framepos_t const editor_left = editor.leftmost_position ();
framepos_t const editor_right = editor_left + editor.current_page_frames ();
framepos_t const xfade_left = crossfade->position ();
framepos_t const xfade_right = xfade_left + crossfade->length ();
/* Work out the range of our frames that are visible */
framepos_t const min_frames = std::max (editor_left, xfade_left);
framepos_t const max_frames = std::min (editor_right, xfade_right);
_all_in_view = (editor_left <= xfade_left && editor_right >= xfade_right);
/* Hence the number of points that we will render */
int32_t const npoints = editor.frame_to_pixel (max_frames - min_frames);
if (!_visible || !crossfade->active() || npoints < 3) {
fade_in->hide();
fade_out->hide();
return;
} else {
fade_in->show();
fade_out->show();
}
Points* points = get_canvas_points ("xfade edit redraw", npoints);
float* vec = new float[npoints];
crossfade->fade_in().curve().get_vector (min_frames - crossfade->position(), max_frames - crossfade->position(), vec, npoints);
/* Work out the offset from the start of the crossfade to the visible part, in pixels */
double xoff = 0;
if (crossfade->position() < editor.leftmost_position()) {
xoff = editor.frame_to_pixel (min_frames) - editor.frame_to_pixel (crossfade->position ());
}
for (int i = 0, pci = 0; i < npoints; ++i) {
Art::Point &p = (*points)[pci++];
p.set_x (xoff + i + 1);
double const ho = crossfade->in()->layer() > crossfade->out()->layer() ? _child_height : _height;
p.set_y (ho - ((_child_height - 2) * vec[i]));
}
fade_in->property_points() = *points;
crossfade->fade_out().curve().get_vector (min_frames - crossfade->position(), max_frames - crossfade->position(), vec, npoints);
for (int i = 0, pci = 0; i < npoints; ++i) {
Art::Point &p = (*points)[pci++];
p.set_x (xoff + i + 1);
double const ho = crossfade->in()->layer() < crossfade->out()->layer() ? _child_height : _height;
p.set_y (ho - ((_child_height - 2) * vec[i]));
}
fade_out->property_points() = *points;
delete [] vec;
delete points;
/* XXX this is ugly, but it will have to wait till Crossfades are reimplented
as regions. This puts crossfade views on top of a track, above all regions.
*/
group->raise_to_top();
}
void
CrossfadeView::active_changed ()
{
if (crossfade->active()) {
frame->property_fill_color_rgba() = ARDOUR_UI::config()->canvasvar_ActiveCrossfade.get();
} else {
frame->property_fill_color_rgba() = ARDOUR_UI::config()->canvasvar_InactiveCrossfade.get();
}
redraw_curves ();
}
void
CrossfadeView::color_handler ()
{
active_changed ();
}
void
CrossfadeView::set_valid (bool yn)
{
_valid = yn;
}
void
CrossfadeView::show ()
{
_visible = true;
group->show();
redraw_curves ();
}
void
CrossfadeView::hide ()
{
group->hide();
_visible = false;
}
void
CrossfadeView::fake_hide ()
{
group->hide();
}
void
CrossfadeView::crossfade_fades_changed ()
{
redraw_curves ();
}
void
CrossfadeView::horizontal_position_changed ()
{
/* If the crossfade curves are entirely within the editor's visible space, there is
no need to redraw them here as they will be completely drawn (as distinct from
the other case where the horizontal position change will uncover `undrawn'
sections).
*/
if (!_all_in_view) {
redraw_curves ();
}
}

View file

@ -90,7 +90,6 @@
#include "canvas-noevent-text.h"
#include "canvas_impl.h"
#include "crossfade_edit.h"
#include "crossfade_view.h"
#include "debug.h"
#include "editing.h"
#include "editor.h"
@ -303,7 +302,6 @@ Editor::Editor ()
clicked_regionview = 0;
clicked_axisview = 0;
clicked_routeview = 0;
clicked_crossfadeview = 0;
clicked_control_point = 0;
last_update_frame = 0;
pre_press_cursor = 0;
@ -340,7 +338,6 @@ Editor::Editor ()
have_pending_keyboard_selection = false;
_follow_playhead = true;
_stationary_playhead = false;
_xfade_visibility = true;
editor_ruler_menu = 0;
no_ruler_shown_update = false;
marker_menu = 0;
@ -659,7 +656,7 @@ Editor::Editor ()
_playlist_selector = new PlaylistSelector();
_playlist_selector->signal_delete_event().connect (sigc::bind (sigc::ptr_fun (just_hide_it), static_cast<Window *> (_playlist_selector)));
RegionView::RegionViewGoingAway.connect (*this, invalidator (*this), ui_bind (&Editor::catch_vanishing_regionview, this, _1), gui_context());
RegionView::RegionViewGoingAway.connect (*this, invalidator (*this), boost::bind (&Editor::catch_vanishing_regionview, this, _1), gui_context());
/* nudge stuff */
@ -709,17 +706,32 @@ Editor::Editor ()
ControlProtocol::ZoomToSession.connect (*this, invalidator (*this), boost::bind (&Editor::temporal_zoom_session, this), gui_context());
ControlProtocol::ZoomIn.connect (*this, invalidator (*this), boost::bind (&Editor::temporal_zoom_step, this, false), gui_context());
ControlProtocol::ZoomOut.connect (*this, invalidator (*this), boost::bind (&Editor::temporal_zoom_step, this, true), gui_context());
ControlProtocol::ScrollTimeline.connect (*this, invalidator (*this), ui_bind (&Editor::control_scroll, this, _1), gui_context());
ControlProtocol::SelectByRID.connect (*this, invalidator (*this), ui_bind (&Editor::control_select, this, _1), gui_context());
BasicUI::AccessAction.connect (*this, invalidator (*this), ui_bind (&Editor::access_action, this, _1, _2), gui_context());
ControlProtocol::Undo.connect (*this, invalidator (*this), boost::bind (&Editor::undo, this, true), gui_context());
ControlProtocol::Redo.connect (*this, invalidator (*this), boost::bind (&Editor::redo, this, true), gui_context());
ControlProtocol::ScrollTimeline.connect (*this, invalidator (*this), boost::bind (&Editor::control_scroll, this, _1), gui_context());
ControlProtocol::StepTracksUp.connect (*this, invalidator (*this), boost::bind (&Editor::control_step_tracks_up, this), gui_context());
ControlProtocol::StepTracksDown.connect (*this, invalidator (*this), boost::bind (&Editor::control_step_tracks_down, this), gui_context());
ControlProtocol::GotoView.connect (*this, invalidator (*this), boost::bind (&Editor::control_view, this, _1), gui_context());
ControlProtocol::CloseDialog.connect (*this, invalidator (*this), Keyboard::close_current_dialog, gui_context());
ControlProtocol::VerticalZoomInAll.connect (*this, invalidator (*this), boost::bind (&Editor::control_vertical_zoom_in_all, this), gui_context());
ControlProtocol::VerticalZoomOutAll.connect (*this, invalidator (*this), boost::bind (&Editor::control_vertical_zoom_out_all, this), gui_context());
ControlProtocol::VerticalZoomInSelected.connect (*this, invalidator (*this), boost::bind (&Editor::control_vertical_zoom_in_selected, this), gui_context());
ControlProtocol::VerticalZoomOutSelected.connect (*this, invalidator (*this), boost::bind (&Editor::control_vertical_zoom_out_selected, this), gui_context());
ControlProtocol::AddRouteToSelection.connect (*this, invalidator (*this), boost::bind (&Editor::control_select, this, _1, Selection::Add), gui_context());
ControlProtocol::RemoveRouteFromSelection.connect (*this, invalidator (*this), boost::bind (&Editor::control_select, this, _1, Selection::Toggle), gui_context());
ControlProtocol::SetRouteSelection.connect (*this, invalidator (*this), boost::bind (&Editor::control_select, this, _1, Selection::Set), gui_context());
ControlProtocol::ClearRouteSelection.connect (*this, invalidator (*this), boost::bind (&Editor::control_unselect, this), gui_context());
BasicUI::AccessAction.connect (*this, invalidator (*this), boost::bind (&Editor::access_action, this, _1, _2), gui_context());
/* problematic: has to return a value and thus cannot be x-thread */
Session::AskAboutPlaylistDeletion.connect_same_thread (*this, boost::bind (&Editor::playlist_deletion_dialog, this, _1));
Config->ParameterChanged.connect (*this, invalidator (*this), ui_bind (&Editor::parameter_changed, this, _1), gui_context());
Config->ParameterChanged.connect (*this, invalidator (*this), boost::bind (&Editor::parameter_changed, this, _1), gui_context());
TimeAxisView::CatchDeletion.connect (*this, invalidator (*this), ui_bind (&Editor::timeaxisview_deleted, this, _1), gui_context());
TimeAxisView::CatchDeletion.connect (*this, invalidator (*this), boost::bind (&Editor::timeaxisview_deleted, this, _1), gui_context());
_ignore_region_action = false;
_last_region_menu_was_main = false;
@ -920,7 +932,43 @@ Editor::zoom_adjustment_changed ()
}
void
Editor::control_select (uint32_t rid)
Editor::control_vertical_zoom_in_all ()
{
tav_zoom_smooth (false, true);
}
void
Editor::control_vertical_zoom_out_all ()
{
tav_zoom_smooth (true, true);
}
void
Editor::control_vertical_zoom_in_selected ()
{
tav_zoom_smooth (false, false);
}
void
Editor::control_vertical_zoom_out_selected ()
{
tav_zoom_smooth (true, false);
}
void
Editor::control_view (uint32_t view)
{
goto_visual_state (view);
}
void
Editor::control_unselect ()
{
selection->clear_tracks ();
}
void
Editor::control_select (uint32_t rid, Selection::Operation op)
{
/* handles the (static) signal from the ControlProtocol class that
* requests setting the selected track to a given RID
@ -939,12 +987,36 @@ Editor::control_select (uint32_t rid)
TimeAxisView* tav = axis_view_from_route (r);
if (tav) {
selection->set (tav);
switch (op) {
case Selection::Add:
selection->add (tav);
break;
case Selection::Toggle:
selection->toggle (tav);
break;
case Selection::Extend:
break;
case Selection::Set:
selection->set (tav);
break;
}
} else {
selection->clear_tracks ();
}
}
void
Editor::control_step_tracks_up ()
{
scroll_tracks_up_line ();
}
void
Editor::control_step_tracks_down ()
{
scroll_tracks_down_line ();
}
void
Editor::control_scroll (float fraction)
{
@ -1198,19 +1270,19 @@ Editor::set_session (Session *t)
but use Gtkmm2ext::UI::instance()->call_slot();
*/
_session->StepEditStatusChange.connect (_session_connections, invalidator (*this), ui_bind(&Editor::step_edit_status_change, this, _1), gui_context());
_session->StepEditStatusChange.connect (_session_connections, invalidator (*this), boost::bind (&Editor::step_edit_status_change, this, _1), gui_context());
_session->TransportStateChange.connect (_session_connections, invalidator (*this), boost::bind (&Editor::map_transport_state, this), gui_context());
_session->PositionChanged.connect (_session_connections, invalidator (*this), ui_bind (&Editor::map_position_change, this, _1), gui_context());
_session->RouteAdded.connect (_session_connections, invalidator (*this), ui_bind (&Editor::handle_new_route, this, _1), gui_context());
_session->PositionChanged.connect (_session_connections, invalidator (*this), boost::bind (&Editor::map_position_change, this, _1), gui_context());
_session->RouteAdded.connect (_session_connections, invalidator (*this), boost::bind (&Editor::handle_new_route, this, _1), gui_context());
_session->DirtyChanged.connect (_session_connections, invalidator (*this), boost::bind (&Editor::update_title, this), gui_context());
_session->tempo_map().PropertyChanged.connect (_session_connections, invalidator (*this), ui_bind (&Editor::tempo_map_changed, this, _1), gui_context());
_session->tempo_map().PropertyChanged.connect (_session_connections, invalidator (*this), boost::bind (&Editor::tempo_map_changed, this, _1), gui_context());
_session->Located.connect (_session_connections, invalidator (*this), boost::bind (&Editor::located, this), gui_context());
_session->config.ParameterChanged.connect (_session_connections, invalidator (*this), ui_bind (&Editor::parameter_changed, this, _1), gui_context());
_session->StateSaved.connect (_session_connections, invalidator (*this), ui_bind (&Editor::session_state_saved, this, _1), gui_context());
_session->locations()->added.connect (_session_connections, invalidator (*this), ui_bind (&Editor::add_new_location, this, _1), gui_context());
_session->locations()->removed.connect (_session_connections, invalidator (*this), ui_bind (&Editor::location_gone, this, _1), gui_context());
_session->config.ParameterChanged.connect (_session_connections, invalidator (*this), boost::bind (&Editor::parameter_changed, this, _1), gui_context());
_session->StateSaved.connect (_session_connections, invalidator (*this), boost::bind (&Editor::session_state_saved, this, _1), gui_context());
_session->locations()->added.connect (_session_connections, invalidator (*this), boost::bind (&Editor::add_new_location, this, _1), gui_context());
_session->locations()->removed.connect (_session_connections, invalidator (*this), boost::bind (&Editor::location_gone, this, _1), gui_context());
_session->locations()->changed.connect (_session_connections, invalidator (*this), boost::bind (&Editor::refresh_location_display, this), gui_context());
_session->locations()->StateChanged.connect (_session_connections, invalidator (*this), ui_bind (&Editor::refresh_location_display, this), gui_context());
_session->locations()->StateChanged.connect (_session_connections, invalidator (*this), boost::bind (&Editor::refresh_location_display, this), gui_context());
_session->history().Changed.connect (_session_connections, invalidator (*this), boost::bind (&Editor::history_changed, this), gui_context());
playhead_cursor->canvas_item.show ();
@ -1453,10 +1525,6 @@ Editor::popup_track_context_menu (int button, int32_t time, ItemType item_type,
}
break;
case CrossfadeViewItem:
build_menu_function = &Editor::build_track_crossfade_context_menu;
break;
case StreamItem:
if (clicked_routeview->track()) {
build_menu_function = &Editor::build_track_context_menu;
@ -1502,9 +1570,6 @@ Editor::popup_track_context_menu (int button, int32_t time, ItemType item_type,
case SelectionItem:
break;
case CrossfadeViewItem:
break;
case StreamItem:
break;
@ -1589,11 +1654,6 @@ Editor::build_track_region_context_menu ()
region_edit_menu_split_item = 0;
region_edit_menu_split_multichannel_item = 0;
/* we might try to use items that are currently attached to a crossfade menu,
so clear that, too.
*/
track_crossfade_context_menu.items().clear ();
RouteTimeAxisView* rtv = dynamic_cast<RouteTimeAxisView*> (clicked_axisview);
if (rtv) {
@ -1610,54 +1670,6 @@ Editor::build_track_region_context_menu ()
return &track_region_context_menu;
}
Menu*
Editor::build_track_crossfade_context_menu ()
{
using namespace Menu_Helpers;
MenuList& edit_items = track_crossfade_context_menu.items();
edit_items.clear ();
/* we might try to use items that are currently attached to a crossfade menu,
so clear that, too.
*/
track_region_context_menu.items().clear ();
AudioTimeAxisView* atv = dynamic_cast<AudioTimeAxisView*> (clicked_axisview);
if (atv) {
boost::shared_ptr<Track> tr;
boost::shared_ptr<Playlist> pl;
boost::shared_ptr<AudioPlaylist> apl;
if ((tr = atv->track()) && ((pl = tr->playlist()) != 0) && ((apl = boost::dynamic_pointer_cast<AudioPlaylist> (pl)) != 0)) {
AudioPlaylist::Crossfades xfades;
framepos_t where;
bool ignored;
/* The xfade menu is a bit of a special case, as we always use the mouse position
to decide whether or not to display it (rather than the edit point). No particularly
strong reasons for this, other than it is a bit surprising to right-click on a xfade
and not get a menu.
*/
mouse_frame (where, ignored);
apl->crossfades_at (where, xfades);
bool const many = xfades.size() > 1;
for (AudioPlaylist::Crossfades::iterator i = xfades.begin(); i != xfades.end(); ++i) {
add_crossfade_context_items (atv->audio_view(), (*i), edit_items, many);
}
add_region_context_items (edit_items, tr);
}
}
add_dstream_context_items (edit_items);
return &track_crossfade_context_menu;
}
void
Editor::analyze_region_selection ()
{
@ -1708,73 +1720,6 @@ Editor::build_track_selection_context_menu ()
return &track_selection_context_menu;
}
/** Add context menu items relevant to crossfades.
* @param edit_items List to add the items to.
*/
void
Editor::add_crossfade_context_items (AudioStreamView* view, boost::shared_ptr<Crossfade> xfade, Menu_Helpers::MenuList& edit_items, bool many)
{
using namespace Menu_Helpers;
Menu *xfade_menu = manage (new Menu);
MenuList& items = xfade_menu->items();
xfade_menu->set_name ("ArdourContextMenu");
string str;
if (xfade->active()) {
str = _("Mute");
} else {
str = _("Unmute");
}
items.push_back (
MenuElem (str, sigc::bind (sigc::mem_fun (*this, &Editor::toggle_xfade_active), &view->trackview(), boost::weak_ptr<Crossfade> (xfade)))
);
items.push_back (
MenuElem (_("Edit..."), sigc::bind (sigc::mem_fun (*this, &Editor::edit_xfade), boost::weak_ptr<Crossfade> (xfade)))
);
if (xfade->can_follow_overlap()) {
if (xfade->following_overlap()) {
str = _("Convert to Short");
} else {
str = _("Convert to Full");
}
items.push_back (
MenuElem (str, sigc::bind (sigc::mem_fun (*this, &Editor::toggle_xfade_length), &view->trackview(), xfade))
);
}
if (many) {
str = xfade->out()->name();
str += "->";
str += xfade->in()->name();
} else {
str = _("Crossfade");
}
edit_items.push_back (MenuElem (str, *xfade_menu));
edit_items.push_back (SeparatorElem());
}
void
Editor::xfade_edit_left_region ()
{
if (clicked_crossfadeview) {
clicked_crossfadeview->left_view.show_region_editor ();
}
}
void
Editor::xfade_edit_right_region ()
{
if (clicked_crossfadeview) {
clicked_crossfadeview->right_view.show_region_editor ();
}
}
void
Editor::add_region_context_items (Menu_Helpers::MenuList& edit_items, boost::shared_ptr<Track> track)
{
@ -2330,12 +2275,6 @@ Editor::set_state (const XMLNode& node, int /*version*/)
_regions->reset_sort_type ((RegionListSortType) string_2_enum (prop->value(), st), true);
}
if ((prop = node.property ("xfades-visible"))) {
bool yn = string_is_affirmative (prop->value());
_xfade_visibility = !yn;
// set_xfade_visibility (yn);
}
if ((prop = node.property ("show-editor-mixer"))) {
Glib::RefPtr<Action> act = ActionManager::get_action (X_("Editor"), X_("show-editor-mixer"));
@ -2462,7 +2401,6 @@ Editor::get_state ()
node->add_property ("maximised", _maximised ? "yes" : "no");
node->add_property ("follow-playhead", _follow_playhead ? "yes" : "no");
node->add_property ("stationary-playhead", _stationary_playhead ? "yes" : "no");
node->add_property ("xfades-visible", _xfade_visibility ? "yes" : "no");
node->add_property ("region-list-sort-type", enum_2_string (_regions->sort_type ()));
node->add_property ("mouse-mode", enum2str(mouse_mode));
node->add_property ("internal-edit", _internal_editing ? "yes" : "no");
@ -2817,15 +2755,9 @@ Editor::setup_toolbar ()
/* make them just a bit bigger */
mouse_move_button.set_size_request (-1, 25);
smart_mode_joiner = manage (new ButtonJoiner ("mouse mode button", mouse_move_button, mouse_select_button));
smart_mode_joiner = manage (new ButtonJoiner ("mouse mode button", mouse_move_button, mouse_select_button, true));
smart_mode_joiner->set_related_action (smart_mode_action);
mouse_move_button.set_elements (ArdourButton::Element (ArdourButton::Body|ArdourButton::Text));
mouse_select_button.set_elements (ArdourButton::Element (ArdourButton::Body|ArdourButton::Text));
mouse_move_button.set_rounded_corner_mask (0x1); // upper left only
mouse_select_button.set_rounded_corner_mask (0x2); // upper right only
mouse_mode_hbox2->set_spacing (2);
mouse_mode_box->set_spacing (2);
@ -3690,80 +3622,6 @@ Editor::set_stationary_playhead (bool yn)
}
}
void
Editor::toggle_xfade_active (RouteTimeAxisView* tv, boost::weak_ptr<Crossfade> wxfade)
{
boost::shared_ptr<Crossfade> xfade (wxfade.lock());
if (!xfade) {
return;
}
vector<boost::shared_ptr<Crossfade> > all = get_equivalent_crossfades (*tv, xfade, ARDOUR::Properties::edit.property_id);
_session->begin_reversible_command (_("Change crossfade active state"));
for (vector<boost::shared_ptr<Crossfade> >::iterator i = all.begin(); i != all.end(); ++i) {
(*i)->clear_changes ();
(*i)->set_active (!(*i)->active());
_session->add_command (new StatefulDiffCommand (*i));
}
_session->commit_reversible_command ();
}
void
Editor::toggle_xfade_length (RouteTimeAxisView* tv, boost::weak_ptr<Crossfade> wxfade)
{
boost::shared_ptr<Crossfade> xfade (wxfade.lock());
if (!xfade) {
return;
}
vector<boost::shared_ptr<Crossfade> > all = get_equivalent_crossfades (*tv, xfade, ARDOUR::Properties::edit.property_id);
/* This can't be a StatefulDiffCommand as the fade shapes are not
managed by the Stateful properties system.
*/
_session->begin_reversible_command (_("Change crossfade length"));
for (vector<boost::shared_ptr<Crossfade> >::iterator i = all.begin(); i != all.end(); ++i) {
XMLNode& before = (*i)->get_state ();
(*i)->set_follow_overlap (!(*i)->following_overlap());
XMLNode& after = (*i)->get_state ();
_session->add_command (new MementoCommand<Crossfade> (*i->get(), &before, &after));
}
_session->commit_reversible_command ();
}
void
Editor::edit_xfade (boost::weak_ptr<Crossfade> wxfade)
{
boost::shared_ptr<Crossfade> xfade (wxfade.lock());
if (!xfade) {
return;
}
CrossfadeEditor cew (_session, xfade, xfade->fade_in().get_min_y(), 1.0);
ensure_float (cew);
switch (cew.run ()) {
case RESPONSE_ACCEPT:
break;
default:
return;
}
cew.apply ();
PropertyChange all_crossfade_properties;
all_crossfade_properties.add (ARDOUR::Properties::active);
all_crossfade_properties.add (ARDOUR::Properties::follow_overlap);
xfade->PropertyChanged (all_crossfade_properties);
}
PlaylistSelector&
Editor::playlist_selector () const
{
@ -4341,19 +4199,6 @@ Editor::idle_visual_changer ()
double const last_time_origin = horizontal_position ();
if (p & VisualChange::TimeOrigin) {
/* This is a bit of a hack, but set_frames_per_unit
below will (if called) end up with the
CrossfadeViews looking at Editor::leftmost_frame,
and if we're changing origin and zoom in the same
operation it will be the wrong value unless we
update it here.
*/
leftmost_frame = pending_visual_change.time_origin;
assert (leftmost_frame >= 0);
}
if (p & VisualChange::ZoomLevel) {
set_frames_per_unit (pending_visual_change.frames_per_unit);
@ -5327,7 +5172,6 @@ Editor::session_going_away ()
clicked_regionview = 0;
clicked_axisview = 0;
clicked_routeview = 0;
clicked_crossfadeview = 0;
entered_regionview = 0;
entered_track = 0;
last_update_frame = 0;
@ -5451,7 +5295,6 @@ Editor::setup_fade_images ()
_fade_out_images[FadeSlow] = new Gtk::Image (get_icon_path (X_("crossfade-out-long-cut")));
}
/** @return Gtk::manage()d menu item for a given action from `editor_actions' */
Gtk::MenuItem&
Editor::action_menu_item (std::string const & name)

View file

@ -83,7 +83,6 @@ namespace ARDOUR {
class NamedSelection;
class Session;
class Filter;
class Crossfade;
class ChanCount;
class MidiOperator;
class Track;
@ -106,7 +105,6 @@ class AutomationTimeAxisView;
class BundleManager;
class ButtonJoiner;
class ControlPoint;
class CrossfadeView;
class DragManager;
class GroupedButtons;
class GUIObjectState;
@ -318,6 +316,7 @@ class Editor : public PublicEditor, public PBD::ScopedConnectionList, public ARD
void temporal_zoom_step (bool coarser);
void tav_zoom_step (bool coarser);
void tav_zoom_smooth (bool coarser, bool force_all);
/* stuff that AudioTimeAxisView and related classes use */
@ -369,12 +368,10 @@ class Editor : public PublicEditor, public PBD::ScopedConnectionList, public ARD
void toggle_measure_visibility ();
void toggle_logo_visibility ();
/* fades/xfades */
/* fades */
void toggle_region_fades (int dir);
void update_region_fade_visibility ();
bool xfade_visibility() const { return _xfade_visibility; }
void update_xfade_visibility ();
/* redirect shared ops menu. caller must free returned menu */
@ -631,16 +628,12 @@ class Editor : public PublicEditor, public PBD::ScopedConnectionList, public ARD
RegionView* clicked_regionview;
RegionSelection latest_regionviews;
uint32_t clicked_selection;
CrossfadeView* clicked_crossfadeview;
ControlPoint* clicked_control_point;
void sort_track_selection (TrackViewList&);
void get_equivalent_regions (RegionView* rv, std::vector<RegionView*> &, PBD::PropertyID) const;
RegionSelection get_equivalent_regions (RegionSelection &, PBD::PropertyID) const;
std::vector<boost::shared_ptr<ARDOUR::Crossfade> > get_equivalent_crossfades (
RouteTimeAxisView&, boost::shared_ptr<ARDOUR::Crossfade>, PBD::PropertyID
) const;
void mapover_tracks (sigc::slot<void,RouteTimeAxisView&,uint32_t> sl, TimeAxisView*, PBD::PropertyID) const;
void mapover_tracks_with_unique_playlists (sigc::slot<void,RouteTimeAxisView&,uint32_t> sl, TimeAxisView*, PBD::PropertyID) const;
@ -649,9 +642,6 @@ class Editor : public PublicEditor, public PBD::ScopedConnectionList, public ARD
void mapped_use_new_playlist (RouteTimeAxisView&, uint32_t, std::vector<boost::shared_ptr<ARDOUR::Playlist> > const &);
void mapped_use_copy_playlist (RouteTimeAxisView&, uint32_t, std::vector<boost::shared_ptr<ARDOUR::Playlist> > const &);
void mapped_clear_playlist (RouteTimeAxisView&, uint32_t);
void mapped_get_equivalent_crossfades (
RouteTimeAxisView&, uint32_t, boost::shared_ptr<ARDOUR::Crossfade>, std::vector<boost::shared_ptr<ARDOUR::Crossfade> >*
) const;
void button_selection (ArdourCanvas::Item* item, GdkEvent* event, ItemType item_type);
bool button_release_can_deselect;
@ -662,7 +652,7 @@ class Editor : public PublicEditor, public PBD::ScopedConnectionList, public ARD
void select_all_tracks ();
void select_all_internal_edit (Selection::Operation);
bool set_selected_control_point_from_click (Selection::Operation op = Selection::Set, bool no_remove=false);
bool set_selected_control_point_from_click (bool press, Selection::Operation op = Selection::Set);
void set_selected_track_from_click (bool press, Selection::Operation op = Selection::Set, bool no_remove=false);
void set_selected_track_as_side_effect (Selection::Operation op);
bool set_selected_regionview_from_click (bool press, Selection::Operation op = Selection::Set);
@ -674,7 +664,6 @@ class Editor : public PublicEditor, public PBD::ScopedConnectionList, public ARD
Gtk::Menu track_context_menu;
Gtk::Menu track_region_context_menu;
Gtk::Menu track_selection_context_menu;
Gtk::Menu track_crossfade_context_menu;
Gtk::MenuItem* region_edit_menu_split_item;
Gtk::MenuItem* region_edit_menu_split_multichannel_item;
@ -688,12 +677,10 @@ class Editor : public PublicEditor, public PBD::ScopedConnectionList, public ARD
Gtk::Menu* build_track_context_menu ();
Gtk::Menu* build_track_bus_context_menu ();
Gtk::Menu* build_track_region_context_menu ();
Gtk::Menu* build_track_crossfade_context_menu ();
Gtk::Menu* build_track_selection_context_menu ();
void add_dstream_context_items (Gtk::Menu_Helpers::MenuList&);
void add_bus_context_items (Gtk::Menu_Helpers::MenuList&);
void add_region_context_items (Gtk::Menu_Helpers::MenuList&, boost::shared_ptr<ARDOUR::Track>);
void add_crossfade_context_items (AudioStreamView*, boost::shared_ptr<ARDOUR::Crossfade>, Gtk::Menu_Helpers::MenuList&, bool many);
void add_selection_context_items (Gtk::Menu_Helpers::MenuList&);
Gtk::MenuItem* _popup_region_menu_item;
@ -987,8 +974,16 @@ class Editor : public PublicEditor, public PBD::ScopedConnectionList, public ARD
Gtk::VBox edit_controls_vbox;
Gtk::HBox edit_controls_hbox;
void control_vertical_zoom_in_all ();
void control_vertical_zoom_out_all ();
void control_vertical_zoom_in_selected ();
void control_vertical_zoom_out_selected ();
void control_step_tracks_up ();
void control_step_tracks_down ();
void control_view (uint32_t);
void control_scroll (float);
void control_select (uint32_t rid);
void control_select (uint32_t rid, Selection::Operation);
void control_unselect ();
void access_action (std::string,std::string);
bool deferred_control_scroll (framepos_t);
sigc::connection control_scroll_connection;
@ -1379,7 +1374,6 @@ class Editor : public PublicEditor, public PBD::ScopedConnectionList, public ARD
bool canvas_selection_rect_event (GdkEvent* event,ArdourCanvas::Item*, SelectionRect*);
bool canvas_selection_start_trim_event (GdkEvent* event,ArdourCanvas::Item*, SelectionRect*);
bool canvas_selection_end_trim_event (GdkEvent* event,ArdourCanvas::Item*, SelectionRect*);
bool canvas_crossfade_view_event (GdkEvent* event,ArdourCanvas::Item*, CrossfadeView*);
bool canvas_fade_in_event (GdkEvent* event,ArdourCanvas::Item*, AudioRegionView*);
bool canvas_fade_in_handle_event (GdkEvent* event,ArdourCanvas::Item*, AudioRegionView*);
bool canvas_fade_out_event (GdkEvent* event,ArdourCanvas::Item*, AudioRegionView*);
@ -1857,10 +1851,6 @@ class Editor : public PublicEditor, public PBD::ScopedConnectionList, public ARD
void nudge_track (bool use_edit_point, bool forwards);
/* xfades */
bool _xfade_visibility;
#ifdef WITH_CMT
void handle_new_imageframe_time_axis_view(const std::string & track_name, void* src) ;
void handle_new_imageframe_marker_time_axis_view(const std::string & track_name, TimeAxisView* marked_track) ;
@ -1902,12 +1892,6 @@ class Editor : public PublicEditor, public PBD::ScopedConnectionList, public ARD
ImageFrameSocketHandler* image_socket_listener ;
#endif
void toggle_xfade_active (RouteTimeAxisView *, boost::weak_ptr<ARDOUR::Crossfade>);
void toggle_xfade_length (RouteTimeAxisView *, boost::weak_ptr<ARDOUR::Crossfade>);
void edit_xfade (boost::weak_ptr<ARDOUR::Crossfade>);
void xfade_edit_left_region ();
void xfade_edit_right_region ();
static const int32_t default_width = 995;
static const int32_t default_height = 765;

View file

@ -1428,8 +1428,6 @@ Editor::parameter_changed (std::string p)
update_punch_range_view (true);
} else if (p == "timecode-format") {
update_just_timecode ();
} else if (p == "xfades-visible") {
update_xfade_visibility ();
} else if (p == "show-region-fades") {
update_region_fade_visibility ();
} else if (p == "edit-mode") {

View file

@ -35,7 +35,6 @@
#include "audio_region_view.h"
#include "audio_streamview.h"
#include "canvas-noevent-text.h"
#include "crossfade_view.h"
#include "audio_time_axis.h"
#include "region_gain_line.h"
#include "automation_line.h"
@ -517,127 +516,6 @@ struct DescendingRegionLayerSorter {
}
};
bool
Editor::canvas_crossfade_view_event (GdkEvent* event, ArdourCanvas::Item* item, CrossfadeView* xfv)
{
/* we handle only button 3 press/release events */
switch (event->type) {
case GDK_BUTTON_PRESS:
clicked_crossfadeview = xfv;
clicked_axisview = &clicked_crossfadeview->get_time_axis_view();
clicked_routeview = dynamic_cast<RouteTimeAxisView*>(clicked_axisview);
if (event->button.button == 3) {
return button_press_handler (item, event, CrossfadeViewItem);
}
break;
case GDK_BUTTON_RELEASE:
if (event->button.button == 3) {
bool ret = button_release_handler (item, event, CrossfadeViewItem);
return ret;
}
break;
default:
break;
}
/* XXX do not forward double clicks */
if (event->type == GDK_2BUTTON_PRESS) {
return false;
}
/* proxy for an underlying regionview */
/* XXX really need to check if we are in the name highlight,
and proxy to that when required.
XXX or in the trim rectangles
*/
TimeAxisView& tv (xfv->get_time_axis_view());
AudioTimeAxisView* atv;
if ((atv = dynamic_cast<AudioTimeAxisView*>(&tv)) != 0) {
if (atv->is_audio_track()) {
boost::shared_ptr<AudioPlaylist> pl;
if ((pl = boost::dynamic_pointer_cast<AudioPlaylist> (atv->track()->playlist())) != 0) {
boost::shared_ptr<RegionList> rl = pl->regions_at (event_frame (event));
if (!rl->empty()) {
if (atv->layer_display() == Overlaid) {
/* we're in overlaid mode; proxy to the uppermost region view */
DescendingRegionLayerSorter cmp;
rl->sort (cmp);
RegionView* rv = atv->view()->find_view (rl->front());
/* proxy */
return canvas_region_view_event (event, rv->get_canvas_group(), rv);
} else {
/* we're in stacked mode; proxy to the region view under the mouse */
double cx = 0;
double cy = 0;
switch (event->type) {
case GDK_BUTTON_PRESS:
case GDK_BUTTON_RELEASE:
cx = event->button.x;
cy = event->button.y;
break;
case GDK_MOTION_NOTIFY:
cx = event->motion.x;
cy = event->motion.y;
break;
case GDK_ENTER_NOTIFY:
case GDK_LEAVE_NOTIFY:
cx = event->crossing.x;
cy = event->crossing.y;
break;
default:
/* XXX: this may be wrong for some events */
cx = event->button.x;
cy = event->button.y;
}
/* position of the event within the track */
atv->view()->canvas_item()->w2i (cx, cy);
/* hence layer that we're over */
double const c = atv->view()->child_height ();
layer_t const l = pl->top_layer () + 1 - (cy / c);
/* hence region */
RegionList::iterator i = rl->begin();
while (i != rl->end() && (*i)->layer() != l) {
++i;
}
if (i != rl->end()) {
RegionView* rv = atv->view()->find_view (*i);
/* proxy */
return canvas_region_view_event (event, rv->get_canvas_group(), rv);
}
}
}
}
}
}
return TRUE;
}
bool
Editor::canvas_control_point_event (GdkEvent *event, ArdourCanvas::Item* item, ControlPoint* cp)
{

View file

@ -453,7 +453,7 @@ RegionDrag::RegionDrag (Editor* e, ArdourCanvas::Item* i, RegionView* p, list<Re
_views.push_back (DraggingView (*i, this));
}
RegionView::RegionViewGoingAway.connect (death_connection, invalidator (*this), ui_bind (&RegionDrag::region_going_away, this, _1), gui_context());
RegionView::RegionViewGoingAway.connect (death_connection, invalidator (*this), boost::bind (&RegionDrag::region_going_away, this, _1), gui_context());
}
void
@ -2981,14 +2981,7 @@ LineDrag::motion (GdkEvent* event, bool)
cy = min ((double) _line->height(), cy);
double const fraction = 1.0 - (cy / _line->height());
bool push;
if (Keyboard::modifier_state_contains (event->button.state, Keyboard::PrimaryModifier)) {
push = false;
} else {
push = true;
}
bool const push = !Keyboard::modifier_state_contains (event->button.state, Keyboard::PrimaryModifier);
/* we are ignoring x position for this drag, so we can just pass in anything */
_line->drag_motion (0, fraction, true, push);
@ -4117,7 +4110,7 @@ AutomationRangeDrag::setup (list<boost::shared_ptr<AutomationLine> > const & lin
/* check this range against all the AudioRanges that we are using */
list<AudioRange>::const_iterator k = _ranges.begin ();
while (k != _ranges.end()) {
if (k->coverage (r.first, r.second) != OverlapNone) {
if (k->coverage (r.first, r.second) != Evoral::OverlapNone) {
break;
}
++k;
@ -4186,9 +4179,7 @@ AutomationRangeDrag::start_grab (GdkEvent* event, Gdk::Cursor* cursor)
double const q = j->line->time_converter().from (a - j->line->time_converter().origin_b ());
the_list->add (p, the_list->eval (p));
j->line->add_always_in_view (p);
the_list->add (q, the_list->eval (q));
j->line->add_always_in_view (q);
}
/* same thing for the end */
@ -4214,9 +4205,7 @@ AutomationRangeDrag::start_grab (GdkEvent* event, Gdk::Cursor* cursor)
double const q = j->line->time_converter().from (i->end - j->line->time_converter().origin_b ());
the_list->add (p, the_list->eval (p));
j->line->add_always_in_view (p);
the_list->add (q, the_list->eval (q));
j->line->add_always_in_view (q);
}
}
@ -4284,7 +4273,6 @@ AutomationRangeDrag::finished (GdkEvent* event, bool)
motion (event, false);
for (list<Line>::iterator i = _lines.begin(); i != _lines.end(); ++i) {
i->line->end_drag ();
i->line->clear_always_in_view ();
}
_editor->session()->commit_reversible_command ();
@ -4294,7 +4282,6 @@ void
AutomationRangeDrag::aborted (bool)
{
for (list<Line>::iterator i = _lines.begin(); i != _lines.end(); ++i) {
i->line->clear_always_in_view ();
i->line->reset ();
}
}

View file

@ -310,7 +310,7 @@ public:
protected:
double compute_x_delta (GdkEvent const *, ARDOUR::framecnt_t *);
double compute_x_delta (GdkEvent const *, ARDOUR::framepos_t *);
bool y_movement_allowed (int, double) const;
bool _brushing;

View file

@ -154,11 +154,11 @@ Editor::add_new_location_internal (Location* location)
lam->show ();
}
location->start_changed.connect (*this, invalidator (*this), ui_bind (&Editor::location_changed, this, _1), gui_context());
location->end_changed.connect (*this, invalidator (*this), ui_bind (&Editor::location_changed, this, _1), gui_context());
location->changed.connect (*this, invalidator (*this), ui_bind (&Editor::location_changed, this, _1), gui_context());
location->name_changed.connect (*this, invalidator (*this), ui_bind (&Editor::location_changed, this, _1), gui_context());
location->FlagsChanged.connect (*this, invalidator (*this), ui_bind (&Editor::location_flags_changed, this, _1, _2), gui_context());
location->start_changed.connect (*this, invalidator (*this), boost::bind (&Editor::location_changed, this, _1), gui_context());
location->end_changed.connect (*this, invalidator (*this), boost::bind (&Editor::location_changed, this, _1), gui_context());
location->changed.connect (*this, invalidator (*this), boost::bind (&Editor::location_changed, this, _1), gui_context());
location->name_changed.connect (*this, invalidator (*this), boost::bind (&Editor::location_changed, this, _1), gui_context());
location->FlagsChanged.connect (*this, invalidator (*this), boost::bind (&Editor::location_flags_changed, this, _1, _2), gui_context());
pair<Location*,LocationMarkers*> newpair;

View file

@ -655,7 +655,7 @@ Editor::button_selection (ArdourCanvas::Item* /*item*/, GdkEvent* event, ItemTyp
case ControlPointItem:
set_selected_track_as_side_effect (op);
if (doing_object_stuff() || (mouse_mode != MouseRange && mouse_mode != MouseObject)) {
set_selected_control_point_from_click (op, false);
set_selected_control_point_from_click (press, op);
}
break;
@ -889,6 +889,7 @@ Editor::button_press_handler_1 (ArdourCanvas::Item* item, GdkEvent* event, ItemT
default:
break;
}
break;
case MouseObject:
switch (item_type) {

View file

@ -63,6 +63,7 @@
#include "route_time_axis.h"
#include "audio_time_axis.h"
#include "automation_time_axis.h"
#include "control_point.h"
#include "streamview.h"
#include "audio_streamview.h"
#include "audio_region_view.h"
@ -1278,11 +1279,17 @@ Editor::scroll_tracks_up_line ()
void
Editor::tav_zoom_step (bool coarser)
{
ENSURE_GUI_THREAD (*this, &Editor::temporal_zoom_step, coarser)
_routes->suspend_redisplay ();
for (TrackViewList::iterator i = track_views.begin(); i != track_views.end(); ++i) {
TrackViewList* ts;
if (selection->tracks.empty()) {
ts = &track_views;
} else {
ts = &selection->tracks;
}
for (TrackViewList::iterator i = ts->begin(); i != ts->end(); ++i) {
TimeAxisView *tv = (static_cast<TimeAxisView*>(*i));
tv->step_height (coarser);
}
@ -1290,6 +1297,38 @@ Editor::tav_zoom_step (bool coarser)
_routes->resume_redisplay ();
}
void
Editor::tav_zoom_smooth (bool coarser, bool force_all)
{
_routes->suspend_redisplay ();
TrackViewList* ts;
if (selection->tracks.empty() || force_all) {
ts = &track_views;
} else {
ts = &selection->tracks;
}
for (TrackViewList::iterator i = ts->begin(); i != ts->end(); ++i) {
TimeAxisView *tv = (static_cast<TimeAxisView*>(*i));
uint32_t h = tv->current_height ();
if (coarser) {
if (h > 5) {
h -= 5; // pixels
if (h >= TimeAxisView::preset_height (HeightSmall)) {
tv->set_height (h);
}
}
} else {
tv->set_height (h + 5);
}
}
_routes->resume_redisplay ();
}
void
Editor::temporal_zoom_step (bool coarser)
{
@ -2472,7 +2511,7 @@ static void
add_if_covered (RegionView* rv, const AudioRange* ar, RegionSelection* rs)
{
switch (rv->region()->coverage (ar->start, ar->end - 1)) {
case OverlapNone:
case Evoral::OverlapNone:
break;
default:
rs->push_back (rv);
@ -3225,7 +3264,7 @@ Editor::trim_region_to_location (const Location& loc, const char* str)
/* require region to span proposed trim */
switch (rv->region()->coverage (loc.start(), loc.end())) {
case OverlapInternal:
case Evoral::OverlapInternal:
break;
default:
continue;
@ -3355,9 +3394,10 @@ Editor::freeze_thread ()
SessionEvent::create_per_thread_pool ("freeze events", 64);
/* create per-thread buffers for process() tree to use */
current_interthread_info->process_thread.init ();
current_interthread_info->process_thread.get_buffers ();
clicked_routeview->audio_track()->freeze_me (*current_interthread_info);
current_interthread_info->done = true;
current_interthread_info->process_thread.drop_buffers();
return 0;
}
@ -3682,19 +3722,87 @@ Editor::cut_copy (CutCopyOp op)
}
}
struct AutomationRecord {
AutomationRecord () : state (0) {}
AutomationRecord (XMLNode* s) : state (s) {}
XMLNode* state; ///< state before any operation
boost::shared_ptr<Evoral::ControlList> copy; ///< copied events for the cut buffer
};
/** Cut, copy or clear selected automation points.
* @param op Operation (Cut, Copy or Clear)
* @param op Operation (Cut, Copy or Clear)
*/
void
Editor::cut_copy_points (CutCopyOp op)
{
if (selection->points.empty ()) {
return;
}
/* XXX: not ideal, as there may be more than one track involved in the point selection */
_last_cut_copy_source_track = &selection->points.front()->line().trackview;
/* Keep a record of the AutomationLists that we end up using in this operation */
typedef std::map<boost::shared_ptr<AutomationList>, AutomationRecord> Lists;
Lists lists;
/* Go through all selected points, making an AutomationRecord for each distinct AutomationList */
for (PointSelection::iterator i = selection->points.begin(); i != selection->points.end(); ++i) {
boost::shared_ptr<AutomationList> al = (*i)->line().the_list();
if (lists.find (al) == lists.end ()) {
/* We haven't seen this list yet, so make a record for it. This includes
taking a copy of its current state, in case this is needed for undo later.
*/
lists[al] = AutomationRecord (&al->get_state ());
}
}
AutomationTimeAxisView* atv = dynamic_cast<AutomationTimeAxisView*>((*i).track);
_last_cut_copy_source_track = atv;
if (op == Cut || op == Copy) {
/* This operation will involve putting things in the cut buffer, so create an empty
ControlList for each of our source lists to put the cut buffer data in.
*/
for (Lists::iterator i = lists.begin(); i != lists.end(); ++i) {
i->second.copy = i->first->create (i->first->parameter ());
}
if (atv) {
atv->cut_copy_clear_objects (selection->points, op);
/* Add all selected points to the relevant copy ControlLists */
for (PointSelection::iterator i = selection->points.begin(); i != selection->points.end(); ++i) {
boost::shared_ptr<AutomationList> al = (*i)->line().the_list();
AutomationList::const_iterator j = (*i)->model ();
lists[al].copy->add ((*j)->when, (*j)->value);
}
for (Lists::iterator i = lists.begin(); i != lists.end(); ++i) {
/* Correct this copy list so that it starts at time 0 */
double const start = i->second.copy->front()->when;
for (AutomationList::iterator j = i->second.copy->begin(); j != i->second.copy->end(); ++j) {
(*j)->when -= start;
}
/* And add it to the cut buffer */
cut_buffer->add (i->second.copy);
}
}
if (op == Delete || op == Cut) {
/* This operation needs to remove things from the main AutomationList, so do that now */
for (Lists::iterator i = lists.begin(); i != lists.end(); ++i) {
i->first->freeze ();
}
/* Remove each selected point from its AutomationList */
for (PointSelection::iterator i = selection->points.begin(); i != selection->points.end(); ++i) {
boost::shared_ptr<AutomationList> al = (*i)->line().the_list();
al->erase ((*i)->model ());
}
/* Thaw the lists and add undo records for them */
for (Lists::iterator i = lists.begin(); i != lists.end(); ++i) {
boost::shared_ptr<AutomationList> al = i->first;
al->thaw ();
_session->add_command (new MementoCommand<AutomationList> (*al.get(), i->second.state, &(al->get_state ())));
}
}
}
@ -4190,18 +4298,13 @@ Editor::duplicate_selection (float times)
commit_reversible_command ();
}
/** Reset all selected points to the relevant default value */
void
Editor::reset_point_selection ()
{
/* reset all selected points to the relevant default value */
for (PointSelection::iterator i = selection->points.begin(); i != selection->points.end(); ++i) {
AutomationTimeAxisView* atv = dynamic_cast<AutomationTimeAxisView*>((*i).track);
if (atv) {
atv->reset_objects (selection->points);
}
ARDOUR::AutomationList::iterator j = (*i)->model ();
(*j)->value = (*i)->line().the_list()->default_value ();
}
}
@ -5207,24 +5310,6 @@ Editor::update_region_fade_visibility ()
}
}
/** Update crossfade visibility after its configuration has been changed */
void
Editor::update_xfade_visibility ()
{
_xfade_visibility = _session->config.get_xfades_visible ();
for (TrackViewList::iterator i = track_views.begin(); i != track_views.end(); ++i) {
AudioTimeAxisView* v = dynamic_cast<AudioTimeAxisView*>(*i);
if (v) {
if (_xfade_visibility) {
v->show_all_xfades ();
} else {
v->hide_all_xfades ();
}
}
}
}
void
Editor::set_edit_point ()
{

View file

@ -212,11 +212,11 @@ EditorRegions::EditorRegions (Editor* e)
//ARDOUR_UI::instance()->secondary_clock.mode_changed.connect (sigc::mem_fun(*this, &Editor::redisplay_regions));
ARDOUR_UI::instance()->secondary_clock->mode_changed.connect (sigc::mem_fun(*this, &EditorRegions::update_all_rows));
ARDOUR::Region::RegionPropertyChanged.connect (region_property_connection, MISSING_INVALIDATOR, ui_bind (&EditorRegions::region_changed, this, _1, _2), gui_context());
ARDOUR::RegionFactory::CheckNewRegion.connect (check_new_region_connection, MISSING_INVALIDATOR, ui_bind (&EditorRegions::add_region, this, _1), gui_context());
ARDOUR::Region::RegionPropertyChanged.connect (region_property_connection, MISSING_INVALIDATOR, boost::bind (&EditorRegions::region_changed, this, _1, _2), gui_context());
ARDOUR::RegionFactory::CheckNewRegion.connect (check_new_region_connection, MISSING_INVALIDATOR, boost::bind (&EditorRegions::add_region, this, _1), gui_context());
e->EditorFreeze.connect (editor_freeze_connection, MISSING_INVALIDATOR, ui_bind (&EditorRegions::freeze_tree_model, this), gui_context());
e->EditorThaw.connect (editor_thaw_connection, MISSING_INVALIDATOR, ui_bind (&EditorRegions::thaw_tree_model, this), gui_context());
e->EditorFreeze.connect (editor_freeze_connection, MISSING_INVALIDATOR, boost::bind (&EditorRegions::freeze_tree_model, this), gui_context());
e->EditorThaw.connect (editor_thaw_connection, MISSING_INVALIDATOR, boost::bind (&EditorRegions::thaw_tree_model, this), gui_context());
}
bool

View file

@ -455,7 +455,7 @@ EditorRouteGroups::add (RouteGroup* group)
focus = true;
}
group->PropertyChanged.connect (_property_changed_connections, MISSING_INVALIDATOR, ui_bind (&EditorRouteGroups::property_changed, this, group, _1), gui_context());
group->PropertyChanged.connect (_property_changed_connections, MISSING_INVALIDATOR, boost::bind (&EditorRouteGroups::property_changed, this, group, _1), gui_context());
if (focus) {
TreeViewColumn* col = _display.get_column (0);
@ -567,9 +567,9 @@ EditorRouteGroups::set_session (Session* s)
RouteGroup& arg (_session->all_route_group());
arg.PropertyChanged.connect (all_route_groups_changed_connection, MISSING_INVALIDATOR, ui_bind (&EditorRouteGroups::all_group_changed, this, _1), gui_context());
arg.PropertyChanged.connect (all_route_groups_changed_connection, MISSING_INVALIDATOR, boost::bind (&EditorRouteGroups::all_group_changed, this, _1), gui_context());
_session->route_group_added.connect (_session_connections, MISSING_INVALIDATOR, ui_bind (&EditorRouteGroups::add, this, _1), gui_context());
_session->route_group_added.connect (_session_connections, MISSING_INVALIDATOR, boost::bind (&EditorRouteGroups::add, this, _1), gui_context());
_session->route_group_removed.connect (
_session_connections, MISSING_INVALIDATOR, boost::bind (&EditorRouteGroups::groups_changed, this), gui_context()
);

View file

@ -282,7 +282,7 @@ EditorRoutes::EditorRoutes (Editor* e)
_display.set_enable_search (false);
Route::SyncOrderKeys.connect (*this, MISSING_INVALIDATOR, ui_bind (&EditorRoutes::sync_order_keys, this, _1), gui_context());
Route::SyncOrderKeys.connect (*this, MISSING_INVALIDATOR, boost::bind (&EditorRoutes::sync_order_keys, this, _1), gui_context());
}
bool
@ -660,8 +660,8 @@ EditorRoutes::routes_added (list<RouteTimeAxisView*> routes)
boost::weak_ptr<Route> wr ((*x)->route());
(*x)->route()->gui_changed.connect (*this, MISSING_INVALIDATOR, ui_bind (&EditorRoutes::handle_gui_changes, this, _1, _2), gui_context());
(*x)->route()->PropertyChanged.connect (*this, MISSING_INVALIDATOR, ui_bind (&EditorRoutes::route_property_changed, this, _1, wr), gui_context());
(*x)->route()->gui_changed.connect (*this, MISSING_INVALIDATOR, boost::bind (&EditorRoutes::handle_gui_changes, this, _1, _2), gui_context());
(*x)->route()->PropertyChanged.connect (*this, MISSING_INVALIDATOR, boost::bind (&EditorRoutes::route_property_changed, this, _1, wr), gui_context());
if ((*x)->is_track()) {
boost::shared_ptr<Track> t = boost::dynamic_pointer_cast<Track> ((*x)->route());
@ -675,8 +675,8 @@ EditorRoutes::routes_added (list<RouteTimeAxisView*> routes)
}
(*x)->route()->mute_changed.connect (*this, MISSING_INVALIDATOR, boost::bind (&EditorRoutes::update_mute_display, this), gui_context());
(*x)->route()->solo_changed.connect (*this, MISSING_INVALIDATOR, ui_bind (&EditorRoutes::update_solo_display, this, _1), gui_context());
(*x)->route()->listen_changed.connect (*this, MISSING_INVALIDATOR, ui_bind (&EditorRoutes::update_solo_display, this, _1), gui_context());
(*x)->route()->solo_changed.connect (*this, MISSING_INVALIDATOR, boost::bind (&EditorRoutes::update_solo_display, this, _1), gui_context());
(*x)->route()->listen_changed.connect (*this, MISSING_INVALIDATOR, boost::bind (&EditorRoutes::update_solo_display, this, _1), gui_context());
(*x)->route()->solo_isolated_changed.connect (*this, MISSING_INVALIDATOR, boost::bind (&EditorRoutes::update_solo_isolate_display, this), gui_context());
(*x)->route()->solo_safe_changed.connect (*this, MISSING_INVALIDATOR, boost::bind (&EditorRoutes::update_solo_safe_display, this), gui_context());
(*x)->route()->active_changed.connect (*this, MISSING_INVALIDATOR, boost::bind (&EditorRoutes::update_active_display, this), gui_context ());

View file

@ -29,6 +29,8 @@
#include "ardour/midi_region.h"
#include "ardour/audioplaylist.h"
#include "control_protocol/control_protocol.h"
#include "editor.h"
#include "actions.h"
#include "audio_time_axis.h"
@ -36,7 +38,6 @@
#include "audio_streamview.h"
#include "automation_line.h"
#include "control_point.h"
#include "crossfade_view.h"
#include "editor_regions.h"
#include "editor_cursors.h"
#include "midi_region_view.h"
@ -313,12 +314,16 @@ Editor::set_selected_track_from_click (bool press, Selection::Operation op, bool
}
bool
Editor::set_selected_control_point_from_click (Selection::Operation op, bool /*no_remove*/)
Editor::set_selected_control_point_from_click (bool press, Selection::Operation op)
{
if (!clicked_control_point) {
return false;
}
if (!press) {
return true;
}
switch (op) {
case Selection::Set:
selection->set (clicked_control_point);
@ -476,32 +481,6 @@ Editor::mapped_get_equivalent_regions (RouteTimeAxisView& tv, uint32_t, RegionVi
}
}
void
Editor::mapped_get_equivalent_crossfades (
RouteTimeAxisView& tv, uint32_t, boost::shared_ptr<Crossfade> basis, vector<boost::shared_ptr<Crossfade> >* equivs
) const
{
boost::shared_ptr<Playlist> pl;
vector<boost::shared_ptr<Crossfade> > results;
boost::shared_ptr<Track> tr;
if ((tr = tv.track()) == 0) {
/* bus */
return;
}
if ((pl = tr->playlist()) != 0) {
boost::shared_ptr<AudioPlaylist> apl = boost::dynamic_pointer_cast<AudioPlaylist> (pl);
if (apl) {
apl->get_equivalent_crossfades (basis, *equivs);
}
}
/* We might have just checked basis for equivalency with itself, so we need to remove dupes */
sort (equivs->begin (), equivs->end ());
unique (equivs->begin (), equivs->end ());
}
void
Editor::get_equivalent_regions (RegionView* basis, vector<RegionView*>& equivalent_regions, PBD::PropertyID property) const
{
@ -535,19 +514,6 @@ Editor::get_equivalent_regions (RegionSelection & basis, PBD::PropertyID prop) c
return equivalent;
}
vector<boost::shared_ptr<Crossfade> >
Editor::get_equivalent_crossfades (RouteTimeAxisView& v, boost::shared_ptr<Crossfade> c, PBD::PropertyID prop) const
{
vector<boost::shared_ptr<Crossfade> > e;
mapover_tracks_with_unique_playlists (
sigc::bind (sigc::mem_fun (*this, &Editor::mapped_get_equivalent_crossfades), c, &e),
&v,
prop
);
return e;
}
int
Editor::get_regionview_count_from_region_list (boost::shared_ptr<Region> region)
{
@ -698,7 +664,7 @@ Editor::set_selected_regionview_from_click (bool press, Selection::Operation op)
/* 2. figure out the boundaries for our search for new objects */
switch (clicked_regionview->region()->coverage (first_frame, last_frame)) {
case OverlapNone:
case Evoral::OverlapNone:
if (last_frame < clicked_regionview->region()->first_frame()) {
first_frame = last_frame;
last_frame = clicked_regionview->region()->last_frame();
@ -708,7 +674,7 @@ Editor::set_selected_regionview_from_click (bool press, Selection::Operation op)
}
break;
case OverlapExternal:
case Evoral::OverlapExternal:
if (last_frame < clicked_regionview->region()->first_frame()) {
first_frame = last_frame;
last_frame = clicked_regionview->region()->last_frame();
@ -718,7 +684,7 @@ Editor::set_selected_regionview_from_click (bool press, Selection::Operation op)
}
break;
case OverlapInternal:
case Evoral::OverlapInternal:
if (last_frame < clicked_regionview->region()->first_frame()) {
first_frame = last_frame;
last_frame = clicked_regionview->region()->last_frame();
@ -728,8 +694,8 @@ Editor::set_selected_regionview_from_click (bool press, Selection::Operation op)
}
break;
case OverlapStart:
case OverlapEnd:
case Evoral::OverlapStart:
case Evoral::OverlapEnd:
/* nothing to do except add clicked region to selection, since it
overlaps with the existing selection in this track.
*/
@ -965,6 +931,8 @@ Editor::track_selection_changed ()
break;
}
RouteNotificationListPtr routes (new RouteNotificationList);
for (TrackViewList::iterator i = track_views.begin(); i != track_views.end(); ++i) {
bool yn = (find (selection->tracks.begin(), selection->tracks.end(), *i) != selection->tracks.end());
@ -983,9 +951,21 @@ Editor::track_selection_changed ()
} else {
(*i)->hide_selection ();
}
if (yn) {
RouteTimeAxisView* rtav = dynamic_cast<RouteTimeAxisView*> (*i);
if (rtav) {
routes->push_back (rtav->route());
}
}
}
ActionManager::set_sensitive (ActionManager::track_selection_sensitive_actions, !selection->tracks.empty());
/* notify control protocols */
ControlProtocol::TrackSelectionChanged (routes);
}
void

View file

@ -54,7 +54,7 @@ EditorSummary::EditorSummary (Editor* e)
_old_follow_playhead (false)
{
Region::RegionPropertyChanged.connect (region_property_connection, invalidator (*this), boost::bind (&CairoWidget::set_dirty, this), gui_context());
_editor->playhead_cursor->PositionChanged.connect (position_connection, invalidator (*this), ui_bind (&EditorSummary::playhead_position_changed, this, _1), gui_context());
_editor->playhead_cursor->PositionChanged.connect (position_connection, invalidator (*this), boost::bind (&EditorSummary::playhead_position_changed, this, _1), gui_context());
add_events (Gdk::POINTER_MOTION_MASK);
}
@ -930,10 +930,10 @@ EditorSummary::routes_added (list<RouteTimeAxisView*> const & r)
{
for (list<RouteTimeAxisView*>::const_iterator i = r.begin(); i != r.end(); ++i) {
/* Connect to gui_changed() on the route so that we know when their colour has changed */
(*i)->route()->gui_changed.connect (*this, invalidator (*this), ui_bind (&EditorSummary::route_gui_changed, this, _1), gui_context ());
(*i)->route()->gui_changed.connect (*this, invalidator (*this), boost::bind (&EditorSummary::route_gui_changed, this, _1), gui_context ());
boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> ((*i)->route ());
if (tr) {
tr->PlaylistChanged.connect (*this, invalidator (*this), ui_bind (&CairoWidget::set_dirty, this), gui_context ());
tr->PlaylistChanged.connect (*this, invalidator (*this), boost::bind (&CairoWidget::set_dirty, this), gui_context ());
}
}

View file

@ -3,7 +3,7 @@
#define fader_cursor_height 25
#define fader_cursor_x_hot 3
#define fader_cursor_y_hot 21
static const gchar fader_cursor_bits[] = {
static const unsigned char fader_cursor_bits[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x30, 0x00,
0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0xfe, 0x01, 0x00, 0x00, 0x02, 0x01,
0x00, 0x00, 0x02, 0x01, 0x00, 0x00, 0x02, 0x01, 0x00, 0x00, 0x02, 0x01,
@ -15,7 +15,7 @@ static const gchar fader_cursor_bits[] = {
0x00, 0x00, 0x00, 0x00 };
/* Created with The GIMP */
static const gchar fader_cursor_mask_bits[] = {
static const unsigned char fader_cursor_mask_bits[] = {
0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x78, 0x00,
0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0xfe, 0x01, 0x00, 0x00, 0xfe, 0x01,
0x00, 0x00, 0xfe, 0x01, 0x00, 0x00, 0xfe, 0x01, 0x00, 0x00, 0xfe, 0x01,
@ -31,7 +31,7 @@ static const gchar fader_cursor_mask_bits[] = {
#define speaker_cursor_height 26
#define speaker_cursor_x_hot 0
#define speaker_cursor_y_hot 0
static const gchar speaker_cursor_bits[] = {
static const unsigned char speaker_cursor_bits[] = {
0x00, 0xc0, 0x00, 0xc0, 0x00, 0xf0, 0x00, 0xf0, 0x00, 0xcc, 0x00, 0xcc,
0xff, 0xc3, 0xff, 0xc3, 0x03, 0xc0, 0x03, 0xc0, 0xc3, 0xc0, 0xc3, 0xc0,
0xc3, 0xc0, 0xc3, 0xc0, 0xc3, 0xc0, 0xc3, 0xc0, 0x03, 0xc0, 0x03, 0xc0,
@ -42,7 +42,7 @@ static const gchar speaker_cursor_bits[] = {
#define speaker_cursor_mask_height 26
#define speaker_cursor_mask_x_hot 0
#define speaker_cursor_mask_y_hot 0
static const gchar speaker_cursor_mask_bits[] = {
static const unsigned char speaker_cursor_mask_bits[] = {
0x00, 0xc0, 0x00, 0xc0, 0x00, 0xf0, 0x00, 0xf0, 0x00, 0xfc, 0x00, 0xfc,
0xff, 0xff, 0xff, 0xff, 0x3f, 0xff, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0xff, 0x3f, 0xff,
@ -85,7 +85,7 @@ static const short cursor_timestretch_mask_bits[] = {
#define cursor_zoom_height 16
#define cursor_zoom_x_hot 6
#define cursor_zoom_y_hot 6
static const short cursor_zoom_bits[] = {
static const unsigned short cursor_zoom_bits[] = {
0x00e0, 0x0000, 0x03b8, 0x0000, 0x0604, 0x0000, 0x0806, 0x0000, 0x0842,
0x0000, 0x1843, 0x0000, 0x11f1, 0x0000, 0x1843, 0x0000, 0x0842, 0x0000,
0x1806, 0x0000, 0x2604, 0x0000, 0x4758, 0x0000, 0x88e0, 0x0000, 0x1000,
@ -95,7 +95,7 @@ static const short cursor_zoom_bits[] = {
#define cursor_zoom_mask_height 16
#define cursor_zoom_mask_x_hot 6
#define cursor_zoom_mask_y_hot 6
static const short cursor_zoom_mask_bits[] = {
static const unsigned short cursor_zoom_mask_bits[] = {
0x00e0, 0x0000, 0x03f8, 0x0000, 0x07fc, 0x0000, 0x0ffe, 0x0000, 0x0ffe,
0x0000, 0x1fff, 0x0000, 0x1fff, 0x0000, 0x1fff, 0x0000, 0x0ffe, 0x0000,
0x1ffe, 0x0000, 0x3ffc, 0x0000, 0x7ff8, 0x0000, 0xf8e0, 0x0000, 0xf000,

View file

@ -1107,6 +1107,9 @@ EngineControl::find_jack_servers (vector<string>& strings)
#endif
jack_servers = scanner (path, jack_server_filter, 0, false, true);
if (!jack_servers) {
return;
}
vector<string *>::iterator iter;

View file

@ -131,7 +131,7 @@ ExportFormatDialog::ExportFormatDialog (FormatPtr format, bool new_dialog) :
close_button = add_button (Gtk::Stock::SAVE, Gtk::RESPONSE_APPLY);
close_button->set_sensitive (false);
close_button->signal_clicked().connect (sigc::mem_fun (*this, &ExportFormatDialog::end_dialog));
manager.CompleteChanged.connect (*this, invalidator (*this), ui_bind (&Gtk::Button::set_sensitive, close_button, _1), gui_context());
manager.CompleteChanged.connect (*this, invalidator (*this), boost::bind (&Gtk::Button::set_sensitive, close_button, _1), gui_context());
with_cue.signal_toggled().connect (sigc::mem_fun (*this, &ExportFormatDialog::update_with_cue));
with_toc.signal_toggled().connect (sigc::mem_fun (*this, &ExportFormatDialog::update_with_toc));
@ -336,7 +336,7 @@ ExportFormatDialog::init_format_table ()
row[compatibility_cols.label] = (*it)->name();
WeakCompatPtr ptr (*it);
(*it)->SelectChanged.connect (*this, invalidator (*this), ui_bind (&ExportFormatDialog::change_compatibility_selection, this, _1, ptr), gui_context());
(*it)->SelectChanged.connect (*this, invalidator (*this), boost::bind (&ExportFormatDialog::change_compatibility_selection, this, _1, ptr), gui_context());
}
compatibility_view.append_column_editable ("", compatibility_cols.selected);
@ -364,8 +364,8 @@ ExportFormatDialog::init_format_table ()
row[quality_cols.label] = (*it)->name();
WeakQualityPtr ptr (*it);
(*it)->SelectChanged.connect (*this, invalidator (*this), ui_bind (&ExportFormatDialog::change_quality_selection, this, _1, ptr), gui_context());
(*it)->CompatibleChanged.connect (*this, invalidator (*this), ui_bind (&ExportFormatDialog::change_quality_compatibility, this, _1, ptr), gui_context());
(*it)->SelectChanged.connect (*this, invalidator (*this), boost::bind (&ExportFormatDialog::change_quality_selection, this, _1, ptr), gui_context());
(*it)->CompatibleChanged.connect (*this, invalidator (*this), boost::bind (&ExportFormatDialog::change_quality_compatibility, this, _1, ptr), gui_context());
}
quality_view.append_column ("", quality_cols.label);
@ -386,19 +386,19 @@ ExportFormatDialog::init_format_table ()
row[format_cols.label] = (*it)->name();
WeakFormatPtr ptr (*it);
(*it)->SelectChanged.connect (*this, invalidator (*this), ui_bind (&ExportFormatDialog::change_format_selection, this, _1, ptr), gui_context());
(*it)->CompatibleChanged.connect (*this, invalidator (*this), ui_bind (&ExportFormatDialog::change_format_compatibility, this, _1, ptr), gui_context());
(*it)->SelectChanged.connect (*this, invalidator (*this), boost::bind (&ExportFormatDialog::change_format_selection, this, _1, ptr), gui_context());
(*it)->CompatibleChanged.connect (*this, invalidator (*this), boost::bind (&ExportFormatDialog::change_format_compatibility, this, _1, ptr), gui_context());
/* Encoding options */
boost::shared_ptr<HasSampleFormat> hsf;
if (hsf = boost::dynamic_pointer_cast<HasSampleFormat> (*it)) {
hsf->SampleFormatSelectChanged.connect (*this, invalidator (*this), ui_bind (&ExportFormatDialog::change_sample_format_selection, this, _1, _2), gui_context());
hsf->SampleFormatCompatibleChanged.connect (*this, invalidator (*this), ui_bind (&ExportFormatDialog::change_sample_format_compatibility, this, _1, _2), gui_context());
hsf->SampleFormatSelectChanged.connect (*this, invalidator (*this), boost::bind (&ExportFormatDialog::change_sample_format_selection, this, _1, _2), gui_context());
hsf->SampleFormatCompatibleChanged.connect (*this, invalidator (*this), boost::bind (&ExportFormatDialog::change_sample_format_compatibility, this, _1, _2), gui_context());
hsf->DitherTypeSelectChanged.connect (*this, invalidator (*this), ui_bind (&ExportFormatDialog::change_dither_type_selection, this, _1, _2), gui_context());
hsf->DitherTypeCompatibleChanged.connect (*this, invalidator (*this), ui_bind (&ExportFormatDialog::change_dither_type_compatibility, this, _1, _2), gui_context());
hsf->DitherTypeSelectChanged.connect (*this, invalidator (*this), boost::bind (&ExportFormatDialog::change_dither_type_selection, this, _1, _2), gui_context());
hsf->DitherTypeCompatibleChanged.connect (*this, invalidator (*this), boost::bind (&ExportFormatDialog::change_dither_type_compatibility, this, _1, _2), gui_context());
}
}
@ -420,8 +420,8 @@ ExportFormatDialog::init_format_table ()
row[sample_rate_cols.label] = (*it)->name();
WeakSampleRatePtr ptr (*it);
(*it)->SelectChanged.connect (*this, invalidator (*this), ui_bind (&ExportFormatDialog::change_sample_rate_selection, this, _1, ptr), gui_context());
(*it)->CompatibleChanged.connect (*this, invalidator (*this), ui_bind (&ExportFormatDialog::change_sample_rate_compatibility, this, _1, ptr), gui_context());
(*it)->SelectChanged.connect (*this, invalidator (*this), boost::bind (&ExportFormatDialog::change_sample_rate_selection, this, _1, ptr), gui_context());
(*it)->CompatibleChanged.connect (*this, invalidator (*this), boost::bind (&ExportFormatDialog::change_sample_rate_compatibility, this, _1, ptr), gui_context());
}
sample_rate_view.append_column ("", sample_rate_cols.label);

View file

@ -192,7 +192,7 @@ GainMeterBase::set_controls (boost::shared_ptr<Route> r,
if (amp) {
amp->ConfigurationChanged.connect (
model_connections, invalidator (*this), ui_bind (&GainMeterBase::setup_gain_adjustment, this), gui_context ()
model_connections, invalidator (*this), boost::bind (&GainMeterBase::setup_gain_adjustment, this), gui_context ()
);
}
@ -905,7 +905,7 @@ GainMeter::set_controls (boost::shared_ptr<Route> r,
if (_meter) {
_meter->ConfigurationChanged.connect (
model_connections, invalidator (*this), ui_bind (&GainMeter::meter_configuration_changed, this, _1), gui_context()
model_connections, invalidator (*this), boost::bind (&GainMeter::meter_configuration_changed, this, _1), gui_context()
);
meter_configuration_changed (_meter->input_streams ());

View file

@ -101,6 +101,9 @@ GenericPluginUI::GenericPluginUI (boost::shared_ptr<PluginInsert> pi, bool scrol
VBox* v1_box = manage (new VBox);
VBox* v2_box = manage (new VBox);
pack_end (plugin_analysis_expander, false, false);
if (!plugin->get_docs().empty()) {
pack_end (description_expander, false, false);
}
v1_box->pack_start (*smaller_hbox, false, true);
v2_box->pack_start (focus_button, false, true);
@ -264,6 +267,11 @@ GenericPluginUI::build ()
continue;
}
const std::string param_docs = plugin->get_parameter_docs(i);
if (!param_docs.empty()) {
ARDOUR_UI::instance()->set_tip(cui, param_docs.c_str());
}
if (cui->controller || cui->clickbox || cui->combo) {
// Get all of the controls into a list, so that
// we can lay them out a bit more nicely later.

View file

@ -81,7 +81,7 @@ ImageFrameTimeAxis::ImageFrameTimeAxis(const string & track_id, PublicEditor& ed
// set the initial height of this time axis
set_height(hNormal) ;
TimeAxisView::CatchDeletion.connect (*this, ui_bind (&ImageFrameTimeAxis::remove_time_axis_view, this, _1), gui_context());
TimeAxisView::CatchDeletion.connect (*this, boost::bind (&ImageFrameTimeAxis::remove_time_axis_view, this, _1), gui_context());
}
/**

View file

@ -52,7 +52,7 @@ ImageFrameTimeAxisGroup::ImageFrameTimeAxisGroup(ImageFrameTimeAxisView& iftav,
selected_imageframe_item = 0;
is_selected = false;
ImageFrameView::CatchDeletion.connect (*this, ui_bind (&ImageFrameTimeAxisGroup::remove_imageframe_item, this, _1), gui_context());
ImageFrameView::CatchDeletion.connect (*this, boost::bind (&ImageFrameTimeAxisGroup::remove_imageframe_item, this, _1), gui_context());
}
/**

View file

@ -67,7 +67,7 @@ ImageFrameTimeAxisView::ImageFrameTimeAxisView (ImageFrameTimeAxis& tv)
selected_imageframe_group = 0 ;
selected_imageframe_view = 0 ;
ImageFrameTimeAxisGroup::CatchDeletion.connect (*this, ui_bind (&ImageFrameTimeAxisView::remove_imageframe_group, this, _1), gui_context());
ImageFrameTimeAxisGroup::CatchDeletion.connect (*this, boost::bind (&ImageFrameTimeAxisView::remove_imageframe_group, this, _1), gui_context());
}
/**

View file

@ -104,7 +104,7 @@ ImageFrameView::ImageFrameView(const string & item_id,
set_position(start, this);
set_duration(duration, this);
MarkerView::CatchDeletion.connect (*this, ui_bind (&ImageFrameView::remove_marker_view_item, this, _1), gui_context());
MarkerView::CatchDeletion.connect (*this, boost::bind (&ImageFrameView::remove_marker_view_item, this, _1), gui_context());
}
/**

View file

@ -193,9 +193,7 @@ KeyEditor::on_key_release_event (GdkEventKey* ev)
goto out;
}
cerr << "real lkeyval: " << ev->keyval << endl;
Gtkmm2ext::possibly_translate_keyval_to_make_legal_accelerator (ev->keyval);
cerr << "using keyval = " << ev->keyval << endl;
bool result = AccelMap::change_entry (path,
@ -203,8 +201,6 @@ KeyEditor::on_key_release_event (GdkEventKey* ev)
ModifierType (Keyboard::RelevantModifierKeyMask & ev->state),
true);
cerr << "New binding to " << ev->keyval << " worked: " << result << endl;
if (result) {
AccelKey key;
(*i)[columns.binding] = ActionManager::get_key_representation (path, key);

View file

@ -59,7 +59,7 @@ LevelMeter::LevelMeter (Session* s)
{
set_session (s);
set_spacing (1);
Config->ParameterChanged.connect (_parameter_connection, invalidator (*this), ui_bind (&LevelMeter::parameter_changed, this, _1), gui_context());
Config->ParameterChanged.connect (_parameter_connection, invalidator (*this), boost::bind (&LevelMeter::parameter_changed, this, _1), gui_context());
UI::instance()->theme_changed.connect (sigc::mem_fun(*this, &LevelMeter::on_theme_changed));
ColorsChanged.connect (sigc::mem_fun (*this, &LevelMeter::color_handler));
max_peak = minus_infinity();
@ -85,7 +85,7 @@ LevelMeter::set_meter (PeakMeter* meter)
_meter = meter;
if (_meter) {
_meter->ConfigurationChanged.connect (_configuration_connection, invalidator (*this), ui_bind (&LevelMeter::configuration_changed, this, _1, _2), gui_context());
_meter->ConfigurationChanged.connect (_configuration_connection, invalidator (*this), boost::bind (&LevelMeter::configuration_changed, this, _1, _2), gui_context());
}
}

View file

@ -328,13 +328,13 @@ LocationEditRow::set_location (Location *loc)
--i_am_the_modifier;
location->start_changed.connect (connections, invalidator (*this), ui_bind (&LocationEditRow::start_changed, this, _1), gui_context());
location->end_changed.connect (connections, invalidator (*this), ui_bind (&LocationEditRow::end_changed, this, _1), gui_context());
location->name_changed.connect (connections, invalidator (*this), ui_bind (&LocationEditRow::name_changed, this, _1), gui_context());
location->changed.connect (connections, invalidator (*this), ui_bind (&LocationEditRow::location_changed, this, _1), gui_context());
location->FlagsChanged.connect (connections, invalidator (*this), ui_bind (&LocationEditRow::flags_changed, this, _1, _2), gui_context());
location->LockChanged.connect (connections, invalidator (*this), ui_bind (&LocationEditRow::lock_changed, this, _1), gui_context());
location->PositionLockStyleChanged.connect (connections, invalidator (*this), ui_bind (&LocationEditRow::position_lock_style_changed, this, _1), gui_context());
location->start_changed.connect (connections, invalidator (*this), boost::bind (&LocationEditRow::start_changed, this, _1), gui_context());
location->end_changed.connect (connections, invalidator (*this), boost::bind (&LocationEditRow::end_changed, this, _1), gui_context());
location->name_changed.connect (connections, invalidator (*this), boost::bind (&LocationEditRow::name_changed, this, _1), gui_context());
location->changed.connect (connections, invalidator (*this), boost::bind (&LocationEditRow::location_changed, this, _1), gui_context());
location->FlagsChanged.connect (connections, invalidator (*this), boost::bind (&LocationEditRow::flags_changed, this, _1, _2), gui_context());
location->LockChanged.connect (connections, invalidator (*this), boost::bind (&LocationEditRow::lock_changed, this, _1), gui_context());
location->PositionLockStyleChanged.connect (connections, invalidator (*this), boost::bind (&LocationEditRow::position_lock_style_changed, this, _1), gui_context());
}
void
@ -1056,8 +1056,8 @@ LocationUI::set_session(ARDOUR::Session* s)
if (_session) {
_session->locations()->changed.connect (_session_connections, invalidator (*this), boost::bind (&LocationUI::locations_changed, this, _1), gui_context());
_session->locations()->StateChanged.connect (_session_connections, invalidator (*this), boost::bind (&LocationUI::refresh_location_list, this), gui_context());
_session->locations()->added.connect (_session_connections, invalidator (*this), ui_bind (&LocationUI::location_added, this, _1), gui_context());
_session->locations()->removed.connect (_session_connections, invalidator (*this), ui_bind (&LocationUI::location_removed, this, _1), gui_context());
_session->locations()->added.connect (_session_connections, invalidator (*this), boost::bind (&LocationUI::location_added, this, _1), gui_context());
_session->locations()->removed.connect (_session_connections, invalidator (*this), boost::bind (&LocationUI::location_removed, this, _1), gui_context());
_clock_group->set_clock_mode (clock_mode_from_session_instant_xml ());
}

View file

@ -20,12 +20,13 @@
#include "ardour/lv2_plugin.h"
#include "ardour/plugin_manager.h"
#include "ardour/processor.h"
#include "ardour/session.h"
#include "ardour_ui.h"
#include "gui_thread.h"
#include "lv2_plugin_ui.h"
#include "lv2_ui.h"
#include "lv2/lv2plug.in/ns/extensions/ui/ui.h"
#include <lilv/lilv.h>
#include <suil/suil.h>
@ -68,13 +69,36 @@ LV2PluginUI::write_to_ui(void* controller,
const void* buffer)
{
LV2PluginUI* me = (LV2PluginUI*)controller;
if (me->_inst) {
suil_instance_port_event((SuilInstance*)me->_inst,
port_index, buffer_size, format, buffer);
}
}
uint32_t
LV2PluginUI::port_index(void* controller, const char* symbol)
{
return ((LV2PluginUI*)controller)->_lv2->port_index(symbol);
}
void
LV2PluginUI::touch(void* controller,
uint32_t port_index,
bool grabbed)
{
LV2PluginUI* me = (LV2PluginUI*)controller;
if (port_index >= me->_controllables.size()) {
return;
}
ControllableRef control = me->_controllables[port_index];
if (grabbed) {
control->start_touch(control->session().transport_frame());
} else {
control->stop_touch(false, control->session().transport_frame());
}
}
void
LV2PluginUI::update_timeout()
{
@ -196,7 +220,10 @@ LV2PluginUI::lv2ui_instantiate(const std::string& title)
}
if (!ui_host) {
ui_host = suil_host_new(LV2PluginUI::write_from_ui, NULL, NULL, NULL);
ui_host = suil_host_new(LV2PluginUI::write_from_ui,
LV2PluginUI::port_index,
NULL, NULL);
suil_host_set_touch_func(ui_host, LV2PluginUI::touch);
}
const char* container_type = (is_external_ui)
? NS_UI "external"
@ -245,7 +272,7 @@ LV2PluginUI::lv2ui_instantiate(const std::string& title)
pack_start(*_ardour_buttons_box, false, false);
GtkWidget* c_widget = (GtkWidget*)GET_WIDGET(_inst);
_gui_widget = Glib::wrap(c_widget);
_gui_widget = Gtk::manage(Glib::wrap(c_widget));
_gui_widget->show_all();
pack_start(*_gui_widget, true, true);
} else {
@ -283,18 +310,13 @@ LV2PluginUI::lv2ui_free()
if (_gui_widget) {
remove (*_gui_widget);
_gui_widget = NULL;
}
if (_ardour_buttons_box) {
remove (*_ardour_buttons_box);
delete _ardour_buttons_box;
_ardour_buttons_box = 0;
if (_inst) {
suil_instance_free((SuilInstance*)_inst);
_inst = NULL;
}
suil_instance_free((SuilInstance*)_inst);
_inst = NULL;
_gui_widget = NULL;
}
LV2PluginUI::~LV2PluginUI ()

View file

@ -94,6 +94,12 @@ class LV2PluginUI : public PlugUIBase, public Gtk::VBox
uint32_t format,
const void* buffer);
static uint32_t port_index(void* controller, const char* symbol);
static void touch(void* controller,
uint32_t port_index,
bool grabbed);
void update_timeout();
void lv2ui_instantiate(const std::string& title);

View file

@ -1,241 +0,0 @@
/* LV2 UI Extension
* Copyright (C) 2006-2008 Lars Luthman <lars.luthman@gmail.com>
* Copyright (C) 2009-2010 David Robillard <d@drobilla.net>
*
* Based on lv2.h, which was
* Copyright (C) 2000-2002 Richard W.E. Furse, Paul Barton-Davis,
* Stefan Westerfeld
* Copyright (C) 2006 Steve Harris, David Robillard.
*
* This header is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation; either version 2.1 of the License,
* or (at your option) any later version.
*
* This header 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
* USA.
*
*/
/** @file
* C header for the LV2 UI extension <http://lv2plug.in/ns/extensions/ui>.
*/
#ifndef LV2_UI_H
#define LV2_UI_H
#include "lv2.h"
#define LV2_UI_URI "http://lv2plug.in/ns/extensions/ui"
#ifdef __cplusplus
extern "C" {
#endif
/** A pointer to some widget or other type of UI handle.
The actual type is defined by the type URI of the UI.
All the functionality provided by this extension is toolkit
independent, the host only needs to pass the necessary callbacks and
display the widget, if possible. Plugins may have several UIs, in various
toolkits. */
typedef void* LV2UI_Widget;
/** A pointer to a particular instance of a UI.
It is valid to compare this to NULL (0 for C++) but otherwise the
host MUST not attempt to interpret it. The UI plugin may use it to
reference internal instance data. */
typedef void* LV2UI_Handle;
/** A pointer to a particular plugin controller, provided by the host.
It is valid to compare this to NULL (0 for C++) but otherwise the
UI plugin MUST not attempt to interpret it. The host may use it to
reference internal instance data. */
typedef void* LV2UI_Controller;
/** The type of the host-provided function that the UI can use to
send data to a plugin's input ports. The @c buffer parameter must point
to a block of data, @c buffer_size bytes large. The contents of this buffer
and what the host should do with it depends on the value of the @c format
parameter.
The @c format parameter should either be 0 or a numeric ID for a "Transfer
mechanism". Transfer mechanisms are Features and may be defined in
meta-extensions. They specify how to translate the data buffers passed
to this function to input data for the plugin ports. If a UI wishes to
write data to an input port, it must list a transfer mechanism Feature
for that port's class as an optional or required feature (depending on
whether the UI will work without being able to write to that port or not).
The only exception is when the UI wants to write single float values to
input ports of the class lv2:ControlPort, in which case @c buffer_size
should always be 4, the buffer should always contain a single IEEE-754
float, and @c format should be 0.
The numeric IDs for the transfer mechanisms are provided by a
URI-to-integer mapping function provided by the host, using the URI Map
feature <http://lv2plug.in/ns/ext/uri-map> with the map URI
"http://lv2plug.in/ns/extensions/ui". Thus a UI that requires transfer
mechanism features also requires the URI Map feature, but this is
implicit - the UI does not have to list the URI map feature as a required
or optional feature in it's RDF data.
An UI MUST NOT pass a @c format parameter value (except 0) that has not
been returned by the host-provided URI mapping function for a
host-supported transfer mechanism feature URI.
The UI MUST NOT try to write to a port for which there is no specified
transfer mechanism, or to an output port. The UI is responsible for
allocating the buffer and deallocating it after the call.
*/
typedef void (*LV2UI_Write_Function)(LV2UI_Controller controller,
uint32_t port_index,
uint32_t buffer_size,
uint32_t format,
const void* buffer);
/** This struct contains the implementation of a UI. A pointer to an
object of this type is returned by the lv2ui_descriptor() function.
*/
typedef struct _LV2UI_Descriptor {
/** The URI for this UI (not for the plugin it controls). */
const char* URI;
/** Create a new UI object and return a handle to it. This function works
similarly to the instantiate() member in LV2_Descriptor.
@param descriptor The descriptor for the UI that you want to instantiate.
@param plugin_uri The URI of the plugin that this UI will control.
@param bundle_path The path to the bundle containing the RDF data file
that references this shared object file, including the
trailing '/'.
@param write_function A function provided by the host that the UI can
use to send data to the plugin's input ports.
@param controller A handle for the plugin instance that should be passed
as the first parameter of @c write_function.
@param widget A pointer to an LV2UI_Widget. The UI will write a
widget pointer to this location (what type of widget
depends on the RDF class of the UI) that will be the
main UI widget.
@param features An array of LV2_Feature pointers. The host must pass
all feature URIs that it and the UI supports and any
additional data, just like in the LV2 plugin
instantiate() function. Note that UI features and plugin
features are NOT necessarily the same, they just share
the same data structure - this will probably not be the
same array as the one the plugin host passes to a
plugin.
*/
LV2UI_Handle (*instantiate)(const struct _LV2UI_Descriptor* descriptor,
const char* plugin_uri,
const char* bundle_path,
LV2UI_Write_Function write_function,
LV2UI_Controller controller,
LV2UI_Widget* widget,
const LV2_Feature* const* features);
/** Destroy the UI object and the associated widget. The host must not try
to access the widget after calling this function.
*/
void (*cleanup)(LV2UI_Handle ui);
/** Tell the UI that something interesting has happened at a plugin port.
What is interesting and how it is written to the buffer passed to this
function is defined by the @c format parameter, which has the same
meaning as in LV2UI_Write_Function. The only exception is ports of the
class lv2:ControlPort, for which this function should be called
when the port value changes (it does not have to be called for every
single change if the host's UI thread has problems keeping up with the
thread the plugin is running in), @c buffer_size should be 4, the buffer
should contain a single IEEE-754 float, and @c format should be 0.
By default, the host should only call this function for input ports of
the lv2:ControlPort class. However, the default setting can be modified
by using the following URIs in the UI's RDF data:
<pre>
uiext:portNotification
uiext:noPortNotification
uiext:plugin
uiext:portIndex
</pre>
For example, if you want the UI with uri
<code><http://my.pluginui></code> for the plugin with URI
<code><http://my.plugin></code> to get notified when the value of the
output control port with index 4 changes, you would use the following
in the RDF for your UI:
<pre>
<http://my.pluginui> uiext:portNotification [ uiext:plugin <http://my.plugin> ;
uiext:portIndex 4 ] .
</pre>
and similarly with <code>uiext:noPortNotification</code> if you wanted
to prevent notifications for a port for which it would be on by default
otherwise. The UI is not allowed to request notifications for ports of
types for which no transfer mechanism is specified, if it does it should
be considered broken and the host should not load it.
The @c buffer is only valid during the time of this function call, so if
the UI wants to keep it for later use it has to copy the contents to an
internal buffer.
This member may be set to NULL if the UI is not interested in any
port events.
*/
void (*port_event)(LV2UI_Handle ui,
uint32_t port_index,
uint32_t buffer_size,
uint32_t format,
const void* buffer);
/** Returns a data structure associated with an extension URI, for example
a struct containing additional function pointers. Avoid returning
function pointers directly since standard C/C++ has no valid way of
casting a void* to a function pointer. This member may be set to NULL
if the UI is not interested in supporting any extensions. This is similar
to the extension_data() member in LV2_Descriptor.
*/
const void* (*extension_data)(const char* uri);
} LV2UI_Descriptor;
/** A plugin UI programmer must include a function called "lv2ui_descriptor"
with the following function prototype within the shared object
file. This function will have C-style linkage (if you are using
C++ this is taken care of by the 'extern "C"' clause at the top of
the file). This function will be accessed by the UI host using the
@c dlsym() function and called to get a LV2UI_UIDescriptor for the
wanted plugin.
Just like lv2_descriptor(), this function takes an index parameter. The
index should only be used for enumeration and not as any sort of ID number -
the host should just iterate from 0 and upwards until the function returns
NULL or a descriptor with an URI matching the one the host is looking for.
*/
const LV2UI_Descriptor* lv2ui_descriptor(uint32_t index);
/** This is the type of the lv2ui_descriptor() function. */
typedef const LV2UI_Descriptor* (*LV2UI_DescriptorFunction)(uint32_t index);
#ifdef __cplusplus
}
#endif
#endif

View file

@ -67,7 +67,7 @@ MarkerTimeAxisView::MarkerTimeAxisView(MarkerTimeAxis& tv)
_samples_per_unit = _trackview.editor.get_current_zoom() ;
_trackview.editor.ZoomChanged.connect (sigc::mem_fun(*this, &MarkerTimeAxisView::reset_samples_per_unit));
MarkerView::CatchDeletion.connect (*this, ui_bind (&MarkerTimeAxisView::remove_marker_view, this, _1), gui_context());
MarkerView::CatchDeletion.connect (*this, boost::bind (&MarkerTimeAxisView::remove_marker_view, this, _1), gui_context());
}
/**

View file

@ -180,8 +180,8 @@ MidiListEditor::scroll_event (GdkEventScroll* ev)
TreeViewColumn* col;
int cellx;
int celly;
int idelta;
double fdelta;
int idelta = 0;
double fdelta = 0;
MidiModel::NoteDiffCommand::Property prop (MidiModel::NoteDiffCommand::NoteNumber);
bool apply = false;
bool was_selected = false;
@ -586,8 +586,8 @@ MidiListEditor::edited (const std::string& path, const std::string& text)
double fval;
int ival;
bool apply = false;
int idelta;
double fdelta;
int idelta = 0;
double fdelta = 0;
char* opname;
switch (edit_column) {
case 0: // start

View file

@ -116,10 +116,10 @@ MidiRegionView::MidiRegionView (ArdourCanvas::Group *parent, RouteTimeAxisView &
_note_group->raise_to_top();
PublicEditor::DropDownKeys.connect (sigc::mem_fun (*this, &MidiRegionView::drop_down_keys));
Config->ParameterChanged.connect (*this, invalidator (*this), ui_bind (&MidiRegionView::parameter_changed, this, _1), gui_context());
Config->ParameterChanged.connect (*this, invalidator (*this), boost::bind (&MidiRegionView::parameter_changed, this, _1), gui_context());
connect_to_diskstream ();
SelectionCleared.connect (_selection_cleared_connection, invalidator (*this), ui_bind (&MidiRegionView::selection_cleared, this, _1), gui_context ());
SelectionCleared.connect (_selection_cleared_connection, invalidator (*this), boost::bind (&MidiRegionView::selection_cleared, this, _1), gui_context ());
}
MidiRegionView::MidiRegionView (ArdourCanvas::Group *parent, RouteTimeAxisView &tv,
@ -155,7 +155,7 @@ MidiRegionView::MidiRegionView (ArdourCanvas::Group *parent, RouteTimeAxisView &
connect_to_diskstream ();
SelectionCleared.connect (_selection_cleared_connection, invalidator (*this), ui_bind (&MidiRegionView::selection_cleared, this, _1), gui_context ());
SelectionCleared.connect (_selection_cleared_connection, invalidator (*this), boost::bind (&MidiRegionView::selection_cleared, this, _1), gui_context ());
}
void
@ -245,7 +245,7 @@ MidiRegionView::init (Gdk::Color const & basic_color, bool wfd)
PublicEditor::DropDownKeys.connect (sigc::mem_fun (*this, &MidiRegionView::drop_down_keys));
CanvasNoteEvent::CanvasNoteEventDeleted.connect (note_delete_connection, MISSING_INVALIDATOR,
ui_bind (&MidiRegionView::maybe_remove_deleted_note_from_selection, this, _1),
boost::bind (&MidiRegionView::maybe_remove_deleted_note_from_selection, this, _1),
gui_context());
if (wfd) {
@ -288,13 +288,13 @@ MidiRegionView::init (Gdk::Color const & basic_color, bool wfd)
sigc::mem_fun(this, &MidiRegionView::midi_patch_settings_changed));
trackview.editor().SnapChanged.connect(snap_changed_connection, invalidator(*this),
ui_bind(&MidiRegionView::snap_changed, this),
boost::bind (&MidiRegionView::snap_changed, this),
gui_context());
Config->ParameterChanged.connect (*this, invalidator (*this), ui_bind (&MidiRegionView::parameter_changed, this, _1), gui_context());
Config->ParameterChanged.connect (*this, invalidator (*this), boost::bind (&MidiRegionView::parameter_changed, this, _1), gui_context());
connect_to_diskstream ();
SelectionCleared.connect (_selection_cleared_connection, invalidator (*this), ui_bind (&MidiRegionView::selection_cleared, this, _1), gui_context ());
SelectionCleared.connect (_selection_cleared_connection, invalidator (*this), boost::bind (&MidiRegionView::selection_cleared, this, _1), gui_context ());
}
const boost::shared_ptr<ARDOUR::MidiRegion>
@ -308,7 +308,7 @@ MidiRegionView::connect_to_diskstream ()
{
midi_view()->midi_track()->DataRecorded.connect(
*this, invalidator(*this),
ui_bind(&MidiRegionView::data_recorded, this, _1),
boost::bind (&MidiRegionView::data_recorded, this, _1),
gui_context());
}
@ -380,7 +380,7 @@ bool
MidiRegionView::enter_notify (GdkEventCrossing* ev)
{
trackview.editor().MouseModeChanged.connect (
_mouse_mode_connection, invalidator (*this), ui_bind (&MidiRegionView::mouse_mode_changed, this), gui_context ()
_mouse_mode_connection, invalidator (*this), boost::bind (&MidiRegionView::mouse_mode_changed, this), gui_context ()
);
if (trackview.editor().current_mouse_mode() == MouseDraw && _mouse_state != AddDragging) {
@ -1396,7 +1396,7 @@ MidiRegionView::add_ghost (TimeAxisView& tv)
ghost->set_duration (_region->length() / samples_per_unit);
ghosts.push_back (ghost);
GhostRegion::CatchDeletion.connect (*this, invalidator (*this), ui_bind (&RegionView::remove_ghost, this, _1), gui_context());
GhostRegion::CatchDeletion.connect (*this, invalidator (*this), boost::bind (&RegionView::remove_ghost, this, _1), gui_context());
return ghost;
}
@ -2953,7 +2953,7 @@ MidiRegionView::nudge_notes (bool forward)
framepos_t ref_point = source_beats_to_absolute_frames ((*(_selection.begin()))->note()->time());
framepos_t unused;
framepos_t distance;
framecnt_t distance;
if (trackview.editor().snap_mode() == Editing::SnapOff) {

View file

@ -24,7 +24,7 @@
MidiRegionSelection::MidiRegionSelection ()
{
RegionView::RegionViewGoingAway.connect (_death_connection, MISSING_INVALIDATOR, ui_bind (&MidiRegionSelection::remove_it, this, _1), gui_context());
RegionView::RegionViewGoingAway.connect (_death_connection, MISSING_INVALIDATOR, boost::bind (&MidiRegionSelection::remove_it, this, _1), gui_context());
}
/** Copy constructor.
@ -33,7 +33,7 @@ MidiRegionSelection::MidiRegionSelection ()
MidiRegionSelection::MidiRegionSelection (MidiRegionSelection const & other)
: std::list<MidiRegionView*> (other)
{
RegionView::RegionViewGoingAway.connect (_death_connection, MISSING_INVALIDATOR, ui_bind (&MidiRegionSelection::remove_it, this, _1), gui_context());
RegionView::RegionViewGoingAway.connect (_death_connection, MISSING_INVALIDATOR, boost::bind (&MidiRegionSelection::remove_it, this, _1), gui_context());
}

View file

@ -63,7 +63,6 @@
#include "automation_time_axis.h"
#include "canvas-note-event.h"
#include "canvas_impl.h"
#include "crossfade_view.h"
#include "editor.h"
#include "enums.h"
#include "ghostregion.h"
@ -160,7 +159,7 @@ MidiTimeAxisView::set_route (boost::shared_ptr<Route> rt)
processors_changed (RouteProcessorChange ());
_route->processors_changed.connect (*this, invalidator (*this), ui_bind (&MidiTimeAxisView::processors_changed, this, _1), gui_context());
_route->processors_changed.connect (*this, invalidator (*this), boost::bind (&MidiTimeAxisView::processors_changed, this, _1), gui_context());
if (is_track()) {
_piano_roll_header->SetNoteSelection.connect (sigc::mem_fun (*this, &MidiTimeAxisView::set_note_selection));
@ -314,7 +313,6 @@ MidiTimeAxisView::model_changed()
for (std::list<std::string>::const_iterator i = device_modes.begin();
i != device_modes.end(); ++i) {
cerr << "found custom device mode " << *i << " thread_id: " << pthread_self() << endl;
_custom_device_mode_selector.append_text(*i);
}

View file

@ -112,7 +112,7 @@ MixerStrip::MixerStrip (Mixer_UI& mx, Session* sess, boost::shared_ptr<Route> rt
, RouteUI (sess)
, _mixer(mx)
, _mixer_owned (in_mixer)
, processor_box (sess, sigc::mem_fun(*this, &MixerStrip::plugin_selector), mx.selection(), this, in_mixer)
, processor_box (sess, boost::bind (&MixerStrip::plugin_selector, this), mx.selection(), this, in_mixer)
, gpm (sess, 250)
, panners (sess)
, button_size_group (Gtk::SizeGroup::create (Gtk::SIZE_GROUP_HORIZONTAL))
@ -355,7 +355,7 @@ MixerStrip::init ()
parameter_changed (X_("mixer-strip-visibility"));
Config->ParameterChanged.connect (_config_connection, MISSING_INVALIDATOR, ui_bind (&MixerStrip::parameter_changed, this, _1), gui_context());
Config->ParameterChanged.connect (_config_connection, MISSING_INVALIDATOR, boost::bind (&MixerStrip::parameter_changed, this, _1), gui_context());
gpm.LevelMeterButtonPress.connect_same_thread (_level_meter_connection, boost::bind (&MixerStrip::level_meter_button_press, this, _1));
}
@ -509,8 +509,8 @@ MixerStrip::set_route (boost::shared_ptr<Route> rt)
audio_track()->DiskstreamChanged.connect (route_connections, invalidator (*this), boost::bind (&MixerStrip::diskstream_changed, this), gui_context());
}
_route->comment_changed.connect (route_connections, invalidator (*this), ui_bind (&MixerStrip::comment_changed, this, _1), gui_context());
_route->PropertyChanged.connect (route_connections, invalidator (*this), ui_bind (&MixerStrip::property_changed, this, _1), gui_context());
_route->comment_changed.connect (route_connections, invalidator (*this), boost::bind (&MixerStrip::comment_changed, this, _1), gui_context());
_route->PropertyChanged.connect (route_connections, invalidator (*this), boost::bind (&MixerStrip::property_changed, this, _1), gui_context());
set_stuff_from_route ();

View file

@ -95,7 +95,7 @@ Mixer_UI::Mixer_UI ()
strip_redisplay_does_not_sync_order_keys = false;
ignore_sync = false;
Route::SyncOrderKeys.connect (*this, invalidator (*this), ui_bind (&Mixer_UI::sync_order_keys, this, _1), gui_context());
Route::SyncOrderKeys.connect (*this, invalidator (*this), boost::bind (&Mixer_UI::sync_order_keys, this, _1), gui_context());
scroller_base.set_flags (Gtk::CAN_FOCUS);
scroller_base.add_events (Gdk::BUTTON_PRESS_MASK|Gdk::BUTTON_RELEASE_MASK);
@ -239,7 +239,7 @@ Mixer_UI::Mixer_UI ()
_in_group_rebuild_or_clear = false;
MixerStrip::CatchDeletion.connect (*this, invalidator (*this), ui_bind (&Mixer_UI::remove_strip, this, _1), gui_context());
MixerStrip::CatchDeletion.connect (*this, invalidator (*this), boost::bind (&Mixer_UI::remove_strip, this, _1), gui_context());
MonitorSection::setup_knob_images ();
@ -340,7 +340,7 @@ Mixer_UI::add_strip (RouteList& routes)
_monitor_section->set_session (_session);
_monitor_section->tearoff().show_all ();
route->DropReferences.connect (*this, invalidator(*this), ui_bind (&Mixer_UI::monitor_section_going_away, this), gui_context());
route->DropReferences.connect (*this, invalidator(*this), boost::bind (&Mixer_UI::monitor_section_going_away, this), gui_context());
/* no regular strip shown for control out */
@ -368,7 +368,7 @@ Mixer_UI::add_strip (RouteList& routes)
route->set_order_key (N_("signal"), track_model->children().size()-1);
}
route->PropertyChanged.connect (*this, invalidator (*this), ui_bind (&Mixer_UI::strip_property_changed, this, _1, strip), gui_context());
route->PropertyChanged.connect (*this, invalidator (*this), boost::bind (&Mixer_UI::strip_property_changed, this, _1, strip), gui_context());
strip->WidthChanged.connect (sigc::mem_fun(*this, &Mixer_UI::strip_width_changed));
strip->signal_button_release_event().connect (sigc::bind (sigc::mem_fun(*this, &Mixer_UI::strip_button_release_event), strip));
@ -583,15 +583,15 @@ Mixer_UI::set_session (Session* sess)
initial_track_display ();
_session->RouteAdded.connect (_session_connections, invalidator (*this), ui_bind (&Mixer_UI::add_strip, this, _1), gui_context());
_session->route_group_added.connect (_session_connections, invalidator (*this), ui_bind (&Mixer_UI::add_route_group, this, _1), gui_context());
_session->RouteAdded.connect (_session_connections, invalidator (*this), boost::bind (&Mixer_UI::add_strip, this, _1), gui_context());
_session->route_group_added.connect (_session_connections, invalidator (*this), boost::bind (&Mixer_UI::add_route_group, this, _1), gui_context());
_session->route_group_removed.connect (_session_connections, invalidator (*this), boost::bind (&Mixer_UI::route_groups_changed, this), gui_context());
_session->route_groups_reordered.connect (_session_connections, invalidator (*this), boost::bind (&Mixer_UI::route_groups_changed, this), gui_context());
_session->config.ParameterChanged.connect (_session_connections, invalidator (*this), ui_bind (&Mixer_UI::parameter_changed, this, _1), gui_context());
_session->config.ParameterChanged.connect (_session_connections, invalidator (*this), boost::bind (&Mixer_UI::parameter_changed, this, _1), gui_context());
_session->DirtyChanged.connect (_session_connections, invalidator (*this), boost::bind (&Mixer_UI::update_title, this), gui_context());
_session->StateSaved.connect (_session_connections, invalidator (*this), ui_bind (&Mixer_UI::update_title, this), gui_context());
_session->StateSaved.connect (_session_connections, invalidator (*this), boost::bind (&Mixer_UI::update_title, this), gui_context());
Config->ParameterChanged.connect (*this, invalidator (*this), ui_bind (&Mixer_UI::parameter_changed, this, _1), gui_context ());
Config->ParameterChanged.connect (*this, invalidator (*this), boost::bind (&Mixer_UI::parameter_changed, this, _1), gui_context ());
route_groups_changed ();
@ -1395,7 +1395,7 @@ Mixer_UI::add_route_group (RouteGroup* group)
focus = true;
}
group->PropertyChanged.connect (*this, invalidator (*this), ui_bind (&Mixer_UI::route_group_property_changed, this, group, _1), gui_context());
group->PropertyChanged.connect (*this, invalidator (*this), boost::bind (&Mixer_UI::route_group_property_changed, this, group, _1), gui_context());
if (focus) {
TreeViewColumn* col = group_display.get_column (0);

View file

@ -164,6 +164,7 @@ This mode provides many different operations on both regions and control points,
@rop|Region/naturalize-region|<@SECONDARY@>o|move to original position
@trans|Editor/set-playhead|p|set playhead position
@select|Editor/select-all-before-playhead|<@PRIMARY@>p|all before playhead
@wvis|Common/ToggleRCOptionsEditor|<@PRIMARY@><@TERTIARY@>p|toggle preferences dialog
@wvis|Common/toggle-audio-connection-manager|<@WINDOW@>p|toggle global audio patchbay
@wvis|Common/toggle-midi-connection-manager|<@WINDOW@><@TERTIARY@>p|toggle global midi patchbay
@midi|MIDI/panic|<@PRIMARY@><@SECONDARY@>p|MIDI panic (stop all notes etc)

View file

@ -36,6 +36,8 @@ MonitorSection::MonitorSection (Session* s)
: AxisView (s)
, RouteUI (s)
, _tearoff (0)
, channel_table_viewport (*channel_table_scroller.get_hadjustment(),
*channel_table_scroller.get_vadjustment ())
, gain_control (0)
, dim_control (0)
, solo_boost_control (0)
@ -257,6 +259,7 @@ MonitorSection::MonitorSection (Session* s)
channel_table_scroller.set_size_request (-1, 150);
channel_table_scroller.set_shadow_type (Gtk::SHADOW_NONE);
channel_table_scroller.show ();
channel_table_scroller.add (channel_table_viewport);
channel_size_group = SizeGroup::create (SIZE_GROUP_HORIZONTAL);
channel_size_group->add_widget (channel_table_header);
@ -318,7 +321,7 @@ MonitorSection::MonitorSection (Session* s)
/* catch changes that affect us */
Config->ParameterChanged.connect (config_connection, invalidator (*this), ui_bind (&MonitorSection::parameter_changed, this, _1), gui_context());
Config->ParameterChanged.connect (config_connection, invalidator (*this), boost::bind (&MonitorSection::parameter_changed, this, _1), gui_context());
}
MonitorSection::~MonitorSection ()
@ -357,23 +360,24 @@ MonitorSection::set_session (Session* s)
if (channel_table_scroller.get_parent()) {
/* scroller is packed, so remove it */
channel_table_packer.remove (channel_table_scroller);
/* remove the table_hpacker from the scroller */
channel_table_scroller.remove ();
}
if (table_hpacker.get_parent ()) {
if (table_hpacker.get_parent () == &channel_table_packer) {
/* this occurs when the table hpacker is directly
packed, so remove it.
*/
channel_table_packer.remove (table_hpacker);
} else if (table_hpacker.get_parent()) {
channel_table_viewport.remove ();
}
if (_monitor->output_streams().n_audio() > 7) {
/* put the table into a scrolled window, and then put
* that into the channel vpacker, after the table header
*/
channel_table_scroller.add (table_hpacker);
channel_table_viewport.add (table_hpacker);
channel_table_packer.pack_start (channel_table_scroller, true, true);
channel_table_viewport.show ();
channel_table_scroller.show ();
} else {

View file

@ -59,6 +59,7 @@ class MonitorSection : public RouteUI
Gtk::Table channel_table;
Gtk::Table channel_table_header;
Gtk::ScrolledWindow channel_table_scroller;
Gtk::Viewport channel_table_viewport;
Glib::RefPtr<Gtk::SizeGroup> channel_size_group;
struct ChannelButtonSet {

View file

@ -41,14 +41,14 @@ MouseCursors::MouseCursors ()
Color ffg ("#000000");
{
RefPtr<Bitmap> source = Bitmap::create (fader_cursor_bits, fader_cursor_width, fader_cursor_height);
RefPtr<Bitmap> mask = Bitmap::create (fader_cursor_mask_bits, fader_cursor_width, fader_cursor_height);
RefPtr<Bitmap> source = Bitmap::create ((char const *) fader_cursor_bits, fader_cursor_width, fader_cursor_height);
RefPtr<Bitmap> mask = Bitmap::create ((char const *) fader_cursor_mask_bits, fader_cursor_width, fader_cursor_height);
fader = new Cursor (source, mask, ffg, fbg, fader_cursor_x_hot, fader_cursor_y_hot);
}
{
RefPtr<Bitmap> source = Bitmap::create (speaker_cursor_bits, speaker_cursor_width, speaker_cursor_height);
RefPtr<Bitmap> mask = Bitmap::create (speaker_cursor_mask_bits, speaker_cursor_width, speaker_cursor_height);
RefPtr<Bitmap> source = Bitmap::create ((char const *) speaker_cursor_bits, speaker_cursor_width, speaker_cursor_height);
RefPtr<Bitmap> mask = Bitmap::create ((char const *) speaker_cursor_mask_bits, speaker_cursor_width, speaker_cursor_height);
speaker = new Cursor (source, mask, ffg, fbg, speaker_cursor_x_hot, speaker_cursor_y_hot);
}

View file

@ -291,7 +291,7 @@ OptionEditor::OptionEditor (Configuration* c, std::string const & t)
show_all_children();
/* Watch out for changes to parameters */
_config->ParameterChanged.connect (config_connection, invalidator (*this), ui_bind (&OptionEditor::parameter_changed, this, _1), gui_context());
_config->ParameterChanged.connect (config_connection, invalidator (*this), boost::bind (&OptionEditor::parameter_changed, this, _1), gui_context());
}
OptionEditor::~OptionEditor ()

View file

@ -145,7 +145,8 @@ PlaylistSelector::show_for (RouteUI* ruix)
}
TreeModel::Row row;
TreeModel::Row* selected_row = 0;
TreeModel::Row selected_row;
bool have_selected = false;
TreePath this_path;
if (tr == this_track) {
@ -173,12 +174,13 @@ PlaylistSelector::show_for (RouteUI* ruix)
child_row[columns.playlist] = *p;
if (*p == this_track->playlist()) {
selected_row = &child_row;
selected_row = child_row;
have_selected = true;
}
}
if (selected_row != 0) {
tree.get_selection()->select (*selected_row);
if (have_selected) {
tree.get_selection()->select (selected_row);
}
}
@ -187,7 +189,8 @@ PlaylistSelector::show_for (RouteUI* ruix)
_session->playlists->unassigned (unassigned);
TreeModel::Row row;
TreeModel::Row* selected_row = 0;
TreeModel::Row selected_row;
bool have_selected = false;
TreePath this_path;
row = *(model->append (others.children()));
@ -203,11 +206,12 @@ PlaylistSelector::show_for (RouteUI* ruix)
child_row[columns.playlist] = *p;
if (*p == this_track->playlist()) {
selected_row = &child_row;
selected_row = child_row;
have_selected = true;
}
if (selected_row != 0) {
tree.get_selection()->select (*selected_row);
if (have_selected) {
tree.get_selection()->select (selected_row);
}
}

View file

@ -141,7 +141,7 @@ PluginEqGui::start_listening ()
_plugin->activate();
set_buffer_size(4096, 16384);
// Connect the realtime signal collection callback
_plugin_insert->AnalysisDataGathered.connect (analysis_connection, invalidator (*this), ui_bind (&PluginEqGui::signal_collect_callback, this, _1, _2), gui_context());
_plugin_insert->AnalysisDataGathered.connect (analysis_connection, invalidator (*this), boost::bind (&PluginEqGui::signal_collect_callback, this, _1, _2), gui_context());
}
void

View file

@ -181,7 +181,7 @@ PluginSelector::PluginSelector (PluginManager& mgr)
//plugin_display.set_name("PluginSelectorList");
added_list.set_name("PluginSelectorList");
plugin_display.signal_button_press_event().connect_notify (sigc::mem_fun(*this, &PluginSelector::row_clicked));
plugin_display.signal_row_activated().connect_notify (sigc::mem_fun(*this, &PluginSelector::row_activated));
plugin_display.get_selection()->signal_changed().connect (sigc::mem_fun(*this, &PluginSelector::display_selection_changed));
plugin_display.grab_focus();
@ -199,11 +199,9 @@ PluginSelector::~PluginSelector ()
}
void
PluginSelector::row_clicked(GdkEventButton* event)
PluginSelector::row_activated(Gtk::TreeModel::Path path, Gtk::TreeViewColumn* col)
{
if (event->type == GDK_2BUTTON_PRESS) {
btn_add_clicked();
}
btn_add_clicked();
}
bool

View file

@ -118,7 +118,7 @@ class PluginSelector : public ArdourDialog
Gtk::Menu* _plugin_menu;
ARDOUR::PluginManager& manager;
void row_clicked(GdkEventButton *);
void row_activated(Gtk::TreeModel::Path path, Gtk::TreeViewColumn* col);
void btn_add_clicked();
void btn_remove_clicked();
void btn_update_clicked();

View file

@ -452,6 +452,7 @@ PlugUIBase::PlugUIBase (boost::shared_ptr<PluginInsert> pi)
, save_button (_("Save"))
, delete_button (_("Delete"))
, bypass_button (ArdourButton::led_default_elements)
, description_expander (_("Description"))
, plugin_analysis_expander (_("Plugin analysis"))
, latency_gui (0)
, latency_dialog (0)
@ -499,6 +500,9 @@ PlugUIBase::PlugUIBase (boost::shared_ptr<PluginInsert> pi)
ARDOUR_UI::instance()->set_tip (focus_button, string_compose (_("Click to allow the plugin to receive keyboard events that %1 would normally use as a shortcut"), PROGRAM_NAME));
ARDOUR_UI::instance()->set_tip (bypass_button, _("Click to enable/disable this plugin"));
description_expander.property_expanded().signal_changed().connect( sigc::mem_fun(*this, &PlugUIBase::toggle_description));
description_expander.set_expanded(false);
plugin_analysis_expander.property_expanded().signal_changed().connect( sigc::mem_fun(*this, &PlugUIBase::toggle_plugin_analysis));
plugin_analysis_expander.set_expanded(false);
@ -662,11 +666,34 @@ PlugUIBase::focus_toggled (GdkEventButton*)
return true;
}
void
PlugUIBase::toggle_description()
{
if (description_expander.get_expanded() &&
!description_expander.get_child()) {
const std::string text = plugin->get_docs();
if (text.empty()) {
return;
}
Gtk::Label* label = manage(new Gtk::Label(text));
label->set_line_wrap(true);
label->set_line_wrap_mode(Pango::WRAP_WORD);
description_expander.add(*label);
description_expander.show_all();
}
if (!description_expander.get_expanded()) {
description_expander.remove();
}
}
void
PlugUIBase::toggle_plugin_analysis()
{
if (plugin_analysis_expander.get_expanded() &&
!plugin_analysis_expander.get_child()) {
!plugin_analysis_expander.get_child()) {
// Create the GUI
if (eqgui == 0) {
eqgui = new PluginEqGui (insert);
@ -684,7 +711,6 @@ PlugUIBase::toggle_plugin_analysis()
}
if (!plugin_analysis_expander.get_expanded()) {
// Hide & remove from expander
eqgui->hide ();

View file

@ -125,6 +125,8 @@ class PlugUIBase : public virtual sigc::trackable, public PBD::ScopedConnectionL
ArdourButton bypass_button;
/** a button to acquire keyboard focus */
Gtk::EventBox focus_button;
/** an expander containing the plugin description */
Gtk::Expander description_expander;
/** an expander containing the plugin analysis graph */
Gtk::Expander plugin_analysis_expander;
/** a label indicating the plugin latency */
@ -150,6 +152,7 @@ class PlugUIBase : public virtual sigc::trackable, public PBD::ScopedConnectionL
void delete_plugin_setting ();
bool focus_toggled(GdkEventButton*);
bool bypass_button_release(GdkEventButton*);
void toggle_description ();
void toggle_plugin_analysis ();
void processor_active_changed (boost::weak_ptr<ARDOUR::Processor> p);
void plugin_going_away ();

View file

@ -21,11 +21,10 @@
#define __ardour_gtk_point_selection_h__
#include <list>
#include <boost/noncopyable.hpp>
#include "automation_range.h"
class ControlPoint;
struct PointSelection : public std::list<AutomationRange>
struct PointSelection : public std::list<ControlPoint *>
{
};

View file

@ -123,7 +123,7 @@ PortGroup::add_bundle_internal (boost::shared_ptr<Bundle> b, boost::shared_ptr<I
}
BundleRecord* br = new BundleRecord (b, io, colour, has_colour);
b->Changed.connect (br->changed_connection, invalidator (*this), ui_bind (&PortGroup::bundle_changed, this, _1), gui_context());
b->Changed.connect (br->changed_connection, invalidator (*this), boost::bind (&PortGroup::bundle_changed, this, _1), gui_context());
_bundles.push_back (br);
Changed ();
@ -695,7 +695,7 @@ PortGroupList::add_group (boost::shared_ptr<PortGroup> g)
_groups.push_back (g);
g->Changed.connect (_changed_connections, invalidator (*this), boost::bind (&PortGroupList::emit_changed, this), gui_context());
g->BundleChanged.connect (_bundle_changed_connections, invalidator (*this), ui_bind (&PortGroupList::emit_bundle_changed, this, _1), gui_context());
g->BundleChanged.connect (_bundle_changed_connections, invalidator (*this), boost::bind (&PortGroupList::emit_bundle_changed, this, _1), gui_context());
emit_changed ();
}

View file

@ -179,7 +179,7 @@ PortMatrix::reconnect_to_routes ()
boost::shared_ptr<RouteList> routes = _session->get_routes ();
for (RouteList::iterator i = routes->begin(); i != routes->end(); ++i) {
(*i)->processors_changed.connect (_route_connections, invalidator (*this), ui_bind (&PortMatrix::route_processors_changed, this, _1), gui_context());
(*i)->processors_changed.connect (_route_connections, invalidator (*this), boost::bind (&PortMatrix::route_processors_changed, this, _1), gui_context());
}
}

View file

@ -119,7 +119,7 @@ ProcessorEntry::ProcessorEntry (ProcessorBox* parent, boost::shared_ptr<Processo
_button.show ();
_processor->ActiveChanged.connect (active_connection, invalidator (*this), boost::bind (&ProcessorEntry::processor_active_changed, this), gui_context());
_processor->PropertyChanged.connect (name_connection, invalidator (*this), ui_bind (&ProcessorEntry::processor_property_changed, this, _1), gui_context());
_processor->PropertyChanged.connect (name_connection, invalidator (*this), boost::bind (&ProcessorEntry::processor_property_changed, this, _1), gui_context());
set<Evoral::Parameter> p = _processor->what_can_be_automated ();
for (set<Evoral::Parameter>::iterator i = p.begin(); i != p.end(); ++i) {
@ -605,7 +605,7 @@ PluginInsertProcessorEntry::PluginInsertProcessorEntry (ProcessorBox* b, boost::
, _plugin_insert (p)
{
p->SplittingChanged.connect (
_splitting_connection, invalidator (*this), ui_bind (&PluginInsertProcessorEntry::plugin_insert_splitting_changed, this), gui_context()
_splitting_connection, invalidator (*this), boost::bind (&PluginInsertProcessorEntry::plugin_insert_splitting_changed, this), gui_context()
);
_splitting_icon.set_size_request (-1, 12);
@ -723,7 +723,7 @@ ProcessorBox::ProcessorBox (ARDOUR::Session* sess, boost::function<PluginSelecto
if (parent) {
parent->DeliveryChanged.connect (
_mixer_strip_connections, invalidator (*this), ui_bind (&ProcessorBox::mixer_strip_delivery_changed, this, _1), gui_context ()
_mixer_strip_connections, invalidator (*this), boost::bind (&ProcessorBox::mixer_strip_delivery_changed, this, _1), gui_context ()
);
}
@ -757,7 +757,7 @@ ProcessorBox::set_route (boost::shared_ptr<Route> r)
_route = r;
_route->processors_changed.connect (
_route_connections, invalidator (*this), ui_bind (&ProcessorBox::route_processors_changed, this, _1), gui_context()
_route_connections, invalidator (*this), boost::bind (&ProcessorBox::route_processors_changed, this, _1), gui_context()
);
_route->DropReferences.connect (
@ -765,7 +765,7 @@ ProcessorBox::set_route (boost::shared_ptr<Route> r)
);
_route->PropertyChanged.connect (
_route_connections, invalidator (*this), ui_bind (&ProcessorBox::route_property_changed, this, _1), gui_context()
_route_connections, invalidator (*this), boost::bind (&ProcessorBox::route_property_changed, this, _1), gui_context()
);
redisplay_processors ();

View file

@ -73,7 +73,6 @@ class Selection;
class AutomationLine;
class ControlPoint;
class SelectionRect;
class CrossfadeView;
class RouteTimeAxisView;
class RegionView;
class AudioRegionView;
@ -315,7 +314,6 @@ class PublicEditor : public Gtk::Window, public PBD::StatefulDestructible {
virtual bool canvas_selection_rect_event (GdkEvent* event, ArdourCanvas::Item*, SelectionRect*) = 0;
virtual bool canvas_selection_start_trim_event (GdkEvent* event, ArdourCanvas::Item*, SelectionRect*) = 0;
virtual bool canvas_selection_end_trim_event (GdkEvent* event, ArdourCanvas::Item*, SelectionRect*) = 0;
virtual bool canvas_crossfade_view_event (GdkEvent* event, ArdourCanvas::Item*, CrossfadeView*) = 0;
virtual bool canvas_fade_in_event (GdkEvent* event, ArdourCanvas::Item*, AudioRegionView*) = 0;
virtual bool canvas_fade_in_handle_event (GdkEvent* event, ArdourCanvas::Item*, AudioRegionView*) = 0;
virtual bool canvas_fade_out_event (GdkEvent* event, ArdourCanvas::Item*, AudioRegionView*) = 0;

View file

@ -903,7 +903,7 @@ RCOptionEditor::RCOptionEditor ()
sigc::mem_fun (*_rc_config, &RCConfiguration::set_periodic_safety_backups)
));
add_option (_("Misc"), new OptionEditorHeading (_("Misc")));
add_option (_("Misc"), new OptionEditorHeading (_("Session Management")));
add_option (_("Misc"),
new BoolOption (
@ -941,6 +941,17 @@ RCOptionEditor::RCOptionEditor ()
sigc::mem_fun (*_rc_config, &RCConfiguration::set_click_gain)
));
add_option (_("Misc"), new OptionEditorHeading (_("Automation")));
add_option (_("Misc"),
new SpinOption<double> (
"automation-thinning-factor",
_("Thinning factor (larger value => less data)"),
sigc::mem_fun (*_rc_config, &RCConfiguration::get_automation_thinning_factor),
sigc::mem_fun (*_rc_config, &RCConfiguration::set_automation_thinning_factor),
0, 1000, 1, 20
));
/* TRANSPORT */
add_option (_("Transport"),

View file

@ -36,7 +36,6 @@ public:
private:
void parameter_changed (std::string const &);
ARDOUR::RCConfiguration* _rc_config;
BoolOption* _solo_control_is_listen_control;
ComboOption<ARDOUR::ListenPosition>* _listen_position;

View file

@ -189,7 +189,7 @@ RegionEditor::RegionEditor (Session* s, boost::shared_ptr<Region> r)
bounds_changed (change);
_region->PropertyChanged.connect (state_connection, invalidator (*this), ui_bind (&RegionEditor::region_changed, this, _1), gui_context());
_region->PropertyChanged.connect (state_connection, invalidator (*this), boost::bind (&RegionEditor::region_changed, this, _1), gui_context());
spin_arrow_grab = false;
@ -266,7 +266,7 @@ RegionEditor::connect_editor_events ()
audition_button.signal_toggled().connect (sigc::mem_fun(*this, &RegionEditor::audition_button_toggled));
_session->AuditionActive.connect (audition_connection, invalidator (*this), ui_bind (&RegionEditor::audition_state_changed, this, _1), gui_context());
_session->AuditionActive.connect (audition_connection, invalidator (*this), boost::bind (&RegionEditor::audition_state_changed, this, _1), gui_context());
}
void

View file

@ -24,6 +24,7 @@
#include "ardour/audioregion.h"
#include "ardour/session.h"
#include "control_point.h"
#include "region_gain_line.h"
#include "audio_region_view.h"
#include "utils.h"
@ -69,10 +70,6 @@ AudioRegionGainLine::start_drag_single (ControlPoint* cp, double x, float fracti
void
AudioRegionGainLine::remove_point (ControlPoint& cp)
{
ModelRepresentation mr;
model_representation (cp, mr);
trackview.editor().session()->begin_reversible_command (_("remove control point"));
XMLNode &before = alist->get_state();
@ -82,7 +79,7 @@ AudioRegionGainLine::remove_point (ControlPoint& cp)
trackview.session()->add_command(new StatefulDiffCommand (rv.audio_region()));
}
alist->erase (mr.start, mr.end);
alist->erase (cp.model());
trackview.editor().session()->add_command (new MementoCommand<AutomationList>(*alist.get(), &before, &alist->get_state()));
trackview.editor().session()->commit_reversible_command ();

View file

@ -33,7 +33,7 @@ using namespace PBD;
*/
RegionSelection::RegionSelection ()
{
RegionView::RegionViewGoingAway.connect (death_connection, MISSING_INVALIDATOR, ui_bind (&RegionSelection::remove_it, this, _1), gui_context());
RegionView::RegionViewGoingAway.connect (death_connection, MISSING_INVALIDATOR, boost::bind (&RegionSelection::remove_it, this, _1), gui_context());
}
/** Copy constructor.
@ -42,7 +42,7 @@ RegionSelection::RegionSelection ()
RegionSelection::RegionSelection (const RegionSelection& other)
: std::list<RegionView*>()
{
RegionView::RegionViewGoingAway.connect (death_connection, MISSING_INVALIDATOR, ui_bind (&RegionSelection::remove_it, this, _1), gui_context());
RegionView::RegionViewGoingAway.connect (death_connection, MISSING_INVALIDATOR, boost::bind (&RegionSelection::remove_it, this, _1), gui_context());
for (RegionSelection::const_iterator i = other.begin(); i != other.end(); ++i) {
add (*i);

View file

@ -86,7 +86,7 @@ RegionView::RegionView (ArdourCanvas::Group* parent,
, _region_relative_time_converter(r->session().tempo_map(), r->position())
, _source_relative_time_converter(r->session().tempo_map(), r->position() - r->start())
{
GhostRegion::CatchDeletion.connect (*this, invalidator (*this), ui_bind (&RegionView::remove_ghost, this, _1), gui_context());
GhostRegion::CatchDeletion.connect (*this, invalidator (*this), boost::bind (&RegionView::remove_ghost, this, _1), gui_context());
}
RegionView::RegionView (const RegionView& other)
@ -103,7 +103,7 @@ RegionView::RegionView (const RegionView& other)
valid = false;
_pixel_width = other._pixel_width;
GhostRegion::CatchDeletion.connect (*this, invalidator (*this), ui_bind (&RegionView::remove_ghost, this, _1), gui_context());
GhostRegion::CatchDeletion.connect (*this, invalidator (*this), boost::bind (&RegionView::remove_ghost, this, _1), gui_context());
}
RegionView::RegionView (const RegionView& other, boost::shared_ptr<Region> other_region)
@ -124,7 +124,7 @@ RegionView::RegionView (const RegionView& other, boost::shared_ptr<Region> other
valid = false;
_pixel_width = other._pixel_width;
GhostRegion::CatchDeletion.connect (*this, invalidator (*this), ui_bind (&RegionView::remove_ghost, this, _1), gui_context());
GhostRegion::CatchDeletion.connect (*this, invalidator (*this), boost::bind (&RegionView::remove_ghost, this, _1), gui_context());
}
RegionView::RegionView (ArdourCanvas::Group* parent,
@ -195,7 +195,7 @@ RegionView::init (Gdk::Color const & basic_color, bool wfd)
set_height (trackview.current_height());
_region->PropertyChanged.connect (*this, invalidator (*this), ui_bind (&RegionView::region_changed, this, _1), gui_context());
_region->PropertyChanged.connect (*this, invalidator (*this), boost::bind (&RegionView::region_changed, this, _1), gui_context());
group->signal_event().connect (sigc::bind (sigc::mem_fun (PublicEditor::instance(), &PublicEditor::canvas_region_view_event), group, this));

View file

@ -59,7 +59,7 @@ ReturnUI::ReturnUI (Gtk::Window* parent, boost::shared_ptr<Return> r, Session* s
show_all ();
_return->set_metering (true);
_return->input()->changed.connect (input_change_connection, invalidator (*this), ui_bind (&ReturnUI::ins_changed, this, _1, _2), gui_context());
_return->input()->changed.connect (input_change_connection, invalidator (*this), boost::bind (&ReturnUI::ins_changed, this, _1, _2), gui_context());
_gpm.setup_meters ();
_gpm.set_fader_name ("ReturnUIFrame");

View file

@ -216,7 +216,7 @@ RhythmFerret::run_analysis ()
}
int
RhythmFerret::run_percussion_onset_analysis (boost::shared_ptr<Readable> readable, framepos_t /*offset*/, AnalysisFeatureList& results)
RhythmFerret::run_percussion_onset_analysis (boost::shared_ptr<Readable> readable, frameoffset_t /*offset*/, AnalysisFeatureList& results)
{
TransientDetector t (_session->frame_rate());
@ -263,7 +263,7 @@ RhythmFerret::get_note_onset_function ()
}
int
RhythmFerret::run_note_onset_analysis (boost::shared_ptr<Readable> readable, framepos_t /*offset*/, AnalysisFeatureList& results)
RhythmFerret::run_note_onset_analysis (boost::shared_ptr<Readable> readable, frameoffset_t /*offset*/, AnalysisFeatureList& results)
{
try {
OnsetDetector t (_session->frame_rate());

View file

@ -180,7 +180,7 @@ RouteParams_UI::add_routes (RouteList& routes)
//route_select_list.rows().back().select ();
route->PropertyChanged.connect (*this, invalidator (*this), ui_bind (&RouteParams_UI::route_property_changed, this, _1, boost::weak_ptr<Route>(route)), gui_context());
route->PropertyChanged.connect (*this, invalidator (*this), boost::bind (&RouteParams_UI::route_property_changed, this, _1, boost::weak_ptr<Route>(route)), gui_context());
route->DropReferences.connect (*this, invalidator (*this), boost::bind (&RouteParams_UI::route_removed, this, boost::weak_ptr<Route>(route)), gui_context());
}
}
@ -402,7 +402,7 @@ RouteParams_UI::set_session (Session *sess)
if (_session) {
boost::shared_ptr<RouteList> r = _session->get_routes();
add_routes (*r);
_session->RouteAdded.connect (_session_connections, invalidator (*this), ui_bind (&RouteParams_UI::add_routes, this, _1), gui_context());
_session->RouteAdded.connect (_session_connections, invalidator (*this), boost::bind (&RouteParams_UI::add_routes, this, _1), gui_context());
start_updating ();
} else {
stop_updating ();
@ -461,7 +461,7 @@ RouteParams_UI::route_selected()
setup_processor_boxes();
setup_latency_frame ();
route->processors_changed.connect (_route_processors_connection, invalidator (*this), ui_bind (&RouteParams_UI::processors_changed, this, _1), gui_context());
route->processors_changed.connect (_route_processors_connection, invalidator (*this), boost::bind (&RouteParams_UI::processors_changed, this, _1), gui_context());
track_input_label.set_text (_route->name());

View file

@ -63,7 +63,7 @@ class RouteParams_UI : public ArdourWindow, public PBD::ScopedConnectionList
void set_session (ARDOUR::Session*);
void session_going_away ();
PluginSelector* plugin_selector() { return _plugin_selector; }
PluginSelector* plugin_selector() { return _plugin_selector; }
private:
Gtk::HBox global_hpacker;

View file

@ -111,7 +111,7 @@ RouteProcessorSelection::add (RouteUI* r)
MixerStrip* ms = dynamic_cast<MixerStrip*> (r);
if (ms) {
ms->CatchDeletion.connect (*this, invalidator (*this), ui_bind (&RouteProcessorSelection::remove, this, _1), gui_context());
ms->CatchDeletion.connect (*this, invalidator (*this), boost::bind (&RouteProcessorSelection::remove, this, _1), gui_context());
}
if (!_no_route_change_signal) {

View file

@ -68,7 +68,6 @@
#include "route_time_axis.h"
#include "automation_time_axis.h"
#include "canvas_impl.h"
#include "crossfade_view.h"
#include "enums.h"
#include "gui_thread.h"
#include "keyboard.h"
@ -194,8 +193,8 @@ RouteTimeAxisView::set_route (boost::shared_ptr<Route> rt)
controls_hbox.pack_start(gm.get_level_meter(), false, false);
_route->meter_change.connect (*this, invalidator (*this), bind (&RouteTimeAxisView::meter_changed, this), gui_context());
_route->input()->changed.connect (*this, invalidator (*this), ui_bind (&RouteTimeAxisView::io_changed, this, _1, _2), gui_context());
_route->output()->changed.connect (*this, invalidator (*this), ui_bind (&RouteTimeAxisView::io_changed, this, _1, _2), gui_context());
_route->input()->changed.connect (*this, invalidator (*this), boost::bind (&RouteTimeAxisView::io_changed, this, _1, _2), gui_context());
_route->output()->changed.connect (*this, invalidator (*this), boost::bind (&RouteTimeAxisView::io_changed, this, _1, _2), gui_context());
controls_table.attach (*mute_button, 6, 7, 0, 1, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND, 0, 0);
@ -227,8 +226,8 @@ RouteTimeAxisView::set_route (boost::shared_ptr<Route> rt)
_y_position = -1;
_route->processors_changed.connect (*this, invalidator (*this), ui_bind (&RouteTimeAxisView::processors_changed, this, _1), gui_context());
_route->PropertyChanged.connect (*this, invalidator (*this), ui_bind (&RouteTimeAxisView::route_property_changed, this, _1), gui_context());
_route->processors_changed.connect (*this, invalidator (*this), boost::bind (&RouteTimeAxisView::processors_changed, this, _1), gui_context());
_route->PropertyChanged.connect (*this, invalidator (*this), boost::bind (&RouteTimeAxisView::route_property_changed, this, _1), gui_context());
if (is_track()) {

View file

@ -145,8 +145,8 @@ RouteUI::init ()
_session->TransportStateChange.connect (_session_connections, invalidator (*this), boost::bind (&RouteUI::check_rec_enable_sensitivity, this), gui_context());
_session->RecordStateChanged.connect (_session_connections, invalidator (*this), boost::bind (&RouteUI::session_rec_enable_changed, this), gui_context());
_session->config.ParameterChanged.connect (*this, invalidator (*this), ui_bind (&RouteUI::parameter_changed, this, _1), gui_context());
Config->ParameterChanged.connect (*this, invalidator (*this), ui_bind (&RouteUI::parameter_changed, this, _1), gui_context());
_session->config.ParameterChanged.connect (*this, invalidator (*this), boost::bind (&RouteUI::parameter_changed, this, _1), gui_context());
Config->ParameterChanged.connect (*this, invalidator (*this), boost::bind (&RouteUI::parameter_changed, this, _1), gui_context());
rec_enable_button->signal_button_press_event().connect (sigc::mem_fun(*this, &RouteUI::rec_enable_press), false);
rec_enable_button->signal_button_release_event().connect (sigc::mem_fun(*this, &RouteUI::rec_enable_release), false);
@ -210,7 +210,7 @@ RouteUI::set_route (boost::shared_ptr<Route> rp)
solo_button->set_controllable (_route->solo_control());
_route->active_changed.connect (route_connections, invalidator (*this), boost::bind (&RouteUI::route_active_changed, this), gui_context());
_route->mute_changed.connect (route_connections, invalidator (*this), ui_bind (&RouteUI::mute_changed, this, _1), gui_context());
_route->mute_changed.connect (route_connections, invalidator (*this), boost::bind (&RouteUI::mute_changed, this, _1), gui_context());
_route->solo_changed.connect (route_connections, invalidator (*this), boost::bind (&RouteUI::update_solo_display, this), gui_context());
_route->solo_safe_changed.connect (route_connections, invalidator (*this), boost::bind (&RouteUI::update_solo_display, this), gui_context());
@ -218,10 +218,10 @@ RouteUI::set_route (boost::shared_ptr<Route> rp)
_route->solo_isolated_changed.connect (route_connections, invalidator (*this), boost::bind (&RouteUI::update_solo_display, this), gui_context());
_route->phase_invert_changed.connect (route_connections, invalidator (*this), boost::bind (&RouteUI::polarity_changed, this), gui_context());
_route->PropertyChanged.connect (route_connections, invalidator (*this), ui_bind (&RouteUI::property_changed, this, _1), gui_context());
_route->PropertyChanged.connect (route_connections, invalidator (*this), boost::bind (&RouteUI::property_changed, this, _1), gui_context());
_route->io_changed.connect (route_connections, invalidator (*this), ui_bind (&RouteUI::setup_invert_buttons, this), gui_context ());
_route->gui_changed.connect (route_connections, invalidator (*this), ui_bind (&RouteUI::route_gui_changed, this, _1), gui_context ());
_route->io_changed.connect (route_connections, invalidator (*this), boost::bind (&RouteUI::setup_invert_buttons, this), gui_context ());
_route->gui_changed.connect (route_connections, invalidator (*this), boost::bind (&RouteUI::route_gui_changed, this, _1), gui_context ());
if (_session->writable() && is_track()) {
boost::shared_ptr<Track> t = boost::dynamic_pointer_cast<Track>(_route);
@ -235,7 +235,7 @@ RouteUI::set_route (boost::shared_ptr<Route> rp)
if (is_midi_track()) {
midi_track()->StepEditStatusChange.connect (route_connections, invalidator (*this),
ui_bind (&RouteUI::step_edit_changed, this, _1), gui_context());
boost::bind (&RouteUI::step_edit_changed, this, _1), gui_context());
}
}

View file

@ -58,10 +58,13 @@ Selection::Selection (const PublicEditor* e)
/* we have disambiguate which remove() for the compiler */
void (Selection::*track_remove)(TimeAxisView*) = &Selection::remove;
TimeAxisView::CatchDeletion.connect (*this, MISSING_INVALIDATOR, ui_bind (track_remove, this, _1), gui_context());
TimeAxisView::CatchDeletion.connect (*this, MISSING_INVALIDATOR, boost::bind (track_remove, this, _1), gui_context());
void (Selection::*marker_remove)(Marker*) = &Selection::remove;
Marker::CatchDeletion.connect (*this, MISSING_INVALIDATOR, ui_bind (marker_remove, this, _1), gui_context());
Marker::CatchDeletion.connect (*this, MISSING_INVALIDATOR, boost::bind (marker_remove, this, _1), gui_context());
void (Selection::*point_remove)(ControlPoint*) = &Selection::remove;
ControlPoint::CatchDeletion.connect (*this, MISSING_INVALIDATOR, boost::bind (point_remove, this, _1), gui_context());
}
#if 0
@ -516,7 +519,6 @@ Selection::add (boost::shared_ptr<Evoral::ControlList> cl)
if (!al) {
warning << "Programming error: Selected list is not an ARDOUR::AutomationList" << endmsg;
return;
return;
}
if (find (lines.begin(), lines.end(), al) == lines.end()) {
lines.push_back (al);
@ -536,6 +538,15 @@ Selection::remove (TimeAxisView* track)
}
}
void
Selection::remove (ControlPoint* p)
{
PointSelection::iterator i = find (points.begin(), points.end(), p);
if (i != points.end ()) {
points.erase (i);
}
}
void
Selection::remove (const TrackViewList& track_list)
{
@ -879,17 +890,22 @@ void
Selection::toggle (ControlPoint* cp)
{
cp->set_selected (!cp->get_selected ());
set_point_selection_from_line (cp->line ());
PointSelection::iterator i = find (points.begin(), points.end(), cp);
if (i == points.end()) {
points.push_back (cp);
} else {
points.erase (i);
}
PointsChanged (); /* EMIT SIGNAL */
}
void
Selection::toggle (vector<ControlPoint*> const & cps)
{
for (vector<ControlPoint*>::const_iterator i = cps.begin(); i != cps.end(); ++i) {
(*i)->set_selected (!(*i)->get_selected ());
toggle (*i);
}
set_point_selection_from_line (cps.front()->line ());
}
void
@ -935,6 +951,13 @@ Selection::set (list<Selectable*> const & selectables)
add (selectables);
}
void
Selection::add (PointSelection const & s)
{
for (PointSelection::const_iterator i = s.begin(); i != s.end(); ++i) {
points.push_back (*i);
}
}
void
Selection::add (list<Selectable*> const & selectables)
@ -979,17 +1002,16 @@ void
Selection::add (ControlPoint* cp)
{
cp->set_selected (true);
set_point_selection_from_line (cp->line ());
points.push_back (cp);
PointsChanged (); /* EMIT SIGNAL */
}
void
Selection::add (vector<ControlPoint*> const & cps)
{
for (vector<ControlPoint*>::const_iterator i = cps.begin(); i != cps.end(); ++i) {
(*i)->set_selected (true);
add (*i);
}
set_point_selection_from_line (cps.front()->line ());
}
void
@ -999,18 +1021,11 @@ Selection::set (ControlPoint* cp)
return;
}
/* We're going to set up the PointSelection from the selected ControlPoints
on this point's line, so we need to deselect all ControlPoints before
we re-add this one.
*/
for (uint32_t i = 0; i < cp->line().npoints(); ++i) {
cp->line().nth (i)->set_selected (false);
}
vector<ControlPoint*> cps;
cps.push_back (cp);
add (cps);
add (cp);
}
void
@ -1083,73 +1098,6 @@ MarkerSelection::range (framepos_t& s, framepos_t& e)
e = std::max (s, e);
}
/** Automation control point selection is mostly manipulated using the selected state
* of the ControlPoints themselves. For example, to add a point to a selection, its
* ControlPoint is marked as selected and then this method is called. It sets up
* our PointSelection from the selected ControlPoints of a given AutomationLine.
*
* We can't use ControlPoints directly in the selection, as we need to express a
* selection of not just a visible ControlPoint but also (possibly) some invisible
* points nearby. Hence the selection stores AutomationRanges, and these are synced
* with ControlPoint selection state using AutomationLine::set_selected_points.
*/
void
Selection::set_point_selection_from_line (AutomationLine const & line)
{
points.clear ();
AutomationRange current (DBL_MAX, 0, 1, 0, &line.trackview);
for (uint32_t i = 0; i < line.npoints(); ++i) {
ControlPoint const * cp = line.nth (i);
if (cp->get_selected()) {
/* x and y position of this control point in coordinates suitable for
an AutomationRange (ie model time and fraction of track height)
*/
double const x = (*(cp->model()))->when;
double const y = 1 - (cp->get_y() / line.trackview.current_height ());
/* work out the position of a rectangle the size of a control point centred
on this point
*/
double const size = cp->size ();
double const x_size = line.time_converter().from (line.trackview.editor().pixel_to_frame (size));
double const y_size = size / line.trackview.current_height ();
double const x1 = max (0.0, x - x_size / 2);
double const x2 = x + x_size / 2;
double const y1 = max (0.0, y - y_size / 2);
double const y2 = y + y_size / 2;
/* extend the current AutomationRange to put this point in */
current.start = min (current.start, x1);
current.end = max (current.end, x2);
current.low_fract = min (current.low_fract, y1);
current.high_fract = max (current.high_fract, y2);
} else {
/* this point isn't selected; if the current AutomationRange has some
stuff in it, push it onto the list and make a new one
*/
if (current.start < DBL_MAX) {
points.push_back (current);
current = AutomationRange (DBL_MAX, 0, 1, 0, &line.trackview);
}
}
}
/* Maybe push the current AutomationRange, as above */
if (current.start < DBL_MAX) {
points.push_back (current);
current = AutomationRange (DBL_MAX, 0, 1, 0, &line.trackview);
}
PointsChanged (); /* EMIT SIGNAL */
}
XMLNode&
Selection::get_state () const
{

View file

@ -165,6 +165,7 @@ class Selection : public sigc::trackable, public PBD::ScopedConnectionList
void add (Marker*);
void add (const std::list<Marker*>&);
void add (const RegionSelection&);
void add (const PointSelection&);
void remove (TimeAxisView*);
void remove (const TrackViewList&);
void remove (const MidiNoteSelection&);
@ -178,6 +179,7 @@ class Selection : public sigc::trackable, public PBD::ScopedConnectionList
void remove (const std::list<boost::shared_ptr<ARDOUR::Playlist> >&);
void remove (const std::list<Selectable*>&);
void remove (Marker*);
void remove (ControlPoint *);
void remove_regions (TimeAxisView *);
@ -202,8 +204,6 @@ class Selection : public sigc::trackable, public PBD::ScopedConnectionList
int set_state (XMLNode const &, int);
private:
void set_point_selection_from_line (AutomationLine const &);
PublicEditor const * editor;
uint32_t next_time_id;
bool _no_tracks_changed;

View file

@ -72,7 +72,7 @@ SendUI::SendUI (Gtk::Window* parent, boost::shared_ptr<Send> s, Session* session
_send->set_metering (true);
_send->output()->changed.connect (connections, invalidator (*this), ui_bind (&SendUI::outs_changed, this, _1, _2), gui_context());
_send->output()->changed.connect (connections, invalidator (*this), boost::bind (&SendUI::outs_changed, this, _1, _2), gui_context());
_panners.set_width (Wide);
_panners.setup_pan ();

View file

@ -27,6 +27,7 @@
#include "ardour/session.h"
#include "ardour/session_directory.h"
#include "ardour/session_utils.h"
#include "ardour/configuration.h"
#include "i18n.h"
@ -81,8 +82,8 @@ TextMetadataField::load_data (ARDOUR::SessionMetadata const & data)
Gtk::Widget &
TextMetadataField::name_widget ()
{
label = Gtk::manage (new Gtk::Label(_name + ':', Gtk::ALIGN_LEFT));
label->set_alignment (0, 0.5);
label = Gtk::manage (new Gtk::Label(_name + ':'));
label->set_alignment (1, 0.5);
return *label;
}
@ -160,8 +161,8 @@ NumberMetadataField::update_value ()
Gtk::Widget &
NumberMetadataField::name_widget ()
{
label = Gtk::manage (new Gtk::Label(_name + ':', Gtk::ALIGN_LEFT));
label->set_alignment (0, 0.5);
label = Gtk::manage (new Gtk::Label(_name + ':'));
label->set_alignment (1, 0.5);
return *label;
}
@ -255,7 +256,7 @@ SessionMetadataSetEditable::set_session (ARDOUR::Session * s)
return;
}
ARDOUR::SessionMetadata const & data = _session->metadata();
ARDOUR::SessionMetadata const & data = *(ARDOUR::SessionMetadata::Metadata());
table.resize (list.size(), 2);
uint32_t row = 0;
@ -272,7 +273,7 @@ SessionMetadataSetEditable::set_session (ARDOUR::Session * s)
void
SessionMetadataSetEditable::save_data ()
{
ARDOUR::SessionMetadata & data = _session->metadata();
ARDOUR::SessionMetadata & data = *(ARDOUR::SessionMetadata::Metadata());
for (DataList::const_iterator it = list.begin(); it != list.end(); ++it) {
(*it)->save_data(data);
}
@ -330,7 +331,7 @@ SessionMetadataSetImportable::load_extra_data (ARDOUR::SessionMetadata const & d
return;
}
ARDOUR::SessionMetadata & session_data = _session->metadata();
ARDOUR::SessionMetadata const & session_data = *(ARDOUR::SessionMetadata::Metadata());
MetadataPtr session_field;
MetadataPtr import_field;
@ -378,7 +379,7 @@ SessionMetadataSetImportable::save_data ()
return;
}
ARDOUR::SessionMetadata & session_data = _session->metadata();
ARDOUR::SessionMetadata & session_data = *(ARDOUR::SessionMetadata::Metadata());
Gtk::TreeModel::Children fields = tree->children();
Gtk::TreeModel::Children::iterator it;
@ -421,22 +422,25 @@ SessionMetadataDialog<DataSet>::SessionMetadataDialog (string const & name) :
{
cancel_button = add_button (Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
cancel_button->signal_clicked().connect (sigc::mem_fun(*this, &SessionMetadataDialog::end_dialog));
save_button = add_button (Gtk::Stock::SAVE, Gtk::RESPONSE_ACCEPT);
save_button = add_button (Gtk::Stock::OK, Gtk::RESPONSE_ACCEPT);
save_button->signal_clicked().connect (sigc::mem_fun(*this, &SessionMetadataDialog::save_and_close));
}
template <typename DataSet>
void
SessionMetadataDialog<DataSet>::init_data ()
SessionMetadataDialog<DataSet>::init_data ( bool skip_user )
{
if (!_session) {
std::cerr << "Programming error: no session set for SessionMetaDataDialog (in init_data)!" << std::endl;
return;
}
if (!skip_user)
init_user_data ();
init_track_data ();
init_album_data ();
init_people_data ();
init_school_data ();
for (DataSetList::iterator it = data_list.begin(); it != data_list.end(); ++it) {
(*it)->set_session (_session);
@ -468,6 +472,7 @@ void
SessionMetadataDialog<DataSet>::save_and_close ()
{
save_data ();
_session->set_dirty();
end_dialog ();
}
@ -507,6 +512,32 @@ SessionMetadataDialog<DataSet>::add_widget (Gtk::Widget & widget)
get_vbox()->pack_start (widget, true, true, 0);
}
template <typename DataSet>
void
SessionMetadataDialog<DataSet>::init_user_data ()
{
DataSetPtr data_set (new DataSet (_("User")));
data_list.push_back (data_set);
MetadataPtr ptr;
ptr = MetadataPtr (new TextMetadataField (&ARDOUR::SessionMetadata::user_name, &ARDOUR::SessionMetadata::set_user_name, _("Name")));
data_set->add_data_field (ptr);
ptr = MetadataPtr (new TextMetadataField (&ARDOUR::SessionMetadata::user_email, &ARDOUR::SessionMetadata::set_user_email, _("Email")));
data_set->add_data_field (ptr);
ptr = MetadataPtr (new TextMetadataField (&ARDOUR::SessionMetadata::user_web, &ARDOUR::SessionMetadata::set_user_web, _("Web")));
data_set->add_data_field (ptr);
ptr = MetadataPtr (new TextMetadataField (&ARDOUR::SessionMetadata::organization, &ARDOUR::SessionMetadata::set_organization, _("Organization")));
data_set->add_data_field (ptr);
ptr = MetadataPtr (new TextMetadataField (&ARDOUR::SessionMetadata::country, &ARDOUR::SessionMetadata::set_country, _("Country")));
data_set->add_data_field (ptr);
}
template <typename DataSet>
void
SessionMetadataDialog<DataSet>::init_track_data ()
@ -615,6 +646,23 @@ SessionMetadataDialog<DataSet>::init_people_data ()
data_set->add_data_field (ptr);
}
template <typename DataSet>
void
SessionMetadataDialog<DataSet>::init_school_data ()
{
DataSetPtr data_set (new DataSet (_("School")));
data_list.push_back (data_set);
MetadataPtr ptr;
ptr = MetadataPtr (new TextMetadataField (&ARDOUR::SessionMetadata::instructor, &ARDOUR::SessionMetadata::set_instructor, _("Instructor")));
data_set->add_data_field (ptr);
ptr = MetadataPtr (new TextMetadataField (&ARDOUR::SessionMetadata::course, &ARDOUR::SessionMetadata::set_course, _("Course")));
data_set->add_data_field (ptr);
}
/* SessionMetadataEditor */
SessionMetadataEditor::SessionMetadataEditor () :
@ -722,10 +770,10 @@ SessionMetadataImporter::run ()
return;
}
//create a temporary
ARDOUR::SessionMetadata data;
data.set_state (*node, version);
init_data ();
init_data ( true ); //skip user data here
load_extra_data (data);
init_gui();

View file

@ -209,7 +209,7 @@ class SessionMetadataDialog : public ArdourDialog
SessionMetadataDialog (std::string const & name);
protected:
void init_data ();
void init_data ( bool skip_user = false );
void load_extra_data (ARDOUR::SessionMetadata const & data);
void save_data ();
@ -232,9 +232,11 @@ class SessionMetadataDialog : public ArdourDialog
Gtk::Notebook notebook;
private:
void init_user_data ();
void init_track_data ();
void init_album_data ();
void init_people_data ();
void init_school_data ();
typedef boost::shared_ptr<SessionMetadataSet> DataSetPtr;
typedef std::list<DataSetPtr> DataSetList;

View file

@ -294,22 +294,6 @@ SessionOptionEditor::SessionOptionEditor (Session* s)
add_option (_("Misc"), li);
add_option (_("Misc"), new OptionEditorHeading (_("Broadcast WAVE metadata")));
add_option (_("Misc"), new EntryOption (
"bwf-country-code",
_("Country code"),
sigc::mem_fun (*_session_config, &SessionConfiguration::get_bwf_country_code),
sigc::mem_fun (*_session_config, &SessionConfiguration::set_bwf_country_code)
));
add_option (_("Misc"), new EntryOption (
"bwf-organization-code",
_("Organization code"),
sigc::mem_fun (*_session_config, &SessionConfiguration::get_bwf_organization_code),
sigc::mem_fun (*_session_config, &SessionConfiguration::set_bwf_organization_code)
));
add_option (_("Misc"), new OptionEditorHeading (_("Glue to bars and beats")));
add_option (_("Misc"), new BoolOption (

View file

@ -50,6 +50,8 @@
#include <glib.h>
#include <glib/gstdio.h>
#include "i18n.h"
#include "ardour/audio_library.h"
static const std::string base_url = "http://www.freesound.org/api";
@ -67,6 +69,7 @@ Mootcher::Mootcher()
//------------------------------------------------------------------------
Mootcher:: ~Mootcher()
{
curl_easy_cleanup(curl);
}
//------------------------------------------------------------------------
@ -184,16 +187,16 @@ std::string Mootcher::doRequest(std::string uri, std::string params)
return "";
}
result = xml_page.memory;
// free the memory
if(xml_page.memory){
free( xml_page.memory );
xml_page.memory = NULL;
xml_page.size = 0;
if (xml_page.memory) {
result = xml_page.memory;
}
return result;
free (xml_page.memory);
xml_page.memory = NULL;
xml_page.size = 0;
return result;
}
@ -215,6 +218,8 @@ std::string Mootcher::searchText(std::string query, int page, std::string filter
if (sort)
params += "&s=" + sortMethodString(sort);
params += "&fields=id,original_filename,duration,serve";
return doRequest("/sounds/search", params);
}
@ -225,7 +230,6 @@ std::string Mootcher::getSoundResourceFile(std::string ID)
std::string originalSoundURI;
std::string audioFileName;
std::string xmlFileName;
std::string xml;
@ -250,28 +254,12 @@ std::string Mootcher::getSoundResourceFile(std::string ID)
}
XMLNode *name = freesound->child("original_filename");
XMLNode *filesize = freesound->child("filesize");
// get the file name and size from xml file
if (name && filesize) {
if (name) {
audioFileName = basePath + "snd/" + ID + "-" + name->child("text")->content();
// create new filename with the ID number
xmlFileName = basePath;
xmlFileName += "snd/";
xmlFileName += freesound->child("id")->child("text")->content();
xmlFileName += "-";
xmlFileName += name->child("text")->content();
xmlFileName += ".xml";
// std::cerr << "getSoundResourceFile: saving XML: " << xmlFileName << std::endl;
// save the xml file to disk
ensureWorkingDir();
doc.write(xmlFileName.c_str());
//store all the tags in the database
XMLNode *tags = freesound->child("tags");
if (tags) {
@ -326,6 +314,11 @@ std::string Mootcher::getAudioFile(std::string originalFileName, std::string ID,
return "";
}
//if already canceling a previous download, bail out here ( this can happen b/c getAudioFile gets called by various UI update funcs )
if ( caller->freesound_download_cancel ) {
return "";
}
//now download the actual file
FILE* theFile;
theFile = g_fopen( audioFileName.c_str(), "wb" );
@ -344,8 +337,12 @@ std::string Mootcher::getAudioFile(std::string originalFileName, std::string ID,
std::cerr << "downloading " << audioFileName << " from " << audioURL << "..." << std::endl;
/* hack to get rid of the barber-pole stripes */
caller->progress_bar.hide();
caller->progress_bar.show();
caller->freesound_progress_bar.hide();
caller->freesound_progress_bar.show();
std::string prog;
prog = string_compose (_("%1: [Stop]->"), originalFileName);
caller->freesound_progress_bar.set_text(prog);
curl_easy_setopt (curl, CURLOPT_NOPROGRESS, 0); // turn on the progress bar
curl_easy_setopt (curl, CURLOPT_PROGRESSFUNCTION, progress_callback);
@ -355,7 +352,8 @@ std::string Mootcher::getAudioFile(std::string originalFileName, std::string ID,
fclose(theFile);
curl_easy_setopt (curl, CURLOPT_NOPROGRESS, 1); // turn off the progress bar
caller->progress_bar.set_fraction(0.0);
caller->freesound_progress_bar.set_fraction(0.0);
caller->freesound_progress_bar.set_text("");
if( res != 0 ) {
std::cerr << "curl error " << res << " (" << curl_easy_strerror(res) << ")" << std::endl;
@ -377,12 +375,12 @@ int Mootcher::progress_callback(void *caller, double dltotal, double dlnow, doub
SoundFileBrowser *sfb = (SoundFileBrowser *) caller;
//XXX I hope it's OK to do GTK things in this callback. Otherwise
// I'll have to do stuff like in interthread_progress_window.
if (sfb->freesound_stop) {
if (sfb->freesound_download_cancel) {
return -1;
}
sfb->progress_bar.set_fraction(dlnow/dltotal);
sfb->freesound_progress_bar.set_fraction(dlnow/dltotal);
/* Make sure the progress widget gets updated */
while (Glib::MainContext::get_default()->iteration (false)) {
/* do nothing */

View file

@ -188,10 +188,10 @@ SoundFileBox::SoundFileBox (bool persistent)
main_box.pack_start (bottom_box, false, false);
play_btn.set_image (*(manage (new Image (Stock::MEDIA_PLAY, ICON_SIZE_BUTTON))));
play_btn.set_label (_("Play"));
// play_btn.set_label (_("Play"));
stop_btn.set_image (*(manage (new Image (Stock::MEDIA_STOP, ICON_SIZE_BUTTON))));
stop_btn.set_label (_("Stop"));
// stop_btn.set_label (_("Stop"));
bottom_box.set_homogeneous (false);
bottom_box.set_spacing (6);
@ -439,6 +439,10 @@ SoundFileBrowser::SoundFileBrowser (Gtk::Window& parent, string title, ARDOUR::S
chooser.add_shortcut_folder_uri("file:///Volumes");
#endif
#ifdef FREESOUND
mootcher = new Mootcher();
#endif
//add the file chooser
{
chooser.set_border_width (12);
@ -502,6 +506,8 @@ SoundFileBrowser::SoundFileBrowser (Gtk::Window& parent, string title, ARDOUR::S
found_search_btn.signal_clicked().connect(sigc::mem_fun(*this, &SoundFileBrowser::found_search_clicked));
found_entry.signal_activate().connect(sigc::mem_fun(*this, &SoundFileBrowser::found_search_clicked));
freesound_stop_btn.signal_clicked().connect(sigc::mem_fun(*this, &SoundFileBrowser::freesound_stop_clicked));
notebook.append_page (*vbox, _("Search Tags"));
}
@ -540,15 +546,8 @@ SoundFileBrowser::SoundFileBrowser (Gtk::Window& parent, string title, ARDOUR::S
freesound_sort.append_text(_("Lowest rated"));
freesound_sort.set_active(0);
label = manage (new Label);
label->set_text (_("Page:"));
passbox->pack_start (*label, false, false);
passbox->pack_start (freesound_page, false, false);
freesound_page.set_range(1, 1000);
freesound_page.set_increments(1, 10);
passbox->pack_start (freesound_search_btn, false, false);
passbox->pack_start (progress_bar);
passbox->pack_start (freesound_progress_bar);
passbox->pack_end (freesound_stop_btn, false, false);
freesound_stop_btn.set_label(_("Stop"));
@ -575,6 +574,7 @@ SoundFileBrowser::SoundFileBrowser (Gtk::Window& parent, string title, ARDOUR::S
freesound_stop_btn.signal_clicked().connect(sigc::mem_fun(*this, &SoundFileBrowser::freesound_stop_clicked));
notebook.append_page (*vbox, _("Search Freesound"));
}
#endif
@ -736,13 +736,13 @@ SoundFileBrowser::found_list_view_selected ()
void
SoundFileBrowser::freesound_list_view_selected ()
{
freesound_download_cancel = false;
#ifdef FREESOUND
if (!reset_options ()) {
set_response_sensitive (RESPONSE_OK, false);
} else {
Mootcher theMootcher; // XXX should be a member of SoundFileBrowser
string file;
TreeView::Selection::ListHandle_Path rows = freesound_list_view.get_selection()->get_selected_rows ();
@ -760,8 +760,7 @@ SoundFileBrowser::freesound_list_view_selected ()
gdk_window_set_cursor (get_window()->gobj(), gdk_cursor_new(GDK_WATCH));
gdk_flush();
freesound_stop = false;
file = theMootcher.getAudioFile(ofn, id, uri, this);
file = mootcher->getAudioFile(ofn, id, uri, this);
gdk_window_set_cursor (get_window()->gobj(), prev_cursor);
@ -805,13 +804,15 @@ SoundFileBrowser::found_search_clicked ()
void
SoundFileBrowser::freesound_search_clicked ()
{
freesound_search_cancel = false;
freesound_search();
}
void
SoundFileBrowser::freesound_stop_clicked ()
{
freesound_stop = true;
freesound_download_cancel = true;
freesound_search_cancel = true;
}
@ -821,97 +822,111 @@ SoundFileBrowser::freesound_search()
#ifdef FREESOUND
freesound_list->clear();
Mootcher theMootcher;
string search_string = freesound_entry.get_text ();
enum sortMethod sort_method = (enum sortMethod) freesound_sort.get_active_row_number();
int page = freesound_page.get_value_as_int();
GdkCursor *prev_cursor;
prev_cursor = gdk_window_get_cursor (get_window()->gobj());
gdk_window_set_cursor (get_window()->gobj(), gdk_cursor_new(GDK_WATCH));
gdk_flush();
for (int page = 1; page <= 99; page++ ) {
string theString = theMootcher.searchText(
search_string,
page,
"", // filter, could do, e.g. "type:wav"
sort_method
);
std::string prog;
prog = string_compose (_("Page %1, [Stop]->"), page);
freesound_progress_bar.set_text(prog);
while (Glib::MainContext::get_default()->iteration (false)) {
/* do nothing */
}
std::string theString = mootcher->searchText(
search_string,
page,
"", // filter, could do, e.g. "type:wav"
sort_method
);
XMLTree doc;
doc.read_buffer( theString );
XMLNode *root = doc.root();
if (!root) {
cerr << "no root XML node!" << endl;
break;
}
if ( strcmp(root->name().c_str(), "response") != 0) {
cerr << "root node name == " << root->name() << ", != \"response\"!" << endl;
break;
}
XMLNode *sounds_root = root->child("sounds");
if (!sounds_root) {
cerr << "no child node \"sounds\" found!" << endl;
break;
}
XMLNodeList sounds = sounds_root->children();
XMLNodeConstIterator niter;
XMLNode *node;
for (niter = sounds.begin(); niter != sounds.end(); ++niter) {
node = *niter;
if( strcmp( node->name().c_str(), "resource") != 0 ){
cerr << "node->name()=" << node->name() << ",!= \"resource\"!" << endl;
freesound_search_cancel = true;
break;
}
// node->dump(cerr, "node:");
XMLNode *id_node = node->child ("id");
XMLNode *uri_node = node->child ("serve");
XMLNode *ofn_node = node->child ("original_filename");
XMLNode *dur_node = node->child ("duration");
if (id_node && uri_node && ofn_node && dur_node) {
std::string id = id_node->child("text")->content();
std::string uri = uri_node->child("text")->content();
std::string ofn = ofn_node->child("text")->content();
std::string dur = dur_node->child("text")->content();
std::string r;
// cerr << "id=" << id << ",uri=" << uri << ",ofn=" << ofn << ",dur=" << dur << endl;
double duration_seconds = atof(dur.c_str());
double h, m, s;
char duration_hhmmss[16];
if (duration_seconds >= 99 * 60 * 60) {
strcpy(duration_hhmmss, ">99h");
} else {
s = modf(duration_seconds/60, &m) * 60;
m = modf(m/60, &h) * 60;
sprintf(duration_hhmmss, "%02.fh:%02.fm:%04.1fs",
h, m, s
);
}
TreeModel::iterator new_row = freesound_list->append();
TreeModel::Row row = *new_row;
row[freesound_list_columns.id ] = id;
row[freesound_list_columns.uri ] = uri;
row[freesound_list_columns.filename] = ofn;
row[freesound_list_columns.duration] = duration_hhmmss;
}
}
if (freesound_search_cancel)
break;
} //page "for" loop
gdk_window_set_cursor (get_window()->gobj(), prev_cursor);
XMLTree doc;
doc.read_buffer( theString );
XMLNode *root = doc.root();
freesound_progress_bar.set_text("");
if (!root) {
cerr << "no root XML node!" << endl;
return;
}
if ( strcmp(root->name().c_str(), "response") != 0) {
cerr << "root node name == " << root->name() << ", != \"response\"!" << endl;
return;
}
XMLNode *sounds_root = root->child("sounds");
if (!sounds_root) {
cerr << "no child node \"sounds\" found!" << endl;
return;
}
XMLNodeList sounds = sounds_root->children();
XMLNodeConstIterator niter;
XMLNode *node;
for (niter = sounds.begin(); niter != sounds.end(); ++niter) {
node = *niter;
if( strcmp( node->name().c_str(), "resource") != 0 ){
cerr << "node->name()=" << node->name() << ",!= \"resource\"!" << endl;
continue; // return;
}
// node->dump(cerr, "node:");
XMLNode *id_node = node->child ("id");
XMLNode *uri_node = node->child ("serve");
XMLNode *ofn_node = node->child ("original_filename");
XMLNode *dur_node = node->child ("duration");
if (id_node && uri_node && ofn_node) {
std::string id = id_node->child("text")->content();
std::string uri = uri_node->child("text")->content();
std::string ofn = ofn_node->child("text")->content();
std::string dur = dur_node->child("text")->content();
std::string r;
// cerr << "id=" << id << ",uri=" << uri << ",ofn=" << ofn << ",dur=" << dur << endl;
double duration_seconds = atof(dur.c_str());
double h, m, s;
char duration_hhmmss[16];
if (duration_seconds >= 99 * 60 * 60) {
strcpy(duration_hhmmss, ">99h");
} else {
s = modf(duration_seconds/60, &m) * 60;
m = modf(m/60, &h) * 60;
sprintf(duration_hhmmss, "%02.fh:%02.fm:%04.1fs",
h, m, s
);
}
TreeModel::iterator new_row = freesound_list->append();
TreeModel::Row row = *new_row;
row[freesound_list_columns.id ] = id;
row[freesound_list_columns.uri ] = uri;
row[freesound_list_columns.filename] = ofn;
row[freesound_list_columns.duration] = duration_hhmmss;
}
}
#endif
}
@ -948,9 +963,6 @@ SoundFileBrowser::get_paths ()
#ifdef FREESOUND
typedef TreeView::Selection::ListHandle_Path ListPath;
Mootcher theMootcher; // XXX should be a member of SoundFileBrowser
ListPath rows = freesound_list_view.get_selection()->get_selected_rows ();
for (ListPath::iterator i = rows.begin() ; i != rows.end(); ++i) {
TreeIter iter = freesound_list->get_iter(*i);
@ -963,8 +975,7 @@ SoundFileBrowser::get_paths ()
gdk_window_set_cursor (get_window()->gobj(), gdk_cursor_new(GDK_WATCH));
gdk_flush();
freesound_stop = false;
string str = theMootcher.getAudioFile(ofn, id, uri, this);
string str = mootcher->getAudioFile(ofn, id, uri, this);
if (str != "") {
results.push_back (str);
}

Some files were not shown because too many files have changed in this diff Show more