Merge lp:~daschuer/mixxx/autodj into lp:~mixxxdevelopers/mixxx/trunk
- autodj
- Merge into trunk
Status: | Merged | ||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Merged at revision: | 2989 | ||||||||||||||||||||||||||||
Proposed branch: | lp:~daschuer/mixxx/autodj | ||||||||||||||||||||||||||||
Merge into: | lp:~mixxxdevelopers/mixxx/trunk | ||||||||||||||||||||||||||||
Diff against target: |
1979 lines (+1168/-231) 22 files modified
mixxx/build/depends.py (+24/-4) mixxx/lib/soundtouch-1.6.0/STTypes.h (+1/-1) mixxx/res/images/autodj/bottom.svg (+137/-0) mixxx/res/images/autodj/media-playlist-shuffle.svg (+214/-0) mixxx/res/images/autodj/stock_mail-send-receive.svg (+87/-0) mixxx/res/mixxx.qrc (+3/-0) mixxx/src/dlgautodj.cpp (+433/-161) mixxx/src/dlgautodj.h (+26/-2) mixxx/src/dlgautodj.ui (+110/-18) mixxx/src/library/autodjfeature.cpp (+30/-24) mixxx/src/library/autodjfeature.h (+2/-0) mixxx/src/library/browse/browsefeature.cpp (+14/-4) mixxx/src/library/browse/browsetablemodel.cpp (+8/-8) mixxx/src/library/dao/cratedao.h (+2/-0) mixxx/src/library/dao/playlistdao.cpp (+11/-3) mixxx/src/library/dao/playlistdao.h (+3/-1) mixxx/src/library/playlistfeature.cpp (+23/-3) mixxx/src/library/playlistfeature.h (+3/-0) mixxx/src/library/playlisttablemodel.cpp (+11/-0) mixxx/src/library/playlisttablemodel.h (+1/-0) mixxx/src/widget/wtracktableview.cpp (+22/-2) mixxx/src/widget/wtracktableview.h (+3/-0) |
||||||||||||||||||||||||||||
To merge this branch: | bzr merge lp:~daschuer/mixxx/autodj | ||||||||||||||||||||||||||||
Related bugs: |
|
||||||||||||||||||||||||||||
Related blueprints: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Mixxx Development Team | Pending | ||
Review via email: mp+61320@code.launchpad.net |
Commit message
Description of the change
I have done some changes, which makes auto DJ useful for manual control.
* Manually to a deck loaded song is played by auto DJ
* Additional "Skip Next" Button
* Auto DJ did not change the "Repeat" Button any more
* "Repeat" works as desired (it temporary disables auto DJ)
* Lock fading of the two decks against each other, plus some other possible exceptions
* Enabling auto DJ always starts playback (we may discuss if it is desired)
* Next track is loaded immediately after fading (see bug 766817) also good to monitor what happens next in case browsing thou the library
* Additional "Fade Now" button (see bug 730577)
* "Fade Now" disables "Repeat"
* Track is deleted from the auto DJ list when it starts to play
* Image Buttons (fits to Outline-
* "Add to Auto DJ Queue" from Rhythmbox and Browser
* "Add to Auto DJ Top 2" for playing a song after next
* Autoscroll Patch
- 2800. By Daniel Schürmann
-
GUI cleanup
- 2801. By Daniel Schürmann
-
auto DJ with Transition time in sec configurable
- 2802. By Daniel Schürmann
-
Transition settings from auto DJ toolbar.
Skip missing tracks. "Fade Now" works when both decks playing. Solved some issues with seek and jumps. - 2803. By Daniel Schürmann
-
made skip next working
Daniel Schürmann (daschuer) wrote : | # |
Hi jus, Thank you for testing.
At the beginning I had strange problems with the maximum size of the auto DJ tools.
The current solution consumes as much space as possible. What's the limit and where can I find it.
I think we will have a lot of problems with i18n. Maybe someone is able to define bitmap buttons or an auto DJ skin. A second toolbar is not nice, it would be look stupid on large screens and consumes to much space from tiny screens.
Do you think we should remove the transition from the preferences dialog?
Thanks for fixing the bugs i mentioned in the first comment.
Can not tell if there is such limit hardcoded/where to find eventually. OTOH the AutoDJ pane looks fine in all other skins. The OUTLINE skin may have no future either, so the escaping library in OUTLINE is nothing to be really worried about for the moment.
> The current solution consumes as much space as possible. What's the limit and
> where can I find it.
Agree on the second toolbar, better have all buttons in one row.
Actually we can already style the buttons,spinbox etc. per skin using style-sheets. See the Spartan skin for example http://
A reason the buttons are currently not styled per default is that style-sheets break the color scheme support which the OUTLINE skins make exclusive use of http://
> I think we will have a lot of problems with i18n. Maybe someone is able to
> define bitmap buttons or an auto DJ skin. A second toolbar is not nice, it
> would be look stupid on large screens and consumes to much space from tiny
> screens.
>
Yes, as it is now in the AutoDJ pane for direct access.
> Do you think we should remove the transition from the preferences dialog?
One last thing:
While "s" is the correct abbreviation for "seconds", do you think it is clear enough for translators? What do you think, maybe go with "sec" instead?
- 2804. By Daniel Schürmann
-
Transition removed from prefcrossfader.
Made the transition from auto DJ Toolbar persistent.
Fixed a bug: Where "loadTrack" was sometimes overtaking "stop" - 2805. By Daniel Schürmann
-
Optimized Auto DJ start, merged with trunk
Daniel Schürmann (daschuer) wrote : | # |
Hi jus,
I am surprised to hear that the OUTLINE skin may have no future, because It is my favourite on the netbook. It has clear buttons with a good size and waveforms on below the others. Only one thing: The position of the loaded track title should be below the waveforms.
I do not know if our American friends like "s" for second. My Problem is, that "sec" is simply to large for OUTLINE skin.
Sean M. Pappalardo (pegasus-renegadetech) wrote : | # |
I'm American and I'll say that 's' for second is fine for us, so long as the context makes it obvious.
Jus is concerned with translations: on LP, it just displays the text to translate, so an 's' all by itself won't be obvious without a screen shot or something. LP does give the line number in the code, but then a translator would have to go look at the code to see exactly what that 's' means to know how (if) to translate it. If there's a detailed tool tip nearby then that might make it more obvious.
Now it reads "Transition [QSpinBox] s" better would be "Transition (sec) [QSpinBox]" or "Fade (sec) [QSpinBox]". This would make the context pretty obvious for translators too.
If we`d just use "Transition (s)" it could be easily mistaken for being plural of "Transition".
Would love to see the additions to AutoDJ in trunk, using it extensively and it works (at least from a user perspective) without complains.
- 2806. By Daniel Schürmann
-
merged with trunk
- 2807. By Daniel Schürmann
-
auto DJ with pause (Transition negative)
- 2808. By Daniel Schürmann
-
auto DJ with pause works for second deck
- 2809. By Daniel Schürmann
-
fixed bug with double-entrys
- 2810. By Daniel Schürmann
-
Added image buttons for auto DJ panel, >Add to Auto DJ Queue< for Bowser and Rhythmbox
Daniel Schürmann (daschuer) wrote : | # |
Now it has image buttons, Taken from "Multicolor-Gnome" Iconset.
I have changed the Text to "Transition [sec]" [SpinBox]
> Now it has image buttons, Taken from "Multicolor-Gnome" Iconset.
Hi Daniel, would love to hear the idea behind this change.
I see the following drawbacks:
* Lack of consistency: Using a mix of labeled and styled un-labeled (styled) buttons for activating AutoDJ / Recordings / Analyze.
* Lack of unity of style within icons : Does not fit with our existing icons used in treeview & preferences.
* Duplicates functionality: Currently elements like buttons, spinboxes etc. can already be customized per skin using QT stylesheets in skin.xml
Daniel Schürmann (daschuer) wrote : | # |
Hi jus,
styling is not the main part of this branch. I am not an expert in GUI or graphic design.
This is just a solution for our escaping and i18n problem.
Whats your main reason for the lack of unity?
Where are the existing icons from? Maybe there are similar icons in that icon set we can use.
Do you have an idea for styled buttons in Recordings and Analyse?
I have decided to use a static sylesheet within the dlgautodj because the library icons are also static. It should be no problem to move all library arts together it to the skin support later.
For now and in respect to the merging work-flow this should be best.
I agree that we could use descriptive icons for some of the player-like elements in AutoDJ, namely "Shuffle Playlist","Skip Next Track" and "Fade Now" to save some horizontal space for smaller skins.
Suggestion:
* Remove the "Multicolor-Gnome" icons and references and replace it with an existing icon as dummy (e.g. ic_library_
* Restore the default "Enable Auto DJ" button, we follow the "Call to action button" paradigm for main buttons in AutoDJ/
- 2811. By Daniel Schürmann
-
fixed Library escaping bug; Restore old enable Auto DJ button
Daniel Schürmann (daschuer) wrote : | # |
Hi jus,
it was a pain, restoring the "Enable Auto DJ" button forces me to solve the escaping library bug ..
Thank you for your offer to make buttons for auto DJ. I will leave the current svg buttons as dummys in the mean time.
- 2812. By Daniel Schürmann
-
fix Deere1280x800-
EXPERIMENTAL side-effect of Bug #804529
Currently there are more dummy buttons in your branch than buttons needed for AutoDJ. Do you plan to use the additional buttons in any way (e.g. for a feature to come?).
Daniel Schürmann (daschuer) wrote : | # |
Hi jus,
I simply haven’t tidy up the resources.
By the way: I still have some ideas like "Auto trim" or "Auto End Looping" and changing the transition effects on the fly e.g. "Spin down (or up)" but those jobs are likely the job of Tom Mast.
He is currently working on a new base for autodj (lp:~thomasomast/mixxx/features_autodj). I'm looking forward to see what his code will offer.
Maybe he needs some artwork too.
- 2813. By Daniel Schürmann
-
* removed unused icons * added required delete statements
- 2814. By Daniel Schürmann
-
merged with lp:mixxx
- 2815. By Daniel Schürmann
-
merged with lp:mixxx
- 2816. By Daniel Schürmann
-
* change button text when enabling autodj
* calculate fade duration for the right track when enabling autodj
* made fade now less restictive - 2817. By Daniel Schürmann
-
merged with lp:mixxx
- 2818. By Daniel Schürmann
-
clean up after merge
- 2819. By Daniel Schürmann
-
merged with lp:mixxx
- 2820. By Daniel Schürmann
-
merged with lp:mixxx
- 2821. By Daniel Schürmann
-
merged with trunk
- 2822. By Daniel Schürmann
-
merged with lp:mixxx
- 2823. By Daniel Schürmann
-
merged with lp:mixxx
Preview Diff
1 | === modified file 'mixxx/build/depends.py' |
2 | --- mixxx/build/depends.py 2011-12-25 05:45:11 +0000 |
3 | +++ mixxx/build/depends.py 2012-03-01 22:38:18 +0000 |
4 | @@ -229,23 +229,43 @@ |
5 | '#lib/%s/FIFOSampleBuffer.cpp' % self.SOUNDTOUCH_PATH, |
6 | '#lib/%s/FIRFilter.cpp' % self.SOUNDTOUCH_PATH, |
7 | '#lib/%s/PeakFinder.cpp' % self.SOUNDTOUCH_PATH, |
8 | - '#lib/%s/BPMDetect.cpp' % self.SOUNDTOUCH_PATH, |
9 | - '#lib/%s/mmx_optimized.cpp' % self.SOUNDTOUCH_PATH, |
10 | - '#lib/%s/sse_optimized.cpp' % self.SOUNDTOUCH_PATH,] |
11 | + '#lib/%s/BPMDetect.cpp' % self.SOUNDTOUCH_PATH] |
12 | |
13 | # SoundTouch CPU optimizations are only for x86 |
14 | # architectures. SoundTouch automatically ignores these files when it is |
15 | # not being built for an architecture that supports them. |
16 | - cpu_detection = '#lib/%s/cpu_detect_x86_win.cpp' if build.toolchain_is_msvs else '#lib/%s/cpu_detect_x86_gcc.cpp' |
17 | + cpu_detection = '#lib/%s/cpu_detect_x86_win.cpp' if build.toolchain_is_msvs else \ |
18 | + '#lib/%s/cpu_detect_x86_gcc.cpp' |
19 | sources.append(cpu_detection % self.SOUNDTOUCH_PATH) |
20 | + |
21 | + # Check if the compiler has SSE extention enabled |
22 | + # Allways the case on x64 (core instructions) |
23 | + optimize = int(util.get_flags(build.env, 'optimize', 1)) |
24 | + if build.machine_is_64bit or \ |
25 | + (build.toolchain_is_msvs and optimize > 2) or \ |
26 | + (build.toolchain_is_gnu and optimize > 1): |
27 | + sources.extend( |
28 | + ['#lib/%s/mmx_optimized.cpp' % self.SOUNDTOUCH_PATH, |
29 | + '#lib/%s/sse_optimized.cpp' % self.SOUNDTOUCH_PATH, |
30 | + ]) |
31 | + |
32 | return sources |
33 | |
34 | + |
35 | def configure(self, build, conf): |
36 | if build.platform_is_windows: |
37 | # Regardless of the bitwidth, ST checks for WIN32 |
38 | build.env.Append(CPPDEFINES = 'WIN32') |
39 | build.env.Append(CPPPATH=['#lib/%s' % self.SOUNDTOUCH_PATH]) |
40 | |
41 | + # Check if the compiler has SSE extention enabled |
42 | + # Allways the case on x64 (core instructions) |
43 | + optimize = int(util.get_flags(build.env, 'optimize', 1)) |
44 | + if build.machine_is_64bit or \ |
45 | + (build.toolchain_is_msvs and optimize > 2) or \ |
46 | + (build.toolchain_is_gnu and optimize > 1): |
47 | + build.env.Append(CPPDEFINES='SOUNDTOUCH_ALLOW_X86_OPTIMIZATIONS') |
48 | + |
49 | class TagLib(Dependence): |
50 | def configure(self, build, conf): |
51 | if not conf.CheckLib('tag'): |
52 | |
53 | === modified file 'mixxx/lib/soundtouch-1.6.0/STTypes.h' |
54 | --- mixxx/lib/soundtouch-1.6.0/STTypes.h 2011-07-24 21:30:08 +0000 |
55 | +++ mixxx/lib/soundtouch-1.6.0/STTypes.h 2012-03-01 22:38:18 +0000 |
56 | @@ -95,7 +95,7 @@ |
57 | /// routines compiled for whatever reason, you may disable these optimizations |
58 | /// to make the library compile. |
59 | |
60 | - #define SOUNDTOUCH_ALLOW_X86_OPTIMIZATIONS 1 |
61 | + // #define SOUNDTOUCH_ALLOW_X86_OPTIMIZATIONS 1 |
62 | |
63 | #endif |
64 | |
65 | |
66 | === added directory 'mixxx/res/images/autodj' |
67 | === added file 'mixxx/res/images/autodj/bottom.svg' |
68 | --- mixxx/res/images/autodj/bottom.svg 1970-01-01 00:00:00 +0000 |
69 | +++ mixxx/res/images/autodj/bottom.svg 2012-03-01 22:38:18 +0000 |
70 | @@ -0,0 +1,137 @@ |
71 | +<?xml version="1.0" encoding="UTF-8" standalone="no"?> |
72 | +<!-- Created with Inkscape (http://www.inkscape.org/) --> |
73 | +<svg |
74 | + xmlns:dc="http://purl.org/dc/elements/1.1/" |
75 | + xmlns:cc="http://creativecommons.org/ns#" |
76 | + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" |
77 | + xmlns:svg="http://www.w3.org/2000/svg" |
78 | + xmlns="http://www.w3.org/2000/svg" |
79 | + xmlns:xlink="http://www.w3.org/1999/xlink" |
80 | + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" |
81 | + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" |
82 | + width="48px" |
83 | + height="48px" |
84 | + id="svg4289" |
85 | + sodipodi:version="0.32" |
86 | + inkscape:version="0.46" |
87 | + sodipodi:docbase="/home/lapo/Icone/cvs/gnome-icon-theme/scalable/categories" |
88 | + sodipodi:docname="bottom.svg" |
89 | + inkscape:output_extension="org.inkscape.output.svg.inkscape"> |
90 | + <defs |
91 | + id="defs4291"> |
92 | + <linearGradient |
93 | + id="linearGradient3155" |
94 | + inkscape:collect="always"> |
95 | + <stop |
96 | + id="stop3157" |
97 | + offset="0" |
98 | + style="stop-color:#ffb584;stop-opacity:1;" /> |
99 | + <stop |
100 | + id="stop3159" |
101 | + offset="1" |
102 | + style="stop-color:#ffb584;stop-opacity:0;" /> |
103 | + </linearGradient> |
104 | + <linearGradient |
105 | + inkscape:collect="always" |
106 | + xlink:href="#linearGradient3155" |
107 | + id="linearGradient3273" |
108 | + gradientUnits="userSpaceOnUse" |
109 | + gradientTransform="matrix(0.1532521,0,0,0.1530054,-25.916429,-53.611392)" |
110 | + x1="325.71429" |
111 | + y1="369.50507" |
112 | + x2="325.71429" |
113 | + y2="546.64789" /> |
114 | + </defs> |
115 | + <sodipodi:namedview |
116 | + id="base" |
117 | + pagecolor="#ffffff" |
118 | + bordercolor="#666" |
119 | + borderopacity="0.31372549" |
120 | + inkscape:pageopacity="0.0" |
121 | + inkscape:pageshadow="2" |
122 | + inkscape:zoom="5.656854" |
123 | + inkscape:cx="25.963489" |
124 | + inkscape:cy="20.551712" |
125 | + inkscape:current-layer="layer1" |
126 | + showgrid="true" |
127 | + inkscape:grid-bbox="true" |
128 | + inkscape:document-units="px" |
129 | + inkscape:window-width="1019" |
130 | + inkscape:window-height="732" |
131 | + inkscape:window-x="259" |
132 | + inkscape:window-y="19" |
133 | + inkscape:showpageshadow="false" /> |
134 | + <metadata |
135 | + id="metadata4294"> |
136 | + <rdf:RDF> |
137 | + <cc:Work |
138 | + rdf:about=""> |
139 | + <dc:format>image/svg+xml</dc:format> |
140 | + <dc:type |
141 | + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> |
142 | + <dc:title>System Preferences</dc:title> |
143 | + <dc:creator> |
144 | + <cc:Agent> |
145 | + <dc:title>Andreas Nilsson</dc:title> |
146 | + </cc:Agent> |
147 | + </dc:creator> |
148 | + <dc:subject> |
149 | + <rdf:Bag> |
150 | + <rdf:li>category</rdf:li> |
151 | + <rdf:li>system</rdf:li> |
152 | + <rdf:li>preferences</rdf:li> |
153 | + <rdf:li>settings</rdf:li> |
154 | + <rdf:li>control center</rdf:li> |
155 | + </rdf:Bag> |
156 | + </dc:subject> |
157 | + <dc:contributor> |
158 | + <cc:Agent> |
159 | + <dc:title>Jakub Steiner</dc:title> |
160 | + </cc:Agent> |
161 | + </dc:contributor> |
162 | + <cc:license |
163 | + rdf:resource="http://creativecommons.org/licenses/GPL/2.0/" /> |
164 | + </cc:Work> |
165 | + <cc:License |
166 | + rdf:about="http://creativecommons.org/licenses/GPL/2.0/"> |
167 | + <cc:permits |
168 | + rdf:resource="http://web.resource.org/cc/Reproduction" /> |
169 | + <cc:permits |
170 | + rdf:resource="http://web.resource.org/cc/Distribution" /> |
171 | + <cc:requires |
172 | + rdf:resource="http://web.resource.org/cc/Notice" /> |
173 | + <cc:permits |
174 | + rdf:resource="http://web.resource.org/cc/DerivativeWorks" /> |
175 | + <cc:requires |
176 | + rdf:resource="http://web.resource.org/cc/ShareAlike" /> |
177 | + <cc:requires |
178 | + rdf:resource="http://web.resource.org/cc/SourceCode" /> |
179 | + </cc:License> |
180 | + </rdf:RDF> |
181 | + </metadata> |
182 | + <g |
183 | + id="layer1" |
184 | + inkscape:label="Layer 1" |
185 | + inkscape:groupmode="layer"> |
186 | + <g |
187 | + id="g2453" |
188 | + inkscape:label="Calque 1" |
189 | + transform="matrix(0.1337942,0,0,0.1337942,-18.472238,-41.04701)" /> |
190 | + <path |
191 | + style="fill:#ea5d00;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.9139747;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" |
192 | + d="M 6.7500156,19.774362 L 24.043348,39.555555 L 41.25,19.774362 L 33.004787,19.774362 L 33.004787,4.0000015 L 15.136157,4.0000015 L 15.136157,19.774362 L 6.7500156,19.774362 z" |
193 | + id="path4348" |
194 | + sodipodi:nodetypes="cccccccc" /> |
195 | + <rect |
196 | + y="39.555557" |
197 | + x="6.75" |
198 | + height="4.4444442" |
199 | + width="34.499985" |
200 | + id="rect4242" |
201 | + style="fill:#ea5d00;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.84845495;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" /> |
202 | + <path |
203 | + style="fill:url(#linearGradient3273);fill-opacity:1" |
204 | + d="M 15.131549,4.0000015 L 15.131549,19.76389 L 6.75,19.76389 L 15.027214,29.208333 C 17.837762,29.718667 20.845017,30.041667 23.999992,30.041667 C 27.180083,30.041667 30.212896,29.726456 33.042326,29.208333 L 41.249983,19.76389 L 33.007548,19.76389 L 33.007548,4.0000015 L 15.131549,4.0000015 z" |
205 | + id="path3261" /> |
206 | + </g> |
207 | +</svg> |
208 | |
209 | === added file 'mixxx/res/images/autodj/media-playlist-shuffle.svg' |
210 | --- mixxx/res/images/autodj/media-playlist-shuffle.svg 1970-01-01 00:00:00 +0000 |
211 | +++ mixxx/res/images/autodj/media-playlist-shuffle.svg 2012-03-01 22:38:18 +0000 |
212 | @@ -0,0 +1,214 @@ |
213 | +<?xml version="1.0" encoding="UTF-8" standalone="no"?> |
214 | +<!-- Created with Inkscape (http://www.inkscape.org/) --> |
215 | + |
216 | +<svg |
217 | + xmlns:dc="http://purl.org/dc/elements/1.1/" |
218 | + xmlns:cc="http://creativecommons.org/ns#" |
219 | + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" |
220 | + xmlns:svg="http://www.w3.org/2000/svg" |
221 | + xmlns="http://www.w3.org/2000/svg" |
222 | + xmlns:xlink="http://www.w3.org/1999/xlink" |
223 | + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" |
224 | + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" |
225 | + width="48" |
226 | + height="48" |
227 | + id="svg7854" |
228 | + sodipodi:version="0.32" |
229 | + inkscape:version="0.47 r22583" |
230 | + version="1.0" |
231 | + sodipodi:docname="media-playlist-shuffle.svg" |
232 | + inkscape:output_extension="org.inkscape.output.svg.inkscape" |
233 | + inkscape:export-filename="/home/lapo/Icone/gnome-icon-theme/32x32/status/media-playlist-repeat.png" |
234 | + inkscape:export-xdpi="90" |
235 | + inkscape:export-ydpi="90"> |
236 | + <defs |
237 | + id="defs7856"> |
238 | + <linearGradient |
239 | + gradientUnits="userSpaceOnUse" |
240 | + y2="21.132059" |
241 | + x2="22.892584" |
242 | + y1="0.90414524" |
243 | + x1="22.892584" |
244 | + id="linearGradient3178" |
245 | + xlink:href="#linearGradient3172" |
246 | + inkscape:collect="always" /> |
247 | + <linearGradient |
248 | + id="linearGradient3172"> |
249 | + <stop |
250 | + id="stop3174" |
251 | + offset="0" |
252 | + style="stop-color:#ffb584;stop-opacity:1;" /> |
253 | + <stop |
254 | + id="stop3176" |
255 | + offset="1" |
256 | + style="stop-color:#ffb584;stop-opacity:0;" /> |
257 | + </linearGradient> |
258 | + <linearGradient |
259 | + inkscape:collect="always" |
260 | + xlink:href="#linearGradient3172" |
261 | + id="linearGradient3747" |
262 | + gradientUnits="userSpaceOnUse" |
263 | + x1="22.892584" |
264 | + y1="0.90414524" |
265 | + x2="22.892584" |
266 | + y2="21.132059" /> |
267 | + <linearGradient |
268 | + inkscape:collect="always" |
269 | + xlink:href="#linearGradient3172" |
270 | + id="linearGradient3752" |
271 | + gradientUnits="userSpaceOnUse" |
272 | + x1="22.892584" |
273 | + y1="0.90414524" |
274 | + x2="22.892584" |
275 | + y2="21.132059" |
276 | + gradientTransform="matrix(0.644962,0,0,-1.1832362,59.235153,43.983663)" /> |
277 | + <linearGradient |
278 | + inkscape:collect="always" |
279 | + xlink:href="#linearGradient3172" |
280 | + id="linearGradient3755" |
281 | + gradientUnits="userSpaceOnUse" |
282 | + gradientTransform="matrix(0.644962,0,0,1.1832362,9.235153,4.016337)" |
283 | + x1="22.892584" |
284 | + y1="0.90414524" |
285 | + x2="22.892584" |
286 | + y2="21.132059" /> |
287 | + </defs> |
288 | + <sodipodi:namedview |
289 | + id="base" |
290 | + pagecolor="#ffffff" |
291 | + bordercolor="#afafaf" |
292 | + borderopacity="1" |
293 | + gridtolerance="15.1" |
294 | + guidetolerance="10" |
295 | + objecttolerance="10" |
296 | + inkscape:pageopacity="0" |
297 | + inkscape:pageshadow="2" |
298 | + inkscape:zoom="8" |
299 | + inkscape:cx="20.022534" |
300 | + inkscape:cy="20.71947" |
301 | + inkscape:document-units="px" |
302 | + inkscape:current-layer="layer1" |
303 | + width="48px" |
304 | + height="48px" |
305 | + inkscape:showpageshadow="false" |
306 | + inkscape:window-width="872" |
307 | + inkscape:window-height="723" |
308 | + inkscape:window-x="406" |
309 | + inkscape:window-y="21" |
310 | + showgrid="false" |
311 | + inkscape:grid-points="false" |
312 | + showborder="true" |
313 | + showguides="false" |
314 | + inkscape:guide-bbox="false" |
315 | + inkscape:grid-bbox="true" |
316 | + inkscape:object-paths="false" |
317 | + inkscape:window-maximized="0"> |
318 | + <sodipodi:guide |
319 | + orientation="horizontal" |
320 | + position="8.6620581" |
321 | + id="guide7377" /> |
322 | + <sodipodi:guide |
323 | + orientation="horizontal" |
324 | + position="6" |
325 | + id="guide7379" /> |
326 | + <sodipodi:guide |
327 | + orientation="horizontal" |
328 | + position="36.062446" |
329 | + id="guide7492" /> |
330 | + <sodipodi:guide |
331 | + orientation="horizontal" |
332 | + position="51" |
333 | + id="guide7046" /> |
334 | + <sodipodi:guide |
335 | + orientation="horizontal" |
336 | + position="-17.5" |
337 | + id="guide7233" /> |
338 | + <sodipodi:guide |
339 | + orientation="horizontal" |
340 | + position="-29" |
341 | + id="guide7235" /> |
342 | + <sodipodi:guide |
343 | + orientation="horizontal" |
344 | + position="44.547727" |
345 | + id="guide6795" /> |
346 | + <sodipodi:guide |
347 | + orientation="horizontal" |
348 | + position="16.970563" |
349 | + id="guide6797" /> |
350 | + <sodipodi:guide |
351 | + orientation="horizontal" |
352 | + position="23.511301" |
353 | + id="guide6914" /> |
354 | + <inkscape:grid |
355 | + id="GridFromPre046Settings" |
356 | + type="xygrid" |
357 | + originx="0px" |
358 | + originy="0px" |
359 | + spacingx="0.5px" |
360 | + spacingy="0.5px" |
361 | + color="#0000ff" |
362 | + empcolor="#0000ff" |
363 | + opacity="0.2" |
364 | + empopacity="0.4" |
365 | + empspacing="2" /> |
366 | + </sodipodi:namedview> |
367 | + <metadata |
368 | + id="metadata7859"> |
369 | + <rdf:RDF> |
370 | + <cc:Work |
371 | + rdf:about=""> |
372 | + <dc:format>image/svg+xml</dc:format> |
373 | + <dc:type |
374 | + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> |
375 | + <dc:creator> |
376 | + <cc:Agent> |
377 | + <dc:title>Lapo Calamandrei</dc:title> |
378 | + </cc:Agent> |
379 | + </dc:creator> |
380 | + <dc:source /> |
381 | + <cc:license |
382 | + rdf:resource="http://creativecommons.org/licenses/GPL/2.0/" /> |
383 | + <dc:title></dc:title> |
384 | + <dc:subject> |
385 | + <rdf:Bag /> |
386 | + </dc:subject> |
387 | + </cc:Work> |
388 | + <cc:License |
389 | + rdf:about="http://creativecommons.org/licenses/GPL/2.0/"> |
390 | + <cc:permits |
391 | + rdf:resource="http://web.resource.org/cc/Reproduction" /> |
392 | + <cc:permits |
393 | + rdf:resource="http://web.resource.org/cc/Distribution" /> |
394 | + <cc:requires |
395 | + rdf:resource="http://web.resource.org/cc/Notice" /> |
396 | + <cc:permits |
397 | + rdf:resource="http://web.resource.org/cc/DerivativeWorks" /> |
398 | + <cc:requires |
399 | + rdf:resource="http://web.resource.org/cc/ShareAlike" /> |
400 | + <cc:requires |
401 | + rdf:resource="http://web.resource.org/cc/SourceCode" /> |
402 | + </cc:License> |
403 | + </rdf:RDF> |
404 | + </metadata> |
405 | + <g |
406 | + inkscape:label="Layer 1" |
407 | + inkscape:groupmode="layer" |
408 | + id="layer1"> |
409 | + <path |
410 | + style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;color:#ea5d00;fill:#ea5d00;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Bitstream Charter;-inkscape-font-specification:Bitstream Charter" |
411 | + d="m 31.458167,11 0,0.971084 0,2.506024 -2.5498,0 c -2.309243,1e-6 -4.600856,0.959829 -6.438247,2.568675 -1.848702,1.618749 -3.250996,4.052721 -3.250996,6.954217 0,1.569915 -0.481869,2.684008 -1.211156,3.414458 -0.729287,0.73045 -1.72852,1.096385 -2.868526,1.096385 l -4.589641,0 -2.0398408,0 -0.5099602,0 0,0.501205 0,4.009639 0,0.501205 0.5099602,0 2.0398408,0 4.589641,0 c 4.913523,0 9.179283,-4.047685 9.179283,-9.522892 0,-1.311125 0.627138,-2.380239 1.593626,-3.226506 0.947549,-0.829685 2.290606,-1.284337 2.996016,-1.284337 l 2.5498,0 0,2.506024 0,0.971084 L 32.25498,22.40241 39.394422,17.390361 40,16.983133 39.394422,16.575904 32.25498,11.563855 31.458167,11 z M 8,14.477108 l 0,0.501205 0,4.009639 0,0.501205 0.5099602,0 2.0398408,0 4.589641,0 c 1.140006,0 2.139239,0.365935 2.868526,1.096385 0.383279,0.38389 0.711734,0.865992 0.924303,1.472289 0.409442,-1.928125 1.388391,-3.582339 2.645418,-4.855421 -0.0054,-0.0055 0.0055,-0.0258 0,-0.03133 -1.680631,-1.696317 -3.981485,-2.693972 -6.438247,-2.693972 l -4.589641,0 -2.0398408,0 -0.5099602,0 z m 23.458167,10.556627 0,0.971084 0,2.506024 -2.5498,0 c -0.70541,0 -2.048467,-0.454652 -2.996016,-1.284337 -0.528622,-0.462867 -0.932659,-0.998256 -1.211156,-1.59759 -0.308884,1.992948 -1.187966,3.74975 -2.422311,5.137349 0.06485,0.05987 0.125211,0.13014 0.191236,0.187952 1.837391,1.608846 4.129004,2.568674 6.438247,2.568675 l 2.5498,0 0,2.506024 0,0.971084 0.796813,-0.563855 7.139442,-5.012049 L 40,31.016867 39.394422,30.609639 32.25498,25.59759 31.458167,25.033735 z" |
412 | + id="path6784" /> |
413 | + <path |
414 | + style="fill:url(#linearGradient3755);fill-opacity:1;stroke:none" |
415 | + d="m 24,29.65625 c -0.297307,0 -0.5803,-0.02559 -0.875,-0.03125 0.774683,-1.167911 1.33229,-2.514662 1.5625,-4 0.278497,0.599334 0.690128,1.130883 1.21875,1.59375 0.947549,0.829685 2.29459,1.28125 3,1.28125 l 2.5625,0 0,-2.5 0,-0.96875 0.78125,0.5625 3.46875,2.4375 C 32.250392,29.058149 28.258286,29.65625 24,29.65625 z M 22.5625,29.625 C 19.537058,29.52951 16.652999,29.1332 14.03125,28.5 l 1.09375,0 c 1.140006,0 2.145713,-0.3633 2.875,-1.09375 0.729287,-0.73045 1.21875,-1.836335 1.21875,-3.40625 0,-2.901496 1.401298,-5.350001 3.25,-6.96875 1.837391,-1.608846 4.128257,-2.562499 6.4375,-2.5625 l 2.5625,0 0,-2.5 0,-0.96875 0.78125,0.5625 7.15625,5 L 40,16.96875 39.40625,17.375 32.25,22.40625 l -0.78125,0.5625 0,-0.96875 0,-2.5 -2.5625,0 c -0.70541,0 -2.052451,0.451565 -3,1.28125 C 24.939762,21.627517 24.3125,22.688875 24.3125,24 c 0,2.153291 -0.650512,4.072677 -1.75,5.625 z m -3.625,-7.5625 C 18.724931,21.456203 18.383279,20.97764 18,20.59375 17.270713,19.8633 16.265006,19.5 15.125,19.5 l -4.5625,0 -2.0625,0 -0.5,0 0,-0.5 0,-4.03125 0,-0.5 0.5,0 2.0625,0 4.5625,0 c 2.456762,0 4.756869,0.991183 6.4375,2.6875 0.0055,0.0055 -0.0054,0.02575 0,0.03125 -1.257027,1.273082 -2.215558,2.946875 -2.625,4.875 z" |
416 | + id="path3741" /> |
417 | + <g |
418 | + transform="matrix(0.1337942,0,0,-0.1337942,31.527762,89.04701)" |
419 | + inkscape:label="Calque 1" |
420 | + id="g3743" /> |
421 | + <g |
422 | + transform="matrix(0.1672428,0,0,-0.1672428,38.442916,104.62323)" |
423 | + inkscape:label="Calque 1" |
424 | + id="g3745" /> |
425 | + </g> |
426 | +</svg> |
427 | |
428 | === added file 'mixxx/res/images/autodj/stock_mail-send-receive.svg' |
429 | --- mixxx/res/images/autodj/stock_mail-send-receive.svg 1970-01-01 00:00:00 +0000 |
430 | +++ mixxx/res/images/autodj/stock_mail-send-receive.svg 2012-03-01 22:38:18 +0000 |
431 | @@ -0,0 +1,87 @@ |
432 | +<?xml version="1.0" encoding="UTF-8" standalone="no"?> |
433 | +<!-- Created with Inkscape (http://www.inkscape.org/) --> |
434 | + |
435 | +<svg |
436 | + xmlns:dc="http://purl.org/dc/elements/1.1/" |
437 | + xmlns:cc="http://creativecommons.org/ns#" |
438 | + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" |
439 | + xmlns:svg="http://www.w3.org/2000/svg" |
440 | + xmlns="http://www.w3.org/2000/svg" |
441 | + xmlns:xlink="http://www.w3.org/1999/xlink" |
442 | + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" |
443 | + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" |
444 | + width="48px" |
445 | + height="48px" |
446 | + id="svg3787" |
447 | + version="1.1" |
448 | + inkscape:version="0.47 r22583" |
449 | + sodipodi:docname="Nouveau document 4"> |
450 | + <defs |
451 | + id="defs3789"> |
452 | + <linearGradient |
453 | + inkscape:collect="always" |
454 | + xlink:href="#linearGradient3172" |
455 | + id="linearGradient3767" |
456 | + gradientUnits="userSpaceOnUse" |
457 | + gradientTransform="matrix(0.644962,0,0,1.1832362,9.235153,4.016337)" |
458 | + x1="22.892584" |
459 | + y1="0.90414524" |
460 | + x2="22.892584" |
461 | + y2="21.132059" /> |
462 | + <linearGradient |
463 | + id="linearGradient3172"> |
464 | + <stop |
465 | + id="stop3174" |
466 | + offset="0" |
467 | + style="stop-color:#ffb584;stop-opacity:1;" /> |
468 | + <stop |
469 | + id="stop3176" |
470 | + offset="1" |
471 | + style="stop-color:#ffb584;stop-opacity:0;" /> |
472 | + </linearGradient> |
473 | + </defs> |
474 | + <sodipodi:namedview |
475 | + id="base" |
476 | + pagecolor="#ffffff" |
477 | + bordercolor="#666666" |
478 | + borderopacity="1.0" |
479 | + inkscape:pageopacity="0.0" |
480 | + inkscape:pageshadow="2" |
481 | + inkscape:zoom="7" |
482 | + inkscape:cx="24" |
483 | + inkscape:cy="24" |
484 | + inkscape:current-layer="layer1" |
485 | + showgrid="true" |
486 | + inkscape:grid-bbox="true" |
487 | + inkscape:document-units="px" |
488 | + inkscape:window-width="596" |
489 | + inkscape:window-height="502" |
490 | + inkscape:window-x="768" |
491 | + inkscape:window-y="24" |
492 | + inkscape:window-maximized="0" /> |
493 | + <metadata |
494 | + id="metadata3792"> |
495 | + <rdf:RDF> |
496 | + <cc:Work |
497 | + rdf:about=""> |
498 | + <dc:format>image/svg+xml</dc:format> |
499 | + <dc:type |
500 | + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> |
501 | + <dc:title></dc:title> |
502 | + </cc:Work> |
503 | + </rdf:RDF> |
504 | + </metadata> |
505 | + <g |
506 | + id="layer1" |
507 | + inkscape:label="Layer 1" |
508 | + inkscape:groupmode="layer"> |
509 | + <path |
510 | + style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;color:#ea5d00;fill:#ea5d00;fill-opacity:1;stroke:none;stroke-width:0.99999988;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Bitstream Charter;-inkscape-font-specification:Bitstream Charter" |
511 | + d="m 14.59375,4 -0.375,0.375 -9.46875,9.15625 -0.75,0.75 1.125,0 4.3125,0 0,18.03125 0,0.46875 0.53125,-0.03125 9.3125,-0.03125 0.5,0 0,-0.4375 0,-18 4.375,0 1.15625,0 -0.75,-0.75 L 14.96875,4.375 14.59375,4 z m 13.46875,11.21875 0,0.4375 0,18.0625 -4.25,0 -1.15625,0 0.75,0.75 L 32.875,43.625 33.25,44 l 0.40625,-0.375 9.5625,-9.15625 0.78125,-0.75 -1.15625,0 -4.40625,0 0,-18 0,-0.4375 -0.53125,0 -9.3125,-0.0625 -0.53125,0 z" |
512 | + id="path4360" /> |
513 | + <path |
514 | + style="fill:url(#linearGradient3767);fill-opacity:1;stroke:none" |
515 | + d="M 19.78125,29.4375 C 15.932317,29.076763 12.418889,28.236656 9.4375,27.03125 l 0,-12.75 -4.3125,0 -1.125,0 0.75,-0.75 9.46875,-9.15625 0.375,-0.375 0.375,0.375 9.59375,9.15625 0.75,0.75 -1.15625,0 -4.375,0 0,15.15625 z m 8.28125,0 0,-13.78125 0,-0.4375 0.53125,0 9.3125,0.0625 0.53125,0 0,0.4375 0,11.34375 c -2.995811,1.195807 -6.517914,2.027067 -10.375,2.375 z" |
516 | + id="path3753" /> |
517 | + </g> |
518 | +</svg> |
519 | |
520 | === modified file 'mixxx/res/mixxx.qrc' |
521 | --- mixxx/res/mixxx.qrc 2011-12-22 18:43:09 +0000 |
522 | +++ mixxx/res/mixxx.qrc 2012-03-01 22:38:18 +0000 |
523 | @@ -1,5 +1,8 @@ |
524 | <RCC> |
525 | <qresource prefix="/"> |
526 | + <file>images/autodj/media-playlist-shuffle.svg</file> |
527 | + <file>images/autodj/stock_mail-send-receive.svg</file> |
528 | + <file>images/autodj/bottom.svg</file> |
529 | <file>html/crates.html</file> |
530 | <file>html/playlists.html</file> |
531 | <file>images/mixxx-icon.png</file> |
532 | |
533 | === modified file 'mixxx/src/dlgautodj.cpp' |
534 | --- mixxx/src/dlgautodj.cpp 2011-11-30 06:19:47 +0000 |
535 | +++ mixxx/src/dlgautodj.cpp 2012-03-01 22:38:18 +0000 |
536 | @@ -6,8 +6,10 @@ |
537 | #include "controlobjectthreadmain.h" |
538 | #include "library/trackcollection.h" |
539 | #include "library/playlisttablemodel.h" |
540 | +#include "playerinfo.h" |
541 | #include "dlgautodj.h" |
542 | |
543 | +#define CONFIG_KEY "[Auto DJ]" |
544 | |
545 | DlgAutoDJ::DlgAutoDJ(QWidget* parent, ConfigObject<ConfigValue>* pConfig, |
546 | TrackCollection* pTrackCollection, MixxxKeyboard* pKeyboard) |
547 | @@ -18,8 +20,12 @@ |
548 | m_pConfig = pConfig; |
549 | m_pTrackCollection = pTrackCollection; |
550 | m_bAutoDJEnabled = false; |
551 | - m_bPlayer1Primed = false; |
552 | - m_bPlayer2Primed = false; |
553 | + m_bFadeNow = false; |
554 | + m_eState = ADJ_IDLE; |
555 | + |
556 | + m_posThreshold1 = 1.0f; |
557 | + m_posThreshold2 = 1.0f; |
558 | + |
559 | m_pTrackTableView = new WTrackTableView(this, pConfig, m_pTrackCollection); |
560 | m_pTrackTableView->installEventFilter(pKeyboard); |
561 | |
562 | @@ -55,9 +61,19 @@ |
563 | connect(pushButtonShuffle, SIGNAL(clicked(bool)), |
564 | this, SLOT(shufflePlaylist(bool))); |
565 | |
566 | + connect(pushButtonSkipNext, SIGNAL(clicked(bool)), |
567 | + this, SLOT(skipNext(bool))); |
568 | + |
569 | + connect(pushButtonFadeNow, SIGNAL(clicked(bool)), |
570 | + this, SLOT(fadeNow(bool))); |
571 | + |
572 | + connect(spinBoxTransition, SIGNAL(valueChanged(int)), |
573 | + this, SLOT(transitionValueChanged(int))); |
574 | + |
575 | connect(pushButtonAutoDJ, SIGNAL(toggled(bool)), |
576 | this, SLOT(toggleAutoDJ(bool))); _blah; |
577 | |
578 | + // playposition is from -0.14 to + 1.14 |
579 | m_pCOPlayPos1 = new ControlObjectThreadMain( |
580 | ControlObject::getControl(ConfigKey("[Channel1]", "playposition"))); |
581 | m_pCOPlayPos2 = new ControlObjectThreadMain( |
582 | @@ -66,12 +82,24 @@ |
583 | ControlObject::getControl(ConfigKey("[Channel1]", "play"))); |
584 | m_pCOPlay2 = new ControlObjectThreadMain( |
585 | ControlObject::getControl(ConfigKey("[Channel2]", "play"))); |
586 | + m_pCOPlay1Fb = new ControlObjectThreadMain( |
587 | + ControlObject::getControl(ConfigKey("[Channel1]", "play"))); |
588 | + m_pCOPlay2Fb = new ControlObjectThreadMain( |
589 | + ControlObject::getControl(ConfigKey("[Channel2]", "play"))); |
590 | m_pCORepeat1 = new ControlObjectThreadMain( |
591 | ControlObject::getControl(ConfigKey("[Channel1]", "repeat"))); |
592 | m_pCORepeat2 = new ControlObjectThreadMain( |
593 | ControlObject::getControl(ConfigKey("[Channel2]", "repeat"))); |
594 | m_pCOCrossfader = new ControlObjectThreadMain( |
595 | ControlObject::getControl(ConfigKey("[Master]", "crossfader"))); |
596 | + |
597 | + QString str_autoDjTransition = m_pConfig->getValueString(ConfigKey(CONFIG_KEY, "Transition")); |
598 | + if (str_autoDjTransition.isEmpty()) { |
599 | + spinBoxTransition->setValue(10); // default 10 sec |
600 | + } |
601 | + else { |
602 | + spinBoxTransition->setValue(str_autoDjTransition.toInt()); |
603 | + } |
604 | } |
605 | |
606 | DlgAutoDJ::~DlgAutoDJ() |
607 | @@ -80,8 +108,12 @@ |
608 | delete m_pCOPlayPos2; |
609 | delete m_pCOPlay1; |
610 | delete m_pCOPlay2; |
611 | + delete m_pCOPlay1Fb; |
612 | + delete m_pCOPlay2Fb; |
613 | + delete m_pCORepeat1; |
614 | delete m_pCORepeat2; |
615 | delete m_pCOCrossfader; |
616 | + delete m_pAutoDJTableModel; |
617 | } |
618 | |
619 | void DlgAutoDJ::onShow() |
620 | @@ -162,196 +194,436 @@ |
621 | qDebug() << "Shuffling done"; |
622 | } |
623 | |
624 | +void DlgAutoDJ::skipNext(bool buttonChecked) |
625 | +{ |
626 | + Q_UNUSED(buttonChecked); |
627 | + //m_pTrackTableView->sortByColumn(0, Qt::AscendingOrder); |
628 | + qDebug() << "Skip Next"; |
629 | + //Load the next song from the queue. |
630 | + |
631 | + if (m_pCOPlay1Fb->get() == 0.0f) { |
632 | + removePlayingTrackFromQueue("[Channel1]"); |
633 | + loadNextTrackFromQueue(); |
634 | + } |
635 | + else if (m_pCOPlay2Fb->get() == 0.0f) { |
636 | + removePlayingTrackFromQueue("[Channel2]"); |
637 | + loadNextTrackFromQueue(); |
638 | + } |
639 | + |
640 | +} |
641 | + |
642 | +void DlgAutoDJ::fadeNow(bool buttonChecked) |
643 | +{ |
644 | + Q_UNUSED(buttonChecked); |
645 | + qDebug() << "Fade Now"; |
646 | + if (m_eState == ADJ_IDLE && m_bAutoDJEnabled) { |
647 | + m_bFadeNow = true; |
648 | + double crossfader = m_pCOCrossfader->get(); |
649 | + if (crossfader <= 0.3f && m_pCOPlay1Fb->get() == 1.0f) { |
650 | + m_posThreshold1 = m_pCOPlayPos1->get() - ((crossfader + 1.0f) / 2 * (m_fadeDuration1)); |
651 | + m_pCORepeat1->slotSet(0.0f); // Repeat is disabled by FadeNow but disables auto Fade |
652 | + } |
653 | + else if (crossfader >= -0.3f && m_pCOPlay2Fb->get() == 1.0f) { |
654 | + m_posThreshold2 = m_pCOPlayPos2->get() - ((1.0f - crossfader) / 2 * (m_fadeDuration2)); |
655 | + m_pCORepeat2->slotSet(0.0f); // Repeat is disabled by FadeNow but disables auto Fade |
656 | + } |
657 | + } |
658 | +} |
659 | + |
660 | void DlgAutoDJ::toggleAutoDJ(bool toggle) |
661 | { |
662 | - if (toggle) //Enable Auto DJ |
663 | + if (toggle) //Enable Auto DJ |
664 | { |
665 | - if (m_pCOPlay1->get() == 1.0f && m_pCOPlay2->get() == 1.0f) { |
666 | + if ( m_pCOPlay1Fb->get() == 1.0f |
667 | + && m_pCOPlay2Fb->get() == 1.0f |
668 | + ){ |
669 | qDebug() << "One player must be stopped before enabling Auto DJ mode"; |
670 | pushButtonAutoDJ->setChecked(false); |
671 | return; |
672 | } |
673 | |
674 | - pushButtonAutoDJ->setText(tr("Disable Auto DJ")); |
675 | + // Never load the same track if it is already playing |
676 | + if (m_pCOPlay1Fb->get() == 1.0f) { |
677 | + removePlayingTrackFromQueue("[Channel1]"); |
678 | + } |
679 | + if ( m_pCOPlay2Fb->get() == 1.0f) { |
680 | + removePlayingTrackFromQueue("[Channel2]"); |
681 | + } |
682 | + |
683 | + TrackPointer nextTrack = getNextTrackFromQueue(); |
684 | + if (!nextTrack) { |
685 | + qDebug() << "Queue is empty now"; |
686 | + pushButtonAutoDJ->setChecked(false); |
687 | + return; |
688 | + } |
689 | + |
690 | + // Track is available so GO |
691 | + pushButtonAutoDJ->setToolTip(tr("Disable Auto DJ")); |
692 | + pushButtonAutoDJ->setText(tr("Disable Auto DJ")); |
693 | + qDebug() << "Auto DJ enabled"; |
694 | m_bAutoDJEnabled = true; |
695 | + |
696 | connect(m_pCOPlayPos1, SIGNAL(valueChanged(double)), |
697 | this, SLOT(player1PositionChanged(double))); |
698 | connect(m_pCOPlayPos2, SIGNAL(valueChanged(double)), |
699 | this, SLOT(player2PositionChanged(double))); |
700 | |
701 | - |
702 | - //Manually override the "next track is already loaded" flag |
703 | - //because we've already primed a player with the first track. |
704 | - //We do this so that you don't lose the first song in your |
705 | - //Auto DJ queue if you enable Auto DJ then change your mind |
706 | - //and disable it right away. This just makes it a little bit |
707 | - //more user friendly. :) |
708 | - //m_bNextTrackAlreadyLoaded = true; |
709 | - m_bPlayer1Primed = false; |
710 | - m_bPlayer2Primed = false; |
711 | - |
712 | - //If there are no tracks in the Auto DJ queue, disable Auto DJ mode. |
713 | - /* if (m_pAutoDJTableModel->rowCount() == 0) |
714 | - { |
715 | - //Queue was empty. Disable and return. |
716 | - pushButtonAutoDJ->setChecked(false); |
717 | - return; |
718 | - }*/ //don't need this code, above block takes care of this case. |
719 | - |
720 | - //If only one of the players is playing... |
721 | - if ((m_pCOPlay1->get() == 1.0f && m_pCOPlay2->get() == 0.0f) || |
722 | - (m_pCOPlay1->get() == 0.0f && m_pCOPlay2->get() == 1.0f)) |
723 | - { |
724 | - //Load the first song from the queue. |
725 | - if (!loadNextTrackFromQueue(false)) { |
726 | - //Queue was empty. Disable and return. |
727 | - pushButtonAutoDJ->setChecked(false); |
728 | - return; |
729 | - } |
730 | - //Set the primed flags so the crossfading algorithm knows |
731 | - //that it doesn't need to load a track into whatever player. |
732 | - if (m_pCOPlay1->get() == 1.0f) |
733 | - { |
734 | - m_bPlayer1Primed = true; |
735 | - } |
736 | - if (m_pCOPlay2->get() == 1.0f) |
737 | - { |
738 | - m_bPlayer2Primed = true; |
739 | - } |
740 | - } |
741 | - //If both players are stopped, start the first one (which should have just had a track loaded into it) |
742 | - else if (m_pCOPlay1->get() == 0.0f && m_pCOPlay2->get() == 0.0f) { |
743 | - //Load the first song from the queue. |
744 | - if (!loadNextTrackFromQueue(false)) { |
745 | - //Queue was empty. Disable and return. |
746 | - pushButtonAutoDJ->setChecked(false); |
747 | - return; |
748 | - } |
749 | - m_pCOCrossfader->slotSet(-1.0f); //Move crossfader to the left! |
750 | - m_pCORepeat1->slotSet(1.0f); //Turn on repeat mode to avoid race condition between async load |
751 | - //and "play" command. |
752 | - m_pCOPlay1->slotSet(1.0f); //Play the track in player 1 |
753 | - } |
754 | + connect(m_pCOPlay1Fb, SIGNAL(valueChanged(double)), |
755 | + this, SLOT(player1PlayChanged(double))); |
756 | + connect(m_pCOPlay2Fb, SIGNAL(valueChanged(double)), |
757 | + this, SLOT(player2PlayChanged(double))); |
758 | + |
759 | + if (m_pCOPlay1Fb->get() == 0.0f && m_pCOPlay2Fb->get() == 0.0f) { |
760 | + // both decks are stopped |
761 | + m_eState = ADJ_ENABLE_P1LOADED; |
762 | + m_pCOPlayPos1->slotSet(-0.001f); // Force Update on load Track |
763 | + } |
764 | + else if (m_pCOPlay1Fb->get() == 1.0f) |
765 | + { |
766 | + // deck 1 is already playing |
767 | + m_eState = ADJ_IDLE; |
768 | + player1PlayChanged(1.0f); |
769 | + } |
770 | + else { |
771 | + // deck 2 is already playing |
772 | + m_eState = ADJ_IDLE; |
773 | + player2PlayChanged(1.0f); |
774 | + } |
775 | + emit(loadTrack(nextTrack)); // Loads into first deck If stopped else into second else not |
776 | } |
777 | - else //Disable Auto DJ |
778 | - { |
779 | + else { //Disable Auto DJ |
780 | + pushButtonAutoDJ->setToolTip(tr("Enable Auto DJ")); |
781 | pushButtonAutoDJ->setText(tr("Enable Auto DJ")); |
782 | qDebug() << "Auto DJ disabled"; |
783 | m_bAutoDJEnabled = false; |
784 | + m_bFadeNow = false; |
785 | m_pCOPlayPos1->disconnect(this); |
786 | m_pCOPlayPos2->disconnect(this); |
787 | - m_pCORepeat1->slotSet(0.0f); //Turn off repeat mode |
788 | - m_pCORepeat2->slotSet(0.0f); //Turn off repeat mode |
789 | + m_pCOPlay1->disconnect(this); |
790 | + m_pCOPlay2->disconnect(this); |
791 | } |
792 | } |
793 | |
794 | void DlgAutoDJ::player1PositionChanged(double value) |
795 | { |
796 | - const float posThreshold = 0.95; //95% playback is when we crossfade and do stuff |
797 | - if (value > posThreshold) |
798 | - { |
799 | - //Crossfade! |
800 | - float crossfadeValue = -1.0f + 2*(value-posThreshold)/(1.0f-posThreshold); |
801 | - m_pCOCrossfader->slotSet(crossfadeValue); //Move crossfader to the right! |
802 | - //If the second player doesn't have a new track loaded in it... |
803 | - if (!m_bPlayer2Primed) |
804 | - { |
805 | - qDebug() << "pp1c loading"; |
806 | - |
807 | - //Load the next track into Player 2 |
808 | - //if (!m_bNextTrackAlreadyLoaded) //Fudge to make us not skip the first track |
809 | - { |
810 | - if (!loadNextTrackFromQueue(true)) |
811 | - return; |
812 | - } |
813 | - //m_bNextTrackAlreadyLoaded = false; //Reset fudge |
814 | - m_bPlayer2Primed = true; |
815 | - } |
816 | - //If the second player is stopped... |
817 | - if (m_pCOPlay2->get() == 0.0f) |
818 | - { |
819 | - //Turn off repeat mode to tell Player 1 to stop at the end |
820 | - m_pCORepeat1->slotSet(0.0f); |
821 | - |
822 | - //Turn on repeat mode to tell Player 2 to start playing when the new track is loaded. |
823 | - //This helps us get around the fact that it takes time for the track to be loaded |
824 | - //and that is executed asynchronously (so we get around the race condition). |
825 | - m_pCORepeat2->slotSet(1.0f); |
826 | - //Play! |
827 | - m_pCOPlay2->slotSet(1.0f); |
828 | - } |
829 | - |
830 | - if (value == 1.0f) |
831 | - { |
832 | - m_pCOPlay1->slotSet(0.0f); //Stop the player |
833 | - m_bPlayer1Primed = false; |
834 | + // const float posThreshold = 0.95; //95% playback is when we crossfade and do stuff |
835 | + const float fadeDuration = m_fadeDuration1; // 0.05; // 5% playback is crossfade duration |
836 | + |
837 | + // qDebug() << "player1PositionChanged(" << value << ")"; |
838 | + |
839 | + if (!m_bAutoDJEnabled) { |
840 | + //nothing to do |
841 | + return; |
842 | + } |
843 | + |
844 | + |
845 | + if (m_eState == ADJ_ENABLE_P1LOADED) { |
846 | + // Auto DJ Start |
847 | + if (m_pCOPlay1Fb->get() == 0.0f && m_pCOPlay2Fb->get() == 0.0f) { |
848 | + m_pCOCrossfader->slotSet(-1.0f); //Move crossfader to the left! |
849 | + m_pCOPlay1->slotSet(1.0f); //Play the track in player 1 |
850 | + removePlayingTrackFromQueue("[Channel1]"); |
851 | + } |
852 | + else if (m_pCOPlay1Fb->get() == 1.0f && m_pCOPlay2Fb->get() == 0.0f) { |
853 | + // Here we are, if first deck was playing before starting Auto DJ |
854 | + // or if it was started just before |
855 | + loadNextTrackFromQueue(); |
856 | + m_eState = ADJ_IDLE; |
857 | + player1PlayChanged(1.0f); // if we start the deck from code we don`t get a signal |
858 | + // call function manually |
859 | + } |
860 | + else { |
861 | + m_eState = ADJ_IDLE; |
862 | + player2PlayChanged(1.0f); |
863 | + } |
864 | + return; |
865 | + } |
866 | + |
867 | + if (m_eState == ADJ_P2FADING) { |
868 | + if (m_pCOPlay2Fb->get() == 0.0f && m_pCOPlay1Fb->get() == 1.0f) { |
869 | + loadNextTrackFromQueue(); |
870 | + // End State |
871 | + m_pCOCrossfader->slotSet(-1.0f); //Move crossfader to the left! |
872 | + // qDebug() << "1: m_pCOCrossfader->slotSet(_-1.0f_);"; |
873 | + m_eState = ADJ_IDLE; |
874 | + } |
875 | + return; |
876 | + } |
877 | + |
878 | + if (m_eState == ADJ_IDLE) { |
879 | + if (m_pCORepeat1->get() == 1.0f) { |
880 | + //repeat disables auto DJ |
881 | + return; |
882 | + } |
883 | + } |
884 | + |
885 | + if (value >= m_posThreshold1) { |
886 | + if ( m_eState == ADJ_IDLE |
887 | + && (m_pCOPlay1Fb->get() == 1.0f|| m_posThreshold1 >= 1.0f) |
888 | + ) { |
889 | + if (m_pCOPlay2Fb->get() == 0.0f) { |
890 | + // Start Deck 2 |
891 | + player2PlayChanged(1.0f); |
892 | + m_pCOPlay2->slotSet(1.0f); |
893 | + if (fadeDuration < 0.0f) { |
894 | + // Scroll back for pause between tracks |
895 | + m_pCOPlayPos2->slotSet(m_fadeDuration2); |
896 | + } |
897 | + } |
898 | + removePlayingTrackFromQueue("[Channel2]"); |
899 | + |
900 | + m_eState = ADJ_P1FADING; |
901 | + } |
902 | + |
903 | + float posFadeEnd = m_posThreshold1 + fadeDuration; |
904 | + if( posFadeEnd > 1.0f ) posFadeEnd = 1.0f; |
905 | + |
906 | + if (value >= posFadeEnd) { |
907 | + // Pre-EndState |
908 | + // m_pCOCrossfader->slotSet(1.0f); //Move crossfader to the right! |
909 | + |
910 | + m_pCOPlay1->slotSet(0.0f); //Stop the player |
911 | + |
912 | + //m_posThreshold = 1.0f - fadeDuration; // back to default |
913 | + |
914 | + // does not work always emediatly after stop |
915 | + // loadNextTrackFromQueue(); |
916 | + // m_eState = ADJ_IDLE; // Fading ready |
917 | + } |
918 | + else { |
919 | + //Crossfade! |
920 | + float crossfadeValue = -1.0f + 2*(value-m_posThreshold1)/(posFadeEnd-m_posThreshold1); |
921 | + // crossfadeValue = -1.0f -> + 1.0f |
922 | + m_pCOCrossfader->slotSet(crossfadeValue); //Move crossfader to the right! |
923 | + // qDebug() << "1: m_pCOCrossfader->slotSet " << crossfadeValue; |
924 | } |
925 | } |
926 | } |
927 | |
928 | void DlgAutoDJ::player2PositionChanged(double value) |
929 | { |
930 | - const float posThreshold = 0.95; //95% playback is when we crossfade and do stuff |
931 | - if (value > posThreshold) |
932 | - { |
933 | - //Crossfade! |
934 | - float crossfadeValue = 1.0f - 2*(value-posThreshold)/(1.0f-posThreshold); |
935 | - m_pCOCrossfader->slotSet(crossfadeValue); //Move crossfader to the right! |
936 | - |
937 | - //If the first player doesn't have the next track loaded, load a track into |
938 | - //it and start playing it! |
939 | - if (!m_bPlayer1Primed) |
940 | - { |
941 | - //Load the next track into player 1 |
942 | - //if (!m_bNextTrackAlreadyLoaded) //Fudge to make us not skip the first track |
943 | - { |
944 | - if (!loadNextTrackFromQueue(true)) |
945 | - return; |
946 | - } |
947 | - //m_bNextTrackAlreadyLoaded = false; //Reset fudge |
948 | - m_bPlayer1Primed = true; |
949 | - } |
950 | - if (m_pCOPlay1->get() == 0.0f) |
951 | - { |
952 | - //Turn off repeat mode to tell Player 2 to stop at the end |
953 | - m_pCORepeat2->slotSet(0.0f); |
954 | - |
955 | - //Turn on repeat mode to tell Player 1 to start playing when the new track is loaded. |
956 | - //This helps us get around the fact that it takes time for the track to be loaded |
957 | - //and that is executed asynchronously (so we get around the race condition). |
958 | - m_pCORepeat1->slotSet(1.0f); |
959 | - m_pCOPlay1->slotSet(1.0f); |
960 | - } |
961 | - |
962 | - if (value == 1.0f) |
963 | - { |
964 | - m_pCOPlay2->slotSet(0.0f); //Stop the player |
965 | - m_bPlayer2Primed = false; |
966 | - } |
967 | - } |
968 | -} |
969 | - |
970 | - |
971 | -bool DlgAutoDJ::loadNextTrackFromQueue(bool removeTopMostBeforeLoading) |
972 | -{ |
973 | - if (removeTopMostBeforeLoading) { |
974 | - //Only remove the top track if this isn't the start of Auto DJ mode. |
975 | - m_pAutoDJTableModel->removeTrack(m_pAutoDJTableModel->index(0, 0)); |
976 | - } |
977 | - |
978 | - //Get the track at the top of the playlist... |
979 | - TrackPointer nextTrack = m_pAutoDJTableModel->getTrack(m_pAutoDJTableModel->index(0, 0)); |
980 | - |
981 | - if (!nextTrack) //We ran out of tracks in the queue... |
982 | - { |
983 | - //Disable auto DJ and return... |
984 | - pushButtonAutoDJ->setChecked(false); |
985 | - return false; |
986 | - } |
987 | - |
988 | - //m_bNextTrackAlreadyLoaded = false; |
989 | - |
990 | - emit(loadTrack(nextTrack)); |
991 | + // const float posThreshold = 0.95; //95% playback is when we crossfade and do stuff |
992 | + float fadeDuration = m_fadeDuration2; // 0.05; // 5% playback is crossfade duration |
993 | + |
994 | + //qDebug() << "player2PositionChanged(" << value << ")"; |
995 | + |
996 | + |
997 | + if (!m_bAutoDJEnabled) { |
998 | + //nothing to do |
999 | + return; |
1000 | + } |
1001 | + |
1002 | + if (m_eState == ADJ_P1FADING) { |
1003 | + if (m_pCOPlay1Fb->get() == 0.0f && m_pCOPlay2Fb->get() == 1.0f) { |
1004 | + // End State |
1005 | + m_pCOCrossfader->slotSet(1.0f); //Move crossfader to the right! |
1006 | + // qDebug() << "1: m_pCOCrossfader->slotSet(_1.0f_);"; |
1007 | + m_eState = ADJ_IDLE; |
1008 | + loadNextTrackFromQueue(); |
1009 | + } |
1010 | + return; |
1011 | + } |
1012 | + |
1013 | + if (m_eState == ADJ_IDLE) { |
1014 | + if (m_pCORepeat2->get() == 1.0f) { |
1015 | + //repeat disables auto DJ |
1016 | + return; |
1017 | + } |
1018 | + } |
1019 | + |
1020 | + if (value >= m_posThreshold2) { |
1021 | + if( m_eState == ADJ_IDLE |
1022 | + && (m_pCOPlay2Fb->get() == 1.0f|| m_posThreshold2 >= 1.0f) |
1023 | + ) { |
1024 | + if (m_pCOPlay1Fb->get() == 0.0f) { |
1025 | + player1PlayChanged(1.0f); |
1026 | + m_pCOPlay1->slotSet(1.0f); |
1027 | + if(fadeDuration < 0 ){ |
1028 | + // Scroll back for pause between tracks |
1029 | + m_pCOPlayPos1->slotSet(m_fadeDuration1); |
1030 | + } |
1031 | + } |
1032 | + removePlayingTrackFromQueue("[Channel1]"); |
1033 | + m_eState = ADJ_P2FADING; |
1034 | + } |
1035 | + |
1036 | + float posFadeEnd = m_posThreshold2 + fadeDuration; |
1037 | + if( posFadeEnd > 1.0f ) posFadeEnd = 1.0f; |
1038 | + |
1039 | + if (value >= posFadeEnd) { |
1040 | + //Pre-End State |
1041 | + //m_pCOCrossfader->slotSet(-1.0f); //Move crossfader to the left! |
1042 | + |
1043 | + m_pCOPlay2->slotSet(0.0f); //Stop the player |
1044 | + |
1045 | + //m_posThreshold = 1.0f - fadeDuration; // back to default |
1046 | + |
1047 | + // does not work always immediately after stop |
1048 | + // loadNextTrackFromQueue(); |
1049 | + // m_eState = ADJ_IDLE; // Fading ready |
1050 | + } |
1051 | + else { |
1052 | + //Crossfade! |
1053 | + float crossfadeValue = 1.0f - 2*(value-m_posThreshold2)/(posFadeEnd-m_posThreshold2); |
1054 | + // crossfadeValue = 1.0f -> + -1.0f |
1055 | + m_pCOCrossfader->slotSet(crossfadeValue); //Move crossfader to the right! |
1056 | + // qDebug() << "2: m_pCOCrossfader->slotSet " << crossfadeValue; |
1057 | + } |
1058 | + } |
1059 | +} |
1060 | + |
1061 | + |
1062 | +TrackPointer DlgAutoDJ::getNextTrackFromQueue() |
1063 | +{ |
1064 | + //Get the track at the top of the playlist... |
1065 | + |
1066 | + TrackPointer nextTrack; |
1067 | + |
1068 | + for (;;) { |
1069 | + nextTrack = m_pAutoDJTableModel->getTrack(m_pAutoDJTableModel->index(0, 0)); |
1070 | + |
1071 | + if (nextTrack) { |
1072 | + if (nextTrack->exists()) { |
1073 | + // found a valid Track |
1074 | + return nextTrack; |
1075 | + } |
1076 | + else { |
1077 | + // Remove missing song from auto DJ playlist |
1078 | + m_pAutoDJTableModel->removeTrack(m_pAutoDJTableModel->index(0, 0)); |
1079 | + } |
1080 | + } |
1081 | + else { |
1082 | + // we are running out of tracks |
1083 | + break; |
1084 | + } |
1085 | + } |
1086 | + return nextTrack; |
1087 | +} |
1088 | + |
1089 | + |
1090 | +bool DlgAutoDJ::loadNextTrackFromQueue() |
1091 | +{ |
1092 | + //Get the track at the top of the playlist... |
1093 | + |
1094 | + TrackPointer nextTrack = getNextTrackFromQueue(); |
1095 | + |
1096 | + if (!nextTrack) { //We ran out of tracks in the queue... |
1097 | + //Disable auto DJ and return... |
1098 | + pushButtonAutoDJ->setChecked(false); |
1099 | + return false; |
1100 | + } |
1101 | + |
1102 | + emit(loadTrack(nextTrack)); |
1103 | + return true; |
1104 | +} |
1105 | + |
1106 | +bool DlgAutoDJ::removePlayingTrackFromQueue(QString group) |
1107 | +{ |
1108 | + TrackPointer nextTrack, loadedTrack; |
1109 | + int nextId = 0, loadedId = 0; |
1110 | + |
1111 | + |
1112 | + //Get the track at the top of the playlist... |
1113 | + nextTrack = m_pAutoDJTableModel->getTrack(m_pAutoDJTableModel->index(0, 0)); |
1114 | + if (nextTrack) { |
1115 | + nextId = nextTrack->getId(); |
1116 | + } |
1117 | + |
1118 | + //Get loaded track |
1119 | + loadedTrack = PlayerInfo::Instance().getTrackInfo(group); |
1120 | + if (loadedTrack) { |
1121 | + loadedId = loadedTrack->getId(); |
1122 | + } |
1123 | + |
1124 | + //When enable auto DJ and Topmost Song is already on second deck, nothing to do |
1125 | + // BaseTrackPlayer::getLoadedTrack() |
1126 | + // pTrack = PlayerInfo::Instance().getCurrentPlayingTrack(); |
1127 | + |
1128 | + |
1129 | + if (loadedId != nextId) { |
1130 | + // Do not remove when the user has loaded a track manualy |
1131 | + return false; |
1132 | + } |
1133 | + |
1134 | + // remove the top track |
1135 | + m_pAutoDJTableModel->removeTrack(m_pAutoDJTableModel->index(0, 0)); |
1136 | |
1137 | return true; |
1138 | } |
1139 | + |
1140 | +void DlgAutoDJ::player1PlayChanged(double value){ |
1141 | + qDebug() << "player1PlayChanged(" << value << ")"; |
1142 | + |
1143 | + if (value == 1.0f && m_eState == ADJ_IDLE) { |
1144 | + TrackPointer loadedTrack = PlayerInfo::Instance().getTrackInfo("[Channel1]"); |
1145 | + if (loadedTrack) { |
1146 | + int TrackDuration = loadedTrack->getDuration(); |
1147 | + qDebug() << "TrackDuration = " << TrackDuration; |
1148 | + |
1149 | + int autoDjTransition = spinBoxTransition->value(); |
1150 | + |
1151 | + if (TrackDuration > autoDjTransition) { |
1152 | + m_fadeDuration1 = (float)autoDjTransition / (float)TrackDuration; |
1153 | + } |
1154 | + else { |
1155 | + m_fadeDuration1 = 0; |
1156 | + } |
1157 | + if (autoDjTransition > 0) { |
1158 | + m_posThreshold1 = 1.0f - m_fadeDuration1; |
1159 | + } |
1160 | + else { |
1161 | + // in case of pause |
1162 | + m_posThreshold1 = 1.0f; |
1163 | + } |
1164 | + qDebug() << "m_fadeDuration1 = " << m_fadeDuration1; |
1165 | + } |
1166 | + } |
1167 | +} |
1168 | + |
1169 | +void DlgAutoDJ::player2PlayChanged(double value){ |
1170 | + qDebug() << "player2PlayChanged(" << value << ")"; |
1171 | + |
1172 | + if (value == 1.0f && m_eState == ADJ_IDLE) { |
1173 | + TrackPointer loadedTrack = PlayerInfo::Instance().getTrackInfo("[Channel2]"); |
1174 | + if (loadedTrack) { |
1175 | + int TrackDuration = loadedTrack->getDuration(); |
1176 | + qDebug() << "TrackDuration = " << TrackDuration; |
1177 | + |
1178 | + int autoDjTransition = spinBoxTransition->value(); |
1179 | + |
1180 | + if (TrackDuration > autoDjTransition) { |
1181 | + m_fadeDuration2 = (float)autoDjTransition / (float)TrackDuration; |
1182 | + } |
1183 | + else { |
1184 | + m_fadeDuration2 = 0; |
1185 | + } |
1186 | + if (autoDjTransition > 0) { |
1187 | + m_posThreshold2 = 1.0f - m_fadeDuration2; |
1188 | + } |
1189 | + else { |
1190 | + // in case of pause |
1191 | + m_posThreshold2 = 1.0f; |
1192 | + } |
1193 | + qDebug() << "m_fadeDuration2 = " << m_fadeDuration2; |
1194 | + } |
1195 | + } |
1196 | +} |
1197 | + |
1198 | +void DlgAutoDJ::transitionValueChanged(int value){ |
1199 | + |
1200 | + if (m_bAutoDJEnabled) { |
1201 | + if (m_bAutoDJEnabled && m_eState == ADJ_IDLE){ |
1202 | + if (m_pCOPlay1Fb->get() == 1.0f) { |
1203 | + player1PlayChanged(1.0f); |
1204 | + } |
1205 | + if (m_pCOPlay2Fb->get() == 1.0f) { |
1206 | + player2PlayChanged(1.0f); |
1207 | + } |
1208 | + } |
1209 | + } |
1210 | + m_pConfig->set(ConfigKey(CONFIG_KEY, "Transition"), ConfigValue(value)); |
1211 | +} |
1212 | + |
1213 | +bool DlgAutoDJ::appendTrack(int trackId){ |
1214 | + return m_pAutoDJTableModel->appendTrack(trackId); |
1215 | +} |
1216 | |
1217 | === modified file 'mixxx/src/dlgautodj.h' |
1218 | --- mixxx/src/dlgautodj.h 2011-04-24 06:00:11 +0000 |
1219 | +++ mixxx/src/dlgautodj.h 2012-03-01 22:38:18 +0000 |
1220 | @@ -31,19 +31,36 @@ |
1221 | virtual void loadSelectedTrack(); |
1222 | virtual void loadSelectedTrackToGroup(QString group); |
1223 | virtual void moveSelection(int delta); |
1224 | + virtual bool appendTrack(int trackId); |
1225 | |
1226 | public slots: |
1227 | void shufflePlaylist(bool buttonChecked); |
1228 | + void skipNext(bool buttonChecked); |
1229 | + void fadeNow(bool buttonChecked); |
1230 | void toggleAutoDJ(bool toggle); |
1231 | void player1PositionChanged(double value); |
1232 | void player2PositionChanged(double value); |
1233 | + void player1PlayChanged(double value); |
1234 | + void player2PlayChanged(double value); |
1235 | + void transitionValueChanged(int value); |
1236 | |
1237 | signals: |
1238 | void loadTrack(TrackPointer tio); |
1239 | void loadTrackToPlayer(TrackPointer tio, QString group); |
1240 | |
1241 | private: |
1242 | - bool loadNextTrackFromQueue(bool removeTopMostBeforeLoading); |
1243 | + enum ADJstates |
1244 | + { |
1245 | + ADJ_IDLE = 0, |
1246 | + ADJ_P1FADING, |
1247 | + ADJ_P2FADING, |
1248 | + ADJ_ENABLE_P1LOADED, |
1249 | + ADJ_ENABLE_P1PLAYING |
1250 | + }; |
1251 | + |
1252 | + TrackPointer getNextTrackFromQueue(); |
1253 | + bool loadNextTrackFromQueue(); |
1254 | + bool removePlayingTrackFromQueue(QString group); |
1255 | |
1256 | ConfigObject<ConfigValue>* m_pConfig; |
1257 | TrackCollection* m_pTrackCollection; |
1258 | @@ -57,11 +74,18 @@ |
1259 | make our first-track-gets-loaded-but- |
1260 | not-removed-from-the-queue behaviour |
1261 | work. */ |
1262 | - bool m_bPlayer1Primed, m_bPlayer2Primed; |
1263 | + bool m_bFadeNow; |
1264 | + enum ADJstates m_eState; |
1265 | + float m_posThreshold1; |
1266 | + float m_posThreshold2; |
1267 | + float m_fadeDuration1; |
1268 | + float m_fadeDuration2; |
1269 | ControlObjectThreadMain* m_pCOPlayPos1; |
1270 | ControlObjectThreadMain* m_pCOPlayPos2; |
1271 | ControlObjectThreadMain* m_pCOPlay1; |
1272 | ControlObjectThreadMain* m_pCOPlay2; |
1273 | + ControlObjectThreadMain* m_pCOPlay1Fb; |
1274 | + ControlObjectThreadMain* m_pCOPlay2Fb; |
1275 | ControlObjectThreadMain* m_pCORepeat1; |
1276 | ControlObjectThreadMain* m_pCORepeat2; |
1277 | ControlObjectThreadMain* m_pCOCrossfader; |
1278 | |
1279 | === modified file 'mixxx/src/dlgautodj.ui' |
1280 | --- mixxx/src/dlgautodj.ui 2011-10-05 03:30:02 +0000 |
1281 | +++ mixxx/src/dlgautodj.ui 2012-03-01 22:38:18 +0000 |
1282 | @@ -6,13 +6,28 @@ |
1283 | <rect> |
1284 | <x>0</x> |
1285 | <y>0</y> |
1286 | - <width>582</width> |
1287 | + <width>500</width> |
1288 | <height>399</height> |
1289 | </rect> |
1290 | </property> |
1291 | <property name="windowTitle"> |
1292 | <string>Manage</string> |
1293 | </property> |
1294 | + <property name="styleSheet"> |
1295 | + <string notr="true">#pushButtonShuffle{ |
1296 | + border-image: url(:/images/autodj/media-playlist-shuffle.svg); |
1297 | +} |
1298 | + |
1299 | +#pushButtonSkipNext{ |
1300 | + border-image: url(:/images/autodj/bottom.svg); |
1301 | +} |
1302 | + |
1303 | +#pushButtonFadeNow{ |
1304 | + border-image: url(:/images/autodj/stock_mail-send-receive.svg); |
1305 | +} |
1306 | + |
1307 | +</string> |
1308 | + </property> |
1309 | <layout class="QVBoxLayout" name="verticalLayout"> |
1310 | <property name="leftMargin"> |
1311 | <number>0</number> |
1312 | @@ -25,13 +40,89 @@ |
1313 | </property> |
1314 | <item> |
1315 | <layout class="QHBoxLayout" name="horizontalLayout"> |
1316 | + <property name="sizeConstraint"> |
1317 | + <enum>QLayout::SetMinimumSize</enum> |
1318 | + </property> |
1319 | <item> |
1320 | <widget class="QPushButton" name="pushButtonShuffle"> |
1321 | - <property name="text"> |
1322 | - <string>Shuffle playlist</string> |
1323 | - </property> |
1324 | - <property name="checkable"> |
1325 | - <bool>false</bool> |
1326 | + <property name="maximumSize"> |
1327 | + <size> |
1328 | + <width>24</width> |
1329 | + <height>24</height> |
1330 | + </size> |
1331 | + </property> |
1332 | + <property name="toolTip"> |
1333 | + <string>Shuffle Playlist</string> |
1334 | + </property> |
1335 | + <property name="text"> |
1336 | + <string/> |
1337 | + </property> |
1338 | + <property name="checkable"> |
1339 | + <bool>false</bool> |
1340 | + </property> |
1341 | + </widget> |
1342 | + </item> |
1343 | + <item> |
1344 | + <widget class="QPushButton" name="pushButtonSkipNext"> |
1345 | + <property name="maximumSize"> |
1346 | + <size> |
1347 | + <width>24</width> |
1348 | + <height>24</height> |
1349 | + </size> |
1350 | + </property> |
1351 | + <property name="toolTip"> |
1352 | + <string>Skip Next Track</string> |
1353 | + </property> |
1354 | + <property name="text"> |
1355 | + <string/> |
1356 | + </property> |
1357 | + <property name="checkable"> |
1358 | + <bool>false</bool> |
1359 | + </property> |
1360 | + </widget> |
1361 | + </item> |
1362 | + <item> |
1363 | + <widget class="QLabel" name="label_2"> |
1364 | + <property name="text"> |
1365 | + <string>Transition [sec]</string> |
1366 | + </property> |
1367 | + </widget> |
1368 | + </item> |
1369 | + <item> |
1370 | + <widget class="QSpinBox" name="spinBoxTransition"> |
1371 | + <property name="sizePolicy"> |
1372 | + <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> |
1373 | + <horstretch>0</horstretch> |
1374 | + <verstretch>0</verstretch> |
1375 | + </sizepolicy> |
1376 | + </property> |
1377 | + <property name="maximumSize"> |
1378 | + <size> |
1379 | + <width>45</width> |
1380 | + <height>16777215</height> |
1381 | + </size> |
1382 | + </property> |
1383 | + <property name="alignment"> |
1384 | + <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> |
1385 | + </property> |
1386 | + <property name="minimum"> |
1387 | + <number>-9</number> |
1388 | + </property> |
1389 | + </widget> |
1390 | + </item> |
1391 | + <item> |
1392 | + <widget class="QPushButton" name="pushButtonFadeNow"> |
1393 | + <property name="maximumSize"> |
1394 | + <size> |
1395 | + <width>24</width> |
1396 | + <height>24</height> |
1397 | + </size> |
1398 | + </property> |
1399 | + <property name="toolTip"> |
1400 | + <string>Fade Now</string> |
1401 | + </property> |
1402 | + <property name="text"> |
1403 | + <string/> |
1404 | </property> |
1405 | </widget> |
1406 | </item> |
1407 | @@ -42,24 +133,17 @@ |
1408 | </property> |
1409 | <property name="sizeHint" stdset="0"> |
1410 | <size> |
1411 | - <width>40</width> |
1412 | + <width>1</width> |
1413 | <height>20</height> |
1414 | </size> |
1415 | </property> |
1416 | </spacer> |
1417 | </item> |
1418 | <item> |
1419 | - <widget class="QLabel" name="label"> |
1420 | - <property name="text"> |
1421 | - <string>Add tracks to the queue below...</string> |
1422 | - </property> |
1423 | - <property name="buddy" > |
1424 | - <cstring>m_pTrackTablePlaceholder</cstring> |
1425 | - </property> |
1426 | - </widget> |
1427 | - </item> |
1428 | - <item> |
1429 | <widget class="QPushButton" name="pushButtonAutoDJ"> |
1430 | + <property name="toolTip"> |
1431 | + <string>Enable Auto DJ</string> |
1432 | + </property> |
1433 | <property name="text"> |
1434 | <string>Enable Auto DJ</string> |
1435 | </property> |
1436 | @@ -88,6 +172,12 @@ |
1437 | </item> |
1438 | <item> |
1439 | <widget class="QTableView" name="m_pTrackTablePlaceholder"> |
1440 | + <property name="sizePolicy"> |
1441 | + <sizepolicy hsizetype="Expanding" vsizetype="Expanding"> |
1442 | + <horstretch>0</horstretch> |
1443 | + <verstretch>0</verstretch> |
1444 | + </sizepolicy> |
1445 | + </property> |
1446 | <property name="showGrid"> |
1447 | <bool>true</bool> |
1448 | </property> |
1449 | @@ -95,6 +185,8 @@ |
1450 | </item> |
1451 | </layout> |
1452 | </widget> |
1453 | - <resources/> |
1454 | + <resources> |
1455 | + <include location="../res/mixxx.qrc"/> |
1456 | + </resources> |
1457 | <connections/> |
1458 | </ui> |
1459 | |
1460 | === modified file 'mixxx/src/library/autodjfeature.cpp' |
1461 | --- mixxx/src/library/autodjfeature.cpp 2011-10-12 17:29:43 +0000 |
1462 | +++ mixxx/src/library/autodjfeature.cpp 2012-03-01 22:38:18 +0000 |
1463 | @@ -23,6 +23,7 @@ |
1464 | m_pConfig(pConfig), |
1465 | m_pTrackCollection(pTrackCollection), |
1466 | m_playlistDao(pTrackCollection->getPlaylistDAO()) { |
1467 | + m_pAutoDJView = NULL; |
1468 | } |
1469 | |
1470 | AutoDJFeature::~AutoDJFeature() { |
1471 | @@ -36,19 +37,19 @@ |
1472 | return QIcon(":/images/library/ic_library_autodj.png"); |
1473 | } |
1474 | |
1475 | -void AutoDJFeature::bindWidget(WLibrarySidebar* sidebarWidget, |
1476 | +void AutoDJFeature::bindWidget(WLibrarySidebar* /*sidebarWidget*/, |
1477 | WLibrary* libraryWidget, |
1478 | MixxxKeyboard* keyboard) { |
1479 | |
1480 | - DlgAutoDJ* pAutoDJView = new DlgAutoDJ(libraryWidget, |
1481 | + m_pAutoDJView = new DlgAutoDJ(libraryWidget, |
1482 | m_pConfig, |
1483 | m_pTrackCollection, |
1484 | keyboard); |
1485 | - pAutoDJView->installEventFilter(keyboard); |
1486 | - libraryWidget->registerView(m_sAutoDJViewName, pAutoDJView); |
1487 | - connect(pAutoDJView, SIGNAL(loadTrack(TrackPointer)), |
1488 | + m_pAutoDJView->installEventFilter(keyboard); |
1489 | + libraryWidget->registerView(m_sAutoDJViewName, m_pAutoDJView); |
1490 | + connect(m_pAutoDJView, SIGNAL(loadTrack(TrackPointer)), |
1491 | this, SIGNAL(loadTrack(TrackPointer))); |
1492 | - connect(pAutoDJView, SIGNAL(loadTrackToPlayer(TrackPointer, QString)), |
1493 | + connect(m_pAutoDJView, SIGNAL(loadTrackToPlayer(TrackPointer, QString)), |
1494 | this, SIGNAL(loadTrackToPlayer(TrackPointer, QString))); |
1495 | } |
1496 | |
1497 | @@ -59,18 +60,17 @@ |
1498 | void AutoDJFeature::activate() { |
1499 | //qDebug() << "AutoDJFeature::activate()"; |
1500 | //emit(showTrackModel(m_pAutoDJTableModelProxy)); |
1501 | - emit(switchToView("Auto DJ")); |
1502 | -} |
1503 | - |
1504 | -void AutoDJFeature::activateChild(const QModelIndex& index) { |
1505 | - |
1506 | -} |
1507 | - |
1508 | -void AutoDJFeature::onRightClick(const QPoint& globalPos) { |
1509 | -} |
1510 | - |
1511 | -void AutoDJFeature::onRightClickChild(const QPoint& globalPos, |
1512 | - QModelIndex index) { |
1513 | + emit(switchToView(m_sAutoDJViewName)); |
1514 | +} |
1515 | + |
1516 | +void AutoDJFeature::activateChild(const QModelIndex& /*index*/) { |
1517 | +} |
1518 | + |
1519 | +void AutoDJFeature::onRightClick(const QPoint& /*globalPos*/) { |
1520 | +} |
1521 | + |
1522 | +void AutoDJFeature::onRightClickChild(const QPoint& /*globalPos*/, |
1523 | + QModelIndex /*index*/) { |
1524 | } |
1525 | |
1526 | bool AutoDJFeature::dropAccept(QUrl url) { |
1527 | @@ -98,12 +98,18 @@ |
1528 | } |
1529 | |
1530 | // TODO(XXX) No feedback on whether this worked. |
1531 | - int playlistId = m_playlistDao.getPlaylistIdFromName(AUTODJ_TABLE); |
1532 | - m_playlistDao.appendTrackToPlaylist(trackId, playlistId); |
1533 | + if( m_pAutoDJView ){ |
1534 | + m_pAutoDJView->appendTrack(trackId); |
1535 | + } |
1536 | + else{ |
1537 | + int playlistId = m_playlistDao.getPlaylistIdFromName(AUTODJ_TABLE); |
1538 | + m_playlistDao.appendTrackToPlaylist(trackId, playlistId); |
1539 | + } |
1540 | + |
1541 | return true; |
1542 | } |
1543 | |
1544 | -bool AutoDJFeature::dropAcceptChild(const QModelIndex& index, QUrl url) { |
1545 | +bool AutoDJFeature::dropAcceptChild(const QModelIndex& /*index*/, QUrl /*url*/) { |
1546 | return false; |
1547 | } |
1548 | |
1549 | @@ -112,10 +118,10 @@ |
1550 | return SoundSourceProxy::isFilenameSupported(file.fileName()); |
1551 | } |
1552 | |
1553 | -bool AutoDJFeature::dragMoveAcceptChild(const QModelIndex& index, |
1554 | - QUrl url) { |
1555 | +bool AutoDJFeature::dragMoveAcceptChild(const QModelIndex& /*index*/, |
1556 | + QUrl /*url*/) { |
1557 | return false; |
1558 | } |
1559 | -void AutoDJFeature::onLazyChildExpandation(const QModelIndex &index){ |
1560 | +void AutoDJFeature::onLazyChildExpandation(const QModelIndex& /*index*/){ |
1561 | //Nothing to do because the childmodel is not of lazy nature. |
1562 | } |
1563 | |
1564 | === modified file 'mixxx/src/library/autodjfeature.h' |
1565 | --- mixxx/src/library/autodjfeature.h 2011-03-10 13:37:21 +0000 |
1566 | +++ mixxx/src/library/autodjfeature.h 2012-03-01 22:38:18 +0000 |
1567 | @@ -11,6 +11,7 @@ |
1568 | #include "library/dao/playlistdao.h" |
1569 | #include "configobject.h" |
1570 | #include "treeitemmodel.h" |
1571 | +#include "dlgautodj.h" |
1572 | |
1573 | class PlaylistTableModel; |
1574 | class TrackCollection; |
1575 | @@ -50,6 +51,7 @@ |
1576 | PlaylistDAO& m_playlistDao; |
1577 | const static QString m_sAutoDJViewName; |
1578 | TreeItemModel m_childModel; |
1579 | + DlgAutoDJ* m_pAutoDJView; |
1580 | }; |
1581 | |
1582 | |
1583 | |
1584 | === modified file 'mixxx/src/library/browse/browsefeature.cpp' |
1585 | --- mixxx/src/library/browse/browsefeature.cpp 2012-01-07 08:36:51 +0000 |
1586 | +++ mixxx/src/library/browse/browsefeature.cpp 2012-03-01 22:38:18 +0000 |
1587 | @@ -119,19 +119,25 @@ |
1588 | } |
1589 | |
1590 | bool BrowseFeature::dropAccept(QUrl url) { |
1591 | - return false; |
1592 | + Q_UNUSED(url); |
1593 | + return false; |
1594 | } |
1595 | |
1596 | bool BrowseFeature::dropAcceptChild(const QModelIndex& index, QUrl url) { |
1597 | - return false; |
1598 | + Q_UNUSED(index); |
1599 | + Q_UNUSED(url); |
1600 | + return false; |
1601 | } |
1602 | |
1603 | bool BrowseFeature::dragMoveAccept(QUrl url) { |
1604 | - return false; |
1605 | + Q_UNUSED(url); |
1606 | + return false; |
1607 | } |
1608 | |
1609 | bool BrowseFeature::dragMoveAcceptChild(const QModelIndex& index, QUrl url) { |
1610 | - return false; |
1611 | + Q_UNUSED(index); |
1612 | + Q_UNUSED(url); |
1613 | + return false; |
1614 | } |
1615 | |
1616 | void BrowseFeature::activate() { |
1617 | @@ -150,10 +156,14 @@ |
1618 | } |
1619 | |
1620 | void BrowseFeature::onRightClick(const QPoint& globalPos) { |
1621 | + Q_UNUSED(globalPos); |
1622 | } |
1623 | |
1624 | void BrowseFeature::onRightClickChild(const QPoint& globalPos, QModelIndex index) { |
1625 | + Q_UNUSED(globalPos); |
1626 | + Q_UNUSED(index); |
1627 | } |
1628 | + |
1629 | /* |
1630 | * This is called whenever you double click or use the triangle symbol to expand |
1631 | * the subtree. The method will read the subfolders. |
1632 | |
1633 | === modified file 'mixxx/src/library/browse/browsetablemodel.cpp' |
1634 | --- mixxx/src/library/browse/browsetablemodel.cpp 2011-12-28 20:30:15 +0000 |
1635 | +++ mixxx/src/library/browse/browsetablemodel.cpp 2012-03-01 22:38:18 +0000 |
1636 | @@ -114,19 +114,19 @@ |
1637 | } |
1638 | |
1639 | int BrowseTableModel::getTrackId(const QModelIndex& index) const { |
1640 | - Q_UNUSED(index); |
1641 | - // We can't implement this as it stands. |
1642 | + Q_UNUSED(index); |
1643 | + // We can't implement this as it stands. |
1644 | return -1; |
1645 | } |
1646 | |
1647 | const QLinkedList<int> BrowseTableModel::getTrackRows(int trackId) const { |
1648 | - Q_UNUSED(trackId); |
1649 | - // We can't implement this as it stands. |
1650 | - return QLinkedList<int>(); |
1651 | + Q_UNUSED(trackId); |
1652 | + // We can't implement this as it stands. |
1653 | + return QLinkedList<int>(); |
1654 | } |
1655 | |
1656 | void BrowseTableModel::search(const QString& searchText) { |
1657 | - Q_UNUSED(searchText); |
1658 | + Q_UNUSED(searchText); |
1659 | } |
1660 | |
1661 | const QString BrowseTableModel::currentSearch() const { |
1662 | @@ -217,7 +217,7 @@ |
1663 | { |
1664 | Q_UNUSED(index); |
1665 | Q_UNUSED(location); |
1666 | - return false; |
1667 | + return false; |
1668 | } |
1669 | |
1670 | QMimeData* BrowseTableModel::mimeData(const QModelIndexList &indexes) const { |
1671 | @@ -320,7 +320,7 @@ |
1672 | { |
1673 | Q_UNUSED(role); |
1674 | |
1675 | - if(!index.isValid()) |
1676 | + if(!index.isValid()) |
1677 | return false; |
1678 | qDebug() << "BrowseTableModel::setData(" << index.data() << ")"; |
1679 | int row = index.row(); |
1680 | |
1681 | === modified file 'mixxx/src/library/dao/cratedao.h' |
1682 | --- mixxx/src/library/dao/cratedao.h 2011-10-21 00:42:23 +0000 |
1683 | +++ mixxx/src/library/dao/cratedao.h 2012-03-01 22:38:18 +0000 |
1684 | @@ -47,6 +47,8 @@ |
1685 | void changed(int crateId); |
1686 | void trackAdded(int crateId, int trackId); |
1687 | void trackRemoved(int crateId, int trackId); |
1688 | + void renamed(int crateId); |
1689 | + void lockChanged(int crateId); |
1690 | |
1691 | private: |
1692 | QSqlDatabase& m_database; |
1693 | |
1694 | === modified file 'mixxx/src/library/dao/playlistdao.cpp' |
1695 | --- mixxx/src/library/dao/playlistdao.cpp 2011-12-18 20:23:14 +0000 |
1696 | +++ mixxx/src/library/dao/playlistdao.cpp 2012-03-01 22:38:18 +0000 |
1697 | @@ -398,7 +398,7 @@ |
1698 | emit(changed(playlistId)); |
1699 | } |
1700 | |
1701 | -void PlaylistDAO::addToAutoDJQueue(int playlistId) { |
1702 | +void PlaylistDAO::addToAutoDJQueue(int playlistId, bool bTop) { |
1703 | //qDebug() << "Adding tracks from playlist " << playlistId << " to the Auto-DJ Queue"; |
1704 | |
1705 | // Query the PlaylistTracks database to locate tracks in the selected playlist |
1706 | @@ -413,7 +413,15 @@ |
1707 | // Get the ID of the Auto-DJ playlist |
1708 | int autoDJId = getPlaylistIdFromName(AUTODJ_TABLE); |
1709 | // Loop through the tracks, adding them to the Auto-DJ Queue |
1710 | - while(query.next()) { |
1711 | - appendTrackToPlaylist(query.value(0).toInt(), autoDJId); |
1712 | + |
1713 | + int i = 2; // Start at position 2 because position 1 was already loaded to the deck |
1714 | + |
1715 | + while (query.next()) { |
1716 | + if (bTop) { |
1717 | + insertTrackIntoPlaylist(query.value(0).toInt(), autoDJId, i++); |
1718 | + } |
1719 | + else { |
1720 | + appendTrackToPlaylist(query.value(0).toInt(), autoDJId); |
1721 | + } |
1722 | } |
1723 | } |
1724 | |
1725 | === modified file 'mixxx/src/library/dao/playlistdao.h' |
1726 | --- mixxx/src/library/dao/playlistdao.h 2011-10-21 00:42:23 +0000 |
1727 | +++ mixxx/src/library/dao/playlistdao.h 2012-03-01 22:38:18 +0000 |
1728 | @@ -53,13 +53,15 @@ |
1729 | /** Insert a track into a specific position in a playlist */ |
1730 | void insertTrackIntoPlaylist(int trackId, int playlistId, int position); |
1731 | /** Add a playlist to the Auto-DJ Queue */ |
1732 | - void addToAutoDJQueue(int playlistId); |
1733 | + void addToAutoDJQueue(int playlistId, bool bTop); |
1734 | signals: |
1735 | void added(int playlistId); |
1736 | void deleted(int playlistId); |
1737 | void changed(int playlistId); |
1738 | void trackAdded(int playlistId, int trackId, int position); |
1739 | void trackRemoved(int playlistId, int trackId, int position); |
1740 | + void renamed(int playlistId); |
1741 | + void lockChanged(int playlistId); |
1742 | private: |
1743 | QSqlDatabase& m_database; |
1744 | DISALLOW_COPY_AND_ASSIGN(PlaylistDAO); |
1745 | |
1746 | === modified file 'mixxx/src/library/playlistfeature.cpp' |
1747 | --- mixxx/src/library/playlistfeature.cpp 2011-11-30 05:27:44 +0000 |
1748 | +++ mixxx/src/library/playlistfeature.cpp 2012-03-01 22:38:18 +0000 |
1749 | @@ -35,10 +35,14 @@ |
1750 | connect(m_pCreatePlaylistAction, SIGNAL(triggered()), |
1751 | this, SLOT(slotCreatePlaylist())); |
1752 | |
1753 | - m_pAddToAutoDJAction = new QAction(tr("Add to Auto-DJ Queue"),this); |
1754 | + m_pAddToAutoDJAction = new QAction(tr("Add to Auto-DJ bottom"),this); |
1755 | connect(m_pAddToAutoDJAction, SIGNAL(triggered()), |
1756 | this, SLOT(slotAddToAutoDJ())); |
1757 | |
1758 | + m_pAddToAutoDJTopAction = new QAction(tr("Add to Auto-DJ top 2"),this); |
1759 | + connect(m_pAddToAutoDJTopAction, SIGNAL(triggered()), |
1760 | + this, SLOT(slotAddToAutoDJTop())); |
1761 | + |
1762 | m_pDeletePlaylistAction = new QAction(tr("Remove"),this); |
1763 | connect(m_pDeletePlaylistAction, SIGNAL(triggered()), |
1764 | this, SLOT(slotDeletePlaylist())); |
1765 | @@ -77,6 +81,7 @@ |
1766 | delete m_pDeletePlaylistAction; |
1767 | delete m_pImportPlaylistAction; |
1768 | delete m_pAddToAutoDJAction; |
1769 | + delete m_pAddToAutoDJTopAction; |
1770 | delete m_pRenamePlaylistAction; |
1771 | delete m_pLockPlaylistAction; |
1772 | } |
1773 | @@ -142,6 +147,7 @@ |
1774 | menu.addAction(m_pCreatePlaylistAction); |
1775 | menu.addSeparator(); |
1776 | menu.addAction(m_pAddToAutoDJAction); |
1777 | + menu.addAction(m_pAddToAutoDJTopAction); |
1778 | menu.addAction(m_pRenamePlaylistAction); |
1779 | menu.addAction(m_pDeletePlaylistAction); |
1780 | menu.addAction(m_pLockPlaylistAction); |
1781 | @@ -430,7 +436,7 @@ |
1782 | //Nothing to do because the childmodel is not of lazy nature. |
1783 | } |
1784 | |
1785 | -void PlaylistFeature::slotExportPlaylist(){ |
1786 | +void PlaylistFeature::slotExportPlaylist() { |
1787 | qDebug() << "Export playlist" << m_lastRightClickedIndex.data(); |
1788 | QString file_location = QFileDialog::getSaveFileName( |
1789 | NULL, |
1790 | @@ -481,12 +487,26 @@ |
1791 | |
1792 | void PlaylistFeature::slotAddToAutoDJ() { |
1793 | //qDebug() << "slotAddToAutoDJ() row:" << m_lastRightClickedIndex.data(); |
1794 | + addToAutoDJ(false); // Top = True |
1795 | +} |
1796 | + |
1797 | + |
1798 | +void PlaylistFeature::slotAddToAutoDJTop() { |
1799 | + //qDebug() << "slotAddToAutoDJTop() row:" << m_lastRightClickedIndex.data(); |
1800 | + addToAutoDJ(true); // bTop = True |
1801 | +} |
1802 | + |
1803 | + |
1804 | + |
1805 | +void PlaylistFeature::addToAutoDJ(bool bTop) { |
1806 | + //qDebug() << "slotAddToAutoDJ() row:" << m_lastRightClickedIndex.data(); |
1807 | |
1808 | if (m_lastRightClickedIndex.isValid()) { |
1809 | int playlistId = m_playlistDao.getPlaylistIdFromName( |
1810 | m_lastRightClickedIndex.data().toString()); |
1811 | if (playlistId >= 0) { |
1812 | - m_playlistDao.addToAutoDJQueue(playlistId); |
1813 | + // Insert this playlist |
1814 | + m_playlistDao.addToAutoDJQueue(playlistId, bTop); |
1815 | } |
1816 | } |
1817 | emit(featureUpdated()); |
1818 | |
1819 | === modified file 'mixxx/src/library/playlistfeature.h' |
1820 | --- mixxx/src/library/playlistfeature.h 2011-11-27 06:59:02 +0000 |
1821 | +++ mixxx/src/library/playlistfeature.h 2012-03-01 22:38:18 +0000 |
1822 | @@ -50,6 +50,7 @@ |
1823 | void slotCreatePlaylist(); |
1824 | void slotDeletePlaylist(); |
1825 | void slotAddToAutoDJ(); |
1826 | + void slotAddToAutoDJTop(); |
1827 | void slotRenamePlaylist(); |
1828 | void slotTogglePlaylistLock(); |
1829 | void slotImportPlaylist(); |
1830 | @@ -59,6 +60,7 @@ |
1831 | private: |
1832 | void constructChildModel(); |
1833 | void clearChildModel(); |
1834 | + void addToAutoDJ(bool bTop); |
1835 | |
1836 | TrackCollection* m_pTrackCollection; |
1837 | PlaylistTableModel* m_pPlaylistTableModel; |
1838 | @@ -67,6 +69,7 @@ |
1839 | QAction *m_pCreatePlaylistAction; |
1840 | QAction *m_pDeletePlaylistAction; |
1841 | QAction *m_pAddToAutoDJAction; |
1842 | + QAction *m_pAddToAutoDJTopAction; |
1843 | QAction *m_pRenamePlaylistAction; |
1844 | QAction *m_pLockPlaylistAction; |
1845 | QAction *m_pImportPlaylistAction; |
1846 | |
1847 | === modified file 'mixxx/src/library/playlisttablemodel.cpp' |
1848 | --- mixxx/src/library/playlisttablemodel.cpp 2011-12-18 20:23:14 +0000 |
1849 | +++ mixxx/src/library/playlisttablemodel.cpp 2012-03-01 22:38:18 +0000 |
1850 | @@ -94,6 +94,16 @@ |
1851 | return true; |
1852 | } |
1853 | |
1854 | +bool PlaylistTableModel::appendTrack(int trackId) { |
1855 | + if (trackId < 0) |
1856 | + return false; |
1857 | + |
1858 | + m_playlistDao.appendTrackToPlaylist(trackId, m_iPlaylistId); |
1859 | + |
1860 | + select(); //Repopulate the data model. |
1861 | + return true; |
1862 | +} |
1863 | + |
1864 | TrackPointer PlaylistTableModel::getTrack(const QModelIndex& index) const { |
1865 | //FIXME: use position instead of location for playlist tracks? |
1866 | |
1867 | @@ -326,6 +336,7 @@ |
1868 | } |
1869 | |
1870 | QItemDelegate* PlaylistTableModel::delegateForColumn(const int i) { |
1871 | + Q_UNUSED(i); |
1872 | return NULL; |
1873 | } |
1874 | |
1875 | |
1876 | === modified file 'mixxx/src/library/playlisttablemodel.h' |
1877 | --- mixxx/src/library/playlisttablemodel.h 2011-11-30 05:27:44 +0000 |
1878 | +++ mixxx/src/library/playlisttablemodel.h 2012-03-01 22:38:18 +0000 |
1879 | @@ -30,6 +30,7 @@ |
1880 | virtual void removeTrack(const QModelIndex& index); |
1881 | virtual void removeTracks(const QModelIndexList& indices); |
1882 | virtual bool addTrack(const QModelIndex& index, QString location); |
1883 | + virtual bool appendTrack(int trackId); |
1884 | virtual void moveTrack(const QModelIndex& sourceIndex, const QModelIndex& destIndex); |
1885 | virtual void shuffleTracks(const QModelIndex& currentIndex); |
1886 | |
1887 | |
1888 | === modified file 'mixxx/src/widget/wtracktableview.cpp' |
1889 | --- mixxx/src/widget/wtracktableview.cpp 2011-12-14 17:22:49 +0000 |
1890 | +++ mixxx/src/widget/wtracktableview.cpp 2012-03-01 22:38:18 +0000 |
1891 | @@ -82,6 +82,7 @@ |
1892 | |
1893 | delete m_pReloadMetadataAct; |
1894 | delete m_pAutoDJAct; |
1895 | + delete m_pAutoDJTopAct; |
1896 | delete m_pRemoveAct; |
1897 | delete m_pPropertiesAct; |
1898 | delete m_pMenu; |
1899 | @@ -256,9 +257,12 @@ |
1900 | m_pPropertiesAct = new QAction(tr("Properties..."), this); |
1901 | connect(m_pPropertiesAct, SIGNAL(triggered()), this, SLOT(slotShowTrackInfo())); |
1902 | |
1903 | - m_pAutoDJAct = new QAction(tr("Add to Auto DJ Queue"),this); |
1904 | + m_pAutoDJAct = new QAction(tr("Add to Auto-DJ bottom"),this); |
1905 | connect(m_pAutoDJAct, SIGNAL(triggered()), this, SLOT(slotSendToAutoDJ())); |
1906 | |
1907 | + m_pAutoDJTopAct = new QAction(tr("Add to Auto-DJ top 2"),this); |
1908 | + connect(m_pAutoDJTopAct, SIGNAL(triggered()), this, SLOT(slotSendToAutoDJTop())); |
1909 | + |
1910 | m_pReloadMetadataAct = new QAction(tr("Reload Track Metadata"), this); |
1911 | connect(m_pReloadMetadataAct, SIGNAL(triggered()), this, SLOT(slotReloadTrackMetadata())); |
1912 | } |
1913 | @@ -356,6 +360,7 @@ |
1914 | |
1915 | if (modelHasCapabilities(TrackModel::TRACKMODELCAPS_ADDTOAUTODJ)) { |
1916 | m_pMenu->addAction(m_pAutoDJAct); |
1917 | + m_pMenu->addAction(m_pAutoDJTopAct); |
1918 | m_pMenu->addSeparator(); |
1919 | } |
1920 | |
1921 | @@ -800,6 +805,15 @@ |
1922 | } |
1923 | |
1924 | void WTrackTableView::slotSendToAutoDJ() { |
1925 | + // append to auto DJ |
1926 | + sendToAutoDJ(false); // bTop = false |
1927 | +} |
1928 | + |
1929 | +void WTrackTableView::slotSendToAutoDJTop() { |
1930 | + sendToAutoDJ(true); // bTop = true |
1931 | +} |
1932 | + |
1933 | +void WTrackTableView::sendToAutoDJ(bool bTop) { |
1934 | if (!modelHasCapabilities(TrackModel::TRACKMODELCAPS_ADDTOAUTODJ)) { |
1935 | return; |
1936 | } |
1937 | @@ -819,7 +833,13 @@ |
1938 | (pTrack = trackModel->getTrack(index))) { |
1939 | int iTrackId = pTrack->getId(); |
1940 | if (iTrackId != -1) { |
1941 | - playlistDao.appendTrackToPlaylist(iTrackId, iAutoDJPlaylistId); |
1942 | + if (bTop) { |
1943 | + // Load track to position two because position one is already loaded to the player |
1944 | + playlistDao.insertTrackIntoPlaylist(iTrackId, iAutoDJPlaylistId, 2); |
1945 | + } |
1946 | + else { |
1947 | + playlistDao.appendTrackToPlaylist(iTrackId, iAutoDJPlaylistId); |
1948 | + } |
1949 | } |
1950 | } |
1951 | } |
1952 | |
1953 | === modified file 'mixxx/src/widget/wtracktableview.h' |
1954 | --- mixxx/src/widget/wtracktableview.h 2011-10-14 03:58:14 +0000 |
1955 | +++ mixxx/src/widget/wtracktableview.h 2012-03-01 22:38:18 +0000 |
1956 | @@ -46,6 +46,7 @@ |
1957 | void slotNextTrackInfo(); |
1958 | void slotPrevTrackInfo(); |
1959 | void slotSendToAutoDJ(); |
1960 | + void slotSendToAutoDJTop(); |
1961 | void slotReloadTrackMetadata(); |
1962 | void addSelectionToPlaylist(int iPlaylistId); |
1963 | void addSelectionToCrate(int iCrateId); |
1964 | @@ -53,6 +54,7 @@ |
1965 | void doSortByColumn(int headerSection); |
1966 | |
1967 | private: |
1968 | + void sendToAutoDJ(bool bTop); |
1969 | void showTrackInfo(QModelIndex index); |
1970 | void createActions(); |
1971 | void dragMoveEvent(QDragMoveEvent * event); |
1972 | @@ -89,6 +91,7 @@ |
1973 | |
1974 | // Send to Auto-DJ Action |
1975 | QAction *m_pAutoDJAct; |
1976 | + QAction *m_pAutoDJTopAct; |
1977 | |
1978 | // Remove from table |
1979 | QAction *m_pRemoveAct; |
Tested r2801 of your autodj branch
* SKIP NEXT button
Does not work as expected. Play-count of the next track in queue is raised by one, but track is not skipped.
* CUSTOM TRANSITION TIME stepper
Changes to the transition time are not instantly effective for the transition from the currently playing track to the next queued track (same for the FADE NOW button). One would expect it works instantly when changed. Nonetheless it works for the next transition.
Furthermore i think the preference dialog is not an optimal place for the stepper. It should go from the preferences directly to the AutoDJ tab in the library widget. This would improve usability and allow easy in-session changes.