mirror of
https://github.com/Ardour/ardour.git
synced 2025-12-10 08:36:32 +01:00
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:
parent
85a27910cb
commit
9c8b57aab0
385 changed files with 14193 additions and 18198 deletions
6
.gitignore
vendored
6
.gitignore
vendored
|
|
@ -125,4 +125,8 @@ gtk2_ardour/po/*.mo
|
||||||
libs/ardour/po/*.mo
|
libs/ardour/po/*.mo
|
||||||
gtk2_ardour/*.pot
|
gtk2_ardour/*.pot
|
||||||
libs/ardour/libardour.pot
|
libs/ardour/libardour.pot
|
||||||
|
.lock-wafbuild
|
||||||
|
GPATH
|
||||||
|
GRTAGS
|
||||||
|
GSYMS
|
||||||
|
GTAGS
|
||||||
|
|
|
||||||
451
doc/eventloop.svg
Normal file
451
doc/eventloop.svg
Normal 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
623
doc/region_read.svg
Normal 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 |
|
|
@ -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_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_PANNER_PATH=$libs/panners/2in2out:$libs/panners/1in2out:$libs/panners/vbap
|
||||||
export ARDOUR_DATA_PATH=$TOP/gtk2_ardour:build/gtk2_ardour:.
|
export ARDOUR_DATA_PATH=$TOP/gtk2_ardour:build/gtk2_ardour:.
|
||||||
|
export ARDOUR_MCP_PATH=$TOP/mcp:.
|
||||||
|
|
||||||
if test -d $HOME/gtk/inst ; then
|
if test -d $HOME/gtk/inst ; then
|
||||||
export GTK_PATH=~/.ardour3:$libs/clearlooks-newer
|
export GTK_PATH=~/.ardour3:$libs/clearlooks-newer
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,7 @@
|
||||||
<accelerator action='focus-on-clock'/>
|
<accelerator action='focus-on-clock'/>
|
||||||
<accelerator action='track-solo-toggle'/>
|
<accelerator action='track-solo-toggle'/>
|
||||||
<accelerator action='track-mute-toggle'/>
|
<accelerator action='track-mute-toggle'/>
|
||||||
|
<accelerator action='toggle-edit-mode'/>
|
||||||
|
|
||||||
<menubar name='Main' action='MainMenu'>
|
<menubar name='Main' action='MainMenu'>
|
||||||
<menu name='Session' action='Session'>
|
<menu name='Session' action='Session'>
|
||||||
|
|
@ -213,7 +214,6 @@
|
||||||
<menuitem action='cycle-edit-point'/>
|
<menuitem action='cycle-edit-point'/>
|
||||||
<menuitem action='cycle-edit-point-with-marker'/>
|
<menuitem action='cycle-edit-point-with-marker'/>
|
||||||
</menu>
|
</menu>
|
||||||
<menuitem action='toggle-edit-mode'/>
|
|
||||||
<separator/>
|
<separator/>
|
||||||
<menu action="TempoMenu">
|
<menu action="TempoMenu">
|
||||||
<menuitem action='set-tempo-from-region'/>
|
<menuitem action='set-tempo-from-region'/>
|
||||||
|
|
|
||||||
|
|
@ -75,10 +75,12 @@ ArdourButton::ArdourButton (Element e)
|
||||||
|
|
||||||
ArdourButton::ArdourButton (const std::string& str, Element e)
|
ArdourButton::ArdourButton (const std::string& str, Element e)
|
||||||
: _elements (e)
|
: _elements (e)
|
||||||
|
, _tweaks (Tweaks (0))
|
||||||
, _text_width (0)
|
, _text_width (0)
|
||||||
, _text_height (0)
|
, _text_height (0)
|
||||||
, _diameter (11.0)
|
, _diameter (11.0)
|
||||||
, _corner_radius (9.0)
|
, _corner_radius (9.0)
|
||||||
|
, _corner_mask (0xf)
|
||||||
, edge_pattern (0)
|
, edge_pattern (0)
|
||||||
, active_pattern (0)
|
, active_pattern (0)
|
||||||
, inactive_pattern (0)
|
, inactive_pattern (0)
|
||||||
|
|
|
||||||
|
|
@ -168,20 +168,8 @@ ARDOUR_UI::ARDOUR_UI (int *argcp, char **argvp[])
|
||||||
, _feedback_exists (false)
|
, _feedback_exists (false)
|
||||||
|
|
||||||
{
|
{
|
||||||
using namespace Gtk::Menu_Helpers;
|
|
||||||
|
|
||||||
Gtkmm2ext::init();
|
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;
|
about = 0;
|
||||||
splash = 0;
|
splash = 0;
|
||||||
_startup = 0;
|
_startup = 0;
|
||||||
|
|
@ -252,7 +240,7 @@ ARDOUR_UI::ARDOUR_UI (int *argcp, char **argvp[])
|
||||||
|
|
||||||
/* handle dialog requests */
|
/* 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) */
|
/* 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) */
|
/* 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 */
|
/* tell the user about feedback */
|
||||||
|
|
||||||
ARDOUR::Session::FeedbackDetected.connect (forever_connections, MISSING_INVALIDATOR, ui_bind (&ARDOUR_UI::feedback_detected, 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, ui_bind (&ARDOUR_UI::successful_graph_sort, 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 */
|
/* 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);
|
_startup->set_new_only (should_be_new);
|
||||||
if (!load_template.empty()) {
|
if (!load_template.empty()) {
|
||||||
_startup->set_load_template( load_template );
|
_startup->set_load_template (load_template);
|
||||||
}
|
}
|
||||||
_startup->present ();
|
_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->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->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));
|
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_cpu_load ();
|
||||||
update_sample_rate (engine->frame_rate());
|
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));
|
boost::function<void (string)> pc (boost::bind (&ARDOUR_UI::parameter_changed, this, _1));
|
||||||
Config->map_parameters (pc);
|
Config->map_parameters (pc);
|
||||||
|
|
||||||
|
|
@ -530,7 +518,6 @@ ARDOUR_UI::configure_timeout ()
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
have_configure_timeout = false;
|
have_configure_timeout = false;
|
||||||
cerr << "config event-driven save\n";
|
|
||||||
save_ardour_state ();
|
save_ardour_state ();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -578,7 +565,6 @@ ARDOUR_UI::set_transport_controllable_state (const XMLNode& node)
|
||||||
if ((prop = node.property ("shuttle")) != 0) {
|
if ((prop = node.property ("shuttle")) != 0) {
|
||||||
shuttle_box->controllable()->set_id (prop->value());
|
shuttle_box->controllable()->set_id (prop->value());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
XMLNode&
|
XMLNode&
|
||||||
|
|
@ -796,10 +782,10 @@ ARDOUR_UI::finish()
|
||||||
if (save_state_canfail ("")) {
|
if (save_state_canfail ("")) {
|
||||||
/* failed - don't quit */
|
/* failed - don't quit */
|
||||||
MessageDialog msg (*editor,
|
MessageDialog msg (*editor,
|
||||||
_("\
|
string_compose (_("\
|
||||||
Ardour was unable to save your session.\n\n\
|
%1 was unable to save your session.\n\n\
|
||||||
If you still wish to quit, please use the\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);
|
pop_back_splash(msg);
|
||||||
msg.run ();
|
msg.run ();
|
||||||
return;
|
return;
|
||||||
|
|
@ -1112,15 +1098,6 @@ ARDOUR_UI::update_disk_space()
|
||||||
}
|
}
|
||||||
|
|
||||||
disk_space_label.set_markup (buf);
|
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
|
gint
|
||||||
|
|
@ -1155,7 +1132,7 @@ ARDOUR_UI::redisplay_recent_sessions ()
|
||||||
recent_session_display.set_model (recent_session_model);
|
recent_session_display.set_model (recent_session_model);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
//
|
|
||||||
// sort them alphabetically
|
// sort them alphabetically
|
||||||
sort (rs.begin(), rs.end(), cmp);
|
sort (rs.begin(), rs.end(), cmp);
|
||||||
|
|
||||||
|
|
@ -1174,12 +1151,12 @@ ARDOUR_UI::redisplay_recent_sessions ()
|
||||||
|
|
||||||
vector<string*>* states;
|
vector<string*>* states;
|
||||||
vector<const gchar*> item;
|
vector<const gchar*> item;
|
||||||
string fullpath = (*i).to_string();
|
string fullpath = i->to_string();
|
||||||
|
|
||||||
/* remove any trailing / */
|
/* remove any trailing / */
|
||||||
|
|
||||||
if (fullpath[fullpath.length()-1] == '/') {
|
if (fullpath[fullpath.length() - 1] == '/') {
|
||||||
fullpath = fullpath.substr (0, fullpath.length()-1);
|
fullpath = fullpath.substr (0, fullpath.length() - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* check whether session still exists */
|
/* check whether session still exists */
|
||||||
|
|
@ -1249,7 +1226,6 @@ ARDOUR_UI::build_session_selector ()
|
||||||
|
|
||||||
recent_session_display.show();
|
recent_session_display.show();
|
||||||
scroller->show();
|
scroller->show();
|
||||||
//session_selector_window->get_vbox()->show();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
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 (...) {
|
catch (...) {
|
||||||
|
|
@ -1612,7 +1584,6 @@ ARDOUR_UI::transport_record (bool roll)
|
||||||
_session->disable_record (false, true);
|
_session->disable_record (false, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//cerr << "ARDOUR_UI::transport_record () called roll = " << roll << " _session->record_status() = " << _session->record_status() << endl;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
@ -1787,35 +1758,34 @@ ARDOUR_UI::transport_rewind (int option)
|
||||||
void
|
void
|
||||||
ARDOUR_UI::transport_forward (int option)
|
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) {
|
if (current_transport_speed <= 0.0f) {
|
||||||
case 0:
|
switch (option) {
|
||||||
_session->request_transport_speed (1.0f);
|
case 0:
|
||||||
break;
|
_session->request_transport_speed (1.0f);
|
||||||
case 1:
|
break;
|
||||||
_session->request_transport_speed (4.0f);
|
case 1:
|
||||||
break;
|
_session->request_transport_speed (4.0f);
|
||||||
case -1:
|
break;
|
||||||
_session->request_transport_speed (0.5f);
|
case -1:
|
||||||
break;
|
_session->request_transport_speed (0.5f);
|
||||||
}
|
break;
|
||||||
} else {
|
|
||||||
/* speed up */
|
|
||||||
_session->request_transport_speed (current_transport_speed * 1.5f);
|
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
/* speed up */
|
||||||
|
_session->request_transport_speed (current_transport_speed * 1.5f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ARDOUR_UI::toggle_record_enable (uint32_t rid)
|
ARDOUR_UI::toggle_record_enable (uint32_t rid)
|
||||||
{
|
{
|
||||||
if (_session == 0) {
|
if (!_session) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1829,9 +1799,6 @@ ARDOUR_UI::toggle_record_enable (uint32_t rid)
|
||||||
t->set_record_enabled (!t->record_enabled(), this);
|
t->set_record_enabled (!t->record_enabled(), this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (_session == 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
@ -2032,7 +1999,6 @@ ARDOUR_UI::stop_clocking ()
|
||||||
|
|
||||||
gint
|
gint
|
||||||
ARDOUR_UI::_blink (void *arg)
|
ARDOUR_UI::_blink (void *arg)
|
||||||
|
|
||||||
{
|
{
|
||||||
((ARDOUR_UI *) arg)->blink ();
|
((ARDOUR_UI *) arg)->blink ();
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
@ -2424,27 +2390,9 @@ ARDOUR_UI::idle_load (const std::string& path)
|
||||||
/* /path/to/foo/foo.ardour => /path/to/foo, foo */
|
/* /path/to/foo/foo.ardour => /path/to/foo, foo */
|
||||||
load_session (Glib::path_get_dirname (path), basename_nosuffix (path));
|
load_session (Glib::path_get_dirname (path), basename_nosuffix (path));
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
ARDOUR_COMMAND_LINE::session_name = path;
|
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) {
|
if (about == 0) {
|
||||||
about = new About;
|
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);
|
about->set_transient_for(*editor);
|
||||||
|
|
@ -3363,14 +3311,14 @@ ARDOUR_UI::pending_state_dialog ()
|
||||||
HBox* hbox = new HBox();
|
HBox* hbox = new HBox();
|
||||||
Image* image = new Image (Stock::DIALOG_QUESTION, ICON_SIZE_DIALOG);
|
Image* image = new Image (Stock::DIALOG_QUESTION, ICON_SIZE_DIALOG);
|
||||||
ArdourDialog dialog (_("Crash Recovery"), true);
|
ArdourDialog dialog (_("Crash Recovery"), true);
|
||||||
Label message (_("\
|
Label message (string_compose (_("\
|
||||||
This session appears to have been in\n\
|
This session appears to have been in\n\
|
||||||
middle of recording when ardour or\n\
|
middle of recording when ardour or\n\
|
||||||
the computer was shutdown.\n\
|
the computer was shutdown.\n\
|
||||||
\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\
|
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);
|
image->set_alignment(ALIGN_CENTER, ALIGN_TOP);
|
||||||
hbox->pack_start (*image, PACK_EXPAND_WIDGET, 12);
|
hbox->pack_start (*image, PACK_EXPAND_WIDGET, 12);
|
||||||
hbox->pack_end (message, PACK_EXPAND_PADDING, 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);
|
Image* image = new Image (Stock::DIALOG_QUESTION, ICON_SIZE_DIALOG);
|
||||||
ArdourDialog dialog (_("Sample Rate Mismatch"), true);
|
ArdourDialog dialog (_("Sample Rate Mismatch"), true);
|
||||||
Label message (string_compose (_("\
|
Label message (string_compose (_("\
|
||||||
This session was created with a sample rate of %1 Hz\n\
|
This session was created with a sample rate of %1 Hz, but\n\
|
||||||
\n\
|
%2 is currently running at %3 Hz. If you load this session,\n\
|
||||||
The audioengine is currently running at %2 Hz\n"), desired, actual));
|
audio may be played at the wrong sample rate.\n"), desired, PROGRAM_NAME, actual));
|
||||||
|
|
||||||
image->set_alignment(ALIGN_CENTER, ALIGN_TOP);
|
image->set_alignment(ALIGN_CENTER, ALIGN_TOP);
|
||||||
hbox->pack_start (*image, PACK_EXPAND_WIDGET, 12);
|
hbox->pack_start (*image, PACK_EXPAND_WIDGET, 12);
|
||||||
|
|
@ -3427,7 +3375,7 @@ void
|
||||||
ARDOUR_UI::disconnect_from_jack ()
|
ARDOUR_UI::disconnect_from_jack ()
|
||||||
{
|
{
|
||||||
if (engine) {
|
if (engine) {
|
||||||
if( engine->disconnect_from_jack ()) {
|
if (engine->disconnect_from_jack ()) {
|
||||||
MessageDialog msg (*editor, _("Could not disconnect from JACK"));
|
MessageDialog msg (*editor, _("Could not disconnect from JACK"));
|
||||||
msg.run ();
|
msg.run ();
|
||||||
}
|
}
|
||||||
|
|
@ -3628,11 +3576,10 @@ ARDOUR_UI::TransportControllable::get_value (void) const
|
||||||
void
|
void
|
||||||
ARDOUR_UI::setup_profile ()
|
ARDOUR_UI::setup_profile ()
|
||||||
{
|
{
|
||||||
if (gdk_screen_width() < 1200) {
|
if (gdk_screen_width() < 1200 || getenv ("ARDOUR_NARROW_SCREEN")) {
|
||||||
Profile->set_small_screen ();
|
Profile->set_small_screen ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (getenv ("ARDOUR_SAE")) {
|
if (getenv ("ARDOUR_SAE")) {
|
||||||
Profile->set_sae ();
|
Profile->set_sae ();
|
||||||
Profile->set_single_package ();
|
Profile->set_single_package ();
|
||||||
|
|
@ -3654,11 +3601,11 @@ ARDOUR_UI::toggle_translations ()
|
||||||
bool already_enabled = !ARDOUR::translations_are_disabled ();
|
bool already_enabled = !ARDOUR::translations_are_disabled ();
|
||||||
|
|
||||||
if (ract->get_active ()) {
|
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);
|
int fd = ::open (i18n_killer.c_str(), O_RDONLY|O_CREAT, 0644);
|
||||||
close (fd);
|
close (fd);
|
||||||
} else {
|
} else {
|
||||||
/* we don't care about errors */
|
/* we don't care about errors */
|
||||||
unlink (i18n_killer.c_str());
|
unlink (i18n_killer.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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->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->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->Xrun.connect (_session_connections, MISSING_INVALIDATOR, boost::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->SoloActive.connect (_session_connections, MISSING_INVALIDATOR, boost::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->AuditionActive.connect (_session_connections, MISSING_INVALIDATOR, boost::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()->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, ui_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, ui_bind (&ARDOUR_UI::session_parameter_changed, 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
|
#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
|
#endif
|
||||||
|
|
||||||
/* Clocks are on by default after we are connected to a session, so show that here.
|
/* Clocks are on by default after we are connected to a session, so show that here.
|
||||||
|
|
|
||||||
|
|
@ -293,7 +293,7 @@ ARDOUR_UI::toggle_editing_space()
|
||||||
void
|
void
|
||||||
ARDOUR_UI::setup_session_options ()
|
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));
|
boost::function<void (std::string)> pc (boost::bind (&ARDOUR_UI::parameter_changed, this, _1));
|
||||||
_session->config.map_parameters (pc);
|
_session->config.map_parameters (pc);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -392,7 +392,12 @@ AUPluginUI::create_cocoa_view ()
|
||||||
// watch for size changes of the view
|
// watch for size changes of the view
|
||||||
|
|
||||||
[[NSNotificationCenter defaultCenter] addObserver:_notify
|
[[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];
|
object:au_view];
|
||||||
|
|
||||||
// Get the size of the new AU View's frame
|
// Get the size of the new AU View's frame
|
||||||
|
|
@ -410,6 +415,9 @@ void
|
||||||
AUPluginUI::cocoa_view_resized ()
|
AUPluginUI::cocoa_view_resized ()
|
||||||
{
|
{
|
||||||
NSRect packFrame = [au_view frame];
|
NSRect packFrame = [au_view frame];
|
||||||
|
prefwidth = packFrame.size.width;
|
||||||
|
prefheight = packFrame.size.height;
|
||||||
|
low_box.set_size_request (prefwidth, prefheight);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
|
|
||||||
|
|
@ -46,7 +46,6 @@
|
||||||
#include "selection.h"
|
#include "selection.h"
|
||||||
#include "public_editor.h"
|
#include "public_editor.h"
|
||||||
#include "ardour_ui.h"
|
#include "ardour_ui.h"
|
||||||
#include "crossfade_view.h"
|
|
||||||
#include "rgb_macros.h"
|
#include "rgb_macros.h"
|
||||||
#include "gui_thread.h"
|
#include "gui_thread.h"
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
|
|
@ -61,30 +60,10 @@ using namespace Editing;
|
||||||
AudioStreamView::AudioStreamView (AudioTimeAxisView& tv)
|
AudioStreamView::AudioStreamView (AudioTimeAxisView& tv)
|
||||||
: StreamView (tv)
|
: StreamView (tv)
|
||||||
{
|
{
|
||||||
crossfades_visible = tv.session()->config.get_xfades_visible ();
|
|
||||||
color_handler ();
|
color_handler ();
|
||||||
_amplitude_above_axis = 1.0;
|
_amplitude_above_axis = 1.0;
|
||||||
|
|
||||||
Config->ParameterChanged.connect (*this, invalidator (*this), ui_bind (&AudioStreamView::parameter_changed, this, _1), gui_context());
|
Config->ParameterChanged.connect (*this, invalidator (*this), boost::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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
|
@ -209,163 +188,10 @@ AudioStreamView::add_region_view_internal (boost::shared_ptr<Region> r, bool wai
|
||||||
return region_view;
|
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
|
void
|
||||||
AudioStreamView::redisplay_track ()
|
AudioStreamView::redisplay_track ()
|
||||||
{
|
{
|
||||||
list<RegionView *>::iterator i;
|
list<RegionView *>::iterator i;
|
||||||
CrossfadeViewList::iterator xi, tmpx;
|
|
||||||
|
|
||||||
// Flag region views as invalid and disable drawing
|
// Flag region views as invalid and disable drawing
|
||||||
for (i = region_views.begin(); i != region_views.end(); ++i) {
|
for (i = region_views.begin(); i != region_views.end(); ++i) {
|
||||||
|
|
@ -373,41 +199,11 @@ AudioStreamView::redisplay_track ()
|
||||||
(*i)->enable_display (false);
|
(*i)->enable_display (false);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Flag crossfade views as invalid
|
// Add and display views, and flag them as valid
|
||||||
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
|
|
||||||
|
|
||||||
if (_trackview.is_audio_track()) {
|
if (_trackview.is_audio_track()) {
|
||||||
_trackview.track()->playlist()->foreach_region(
|
_trackview.track()->playlist()->foreach_region(
|
||||||
sigc::hide_return (sigc::mem_fun (*this, &StreamView::add_region_view))
|
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
|
// Stack regions by layer, and remove invalid regions
|
||||||
|
|
@ -473,7 +269,7 @@ AudioStreamView::setup_rec_box ()
|
||||||
sources.push_back (src);
|
sources.push_back (src);
|
||||||
src->PeakRangeReady.connect (rec_data_ready_connections,
|
src->PeakRangeReady.connect (rec_data_ready_connections,
|
||||||
invalidator (*this),
|
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());
|
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
|
void
|
||||||
AudioStreamView::rec_peak_range_ready (framepos_t start, framecnt_t cnt, boost::weak_ptr<Source> weak_src)
|
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
|
void
|
||||||
AudioStreamView::color_handler ()
|
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
|
void
|
||||||
AudioStreamView::parameter_changed (string const & p)
|
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 ();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,6 @@ namespace Gdk {
|
||||||
|
|
||||||
namespace ARDOUR {
|
namespace ARDOUR {
|
||||||
class Route;
|
class Route;
|
||||||
class Crossfade;
|
|
||||||
class PeakData;
|
class PeakData;
|
||||||
class AudioRegion;
|
class AudioRegion;
|
||||||
class Source;
|
class Source;
|
||||||
|
|
@ -47,33 +46,21 @@ class Selectable;
|
||||||
class AudioTimeAxisView;
|
class AudioTimeAxisView;
|
||||||
class AudioRegionView;
|
class AudioRegionView;
|
||||||
class RegionSelection;
|
class RegionSelection;
|
||||||
class CrossfadeView;
|
|
||||||
class Selection;
|
class Selection;
|
||||||
|
|
||||||
class AudioStreamView : public StreamView
|
class AudioStreamView : public StreamView
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
AudioStreamView (AudioTimeAxisView&);
|
AudioStreamView (AudioTimeAxisView&);
|
||||||
~AudioStreamView ();
|
|
||||||
|
|
||||||
int set_samples_per_unit (gdouble spp);
|
|
||||||
void horizontal_position_changed ();
|
|
||||||
|
|
||||||
int set_amplitude_above_axis (gdouble app);
|
int set_amplitude_above_axis (gdouble app);
|
||||||
gdouble get_amplitude_above_axis () { return _amplitude_above_axis; }
|
gdouble get_amplitude_above_axis () { return _amplitude_above_axis; }
|
||||||
|
|
||||||
void set_show_waveforms (bool yn);
|
void set_show_waveforms (bool yn);
|
||||||
|
|
||||||
void foreach_crossfadeview (void (CrossfadeView::*pmf)(void));
|
|
||||||
|
|
||||||
void show_all_fades ();
|
void show_all_fades ();
|
||||||
void hide_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);
|
RegionView* create_region_view (boost::shared_ptr<ARDOUR::Region>, bool, bool);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
@ -82,32 +69,18 @@ class AudioStreamView : public StreamView
|
||||||
void update_rec_regions (ARDOUR::framepos_t, ARDOUR::framecnt_t);
|
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);
|
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 remove_audio_region_view (boost::shared_ptr<ARDOUR::AudioRegion> );
|
||||||
|
|
||||||
void undisplay_track ();
|
|
||||||
void redisplay_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 color_handler ();
|
||||||
|
|
||||||
void update_contents_height ();
|
|
||||||
void update_content_height (CrossfadeView *);
|
|
||||||
|
|
||||||
void parameter_changed (std::string const &);
|
void parameter_changed (std::string const &);
|
||||||
void set_waveform_shape (ARDOUR::WaveformShape);
|
void set_waveform_shape (ARDOUR::WaveformShape);
|
||||||
void set_waveform_scale (ARDOUR::WaveformScale);
|
void set_waveform_scale (ARDOUR::WaveformScale);
|
||||||
|
|
||||||
double _amplitude_above_axis;
|
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;
|
std::map<boost::shared_ptr<ARDOUR::Source>, bool> rec_data_ready_map;
|
||||||
|
|
||||||
bool outline_region;
|
bool outline_region;
|
||||||
|
|
|
||||||
|
|
@ -55,7 +55,6 @@
|
||||||
#include "audio_time_axis.h"
|
#include "audio_time_axis.h"
|
||||||
#include "automation_line.h"
|
#include "automation_line.h"
|
||||||
#include "canvas_impl.h"
|
#include "canvas_impl.h"
|
||||||
#include "crossfade_view.h"
|
|
||||||
#include "enums.h"
|
#include "enums.h"
|
||||||
#include "gui_thread.h"
|
#include "gui_thread.h"
|
||||||
#include "automation_time_axis.h"
|
#include "automation_time_axis.h"
|
||||||
|
|
@ -176,22 +175,6 @@ AudioTimeAxisView::hide ()
|
||||||
TimeAxisView::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
|
void
|
||||||
AudioTimeAxisView::create_automation_child (const Evoral::Parameter& param, bool show)
|
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
|
void
|
||||||
AudioTimeAxisView::route_active_changed ()
|
AudioTimeAxisView::route_active_changed ()
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -73,10 +73,6 @@ class AudioTimeAxisView : public RouteTimeAxisView
|
||||||
AudioStreamView* audio_view();
|
AudioStreamView* audio_view();
|
||||||
|
|
||||||
void set_show_waveforms_recording (bool yn);
|
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 */
|
/* Overridden from parent to store display state */
|
||||||
guint32 show_at (double y, int& nth, Gtk::VBox *parent);
|
guint32 show_at (double y, int& nth, Gtk::VBox *parent);
|
||||||
|
|
@ -94,7 +90,6 @@ class AudioTimeAxisView : public RouteTimeAxisView
|
||||||
|
|
||||||
void route_active_changed ();
|
void route_active_changed ();
|
||||||
|
|
||||||
void append_extra_display_menu_items ();
|
|
||||||
Gtk::Menu* build_mode_menu();
|
Gtk::Menu* build_mode_menu();
|
||||||
void build_automation_action_menu (bool);
|
void build_automation_action_menu (bool);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -254,7 +254,7 @@ AutomationLine::modify_point_y (ControlPoint& cp, double y)
|
||||||
}
|
}
|
||||||
|
|
||||||
alist->freeze ();
|
alist->freeze ();
|
||||||
sync_model_with_view_point (cp, false, 0);
|
sync_model_with_view_point (cp, 0);
|
||||||
alist->thaw ();
|
alist->thaw ();
|
||||||
|
|
||||||
update_pending = false;
|
update_pending = false;
|
||||||
|
|
@ -277,255 +277,15 @@ AutomationLine::reset_line_coords (ControlPoint& cp)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
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;
|
update_pending = true;
|
||||||
|
|
||||||
for (list<ControlPoint*>::iterator i = cp.begin(); i != cp.end(); ++i) {
|
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
|
string
|
||||||
AutomationLine::get_verbose_cursor_string (double fraction) const
|
AutomationLine::get_verbose_cursor_string (double fraction) const
|
||||||
{
|
{
|
||||||
|
|
@ -589,19 +349,6 @@ AutomationLine::string_to_fraction (string const & s) const
|
||||||
return v;
|
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
|
/** Start dragging a single point, possibly adding others if the supplied point is selected and there
|
||||||
* are other selected points.
|
* 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.
|
/** 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.
|
* @param fraction New y fraction.
|
||||||
* @return x position and y fraction that were actually used (once clamped).
|
* @return x position and y fraction that were actually used (once clamped).
|
||||||
*/
|
*/
|
||||||
|
|
@ -823,7 +570,7 @@ AutomationLine::end_drag ()
|
||||||
points.sort (ControlPointSorter ());
|
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 ();
|
alist->thaw ();
|
||||||
|
|
||||||
|
|
@ -834,72 +581,38 @@ AutomationLine::end_drag ()
|
||||||
);
|
);
|
||||||
|
|
||||||
trackview.editor().session()->set_dirty ();
|
trackview.editor().session()->set_dirty ();
|
||||||
|
did_push = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
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;
|
/* find out where the visual control point is.
|
||||||
double ydelta;
|
initial results are in canvas units. ask the
|
||||||
|
line to convert them to something relevant.
|
||||||
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.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* 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);
|
if (view_x == trackview.editor().frame_to_unit (_time_converter->to ((*cp.model())->when)) - _offset) {
|
||||||
double y_delta = ydelta * fract;
|
view_x = (*cp.model())->when - _offset;
|
||||||
double x_delta = distance * fract;
|
} else {
|
||||||
|
view_x = trackview.editor().unit_to_frame (view_x);
|
||||||
/* interpolate */
|
view_x = _time_converter->from (view_x + _offset);
|
||||||
|
|
||||||
if (y_delta || x_delta) {
|
|
||||||
alist->modify (i, (*i)->when + x_delta, mr.ymin + y_delta);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* change the primary point */
|
|
||||||
|
|
||||||
update_pending = true;
|
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();
|
alist->modify (cp.model(), view_x, view_y);
|
||||||
|
|
||||||
++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;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (did_push) {
|
if (did_push) {
|
||||||
|
/* move all points after cp by the same distance */
|
||||||
/* move all points after the range represented by the view by the same distance
|
alist->slide (cp.model()++, _time_converter->from (distance));
|
||||||
as the main point moved.
|
|
||||||
*/
|
|
||||||
|
|
||||||
alist->slide (mr.end, distance);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -934,13 +647,16 @@ AutomationLine::control_points_adjacent (double xval, uint32_t & before, uint32_
|
||||||
bool
|
bool
|
||||||
AutomationLine::is_last_point (ControlPoint& cp)
|
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 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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -950,13 +666,9 @@ AutomationLine::is_last_point (ControlPoint& cp)
|
||||||
bool
|
bool
|
||||||
AutomationLine::is_first_point (ControlPoint& cp)
|
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 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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -967,15 +679,11 @@ AutomationLine::is_first_point (ControlPoint& cp)
|
||||||
void
|
void
|
||||||
AutomationLine::remove_point (ControlPoint& cp)
|
AutomationLine::remove_point (ControlPoint& cp)
|
||||||
{
|
{
|
||||||
ModelRepresentation mr;
|
|
||||||
|
|
||||||
model_representation (cp, mr);
|
|
||||||
|
|
||||||
trackview.editor().session()->begin_reversible_command (_("remove control point"));
|
trackview.editor().session()->begin_reversible_command (_("remove control point"));
|
||||||
XMLNode &before = alist->get_state();
|
XMLNode &before = alist->get_state();
|
||||||
|
|
||||||
alist->erase (mr.start, mr.end);
|
alist->erase (cp.model());
|
||||||
|
|
||||||
trackview.editor().session()->add_command(
|
trackview.editor().session()->add_command(
|
||||||
new MementoCommand<AutomationList> (memento_command_binder (), &before, &alist->get_state())
|
new MementoCommand<AutomationList> (memento_command_binder (), &before, &alist->get_state())
|
||||||
);
|
);
|
||||||
|
|
@ -1021,38 +729,6 @@ AutomationLine::get_inverted_selectables (Selection&, list<Selectable*>& /*resul
|
||||||
// hmmm ....
|
// 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
|
void
|
||||||
AutomationLine::set_selected_points (PointSelection const & points)
|
AutomationLine::set_selected_points (PointSelection const & points)
|
||||||
{
|
{
|
||||||
|
|
@ -1060,11 +736,8 @@ AutomationLine::set_selected_points (PointSelection const & points)
|
||||||
(*i)->set_selected (false);
|
(*i)->set_selected (false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!points.empty()) {
|
for (PointSelection::const_iterator i = points.begin(); i != points.end(); ++i) {
|
||||||
list<ControlPoint*> cp = point_selection_to_control_points (points);
|
(*i)->set_selected (true);
|
||||||
for (list<ControlPoint*>::iterator i = cp.begin(); i != cp.end(); ++i) {
|
|
||||||
(*i)->set_selected (true);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
set_colors ();
|
set_colors ();
|
||||||
|
|
@ -1087,10 +760,11 @@ AutomationLine::list_changed ()
|
||||||
void
|
void
|
||||||
AutomationLine::reset_callback (const Evoral::ControlList& events)
|
AutomationLine::reset_callback (const Evoral::ControlList& events)
|
||||||
{
|
{
|
||||||
ALPoints tmp_points;
|
uint32_t vp = 0;
|
||||||
uint32_t npoints = events.size();
|
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) {
|
for (vector<ControlPoint*>::iterator i = control_points.begin(); i != control_points.end(); ++i) {
|
||||||
delete *i;
|
delete *i;
|
||||||
}
|
}
|
||||||
|
|
@ -1099,26 +773,89 @@ AutomationLine::reset_callback (const Evoral::ControlList& events)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
AutomationList::const_iterator ai;
|
/* hide all existing points, and the line */
|
||||||
int skipped = 0;
|
|
||||||
|
|
||||||
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;
|
line->hide ();
|
||||||
double translated_y = (*ai)->value;
|
np = events.size();
|
||||||
model_to_view_coord (translated_x, translated_y);
|
|
||||||
|
|
||||||
if (translated_x >= 0 && translated_x < _maximum_time) {
|
Evoral::ControlList& e = const_cast<Evoral::ControlList&> (events);
|
||||||
tmp_points.push_back (ALPoint (
|
|
||||||
trackview.editor().frame_to_unit (translated_x),
|
for (AutomationList::iterator ai = e.begin(); ai != e.end(); ++ai, ++pi) {
|
||||||
_height - (translated_y * _height))
|
|
||||||
);
|
double tx = (*ai)->when;
|
||||||
} else if (translated_x < 0) {
|
double ty = (*ai)->value;
|
||||||
++skipped;
|
|
||||||
|
/* 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
|
void
|
||||||
|
|
@ -1284,8 +1021,11 @@ AutomationLine::interpolation_changed (AutomationList::InterpolationStyle style)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
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()) {
|
if (view_index >= control_points.size()) {
|
||||||
|
|
||||||
/* make sure we have enough control points */
|
/* 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);
|
control_points.push_back (ncp);
|
||||||
}
|
}
|
||||||
|
|
||||||
ControlPoint::ShapeType shape;
|
|
||||||
|
|
||||||
if (!terminal_points_can_slide) {
|
if (!terminal_points_can_slide) {
|
||||||
if (pi == 0) {
|
if (pi == 0) {
|
||||||
control_points[view_index]->set_can_slide(false);
|
control_points[view_index]->set_can_slide (false);
|
||||||
if (tx == 0) {
|
if (tx == 0) {
|
||||||
shape = ControlPoint::Start;
|
shape = ControlPoint::Start;
|
||||||
} else {
|
} else {
|
||||||
shape = ControlPoint::Full;
|
shape = ControlPoint::Full;
|
||||||
}
|
}
|
||||||
} else if (pi == npoints - 1) {
|
} else if (pi == npoints - 1) {
|
||||||
control_points[view_index]->set_can_slide(false);
|
control_points[view_index]->set_can_slide (false);
|
||||||
shape = ControlPoint::End;
|
shape = ControlPoint::End;
|
||||||
} else {
|
} else {
|
||||||
control_points[view_index]->set_can_slide(true);
|
control_points[view_index]->set_can_slide (true);
|
||||||
shape = ControlPoint::Full;
|
shape = ControlPoint::Full;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
control_points[view_index]->set_can_slide(true);
|
control_points[view_index]->set_can_slide (true);
|
||||||
shape = ControlPoint::Full;
|
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
|
void
|
||||||
AutomationLine::connect_to_list ()
|
AutomationLine::connect_to_list ()
|
||||||
{
|
{
|
||||||
|
|
@ -1386,13 +1110,19 @@ AutomationLine::get_point_x_range () const
|
||||||
pair<framepos_t, framepos_t> r (max_framepos, 0);
|
pair<framepos_t, framepos_t> r (max_framepos, 0);
|
||||||
|
|
||||||
for (AutomationList::const_iterator i = the_list()->begin(); i != the_list()->end(); ++i) {
|
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.first = min (r.first, session_position (i));
|
||||||
r.second = max (r.second, _time_converter->to ((*i)->when) + _offset + _time_converter->origin_b ());
|
r.second = max (r.second, session_position (i));
|
||||||
}
|
}
|
||||||
|
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
framepos_t
|
||||||
|
AutomationLine::session_position (AutomationList::const_iterator p) const
|
||||||
|
{
|
||||||
|
return _time_converter->to ((*p)->when) + _offset + _time_converter->origin_b ();
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
AutomationLine::set_offset (framepos_t off)
|
AutomationLine::set_offset (framepos_t off)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -66,7 +66,6 @@ class AutomationLine : public sigc::trackable, public PBD::StatefulDestructible
|
||||||
void reset ();
|
void reset ();
|
||||||
void clear ();
|
void clear ();
|
||||||
|
|
||||||
std::list<ControlPoint*> point_selection_to_control_points (PointSelection const &);
|
|
||||||
void set_selected_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_selectables (ARDOUR::framepos_t, ARDOUR::framepos_t, double, double, std::list<Selectable*>&);
|
||||||
void get_inverted_selectables (Selection&, std::list<Selectable*>& results);
|
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 modify_point_y (ControlPoint&, double);
|
||||||
|
|
||||||
void add_always_in_view (double);
|
|
||||||
void clear_always_in_view ();
|
|
||||||
|
|
||||||
virtual MementoCommandBinder<ARDOUR::AutomationList>* memento_command_binder ();
|
virtual MementoCommandBinder<ARDOUR::AutomationList>* memento_command_binder ();
|
||||||
|
|
||||||
const Evoral::TimeConverter<double, ARDOUR::framepos_t>& time_converter () const {
|
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_offset (ARDOUR::framecnt_t);
|
||||||
void set_width (ARDOUR::framecnt_t);
|
void set_width (ARDOUR::framecnt_t);
|
||||||
|
|
||||||
|
framepos_t session_position (ARDOUR::AutomationList::const_iterator) const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
std::string _name;
|
std::string _name;
|
||||||
|
|
@ -156,7 +154,7 @@ class AutomationLine : public sigc::trackable, public PBD::StatefulDestructible
|
||||||
|
|
||||||
boost::shared_ptr<ARDOUR::AutomationList> alist;
|
boost::shared_ptr<ARDOUR::AutomationList> alist;
|
||||||
Evoral::TimeConverter<double, ARDOUR::framepos_t>* _time_converter;
|
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 _our_time_converter;
|
||||||
|
|
||||||
bool _visible : 1;
|
bool _visible : 1;
|
||||||
|
|
@ -174,20 +172,8 @@ class AutomationLine : public sigc::trackable, public PBD::StatefulDestructible
|
||||||
ArdourCanvas::Points line_points; /* coordinates for canvas line */
|
ArdourCanvas::Points line_points; /* coordinates for canvas line */
|
||||||
std::vector<ControlPoint*> control_points; /* visible control points */
|
std::vector<ControlPoint*> control_points; /* visible control points */
|
||||||
|
|
||||||
struct ALPoint {
|
void sync_model_with_view_point (ControlPoint&, ARDOUR::framecnt_t);
|
||||||
double x;
|
void sync_model_with_view_points (std::list<ControlPoint*>, ARDOUR::framecnt_t);
|
||||||
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 start_drag_common (double, float);
|
void start_drag_common (double, float);
|
||||||
|
|
||||||
virtual void change_model (ARDOUR::AutomationList::iterator, double x, double y);
|
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
|
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
|
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_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
|
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
|
/** 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
|
* 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 connect_to_list ();
|
||||||
void interpolation_changed (ARDOUR::AutomationList::InterpolationStyle);
|
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;
|
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 */
|
/** maximum time that a point on this line can be at, relative to the position of its region or start of its track */
|
||||||
|
|
|
||||||
|
|
@ -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__ */
|
|
||||||
|
|
@ -44,6 +44,7 @@
|
||||||
#include "rgb_macros.h"
|
#include "rgb_macros.h"
|
||||||
#include "point_selection.h"
|
#include "point_selection.h"
|
||||||
#include "canvas_impl.h"
|
#include "canvas_impl.h"
|
||||||
|
#include "control_point.h"
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
|
|
||||||
#include "i18n.h"
|
#include "i18n.h"
|
||||||
|
|
@ -226,7 +227,7 @@ AutomationTimeAxisView::AutomationTimeAxisView (
|
||||||
ColorsChanged.connect (sigc::mem_fun (*this, &AutomationTimeAxisView::color_handler));
|
ColorsChanged.connect (sigc::mem_fun (*this, &AutomationTimeAxisView::color_handler));
|
||||||
|
|
||||||
_route->DropReferences.connect (
|
_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 ();
|
_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.
|
/** Paste a selection.
|
||||||
* @param pos Position to paste to (session frames).
|
* @param pos Position to paste to (session frames).
|
||||||
* @param times Number of times to paste.
|
* @param times Number of times to paste.
|
||||||
|
|
@ -794,25 +629,10 @@ AutomationTimeAxisView::paste_one (AutomationLine& line, framepos_t pos, float t
|
||||||
return false;
|
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 ());
|
double const model_pos = line.time_converter().from (pos - line.time_converter().origin_b ());
|
||||||
|
|
||||||
XMLNode &before = alist->get_state();
|
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()));
|
_session->add_command (new MementoCommand<AutomationList>(*alist.get(), &before, &alist->get_state()));
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
|
||||||
|
|
@ -91,10 +91,7 @@ class AutomationTimeAxisView : public TimeAxisView {
|
||||||
|
|
||||||
/* editing operations */
|
/* 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);
|
bool paste (ARDOUR::framepos_t, float times, Selection&, size_t nth);
|
||||||
void reset_objects (PointSelection&);
|
|
||||||
|
|
||||||
int set_state (const XMLNode&, int version);
|
int set_state (const XMLNode&, int version);
|
||||||
|
|
||||||
|
|
@ -169,10 +166,7 @@ class AutomationTimeAxisView : public TimeAxisView {
|
||||||
|
|
||||||
void build_display_menu ();
|
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);
|
bool paste_one (AutomationLine&, ARDOUR::framepos_t, float times, Selection&, size_t nth);
|
||||||
void reset_objects_one (AutomationLine&, PointSelection&);
|
|
||||||
void route_going_away ();
|
void route_going_away ();
|
||||||
|
|
||||||
void set_automation_state (ARDOUR::AutoState);
|
void set_automation_state (ARDOUR::AutoState);
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,7 @@
|
||||||
#include <list>
|
#include <list>
|
||||||
|
|
||||||
#include "pbd/error.h"
|
#include "pbd/error.h"
|
||||||
|
#include "pbd/convert.h"
|
||||||
|
|
||||||
#include <gtkmm2ext/utils.h>
|
#include <gtkmm2ext/utils.h>
|
||||||
#include <gtkmm2ext/selector.h>
|
#include <gtkmm2ext/selector.h>
|
||||||
|
|
@ -74,14 +75,14 @@ bool
|
||||||
AxisView::marked_for_display () const
|
AxisView::marked_for_display () const
|
||||||
{
|
{
|
||||||
string const v = gui_property ("visible");
|
string const v = gui_property ("visible");
|
||||||
return (v == "" || string_is_affirmative (v));
|
return (v == "" || PBD::string_is_affirmative (v));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
AxisView::set_marked_for_display (bool yn)
|
AxisView::set_marked_for_display (bool yn)
|
||||||
{
|
{
|
||||||
string const v = gui_property ("visible");
|
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);
|
set_gui_property ("visible", yn);
|
||||||
return true; // things changed
|
return true; // things changed
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -377,7 +377,7 @@ BundleManager::add_bundle (boost::shared_ptr<Bundle> b)
|
||||||
(*i)[_list_model_columns.name] = u->name ();
|
(*i)[_list_model_columns.name] = u->name ();
|
||||||
(*i)[_list_model_columns.bundle] = u;
|
(*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
|
void
|
||||||
|
|
|
||||||
|
|
@ -13,21 +13,38 @@
|
||||||
|
|
||||||
using namespace Gtk;
|
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)
|
: left (lw)
|
||||||
, right (rw)
|
, right (rw)
|
||||||
, name (str)
|
, name (str)
|
||||||
, active_fill_pattern (0)
|
, active_fill_pattern (0)
|
||||||
, inactive_fill_pattern (0)
|
, inactive_fill_pattern (0)
|
||||||
|
, central_link (central_joiner)
|
||||||
{
|
{
|
||||||
packer.set_homogeneous (true);
|
packer.set_homogeneous (true);
|
||||||
|
|
||||||
|
if (central_link) {
|
||||||
|
packer.set_spacing (20);
|
||||||
|
}
|
||||||
|
|
||||||
packer.pack_start (left);
|
packer.pack_start (left);
|
||||||
packer.pack_start (right);
|
packer.pack_start (right);
|
||||||
packer.show ();
|
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.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 ();
|
align.show ();
|
||||||
|
|
||||||
add (align);
|
add (align);
|
||||||
|
|
@ -73,22 +90,44 @@ ButtonJoiner::render (cairo_t* cr)
|
||||||
cairo_set_source (cr, active_fill_pattern);
|
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_set_line_width (cr, 1.5);
|
||||||
cairo_stroke (cr);
|
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
|
void
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@
|
||||||
|
|
||||||
class ButtonJoiner : public CairoWidget, public Gtkmm2ext::Activatable {
|
class ButtonJoiner : public CairoWidget, public Gtkmm2ext::Activatable {
|
||||||
public:
|
public:
|
||||||
ButtonJoiner (const std::string&, Gtk::Widget&, Gtk::Widget&);
|
ButtonJoiner (const std::string&, Gtk::Widget&, Gtk::Widget&, bool central_link = false);
|
||||||
~ButtonJoiner ();
|
~ButtonJoiner ();
|
||||||
|
|
||||||
void set_related_action (Glib::RefPtr<Gtk::Action>);
|
void set_related_action (Glib::RefPtr<Gtk::Action>);
|
||||||
|
|
@ -35,6 +35,7 @@ class ButtonJoiner : public CairoWidget, public Gtkmm2ext::Activatable {
|
||||||
std::string name;
|
std::string name;
|
||||||
cairo_pattern_t* active_fill_pattern;
|
cairo_pattern_t* active_fill_pattern;
|
||||||
cairo_pattern_t* inactive_fill_pattern;
|
cairo_pattern_t* inactive_fill_pattern;
|
||||||
|
bool central_link;
|
||||||
double border_r;
|
double border_r;
|
||||||
double border_g;
|
double border_g;
|
||||||
double border_b;
|
double border_b;
|
||||||
|
|
|
||||||
|
|
@ -30,6 +30,8 @@ using namespace ARDOUR;
|
||||||
using namespace PBD;
|
using namespace PBD;
|
||||||
using namespace Gnome; // for Canvas
|
using namespace Gnome; // for Canvas
|
||||||
|
|
||||||
|
PBD::Signal1<void, ControlPoint *> ControlPoint::CatchDeletion;
|
||||||
|
|
||||||
ControlPoint::ControlPoint (AutomationLine& al)
|
ControlPoint::ControlPoint (AutomationLine& al)
|
||||||
: _line (al)
|
: _line (al)
|
||||||
{
|
{
|
||||||
|
|
@ -82,6 +84,8 @@ ControlPoint::ControlPoint (const ControlPoint& other, bool /*dummy_arg_to_force
|
||||||
|
|
||||||
ControlPoint::~ControlPoint ()
|
ControlPoint::~ControlPoint ()
|
||||||
{
|
{
|
||||||
|
CatchDeletion (this); /* EMIT SIGNAL */
|
||||||
|
|
||||||
delete _item;
|
delete _item;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -83,21 +83,21 @@ class ControlPoint : public Selectable
|
||||||
ARDOUR::AutomationList::iterator model() const { return _model; }
|
ARDOUR::AutomationList::iterator model() const { return _model; }
|
||||||
AutomationLine& line() const { return _line; }
|
AutomationLine& line() const { return _line; }
|
||||||
|
|
||||||
|
static PBD::Signal1<void, ControlPoint *> CatchDeletion;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ArdourCanvas::SimpleRect* _item;
|
ArdourCanvas::SimpleRect* _item;
|
||||||
|
AutomationLine& _line;
|
||||||
AutomationLine& _line;
|
|
||||||
|
|
||||||
ARDOUR::AutomationList::iterator _model;
|
ARDOUR::AutomationList::iterator _model;
|
||||||
uint32_t _view_index;
|
uint32_t _view_index;
|
||||||
bool _can_slide;
|
bool _can_slide;
|
||||||
|
double _x;
|
||||||
|
double _y;
|
||||||
|
double _size;
|
||||||
|
ShapeType _shape;
|
||||||
|
|
||||||
virtual bool event_handler (GdkEvent*);
|
virtual bool event_handler (GdkEvent*);
|
||||||
|
|
||||||
double _x;
|
|
||||||
double _y;
|
|
||||||
double _size;
|
|
||||||
ShapeType _shape;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -296,9 +296,9 @@ CrossfadeEditor::CrossfadeEditor (Session* s, boost::shared_ptr<Crossfade> xf, d
|
||||||
|
|
||||||
curve_select_clicked (In);
|
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();
|
show_all_children();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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 ();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -90,7 +90,6 @@
|
||||||
#include "canvas-noevent-text.h"
|
#include "canvas-noevent-text.h"
|
||||||
#include "canvas_impl.h"
|
#include "canvas_impl.h"
|
||||||
#include "crossfade_edit.h"
|
#include "crossfade_edit.h"
|
||||||
#include "crossfade_view.h"
|
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
#include "editing.h"
|
#include "editing.h"
|
||||||
#include "editor.h"
|
#include "editor.h"
|
||||||
|
|
@ -303,7 +302,6 @@ Editor::Editor ()
|
||||||
clicked_regionview = 0;
|
clicked_regionview = 0;
|
||||||
clicked_axisview = 0;
|
clicked_axisview = 0;
|
||||||
clicked_routeview = 0;
|
clicked_routeview = 0;
|
||||||
clicked_crossfadeview = 0;
|
|
||||||
clicked_control_point = 0;
|
clicked_control_point = 0;
|
||||||
last_update_frame = 0;
|
last_update_frame = 0;
|
||||||
pre_press_cursor = 0;
|
pre_press_cursor = 0;
|
||||||
|
|
@ -340,7 +338,6 @@ Editor::Editor ()
|
||||||
have_pending_keyboard_selection = false;
|
have_pending_keyboard_selection = false;
|
||||||
_follow_playhead = true;
|
_follow_playhead = true;
|
||||||
_stationary_playhead = false;
|
_stationary_playhead = false;
|
||||||
_xfade_visibility = true;
|
|
||||||
editor_ruler_menu = 0;
|
editor_ruler_menu = 0;
|
||||||
no_ruler_shown_update = false;
|
no_ruler_shown_update = false;
|
||||||
marker_menu = 0;
|
marker_menu = 0;
|
||||||
|
|
@ -659,7 +656,7 @@ Editor::Editor ()
|
||||||
_playlist_selector = new PlaylistSelector();
|
_playlist_selector = new PlaylistSelector();
|
||||||
_playlist_selector->signal_delete_event().connect (sigc::bind (sigc::ptr_fun (just_hide_it), static_cast<Window *> (_playlist_selector)));
|
_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 */
|
/* nudge stuff */
|
||||||
|
|
||||||
|
|
@ -709,17 +706,32 @@ Editor::Editor ()
|
||||||
ControlProtocol::ZoomToSession.connect (*this, invalidator (*this), boost::bind (&Editor::temporal_zoom_session, this), gui_context());
|
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::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::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::Undo.connect (*this, invalidator (*this), boost::bind (&Editor::undo, this, true), gui_context());
|
||||||
ControlProtocol::SelectByRID.connect (*this, invalidator (*this), ui_bind (&Editor::control_select, this, _1), gui_context());
|
ControlProtocol::Redo.connect (*this, invalidator (*this), boost::bind (&Editor::redo, this, true), gui_context());
|
||||||
BasicUI::AccessAction.connect (*this, invalidator (*this), ui_bind (&Editor::access_action, this, _1, _2), 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 */
|
/* 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));
|
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;
|
_ignore_region_action = false;
|
||||||
_last_region_menu_was_main = false;
|
_last_region_menu_was_main = false;
|
||||||
|
|
@ -920,7 +932,43 @@ Editor::zoom_adjustment_changed ()
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
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
|
/* handles the (static) signal from the ControlProtocol class that
|
||||||
* requests setting the selected track to a given RID
|
* 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);
|
TimeAxisView* tav = axis_view_from_route (r);
|
||||||
|
|
||||||
if (tav) {
|
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 {
|
} else {
|
||||||
selection->clear_tracks ();
|
selection->clear_tracks ();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Editor::control_step_tracks_up ()
|
||||||
|
{
|
||||||
|
scroll_tracks_up_line ();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Editor::control_step_tracks_down ()
|
||||||
|
{
|
||||||
|
scroll_tracks_down_line ();
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Editor::control_scroll (float fraction)
|
Editor::control_scroll (float fraction)
|
||||||
{
|
{
|
||||||
|
|
@ -1198,19 +1270,19 @@ Editor::set_session (Session *t)
|
||||||
but use Gtkmm2ext::UI::instance()->call_slot();
|
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->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->PositionChanged.connect (_session_connections, invalidator (*this), boost::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->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->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->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->config.ParameterChanged.connect (_session_connections, invalidator (*this), boost::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->StateSaved.connect (_session_connections, invalidator (*this), boost::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()->added.connect (_session_connections, invalidator (*this), boost::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->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()->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());
|
_session->history().Changed.connect (_session_connections, invalidator (*this), boost::bind (&Editor::history_changed, this), gui_context());
|
||||||
|
|
||||||
playhead_cursor->canvas_item.show ();
|
playhead_cursor->canvas_item.show ();
|
||||||
|
|
@ -1453,10 +1525,6 @@ Editor::popup_track_context_menu (int button, int32_t time, ItemType item_type,
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CrossfadeViewItem:
|
|
||||||
build_menu_function = &Editor::build_track_crossfade_context_menu;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case StreamItem:
|
case StreamItem:
|
||||||
if (clicked_routeview->track()) {
|
if (clicked_routeview->track()) {
|
||||||
build_menu_function = &Editor::build_track_context_menu;
|
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:
|
case SelectionItem:
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CrossfadeViewItem:
|
|
||||||
break;
|
|
||||||
|
|
||||||
case StreamItem:
|
case StreamItem:
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
@ -1589,11 +1654,6 @@ Editor::build_track_region_context_menu ()
|
||||||
region_edit_menu_split_item = 0;
|
region_edit_menu_split_item = 0;
|
||||||
region_edit_menu_split_multichannel_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);
|
RouteTimeAxisView* rtv = dynamic_cast<RouteTimeAxisView*> (clicked_axisview);
|
||||||
|
|
||||||
if (rtv) {
|
if (rtv) {
|
||||||
|
|
@ -1610,54 +1670,6 @@ Editor::build_track_region_context_menu ()
|
||||||
return &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
|
void
|
||||||
Editor::analyze_region_selection ()
|
Editor::analyze_region_selection ()
|
||||||
{
|
{
|
||||||
|
|
@ -1708,73 +1720,6 @@ Editor::build_track_selection_context_menu ()
|
||||||
return &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
|
void
|
||||||
Editor::add_region_context_items (Menu_Helpers::MenuList& edit_items, boost::shared_ptr<Track> track)
|
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);
|
_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"))) {
|
if ((prop = node.property ("show-editor-mixer"))) {
|
||||||
|
|
||||||
Glib::RefPtr<Action> act = ActionManager::get_action (X_("Editor"), X_("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 ("maximised", _maximised ? "yes" : "no");
|
||||||
node->add_property ("follow-playhead", _follow_playhead ? "yes" : "no");
|
node->add_property ("follow-playhead", _follow_playhead ? "yes" : "no");
|
||||||
node->add_property ("stationary-playhead", _stationary_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 ("region-list-sort-type", enum_2_string (_regions->sort_type ()));
|
||||||
node->add_property ("mouse-mode", enum2str(mouse_mode));
|
node->add_property ("mouse-mode", enum2str(mouse_mode));
|
||||||
node->add_property ("internal-edit", _internal_editing ? "yes" : "no");
|
node->add_property ("internal-edit", _internal_editing ? "yes" : "no");
|
||||||
|
|
@ -2817,15 +2755,9 @@ Editor::setup_toolbar ()
|
||||||
/* make them just a bit bigger */
|
/* make them just a bit bigger */
|
||||||
mouse_move_button.set_size_request (-1, 25);
|
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);
|
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_hbox2->set_spacing (2);
|
||||||
mouse_mode_box->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&
|
PlaylistSelector&
|
||||||
Editor::playlist_selector () const
|
Editor::playlist_selector () const
|
||||||
{
|
{
|
||||||
|
|
@ -4341,19 +4199,6 @@ Editor::idle_visual_changer ()
|
||||||
|
|
||||||
double const last_time_origin = horizontal_position ();
|
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) {
|
if (p & VisualChange::ZoomLevel) {
|
||||||
set_frames_per_unit (pending_visual_change.frames_per_unit);
|
set_frames_per_unit (pending_visual_change.frames_per_unit);
|
||||||
|
|
||||||
|
|
@ -5327,7 +5172,6 @@ Editor::session_going_away ()
|
||||||
clicked_regionview = 0;
|
clicked_regionview = 0;
|
||||||
clicked_axisview = 0;
|
clicked_axisview = 0;
|
||||||
clicked_routeview = 0;
|
clicked_routeview = 0;
|
||||||
clicked_crossfadeview = 0;
|
|
||||||
entered_regionview = 0;
|
entered_regionview = 0;
|
||||||
entered_track = 0;
|
entered_track = 0;
|
||||||
last_update_frame = 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")));
|
_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' */
|
/** @return Gtk::manage()d menu item for a given action from `editor_actions' */
|
||||||
Gtk::MenuItem&
|
Gtk::MenuItem&
|
||||||
Editor::action_menu_item (std::string const & name)
|
Editor::action_menu_item (std::string const & name)
|
||||||
|
|
|
||||||
|
|
@ -83,7 +83,6 @@ namespace ARDOUR {
|
||||||
class NamedSelection;
|
class NamedSelection;
|
||||||
class Session;
|
class Session;
|
||||||
class Filter;
|
class Filter;
|
||||||
class Crossfade;
|
|
||||||
class ChanCount;
|
class ChanCount;
|
||||||
class MidiOperator;
|
class MidiOperator;
|
||||||
class Track;
|
class Track;
|
||||||
|
|
@ -106,7 +105,6 @@ class AutomationTimeAxisView;
|
||||||
class BundleManager;
|
class BundleManager;
|
||||||
class ButtonJoiner;
|
class ButtonJoiner;
|
||||||
class ControlPoint;
|
class ControlPoint;
|
||||||
class CrossfadeView;
|
|
||||||
class DragManager;
|
class DragManager;
|
||||||
class GroupedButtons;
|
class GroupedButtons;
|
||||||
class GUIObjectState;
|
class GUIObjectState;
|
||||||
|
|
@ -318,6 +316,7 @@ class Editor : public PublicEditor, public PBD::ScopedConnectionList, public ARD
|
||||||
|
|
||||||
void temporal_zoom_step (bool coarser);
|
void temporal_zoom_step (bool coarser);
|
||||||
void tav_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 */
|
/* 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_measure_visibility ();
|
||||||
void toggle_logo_visibility ();
|
void toggle_logo_visibility ();
|
||||||
|
|
||||||
/* fades/xfades */
|
/* fades */
|
||||||
|
|
||||||
void toggle_region_fades (int dir);
|
void toggle_region_fades (int dir);
|
||||||
void update_region_fade_visibility ();
|
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 */
|
/* 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;
|
RegionView* clicked_regionview;
|
||||||
RegionSelection latest_regionviews;
|
RegionSelection latest_regionviews;
|
||||||
uint32_t clicked_selection;
|
uint32_t clicked_selection;
|
||||||
CrossfadeView* clicked_crossfadeview;
|
|
||||||
ControlPoint* clicked_control_point;
|
ControlPoint* clicked_control_point;
|
||||||
|
|
||||||
void sort_track_selection (TrackViewList&);
|
void sort_track_selection (TrackViewList&);
|
||||||
|
|
||||||
void get_equivalent_regions (RegionView* rv, std::vector<RegionView*> &, PBD::PropertyID) const;
|
void get_equivalent_regions (RegionView* rv, std::vector<RegionView*> &, PBD::PropertyID) const;
|
||||||
RegionSelection get_equivalent_regions (RegionSelection &, 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 (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;
|
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_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_use_copy_playlist (RouteTimeAxisView&, uint32_t, std::vector<boost::shared_ptr<ARDOUR::Playlist> > const &);
|
||||||
void mapped_clear_playlist (RouteTimeAxisView&, uint32_t);
|
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);
|
void button_selection (ArdourCanvas::Item* item, GdkEvent* event, ItemType item_type);
|
||||||
bool button_release_can_deselect;
|
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_tracks ();
|
||||||
void select_all_internal_edit (Selection::Operation);
|
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_from_click (bool press, Selection::Operation op = Selection::Set, bool no_remove=false);
|
||||||
void set_selected_track_as_side_effect (Selection::Operation op);
|
void set_selected_track_as_side_effect (Selection::Operation op);
|
||||||
bool set_selected_regionview_from_click (bool press, Selection::Operation op = Selection::Set);
|
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_context_menu;
|
||||||
Gtk::Menu track_region_context_menu;
|
Gtk::Menu track_region_context_menu;
|
||||||
Gtk::Menu track_selection_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_item;
|
||||||
Gtk::MenuItem* region_edit_menu_split_multichannel_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_context_menu ();
|
||||||
Gtk::Menu* build_track_bus_context_menu ();
|
Gtk::Menu* build_track_bus_context_menu ();
|
||||||
Gtk::Menu* build_track_region_context_menu ();
|
Gtk::Menu* build_track_region_context_menu ();
|
||||||
Gtk::Menu* build_track_crossfade_context_menu ();
|
|
||||||
Gtk::Menu* build_track_selection_context_menu ();
|
Gtk::Menu* build_track_selection_context_menu ();
|
||||||
void add_dstream_context_items (Gtk::Menu_Helpers::MenuList&);
|
void add_dstream_context_items (Gtk::Menu_Helpers::MenuList&);
|
||||||
void add_bus_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_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&);
|
void add_selection_context_items (Gtk::Menu_Helpers::MenuList&);
|
||||||
Gtk::MenuItem* _popup_region_menu_item;
|
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::VBox edit_controls_vbox;
|
||||||
Gtk::HBox edit_controls_hbox;
|
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_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);
|
void access_action (std::string,std::string);
|
||||||
bool deferred_control_scroll (framepos_t);
|
bool deferred_control_scroll (framepos_t);
|
||||||
sigc::connection control_scroll_connection;
|
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_rect_event (GdkEvent* event,ArdourCanvas::Item*, SelectionRect*);
|
||||||
bool canvas_selection_start_trim_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_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_event (GdkEvent* event,ArdourCanvas::Item*, AudioRegionView*);
|
||||||
bool canvas_fade_in_handle_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*);
|
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);
|
void nudge_track (bool use_edit_point, bool forwards);
|
||||||
|
|
||||||
/* xfades */
|
|
||||||
|
|
||||||
bool _xfade_visibility;
|
|
||||||
|
|
||||||
#ifdef WITH_CMT
|
#ifdef WITH_CMT
|
||||||
void handle_new_imageframe_time_axis_view(const std::string & track_name, void* src) ;
|
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) ;
|
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 ;
|
ImageFrameSocketHandler* image_socket_listener ;
|
||||||
#endif
|
#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_width = 995;
|
||||||
static const int32_t default_height = 765;
|
static const int32_t default_height = 765;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1428,8 +1428,6 @@ Editor::parameter_changed (std::string p)
|
||||||
update_punch_range_view (true);
|
update_punch_range_view (true);
|
||||||
} else if (p == "timecode-format") {
|
} else if (p == "timecode-format") {
|
||||||
update_just_timecode ();
|
update_just_timecode ();
|
||||||
} else if (p == "xfades-visible") {
|
|
||||||
update_xfade_visibility ();
|
|
||||||
} else if (p == "show-region-fades") {
|
} else if (p == "show-region-fades") {
|
||||||
update_region_fade_visibility ();
|
update_region_fade_visibility ();
|
||||||
} else if (p == "edit-mode") {
|
} else if (p == "edit-mode") {
|
||||||
|
|
|
||||||
|
|
@ -35,7 +35,6 @@
|
||||||
#include "audio_region_view.h"
|
#include "audio_region_view.h"
|
||||||
#include "audio_streamview.h"
|
#include "audio_streamview.h"
|
||||||
#include "canvas-noevent-text.h"
|
#include "canvas-noevent-text.h"
|
||||||
#include "crossfade_view.h"
|
|
||||||
#include "audio_time_axis.h"
|
#include "audio_time_axis.h"
|
||||||
#include "region_gain_line.h"
|
#include "region_gain_line.h"
|
||||||
#include "automation_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
|
bool
|
||||||
Editor::canvas_control_point_event (GdkEvent *event, ArdourCanvas::Item* item, ControlPoint* cp)
|
Editor::canvas_control_point_event (GdkEvent *event, ArdourCanvas::Item* item, ControlPoint* cp)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -453,7 +453,7 @@ RegionDrag::RegionDrag (Editor* e, ArdourCanvas::Item* i, RegionView* p, list<Re
|
||||||
_views.push_back (DraggingView (*i, this));
|
_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
|
void
|
||||||
|
|
@ -2981,14 +2981,7 @@ LineDrag::motion (GdkEvent* event, bool)
|
||||||
cy = min ((double) _line->height(), cy);
|
cy = min ((double) _line->height(), cy);
|
||||||
|
|
||||||
double const fraction = 1.0 - (cy / _line->height());
|
double const fraction = 1.0 - (cy / _line->height());
|
||||||
|
bool const push = !Keyboard::modifier_state_contains (event->button.state, Keyboard::PrimaryModifier);
|
||||||
bool push;
|
|
||||||
|
|
||||||
if (Keyboard::modifier_state_contains (event->button.state, Keyboard::PrimaryModifier)) {
|
|
||||||
push = false;
|
|
||||||
} else {
|
|
||||||
push = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* we are ignoring x position for this drag, so we can just pass in anything */
|
/* we are ignoring x position for this drag, so we can just pass in anything */
|
||||||
_line->drag_motion (0, fraction, true, push);
|
_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 */
|
/* check this range against all the AudioRanges that we are using */
|
||||||
list<AudioRange>::const_iterator k = _ranges.begin ();
|
list<AudioRange>::const_iterator k = _ranges.begin ();
|
||||||
while (k != _ranges.end()) {
|
while (k != _ranges.end()) {
|
||||||
if (k->coverage (r.first, r.second) != OverlapNone) {
|
if (k->coverage (r.first, r.second) != Evoral::OverlapNone) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
++k;
|
++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 ());
|
double const q = j->line->time_converter().from (a - j->line->time_converter().origin_b ());
|
||||||
|
|
||||||
the_list->add (p, the_list->eval (p));
|
the_list->add (p, the_list->eval (p));
|
||||||
j->line->add_always_in_view (p);
|
|
||||||
the_list->add (q, the_list->eval (q));
|
the_list->add (q, the_list->eval (q));
|
||||||
j->line->add_always_in_view (q);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* same thing for the end */
|
/* 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 ());
|
double const q = j->line->time_converter().from (i->end - j->line->time_converter().origin_b ());
|
||||||
|
|
||||||
the_list->add (p, the_list->eval (p));
|
the_list->add (p, the_list->eval (p));
|
||||||
j->line->add_always_in_view (p);
|
|
||||||
the_list->add (q, the_list->eval (q));
|
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);
|
motion (event, false);
|
||||||
for (list<Line>::iterator i = _lines.begin(); i != _lines.end(); ++i) {
|
for (list<Line>::iterator i = _lines.begin(); i != _lines.end(); ++i) {
|
||||||
i->line->end_drag ();
|
i->line->end_drag ();
|
||||||
i->line->clear_always_in_view ();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_editor->session()->commit_reversible_command ();
|
_editor->session()->commit_reversible_command ();
|
||||||
|
|
@ -4294,7 +4282,6 @@ void
|
||||||
AutomationRangeDrag::aborted (bool)
|
AutomationRangeDrag::aborted (bool)
|
||||||
{
|
{
|
||||||
for (list<Line>::iterator i = _lines.begin(); i != _lines.end(); ++i) {
|
for (list<Line>::iterator i = _lines.begin(); i != _lines.end(); ++i) {
|
||||||
i->line->clear_always_in_view ();
|
|
||||||
i->line->reset ();
|
i->line->reset ();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -310,7 +310,7 @@ public:
|
||||||
|
|
||||||
protected:
|
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 y_movement_allowed (int, double) const;
|
||||||
|
|
||||||
bool _brushing;
|
bool _brushing;
|
||||||
|
|
|
||||||
|
|
@ -154,11 +154,11 @@ Editor::add_new_location_internal (Location* location)
|
||||||
lam->show ();
|
lam->show ();
|
||||||
}
|
}
|
||||||
|
|
||||||
location->start_changed.connect (*this, invalidator (*this), ui_bind (&Editor::location_changed, this, _1), 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), ui_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), ui_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), ui_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), ui_bind (&Editor::location_flags_changed, this, _1, _2), gui_context());
|
location->FlagsChanged.connect (*this, invalidator (*this), boost::bind (&Editor::location_flags_changed, this, _1, _2), gui_context());
|
||||||
|
|
||||||
pair<Location*,LocationMarkers*> newpair;
|
pair<Location*,LocationMarkers*> newpair;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -655,7 +655,7 @@ Editor::button_selection (ArdourCanvas::Item* /*item*/, GdkEvent* event, ItemTyp
|
||||||
case ControlPointItem:
|
case ControlPointItem:
|
||||||
set_selected_track_as_side_effect (op);
|
set_selected_track_as_side_effect (op);
|
||||||
if (doing_object_stuff() || (mouse_mode != MouseRange && mouse_mode != MouseObject)) {
|
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;
|
break;
|
||||||
|
|
||||||
|
|
@ -889,6 +889,7 @@ Editor::button_press_handler_1 (ArdourCanvas::Item* item, GdkEvent* event, ItemT
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case MouseObject:
|
case MouseObject:
|
||||||
switch (item_type) {
|
switch (item_type) {
|
||||||
|
|
|
||||||
|
|
@ -63,6 +63,7 @@
|
||||||
#include "route_time_axis.h"
|
#include "route_time_axis.h"
|
||||||
#include "audio_time_axis.h"
|
#include "audio_time_axis.h"
|
||||||
#include "automation_time_axis.h"
|
#include "automation_time_axis.h"
|
||||||
|
#include "control_point.h"
|
||||||
#include "streamview.h"
|
#include "streamview.h"
|
||||||
#include "audio_streamview.h"
|
#include "audio_streamview.h"
|
||||||
#include "audio_region_view.h"
|
#include "audio_region_view.h"
|
||||||
|
|
@ -1278,11 +1279,17 @@ Editor::scroll_tracks_up_line ()
|
||||||
void
|
void
|
||||||
Editor::tav_zoom_step (bool coarser)
|
Editor::tav_zoom_step (bool coarser)
|
||||||
{
|
{
|
||||||
ENSURE_GUI_THREAD (*this, &Editor::temporal_zoom_step, coarser)
|
|
||||||
|
|
||||||
_routes->suspend_redisplay ();
|
_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));
|
TimeAxisView *tv = (static_cast<TimeAxisView*>(*i));
|
||||||
tv->step_height (coarser);
|
tv->step_height (coarser);
|
||||||
}
|
}
|
||||||
|
|
@ -1290,6 +1297,38 @@ Editor::tav_zoom_step (bool coarser)
|
||||||
_routes->resume_redisplay ();
|
_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
|
void
|
||||||
Editor::temporal_zoom_step (bool coarser)
|
Editor::temporal_zoom_step (bool coarser)
|
||||||
{
|
{
|
||||||
|
|
@ -2472,7 +2511,7 @@ static void
|
||||||
add_if_covered (RegionView* rv, const AudioRange* ar, RegionSelection* rs)
|
add_if_covered (RegionView* rv, const AudioRange* ar, RegionSelection* rs)
|
||||||
{
|
{
|
||||||
switch (rv->region()->coverage (ar->start, ar->end - 1)) {
|
switch (rv->region()->coverage (ar->start, ar->end - 1)) {
|
||||||
case OverlapNone:
|
case Evoral::OverlapNone:
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
rs->push_back (rv);
|
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 */
|
/* require region to span proposed trim */
|
||||||
switch (rv->region()->coverage (loc.start(), loc.end())) {
|
switch (rv->region()->coverage (loc.start(), loc.end())) {
|
||||||
case OverlapInternal:
|
case Evoral::OverlapInternal:
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
continue;
|
continue;
|
||||||
|
|
@ -3355,9 +3394,10 @@ Editor::freeze_thread ()
|
||||||
SessionEvent::create_per_thread_pool ("freeze events", 64);
|
SessionEvent::create_per_thread_pool ("freeze events", 64);
|
||||||
/* create per-thread buffers for process() tree to use */
|
/* create per-thread buffers for process() tree to use */
|
||||||
current_interthread_info->process_thread.init ();
|
current_interthread_info->process_thread.init ();
|
||||||
|
current_interthread_info->process_thread.get_buffers ();
|
||||||
clicked_routeview->audio_track()->freeze_me (*current_interthread_info);
|
clicked_routeview->audio_track()->freeze_me (*current_interthread_info);
|
||||||
current_interthread_info->done = true;
|
current_interthread_info->done = true;
|
||||||
|
current_interthread_info->process_thread.drop_buffers();
|
||||||
return 0;
|
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.
|
/** Cut, copy or clear selected automation points.
|
||||||
* @param op Operation (Cut, Copy or Clear)
|
* @param op Operation (Cut, Copy or Clear)
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
Editor::cut_copy_points (CutCopyOp op)
|
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) {
|
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);
|
if (op == Cut || op == Copy) {
|
||||||
_last_cut_copy_source_track = atv;
|
/* 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) {
|
/* Add all selected points to the relevant copy ControlLists */
|
||||||
atv->cut_copy_clear_objects (selection->points, op);
|
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 ();
|
commit_reversible_command ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Reset all selected points to the relevant default value */
|
||||||
void
|
void
|
||||||
Editor::reset_point_selection ()
|
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) {
|
for (PointSelection::iterator i = selection->points.begin(); i != selection->points.end(); ++i) {
|
||||||
|
ARDOUR::AutomationList::iterator j = (*i)->model ();
|
||||||
AutomationTimeAxisView* atv = dynamic_cast<AutomationTimeAxisView*>((*i).track);
|
(*j)->value = (*i)->line().the_list()->default_value ();
|
||||||
|
|
||||||
if (atv) {
|
|
||||||
atv->reset_objects (selection->points);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -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
|
void
|
||||||
Editor::set_edit_point ()
|
Editor::set_edit_point ()
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -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, &Editor::redisplay_regions));
|
||||||
ARDOUR_UI::instance()->secondary_clock->mode_changed.connect (sigc::mem_fun(*this, &EditorRegions::update_all_rows));
|
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::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, ui_bind (&EditorRegions::add_region, this, _1), 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->EditorFreeze.connect (editor_freeze_connection, MISSING_INVALIDATOR, boost::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->EditorThaw.connect (editor_thaw_connection, MISSING_INVALIDATOR, boost::bind (&EditorRegions::thaw_tree_model, this), gui_context());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
|
|
||||||
|
|
@ -455,7 +455,7 @@ EditorRouteGroups::add (RouteGroup* group)
|
||||||
focus = true;
|
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) {
|
if (focus) {
|
||||||
TreeViewColumn* col = _display.get_column (0);
|
TreeViewColumn* col = _display.get_column (0);
|
||||||
|
|
@ -567,9 +567,9 @@ EditorRouteGroups::set_session (Session* s)
|
||||||
|
|
||||||
RouteGroup& arg (_session->all_route_group());
|
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->route_group_removed.connect (
|
||||||
_session_connections, MISSING_INVALIDATOR, boost::bind (&EditorRouteGroups::groups_changed, this), gui_context()
|
_session_connections, MISSING_INVALIDATOR, boost::bind (&EditorRouteGroups::groups_changed, this), gui_context()
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -282,7 +282,7 @@ EditorRoutes::EditorRoutes (Editor* e)
|
||||||
|
|
||||||
_display.set_enable_search (false);
|
_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
|
bool
|
||||||
|
|
@ -660,8 +660,8 @@ EditorRoutes::routes_added (list<RouteTimeAxisView*> routes)
|
||||||
|
|
||||||
boost::weak_ptr<Route> wr ((*x)->route());
|
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()->gui_changed.connect (*this, MISSING_INVALIDATOR, boost::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()->PropertyChanged.connect (*this, MISSING_INVALIDATOR, boost::bind (&EditorRoutes::route_property_changed, this, _1, wr), gui_context());
|
||||||
|
|
||||||
if ((*x)->is_track()) {
|
if ((*x)->is_track()) {
|
||||||
boost::shared_ptr<Track> t = boost::dynamic_pointer_cast<Track> ((*x)->route());
|
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()->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()->solo_changed.connect (*this, MISSING_INVALIDATOR, boost::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()->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_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()->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 ());
|
(*x)->route()->active_changed.connect (*this, MISSING_INVALIDATOR, boost::bind (&EditorRoutes::update_active_display, this), gui_context ());
|
||||||
|
|
|
||||||
|
|
@ -29,6 +29,8 @@
|
||||||
#include "ardour/midi_region.h"
|
#include "ardour/midi_region.h"
|
||||||
#include "ardour/audioplaylist.h"
|
#include "ardour/audioplaylist.h"
|
||||||
|
|
||||||
|
#include "control_protocol/control_protocol.h"
|
||||||
|
|
||||||
#include "editor.h"
|
#include "editor.h"
|
||||||
#include "actions.h"
|
#include "actions.h"
|
||||||
#include "audio_time_axis.h"
|
#include "audio_time_axis.h"
|
||||||
|
|
@ -36,7 +38,6 @@
|
||||||
#include "audio_streamview.h"
|
#include "audio_streamview.h"
|
||||||
#include "automation_line.h"
|
#include "automation_line.h"
|
||||||
#include "control_point.h"
|
#include "control_point.h"
|
||||||
#include "crossfade_view.h"
|
|
||||||
#include "editor_regions.h"
|
#include "editor_regions.h"
|
||||||
#include "editor_cursors.h"
|
#include "editor_cursors.h"
|
||||||
#include "midi_region_view.h"
|
#include "midi_region_view.h"
|
||||||
|
|
@ -313,12 +314,16 @@ Editor::set_selected_track_from_click (bool press, Selection::Operation op, bool
|
||||||
}
|
}
|
||||||
|
|
||||||
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) {
|
if (!clicked_control_point) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!press) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
switch (op) {
|
switch (op) {
|
||||||
case Selection::Set:
|
case Selection::Set:
|
||||||
selection->set (clicked_control_point);
|
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
|
void
|
||||||
Editor::get_equivalent_regions (RegionView* basis, vector<RegionView*>& equivalent_regions, PBD::PropertyID property) const
|
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;
|
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
|
int
|
||||||
Editor::get_regionview_count_from_region_list (boost::shared_ptr<Region> region)
|
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 */
|
/* 2. figure out the boundaries for our search for new objects */
|
||||||
|
|
||||||
switch (clicked_regionview->region()->coverage (first_frame, last_frame)) {
|
switch (clicked_regionview->region()->coverage (first_frame, last_frame)) {
|
||||||
case OverlapNone:
|
case Evoral::OverlapNone:
|
||||||
if (last_frame < clicked_regionview->region()->first_frame()) {
|
if (last_frame < clicked_regionview->region()->first_frame()) {
|
||||||
first_frame = last_frame;
|
first_frame = last_frame;
|
||||||
last_frame = clicked_regionview->region()->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;
|
break;
|
||||||
|
|
||||||
case OverlapExternal:
|
case Evoral::OverlapExternal:
|
||||||
if (last_frame < clicked_regionview->region()->first_frame()) {
|
if (last_frame < clicked_regionview->region()->first_frame()) {
|
||||||
first_frame = last_frame;
|
first_frame = last_frame;
|
||||||
last_frame = clicked_regionview->region()->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;
|
break;
|
||||||
|
|
||||||
case OverlapInternal:
|
case Evoral::OverlapInternal:
|
||||||
if (last_frame < clicked_regionview->region()->first_frame()) {
|
if (last_frame < clicked_regionview->region()->first_frame()) {
|
||||||
first_frame = last_frame;
|
first_frame = last_frame;
|
||||||
last_frame = clicked_regionview->region()->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;
|
break;
|
||||||
|
|
||||||
case OverlapStart:
|
case Evoral::OverlapStart:
|
||||||
case OverlapEnd:
|
case Evoral::OverlapEnd:
|
||||||
/* nothing to do except add clicked region to selection, since it
|
/* nothing to do except add clicked region to selection, since it
|
||||||
overlaps with the existing selection in this track.
|
overlaps with the existing selection in this track.
|
||||||
*/
|
*/
|
||||||
|
|
@ -965,6 +931,8 @@ Editor::track_selection_changed ()
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RouteNotificationListPtr routes (new RouteNotificationList);
|
||||||
|
|
||||||
for (TrackViewList::iterator i = track_views.begin(); i != track_views.end(); ++i) {
|
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());
|
bool yn = (find (selection->tracks.begin(), selection->tracks.end(), *i) != selection->tracks.end());
|
||||||
|
|
@ -983,9 +951,21 @@ Editor::track_selection_changed ()
|
||||||
} else {
|
} else {
|
||||||
(*i)->hide_selection ();
|
(*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());
|
ActionManager::set_sensitive (ActionManager::track_selection_sensitive_actions, !selection->tracks.empty());
|
||||||
|
|
||||||
|
/* notify control protocols */
|
||||||
|
|
||||||
|
ControlProtocol::TrackSelectionChanged (routes);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
||||||
|
|
@ -54,7 +54,7 @@ EditorSummary::EditorSummary (Editor* e)
|
||||||
_old_follow_playhead (false)
|
_old_follow_playhead (false)
|
||||||
{
|
{
|
||||||
Region::RegionPropertyChanged.connect (region_property_connection, invalidator (*this), boost::bind (&CairoWidget::set_dirty, this), gui_context());
|
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);
|
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) {
|
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 */
|
/* 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 ());
|
boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> ((*i)->route ());
|
||||||
if (tr) {
|
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 ());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
#define fader_cursor_height 25
|
#define fader_cursor_height 25
|
||||||
#define fader_cursor_x_hot 3
|
#define fader_cursor_x_hot 3
|
||||||
#define fader_cursor_y_hot 21
|
#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, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x30, 0x00,
|
||||||
0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0xfe, 0x01, 0x00, 0x00, 0x02, 0x01,
|
0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0xfe, 0x01, 0x00, 0x00, 0x02, 0x01,
|
||||||
0x00, 0x00, 0x02, 0x01, 0x00, 0x00, 0x02, 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 };
|
0x00, 0x00, 0x00, 0x00 };
|
||||||
|
|
||||||
/* Created with The GIMP */
|
/* 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, 0x30, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x78, 0x00,
|
||||||
0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0xfe, 0x01, 0x00, 0x00, 0xfe, 0x01,
|
0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0xfe, 0x01, 0x00, 0x00, 0xfe, 0x01,
|
||||||
0x00, 0x00, 0xfe, 0x01, 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_height 26
|
||||||
#define speaker_cursor_x_hot 0
|
#define speaker_cursor_x_hot 0
|
||||||
#define speaker_cursor_y_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,
|
0x00, 0xc0, 0x00, 0xc0, 0x00, 0xf0, 0x00, 0xf0, 0x00, 0xcc, 0x00, 0xcc,
|
||||||
0xff, 0xc3, 0xff, 0xc3, 0x03, 0xc0, 0x03, 0xc0, 0xc3, 0xc0, 0xc3, 0xc0,
|
0xff, 0xc3, 0xff, 0xc3, 0x03, 0xc0, 0x03, 0xc0, 0xc3, 0xc0, 0xc3, 0xc0,
|
||||||
0xc3, 0xc0, 0xc3, 0xc0, 0xc3, 0xc0, 0xc3, 0xc0, 0x03, 0xc0, 0x03, 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_height 26
|
||||||
#define speaker_cursor_mask_x_hot 0
|
#define speaker_cursor_mask_x_hot 0
|
||||||
#define speaker_cursor_mask_y_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,
|
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, 0x3f, 0xff, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0xff, 0x3f, 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_height 16
|
||||||
#define cursor_zoom_x_hot 6
|
#define cursor_zoom_x_hot 6
|
||||||
#define cursor_zoom_y_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,
|
0x00e0, 0x0000, 0x03b8, 0x0000, 0x0604, 0x0000, 0x0806, 0x0000, 0x0842,
|
||||||
0x0000, 0x1843, 0x0000, 0x11f1, 0x0000, 0x1843, 0x0000, 0x0842, 0x0000,
|
0x0000, 0x1843, 0x0000, 0x11f1, 0x0000, 0x1843, 0x0000, 0x0842, 0x0000,
|
||||||
0x1806, 0x0000, 0x2604, 0x0000, 0x4758, 0x0000, 0x88e0, 0x0000, 0x1000,
|
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_height 16
|
||||||
#define cursor_zoom_mask_x_hot 6
|
#define cursor_zoom_mask_x_hot 6
|
||||||
#define cursor_zoom_mask_y_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,
|
0x00e0, 0x0000, 0x03f8, 0x0000, 0x07fc, 0x0000, 0x0ffe, 0x0000, 0x0ffe,
|
||||||
0x0000, 0x1fff, 0x0000, 0x1fff, 0x0000, 0x1fff, 0x0000, 0x0ffe, 0x0000,
|
0x0000, 0x1fff, 0x0000, 0x1fff, 0x0000, 0x1fff, 0x0000, 0x0ffe, 0x0000,
|
||||||
0x1ffe, 0x0000, 0x3ffc, 0x0000, 0x7ff8, 0x0000, 0xf8e0, 0x0000, 0xf000,
|
0x1ffe, 0x0000, 0x3ffc, 0x0000, 0x7ff8, 0x0000, 0xf8e0, 0x0000, 0xf000,
|
||||||
|
|
|
||||||
|
|
@ -1107,6 +1107,9 @@ EngineControl::find_jack_servers (vector<string>& strings)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
jack_servers = scanner (path, jack_server_filter, 0, false, true);
|
jack_servers = scanner (path, jack_server_filter, 0, false, true);
|
||||||
|
if (!jack_servers) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
vector<string *>::iterator iter;
|
vector<string *>::iterator iter;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -131,7 +131,7 @@ ExportFormatDialog::ExportFormatDialog (FormatPtr format, bool new_dialog) :
|
||||||
close_button = add_button (Gtk::Stock::SAVE, Gtk::RESPONSE_APPLY);
|
close_button = add_button (Gtk::Stock::SAVE, Gtk::RESPONSE_APPLY);
|
||||||
close_button->set_sensitive (false);
|
close_button->set_sensitive (false);
|
||||||
close_button->signal_clicked().connect (sigc::mem_fun (*this, &ExportFormatDialog::end_dialog));
|
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_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));
|
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();
|
row[compatibility_cols.label] = (*it)->name();
|
||||||
|
|
||||||
WeakCompatPtr ptr (*it);
|
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);
|
compatibility_view.append_column_editable ("", compatibility_cols.selected);
|
||||||
|
|
@ -364,8 +364,8 @@ ExportFormatDialog::init_format_table ()
|
||||||
row[quality_cols.label] = (*it)->name();
|
row[quality_cols.label] = (*it)->name();
|
||||||
|
|
||||||
WeakQualityPtr ptr (*it);
|
WeakQualityPtr ptr (*it);
|
||||||
(*it)->SelectChanged.connect (*this, invalidator (*this), ui_bind (&ExportFormatDialog::change_quality_selection, 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), ui_bind (&ExportFormatDialog::change_quality_compatibility, 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);
|
quality_view.append_column ("", quality_cols.label);
|
||||||
|
|
@ -386,19 +386,19 @@ ExportFormatDialog::init_format_table ()
|
||||||
row[format_cols.label] = (*it)->name();
|
row[format_cols.label] = (*it)->name();
|
||||||
|
|
||||||
WeakFormatPtr ptr (*it);
|
WeakFormatPtr ptr (*it);
|
||||||
(*it)->SelectChanged.connect (*this, invalidator (*this), ui_bind (&ExportFormatDialog::change_format_selection, 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), ui_bind (&ExportFormatDialog::change_format_compatibility, this, _1, ptr), gui_context());
|
(*it)->CompatibleChanged.connect (*this, invalidator (*this), boost::bind (&ExportFormatDialog::change_format_compatibility, this, _1, ptr), gui_context());
|
||||||
|
|
||||||
/* Encoding options */
|
/* Encoding options */
|
||||||
|
|
||||||
boost::shared_ptr<HasSampleFormat> hsf;
|
boost::shared_ptr<HasSampleFormat> hsf;
|
||||||
|
|
||||||
if (hsf = boost::dynamic_pointer_cast<HasSampleFormat> (*it)) {
|
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->SampleFormatSelectChanged.connect (*this, invalidator (*this), boost::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->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->DitherTypeSelectChanged.connect (*this, invalidator (*this), boost::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->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();
|
row[sample_rate_cols.label] = (*it)->name();
|
||||||
|
|
||||||
WeakSampleRatePtr ptr (*it);
|
WeakSampleRatePtr ptr (*it);
|
||||||
(*it)->SelectChanged.connect (*this, invalidator (*this), ui_bind (&ExportFormatDialog::change_sample_rate_selection, 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), ui_bind (&ExportFormatDialog::change_sample_rate_compatibility, 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);
|
sample_rate_view.append_column ("", sample_rate_cols.label);
|
||||||
|
|
|
||||||
|
|
@ -192,7 +192,7 @@ GainMeterBase::set_controls (boost::shared_ptr<Route> r,
|
||||||
|
|
||||||
if (amp) {
|
if (amp) {
|
||||||
amp->ConfigurationChanged.connect (
|
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) {
|
if (_meter) {
|
||||||
_meter->ConfigurationChanged.connect (
|
_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 ());
|
meter_configuration_changed (_meter->input_streams ());
|
||||||
|
|
|
||||||
|
|
@ -101,6 +101,9 @@ GenericPluginUI::GenericPluginUI (boost::shared_ptr<PluginInsert> pi, bool scrol
|
||||||
VBox* v1_box = manage (new VBox);
|
VBox* v1_box = manage (new VBox);
|
||||||
VBox* v2_box = manage (new VBox);
|
VBox* v2_box = manage (new VBox);
|
||||||
pack_end (plugin_analysis_expander, false, false);
|
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);
|
v1_box->pack_start (*smaller_hbox, false, true);
|
||||||
v2_box->pack_start (focus_button, false, true);
|
v2_box->pack_start (focus_button, false, true);
|
||||||
|
|
@ -264,6 +267,11 @@ GenericPluginUI::build ()
|
||||||
continue;
|
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) {
|
if (cui->controller || cui->clickbox || cui->combo) {
|
||||||
// Get all of the controls into a list, so that
|
// Get all of the controls into a list, so that
|
||||||
// we can lay them out a bit more nicely later.
|
// we can lay them out a bit more nicely later.
|
||||||
|
|
|
||||||
|
|
@ -81,7 +81,7 @@ ImageFrameTimeAxis::ImageFrameTimeAxis(const string & track_id, PublicEditor& ed
|
||||||
// set the initial height of this time axis
|
// set the initial height of this time axis
|
||||||
set_height(hNormal) ;
|
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());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -52,7 +52,7 @@ ImageFrameTimeAxisGroup::ImageFrameTimeAxisGroup(ImageFrameTimeAxisView& iftav,
|
||||||
selected_imageframe_item = 0;
|
selected_imageframe_item = 0;
|
||||||
is_selected = false;
|
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());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -67,7 +67,7 @@ ImageFrameTimeAxisView::ImageFrameTimeAxisView (ImageFrameTimeAxis& tv)
|
||||||
selected_imageframe_group = 0 ;
|
selected_imageframe_group = 0 ;
|
||||||
selected_imageframe_view = 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());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -104,7 +104,7 @@ ImageFrameView::ImageFrameView(const string & item_id,
|
||||||
set_position(start, this);
|
set_position(start, this);
|
||||||
set_duration(duration, 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());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -193,9 +193,7 @@ KeyEditor::on_key_release_event (GdkEventKey* ev)
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
cerr << "real lkeyval: " << ev->keyval << endl;
|
|
||||||
Gtkmm2ext::possibly_translate_keyval_to_make_legal_accelerator (ev->keyval);
|
Gtkmm2ext::possibly_translate_keyval_to_make_legal_accelerator (ev->keyval);
|
||||||
cerr << "using keyval = " << ev->keyval << endl;
|
|
||||||
|
|
||||||
|
|
||||||
bool result = AccelMap::change_entry (path,
|
bool result = AccelMap::change_entry (path,
|
||||||
|
|
@ -203,8 +201,6 @@ KeyEditor::on_key_release_event (GdkEventKey* ev)
|
||||||
ModifierType (Keyboard::RelevantModifierKeyMask & ev->state),
|
ModifierType (Keyboard::RelevantModifierKeyMask & ev->state),
|
||||||
true);
|
true);
|
||||||
|
|
||||||
cerr << "New binding to " << ev->keyval << " worked: " << result << endl;
|
|
||||||
|
|
||||||
if (result) {
|
if (result) {
|
||||||
AccelKey key;
|
AccelKey key;
|
||||||
(*i)[columns.binding] = ActionManager::get_key_representation (path, key);
|
(*i)[columns.binding] = ActionManager::get_key_representation (path, key);
|
||||||
|
|
|
||||||
|
|
@ -59,7 +59,7 @@ LevelMeter::LevelMeter (Session* s)
|
||||||
{
|
{
|
||||||
set_session (s);
|
set_session (s);
|
||||||
set_spacing (1);
|
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));
|
UI::instance()->theme_changed.connect (sigc::mem_fun(*this, &LevelMeter::on_theme_changed));
|
||||||
ColorsChanged.connect (sigc::mem_fun (*this, &LevelMeter::color_handler));
|
ColorsChanged.connect (sigc::mem_fun (*this, &LevelMeter::color_handler));
|
||||||
max_peak = minus_infinity();
|
max_peak = minus_infinity();
|
||||||
|
|
@ -85,7 +85,7 @@ LevelMeter::set_meter (PeakMeter* meter)
|
||||||
_meter = meter;
|
_meter = meter;
|
||||||
|
|
||||||
if (_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());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -328,13 +328,13 @@ LocationEditRow::set_location (Location *loc)
|
||||||
|
|
||||||
--i_am_the_modifier;
|
--i_am_the_modifier;
|
||||||
|
|
||||||
location->start_changed.connect (connections, invalidator (*this), ui_bind (&LocationEditRow::start_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), ui_bind (&LocationEditRow::end_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), ui_bind (&LocationEditRow::name_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), ui_bind (&LocationEditRow::location_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), ui_bind (&LocationEditRow::flags_changed, this, _1, _2), gui_context());
|
location->FlagsChanged.connect (connections, invalidator (*this), boost::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->LockChanged.connect (connections, invalidator (*this), boost::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->PositionLockStyleChanged.connect (connections, invalidator (*this), boost::bind (&LocationEditRow::position_lock_style_changed, this, _1), gui_context());
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
@ -1056,8 +1056,8 @@ LocationUI::set_session(ARDOUR::Session* s)
|
||||||
if (_session) {
|
if (_session) {
|
||||||
_session->locations()->changed.connect (_session_connections, invalidator (*this), boost::bind (&LocationUI::locations_changed, this, _1), gui_context());
|
_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()->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()->added.connect (_session_connections, invalidator (*this), boost::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()->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 ());
|
_clock_group->set_clock_mode (clock_mode_from_session_instant_xml ());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -20,12 +20,13 @@
|
||||||
#include "ardour/lv2_plugin.h"
|
#include "ardour/lv2_plugin.h"
|
||||||
#include "ardour/plugin_manager.h"
|
#include "ardour/plugin_manager.h"
|
||||||
#include "ardour/processor.h"
|
#include "ardour/processor.h"
|
||||||
|
#include "ardour/session.h"
|
||||||
|
|
||||||
#include "ardour_ui.h"
|
#include "ardour_ui.h"
|
||||||
#include "gui_thread.h"
|
#include "gui_thread.h"
|
||||||
#include "lv2_plugin_ui.h"
|
#include "lv2_plugin_ui.h"
|
||||||
|
|
||||||
#include "lv2_ui.h"
|
#include "lv2/lv2plug.in/ns/extensions/ui/ui.h"
|
||||||
|
|
||||||
#include <lilv/lilv.h>
|
#include <lilv/lilv.h>
|
||||||
#include <suil/suil.h>
|
#include <suil/suil.h>
|
||||||
|
|
@ -68,13 +69,36 @@ LV2PluginUI::write_to_ui(void* controller,
|
||||||
const void* buffer)
|
const void* buffer)
|
||||||
{
|
{
|
||||||
LV2PluginUI* me = (LV2PluginUI*)controller;
|
LV2PluginUI* me = (LV2PluginUI*)controller;
|
||||||
|
|
||||||
if (me->_inst) {
|
if (me->_inst) {
|
||||||
suil_instance_port_event((SuilInstance*)me->_inst,
|
suil_instance_port_event((SuilInstance*)me->_inst,
|
||||||
port_index, buffer_size, format, buffer);
|
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
|
void
|
||||||
LV2PluginUI::update_timeout()
|
LV2PluginUI::update_timeout()
|
||||||
{
|
{
|
||||||
|
|
@ -196,7 +220,10 @@ LV2PluginUI::lv2ui_instantiate(const std::string& title)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ui_host) {
|
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)
|
const char* container_type = (is_external_ui)
|
||||||
? NS_UI "external"
|
? NS_UI "external"
|
||||||
|
|
@ -245,7 +272,7 @@ LV2PluginUI::lv2ui_instantiate(const std::string& title)
|
||||||
pack_start(*_ardour_buttons_box, false, false);
|
pack_start(*_ardour_buttons_box, false, false);
|
||||||
|
|
||||||
GtkWidget* c_widget = (GtkWidget*)GET_WIDGET(_inst);
|
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();
|
_gui_widget->show_all();
|
||||||
pack_start(*_gui_widget, true, true);
|
pack_start(*_gui_widget, true, true);
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -283,18 +310,13 @@ LV2PluginUI::lv2ui_free()
|
||||||
|
|
||||||
if (_gui_widget) {
|
if (_gui_widget) {
|
||||||
remove (*_gui_widget);
|
remove (*_gui_widget);
|
||||||
|
_gui_widget = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_ardour_buttons_box) {
|
if (_inst) {
|
||||||
remove (*_ardour_buttons_box);
|
suil_instance_free((SuilInstance*)_inst);
|
||||||
delete _ardour_buttons_box;
|
_inst = NULL;
|
||||||
_ardour_buttons_box = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
suil_instance_free((SuilInstance*)_inst);
|
|
||||||
|
|
||||||
_inst = NULL;
|
|
||||||
_gui_widget = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
LV2PluginUI::~LV2PluginUI ()
|
LV2PluginUI::~LV2PluginUI ()
|
||||||
|
|
|
||||||
|
|
@ -94,6 +94,12 @@ class LV2PluginUI : public PlugUIBase, public Gtk::VBox
|
||||||
uint32_t format,
|
uint32_t format,
|
||||||
const void* buffer);
|
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 update_timeout();
|
||||||
|
|
||||||
void lv2ui_instantiate(const std::string& title);
|
void lv2ui_instantiate(const std::string& title);
|
||||||
|
|
|
||||||
|
|
@ -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
|
|
||||||
|
|
@ -67,7 +67,7 @@ MarkerTimeAxisView::MarkerTimeAxisView(MarkerTimeAxis& tv)
|
||||||
_samples_per_unit = _trackview.editor.get_current_zoom() ;
|
_samples_per_unit = _trackview.editor.get_current_zoom() ;
|
||||||
|
|
||||||
_trackview.editor.ZoomChanged.connect (sigc::mem_fun(*this, &MarkerTimeAxisView::reset_samples_per_unit));
|
_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());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -180,8 +180,8 @@ MidiListEditor::scroll_event (GdkEventScroll* ev)
|
||||||
TreeViewColumn* col;
|
TreeViewColumn* col;
|
||||||
int cellx;
|
int cellx;
|
||||||
int celly;
|
int celly;
|
||||||
int idelta;
|
int idelta = 0;
|
||||||
double fdelta;
|
double fdelta = 0;
|
||||||
MidiModel::NoteDiffCommand::Property prop (MidiModel::NoteDiffCommand::NoteNumber);
|
MidiModel::NoteDiffCommand::Property prop (MidiModel::NoteDiffCommand::NoteNumber);
|
||||||
bool apply = false;
|
bool apply = false;
|
||||||
bool was_selected = false;
|
bool was_selected = false;
|
||||||
|
|
@ -586,8 +586,8 @@ MidiListEditor::edited (const std::string& path, const std::string& text)
|
||||||
double fval;
|
double fval;
|
||||||
int ival;
|
int ival;
|
||||||
bool apply = false;
|
bool apply = false;
|
||||||
int idelta;
|
int idelta = 0;
|
||||||
double fdelta;
|
double fdelta = 0;
|
||||||
char* opname;
|
char* opname;
|
||||||
switch (edit_column) {
|
switch (edit_column) {
|
||||||
case 0: // start
|
case 0: // start
|
||||||
|
|
|
||||||
|
|
@ -116,10 +116,10 @@ MidiRegionView::MidiRegionView (ArdourCanvas::Group *parent, RouteTimeAxisView &
|
||||||
_note_group->raise_to_top();
|
_note_group->raise_to_top();
|
||||||
PublicEditor::DropDownKeys.connect (sigc::mem_fun (*this, &MidiRegionView::drop_down_keys));
|
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 ();
|
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,
|
MidiRegionView::MidiRegionView (ArdourCanvas::Group *parent, RouteTimeAxisView &tv,
|
||||||
|
|
@ -155,7 +155,7 @@ MidiRegionView::MidiRegionView (ArdourCanvas::Group *parent, RouteTimeAxisView &
|
||||||
|
|
||||||
connect_to_diskstream ();
|
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
|
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));
|
PublicEditor::DropDownKeys.connect (sigc::mem_fun (*this, &MidiRegionView::drop_down_keys));
|
||||||
|
|
||||||
CanvasNoteEvent::CanvasNoteEventDeleted.connect (note_delete_connection, MISSING_INVALIDATOR,
|
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());
|
gui_context());
|
||||||
|
|
||||||
if (wfd) {
|
if (wfd) {
|
||||||
|
|
@ -288,13 +288,13 @@ MidiRegionView::init (Gdk::Color const & basic_color, bool wfd)
|
||||||
sigc::mem_fun(this, &MidiRegionView::midi_patch_settings_changed));
|
sigc::mem_fun(this, &MidiRegionView::midi_patch_settings_changed));
|
||||||
|
|
||||||
trackview.editor().SnapChanged.connect(snap_changed_connection, invalidator(*this),
|
trackview.editor().SnapChanged.connect(snap_changed_connection, invalidator(*this),
|
||||||
ui_bind(&MidiRegionView::snap_changed, this),
|
boost::bind (&MidiRegionView::snap_changed, this),
|
||||||
gui_context());
|
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 ();
|
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>
|
const boost::shared_ptr<ARDOUR::MidiRegion>
|
||||||
|
|
@ -308,7 +308,7 @@ MidiRegionView::connect_to_diskstream ()
|
||||||
{
|
{
|
||||||
midi_view()->midi_track()->DataRecorded.connect(
|
midi_view()->midi_track()->DataRecorded.connect(
|
||||||
*this, invalidator(*this),
|
*this, invalidator(*this),
|
||||||
ui_bind(&MidiRegionView::data_recorded, this, _1),
|
boost::bind (&MidiRegionView::data_recorded, this, _1),
|
||||||
gui_context());
|
gui_context());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -380,7 +380,7 @@ bool
|
||||||
MidiRegionView::enter_notify (GdkEventCrossing* ev)
|
MidiRegionView::enter_notify (GdkEventCrossing* ev)
|
||||||
{
|
{
|
||||||
trackview.editor().MouseModeChanged.connect (
|
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) {
|
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);
|
ghost->set_duration (_region->length() / samples_per_unit);
|
||||||
ghosts.push_back (ghost);
|
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;
|
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 ref_point = source_beats_to_absolute_frames ((*(_selection.begin()))->note()->time());
|
||||||
framepos_t unused;
|
framepos_t unused;
|
||||||
framepos_t distance;
|
framecnt_t distance;
|
||||||
|
|
||||||
if (trackview.editor().snap_mode() == Editing::SnapOff) {
|
if (trackview.editor().snap_mode() == Editing::SnapOff) {
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,7 @@
|
||||||
|
|
||||||
MidiRegionSelection::MidiRegionSelection ()
|
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.
|
/** Copy constructor.
|
||||||
|
|
@ -33,7 +33,7 @@ MidiRegionSelection::MidiRegionSelection ()
|
||||||
MidiRegionSelection::MidiRegionSelection (MidiRegionSelection const & other)
|
MidiRegionSelection::MidiRegionSelection (MidiRegionSelection const & other)
|
||||||
: std::list<MidiRegionView*> (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());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -63,7 +63,6 @@
|
||||||
#include "automation_time_axis.h"
|
#include "automation_time_axis.h"
|
||||||
#include "canvas-note-event.h"
|
#include "canvas-note-event.h"
|
||||||
#include "canvas_impl.h"
|
#include "canvas_impl.h"
|
||||||
#include "crossfade_view.h"
|
|
||||||
#include "editor.h"
|
#include "editor.h"
|
||||||
#include "enums.h"
|
#include "enums.h"
|
||||||
#include "ghostregion.h"
|
#include "ghostregion.h"
|
||||||
|
|
@ -160,7 +159,7 @@ MidiTimeAxisView::set_route (boost::shared_ptr<Route> rt)
|
||||||
|
|
||||||
processors_changed (RouteProcessorChange ());
|
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()) {
|
if (is_track()) {
|
||||||
_piano_roll_header->SetNoteSelection.connect (sigc::mem_fun (*this, &MidiTimeAxisView::set_note_selection));
|
_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();
|
for (std::list<std::string>::const_iterator i = device_modes.begin();
|
||||||
i != device_modes.end(); ++i) {
|
i != device_modes.end(); ++i) {
|
||||||
cerr << "found custom device mode " << *i << " thread_id: " << pthread_self() << endl;
|
|
||||||
_custom_device_mode_selector.append_text(*i);
|
_custom_device_mode_selector.append_text(*i);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -112,7 +112,7 @@ MixerStrip::MixerStrip (Mixer_UI& mx, Session* sess, boost::shared_ptr<Route> rt
|
||||||
, RouteUI (sess)
|
, RouteUI (sess)
|
||||||
, _mixer(mx)
|
, _mixer(mx)
|
||||||
, _mixer_owned (in_mixer)
|
, _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)
|
, gpm (sess, 250)
|
||||||
, panners (sess)
|
, panners (sess)
|
||||||
, button_size_group (Gtk::SizeGroup::create (Gtk::SIZE_GROUP_HORIZONTAL))
|
, button_size_group (Gtk::SizeGroup::create (Gtk::SIZE_GROUP_HORIZONTAL))
|
||||||
|
|
@ -355,7 +355,7 @@ MixerStrip::init ()
|
||||||
|
|
||||||
parameter_changed (X_("mixer-strip-visibility"));
|
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));
|
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());
|
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->comment_changed.connect (route_connections, invalidator (*this), boost::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->PropertyChanged.connect (route_connections, invalidator (*this), boost::bind (&MixerStrip::property_changed, this, _1), gui_context());
|
||||||
|
|
||||||
set_stuff_from_route ();
|
set_stuff_from_route ();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -95,7 +95,7 @@ Mixer_UI::Mixer_UI ()
|
||||||
strip_redisplay_does_not_sync_order_keys = false;
|
strip_redisplay_does_not_sync_order_keys = false;
|
||||||
ignore_sync = 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.set_flags (Gtk::CAN_FOCUS);
|
||||||
scroller_base.add_events (Gdk::BUTTON_PRESS_MASK|Gdk::BUTTON_RELEASE_MASK);
|
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;
|
_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 ();
|
MonitorSection::setup_knob_images ();
|
||||||
|
|
||||||
|
|
@ -340,7 +340,7 @@ Mixer_UI::add_strip (RouteList& routes)
|
||||||
_monitor_section->set_session (_session);
|
_monitor_section->set_session (_session);
|
||||||
_monitor_section->tearoff().show_all ();
|
_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 */
|
/* 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->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->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));
|
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 ();
|
initial_track_display ();
|
||||||
|
|
||||||
_session->RouteAdded.connect (_session_connections, invalidator (*this), ui_bind (&Mixer_UI::add_strip, 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), ui_bind (&Mixer_UI::add_route_group, 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_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->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->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 ();
|
route_groups_changed ();
|
||||||
|
|
||||||
|
|
@ -1395,7 +1395,7 @@ Mixer_UI::add_route_group (RouteGroup* group)
|
||||||
focus = true;
|
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) {
|
if (focus) {
|
||||||
TreeViewColumn* col = group_display.get_column (0);
|
TreeViewColumn* col = group_display.get_column (0);
|
||||||
|
|
|
||||||
|
|
@ -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
|
@rop|Region/naturalize-region|<@SECONDARY@>o|move to original position
|
||||||
@trans|Editor/set-playhead|p|set playhead position
|
@trans|Editor/set-playhead|p|set playhead position
|
||||||
@select|Editor/select-all-before-playhead|<@PRIMARY@>p|all before playhead
|
@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-audio-connection-manager|<@WINDOW@>p|toggle global audio patchbay
|
||||||
@wvis|Common/toggle-midi-connection-manager|<@WINDOW@><@TERTIARY@>p|toggle global midi 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)
|
@midi|MIDI/panic|<@PRIMARY@><@SECONDARY@>p|MIDI panic (stop all notes etc)
|
||||||
|
|
|
||||||
|
|
@ -36,6 +36,8 @@ MonitorSection::MonitorSection (Session* s)
|
||||||
: AxisView (s)
|
: AxisView (s)
|
||||||
, RouteUI (s)
|
, RouteUI (s)
|
||||||
, _tearoff (0)
|
, _tearoff (0)
|
||||||
|
, channel_table_viewport (*channel_table_scroller.get_hadjustment(),
|
||||||
|
*channel_table_scroller.get_vadjustment ())
|
||||||
, gain_control (0)
|
, gain_control (0)
|
||||||
, dim_control (0)
|
, dim_control (0)
|
||||||
, solo_boost_control (0)
|
, solo_boost_control (0)
|
||||||
|
|
@ -257,7 +259,8 @@ MonitorSection::MonitorSection (Session* s)
|
||||||
channel_table_scroller.set_size_request (-1, 150);
|
channel_table_scroller.set_size_request (-1, 150);
|
||||||
channel_table_scroller.set_shadow_type (Gtk::SHADOW_NONE);
|
channel_table_scroller.set_shadow_type (Gtk::SHADOW_NONE);
|
||||||
channel_table_scroller.show ();
|
channel_table_scroller.show ();
|
||||||
|
channel_table_scroller.add (channel_table_viewport);
|
||||||
|
|
||||||
channel_size_group = SizeGroup::create (SIZE_GROUP_HORIZONTAL);
|
channel_size_group = SizeGroup::create (SIZE_GROUP_HORIZONTAL);
|
||||||
channel_size_group->add_widget (channel_table_header);
|
channel_size_group->add_widget (channel_table_header);
|
||||||
channel_size_group->add_widget (channel_table);
|
channel_size_group->add_widget (channel_table);
|
||||||
|
|
@ -318,7 +321,7 @@ MonitorSection::MonitorSection (Session* s)
|
||||||
|
|
||||||
/* catch changes that affect us */
|
/* 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 ()
|
MonitorSection::~MonitorSection ()
|
||||||
|
|
@ -357,23 +360,24 @@ MonitorSection::set_session (Session* s)
|
||||||
if (channel_table_scroller.get_parent()) {
|
if (channel_table_scroller.get_parent()) {
|
||||||
/* scroller is packed, so remove it */
|
/* scroller is packed, so remove it */
|
||||||
channel_table_packer.remove (channel_table_scroller);
|
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
|
/* this occurs when the table hpacker is directly
|
||||||
packed, so remove it.
|
packed, so remove it.
|
||||||
*/
|
*/
|
||||||
channel_table_packer.remove (table_hpacker);
|
channel_table_packer.remove (table_hpacker);
|
||||||
|
} else if (table_hpacker.get_parent()) {
|
||||||
|
channel_table_viewport.remove ();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_monitor->output_streams().n_audio() > 7) {
|
if (_monitor->output_streams().n_audio() > 7) {
|
||||||
/* put the table into a scrolled window, and then put
|
/* put the table into a scrolled window, and then put
|
||||||
* that into the channel vpacker, after the table header
|
* 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_packer.pack_start (channel_table_scroller, true, true);
|
||||||
|
channel_table_viewport.show ();
|
||||||
channel_table_scroller.show ();
|
channel_table_scroller.show ();
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
|
|
@ -59,6 +59,7 @@ class MonitorSection : public RouteUI
|
||||||
Gtk::Table channel_table;
|
Gtk::Table channel_table;
|
||||||
Gtk::Table channel_table_header;
|
Gtk::Table channel_table_header;
|
||||||
Gtk::ScrolledWindow channel_table_scroller;
|
Gtk::ScrolledWindow channel_table_scroller;
|
||||||
|
Gtk::Viewport channel_table_viewport;
|
||||||
Glib::RefPtr<Gtk::SizeGroup> channel_size_group;
|
Glib::RefPtr<Gtk::SizeGroup> channel_size_group;
|
||||||
|
|
||||||
struct ChannelButtonSet {
|
struct ChannelButtonSet {
|
||||||
|
|
|
||||||
|
|
@ -41,14 +41,14 @@ MouseCursors::MouseCursors ()
|
||||||
Color ffg ("#000000");
|
Color ffg ("#000000");
|
||||||
|
|
||||||
{
|
{
|
||||||
RefPtr<Bitmap> source = Bitmap::create (fader_cursor_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 (fader_cursor_mask_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);
|
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> source = Bitmap::create ((char const *) 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> 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);
|
speaker = new Cursor (source, mask, ffg, fbg, speaker_cursor_x_hot, speaker_cursor_y_hot);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -291,7 +291,7 @@ OptionEditor::OptionEditor (Configuration* c, std::string const & t)
|
||||||
show_all_children();
|
show_all_children();
|
||||||
|
|
||||||
/* Watch out for changes to parameters */
|
/* 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 ()
|
OptionEditor::~OptionEditor ()
|
||||||
|
|
|
||||||
|
|
@ -145,7 +145,8 @@ PlaylistSelector::show_for (RouteUI* ruix)
|
||||||
}
|
}
|
||||||
|
|
||||||
TreeModel::Row row;
|
TreeModel::Row row;
|
||||||
TreeModel::Row* selected_row = 0;
|
TreeModel::Row selected_row;
|
||||||
|
bool have_selected = false;
|
||||||
TreePath this_path;
|
TreePath this_path;
|
||||||
|
|
||||||
if (tr == this_track) {
|
if (tr == this_track) {
|
||||||
|
|
@ -173,12 +174,13 @@ PlaylistSelector::show_for (RouteUI* ruix)
|
||||||
child_row[columns.playlist] = *p;
|
child_row[columns.playlist] = *p;
|
||||||
|
|
||||||
if (*p == this_track->playlist()) {
|
if (*p == this_track->playlist()) {
|
||||||
selected_row = &child_row;
|
selected_row = child_row;
|
||||||
|
have_selected = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (selected_row != 0) {
|
if (have_selected) {
|
||||||
tree.get_selection()->select (*selected_row);
|
tree.get_selection()->select (selected_row);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -187,7 +189,8 @@ PlaylistSelector::show_for (RouteUI* ruix)
|
||||||
_session->playlists->unassigned (unassigned);
|
_session->playlists->unassigned (unassigned);
|
||||||
|
|
||||||
TreeModel::Row row;
|
TreeModel::Row row;
|
||||||
TreeModel::Row* selected_row = 0;
|
TreeModel::Row selected_row;
|
||||||
|
bool have_selected = false;
|
||||||
TreePath this_path;
|
TreePath this_path;
|
||||||
|
|
||||||
row = *(model->append (others.children()));
|
row = *(model->append (others.children()));
|
||||||
|
|
@ -203,11 +206,12 @@ PlaylistSelector::show_for (RouteUI* ruix)
|
||||||
child_row[columns.playlist] = *p;
|
child_row[columns.playlist] = *p;
|
||||||
|
|
||||||
if (*p == this_track->playlist()) {
|
if (*p == this_track->playlist()) {
|
||||||
selected_row = &child_row;
|
selected_row = child_row;
|
||||||
|
have_selected = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (selected_row != 0) {
|
if (have_selected) {
|
||||||
tree.get_selection()->select (*selected_row);
|
tree.get_selection()->select (selected_row);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -141,7 +141,7 @@ PluginEqGui::start_listening ()
|
||||||
_plugin->activate();
|
_plugin->activate();
|
||||||
set_buffer_size(4096, 16384);
|
set_buffer_size(4096, 16384);
|
||||||
// Connect the realtime signal collection callback
|
// 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
|
void
|
||||||
|
|
|
||||||
|
|
@ -181,7 +181,7 @@ PluginSelector::PluginSelector (PluginManager& mgr)
|
||||||
//plugin_display.set_name("PluginSelectorList");
|
//plugin_display.set_name("PluginSelectorList");
|
||||||
added_list.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.get_selection()->signal_changed().connect (sigc::mem_fun(*this, &PluginSelector::display_selection_changed));
|
||||||
plugin_display.grab_focus();
|
plugin_display.grab_focus();
|
||||||
|
|
||||||
|
|
@ -199,11 +199,9 @@ PluginSelector::~PluginSelector ()
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
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
|
bool
|
||||||
|
|
|
||||||
|
|
@ -118,7 +118,7 @@ class PluginSelector : public ArdourDialog
|
||||||
Gtk::Menu* _plugin_menu;
|
Gtk::Menu* _plugin_menu;
|
||||||
ARDOUR::PluginManager& manager;
|
ARDOUR::PluginManager& manager;
|
||||||
|
|
||||||
void row_clicked(GdkEventButton *);
|
void row_activated(Gtk::TreeModel::Path path, Gtk::TreeViewColumn* col);
|
||||||
void btn_add_clicked();
|
void btn_add_clicked();
|
||||||
void btn_remove_clicked();
|
void btn_remove_clicked();
|
||||||
void btn_update_clicked();
|
void btn_update_clicked();
|
||||||
|
|
|
||||||
|
|
@ -452,6 +452,7 @@ PlugUIBase::PlugUIBase (boost::shared_ptr<PluginInsert> pi)
|
||||||
, save_button (_("Save"))
|
, save_button (_("Save"))
|
||||||
, delete_button (_("Delete"))
|
, delete_button (_("Delete"))
|
||||||
, bypass_button (ArdourButton::led_default_elements)
|
, bypass_button (ArdourButton::led_default_elements)
|
||||||
|
, description_expander (_("Description"))
|
||||||
, plugin_analysis_expander (_("Plugin analysis"))
|
, plugin_analysis_expander (_("Plugin analysis"))
|
||||||
, latency_gui (0)
|
, latency_gui (0)
|
||||||
, latency_dialog (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 (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"));
|
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.property_expanded().signal_changed().connect( sigc::mem_fun(*this, &PlugUIBase::toggle_plugin_analysis));
|
||||||
plugin_analysis_expander.set_expanded(false);
|
plugin_analysis_expander.set_expanded(false);
|
||||||
|
|
||||||
|
|
@ -662,11 +666,34 @@ PlugUIBase::focus_toggled (GdkEventButton*)
|
||||||
return true;
|
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
|
void
|
||||||
PlugUIBase::toggle_plugin_analysis()
|
PlugUIBase::toggle_plugin_analysis()
|
||||||
{
|
{
|
||||||
if (plugin_analysis_expander.get_expanded() &&
|
if (plugin_analysis_expander.get_expanded() &&
|
||||||
!plugin_analysis_expander.get_child()) {
|
!plugin_analysis_expander.get_child()) {
|
||||||
// Create the GUI
|
// Create the GUI
|
||||||
if (eqgui == 0) {
|
if (eqgui == 0) {
|
||||||
eqgui = new PluginEqGui (insert);
|
eqgui = new PluginEqGui (insert);
|
||||||
|
|
@ -684,7 +711,6 @@ PlugUIBase::toggle_plugin_analysis()
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!plugin_analysis_expander.get_expanded()) {
|
if (!plugin_analysis_expander.get_expanded()) {
|
||||||
|
|
||||||
// Hide & remove from expander
|
// Hide & remove from expander
|
||||||
|
|
||||||
eqgui->hide ();
|
eqgui->hide ();
|
||||||
|
|
|
||||||
|
|
@ -125,6 +125,8 @@ class PlugUIBase : public virtual sigc::trackable, public PBD::ScopedConnectionL
|
||||||
ArdourButton bypass_button;
|
ArdourButton bypass_button;
|
||||||
/** a button to acquire keyboard focus */
|
/** a button to acquire keyboard focus */
|
||||||
Gtk::EventBox focus_button;
|
Gtk::EventBox focus_button;
|
||||||
|
/** an expander containing the plugin description */
|
||||||
|
Gtk::Expander description_expander;
|
||||||
/** an expander containing the plugin analysis graph */
|
/** an expander containing the plugin analysis graph */
|
||||||
Gtk::Expander plugin_analysis_expander;
|
Gtk::Expander plugin_analysis_expander;
|
||||||
/** a label indicating the plugin latency */
|
/** a label indicating the plugin latency */
|
||||||
|
|
@ -150,6 +152,7 @@ class PlugUIBase : public virtual sigc::trackable, public PBD::ScopedConnectionL
|
||||||
void delete_plugin_setting ();
|
void delete_plugin_setting ();
|
||||||
bool focus_toggled(GdkEventButton*);
|
bool focus_toggled(GdkEventButton*);
|
||||||
bool bypass_button_release(GdkEventButton*);
|
bool bypass_button_release(GdkEventButton*);
|
||||||
|
void toggle_description ();
|
||||||
void toggle_plugin_analysis ();
|
void toggle_plugin_analysis ();
|
||||||
void processor_active_changed (boost::weak_ptr<ARDOUR::Processor> p);
|
void processor_active_changed (boost::weak_ptr<ARDOUR::Processor> p);
|
||||||
void plugin_going_away ();
|
void plugin_going_away ();
|
||||||
|
|
|
||||||
|
|
@ -21,11 +21,10 @@
|
||||||
#define __ardour_gtk_point_selection_h__
|
#define __ardour_gtk_point_selection_h__
|
||||||
|
|
||||||
#include <list>
|
#include <list>
|
||||||
#include <boost/noncopyable.hpp>
|
|
||||||
|
|
||||||
#include "automation_range.h"
|
class ControlPoint;
|
||||||
|
|
||||||
struct PointSelection : public std::list<AutomationRange>
|
struct PointSelection : public std::list<ControlPoint *>
|
||||||
{
|
{
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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);
|
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);
|
_bundles.push_back (br);
|
||||||
|
|
||||||
Changed ();
|
Changed ();
|
||||||
|
|
@ -695,7 +695,7 @@ PortGroupList::add_group (boost::shared_ptr<PortGroup> g)
|
||||||
_groups.push_back (g);
|
_groups.push_back (g);
|
||||||
|
|
||||||
g->Changed.connect (_changed_connections, invalidator (*this), boost::bind (&PortGroupList::emit_changed, this), gui_context());
|
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 ();
|
emit_changed ();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -179,7 +179,7 @@ PortMatrix::reconnect_to_routes ()
|
||||||
|
|
||||||
boost::shared_ptr<RouteList> routes = _session->get_routes ();
|
boost::shared_ptr<RouteList> routes = _session->get_routes ();
|
||||||
for (RouteList::iterator i = routes->begin(); i != routes->end(); ++i) {
|
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());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -119,7 +119,7 @@ ProcessorEntry::ProcessorEntry (ProcessorBox* parent, boost::shared_ptr<Processo
|
||||||
_button.show ();
|
_button.show ();
|
||||||
|
|
||||||
_processor->ActiveChanged.connect (active_connection, invalidator (*this), boost::bind (&ProcessorEntry::processor_active_changed, this), gui_context());
|
_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 ();
|
set<Evoral::Parameter> p = _processor->what_can_be_automated ();
|
||||||
for (set<Evoral::Parameter>::iterator i = p.begin(); i != p.end(); ++i) {
|
for (set<Evoral::Parameter>::iterator i = p.begin(); i != p.end(); ++i) {
|
||||||
|
|
@ -605,7 +605,7 @@ PluginInsertProcessorEntry::PluginInsertProcessorEntry (ProcessorBox* b, boost::
|
||||||
, _plugin_insert (p)
|
, _plugin_insert (p)
|
||||||
{
|
{
|
||||||
p->SplittingChanged.connect (
|
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);
|
_splitting_icon.set_size_request (-1, 12);
|
||||||
|
|
@ -723,7 +723,7 @@ ProcessorBox::ProcessorBox (ARDOUR::Session* sess, boost::function<PluginSelecto
|
||||||
|
|
||||||
if (parent) {
|
if (parent) {
|
||||||
parent->DeliveryChanged.connect (
|
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 = r;
|
||||||
|
|
||||||
_route->processors_changed.connect (
|
_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 (
|
_route->DropReferences.connect (
|
||||||
|
|
@ -765,7 +765,7 @@ ProcessorBox::set_route (boost::shared_ptr<Route> r)
|
||||||
);
|
);
|
||||||
|
|
||||||
_route->PropertyChanged.connect (
|
_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 ();
|
redisplay_processors ();
|
||||||
|
|
|
||||||
|
|
@ -73,7 +73,6 @@ class Selection;
|
||||||
class AutomationLine;
|
class AutomationLine;
|
||||||
class ControlPoint;
|
class ControlPoint;
|
||||||
class SelectionRect;
|
class SelectionRect;
|
||||||
class CrossfadeView;
|
|
||||||
class RouteTimeAxisView;
|
class RouteTimeAxisView;
|
||||||
class RegionView;
|
class RegionView;
|
||||||
class AudioRegionView;
|
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_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_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_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_event (GdkEvent* event, ArdourCanvas::Item*, AudioRegionView*) = 0;
|
||||||
virtual bool canvas_fade_in_handle_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;
|
virtual bool canvas_fade_out_event (GdkEvent* event, ArdourCanvas::Item*, AudioRegionView*) = 0;
|
||||||
|
|
|
||||||
|
|
@ -903,7 +903,7 @@ RCOptionEditor::RCOptionEditor ()
|
||||||
sigc::mem_fun (*_rc_config, &RCConfiguration::set_periodic_safety_backups)
|
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"),
|
add_option (_("Misc"),
|
||||||
new BoolOption (
|
new BoolOption (
|
||||||
|
|
@ -941,6 +941,17 @@ RCOptionEditor::RCOptionEditor ()
|
||||||
sigc::mem_fun (*_rc_config, &RCConfiguration::set_click_gain)
|
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 */
|
/* TRANSPORT */
|
||||||
|
|
||||||
add_option (_("Transport"),
|
add_option (_("Transport"),
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,6 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void parameter_changed (std::string const &);
|
void parameter_changed (std::string const &);
|
||||||
|
|
||||||
ARDOUR::RCConfiguration* _rc_config;
|
ARDOUR::RCConfiguration* _rc_config;
|
||||||
BoolOption* _solo_control_is_listen_control;
|
BoolOption* _solo_control_is_listen_control;
|
||||||
ComboOption<ARDOUR::ListenPosition>* _listen_position;
|
ComboOption<ARDOUR::ListenPosition>* _listen_position;
|
||||||
|
|
|
||||||
|
|
@ -189,7 +189,7 @@ RegionEditor::RegionEditor (Session* s, boost::shared_ptr<Region> r)
|
||||||
|
|
||||||
bounds_changed (change);
|
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;
|
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));
|
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
|
void
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,7 @@
|
||||||
#include "ardour/audioregion.h"
|
#include "ardour/audioregion.h"
|
||||||
#include "ardour/session.h"
|
#include "ardour/session.h"
|
||||||
|
|
||||||
|
#include "control_point.h"
|
||||||
#include "region_gain_line.h"
|
#include "region_gain_line.h"
|
||||||
#include "audio_region_view.h"
|
#include "audio_region_view.h"
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
|
|
@ -69,10 +70,6 @@ AudioRegionGainLine::start_drag_single (ControlPoint* cp, double x, float fracti
|
||||||
void
|
void
|
||||||
AudioRegionGainLine::remove_point (ControlPoint& cp)
|
AudioRegionGainLine::remove_point (ControlPoint& cp)
|
||||||
{
|
{
|
||||||
ModelRepresentation mr;
|
|
||||||
|
|
||||||
model_representation (cp, mr);
|
|
||||||
|
|
||||||
trackview.editor().session()->begin_reversible_command (_("remove control point"));
|
trackview.editor().session()->begin_reversible_command (_("remove control point"));
|
||||||
XMLNode &before = alist->get_state();
|
XMLNode &before = alist->get_state();
|
||||||
|
|
||||||
|
|
@ -82,7 +79,7 @@ AudioRegionGainLine::remove_point (ControlPoint& cp)
|
||||||
trackview.session()->add_command(new StatefulDiffCommand (rv.audio_region()));
|
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()->add_command (new MementoCommand<AutomationList>(*alist.get(), &before, &alist->get_state()));
|
||||||
trackview.editor().session()->commit_reversible_command ();
|
trackview.editor().session()->commit_reversible_command ();
|
||||||
|
|
|
||||||
|
|
@ -33,7 +33,7 @@ using namespace PBD;
|
||||||
*/
|
*/
|
||||||
RegionSelection::RegionSelection ()
|
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.
|
/** Copy constructor.
|
||||||
|
|
@ -42,7 +42,7 @@ RegionSelection::RegionSelection ()
|
||||||
RegionSelection::RegionSelection (const RegionSelection& other)
|
RegionSelection::RegionSelection (const RegionSelection& other)
|
||||||
: std::list<RegionView*>()
|
: 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) {
|
for (RegionSelection::const_iterator i = other.begin(); i != other.end(); ++i) {
|
||||||
add (*i);
|
add (*i);
|
||||||
|
|
|
||||||
|
|
@ -86,7 +86,7 @@ RegionView::RegionView (ArdourCanvas::Group* parent,
|
||||||
, _region_relative_time_converter(r->session().tempo_map(), r->position())
|
, _region_relative_time_converter(r->session().tempo_map(), r->position())
|
||||||
, _source_relative_time_converter(r->session().tempo_map(), r->position() - r->start())
|
, _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)
|
RegionView::RegionView (const RegionView& other)
|
||||||
|
|
@ -103,7 +103,7 @@ RegionView::RegionView (const RegionView& other)
|
||||||
valid = false;
|
valid = false;
|
||||||
_pixel_width = other._pixel_width;
|
_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)
|
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;
|
valid = false;
|
||||||
_pixel_width = other._pixel_width;
|
_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,
|
RegionView::RegionView (ArdourCanvas::Group* parent,
|
||||||
|
|
@ -195,7 +195,7 @@ RegionView::init (Gdk::Color const & basic_color, bool wfd)
|
||||||
|
|
||||||
set_height (trackview.current_height());
|
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));
|
group->signal_event().connect (sigc::bind (sigc::mem_fun (PublicEditor::instance(), &PublicEditor::canvas_region_view_event), group, this));
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -59,7 +59,7 @@ ReturnUI::ReturnUI (Gtk::Window* parent, boost::shared_ptr<Return> r, Session* s
|
||||||
show_all ();
|
show_all ();
|
||||||
|
|
||||||
_return->set_metering (true);
|
_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.setup_meters ();
|
||||||
_gpm.set_fader_name ("ReturnUIFrame");
|
_gpm.set_fader_name ("ReturnUIFrame");
|
||||||
|
|
|
||||||
|
|
@ -216,7 +216,7 @@ RhythmFerret::run_analysis ()
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
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());
|
TransientDetector t (_session->frame_rate());
|
||||||
|
|
||||||
|
|
@ -263,7 +263,7 @@ RhythmFerret::get_note_onset_function ()
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
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 {
|
try {
|
||||||
OnsetDetector t (_session->frame_rate());
|
OnsetDetector t (_session->frame_rate());
|
||||||
|
|
|
||||||
|
|
@ -180,7 +180,7 @@ RouteParams_UI::add_routes (RouteList& routes)
|
||||||
|
|
||||||
//route_select_list.rows().back().select ();
|
//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());
|
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) {
|
if (_session) {
|
||||||
boost::shared_ptr<RouteList> r = _session->get_routes();
|
boost::shared_ptr<RouteList> r = _session->get_routes();
|
||||||
add_routes (*r);
|
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 ();
|
start_updating ();
|
||||||
} else {
|
} else {
|
||||||
stop_updating ();
|
stop_updating ();
|
||||||
|
|
@ -461,7 +461,7 @@ RouteParams_UI::route_selected()
|
||||||
setup_processor_boxes();
|
setup_processor_boxes();
|
||||||
setup_latency_frame ();
|
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());
|
track_input_label.set_text (_route->name());
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -63,7 +63,7 @@ class RouteParams_UI : public ArdourWindow, public PBD::ScopedConnectionList
|
||||||
|
|
||||||
void set_session (ARDOUR::Session*);
|
void set_session (ARDOUR::Session*);
|
||||||
void session_going_away ();
|
void session_going_away ();
|
||||||
PluginSelector* plugin_selector() { return _plugin_selector; }
|
PluginSelector* plugin_selector() { return _plugin_selector; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Gtk::HBox global_hpacker;
|
Gtk::HBox global_hpacker;
|
||||||
|
|
|
||||||
|
|
@ -111,7 +111,7 @@ RouteProcessorSelection::add (RouteUI* r)
|
||||||
MixerStrip* ms = dynamic_cast<MixerStrip*> (r);
|
MixerStrip* ms = dynamic_cast<MixerStrip*> (r);
|
||||||
|
|
||||||
if (ms) {
|
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) {
|
if (!_no_route_change_signal) {
|
||||||
|
|
|
||||||
|
|
@ -68,7 +68,6 @@
|
||||||
#include "route_time_axis.h"
|
#include "route_time_axis.h"
|
||||||
#include "automation_time_axis.h"
|
#include "automation_time_axis.h"
|
||||||
#include "canvas_impl.h"
|
#include "canvas_impl.h"
|
||||||
#include "crossfade_view.h"
|
|
||||||
#include "enums.h"
|
#include "enums.h"
|
||||||
#include "gui_thread.h"
|
#include "gui_thread.h"
|
||||||
#include "keyboard.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);
|
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->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->input()->changed.connect (*this, invalidator (*this), boost::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->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);
|
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;
|
_y_position = -1;
|
||||||
|
|
||||||
_route->processors_changed.connect (*this, invalidator (*this), ui_bind (&RouteTimeAxisView::processors_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), ui_bind (&RouteTimeAxisView::route_property_changed, this, _1), gui_context());
|
_route->PropertyChanged.connect (*this, invalidator (*this), boost::bind (&RouteTimeAxisView::route_property_changed, this, _1), gui_context());
|
||||||
|
|
||||||
if (is_track()) {
|
if (is_track()) {
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -145,8 +145,8 @@ RouteUI::init ()
|
||||||
_session->TransportStateChange.connect (_session_connections, invalidator (*this), boost::bind (&RouteUI::check_rec_enable_sensitivity, this), gui_context());
|
_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->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());
|
_session->config.ParameterChanged.connect (*this, invalidator (*this), boost::bind (&RouteUI::parameter_changed, this, _1), gui_context());
|
||||||
Config->ParameterChanged.connect (*this, invalidator (*this), ui_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_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);
|
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());
|
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->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_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());
|
_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->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->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->io_changed.connect (route_connections, invalidator (*this), boost::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->gui_changed.connect (route_connections, invalidator (*this), boost::bind (&RouteUI::route_gui_changed, this, _1), gui_context ());
|
||||||
|
|
||||||
if (_session->writable() && is_track()) {
|
if (_session->writable() && is_track()) {
|
||||||
boost::shared_ptr<Track> t = boost::dynamic_pointer_cast<Track>(_route);
|
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()) {
|
if (is_midi_track()) {
|
||||||
midi_track()->StepEditStatusChange.connect (route_connections, invalidator (*this),
|
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());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -58,10 +58,13 @@ Selection::Selection (const PublicEditor* e)
|
||||||
/* we have disambiguate which remove() for the compiler */
|
/* we have disambiguate which remove() for the compiler */
|
||||||
|
|
||||||
void (Selection::*track_remove)(TimeAxisView*) = &Selection::remove;
|
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;
|
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
|
#if 0
|
||||||
|
|
@ -516,7 +519,6 @@ Selection::add (boost::shared_ptr<Evoral::ControlList> cl)
|
||||||
if (!al) {
|
if (!al) {
|
||||||
warning << "Programming error: Selected list is not an ARDOUR::AutomationList" << endmsg;
|
warning << "Programming error: Selected list is not an ARDOUR::AutomationList" << endmsg;
|
||||||
return;
|
return;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
if (find (lines.begin(), lines.end(), al) == lines.end()) {
|
if (find (lines.begin(), lines.end(), al) == lines.end()) {
|
||||||
lines.push_back (al);
|
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
|
void
|
||||||
Selection::remove (const TrackViewList& track_list)
|
Selection::remove (const TrackViewList& track_list)
|
||||||
{
|
{
|
||||||
|
|
@ -879,17 +890,22 @@ void
|
||||||
Selection::toggle (ControlPoint* cp)
|
Selection::toggle (ControlPoint* cp)
|
||||||
{
|
{
|
||||||
cp->set_selected (!cp->get_selected ());
|
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
|
void
|
||||||
Selection::toggle (vector<ControlPoint*> const & cps)
|
Selection::toggle (vector<ControlPoint*> const & cps)
|
||||||
{
|
{
|
||||||
for (vector<ControlPoint*>::const_iterator i = cps.begin(); i != cps.end(); ++i) {
|
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
|
void
|
||||||
|
|
@ -935,6 +951,13 @@ Selection::set (list<Selectable*> const & selectables)
|
||||||
add (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
|
void
|
||||||
Selection::add (list<Selectable*> const & selectables)
|
Selection::add (list<Selectable*> const & selectables)
|
||||||
|
|
@ -979,17 +1002,16 @@ void
|
||||||
Selection::add (ControlPoint* cp)
|
Selection::add (ControlPoint* cp)
|
||||||
{
|
{
|
||||||
cp->set_selected (true);
|
cp->set_selected (true);
|
||||||
set_point_selection_from_line (cp->line ());
|
points.push_back (cp);
|
||||||
|
PointsChanged (); /* EMIT SIGNAL */
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Selection::add (vector<ControlPoint*> const & cps)
|
Selection::add (vector<ControlPoint*> const & cps)
|
||||||
{
|
{
|
||||||
for (vector<ControlPoint*>::const_iterator i = cps.begin(); i != cps.end(); ++i) {
|
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
|
void
|
||||||
|
|
@ -999,18 +1021,11 @@ Selection::set (ControlPoint* cp)
|
||||||
return;
|
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) {
|
for (uint32_t i = 0; i < cp->line().npoints(); ++i) {
|
||||||
cp->line().nth (i)->set_selected (false);
|
cp->line().nth (i)->set_selected (false);
|
||||||
}
|
}
|
||||||
|
|
||||||
vector<ControlPoint*> cps;
|
add (cp);
|
||||||
cps.push_back (cp);
|
|
||||||
add (cps);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
@ -1083,73 +1098,6 @@ MarkerSelection::range (framepos_t& s, framepos_t& e)
|
||||||
e = std::max (s, 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&
|
XMLNode&
|
||||||
Selection::get_state () const
|
Selection::get_state () const
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -165,6 +165,7 @@ class Selection : public sigc::trackable, public PBD::ScopedConnectionList
|
||||||
void add (Marker*);
|
void add (Marker*);
|
||||||
void add (const std::list<Marker*>&);
|
void add (const std::list<Marker*>&);
|
||||||
void add (const RegionSelection&);
|
void add (const RegionSelection&);
|
||||||
|
void add (const PointSelection&);
|
||||||
void remove (TimeAxisView*);
|
void remove (TimeAxisView*);
|
||||||
void remove (const TrackViewList&);
|
void remove (const TrackViewList&);
|
||||||
void remove (const MidiNoteSelection&);
|
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<boost::shared_ptr<ARDOUR::Playlist> >&);
|
||||||
void remove (const std::list<Selectable*>&);
|
void remove (const std::list<Selectable*>&);
|
||||||
void remove (Marker*);
|
void remove (Marker*);
|
||||||
|
void remove (ControlPoint *);
|
||||||
|
|
||||||
void remove_regions (TimeAxisView *);
|
void remove_regions (TimeAxisView *);
|
||||||
|
|
||||||
|
|
@ -202,8 +204,6 @@ class Selection : public sigc::trackable, public PBD::ScopedConnectionList
|
||||||
int set_state (XMLNode const &, int);
|
int set_state (XMLNode const &, int);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void set_point_selection_from_line (AutomationLine const &);
|
|
||||||
|
|
||||||
PublicEditor const * editor;
|
PublicEditor const * editor;
|
||||||
uint32_t next_time_id;
|
uint32_t next_time_id;
|
||||||
bool _no_tracks_changed;
|
bool _no_tracks_changed;
|
||||||
|
|
|
||||||
|
|
@ -72,7 +72,7 @@ SendUI::SendUI (Gtk::Window* parent, boost::shared_ptr<Send> s, Session* session
|
||||||
|
|
||||||
_send->set_metering (true);
|
_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.set_width (Wide);
|
||||||
_panners.setup_pan ();
|
_panners.setup_pan ();
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,7 @@
|
||||||
#include "ardour/session.h"
|
#include "ardour/session.h"
|
||||||
#include "ardour/session_directory.h"
|
#include "ardour/session_directory.h"
|
||||||
#include "ardour/session_utils.h"
|
#include "ardour/session_utils.h"
|
||||||
|
#include "ardour/configuration.h"
|
||||||
|
|
||||||
#include "i18n.h"
|
#include "i18n.h"
|
||||||
|
|
||||||
|
|
@ -81,8 +82,8 @@ TextMetadataField::load_data (ARDOUR::SessionMetadata const & data)
|
||||||
Gtk::Widget &
|
Gtk::Widget &
|
||||||
TextMetadataField::name_widget ()
|
TextMetadataField::name_widget ()
|
||||||
{
|
{
|
||||||
label = Gtk::manage (new Gtk::Label(_name + ':', Gtk::ALIGN_LEFT));
|
label = Gtk::manage (new Gtk::Label(_name + ':'));
|
||||||
label->set_alignment (0, 0.5);
|
label->set_alignment (1, 0.5);
|
||||||
return *label;
|
return *label;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -160,8 +161,8 @@ NumberMetadataField::update_value ()
|
||||||
Gtk::Widget &
|
Gtk::Widget &
|
||||||
NumberMetadataField::name_widget ()
|
NumberMetadataField::name_widget ()
|
||||||
{
|
{
|
||||||
label = Gtk::manage (new Gtk::Label(_name + ':', Gtk::ALIGN_LEFT));
|
label = Gtk::manage (new Gtk::Label(_name + ':'));
|
||||||
label->set_alignment (0, 0.5);
|
label->set_alignment (1, 0.5);
|
||||||
return *label;
|
return *label;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -255,7 +256,7 @@ SessionMetadataSetEditable::set_session (ARDOUR::Session * s)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ARDOUR::SessionMetadata const & data = _session->metadata();
|
ARDOUR::SessionMetadata const & data = *(ARDOUR::SessionMetadata::Metadata());
|
||||||
|
|
||||||
table.resize (list.size(), 2);
|
table.resize (list.size(), 2);
|
||||||
uint32_t row = 0;
|
uint32_t row = 0;
|
||||||
|
|
@ -272,7 +273,7 @@ SessionMetadataSetEditable::set_session (ARDOUR::Session * s)
|
||||||
void
|
void
|
||||||
SessionMetadataSetEditable::save_data ()
|
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) {
|
for (DataList::const_iterator it = list.begin(); it != list.end(); ++it) {
|
||||||
(*it)->save_data(data);
|
(*it)->save_data(data);
|
||||||
}
|
}
|
||||||
|
|
@ -330,7 +331,7 @@ SessionMetadataSetImportable::load_extra_data (ARDOUR::SessionMetadata const & d
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ARDOUR::SessionMetadata & session_data = _session->metadata();
|
ARDOUR::SessionMetadata const & session_data = *(ARDOUR::SessionMetadata::Metadata());
|
||||||
|
|
||||||
MetadataPtr session_field;
|
MetadataPtr session_field;
|
||||||
MetadataPtr import_field;
|
MetadataPtr import_field;
|
||||||
|
|
@ -378,7 +379,7 @@ SessionMetadataSetImportable::save_data ()
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ARDOUR::SessionMetadata & session_data = _session->metadata();
|
ARDOUR::SessionMetadata & session_data = *(ARDOUR::SessionMetadata::Metadata());
|
||||||
|
|
||||||
Gtk::TreeModel::Children fields = tree->children();
|
Gtk::TreeModel::Children fields = tree->children();
|
||||||
Gtk::TreeModel::Children::iterator it;
|
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 = add_button (Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
|
||||||
cancel_button->signal_clicked().connect (sigc::mem_fun(*this, &SessionMetadataDialog::end_dialog));
|
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));
|
save_button->signal_clicked().connect (sigc::mem_fun(*this, &SessionMetadataDialog::save_and_close));
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename DataSet>
|
template <typename DataSet>
|
||||||
void
|
void
|
||||||
SessionMetadataDialog<DataSet>::init_data ()
|
SessionMetadataDialog<DataSet>::init_data ( bool skip_user )
|
||||||
{
|
{
|
||||||
if (!_session) {
|
if (!_session) {
|
||||||
std::cerr << "Programming error: no session set for SessionMetaDataDialog (in init_data)!" << std::endl;
|
std::cerr << "Programming error: no session set for SessionMetaDataDialog (in init_data)!" << std::endl;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!skip_user)
|
||||||
|
init_user_data ();
|
||||||
init_track_data ();
|
init_track_data ();
|
||||||
init_album_data ();
|
init_album_data ();
|
||||||
init_people_data ();
|
init_people_data ();
|
||||||
|
init_school_data ();
|
||||||
|
|
||||||
for (DataSetList::iterator it = data_list.begin(); it != data_list.end(); ++it) {
|
for (DataSetList::iterator it = data_list.begin(); it != data_list.end(); ++it) {
|
||||||
(*it)->set_session (_session);
|
(*it)->set_session (_session);
|
||||||
|
|
@ -468,6 +472,7 @@ void
|
||||||
SessionMetadataDialog<DataSet>::save_and_close ()
|
SessionMetadataDialog<DataSet>::save_and_close ()
|
||||||
{
|
{
|
||||||
save_data ();
|
save_data ();
|
||||||
|
_session->set_dirty();
|
||||||
end_dialog ();
|
end_dialog ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -507,6 +512,32 @@ SessionMetadataDialog<DataSet>::add_widget (Gtk::Widget & widget)
|
||||||
get_vbox()->pack_start (widget, true, true, 0);
|
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>
|
template <typename DataSet>
|
||||||
void
|
void
|
||||||
SessionMetadataDialog<DataSet>::init_track_data ()
|
SessionMetadataDialog<DataSet>::init_track_data ()
|
||||||
|
|
@ -615,6 +646,23 @@ SessionMetadataDialog<DataSet>::init_people_data ()
|
||||||
data_set->add_data_field (ptr);
|
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::SessionMetadataEditor () :
|
SessionMetadataEditor::SessionMetadataEditor () :
|
||||||
|
|
@ -722,10 +770,10 @@ SessionMetadataImporter::run ()
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//create a temporary
|
||||||
ARDOUR::SessionMetadata data;
|
ARDOUR::SessionMetadata data;
|
||||||
data.set_state (*node, version);
|
data.set_state (*node, version);
|
||||||
|
init_data ( true ); //skip user data here
|
||||||
init_data ();
|
|
||||||
load_extra_data (data);
|
load_extra_data (data);
|
||||||
init_gui();
|
init_gui();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -209,7 +209,7 @@ class SessionMetadataDialog : public ArdourDialog
|
||||||
SessionMetadataDialog (std::string const & name);
|
SessionMetadataDialog (std::string const & name);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void init_data ();
|
void init_data ( bool skip_user = false );
|
||||||
void load_extra_data (ARDOUR::SessionMetadata const & data);
|
void load_extra_data (ARDOUR::SessionMetadata const & data);
|
||||||
void save_data ();
|
void save_data ();
|
||||||
|
|
||||||
|
|
@ -232,9 +232,11 @@ class SessionMetadataDialog : public ArdourDialog
|
||||||
Gtk::Notebook notebook;
|
Gtk::Notebook notebook;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void init_user_data ();
|
||||||
void init_track_data ();
|
void init_track_data ();
|
||||||
void init_album_data ();
|
void init_album_data ();
|
||||||
void init_people_data ();
|
void init_people_data ();
|
||||||
|
void init_school_data ();
|
||||||
|
|
||||||
typedef boost::shared_ptr<SessionMetadataSet> DataSetPtr;
|
typedef boost::shared_ptr<SessionMetadataSet> DataSetPtr;
|
||||||
typedef std::list<DataSetPtr> DataSetList;
|
typedef std::list<DataSetPtr> DataSetList;
|
||||||
|
|
|
||||||
|
|
@ -294,22 +294,6 @@ SessionOptionEditor::SessionOptionEditor (Session* s)
|
||||||
|
|
||||||
add_option (_("Misc"), li);
|
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 OptionEditorHeading (_("Glue to bars and beats")));
|
||||||
|
|
||||||
add_option (_("Misc"), new BoolOption (
|
add_option (_("Misc"), new BoolOption (
|
||||||
|
|
|
||||||
|
|
@ -50,6 +50,8 @@
|
||||||
#include <glib.h>
|
#include <glib.h>
|
||||||
#include <glib/gstdio.h>
|
#include <glib/gstdio.h>
|
||||||
|
|
||||||
|
#include "i18n.h"
|
||||||
|
|
||||||
#include "ardour/audio_library.h"
|
#include "ardour/audio_library.h"
|
||||||
|
|
||||||
static const std::string base_url = "http://www.freesound.org/api";
|
static const std::string base_url = "http://www.freesound.org/api";
|
||||||
|
|
@ -67,6 +69,7 @@ Mootcher::Mootcher()
|
||||||
//------------------------------------------------------------------------
|
//------------------------------------------------------------------------
|
||||||
Mootcher:: ~Mootcher()
|
Mootcher:: ~Mootcher()
|
||||||
{
|
{
|
||||||
|
curl_easy_cleanup(curl);
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------
|
//------------------------------------------------------------------------
|
||||||
|
|
@ -184,16 +187,16 @@ std::string Mootcher::doRequest(std::string uri, std::string params)
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
result = xml_page.memory;
|
|
||||||
// free the memory
|
// free the memory
|
||||||
if(xml_page.memory){
|
if (xml_page.memory) {
|
||||||
free( xml_page.memory );
|
result = xml_page.memory;
|
||||||
xml_page.memory = NULL;
|
|
||||||
xml_page.size = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
free (xml_page.memory);
|
||||||
|
xml_page.memory = NULL;
|
||||||
|
xml_page.size = 0;
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -215,6 +218,8 @@ std::string Mootcher::searchText(std::string query, int page, std::string filter
|
||||||
if (sort)
|
if (sort)
|
||||||
params += "&s=" + sortMethodString(sort);
|
params += "&s=" + sortMethodString(sort);
|
||||||
|
|
||||||
|
params += "&fields=id,original_filename,duration,serve";
|
||||||
|
|
||||||
return doRequest("/sounds/search", params);
|
return doRequest("/sounds/search", params);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -225,7 +230,6 @@ std::string Mootcher::getSoundResourceFile(std::string ID)
|
||||||
|
|
||||||
std::string originalSoundURI;
|
std::string originalSoundURI;
|
||||||
std::string audioFileName;
|
std::string audioFileName;
|
||||||
std::string xmlFileName;
|
|
||||||
std::string xml;
|
std::string xml;
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -250,28 +254,12 @@ std::string Mootcher::getSoundResourceFile(std::string ID)
|
||||||
}
|
}
|
||||||
|
|
||||||
XMLNode *name = freesound->child("original_filename");
|
XMLNode *name = freesound->child("original_filename");
|
||||||
XMLNode *filesize = freesound->child("filesize");
|
|
||||||
|
|
||||||
|
|
||||||
// get the file name and size from xml file
|
// get the file name and size from xml file
|
||||||
if (name && filesize) {
|
if (name) {
|
||||||
|
|
||||||
audioFileName = basePath + "snd/" + ID + "-" + name->child("text")->content();
|
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
|
//store all the tags in the database
|
||||||
XMLNode *tags = freesound->child("tags");
|
XMLNode *tags = freesound->child("tags");
|
||||||
if (tags) {
|
if (tags) {
|
||||||
|
|
@ -326,6 +314,11 @@ std::string Mootcher::getAudioFile(std::string originalFileName, std::string ID,
|
||||||
return "";
|
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
|
//now download the actual file
|
||||||
FILE* theFile;
|
FILE* theFile;
|
||||||
theFile = g_fopen( audioFileName.c_str(), "wb" );
|
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;
|
std::cerr << "downloading " << audioFileName << " from " << audioURL << "..." << std::endl;
|
||||||
/* hack to get rid of the barber-pole stripes */
|
/* hack to get rid of the barber-pole stripes */
|
||||||
caller->progress_bar.hide();
|
caller->freesound_progress_bar.hide();
|
||||||
caller->progress_bar.show();
|
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_NOPROGRESS, 0); // turn on the progress bar
|
||||||
curl_easy_setopt (curl, CURLOPT_PROGRESSFUNCTION, progress_callback);
|
curl_easy_setopt (curl, CURLOPT_PROGRESSFUNCTION, progress_callback);
|
||||||
|
|
@ -355,7 +352,8 @@ std::string Mootcher::getAudioFile(std::string originalFileName, std::string ID,
|
||||||
fclose(theFile);
|
fclose(theFile);
|
||||||
|
|
||||||
curl_easy_setopt (curl, CURLOPT_NOPROGRESS, 1); // turn off the progress bar
|
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 ) {
|
if( res != 0 ) {
|
||||||
std::cerr << "curl error " << res << " (" << curl_easy_strerror(res) << ")" << std::endl;
|
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;
|
SoundFileBrowser *sfb = (SoundFileBrowser *) caller;
|
||||||
//XXX I hope it's OK to do GTK things in this callback. Otherwise
|
//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.
|
// I'll have to do stuff like in interthread_progress_window.
|
||||||
if (sfb->freesound_stop) {
|
if (sfb->freesound_download_cancel) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
sfb->progress_bar.set_fraction(dlnow/dltotal);
|
sfb->freesound_progress_bar.set_fraction(dlnow/dltotal);
|
||||||
/* Make sure the progress widget gets updated */
|
/* Make sure the progress widget gets updated */
|
||||||
while (Glib::MainContext::get_default()->iteration (false)) {
|
while (Glib::MainContext::get_default()->iteration (false)) {
|
||||||
/* do nothing */
|
/* do nothing */
|
||||||
|
|
|
||||||
|
|
@ -188,10 +188,10 @@ SoundFileBox::SoundFileBox (bool persistent)
|
||||||
main_box.pack_start (bottom_box, false, false);
|
main_box.pack_start (bottom_box, false, false);
|
||||||
|
|
||||||
play_btn.set_image (*(manage (new Image (Stock::MEDIA_PLAY, ICON_SIZE_BUTTON))));
|
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_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_homogeneous (false);
|
||||||
bottom_box.set_spacing (6);
|
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");
|
chooser.add_shortcut_folder_uri("file:///Volumes");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef FREESOUND
|
||||||
|
mootcher = new Mootcher();
|
||||||
|
#endif
|
||||||
|
|
||||||
//add the file chooser
|
//add the file chooser
|
||||||
{
|
{
|
||||||
chooser.set_border_width (12);
|
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_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));
|
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"));
|
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.append_text(_("Lowest rated"));
|
||||||
freesound_sort.set_active(0);
|
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 (freesound_search_btn, false, false);
|
||||||
passbox->pack_start (progress_bar);
|
passbox->pack_start (freesound_progress_bar);
|
||||||
passbox->pack_end (freesound_stop_btn, false, false);
|
passbox->pack_end (freesound_stop_btn, false, false);
|
||||||
freesound_stop_btn.set_label(_("Stop"));
|
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));
|
freesound_stop_btn.signal_clicked().connect(sigc::mem_fun(*this, &SoundFileBrowser::freesound_stop_clicked));
|
||||||
notebook.append_page (*vbox, _("Search Freesound"));
|
notebook.append_page (*vbox, _("Search Freesound"));
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -736,13 +736,13 @@ SoundFileBrowser::found_list_view_selected ()
|
||||||
void
|
void
|
||||||
SoundFileBrowser::freesound_list_view_selected ()
|
SoundFileBrowser::freesound_list_view_selected ()
|
||||||
{
|
{
|
||||||
|
freesound_download_cancel = false;
|
||||||
|
|
||||||
#ifdef FREESOUND
|
#ifdef FREESOUND
|
||||||
if (!reset_options ()) {
|
if (!reset_options ()) {
|
||||||
set_response_sensitive (RESPONSE_OK, false);
|
set_response_sensitive (RESPONSE_OK, false);
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
Mootcher theMootcher; // XXX should be a member of SoundFileBrowser
|
|
||||||
|
|
||||||
string file;
|
string file;
|
||||||
|
|
||||||
TreeView::Selection::ListHandle_Path rows = freesound_list_view.get_selection()->get_selected_rows ();
|
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_window_set_cursor (get_window()->gobj(), gdk_cursor_new(GDK_WATCH));
|
||||||
gdk_flush();
|
gdk_flush();
|
||||||
|
|
||||||
freesound_stop = false;
|
file = mootcher->getAudioFile(ofn, id, uri, this);
|
||||||
file = theMootcher.getAudioFile(ofn, id, uri, this);
|
|
||||||
|
|
||||||
gdk_window_set_cursor (get_window()->gobj(), prev_cursor);
|
gdk_window_set_cursor (get_window()->gobj(), prev_cursor);
|
||||||
|
|
||||||
|
|
@ -805,13 +804,15 @@ SoundFileBrowser::found_search_clicked ()
|
||||||
void
|
void
|
||||||
SoundFileBrowser::freesound_search_clicked ()
|
SoundFileBrowser::freesound_search_clicked ()
|
||||||
{
|
{
|
||||||
|
freesound_search_cancel = false;
|
||||||
freesound_search();
|
freesound_search();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
SoundFileBrowser::freesound_stop_clicked ()
|
SoundFileBrowser::freesound_stop_clicked ()
|
||||||
{
|
{
|
||||||
freesound_stop = true;
|
freesound_download_cancel = true;
|
||||||
|
freesound_search_cancel = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -821,97 +822,111 @@ SoundFileBrowser::freesound_search()
|
||||||
#ifdef FREESOUND
|
#ifdef FREESOUND
|
||||||
freesound_list->clear();
|
freesound_list->clear();
|
||||||
|
|
||||||
Mootcher theMootcher;
|
|
||||||
|
|
||||||
string search_string = freesound_entry.get_text ();
|
string search_string = freesound_entry.get_text ();
|
||||||
enum sortMethod sort_method = (enum sortMethod) freesound_sort.get_active_row_number();
|
enum sortMethod sort_method = (enum sortMethod) freesound_sort.get_active_row_number();
|
||||||
int page = freesound_page.get_value_as_int();
|
|
||||||
|
|
||||||
GdkCursor *prev_cursor;
|
GdkCursor *prev_cursor;
|
||||||
prev_cursor = gdk_window_get_cursor (get_window()->gobj());
|
prev_cursor = gdk_window_get_cursor (get_window()->gobj());
|
||||||
gdk_window_set_cursor (get_window()->gobj(), gdk_cursor_new(GDK_WATCH));
|
gdk_window_set_cursor (get_window()->gobj(), gdk_cursor_new(GDK_WATCH));
|
||||||
gdk_flush();
|
gdk_flush();
|
||||||
|
for (int page = 1; page <= 99; page++ ) {
|
||||||
|
|
||||||
|
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 */
|
||||||
|
}
|
||||||
|
|
||||||
string theString = theMootcher.searchText(
|
std::string theString = mootcher->searchText(
|
||||||
search_string,
|
search_string,
|
||||||
page,
|
page,
|
||||||
"", // filter, could do, e.g. "type:wav"
|
"", // filter, could do, e.g. "type:wav"
|
||||||
sort_method
|
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);
|
gdk_window_set_cursor (get_window()->gobj(), prev_cursor);
|
||||||
|
|
||||||
XMLTree doc;
|
freesound_progress_bar.set_text("");
|
||||||
doc.read_buffer( theString );
|
|
||||||
XMLNode *root = doc.root();
|
|
||||||
|
|
||||||
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
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -948,9 +963,6 @@ SoundFileBrowser::get_paths ()
|
||||||
#ifdef FREESOUND
|
#ifdef FREESOUND
|
||||||
typedef TreeView::Selection::ListHandle_Path ListPath;
|
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 ();
|
ListPath rows = freesound_list_view.get_selection()->get_selected_rows ();
|
||||||
for (ListPath::iterator i = rows.begin() ; i != rows.end(); ++i) {
|
for (ListPath::iterator i = rows.begin() ; i != rows.end(); ++i) {
|
||||||
TreeIter iter = freesound_list->get_iter(*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_window_set_cursor (get_window()->gobj(), gdk_cursor_new(GDK_WATCH));
|
||||||
gdk_flush();
|
gdk_flush();
|
||||||
|
|
||||||
freesound_stop = false;
|
string str = mootcher->getAudioFile(ofn, id, uri, this);
|
||||||
string str = theMootcher.getAudioFile(ofn, id, uri, this);
|
|
||||||
if (str != "") {
|
if (str != "") {
|
||||||
results.push_back (str);
|
results.push_back (str);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue