├── LICENSE ├── README.md ├── aspect_ratio_crop.html ├── css └── styles.css ├── custom_artwork.html ├── custom_titles.html ├── default_skin.html ├── external_subtitle.html ├── images ├── close_but.png ├── webchimera_logo.png └── webchimera_logo_small.png ├── index.html ├── internal_subtitles.html ├── keypress_events.html ├── m3u_playlist.html ├── mouse_events.html ├── multiscreen.html ├── player ├── core │ ├── Buttons.qml │ ├── Functions.qml │ ├── Hotkeys.qml │ ├── Settings.qml │ └── qmldir ├── images │ ├── cursor-openhand.png │ └── dragger.png ├── themes │ └── sleek │ │ ├── UIsettings.qml │ │ ├── components │ │ ├── AddMRL.qml │ │ ├── ArtworkLayer.qml │ │ ├── BigPauseIcon.qml │ │ ├── BigPlayIcon.qml │ │ ├── ContextMenu.qml │ │ ├── DigitalZoom.qml │ │ ├── Fonts.qml │ │ ├── Menu.qml │ │ ├── MenuClose.qml │ │ ├── MenuContent.qml │ │ ├── MenuHeader.qml │ │ ├── MenuScroll.qml │ │ ├── MouseSurface.qml │ │ ├── PIP.qml │ │ ├── PlaylistMenuItems.qml │ │ ├── ProgressBar.qml │ │ ├── ReplaceMRL.qml │ │ ├── SplashScreen.qml │ │ ├── SubtitleMenuItems.qml │ │ ├── SubtitleText.qml │ │ ├── TimeBubble.qml │ │ ├── TitleBar.qml │ │ ├── Toolbar.qml │ │ ├── ToolbarBackground.qml │ │ ├── ToolbarBorder.qml │ │ ├── ToolbarButton.qml │ │ ├── ToolbarLeft.qml │ │ ├── ToolbarRight.qml │ │ ├── ToolbarTimeLength.qml │ │ ├── TopCenterText.qml │ │ ├── TopRightText.qml │ │ ├── VideoLayer.qml │ │ ├── VolumeHeat.qml │ │ ├── VolumeHeatColors.qml │ │ ├── VolumeHeatGraphics.qml │ │ ├── VolumeHeatMouse.qml │ │ ├── VolumeHeatScale.qml │ │ └── qmldir │ │ ├── fonts │ │ └── glyphicons.ttf │ │ ├── main.qml │ │ └── qmldir └── webchimera.js └── playlist.html /LICENSE: -------------------------------------------------------------------------------- 1 | GNU LESSER GENERAL PUBLIC LICENSE 2 | Version 2.1, February 1999 3 | 4 | Copyright (C) 1991, 1999 Free Software Foundation, Inc. 5 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 6 | Everyone is permitted to copy and distribute verbatim copies 7 | of this license document, but changing it is not allowed. 8 | 9 | (This is the first released version of the Lesser GPL. It also counts 10 | as the successor of the GNU Library Public License, version 2, hence 11 | the version number 2.1.) 12 | 13 | Preamble 14 | 15 | The licenses for most software are designed to take away your 16 | freedom to share and change it. By contrast, the GNU General Public 17 | Licenses are intended to guarantee your freedom to share and change 18 | free software--to make sure the software is free for all its users. 19 | 20 | This license, the Lesser General Public License, applies to some 21 | specially designated software packages--typically libraries--of the 22 | Free Software Foundation and other authors who decide to use it. You 23 | can use it too, but we suggest you first think carefully about whether 24 | this license or the ordinary General Public License is the better 25 | strategy to use in any particular case, based on the explanations below. 26 | 27 | When we speak of free software, we are referring to freedom of use, 28 | not price. Our General Public Licenses are designed to make sure that 29 | you have the freedom to distribute copies of free software (and charge 30 | for this service if you wish); that you receive source code or can get 31 | it if you want it; that you can change the software and use pieces of 32 | it in new free programs; and that you are informed that you can do 33 | these things. 34 | 35 | To protect your rights, we need to make restrictions that forbid 36 | distributors to deny you these rights or to ask you to surrender these 37 | rights. These restrictions translate to certain responsibilities for 38 | you if you distribute copies of the library or if you modify it. 39 | 40 | For example, if you distribute copies of the library, whether gratis 41 | or for a fee, you must give the recipients all the rights that we gave 42 | you. You must make sure that they, too, receive or can get the source 43 | code. If you link other code with the library, you must provide 44 | complete object files to the recipients, so that they can relink them 45 | with the library after making changes to the library and recompiling 46 | it. And you must show them these terms so they know their rights. 47 | 48 | We protect your rights with a two-step method: (1) we copyright the 49 | library, and (2) we offer you this license, which gives you legal 50 | permission to copy, distribute and/or modify the library. 51 | 52 | To protect each distributor, we want to make it very clear that 53 | there is no warranty for the free library. Also, if the library is 54 | modified by someone else and passed on, the recipients should know 55 | that what they have is not the original version, so that the original 56 | author's reputation will not be affected by problems that might be 57 | introduced by others. 58 | 59 | Finally, software patents pose a constant threat to the existence of 60 | any free program. We wish to make sure that a company cannot 61 | effectively restrict the users of a free program by obtaining a 62 | restrictive license from a patent holder. Therefore, we insist that 63 | any patent license obtained for a version of the library must be 64 | consistent with the full freedom of use specified in this license. 65 | 66 | Most GNU software, including some libraries, is covered by the 67 | ordinary GNU General Public License. This license, the GNU Lesser 68 | General Public License, applies to certain designated libraries, and 69 | is quite different from the ordinary General Public License. We use 70 | this license for certain libraries in order to permit linking those 71 | libraries into non-free programs. 72 | 73 | When a program is linked with a library, whether statically or using 74 | a shared library, the combination of the two is legally speaking a 75 | combined work, a derivative of the original library. The ordinary 76 | General Public License therefore permits such linking only if the 77 | entire combination fits its criteria of freedom. The Lesser General 78 | Public License permits more lax criteria for linking other code with 79 | the library. 80 | 81 | We call this license the "Lesser" General Public License because it 82 | does Less to protect the user's freedom than the ordinary General 83 | Public License. It also provides other free software developers Less 84 | of an advantage over competing non-free programs. These disadvantages 85 | are the reason we use the ordinary General Public License for many 86 | libraries. However, the Lesser license provides advantages in certain 87 | special circumstances. 88 | 89 | For example, on rare occasions, there may be a special need to 90 | encourage the widest possible use of a certain library, so that it becomes 91 | a de-facto standard. To achieve this, non-free programs must be 92 | allowed to use the library. A more frequent case is that a free 93 | library does the same job as widely used non-free libraries. In this 94 | case, there is little to gain by limiting the free library to free 95 | software only, so we use the Lesser General Public License. 96 | 97 | In other cases, permission to use a particular library in non-free 98 | programs enables a greater number of people to use a large body of 99 | free software. For example, permission to use the GNU C Library in 100 | non-free programs enables many more people to use the whole GNU 101 | operating system, as well as its variant, the GNU/Linux operating 102 | system. 103 | 104 | Although the Lesser General Public License is Less protective of the 105 | users' freedom, it does ensure that the user of a program that is 106 | linked with the Library has the freedom and the wherewithal to run 107 | that program using a modified version of the Library. 108 | 109 | The precise terms and conditions for copying, distribution and 110 | modification follow. Pay close attention to the difference between a 111 | "work based on the library" and a "work that uses the library". The 112 | former contains code derived from the library, whereas the latter must 113 | be combined with the library in order to run. 114 | 115 | GNU LESSER GENERAL PUBLIC LICENSE 116 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 117 | 118 | 0. This License Agreement applies to any software library or other 119 | program which contains a notice placed by the copyright holder or 120 | other authorized party saying it may be distributed under the terms of 121 | this Lesser General Public License (also called "this License"). 122 | Each licensee is addressed as "you". 123 | 124 | A "library" means a collection of software functions and/or data 125 | prepared so as to be conveniently linked with application programs 126 | (which use some of those functions and data) to form executables. 127 | 128 | The "Library", below, refers to any such software library or work 129 | which has been distributed under these terms. A "work based on the 130 | Library" means either the Library or any derivative work under 131 | copyright law: that is to say, a work containing the Library or a 132 | portion of it, either verbatim or with modifications and/or translated 133 | straightforwardly into another language. (Hereinafter, translation is 134 | included without limitation in the term "modification".) 135 | 136 | "Source code" for a work means the preferred form of the work for 137 | making modifications to it. For a library, complete source code means 138 | all the source code for all modules it contains, plus any associated 139 | interface definition files, plus the scripts used to control compilation 140 | and installation of the library. 141 | 142 | Activities other than copying, distribution and modification are not 143 | covered by this License; they are outside its scope. The act of 144 | running a program using the Library is not restricted, and output from 145 | such a program is covered only if its contents constitute a work based 146 | on the Library (independent of the use of the Library in a tool for 147 | writing it). Whether that is true depends on what the Library does 148 | and what the program that uses the Library does. 149 | 150 | 1. You may copy and distribute verbatim copies of the Library's 151 | complete source code as you receive it, in any medium, provided that 152 | you conspicuously and appropriately publish on each copy an 153 | appropriate copyright notice and disclaimer of warranty; keep intact 154 | all the notices that refer to this License and to the absence of any 155 | warranty; and distribute a copy of this License along with the 156 | Library. 157 | 158 | You may charge a fee for the physical act of transferring a copy, 159 | and you may at your option offer warranty protection in exchange for a 160 | fee. 161 | 162 | 2. You may modify your copy or copies of the Library or any portion 163 | of it, thus forming a work based on the Library, and copy and 164 | distribute such modifications or work under the terms of Section 1 165 | above, provided that you also meet all of these conditions: 166 | 167 | a) The modified work must itself be a software library. 168 | 169 | b) You must cause the files modified to carry prominent notices 170 | stating that you changed the files and the date of any change. 171 | 172 | c) You must cause the whole of the work to be licensed at no 173 | charge to all third parties under the terms of this License. 174 | 175 | d) If a facility in the modified Library refers to a function or a 176 | table of data to be supplied by an application program that uses 177 | the facility, other than as an argument passed when the facility 178 | is invoked, then you must make a good faith effort to ensure that, 179 | in the event an application does not supply such function or 180 | table, the facility still operates, and performs whatever part of 181 | its purpose remains meaningful. 182 | 183 | (For example, a function in a library to compute square roots has 184 | a purpose that is entirely well-defined independent of the 185 | application. Therefore, Subsection 2d requires that any 186 | application-supplied function or table used by this function must 187 | be optional: if the application does not supply it, the square 188 | root function must still compute square roots.) 189 | 190 | These requirements apply to the modified work as a whole. If 191 | identifiable sections of that work are not derived from the Library, 192 | and can be reasonably considered independent and separate works in 193 | themselves, then this License, and its terms, do not apply to those 194 | sections when you distribute them as separate works. But when you 195 | distribute the same sections as part of a whole which is a work based 196 | on the Library, the distribution of the whole must be on the terms of 197 | this License, whose permissions for other licensees extend to the 198 | entire whole, and thus to each and every part regardless of who wrote 199 | it. 200 | 201 | Thus, it is not the intent of this section to claim rights or contest 202 | your rights to work written entirely by you; rather, the intent is to 203 | exercise the right to control the distribution of derivative or 204 | collective works based on the Library. 205 | 206 | In addition, mere aggregation of another work not based on the Library 207 | with the Library (or with a work based on the Library) on a volume of 208 | a storage or distribution medium does not bring the other work under 209 | the scope of this License. 210 | 211 | 3. You may opt to apply the terms of the ordinary GNU General Public 212 | License instead of this License to a given copy of the Library. To do 213 | this, you must alter all the notices that refer to this License, so 214 | that they refer to the ordinary GNU General Public License, version 2, 215 | instead of to this License. (If a newer version than version 2 of the 216 | ordinary GNU General Public License has appeared, then you can specify 217 | that version instead if you wish.) Do not make any other change in 218 | these notices. 219 | 220 | Once this change is made in a given copy, it is irreversible for 221 | that copy, so the ordinary GNU General Public License applies to all 222 | subsequent copies and derivative works made from that copy. 223 | 224 | This option is useful when you wish to copy part of the code of 225 | the Library into a program that is not a library. 226 | 227 | 4. You may copy and distribute the Library (or a portion or 228 | derivative of it, under Section 2) in object code or executable form 229 | under the terms of Sections 1 and 2 above provided that you accompany 230 | it with the complete corresponding machine-readable source code, which 231 | must be distributed under the terms of Sections 1 and 2 above on a 232 | medium customarily used for software interchange. 233 | 234 | If distribution of object code is made by offering access to copy 235 | from a designated place, then offering equivalent access to copy the 236 | source code from the same place satisfies the requirement to 237 | distribute the source code, even though third parties are not 238 | compelled to copy the source along with the object code. 239 | 240 | 5. A program that contains no derivative of any portion of the 241 | Library, but is designed to work with the Library by being compiled or 242 | linked with it, is called a "work that uses the Library". Such a 243 | work, in isolation, is not a derivative work of the Library, and 244 | therefore falls outside the scope of this License. 245 | 246 | However, linking a "work that uses the Library" with the Library 247 | creates an executable that is a derivative of the Library (because it 248 | contains portions of the Library), rather than a "work that uses the 249 | library". The executable is therefore covered by this License. 250 | Section 6 states terms for distribution of such executables. 251 | 252 | When a "work that uses the Library" uses material from a header file 253 | that is part of the Library, the object code for the work may be a 254 | derivative work of the Library even though the source code is not. 255 | Whether this is true is especially significant if the work can be 256 | linked without the Library, or if the work is itself a library. The 257 | threshold for this to be true is not precisely defined by law. 258 | 259 | If such an object file uses only numerical parameters, data 260 | structure layouts and accessors, and small macros and small inline 261 | functions (ten lines or less in length), then the use of the object 262 | file is unrestricted, regardless of whether it is legally a derivative 263 | work. (Executables containing this object code plus portions of the 264 | Library will still fall under Section 6.) 265 | 266 | Otherwise, if the work is a derivative of the Library, you may 267 | distribute the object code for the work under the terms of Section 6. 268 | Any executables containing that work also fall under Section 6, 269 | whether or not they are linked directly with the Library itself. 270 | 271 | 6. As an exception to the Sections above, you may also combine or 272 | link a "work that uses the Library" with the Library to produce a 273 | work containing portions of the Library, and distribute that work 274 | under terms of your choice, provided that the terms permit 275 | modification of the work for the customer's own use and reverse 276 | engineering for debugging such modifications. 277 | 278 | You must give prominent notice with each copy of the work that the 279 | Library is used in it and that the Library and its use are covered by 280 | this License. You must supply a copy of this License. If the work 281 | during execution displays copyright notices, you must include the 282 | copyright notice for the Library among them, as well as a reference 283 | directing the user to the copy of this License. Also, you must do one 284 | of these things: 285 | 286 | a) Accompany the work with the complete corresponding 287 | machine-readable source code for the Library including whatever 288 | changes were used in the work (which must be distributed under 289 | Sections 1 and 2 above); and, if the work is an executable linked 290 | with the Library, with the complete machine-readable "work that 291 | uses the Library", as object code and/or source code, so that the 292 | user can modify the Library and then relink to produce a modified 293 | executable containing the modified Library. (It is understood 294 | that the user who changes the contents of definitions files in the 295 | Library will not necessarily be able to recompile the application 296 | to use the modified definitions.) 297 | 298 | b) Use a suitable shared library mechanism for linking with the 299 | Library. A suitable mechanism is one that (1) uses at run time a 300 | copy of the library already present on the user's computer system, 301 | rather than copying library functions into the executable, and (2) 302 | will operate properly with a modified version of the library, if 303 | the user installs one, as long as the modified version is 304 | interface-compatible with the version that the work was made with. 305 | 306 | c) Accompany the work with a written offer, valid for at 307 | least three years, to give the same user the materials 308 | specified in Subsection 6a, above, for a charge no more 309 | than the cost of performing this distribution. 310 | 311 | d) If distribution of the work is made by offering access to copy 312 | from a designated place, offer equivalent access to copy the above 313 | specified materials from the same place. 314 | 315 | e) Verify that the user has already received a copy of these 316 | materials or that you have already sent this user a copy. 317 | 318 | For an executable, the required form of the "work that uses the 319 | Library" must include any data and utility programs needed for 320 | reproducing the executable from it. However, as a special exception, 321 | the materials to be distributed need not include anything that is 322 | normally distributed (in either source or binary form) with the major 323 | components (compiler, kernel, and so on) of the operating system on 324 | which the executable runs, unless that component itself accompanies 325 | the executable. 326 | 327 | It may happen that this requirement contradicts the license 328 | restrictions of other proprietary libraries that do not normally 329 | accompany the operating system. Such a contradiction means you cannot 330 | use both them and the Library together in an executable that you 331 | distribute. 332 | 333 | 7. You may place library facilities that are a work based on the 334 | Library side-by-side in a single library together with other library 335 | facilities not covered by this License, and distribute such a combined 336 | library, provided that the separate distribution of the work based on 337 | the Library and of the other library facilities is otherwise 338 | permitted, and provided that you do these two things: 339 | 340 | a) Accompany the combined library with a copy of the same work 341 | based on the Library, uncombined with any other library 342 | facilities. This must be distributed under the terms of the 343 | Sections above. 344 | 345 | b) Give prominent notice with the combined library of the fact 346 | that part of it is a work based on the Library, and explaining 347 | where to find the accompanying uncombined form of the same work. 348 | 349 | 8. You may not copy, modify, sublicense, link with, or distribute 350 | the Library except as expressly provided under this License. Any 351 | attempt otherwise to copy, modify, sublicense, link with, or 352 | distribute the Library is void, and will automatically terminate your 353 | rights under this License. However, parties who have received copies, 354 | or rights, from you under this License will not have their licenses 355 | terminated so long as such parties remain in full compliance. 356 | 357 | 9. You are not required to accept this License, since you have not 358 | signed it. However, nothing else grants you permission to modify or 359 | distribute the Library or its derivative works. These actions are 360 | prohibited by law if you do not accept this License. Therefore, by 361 | modifying or distributing the Library (or any work based on the 362 | Library), you indicate your acceptance of this License to do so, and 363 | all its terms and conditions for copying, distributing or modifying 364 | the Library or works based on it. 365 | 366 | 10. Each time you redistribute the Library (or any work based on the 367 | Library), the recipient automatically receives a license from the 368 | original licensor to copy, distribute, link with or modify the Library 369 | subject to these terms and conditions. You may not impose any further 370 | restrictions on the recipients' exercise of the rights granted herein. 371 | You are not responsible for enforcing compliance by third parties with 372 | this License. 373 | 374 | 11. If, as a consequence of a court judgment or allegation of patent 375 | infringement or for any other reason (not limited to patent issues), 376 | conditions are imposed on you (whether by court order, agreement or 377 | otherwise) that contradict the conditions of this License, they do not 378 | excuse you from the conditions of this License. If you cannot 379 | distribute so as to satisfy simultaneously your obligations under this 380 | License and any other pertinent obligations, then as a consequence you 381 | may not distribute the Library at all. For example, if a patent 382 | license would not permit royalty-free redistribution of the Library by 383 | all those who receive copies directly or indirectly through you, then 384 | the only way you could satisfy both it and this License would be to 385 | refrain entirely from distribution of the Library. 386 | 387 | If any portion of this section is held invalid or unenforceable under any 388 | particular circumstance, the balance of the section is intended to apply, 389 | and the section as a whole is intended to apply in other circumstances. 390 | 391 | It is not the purpose of this section to induce you to infringe any 392 | patents or other property right claims or to contest validity of any 393 | such claims; this section has the sole purpose of protecting the 394 | integrity of the free software distribution system which is 395 | implemented by public license practices. Many people have made 396 | generous contributions to the wide range of software distributed 397 | through that system in reliance on consistent application of that 398 | system; it is up to the author/donor to decide if he or she is willing 399 | to distribute software through any other system and a licensee cannot 400 | impose that choice. 401 | 402 | This section is intended to make thoroughly clear what is believed to 403 | be a consequence of the rest of this License. 404 | 405 | 12. If the distribution and/or use of the Library is restricted in 406 | certain countries either by patents or by copyrighted interfaces, the 407 | original copyright holder who places the Library under this License may add 408 | an explicit geographical distribution limitation excluding those countries, 409 | so that distribution is permitted only in or among countries not thus 410 | excluded. In such case, this License incorporates the limitation as if 411 | written in the body of this License. 412 | 413 | 13. The Free Software Foundation may publish revised and/or new 414 | versions of the Lesser General Public License from time to time. 415 | Such new versions will be similar in spirit to the present version, 416 | but may differ in detail to address new problems or concerns. 417 | 418 | Each version is given a distinguishing version number. If the Library 419 | specifies a version number of this License which applies to it and 420 | "any later version", you have the option of following the terms and 421 | conditions either of that version or of any later version published by 422 | the Free Software Foundation. If the Library does not specify a 423 | license version number, you may choose any version ever published by 424 | the Free Software Foundation. 425 | 426 | 14. If you wish to incorporate parts of the Library into other free 427 | programs whose distribution conditions are incompatible with these, 428 | write to the author to ask for permission. For software which is 429 | copyrighted by the Free Software Foundation, write to the Free 430 | Software Foundation; we sometimes make exceptions for this. Our 431 | decision will be guided by the two goals of preserving the free status 432 | of all derivatives of our free software and of promoting the sharing 433 | and reuse of software generally. 434 | 435 | NO WARRANTY 436 | 437 | 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO 438 | WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. 439 | EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR 440 | OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY 441 | KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE 442 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 443 | PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE 444 | LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME 445 | THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 446 | 447 | 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN 448 | WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY 449 | AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU 450 | FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR 451 | CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE 452 | LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING 453 | RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A 454 | FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF 455 | SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH 456 | DAMAGES. 457 | 458 | END OF TERMS AND CONDITIONS 459 | 460 | How to Apply These Terms to Your New Libraries 461 | 462 | If you develop a new library, and you want it to be of the greatest 463 | possible use to the public, we recommend making it free software that 464 | everyone can redistribute and change. You can do so by permitting 465 | redistribution under these terms (or, alternatively, under the terms of the 466 | ordinary General Public License). 467 | 468 | To apply these terms, attach the following notices to the library. It is 469 | safest to attach them to the start of each source file to most effectively 470 | convey the exclusion of warranty; and each file should have at least the 471 | "copyright" line and a pointer to where the full notice is found. 472 | 473 | {description} 474 | Copyright (C) {year} {fullname} 475 | 476 | This library is free software; you can redistribute it and/or 477 | modify it under the terms of the GNU Lesser General Public 478 | License as published by the Free Software Foundation; either 479 | version 2.1 of the License, or (at your option) any later version. 480 | 481 | This library is distributed in the hope that it will be useful, 482 | but WITHOUT ANY WARRANTY; without even the implied warranty of 483 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 484 | Lesser General Public License for more details. 485 | 486 | You should have received a copy of the GNU Lesser General Public 487 | License along with this library; if not, write to the Free Software 488 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 489 | USA 490 | 491 | Also add information on how to contact you by electronic and paper mail. 492 | 493 | You should also get your employer (if you work as a programmer) or your 494 | school, if any, to sign a "copyright disclaimer" for the library, if 495 | necessary. Here is a sample; alter the names: 496 | 497 | Yoyodyne, Inc., hereby disclaims all copyright interest in the 498 | library `Frob' (a library for tweaking knobs) written by James Random 499 | Hacker. 500 | 501 | {signature of Ty Coon}, 1 April 1990 502 | Ty Coon, President of Vice 503 | 504 | That's all there is to it! 505 | 506 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | WebChimera NPAPI Player v1.20 2 | ============== 3 | 4 | This project is now deprecated as WebChimera NPAPI/ActiveX Plugin is no longer supported by any browser since December 2015. 5 | 6 | An Open Source WebChimera Player 7 | 8 | To use WebChimera Player you need to install the lattest version of WebChimera (Github) on your PC. 9 | 10 | WebChimera is a VLC Web Plugin based on FireBreath that offers the possibility of using QT QML to build complex User Interfaces for the Web Player. 11 | 12 | Make sure to check out the JS API and QML API 13 | 14 | Features 15 | ============== 16 | - External HTTP Subtitle Support (supports SUB, SRT and WebVTT subtitle formats) 17 | - Playlist Support (JavaScript or M3U File) 18 | - Custom Video Titles and Artwork Support 19 | - Hotkeys and Mouse Actions 20 | - Skinning and Themes 21 | - Internal Video Subtitle and Audio Track Support 22 | - Picture in Picture 23 | - Digital Interactive Zoom 24 | - Advanced Playlist Menu (debugging, drag and drop, scroll with mouse, skip items) 25 | - Key Press and Mouse Tracking Events 26 | - Context Menu with: Audio Tracks, Aspect Ratio, Crop and Zoom. 27 | - Supported Video Formats: AVI, MP4, MKV, MPEG, Flash and more 28 | - Supported Streams: RTMP, RTSP, HTTP, FTP, File, YouTube and more 29 | - Supported Audio Formats: MP3, AAC, MPEG3, FLAC, WAV and more 30 | -------------------------------------------------------------------------------- /aspect_ratio_crop.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Aspect Ratio and Crop Demo - WebChimera Player 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 |

Aspect Ratio and Crop Demo

18 | 19 |
20 | 21 | 22 | 42 | 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /css/styles.css: -------------------------------------------------------------------------------- 1 | body { background-color: #424242; color: #eaeaea } 2 | 3 | #logo { margin-bottom: 2px; margin-top: 8px } 4 | #logo_small { margin-top: 45px; margin-right: 10px } 5 | h1 { margin: 0; font-size: 39px; display: inline } 6 | h2 { margin: 0; font-size: 22px; display: inline } 7 | #main_menu { width: 100%; margin-top: 45px; margin-bottom: 45px; text-align: center; font-family: Helvetica, Arial, sans-serif; font-size: 39px; font-weight: bold; text-shadow: 0px 0px 17px rgba(0, 0, 0, 0.8) } 8 | #main_content { font-size: 16px; font-weight: normal; text-shadow: 0px 0px 7px rgba(0, 0, 0, 0.8) } 9 | .github_wrap { font-weight: bold; font-size: 22px; } 10 | a.github { color: #3CA0CB; font-weight: bold; font-size: 22px; text-decoration: none } 11 | a.github:hover { text-decoration: underline } 12 | a.blue_small { color: #3CA0CB } 13 | a.blue_small:hover { text-decoration: none } 14 | a.blue_big { color: #3CA0CB; font-weight: bold; font-size: 19px } 15 | a.blue_big:hover { text-decoration: none } 16 | h1.main-title { font-size: 33px } 17 | h2.main-title { font-size: 26px } 18 | span.main-text { font-weight: bold; font-size: 19px } 19 | h2.footer-title { font-size: 21px; text-shadow: 0px 0px 7px rgba(0, 0, 0, 0.8); display: block; margin-top: 12px } 20 | span.footer-text { font-weight: bold; font-size: 16px } 21 | a.footer-links { font-size: 16px } 22 | 23 | #close_wrapper { width: 100%; height: 450px; width: 738px; position: fixed; top: 50%; left: 50%; margin-top: -294px; margin-left: -369px; text-align: center; font-family: Helvetica, Arial, sans-serif; font-size: 39px; font-weight: bold; text-shadow: 0px 0px 17px rgba(0, 0, 0, 0.8); z-index: 1000 } 24 | #close_button { display: inline-block; float: right } 25 | #page_title { width: 100%; height: 450px; position: fixed; top: 50%; margin-top: -300px; text-align: center; font-family: Helvetica, Arial, sans-serif; font-size: 39px; font-weight: bold; text-shadow: 0px 0px 17px rgba(0, 0, 0, 0.8); z-index: 999 } 26 | #page_desc { font-size: 16px; font-weight: normal; position: relative; top: -19px; color: #a8a8a8 } 27 | #player_wrapper { width: 738px; height: 450px; position: fixed; top: 50%; left: 50%; margin-top: -225px; margin-left: -369px; -webkit-box-shadow: 0px 0px 54px 12px rgba(0,0,0,0.7); -moz-box-shadow: 0px 0px 54px 12px rgba(0,0,0,0.7); box-shadow: 0px 0px 54px 12px rgba(0,0,0,0.7) } 28 | 29 | /* Styles for Error Message that appears if you are trying to view WebChimera on Local Filesystem */ 30 | #lwarning {color:#fff;background-color:#d9534f;border-color:#d43f3a;display:inline-block;padding:6px 12px;margin-bottom:0;font-size:14px;font-weight:400;line-height:1.42857143;text-align:center;white-space:nowrap;vertical-align:middle;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background-image:none;border:1px solid transparent;border-radius:4px;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;margin-right:10px} 31 | #warning-wrapper {text-align:center;margin-top:30px;z-index:1002} 32 | -------------------------------------------------------------------------------- /custom_artwork.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Custom Artwork Demo - WebChimera Player 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 |

Custom Artwork Demo

18 | 19 |
20 | 21 | 22 | 47 | 48 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /custom_titles.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Custom Titles Demo - WebChimera Player 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 |

Custom Titles Demo

18 | 19 |
20 | 21 | 22 | 47 | 48 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /default_skin.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Default Skin Demo - WebChimera Player 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 |

Default Skin Demo

18 | 19 |
20 | 21 | 22 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /external_subtitle.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | External Subtitle Demo - WebChimera Player 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 |

External Subtitle Demo

18 | 19 |
20 | 21 | 22 | 39 | 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /images/close_but.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jaruba/WebChimeraPlayer/9d1f55dd89b93e9fc5a83e8d9ea86070fc7e0ae2/images/close_but.png -------------------------------------------------------------------------------- /images/webchimera_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jaruba/WebChimeraPlayer/9d1f55dd89b93e9fc5a83e8d9ea86070fc7e0ae2/images/webchimera_logo.png -------------------------------------------------------------------------------- /images/webchimera_logo_small.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jaruba/WebChimeraPlayer/9d1f55dd89b93e9fc5a83e8d9ea86070fc7e0ae2/images/webchimera_logo_small.png -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | WebChimera Player Demos 10 | 11 | 12 | 13 | 14 | 15 | 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /internal_subtitles.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Internal Subtitles Demo - WebChimera Player 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 |

Internal Subtitles Demo

18 | 19 |
20 | 21 | 22 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /keypress_events.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | JS Key Events Demo - WebChimera Player 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 |

JS Mouse Events Demo

18 | 19 |
20 |
Key Events
21 |
22 |
23 | 24 | 25 | 42 | 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /m3u_playlist.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | M3U Playlist Demo - WebChimera Player 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 |

M3U Playlist Demo

18 | 19 |
20 | 21 | 22 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /mouse_events.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | JS Mouse Events Demo - WebChimera Player 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 |

JS Mouse Events Demo

18 | 19 |
20 |
Mouse Events
21 |
22 |
23 | 24 | 25 | 54 | 55 | 56 | 57 | 58 | -------------------------------------------------------------------------------- /multiscreen.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Multiscreen Demo - WebChimera Player 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 |

Multiscreen Demo


Click on a Video!
18 | 19 | 20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 | 29 | 30 | 43 | 44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /player/core/Buttons.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.1 2 | import QmlVlc 0.1 3 | 4 | Rectangle { 5 | // START BUTTON ACTIONS 6 | function clicked(action) { 7 | 8 | // send data back to On Page JavaScript for .onClicked 9 | fireQmlMessage("[clicked]"+action); 10 | // end send data back to On Page JavaScript for .onClicked 11 | 12 | if (contextblock.visible === true) contextblock.close(); 13 | 14 | if (action == "play") if (typeof settings.preventClicked[action] === "undefined") { 15 | wjs.togPause(); 16 | } 17 | if (action == "prev") if (typeof settings.preventClicked[action] === "undefined") { 18 | vlcPlayer.playlist.prev(); 19 | } 20 | if (action == "next") if (typeof settings.preventClicked[action] === "undefined") { 21 | vlcPlayer.playlist.next(); 22 | } 23 | if (action == "mute") if (typeof settings.preventClicked[action] === "undefined") { 24 | wjs.toggleMute(); 25 | } 26 | if (action == "subtitles") if (typeof settings.preventClicked[action] === "undefined") { 27 | subMenu.toggleSubtitles(); 28 | } 29 | if (action == "playlist") if (typeof settings.preventClicked[action] === "undefined") { 30 | wjs.togglePlaylist(); 31 | } 32 | if (action == "fullscreen") if (typeof settings.preventClicked[action] === "undefined") { 33 | if (settings.allowfullscreen == 1) { 34 | wjs.togFullscreen(); 35 | if (settings.multiscreen == 1) wjs.toggleMute(); // Multiscreen - Edit 36 | } 37 | } 38 | } 39 | // END BUTTON ACTIONS 40 | } -------------------------------------------------------------------------------- /player/core/Hotkeys.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.1 2 | import QmlVlc 0.1 3 | 4 | Rectangle { 5 | property var mouseClicked: 0; // Fix for Missing Clicks 6 | 7 | // START HOTKEYS 8 | function keys(event) { 9 | 10 | // send data back to On Page JavaScript for .onKeyPressed 11 | if (event.modifiers) { 12 | if (event.modifiers == Qt.ControlModifier && event.key == Qt.Key_Control) { 13 | fireQmlMessage("[pressed-"+event.key+"]"); 14 | } else if (event.modifiers == Qt.MetaModifier && event.key == Qt.Key_Meta) { 15 | fireQmlMessage("[pressed-"+event.key+"]"); 16 | } else if (event.modifiers == Qt.ShiftModifier && event.key == Qt.Key_Shift) { 17 | fireQmlMessage("[pressed-"+event.key+"]"); 18 | } else if (event.modifiers == Qt.AltModifier && event.key == Qt.Key_Alt) { 19 | fireQmlMessage("[pressed-"+event.key+"]"); 20 | } else { 21 | fireQmlMessage("[pressed-"+event.modifiers+"+"+event.key+"]"); 22 | } 23 | } else { 24 | fireQmlMessage("[pressed-"+event.key+"]"); 25 | } 26 | // end send data back to On Page JavaScript for .onKeyPressed 27 | 28 | if (contextblock.visible === true) contextblock.close(); 29 | if (event.key == Qt.Key_Space) { 30 | if (typeof settings.preventKey[Qt.Key_Space] === "undefined") { 31 | wjs.togPause(); 32 | } 33 | } 34 | if (event.key == Qt.Key_Escape) { 35 | if (typeof settings.preventKey[Qt.Key_Escape] === "undefined") { 36 | if (subMenublock.visible === true || playlistblock.visible === true) { 37 | subMenublock.visible = false; 38 | playlistblock.visible = false; 39 | } else if (fullscreen) { 40 | fullscreen = false; 41 | if (settings.multiscreen == 1) if (vlcPlayer.audio.mute === false) vlcPlayer.toggleMute(); // Multiscreen - Mute on Playback Start 42 | } 43 | } 44 | } 45 | if (event.key == Qt.Key_F || event.key == Qt.Key_F11) { 46 | if (typeof settings.preventKey[Qt.Key_F] === "undefined" && typeof settings.preventKey[Qt.Key_F11] === "undefined") { 47 | wjs.togFullscreen(); 48 | } 49 | } 50 | if (event.key == Qt.Key_E) { 51 | if (typeof settings.preventKey[Qt.Key_E] === "undefined") { 52 | wjs.nextFrame(500); 53 | } 54 | } 55 | if (event.key == Qt.Key_N) { 56 | if (typeof settings.preventKey[Qt.Key_N] === "undefined") { 57 | vlcPlayer.playlist.next(); 58 | } 59 | } 60 | if(event.modifiers == Qt.ControlModifier) { 61 | if (event.key == Qt.Key_Right) { 62 | if (typeof settings.preventKey[Qt.ControlModifier+"+"+Qt.Key_Right] === "undefined") { 63 | wjs.jumpTo(60000); 64 | return; 65 | } 66 | } else if (event.key == Qt.Key_Left) { 67 | if (typeof settings.preventKey[Qt.ControlModifier+"+"+Qt.Key_Left] === "undefined") { 68 | wjs.jumpTo(-60000); 69 | return; 70 | } 71 | } else if (event.key == Qt.Key_Up) { 72 | if (typeof settings.preventKey[Qt.ControlModifier+"+"+Qt.Key_Up] === "undefined") { 73 | wjs.volumeTo(8); 74 | return; 75 | } 76 | } else if (event.key == Qt.Key_Down) { 77 | if (typeof settings.preventKey[Qt.ControlModifier+"+"+Qt.Key_Down] === "undefined") { 78 | wjs.volumeTo(-8); 79 | return; 80 | } 81 | } else if (event.key == Qt.Key_L) { 82 | if (typeof settings.preventKey[Qt.ControlModifier+"+"+Qt.Key_L] === "undefined") { 83 | wjs.togglePlaylist(); 84 | return; 85 | } 86 | } else if (event.key == Qt.Key_D) { 87 | if (typeof settings.preventKey[Qt.ControlModifier+"+"+Qt.Key_D] === "undefined") { 88 | if (settings.debugPlaylist) { 89 | if (inputAddBox.visible) inputAddBox.visible = false; 90 | settings.selectedItem = vlcPlayer.playlist.currentItem; 91 | inputBox.textBox.text = vlcPlayer.playlist.items[vlcPlayer.playlist.currentItem].mrl; 92 | inputBox.textBox.selectAll(); 93 | inputBox.visible = true; 94 | inputBox.textBox.forceActiveFocus(); 95 | return; 96 | } 97 | } 98 | } else if (event.key == Qt.Key_A) { 99 | if (typeof settings.preventKey[Qt.ControlModifier+"+"+Qt.Key_A] === "undefined") { 100 | if (settings.debugPlaylist) { 101 | if (inputBox.visible) inputBox.visible = false 102 | inputAddBox.textBox.text = ""; 103 | inputAddBox.visible = true; 104 | inputAddBox.textBox.forceActiveFocus(); 105 | return; 106 | } 107 | } 108 | } else if (event.key == Qt.Key_H) { 109 | if (typeof settings.preventKey[Qt.ControlModifier+"+"+Qt.Key_H] === "undefined") { 110 | wjs.toggleUI(); 111 | if (settings.uiVisible) { 112 | wjs.setText("UI Visible"); 113 | } else wjs.setText("UI Hidden"); 114 | settings = settings; 115 | return; 116 | } 117 | } 118 | return; 119 | } 120 | if(event.modifiers == Qt.AltModifier) { 121 | if (event.key == Qt.Key_Right) { 122 | if (typeof settings.preventKey[Qt.AltModifier+"+"+Qt.Key_Right] === "undefined") { 123 | wjs.jumpTo(10000); 124 | return; 125 | } 126 | } else if (event.key == Qt.Key_Left) { 127 | if (typeof settings.preventKey[Qt.AltModifier+"+"+Qt.Key_Left] === "undefined") { 128 | wjs.jumpTo(-10000); 129 | return; 130 | } 131 | } else if (event.key == Qt.Key_Up) { 132 | if (typeof settings.preventKey[Qt.AltModifier+"+"+Qt.Key_Plus] === "undefined") { 133 | if (settings.subSize < 4) settings.subSize++; 134 | wjs.setText("Subtitle Size: "+(settings.subSize+1)); 135 | settings = settings; 136 | return; 137 | } 138 | } else if (event.key == Qt.Key_Down) { 139 | if (typeof settings.preventKey[Qt.AltModifier+"+"+Qt.Key_Minus] === "undefined") { 140 | if (settings.subSize > 0) settings.subSize--; 141 | wjs.setText("Subtitle Size: "+(settings.subSize+1)); 142 | settings = settings; 143 | return; 144 | } 145 | } 146 | return; 147 | } 148 | if(event.modifiers == Qt.ShiftModifier) { 149 | if (event.key == Qt.Key_Right) { 150 | if (typeof settings.preventKey[Qt.ShiftModifier+"+"+Qt.Key_Right] === "undefined") { 151 | wjs.jumpTo(3000); 152 | return; 153 | } 154 | } else if (event.key == Qt.Key_Left) { 155 | if (typeof settings.preventKey[Qt.ShiftModifier+"+"+Qt.Key_Left] === "undefined") { 156 | wjs.jumpTo(-3000); 157 | return; 158 | } 159 | } 160 | return; 161 | } 162 | if (event.key == Qt.Key_M) { 163 | if (typeof settings.preventKey[Qt.Key_M] === "undefined") { 164 | wjs.toggleMute(); 165 | if (vlcPlayer.audio.mute) { 166 | wjs.setText("Muted"); 167 | } else { 168 | wjs.setText("Volume " + (Math.round((250 * (vlcPlayer.volume /200))/10) *5) + "%"); 169 | } 170 | wjs.refreshMuteIcon(); 171 | } 172 | } 173 | if (event.key == Qt.Key_P) { 174 | if (typeof settings.preventKey[Qt.Key_P] === "undefined") { 175 | vlcPlayer.time = 0; 176 | } 177 | } 178 | if (event.key == Qt.Key_Plus || event.key == Qt.Key_BracketRight) { 179 | if (typeof settings.preventKey[Qt.Key_Plus] === "undefined" && typeof settings.preventKey[Qt.Key_BracketRight] === "undefined") { 180 | wjs.rateTo("increase"); 181 | } 182 | } 183 | if (event.key == Qt.Key_Minus || event.key == Qt.Key_BracketLeft) { 184 | if (typeof settings.preventKey[Qt.Key_Minus] === "undefined" && typeof settings.preventKey[Qt.Key_BracketLeft] === "undefined") { 185 | wjs.rateTo("decrease"); 186 | } 187 | } 188 | if (event.key == Qt.Key_Equal) { 189 | if (typeof settings.preventKey[Qt.Key_Equal] === "undefined") { 190 | wjs.rateTo("normal"); 191 | } 192 | } 193 | if (event.key == Qt.Key_A) { 194 | if (typeof settings.preventKey[Qt.Key_A] === "undefined") { 195 | var kl = 0; 196 | for (kl = 0; typeof settings.aspectRatios[kl] !== 'undefined'; kl++) if (settings.aspectRatios[kl] == settings.curAspect) { 197 | if (typeof settings.aspectRatios[kl+1] !== 'undefined') { 198 | settings.curAspect = settings.aspectRatios[kl+1]; 199 | } else settings.curAspect = settings.aspectRatios[0]; 200 | 201 | if (settings.curAspect == "Default") { 202 | wjs.resetAspect(); 203 | } else { 204 | wjs.changeAspect(settings.curAspect,"ratio"); 205 | } 206 | 207 | wjs.setText("Aspect Ratio: " + settings.curAspect); 208 | break; 209 | } 210 | } 211 | } 212 | if (event.key == Qt.Key_C) { 213 | if (typeof settings.preventKey[Qt.Key_C] === "undefined") { 214 | var kl = 0; 215 | for (kl = 0; typeof settings.crops[kl] !== 'undefined'; kl++) if (settings.crops[kl] == settings.curCrop) { 216 | if (typeof settings.crops[kl+1] !== 'undefined') { 217 | settings.curCrop = settings.crops[kl+1]; 218 | } else settings.curCrop = settings.crops[0]; 219 | if (settings.curCrop == "Default") { 220 | wjs.resetAspect(); 221 | } else { 222 | wjs.changeAspect(settings.curCrop,"crop"); 223 | } 224 | 225 | wjs.setText("Crop: " + settings.curCrop); 226 | break; 227 | } 228 | } 229 | } 230 | if (event.key == Qt.Key_Z) { 231 | if (typeof settings.preventKey[Qt.Key_Z] === "undefined") { 232 | var kl = 0; 233 | for (kl = 0; typeof settings.zooms[kl] !== 'undefined'; kl++) if (settings.curZoom == kl) { 234 | if (typeof settings.zooms[kl+1] !== 'undefined') { 235 | settings.curZoom = kl +1; 236 | } else settings.curZoom = 0; 237 | 238 | wjs.changeZoom(settings.zooms[settings.curZoom][0]); 239 | 240 | wjs.setText("Zoom Mode: " + settings.zooms[settings.curZoom][1]); 241 | break; 242 | } 243 | } 244 | } 245 | if (event.key == Qt.Key_T) { 246 | if (typeof settings.preventKey[Qt.Key_T] === "undefined") { 247 | wjs.setText(showtime.text.trim()); 248 | } 249 | } 250 | if (event.key == Qt.Key_G) { 251 | if (typeof settings.preventKey[Qt.Key_G] === "undefined") { 252 | settings.subDelay = settings.subDelay -50; 253 | wjs.setText("Subtitle Delay: "+settings.subDelay+" ms"); 254 | vlcPlayer.subtitle.delay = settings.subDelay; 255 | } 256 | } 257 | if (event.key == Qt.Key_H) { 258 | if (typeof settings.preventKey[Qt.Key_H] === "undefined") { 259 | settings.subDelay = settings.subDelay +50; 260 | wjs.setText("Subtitle Delay: "+settings.subDelay+" ms"); 261 | vlcPlayer.subtitle.delay = settings.subDelay; 262 | } 263 | } 264 | if (event.key == Qt.Key_J) { 265 | if (typeof settings.preventKey[Qt.Key_J] === "undefined") { 266 | settings.audioDelay = settings.audioDelay -50; 267 | wjs.setText("Audio Delay: "+settings.audioDelay+" ms"); 268 | vlcPlayer.audio.delay = settings.audioDelay; 269 | } 270 | } 271 | if (event.key == Qt.Key_K) { 272 | if (typeof settings.preventKey[Qt.Key_K] === "undefined") { 273 | settings.audioDelay = settings.audioDelay +50; 274 | wjs.setText("Audio Delay: "+settings.audioDelay+" ms"); 275 | vlcPlayer.audio.delay = settings.audioDelay; 276 | } 277 | } 278 | } 279 | // END HOTKEYS 280 | 281 | 282 | // MOUSE ACTIONS 283 | function mouseScroll(mouseX,mouseY) { 284 | // Change Volume on Mouse Scroll 285 | if (mouseY > 0) wjs.volumeTo(8); 286 | if (mouseY < 0) wjs.volumeTo(-8); 287 | // End Change Volume on Mouse Scroll 288 | } 289 | function mouseMoved(mouseX,mouseY) { 290 | settings.ismoving = 1; // Reset Idle Mouse Movement if mouse position has changed 291 | 292 | if (settings.mouseevents == 1) { 293 | // JavaScript Mouse Events Demo 294 | var sendjsdata = {}; 295 | sendjsdata["type"] = "mouseMove"; 296 | sendjsdata["x"] = mouseX; 297 | sendjsdata["y"] = mouseY; 298 | 299 | fireQmlMessage(JSON.stringify(sendjsdata)); 300 | } 301 | 302 | settings.cursorX = mouseX; 303 | settings.cursorY = mouseY; 304 | } 305 | function mouseDblClick(clicked) { 306 | if (settings.multiscreen == 0) { 307 | if (settings.mouseevents == 1) { 308 | // JavaScript Mouse Events Demo 309 | if (vlcPlayer.state != 1) if (toolbarBackground.bottomtab.containsMouse === false) if (clicked == Qt.LeftButton) { 310 | var sendjsdata = {}; 311 | sendjsdata["type"] = "mouseDoubleClick"; 312 | 313 | fireQmlMessage(JSON.stringify(sendjsdata)); 314 | } 315 | } 316 | var doit = 0; 317 | if (clicked == Qt.LeftButton) { 318 | if (settings.multiscreen == 0) doit = 1; 319 | if (fullscreen) if (settings.multiscreen == 1) doit = 1; 320 | } 321 | if (doit == 1) { 322 | 323 | if (vlcPlayer.state == 4) wjs.togPause(); 324 | 325 | settings.gobigpause = false; 326 | settings.gobigplay = false; 327 | pausetog.visible = false; 328 | playtog.visible = false; 329 | if (!fullscreen) mouseClicked = 1; // Fix for Missing Clicks 330 | wjs.togFullscreen(); 331 | mousesurface.focus = true; 332 | } 333 | } 334 | if (settings.multiscreen == 1) MouseClicked(clicked); // Multiscreen does not support Fullscreen Toggle on Double Click 335 | } 336 | function mouseClick(clicked) { 337 | mouseClicked = 1; // Fix for Missing Clicks 338 | if (toolbarBackground.bottomtab.containsMouse === false) { 339 | var sendjsdata = {}; 340 | 341 | if (clicked == Qt.RightButton) { 342 | // JavaScript Mouse Events Demo 343 | if (settings.mouseevents == 1) { 344 | sendjsdata["type"] = "mouseRightClick"; 345 | fireQmlMessage(JSON.stringify(sendjsdata)); 346 | } 347 | if (settings.cursorX == 0 && settings.cursorY == 0) { } else { 348 | if (settings.multiscreen == 1 && fullscreen === false) { } else { 349 | contextblock.addContextItems(); 350 | contextblock.open(); 351 | } 352 | } 353 | } else { 354 | if (contextblock.visible === true) { 355 | contextblock.close(); 356 | } else { 357 | if (settings.multiscreen == 0) { 358 | if (vlcPlayer.state != 1) wjs.isbig(); // Toggle Pause if clicked on Surface 359 | if (settings.mouseevents == 1) { 360 | // JavaScript Mouse Events Demo 361 | sendjsdata["type"] = "mouseLeftClick"; 362 | fireQmlMessage(JSON.stringify(sendjsdata)); 363 | } 364 | } else { 365 | if (fullscreen) { 366 | wjs.isbig(); 367 | } else { 368 | wjs.gobig(); 369 | } 370 | } 371 | } 372 | } 373 | } 374 | } 375 | function mouseRelease(clicked) { 376 | // Start Fix for Missing Clicks 377 | if (mouseClicked == 1) { 378 | mouseClicked = 0; 379 | } else { 380 | if (toolbarBackground.bottomtab.containsMouse === false) { 381 | var sendjsdata = {}; 382 | 383 | if (clicked == Qt.RightButton) { 384 | // JavaScript Mouse Events Demo 385 | if (settings.mouseevents == 1) { 386 | sendjsdata["type"] = "mouseRightClick"; 387 | fireQmlMessage(JSON.stringify(sendjsdata)); 388 | } 389 | contextblock.addContextItems(); 390 | contextblock.open(); 391 | } else { 392 | if (settings.multiscreen == 0) { 393 | if (vlcPlayer.state != 1) wjs.isbig(); // Toggle Pause if clicked on Surface 394 | if (settings.mouseevents == 1) { 395 | // JavaScript Mouse Events Demo 396 | sendjsdata["type"] = "mouseLeftClick"; 397 | fireQmlMessage(JSON.stringify(sendjsdata)); 398 | } 399 | } else { 400 | if (fullscreen) { 401 | wjs.isbig(); 402 | } else { 403 | wjs.gobig(); 404 | } 405 | } 406 | } 407 | } 408 | } 409 | // End Fix for Missing Clicks 410 | } 411 | // END MOUSE ACTIONS 412 | } -------------------------------------------------------------------------------- /player/core/Settings.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.1 2 | 3 | QtObject { 4 | property alias data: root; 5 | 6 | id: root; 7 | property var gobigplay: false; 8 | property var gobigpause: false; 9 | property var dragging: false; 10 | property var ismoving: 1; 11 | property var buffering: 0; 12 | property var toolbar: 1; 13 | property var uiVisible: 1; 14 | property var autoloop: 0; 15 | property var automute: 0; 16 | property var autoplay: 0; 17 | property var allowfullscreen: 1; 18 | property var playlistmenu: false; 19 | property var subtitlemenu: false; 20 | property var totalSubs: 0; 21 | property var title: ""; 22 | property var multiscreen: 0; 23 | property var timervolume: 0; 24 | property var glyphsLoaded: false; 25 | property var firsttime: 1; 26 | property var firstvolume: 1; 27 | property var cache: 0; 28 | property var lastTime: 0; 29 | property var cursorX: 0; 30 | property var cursorY: 0; 31 | property var contextmenu: false; 32 | property var curZoom: 0; 33 | property var curCrop: "Default"; 34 | property var curAspect: "Default"; 35 | property var mouseevents: 0; 36 | property var downloaded: 0; 37 | property var customLength: 0; 38 | property var newProgress: 0; 39 | property var openingText: "Loading Resource"; 40 | property variant preventKey: []; 41 | property variant preventClicked: []; 42 | property variant aspectRatios: ["Default", "1:1", "4:3", "16:9", "16:10", "2.21:1", "2.35:1", "2.39:1", "5:4"]; 43 | property variant crops: ["Default", "16:10", "16:9", "1.85:1", "2.21:1", "2.35:1", "2.39:1", "5:3", "4:3", "5:4", "1:1"]; 44 | property variant zooms: [[1, "Default"], [2, "2x Double"], [0.25, "0.25x Quarter"], [0.5, "0.5x Half"]]; 45 | property variant subPresets: ["0.025", "0.03", "0.037", "0.045", "0.05"]; 46 | property variant titleCache: []; 47 | property var debugPlaylist: false; 48 | property var selectedItem: 0; 49 | property var subSize: 2; 50 | property var subDelay: 0; 51 | property var audioDelay: 0; 52 | property var digitalzoom: 0; 53 | property var digiZoomClosed: false; 54 | property var pip: 0; 55 | property var pipClosed: false; 56 | property var refreshTime: false; 57 | property var refreshPlaylistItems: false; 58 | } -------------------------------------------------------------------------------- /player/core/qmldir: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jaruba/WebChimeraPlayer/9d1f55dd89b93e9fc5a83e8d9ea86070fc7e0ae2/player/core/qmldir -------------------------------------------------------------------------------- /player/images/cursor-openhand.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jaruba/WebChimeraPlayer/9d1f55dd89b93e9fc5a83e8d9ea86070fc7e0ae2/player/images/cursor-openhand.png -------------------------------------------------------------------------------- /player/images/dragger.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jaruba/WebChimeraPlayer/9d1f55dd89b93e9fc5a83e8d9ea86070fc7e0ae2/player/images/dragger.png -------------------------------------------------------------------------------- /player/themes/sleek/UIsettings.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.1 2 | 3 | Rectangle { 4 | 5 | property var done: false; 6 | 7 | property variant variables: { 8 | 9 | 'settings': { 10 | 'iconFont': "fonts/glyphicons.ttf", 11 | 'defaultFont': "http://fonts.gstatic.com/s/sourcesanspro/v9/toadOcfmlt9b38dHJxOBGNNE-IuDiR70wI4zXaKqWCM.ttf", 12 | 'secondaryFont': "http://fonts.gstatic.com/s/opensans/v10/k3k702ZOKiLJc3WVjuplzInF5uFdDttMLvmWuJdhhgs.ttf", 13 | 'toolbar': { 14 | 'borderVisible': true, 15 | 'buttonWidth': 59, 16 | 'buttonMuteWidth': 40, 17 | 'opacity': 0.9, 18 | 19 | // this is the space between the time/length (00:00/00:00) in the toolbar and the mute button 20 | 'timeMargin': 11 21 | }, 22 | 'caching': false, // If cache progress bar is visible or not 23 | 'titleBar': "fullscreen", // When should the title bar be visible, possible values are: "fullscreen", "minimized", "both", "none" 24 | 'buttonGlow': false // if button icons should glow when hovered 25 | }, 26 | 27 | 'icon': { 28 | 29 | // Playback Button Icons 30 | 'prev': "\ue80a", 31 | 'next': "\ue809", 32 | 'play': "\ue87f", 33 | 'pause': "\ue880", 34 | 'replay': "\ue8a7", 35 | 36 | // Audio Related Button Icons 37 | 'mute': "\ue877", 38 | 'volume': { 39 | 'low': "\ue876", 40 | 'medium': "\ue875", 41 | 'high': "\ue878" 42 | }, 43 | 44 | // Playlist Button Icon 45 | 'playlist': "\ue833", 46 | 47 | // Subtitle Menu Button Icon 48 | 'subtitles': "\ue83a", 49 | 50 | // Fullscreen Button Icons 51 | 'minimize': "\ue805", 52 | 'maximize': "\ue804", 53 | 54 | // Big Play/Pause Icons (appear in the center of the screen when Toggle Pause) 55 | 'bigPlay': "\ue82d", 56 | 'bigPause': "\ue82e", 57 | 58 | // Appears when hovering over progress bar 59 | 'timeBubble': { 60 | 'big': "\ue802", 61 | 'small': "\ue803" 62 | }, 63 | 64 | // Close Playlist Button 65 | 'closePlaylist': "\ue896", 66 | 67 | // Settings Button (for advanced playlist feature) 68 | 'settings': "\ue801", 69 | 70 | // Picture in Picture Button (playlist menu) 71 | 'pip': "\ue800" 72 | 73 | }, 74 | 75 | 'colors': { 76 | 77 | // Video Background Color 78 | 'videoBackground': "#000000", 79 | 80 | // UI Background Color (toolbar, playlist menu) 81 | 'background': "#000000", 82 | 83 | // Default Font Colors 84 | 'font': "#ffffff", 85 | 'fontShadow': "#000000", 86 | 87 | // Top Title Bar Colors 88 | 'titleBar': { 89 | 'background': "#000000", 90 | 'font': "#cbcbcb" 91 | }, 92 | 93 | // Progress Bar Colors 94 | 'progress': { 95 | 'background': "#262626", 96 | 'viewed': "#08758F", 97 | 'position': "#e5e5e5", 98 | 'cache': "#3e3e3e" 99 | }, 100 | 101 | // Appears when hovering over progress bar 102 | 'timeBubble': { 103 | 'background': "#000000", 104 | 'border': "#898989", 105 | 'font': "#ffffff" 106 | }, 107 | 108 | // Toolbar colors 109 | 'toolbar': { 110 | 'border': "#262626", 111 | 'button': "#7b7b7b", 112 | 'buttonHover': "#ffffff", 113 | 114 | // Color for Current Time Text in Toolbar (first part of "00:00 / 00:00") 115 | 'currentTime': "#9a9a9a", 116 | 117 | // Color for Total Length Time Text in Toolbar (second part of "00:00 / 00:00") 118 | 'lengthTime': "#9a9a9a" 119 | }, 120 | 121 | // Big Play/Pause Icon (appears in center of screen when Toggle Pause) 122 | 'bigIcon': "#ffffff", 123 | 'bigIconBackground': "#1c1c1c", 124 | 125 | // Playlist Menu Colors 126 | 'playlistMenu': { 127 | 'background': "#292929", 128 | 'scroller': "#696969", 129 | 'drag': "#e5e5e5", 130 | 'header': "#1C1C1C", 131 | 'headerFont': "#d5d5d5", 132 | 133 | // Playlist Menu Close Button 134 | 'close': "#c0c0c0", 135 | 'closeHover': "#eaeaea", 136 | 137 | // Playlist Menu Close Button Background 138 | 'closeBackground': "#1C1C1C", 139 | 'closeBackgroundHover': "#151515" 140 | }, 141 | 142 | 'volumeHeat': { 143 | 'background': "#696969", 144 | 'color': "#E77607" 145 | } 146 | 147 | } 148 | } 149 | // hack to force property notify for .skin() 150 | Component.onCompleted: { ui = variables; done = true; } 151 | Timer { 152 | interval: 0; running: done === true && mutebut.width != ui.settings.toolbar.buttonMuteWidth ? true : false; repeat: false 153 | onTriggered: { ui = ui } 154 | } 155 | Timer { 156 | interval: 0; running: done === true && prevBut.width != buttonWidth ? true : false; repeat: false 157 | onTriggered: { buttonWidth = buttonWidth } 158 | } 159 | // end hack to force property notify for .skin() 160 | } -------------------------------------------------------------------------------- /player/themes/sleek/components/AddMRL.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.1 2 | import QtQuick.Controls 1.1 3 | import QtQuick.Layouts 1.0 4 | import QtQuick.Controls.Styles 1.1 5 | import QmlVlc 0.1 6 | 7 | Rectangle { 8 | property alias textBox: newURL 9 | 10 | visible: false 11 | anchors.centerIn: parent 12 | width: fullscreen ? 450 : (parent.width * 0.9) < 394 ? (parent.width * 0.9) : 394 13 | height: 80 14 | color: "transparent" 15 | focus: true 16 | 17 | MouseArea { 18 | hoverEnabled: true 19 | anchors.fill: parent 20 | } 21 | Rectangle { 22 | height: 30 23 | width: parent.width - 20 24 | anchors.top: parent.top 25 | anchors.horizontalCenter: parent.horizontalCenter 26 | color: "transparent" 27 | Text { 28 | text: "Add Media URL" 29 | font.weight: Font.DemiBold 30 | font.pointSize: 10 31 | anchors.verticalCenter: parent.verticalCenter 32 | color: "#e5e5e5" 33 | } 34 | Rectangle { 35 | height: 20 36 | width: 20 37 | anchors.right: parent.right 38 | anchors.verticalCenter: parent.verticalCenter 39 | color: "transparent" 40 | Text { 41 | font.pointSize: 10 42 | color: urlClose.containsMouse ? ui.colors.playlistMenu.closeHover : ui.colors.playlistMenu.close 43 | anchors.right: parent.right 44 | anchors.verticalCenter: parent.verticalCenter 45 | font.family: fonts.icons.name 46 | text: settings.glyphsLoaded ? ui.icon.closePlaylist : "" 47 | } 48 | MouseArea { 49 | id: urlClose 50 | cursorShape: Qt.PointingHandCursor 51 | hoverEnabled: true 52 | anchors.fill: parent 53 | onClicked: { 54 | mousesurface.forceActiveFocus(); 55 | inputAddBox.visible = false; 56 | } 57 | } 58 | } 59 | } 60 | 61 | TextField { 62 | id: newURL 63 | readOnly: false 64 | placeholderText: "Media URL" 65 | width: (parent.width - 20) * 0.8 66 | height: parent.height - 40 67 | anchors.left: parent.left 68 | anchors.leftMargin: 10 69 | anchors.bottom: parent.bottom 70 | anchors.bottomMargin: 10 71 | style: TextFieldStyle { 72 | font.pixelSize: 14 73 | background: Rectangle { 74 | radius: 0 75 | color: "#e5e5e5" 76 | anchors.fill: parent 77 | } 78 | } 79 | Keys.onReturnPressed: { 80 | mousesurface.forceActiveFocus(); 81 | inputAddBox.visible = false; 82 | vlcPlayer.playlist.add(newURL.text); 83 | playlist.addPlaylistItems(); // Refresh Playlist GUI 84 | } 85 | Keys.onEscapePressed: { 86 | mousesurface.forceActiveFocus(); 87 | inputAddBox.visible = false; 88 | } 89 | Keys.onPressed: { 90 | if(event.modifiers == Qt.ControlModifier) { 91 | if (event.key == Qt.Key_D) { 92 | if (typeof settings.preventKey[Qt.ControlModifier+"+"+Qt.Key_D] === "undefined") { 93 | if (settings.debugPlaylist) { 94 | if (inputAddBox.visible) inputAddBox.visible = false; 95 | settings.selectedItem = vlcPlayer.playlist.currentItem; 96 | inputBox.textBox.text = vlcPlayer.playlist.items[vlcPlayer.playlist.currentItem].mrl; 97 | inputBox.textBox.selectAll(); 98 | inputBox.visible = true; 99 | inputBox.textBox.forceActiveFocus(); 100 | return; 101 | } 102 | } 103 | } 104 | } 105 | } 106 | } 107 | Rectangle { 108 | width: (parent.width - 20) * 0.2 109 | height: parent.height - 40 110 | anchors.right: parent.right 111 | anchors.rightMargin: 10 112 | anchors.bottom: parent.bottom 113 | anchors.bottomMargin: 10 114 | color: submitButton.containsMouse ? "#3D3D3D" : "#363636" 115 | Text { 116 | anchors.centerIn: parent 117 | text: "Add" 118 | font.pointSize: 12 119 | color: "#e5e5e5" 120 | } 121 | MouseArea { 122 | id: submitButton 123 | cursorShape: Qt.PointingHandCursor 124 | hoverEnabled: true 125 | anchors.fill: parent 126 | onClicked: { 127 | mousesurface.forceActiveFocus(); 128 | inputAddBox.visible = false; 129 | vlcPlayer.playlist.add(newURL.text); 130 | playlist.addPlaylistItems(); // Refresh Playlist GUI 131 | } 132 | } 133 | } 134 | } -------------------------------------------------------------------------------- /player/themes/sleek/components/ArtworkLayer.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.1 2 | 3 | // Declare Artwork Layer 4 | Image { 5 | source: ""; 6 | visible: false; 7 | smooth: true; 8 | anchors.centerIn: parent; 9 | width: parent.width; 10 | height: parent.height; 11 | fillMode: Image.PreserveAspectFit; 12 | } 13 | // End Artwork Layer -------------------------------------------------------------------------------- /player/themes/sleek/components/BigPauseIcon.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.1 2 | import QmlVlc 0.1 3 | 4 | // Draw Pause Icon (appears in center of screen when Toggle Pause) 5 | Rectangle { 6 | property alias icon: icon.text 7 | property alias iconColor: icon.color 8 | 9 | anchors.centerIn: parent 10 | visible: false 11 | height: fullscreen ? settings.gobigpause ? 170 : 85 : settings.gobigpause ? 150 : 75 12 | width: fullscreen ? settings.gobigpause ? 170 : 85 : settings.gobigpause ? 150 : 75 13 | opacity: settings.gobigpause ? 0 : 1 14 | radius: 10 15 | smooth: true 16 | 17 | // Start Play Icon Effect when Visible 18 | Behavior on height { PropertyAnimation { duration: 300 } } 19 | Behavior on width { PropertyAnimation { duration: 300 } } 20 | Behavior on opacity { PropertyAnimation { duration: 300 } } 21 | // End Play Icon Effect when Visible 22 | 23 | Text { 24 | id: icon 25 | anchors.centerIn: parent 26 | font.family: fonts.icons.name 27 | text: UI.icon.bigPause 28 | font.pointSize: fullscreen ? settings.gobigpause ? 92 : 46 : settings.gobigpause ? 72 : 36 29 | opacity: settings.gobigpause ? 0 : 1 30 | 31 | // Start Play Icon Effect when Visible 32 | Behavior on font.pointSize { PropertyAnimation { duration: 300 } } 33 | Behavior on opacity { PropertyAnimation { duration: 300 } } 34 | // End Play Icon Effect when Visible 35 | } 36 | 37 | // Start Timer to Hide Big Pause Icon after 300ms 38 | Timer { 39 | interval: 300; running: settings.gobigpause ? true : false; repeat: false 40 | onTriggered: { 41 | pausetog.visible = false; 42 | settings.gobigpause = false; 43 | } 44 | } 45 | // End Timer to Hide Big Pause Icon after 300ms 46 | } 47 | // End Draw Pause Icon (appears in center of screen when Toggle Pause) -------------------------------------------------------------------------------- /player/themes/sleek/components/BigPlayIcon.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.1 2 | import QmlVlc 0.1 3 | 4 | // Draw Play Icon (appears in center of screen when Toggle Pause) 5 | Rectangle { 6 | property alias icon: icon.text 7 | property alias iconColor: icon.color 8 | 9 | anchors.centerIn: parent 10 | visible: false 11 | height: fullscreen ? settings.gobigplay ? 170 : 85 : settings.gobigplay ? 150 : 75 12 | width: fullscreen ? settings.gobigplay ? 170 : 85 : settings.gobigplay ? 150 : 75 13 | opacity: settings.gobigplay ? 0 : 1 14 | radius: 10 15 | smooth: true 16 | 17 | // Start Play Icon Effect when Visible 18 | Behavior on height { PropertyAnimation { duration: 300 } } 19 | Behavior on width { PropertyAnimation { duration: 300 } } 20 | Behavior on opacity { PropertyAnimation { duration: 300 } } 21 | // End Play Icon Effect when Visible 22 | 23 | Text { 24 | id: icon 25 | anchors.centerIn: parent 26 | font.family: fonts.icons.name 27 | text: UI.icon.bigPlay 28 | font.pointSize: fullscreen ? settings.gobigplay ? 108 : 54 : settings.gobigplay ? 90 : 45 29 | color: UI.colors.bigIcon 30 | opacity: settings.gobigplay ? 0 : 1 31 | 32 | // Start Play Icon Effect when Visible 33 | Behavior on font.pointSize { PropertyAnimation { duration: 300 } } 34 | Behavior on opacity { PropertyAnimation { duration: 300 } } 35 | // End Play Icon Effect when Visible 36 | } 37 | 38 | // Start Timer to Hide Big Play Icon after 300ms 39 | Timer { 40 | interval: 320; running: settings.gobigplay ? true : false; repeat: false 41 | onTriggered: { 42 | playtog.visible = false; 43 | settings.gobigplay = false; 44 | } 45 | } 46 | // End Timer to Hide Big Play Icon after 300ms 47 | } 48 | // End Draw Play Icon (appears in center of screen when Toggle Pause) 49 | -------------------------------------------------------------------------------- /player/themes/sleek/components/ContextMenu.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.1 2 | import QmlVlc 0.1 3 | 4 | Rectangle { 5 | id: root 6 | anchors.top: parent.top 7 | anchors.topMargin: 0 8 | anchors.left: parent.left 9 | anchors.leftMargin: 0 10 | visible: false; 11 | width: 152 12 | height: 2+(totalCons * 30) 13 | color: "transparent" 14 | border.color: "transparent" 15 | border.width: 1 16 | 17 | property var totalCons: 0; 18 | property variant conItems: []; 19 | property variant conArrows: []; 20 | property var subTimer: false; 21 | property var rightPx: 0; 22 | property var bottomPx: 0; 23 | 24 | 25 | // Start Open/Close Context Menu Functions 26 | function open() { 27 | if (settings.cursorX + root.width > mousesurface.width) { 28 | root.anchors.leftMargin = mousesurface.width - root.width; 29 | } else root.anchors.leftMargin = settings.cursorX; 30 | 31 | rightPx = mousesurface.width - (root.anchors.leftMargin + root.width); 32 | 33 | if (settings.cursorY + root.height > mousesurface.height) { 34 | root.anchors.topMargin = mousesurface.height - root.height; 35 | } else root.anchors.topMargin = settings.cursorY; 36 | 37 | bottomPx = mousesurface.height - (root.anchors.topMargin + root.height); 38 | 39 | root.visible = true; 40 | } 41 | function close() { 42 | root.visible = false; 43 | } 44 | // End Open/Close Context Menu Functions 45 | 46 | // Start Remove all Context Menu Items 47 | function clearAll() { 48 | var pli = 0; 49 | 50 | if (totalCons > 0) for (pli = 0; pli < totalCons; pli++) if (typeof conItems[pli] !== 'undefined') { 51 | conItems[pli].destroy(); 52 | delete conItems[pli]; 53 | } 54 | for (pli = 0; conArrows[pli]; pli++) if (typeof conArrows[pli] !== 'undefined') { 55 | conArrows[pli].destroy(); 56 | delete conArrows[pli]; 57 | } 58 | 59 | conItems = []; 60 | totalCons = 0; 61 | } 62 | // End Remove all Context Menu Items 63 | 64 | function href(target) { 65 | fireQmlMessage("[href]"+target); 66 | } 67 | 68 | function addContextItems() { 69 | // Remove Old Context Menu Items 70 | clearAll(); 71 | 72 | // Adding Context Menu Items 73 | var pli = 0; 74 | 75 | if (vlcPlayer.state == 2 || vlcPlayer.state == 3 || vlcPlayer.state == 4) { 76 | if (vlcPlayer.audio.count > 1) { 77 | var plstring = "Audio Tracks"; 78 | var submenuIt = ""; 79 | var logicIt = ""; 80 | var clickIt = ""; 81 | var preLogicIt = ""; 82 | var selected = 0; 83 | var submenuWidth = 102; 84 | 85 | for (plsi = 0; plsi < vlcPlayer.audio.count; plsi++) if ((vlcPlayer.audio.description(plsi).length *6) +9 > submenuWidth) submenuWidth = (vlcPlayer.audio.description(plsi).length *6) +9; 86 | 87 | var submenuHeight = (vlcPlayer.audio.count *30) +2; 88 | if (submenuHeight < mousesurface.height) { 89 | 90 | var plsi = 0; 91 | for (plsi = 0; plsi < vlcPlayer.audio.count; plsi++) { 92 | if (vlcPlayer.audio.track == plsi) selected = plsi *30; 93 | submenuIt += ' Rectangle { id: sbmenu'+ plsi +'; height: 30; width: '+ submenuWidth +' -2; anchors.left: parent.left; anchors.leftMargin: 1; anchors.top: parent.top; anchors.topMargin: ('+ plsi +' * 30) +1; color: "transparent"; Text { anchors.left: parent.left; anchors.leftMargin: 15; anchors.top: parent.top; anchors.topMargin: 7; text: "'+ vlcPlayer.audio.description(plsi) +'"; color: "#e5e5e5"; font.pointSize: 9 } } '; 94 | preLogicIt += ' sbmenu'+ plsi +'.color = "transparent"; '; 95 | } 96 | for (plsi = 0; plsi < vlcPlayer.audio.count; plsi++) { 97 | if (logicIt != "") logicIt += ' else'; 98 | logicIt += ' if (iTmouseY > ('+ plsi +' *30) && iTmouseY < (('+ plsi +' +1) *30)) { if (sbmenu'+ plsi +'.color != "#3D3D3D") { '+ preLogicIt +' sbmenu'+ plsi +'.color = "#3D3D3D"; } } '; 99 | clickIt += ' if (iTmouseY > ('+ plsi +' *30) && iTmouseY < (('+ plsi +' +1) *30)) { vlcPlayer.audio.track = '+ plsi +'; selectedIt.anchors.topMargin = '+ plsi +' *30 +11; wjs.setText("Audio Track: " + vlcPlayer.audio.description('+ plsi +')); } '; 100 | } 101 | 102 | submenuIt += ' Text { id: selectedIt; anchors.left: parent.left; anchors.leftMargin: 5; anchors.top: parent.top; anchors.topMargin: '+ selected +' +11; text: ui.icon.closePlaylist; font.family: fonts.icons.name; color: "#e5e5e5"; font.pointSize: 6 } '; 103 | 104 | var submenuTop = 0; 105 | var submenuLeft = 0; 106 | 107 | if (((pli *30) +submenuHeight) + root.anchors.topMargin > mousesurface.height) { 108 | submenuTop = (((pli *30) +submenuHeight) + root.anchors.topMargin - mousesurface.height) * (-1) -2; 109 | } else submenuTop = 0; 110 | 111 | if (rightPx < submenuWidth) { 112 | submenuLeft = (submenuWidth + root.width - 2) * (-1); 113 | } else submenuLeft = 0; 114 | 115 | conItems[pli] = Qt.createQmlObject('import QtQuick 2.1; import QtQuick.Layouts 1.0; import QmlVlc 0.1; Rectangle { property var iTmouseY: subcmitem'+ pli +'.mouseY; property var tempvar: false; id: ctxitem'+ pli +'; anchors.left: parent.left; anchors.leftMargin: 1; anchors.top: parent.top; anchors.topMargin: 1+ ('+ pli +' *30); color: "transparent"; width: root.width -2; height: 30; MouseArea { id: cmitem'+ pli +'; cursorShape: Qt.PointingHandCursor; hoverEnabled: true; anchors.fill: parent; onClicked: { } onExited: { tempvar = true; } } Rectangle { width: root.width -2; clip: true; height: 30; color: cmitem'+ pli +'.containsMouse ? "#3D3D3D" : "transparent"; Text { anchors.left: parent.left; anchors.leftMargin: 9; anchors.verticalCenter: parent.verticalCenter; text: "'+ plstring +'"; font.pointSize: 9; color: "#e5e5e5"; } } Rectangle { id: submenu'+ pli +'; visible: cmitem'+ pli +'.containsMouse ? true : subcmitem'+ pli +'.containsMouse ? true : false; anchors.left: parent.right; anchors.leftMargin: '+ submenuLeft +'; anchors.top: parent.top; anchors.topMargin: '+ submenuTop +'; border.color: root.border.color; border.width: 1; height: '+submenuHeight+'; width: '+submenuWidth+'; color: root.color; '+ submenuIt +' } MouseArea { id: subcmitem'+ pli +'; anchors.left: parent.right; anchors.leftMargin: '+ submenuLeft +'; anchors.top: parent.top; anchors.topMargin: '+ submenuTop +'; height: '+submenuHeight+'; width: '+submenuWidth+'; visible: submenu'+ pli +'.visible ? true : tempvar ? true : false; hoverEnabled: submenu'+ pli +'.visible ? true : tempvar ? true : false; cursorShape: Qt.PointingHandCursor; onEntered: { tempvar = true; } onExited: { tempvar = false; '+ preLogicIt +' } onPositionChanged: { '+ logicIt +' } onClicked: { '+ clickIt +' } } Timer { interval: 300; running: tempvar; repeat: false; onTriggered: { if (!subcmitem'+ pli +'.containsMouse) tempvar = false; } } }', root, 'cmenustr' +pli); 116 | 117 | conArrows[pli] = Qt.createQmlObject('import QtQuick 2.1; import QtQuick.Layouts 1.0; import QmlVlc 0.1; Text { anchors.right: parent.right; anchors.rightMargin: 11; anchors.top: parent.top; anchors.topMargin: 10+ ('+ pli +' *30); text: settings.glyphsLoaded ? ui.icon.play : ""; font.family: fonts.icons.name; font.pointSize: 9; color: "#e5e5e5"; }', root, 'omenustr' +pli); 118 | pli++; 119 | } 120 | } 121 | 122 | var plstring = "Aspect Ratio"; 123 | var submenuIt = ""; 124 | var logicIt = ""; 125 | var clickIt = ""; 126 | var preLogicIt = ""; 127 | var selected = 0; 128 | 129 | var submenuHeight = (settings.aspectRatios.length *30) +2; 130 | if (submenuHeight < mousesurface.height) { 131 | 132 | var plsi = 0; 133 | for (plsi = 0; plsi < settings.aspectRatios.length; plsi++) { 134 | if (settings.aspectRatios[plsi] == settings.curAspect) selected = plsi *30; 135 | submenuIt += ' Rectangle { id: sbmenu'+ plsi +'; height: 30; width: 100; anchors.left: parent.left; anchors.leftMargin: 1; anchors.top: parent.top; anchors.topMargin: ('+ plsi +' * 30) +1; color: "transparent"; Text { anchors.left: parent.left; anchors.leftMargin: 15; anchors.top: parent.top; anchors.topMargin: 7; text: "'+ settings.aspectRatios[plsi] +'"; color: "#e5e5e5"; font.pointSize: 9 } } '; 136 | preLogicIt += ' sbmenu'+ plsi +'.color = "transparent"; '; 137 | } 138 | for (plsi = 0; plsi < settings.aspectRatios.length; plsi++) { 139 | if (logicIt != "") logicIt += ' else'; 140 | logicIt += ' if (iTmouseY > ('+ plsi +' *30) && iTmouseY < (('+ plsi +' +1) *30)) { if (sbmenu'+ plsi +'.color != "#3D3D3D") { '+ preLogicIt +' sbmenu'+ plsi +'.color = "#3D3D3D"; } } '; 141 | clickIt += ' if (iTmouseY > ('+ plsi +' *30) && iTmouseY < (('+ plsi +' +1) *30)) { settings.curAspect = "'+ settings.aspectRatios[plsi] +'"; if (settings.curAspect == "Default") { wjs.resetAspect(); } else { wjs.changeAspect(settings.curAspect,"ratio"); } wjs.setText("Aspect Ratio: " + settings.curAspect); selectedIt.anchors.topMargin = '+ plsi +' *30 +11; } '; 142 | } 143 | 144 | submenuIt += ' Text { id: selectedIt; anchors.left: parent.left; anchors.leftMargin: 5; anchors.top: parent.top; anchors.topMargin: '+ selected +' +11; text: ui.icon.closePlaylist; font.family: fonts.icons.name; color: "#e5e5e5"; font.pointSize: 6 } '; 145 | 146 | var submenuWidth = 102; 147 | var submenuTop = 0; 148 | var submenuLeft = 0; 149 | 150 | if (((pli *30) +submenuHeight) + root.anchors.topMargin > mousesurface.height) { 151 | submenuTop = (((pli *30) +submenuHeight) + root.anchors.topMargin - mousesurface.height) * (-1) -2; 152 | } else submenuTop = 0; 153 | 154 | if (rightPx < submenuWidth) { 155 | submenuLeft = (submenuWidth + root.width - 2) * (-1); 156 | } else submenuLeft = 0; 157 | 158 | conItems[pli] = Qt.createQmlObject('import QtQuick 2.1; import QtQuick.Layouts 1.0; import QmlVlc 0.1; Rectangle { property var iTmouseY: subcmitem'+ pli +'.mouseY; property var tempvar: false; id: ctxitem'+ pli +'; anchors.left: parent.left; anchors.leftMargin: 1; anchors.top: parent.top; anchors.topMargin: 1+ ('+ pli +' *30); color: "transparent"; width: root.width -2; height: 30; MouseArea { id: cmitem'+ pli +'; cursorShape: Qt.PointingHandCursor; hoverEnabled: true; anchors.fill: parent; onClicked: { } onExited: { tempvar = true; } } Rectangle { width: root.width -2; clip: true; height: 30; color: cmitem'+ pli +'.containsMouse ? "#3D3D3D" : "transparent"; Text { anchors.left: parent.left; anchors.leftMargin: 9; anchors.verticalCenter: parent.verticalCenter; text: "'+ plstring +'"; font.pointSize: 9; color: "#e5e5e5"; } } Rectangle { id: submenu'+ pli +'; visible: cmitem'+ pli +'.containsMouse ? true : subcmitem'+ pli +'.containsMouse ? true : false; anchors.left: parent.right; anchors.leftMargin: '+ submenuLeft +'; anchors.top: parent.top; anchors.topMargin: '+ submenuTop +'; border.color: root.border.color; border.width: 1; height: '+submenuHeight+'; width: '+submenuWidth+'; color: root.color; '+ submenuIt +' } MouseArea { id: subcmitem'+ pli +'; anchors.left: parent.right; anchors.leftMargin: '+ submenuLeft +'; anchors.top: parent.top; anchors.topMargin: '+ submenuTop +'; height: '+submenuHeight+'; width: '+submenuWidth+'; visible: submenu'+ pli +'.visible ? true : tempvar ? true : false; hoverEnabled: submenu'+ pli +'.visible ? true : tempvar ? true : false; cursorShape: Qt.PointingHandCursor; onEntered: { tempvar = true; } onExited: { tempvar = false; '+ preLogicIt +' } onPositionChanged: { '+ logicIt +' } onClicked: { '+ clickIt +' } } Timer { interval: 300; running: tempvar; repeat: false; onTriggered: { if (!subcmitem'+ pli +'.containsMouse) tempvar = false; } } }', root, 'cmenustr' +pli); 159 | 160 | conArrows[pli] = Qt.createQmlObject('import QtQuick 2.1; import QtQuick.Layouts 1.0; import QmlVlc 0.1; Text { anchors.right: parent.right; anchors.rightMargin: 11; anchors.top: parent.top; anchors.topMargin: 10+ ('+ pli +' *30); text: settings.glyphsLoaded ? ui.icon.play : ""; font.family: fonts.icons.name; font.pointSize: 9; color: "#e5e5e5"; }', root, 'omenustr' +pli); 161 | pli++; 162 | } 163 | 164 | var plstring = "Crop"; 165 | var submenuIt = ""; 166 | var logicIt = ""; 167 | var clickIt = ""; 168 | var preLogicIt = ""; 169 | var selected = 0; 170 | 171 | var submenuHeight = (settings.crops.length *30) +2; 172 | if (submenuHeight < mousesurface.height) { 173 | 174 | var plsi = 0; 175 | for (plsi = 0; plsi < settings.crops.length; plsi++) { 176 | if (settings.crops[plsi] == settings.curCrop) selected = plsi *30; 177 | submenuIt += ' Rectangle { id: sbmenu'+ plsi +'; height: 30; width: 100; anchors.left: parent.left; anchors.leftMargin: 1; anchors.top: parent.top; anchors.topMargin: ('+ plsi +' * 30) +1; color: "transparent"; Text { anchors.left: parent.left; anchors.leftMargin: 15; anchors.top: parent.top; anchors.topMargin: 7; text: "'+ settings.crops[plsi] +'"; color: "#e5e5e5"; font.pointSize: 9 } } '; 178 | preLogicIt += ' sbmenu'+ plsi +'.color = "transparent"; '; 179 | } 180 | for (plsi = 0; plsi < settings.crops.length; plsi++) { 181 | if (logicIt != "") logicIt += ' else'; 182 | logicIt += ' if (iTmouseY > ('+ plsi +' *30) && iTmouseY < (('+ plsi +' +1) *30)) { if (sbmenu'+ plsi +'.color != "#3D3D3D") { '+ preLogicIt +' sbmenu'+ plsi +'.color = "#3D3D3D"; } } '; 183 | clickIt += ' if (iTmouseY > ('+ plsi +' *30) && iTmouseY < (('+ plsi +' +1) *30)) { settings.curCrop = "'+ settings.crops[plsi] +'"; if (settings.curCrop == "Default") { wjs.resetAspect(); } else { wjs.changeAspect(settings.curCrop,"crop"); } wjs.setText("Crop: " + settings.curCrop); selectedIt.anchors.topMargin = '+ plsi +' *30 +11; } '; 184 | } 185 | 186 | submenuIt += ' Text { id: selectedIt; anchors.left: parent.left; anchors.leftMargin: 5; anchors.top: parent.top; anchors.topMargin: '+ selected +' +11; text: ui.icon.closePlaylist; font.family: fonts.icons.name; color: "#e5e5e5"; font.pointSize: 6 } '; 187 | 188 | var submenuWidth = 102; 189 | var submenuTop = 0; 190 | var submenuLeft = 0; 191 | 192 | if (((pli *30) +submenuHeight) + root.anchors.topMargin > mousesurface.height) { 193 | submenuTop = (((pli *30) +submenuHeight) + root.anchors.topMargin - mousesurface.height) * (-1) -2; 194 | } else submenuTop = 0; 195 | 196 | if (rightPx < submenuWidth) { 197 | submenuLeft = (submenuWidth + root.width - 2) * (-1); 198 | } else submenuLeft = 0; 199 | 200 | conItems[pli] = Qt.createQmlObject('import QtQuick 2.1; import QtQuick.Layouts 1.0; import QmlVlc 0.1; Rectangle { property var iTmouseY: subcmitem'+ pli +'.mouseY; property var tempvar: false; id: ctxitem'+ pli +'; anchors.left: parent.left; anchors.leftMargin: 1; anchors.top: parent.top; anchors.topMargin: 1+ ('+ pli +' *30); color: "transparent"; width: root.width -2; height: 30; MouseArea { id: cmitem'+ pli +'; cursorShape: Qt.PointingHandCursor; hoverEnabled: true; anchors.fill: parent; onClicked: { } onExited: { tempvar = true; } } Rectangle { width: root.width -2; clip: true; height: 30; color: cmitem'+ pli +'.containsMouse ? "#3D3D3D" : "transparent"; Text { anchors.left: parent.left; anchors.leftMargin: 9; anchors.verticalCenter: parent.verticalCenter; text: "'+ plstring +'"; font.pointSize: 9; color: "#e5e5e5"; } } Rectangle { id: submenu'+ pli +'; visible: cmitem'+ pli +'.containsMouse ? true : subcmitem'+ pli +'.containsMouse ? true : false; anchors.left: parent.right; anchors.leftMargin: '+ submenuLeft +'; anchors.top: parent.top; anchors.topMargin: '+ submenuTop +'; border.color: root.border.color; border.width: 1; height: '+submenuHeight+'; width: '+submenuWidth+'; color: root.color; '+ submenuIt +' } MouseArea { id: subcmitem'+ pli +'; anchors.left: parent.right; anchors.leftMargin: '+ submenuLeft +'; anchors.top: parent.top; anchors.topMargin: '+ submenuTop +'; height: '+submenuHeight+'; width: '+submenuWidth+'; visible: submenu'+ pli +'.visible ? true : tempvar ? true : false; hoverEnabled: submenu'+ pli +'.visible ? true : tempvar ? true : false; cursorShape: Qt.PointingHandCursor; onEntered: { tempvar = true; } onExited: { tempvar = false; '+ preLogicIt +' } onPositionChanged: { '+ logicIt +' } onClicked: { '+ clickIt +' } } Timer { interval: 300; running: tempvar; repeat: false; onTriggered: { if (!subcmitem'+ pli +'.containsMouse) tempvar = false; } } }', root, 'cmenustr' +pli); 201 | 202 | conArrows[pli] = Qt.createQmlObject('import QtQuick 2.1; import QtQuick.Layouts 1.0; import QmlVlc 0.1; Text { anchors.right: parent.right; anchors.rightMargin: 11; anchors.top: parent.top; anchors.topMargin: 10+ ('+ pli +' *30); text: settings.glyphsLoaded ? ui.icon.play : ""; font.family: fonts.icons.name; font.pointSize: 9; color: "#e5e5e5"; }', root, 'omenustr' +pli); 203 | pli++; 204 | } 205 | 206 | var plstring = "Zoom"; 207 | var submenuIt = ""; 208 | var logicIt = ""; 209 | var clickIt = ""; 210 | var preLogicIt = ""; 211 | var selected = 0; 212 | 213 | var submenuHeight = (settings.zooms.length *30) +2; 214 | if (submenuHeight < mousesurface.height) { 215 | 216 | var plsi = 0; 217 | for (plsi = 0; plsi < settings.zooms.length; plsi++) { 218 | if (plsi == settings.curZoom) selected = plsi *30; 219 | submenuIt += ' Rectangle { id: sbmenu'+ plsi +'; height: 30; width: 100; anchors.left: parent.left; anchors.leftMargin: 1; anchors.top: parent.top; anchors.topMargin: ('+ plsi +' * 30) +1; color: "transparent"; Text { anchors.left: parent.left; anchors.leftMargin: 15; anchors.top: parent.top; anchors.topMargin: 7; text: "'+ settings.zooms[plsi][1] +'"; color: "#e5e5e5"; font.pointSize: 9 } } '; 220 | preLogicIt += ' sbmenu'+ plsi +'.color = "transparent"; '; 221 | } 222 | for (plsi = 0; plsi < settings.zooms.length; plsi++) { 223 | if (logicIt != "") logicIt += ' else'; 224 | logicIt += ' if (iTmouseY > ('+ plsi +' *30) && iTmouseY < (('+ plsi +' +1) *30)) { if (sbmenu'+ plsi +'.color != "#3D3D3D") { '+ preLogicIt +' sbmenu'+ plsi +'.color = "#3D3D3D"; } } '; 225 | clickIt += ' if (iTmouseY > ('+ plsi +' *30) && iTmouseY < (('+ plsi +' +1) *30)) { settings.curZoom = "'+ plsi +'"; wjs.changeZoom('+ settings.zooms[plsi][0] +'); wjs.setText("Zoom Mode: '+ settings.zooms[plsi][1] +'"); selectedIt.anchors.topMargin = '+ plsi +' *30 +11; } '; 226 | } 227 | 228 | submenuIt += ' Text { id: selectedIt; anchors.left: parent.left; anchors.leftMargin: 5; anchors.top: parent.top; anchors.topMargin: '+ selected +' +11; text: ui.icon.closePlaylist; font.family: fonts.icons.name; color: "#e5e5e5"; font.pointSize: 6 } '; 229 | 230 | var submenuWidth = 102; 231 | var submenuTop = 0; 232 | var submenuLeft = 0; 233 | 234 | if (((pli *30) +submenuHeight) + root.anchors.topMargin > mousesurface.height) { 235 | submenuTop = (((pli *30) +submenuHeight) + root.anchors.topMargin - mousesurface.height) * (-1) -2; 236 | } else submenuTop = 0; 237 | 238 | if (rightPx < submenuWidth) { 239 | submenuLeft = (submenuWidth + root.width - 2) * (-1); 240 | } else submenuLeft = 0; 241 | 242 | conItems[pli] = Qt.createQmlObject('import QtQuick 2.1; import QtQuick.Layouts 1.0; import QmlVlc 0.1; Rectangle { property var iTmouseY: subcmitem'+ pli +'.mouseY; property var tempvar: false; id: ctxitem'+ pli +'; anchors.left: parent.left; anchors.leftMargin: 1; anchors.top: parent.top; anchors.topMargin: 1+ ('+ pli +' *30); color: "transparent"; width: root.width -2; height: 30; MouseArea { id: cmitem'+ pli +'; cursorShape: Qt.PointingHandCursor; hoverEnabled: true; anchors.fill: parent; onClicked: { } onExited: { tempvar = true; } } Rectangle { width: root.width -2; clip: true; height: 30; color: cmitem'+ pli +'.containsMouse ? "#3D3D3D" : "transparent"; Text { anchors.left: parent.left; anchors.leftMargin: 9; anchors.verticalCenter: parent.verticalCenter; text: "'+ plstring +'"; font.pointSize: 9; color: "#e5e5e5"; } } Rectangle { id: submenu'+ pli +'; visible: cmitem'+ pli +'.containsMouse ? true : subcmitem'+ pli +'.containsMouse ? true : false; anchors.left: parent.right; anchors.leftMargin: '+ submenuLeft +'; anchors.top: parent.top; anchors.topMargin: '+ submenuTop +'; border.color: root.border.color; border.width: 1; height: '+submenuHeight+'; width: '+submenuWidth+'; color: root.color; '+ submenuIt +' } MouseArea { id: subcmitem'+ pli +'; anchors.left: parent.right; anchors.leftMargin: '+ submenuLeft +'; anchors.top: parent.top; anchors.topMargin: '+ submenuTop +'; height: '+submenuHeight+'; width: '+submenuWidth+'; visible: submenu'+ pli +'.visible ? true : tempvar ? true : false; hoverEnabled: submenu'+ pli +'.visible ? true : tempvar ? true : false; cursorShape: Qt.PointingHandCursor; onEntered: { tempvar = true; } onExited: { tempvar = false; '+ preLogicIt +' } onPositionChanged: { '+ logicIt +' } onClicked: { '+ clickIt +' } } Timer { interval: 300; running: tempvar; repeat: false; onTriggered: { if (!subcmitem'+ pli +'.containsMouse) tempvar = false; } } }', root, 'cmenustr' +pli); 243 | 244 | conArrows[pli] = Qt.createQmlObject('import QtQuick 2.1; import QtQuick.Layouts 1.0; import QmlVlc 0.1; Text { anchors.right: parent.right; anchors.rightMargin: 11; anchors.top: parent.top; anchors.topMargin: 10+ ('+ pli +' *30); text: settings.glyphsLoaded ? ui.icon.play : ""; font.family: fonts.icons.name; font.pointSize: 9; color: "#e5e5e5"; }', root, 'omenustr' +pli); 245 | pli++; 246 | } 247 | } 248 | 249 | if (settings.digitalzoom >= 1) { 250 | 251 | if (digiZoom.visible) { 252 | var plstring = "Hide Digital Zoom"; 253 | 254 | conItems[pli] = Qt.createQmlObject('import QtQuick 2.1; import QtQuick.Layouts 1.0; import QmlVlc 0.1; Rectangle { id: ctxitem'+ pli +'; anchors.left: parent.left; anchors.leftMargin: 1; anchors.top: parent.top; anchors.topMargin: 1+ ('+ pli +' *30); color: "transparent"; width: root.width -2; height: 30; MouseArea { id: cmitem'+ pli +'; cursorShape: Qt.PointingHandCursor; hoverEnabled: true; anchors.fill: parent; onClicked: { close(); settings.digiZoomClosed = true; settings = settings; } } Rectangle { width: root.width -2; clip: true; height: 30; color: cmitem'+ pli +'.containsMouse ? "#3D3D3D" : "transparent"; Text { anchors.left: parent.left; anchors.leftMargin: 9; anchors.verticalCenter: parent.verticalCenter; text: "'+ plstring +'"; font.pointSize: 9; color: "#e5e5e5"; } } }', root, 'cmenustr' +pli); 255 | 256 | 257 | pli++; 258 | } else { 259 | var plstring = "Show Digital Zoom"; 260 | 261 | conItems[pli] = Qt.createQmlObject('import QtQuick 2.1; import QtQuick.Layouts 1.0; import QmlVlc 0.1; Rectangle { id: ctxitem'+ pli +'; anchors.left: parent.left; anchors.leftMargin: 1; anchors.top: parent.top; anchors.topMargin: 1+ ('+ pli +' *30); color: "transparent"; width: root.width -2; height: 30; MouseArea { id: cmitem'+ pli +'; cursorShape: Qt.PointingHandCursor; hoverEnabled: true; anchors.fill: parent; onClicked: { close(); settings.digiZoomClosed = false; settings = settings; } } Rectangle { width: root.width -2; clip: true; height: 30; color: cmitem'+ pli +'.containsMouse ? "#3D3D3D" : "transparent"; Text { anchors.left: parent.left; anchors.leftMargin: 9; anchors.verticalCenter: parent.verticalCenter; text: "'+ plstring +'"; font.pointSize: 9; color: "#e5e5e5"; } } }', root, 'cmenustr' +pli); 262 | 263 | 264 | pli++; 265 | } 266 | 267 | } 268 | 269 | var plstring = "About WebChimera"; 270 | 271 | conItems[pli] = Qt.createQmlObject('import QtQuick 2.1; import QtQuick.Layouts 1.0; import QmlVlc 0.1; Rectangle { id: ctxitem'+ pli +'; anchors.left: parent.left; anchors.leftMargin: 1; anchors.top: parent.top; anchors.topMargin: 1+ ('+ pli +' *30); color: "transparent"; width: root.width -2; height: 30; MouseArea { id: cmitem'+ pli +'; cursorShape: Qt.PointingHandCursor; hoverEnabled: true; anchors.fill: parent; onClicked: { close(); goHome(); if (vlcPlayer.playing) vlcPlayer.togglePause(); } } Rectangle { width: root.width -2; clip: true; height: 30; color: cmitem'+ pli +'.containsMouse ? "#3D3D3D" : "transparent"; Text { anchors.left: parent.left; anchors.leftMargin: 9; anchors.verticalCenter: parent.verticalCenter; text: "'+ plstring +'"; font.pointSize: 9; color: "#e5e5e5"; } } }', root, 'cmenustr' +pli); 272 | 273 | 274 | pli++; 275 | totalCons = pli; 276 | 277 | // End Adding Context Menu Items 278 | } 279 | 280 | // This is where the Context Menu Items will be loaded 281 | } 282 | -------------------------------------------------------------------------------- /player/themes/sleek/components/DigitalZoom.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.1 2 | import QmlVlc 0.1 3 | 4 | // Digital Zoom Feature 5 | VlcVideoSurface { 6 | property alias preview: zoomPreview 7 | property alias mousepos: zoomArea 8 | 9 | property var zoomTop: 0; 10 | property var zoomLeft: 0; 11 | property var zoomHeight: 0; 12 | property var zoomWidth: 0; 13 | property var zoomVisible: false; 14 | property var hasMediaChanged: 1; 15 | property var zoomIsPressed: 0; 16 | property var lastMouseX: 0; 17 | property var lastMouseY: 0; 18 | 19 | function isFloat(n){ 20 | return n===Number(n) && n%1!==0 21 | } 22 | 23 | function zoomResetPosition() { 24 | if (vlcPlayer.video.width > 0 && vlcPlayer.video.height > 0) { 25 | var iW = vlcPlayer.video.width, 26 | iH = vlcPlayer.video.height, 27 | oW = theview.width, 28 | oH = theview.height; 29 | 30 | if (fullscreen) var zoomDiff = 4; else { if (theview.width < 700) var zoomDiff = 3; else var zoomDiff = 3.5; } 31 | if(oH/iH > oW/iW){ 32 | zoomTop = (oH - iH*(oW/iW)) /2; 33 | zoomLeft = 0; 34 | zoomHeight = iH*(oW/iW) / zoomDiff; 35 | zoomWidth = oW / zoomDiff; 36 | } else { 37 | zoomTop = 0; 38 | zoomLeft = (oW - iW*(oH/iH)) /2; 39 | zoomHeight = oH / zoomDiff; 40 | zoomWidth = iW*(oH/iH) / zoomDiff; 41 | } 42 | zoomVisible = true; 43 | } 44 | zoomPreview.width = root.width; 45 | zoomPreview.height = root.height; 46 | zoomPreview.anchors.leftMargin = 0; 47 | zoomPreview.anchors.topMargin = 0; 48 | } 49 | 50 | function zoomNewPosition() { 51 | if (settings.digitalzoom > 0) { 52 | var lastZoomWidth = zoomWidth; 53 | var lastZoomHeight = zoomHeight; 54 | 55 | if (vlcPlayer.video.width > 0 && vlcPlayer.video.height > 0) { 56 | var iW = vlcPlayer.video.width, 57 | iH = vlcPlayer.video.height, 58 | oW = theview.width, 59 | oH = theview.height; 60 | 61 | if (fullscreen) var zoomDiff = 4; else { if (theview.width < 700) var zoomDiff = 3; else var zoomDiff = 3.5; } 62 | if(oH/iH > oW/iW){ 63 | zoomTop = (oH - iH*(oW/iW)) /2; 64 | zoomLeft = 0; 65 | zoomHeight = iH*(oW/iW) / zoomDiff; 66 | zoomWidth = oW / zoomDiff; 67 | } else { 68 | zoomTop = 0; 69 | zoomLeft = (oW - iW*(oH/iH)) /2; 70 | zoomHeight = oH / zoomDiff; 71 | zoomWidth = iW*(oH/iH) / zoomDiff; 72 | } 73 | zoomPreview.width = zoomPreview.width / (lastZoomWidth / zoomWidth); 74 | zoomPreview.height = zoomPreview.height / (lastZoomHeight / zoomHeight); 75 | zoomPreview.anchors.leftMargin = zoomPreview.anchors.leftMargin / (lastZoomWidth / zoomWidth); 76 | zoomPreview.anchors.topMargin = zoomPreview.anchors.topMargin / (lastZoomHeight / zoomHeight); 77 | 78 | lastMouseX = zoomPreview.anchors.leftMargin + (zoomPreview.width /2); 79 | lastMouseY = zoomPreview.anchors.topMargin + (zoomPreview.height /2); 80 | 81 | videoSource.scale.origin.x = ((zoomPreview.anchors.leftMargin + (zoomPreview.width/2)) * (videoSource.width / root.width)) + ((videoSource.width * (((zoomPreview.anchors.leftMargin + (zoomPreview.width/2)) - (root.width /2)) / root.width))/settings.digitalzoom); 82 | videoSource.scale.origin.y = ((zoomPreview.anchors.topMargin + (zoomPreview.height/2)) * (videoSource.height / root.height)) + ((videoSource.height * (((zoomPreview.anchors.topMargin + (zoomPreview.height/2)) - (root.height /2)) / root.height))/settings.digitalzoom); 83 | 84 | if (videoSource.scale.origin.x > videoSource.width) videoSource.scale.origin.x = videoSource.width; 85 | if (videoSource.scale.origin.y > videoSource.height) videoSource.scale.origin.y = videoSource.height; 86 | 87 | if (videoSource.scale.origin.x < 0) videoSource.scale.origin.x = 0; 88 | if (videoSource.scale.origin.y < 0) videoSource.scale.origin.y = 0; 89 | 90 | zoomVisible = true; 91 | } 92 | } 93 | } 94 | 95 | function zoomClicked(clicked) { 96 | if (zoomIsPressed == 1) { 97 | if ((zoomPreview.width < root.width && zoomPreview.height < root.height) || (zoomPreview.height < root.height || zoomPreview.height < root.height)) { 98 | 99 | lastMouseX = zoomArea.mouseX; 100 | lastMouseY = zoomArea.mouseY; 101 | 102 | if (fullscreen) var zoomDiff = 4; else { if (theview.width < 700) var zoomDiff = 3; else var zoomDiff = 3.5; } 103 | 104 | var iW = vlcPlayer.video.width, 105 | iH = vlcPlayer.video.height, 106 | oW = theview.width, 107 | oH = theview.height; 108 | 109 | if(oH/iH > oW/iW){ 110 | var resizedHeight = iH*(oW/iW); 111 | var resizedWidth = oW; 112 | } else { 113 | var resizedHeight = oH; 114 | var resizedWidth = iW*(oH/iH); 115 | } 116 | 117 | if ((zoomArea.mouseX - (zoomPreview.width /2)) < 0) { 118 | zoomPreview.anchors.leftMargin = 0; 119 | } else if ((zoomArea.mouseX - (zoomPreview.width /2)) > (root.width - zoomPreview.width)) { 120 | zoomPreview.anchors.leftMargin = root.width - zoomPreview.width; 121 | } else { 122 | zoomPreview.anchors.leftMargin = zoomArea.mouseX - (zoomPreview.width /2); 123 | } 124 | if ((zoomArea.mouseY - (zoomPreview.height /2)) < 0) { 125 | zoomPreview.anchors.topMargin = 0; 126 | } else if ((zoomArea.mouseY - (zoomPreview.height /2)) > (root.height - zoomPreview.height)) { 127 | zoomPreview.anchors.topMargin = root.height - zoomPreview.height; 128 | } else { 129 | zoomPreview.anchors.topMargin = zoomArea.mouseY - (zoomPreview.height /2); 130 | } 131 | 132 | videoSource.scale.origin.x = ((zoomPreview.anchors.leftMargin + (zoomPreview.width/2)) * (videoSource.width / root.width)) + ((videoSource.width * (((zoomPreview.anchors.leftMargin + (zoomPreview.width/2)) - (root.width /2)) / root.width))/settings.digitalzoom); 133 | videoSource.scale.origin.y = ((zoomPreview.anchors.topMargin + (zoomPreview.height/2)) * (videoSource.height / root.height)) + ((videoSource.height * (((zoomPreview.anchors.topMargin + (zoomPreview.height/2)) - (root.height /2)) / root.height))/settings.digitalzoom); 134 | 135 | if (videoSource.scale.origin.x > videoSource.width) videoSource.scale.origin.x = videoSource.width; 136 | if (videoSource.scale.origin.y > videoSource.height) videoSource.scale.origin.y = videoSource.height; 137 | 138 | if (videoSource.scale.origin.x < 0) videoSource.scale.origin.x = 0; 139 | if (videoSource.scale.origin.y < 0) videoSource.scale.origin.y = 0; 140 | 141 | } 142 | } 143 | } 144 | 145 | function zoomScroll(mouseX,mouseY) { 146 | 147 | // Change Zoom on Mouse Scroll 148 | 149 | wjs.resetAspect(); 150 | 151 | var lastZoomWidth = zoomPreview.width; 152 | var lastZoomHeight = zoomPreview.height; 153 | var moveZoom = 0; 154 | 155 | if (mouseY > 0) { 156 | if (settings.digitalzoom >= 1 && settings.digitalzoom < 10) settings.digitalzoom = settings.digitalzoom + 0.5; 157 | if (settings.digitalzoom == 1.5) { 158 | 159 | videoSource.scale.origin.x = (zoomArea.mouseX * (videoSource.width / root.width)) + ((videoSource.width * ((zoomArea.mouseX - (root.width /2)) / root.width))/settings.digitalzoom); 160 | videoSource.scale.origin.y = (zoomArea.mouseY * (videoSource.height / root.height)) + ((videoSource.height * ((zoomArea.mouseY - (root.height /2)) / root.height))/settings.digitalzoom); 161 | 162 | lastMouseX = zoomArea.mouseX; 163 | lastMouseY = zoomArea.mouseY; 164 | 165 | moveZoom = 1; 166 | 167 | } else { 168 | videoSource.scale.origin.x = ((zoomPreview.anchors.leftMargin + (zoomPreview.width/2)) * (videoSource.width / root.width)) + ((videoSource.width * (((zoomPreview.anchors.leftMargin + (zoomPreview.width/2)) - (root.width /2)) / root.width))/settings.digitalzoom); 169 | videoSource.scale.origin.y = ((zoomPreview.anchors.topMargin + (zoomPreview.height/2)) * (videoSource.height / root.height)) + ((videoSource.height * (((zoomPreview.anchors.topMargin + (zoomPreview.height/2)) - (root.height /2)) / root.height))/settings.digitalzoom); 170 | } 171 | 172 | } else if (mouseY < 0) { 173 | if (settings.digitalzoom > 1 && settings.digitalzoom <= 10) { 174 | settings.digitalzoom = settings.digitalzoom - 0.5; 175 | videoSource.scale.origin.x = ((zoomPreview.anchors.leftMargin + (zoomPreview.width/2)) * (videoSource.width / root.width)) + ((videoSource.width * (((zoomPreview.anchors.leftMargin + (zoomPreview.width/2)) - (root.width /2)) / root.width))/settings.digitalzoom); 176 | videoSource.scale.origin.y = ((zoomPreview.anchors.topMargin + (zoomPreview.height/2)) * (videoSource.height / root.height)) + ((videoSource.height * (((zoomPreview.anchors.topMargin + (zoomPreview.height/2)) - (root.height /2)) / root.height))/settings.digitalzoom); 177 | } 178 | } 179 | 180 | if (settings.digitalzoom > 1 && settings.digitalzoom < 10) { 181 | 182 | if (theview.height/root.height > theview.width/root.width) { 183 | zoomPreview.width = root.width; 184 | zoomPreview.height = theview.height*(root.width/theview.width); 185 | } else { 186 | zoomPreview.height = root.height; 187 | zoomPreview.width = theview.width*(root.height/theview.height); 188 | } 189 | 190 | zoomPreview.width = zoomPreview.width / settings.digitalzoom; 191 | zoomPreview.height = zoomPreview.height / settings.digitalzoom; 192 | 193 | } 194 | 195 | if (settings.digitalzoom == 1) { 196 | videoSource.scale.origin.x = 1; 197 | videoSource.scale.origin.y = 1; 198 | zoomPreview.width = root.width; 199 | zoomPreview.height = root.height; 200 | zoomPreview.anchors.topMargin = 0; 201 | zoomPreview.anchors.leftMargin = 0; 202 | } 203 | 204 | if ((lastMouseX - (zoomPreview.width /2)) < 0) { 205 | zoomPreview.anchors.leftMargin = 0; 206 | } else if ((lastMouseX - (zoomPreview.width /2)) > (root.width - zoomPreview.width)) { 207 | zoomPreview.anchors.leftMargin = root.width - zoomPreview.width; 208 | } else { 209 | zoomPreview.anchors.leftMargin = lastMouseX - (zoomPreview.width /2); 210 | } 211 | if ((lastMouseY - (zoomPreview.height /2)) < 0) { 212 | zoomPreview.anchors.topMargin = 0; 213 | } else if ((lastMouseY - (zoomPreview.height /2)) > (root.height - zoomPreview.height)) { 214 | zoomPreview.anchors.topMargin = root.height - zoomPreview.height; 215 | } else { 216 | zoomPreview.anchors.topMargin = lastMouseY - (zoomPreview.height /2); 217 | } 218 | 219 | if (videoSource.scale.origin.x > videoSource.width) videoSource.scale.origin.x = videoSource.width; 220 | if (videoSource.scale.origin.y > videoSource.height) videoSource.scale.origin.y = videoSource.height; 221 | 222 | if (videoSource.scale.origin.x < 0) videoSource.scale.origin.x = 0; 223 | if (videoSource.scale.origin.y < 0) videoSource.scale.origin.y = 0; 224 | 225 | settings = settings; 226 | 227 | if (!isFloat(settings.digitalzoom)) wjs.setText("Digital Zoom: "+settings.digitalzoom+".0x"); 228 | else wjs.setText("Digital Zoom: "+settings.digitalzoom+"x"); 229 | 230 | // End Change Zoom on Mouse Scroll 231 | } 232 | 233 | id: root; 234 | visible: settings.digiZoomClosed ? false : settings.digitalzoom > 0 ? zoomVisible : false; 235 | source: vlcPlayer; 236 | anchors.top: parent.top; 237 | anchors.topMargin: zoomTop; 238 | anchors.left: parent.left; 239 | anchors.leftMargin: zoomLeft; 240 | width: zoomWidth; 241 | height: zoomHeight; 242 | fillMode: VlcVideoSurface.PreserveAspectFit 243 | 244 | Rectangle { 245 | id: zoomPreview 246 | color: "transparent" 247 | width: parent.width 248 | height: parent.height 249 | anchors.top: parent.top 250 | anchors.left: parent.left 251 | anchors.topMargin: 0 252 | anchors.leftMargin: 0 253 | border.width: 1 254 | border.color: "#ffffff" 255 | Connections { 256 | target: vlcPlayer 257 | onMediaPlayerMediaChanged: { 258 | if (settings.digitalzoom >= 1) { 259 | lastMouseX = 0; 260 | lastMouseY = 0; 261 | settings.digitalzoom = 1; 262 | zoomVisible = false; 263 | hasMediaChanged = 1; 264 | } 265 | } 266 | onMediaPlayerPlaying: { 267 | if (hasMediaChanged == 1 && settings.digitalzoom >= 1) { 268 | settings.digitalzoom = 1; 269 | settings = settings; 270 | hasMediaChanged = 0; 271 | digiZoom.zoomResetPosition(); 272 | } 273 | } 274 | } 275 | } 276 | 277 | MouseArea { 278 | id: zoomArea 279 | cursorShape: Qt.CrossCursor 280 | hoverEnabled: true 281 | anchors.fill: parent 282 | focus: true 283 | acceptedButtons: Qt.LeftButton 284 | onPressed: { zoomIsPressed = 1; zoomClicked(mouse.button); } 285 | onReleased: { zoomIsPressed = 0; zoomClicked(mouse.button); } 286 | onPositionChanged: zoomClicked(mouse.button); 287 | onWheel: zoomScroll(wheel.angleDelta.x,wheel.angleDelta.y); 288 | } 289 | } 290 | // End Digital Zoom Feature 291 | -------------------------------------------------------------------------------- /player/themes/sleek/components/Fonts.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.1 2 | 3 | Rectangle { 4 | property alias icons: glyphs 5 | property alias defaultFont: defaultFont 6 | property alias secondaryFont: defaultFont2 7 | 8 | FontLoader { 9 | id: glyphs 10 | source: "" 11 | } 12 | 13 | // onStatusChanged does not seem to work, so we add a timer to find out when the glyphicons have loaded 14 | Timer { 15 | interval: 0; running: glyphs.source != "" ? glyphs.status == FontLoader.Ready ? true : false : false; repeat: false 16 | onTriggered: { settings.glyphsLoaded = true; } 17 | } 18 | // End onStatusChanged does not seem to work, so we add a timer to find out when the glyphicons have loaded 19 | 20 | FontLoader { 21 | id: defaultFont 22 | source: "" 23 | } 24 | FontLoader { 25 | id: defaultFont2 26 | source: "" 27 | } 28 | } -------------------------------------------------------------------------------- /player/themes/sleek/components/Menu.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.1 2 | 3 | Rectangle { 4 | property alias background: menuBackground 5 | 6 | visible: false 7 | anchors.centerIn: parent 8 | width: (parent.width * 0.9) < 694 ? (parent.width * 0.9) : 694 9 | height: 284 10 | color: "transparent" 11 | Rectangle { 12 | id: menuBackground 13 | anchors.fill: parent 14 | } 15 | MouseArea { 16 | hoverEnabled: true 17 | anchors.fill: parent 18 | } 19 | } -------------------------------------------------------------------------------- /player/themes/sleek/components/MenuClose.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.1 2 | 3 | Rectangle { 4 | property alias icon: icon.text 5 | property alias iconSize: icon.font.pointSize 6 | property alias iconColor: icon.color 7 | property alias hover: mouseAreaClose 8 | 9 | anchors.right: parent.right 10 | anchors.rightMargin: 0 11 | width: 35 12 | height: 26 13 | color: mouseAreaClose.containsMouse ? "#232323" : "#2f2f2f"; 14 | Text { 15 | id: icon 16 | anchors.centerIn: parent 17 | font.family: fonts.icons.name 18 | color: mouseAreaClose.containsMouse ? "#eaeaea" : "#c0c0c0" 19 | } 20 | MouseArea { 21 | id: mouseAreaClose 22 | anchors.fill: parent 23 | cursorShape: Qt.PointingHandCursor 24 | hoverEnabled: true 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /player/themes/sleek/components/MenuContent.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.1 2 | 3 | Rectangle { 4 | anchors.centerIn: parent 5 | height: 272 6 | color: "transparent" 7 | clip: true 8 | } -------------------------------------------------------------------------------- /player/themes/sleek/components/MenuHeader.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.1 2 | 3 | Rectangle { 4 | property alias text: headerText.text 5 | property alias textColor: headerText.color 6 | property alias backgroundColor: headerBack.color 7 | 8 | anchors.fill: parent 9 | anchors.centerIn: parent 10 | width: parent.width 11 | height: 26 12 | color: "transparent" 13 | // Top "Title" text Holder 14 | Rectangle { 15 | id: headerBack 16 | width: parent.width -44 17 | anchors.left: parent.left 18 | 19 | anchors.leftMargin: 0 20 | height: 26 21 | Text { 22 | id: headerText 23 | anchors.verticalCenter: parent.verticalCenter 24 | anchors.left: parent.left 25 | anchors.leftMargin: 12 26 | font.pointSize: 10 27 | } 28 | MouseArea { hoverEnabled: true; anchors.fill: parent; } 29 | } 30 | // End Top "Title" text Holder 31 | } -------------------------------------------------------------------------------- /player/themes/sleek/components/MenuScroll.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.1 2 | import QmlVlc 0.1 3 | 4 | Rectangle { 5 | property alias draggerColor: playmdrag.color 6 | property alias backgroundColor: scrollerBack.color 7 | property alias dragger: playmdrag 8 | signal drag(string mouseY) 9 | 10 | id: root 11 | anchors.top: parent.top 12 | anchors.topMargin: 38 13 | anchors.right: parent.right 14 | anchors.rightMargin: 6 15 | width: 35 16 | height: 240 17 | color: "transparent" 18 | Rectangle { 19 | id: scrollerBack 20 | anchors.horizontalCenter: parent.horizontalCenter 21 | width: 10 22 | height: 240 23 | opacity: playmdrag.height == 240 ? 0.5 : 1 24 | } 25 | Rectangle { 26 | id: playmdrag 27 | anchors.top: parent.top 28 | anchors.topMargin: 0 29 | anchors.left: parent.left 30 | anchors.leftMargin: 13 31 | width: 10 32 | opacity: playmdrag.height == 240 ? 0 : 1 33 | } 34 | MouseArea { 35 | id: playmdragger 36 | anchors.fill: parent 37 | cursorShape: playmdrag.opacity == 1 ? Qt.PointingHandCursor : mousesurface.cursorShape 38 | onPressed: root.drag(mouse.y) 39 | onPressAndHold: root.drag(mouse.y) 40 | onPositionChanged: root.drag(mouse.y) 41 | onReleased: root.drag(mouse.y) 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /player/themes/sleek/components/MouseSurface.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.1 2 | import QmlVlc 0.1 3 | 4 | MouseArea { 5 | cursorShape: vlcPlayer.time == 0 ? Qt.ArrowCursor : fullscreen ? settings.ismoving > 5 ? Qt.BlankCursor : Qt.ArrowCursor : settings.multiscreen == 1 ? Qt.PointingHandCursor : Qt.ArrowCursor 6 | hoverEnabled: true 7 | anchors.fill: parent 8 | focus: true 9 | acceptedButtons: Qt.LeftButton | Qt.RightButton 10 | } -------------------------------------------------------------------------------- /player/themes/sleek/components/PIP.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.1 2 | import QmlVlc 0.1 3 | 4 | // Picture in Picture Feature 5 | VlcVideoSurface { 6 | property alias vSource: vlcPlayer2; 7 | property alias hover: pipHover; 8 | property alias closeBut: pipCloseBut; 9 | 10 | property var pipTop: 0; 11 | property var pipRight: 0; 12 | property var pipHeight: 0; 13 | property var pipWidth: 0; 14 | property var pipVisible: false; 15 | property var hasMediaChanged: 1; 16 | property var instantPipButEffect: 0; // for settings button 17 | 18 | function keepMuted() { 19 | if (!vlcPlayer2.audio.mute) vlcPlayer2.audio.mute = true; 20 | } 21 | 22 | function playPip(pipItem) { 23 | vlcPlayer2.playlist.clear(); 24 | for (var i = 0; i < vlcPlayer.playlist.itemCount; i++) vlcPlayer2.playlist.add(vlcPlayer.playlist.items[i].mrl); 25 | vlcPlayer2.playlist.playItem(pipItem); 26 | settings.pipClosed = false; 27 | } 28 | 29 | function pipResetPosition() { 30 | if (vlcPlayer.video.width > 0 && vlcPlayer.video.height > 0) { 31 | var iW = vlcPlayer2.video.width, 32 | iH = vlcPlayer2.video.height, 33 | iWc = vlcPlayer.video.width, 34 | iHc = vlcPlayer.video.height, 35 | oW = theview.width, 36 | oH = theview.height; 37 | 38 | if (fullscreen) var pipDiff = 4; else { if (theview.width < 700) var pipDiff = 3; else var pipDiff = 3.5; } 39 | 40 | if(oH/iHc > oW/iWc){ 41 | pipTop = (oH - iHc*(oW/iWc)) /2; 42 | pipRight = 0; 43 | } else { 44 | pipTop = 0; 45 | pipRight = (oW - iWc*(oH/iHc)) /2; 46 | } 47 | if(oH/iH > oW/iW){ 48 | pipHeight = iH*(oW/iW) / pipDiff; 49 | pipWidth = oW / pipDiff; 50 | } else { 51 | pipHeight = oH / pipDiff; 52 | pipWidth = iW*(oH/iH) / pipDiff; 53 | } 54 | pipVisible = true; 55 | } 56 | } 57 | 58 | function pipNewPosition() { 59 | 60 | if (settings.pip > 0) { 61 | var lastPipWidth = pipWidth; 62 | var lastPipHeight = pipHeight; 63 | 64 | if (vlcPlayer.video.width > 0 && vlcPlayer.video.height > 0) { 65 | var iW = vlcPlayer2.video.width, 66 | iH = vlcPlayer2.video.height, 67 | iWc = vlcPlayer.video.width, 68 | iHc = vlcPlayer.video.height, 69 | oW = theview.width, 70 | oH = theview.height; 71 | 72 | if (fullscreen) var pipDiff = 4; else { if (theview.width < 700) var pipDiff = 3; else var pipDiff = 3.5; } 73 | if(oH/iHc > oW/iWc){ 74 | pipTop = (oH - iHc*(oW/iWc)) /2; 75 | pipRight = 0; 76 | } else { 77 | pipTop = 0; 78 | pipRight = (oW - iWc*(oH/iHc)) /2; 79 | } 80 | if(oH/iH > oW/iW){ 81 | pipHeight = iH*(oW/iW) / pipDiff; 82 | pipWidth = oW / pipDiff; 83 | } else { 84 | pipHeight = oH / pipDiff; 85 | pipWidth = iW*(oH/iH) / pipDiff; 86 | } 87 | 88 | pipVisible = true; 89 | } 90 | } 91 | } 92 | 93 | function pipClicked() { 94 | // vlcPlayer.playlist.stop(); 95 | vlcPlayer.swap(vlcPlayer2); 96 | vlcPlayer.audio.mute = false; 97 | // settings.pipClosed = true; 98 | if (videoSource.source == vlcPlayer) { 99 | videoSource.source = vlcPlayer2; 100 | root.source = vlcPlayer; 101 | if (settings.digitalzoom > 0) digiZoom.source = vlcPlayer2; 102 | } else { 103 | videoSource.source = vlcPlayer; 104 | root.source = vlcPlayer2; 105 | if (settings.digitalzoom > 0) digiZoom.source = vlcPlayer; 106 | } 107 | wjs.onMediaChanged(); 108 | wjs.onState(); 109 | 110 | if (settings.refreshTime) settings.refreshTime = false; 111 | else settings.refreshTime = true; 112 | 113 | if (settings.refreshPlaylistItems) settings.refreshPlaylistItems = false; 114 | else settings.refreshPlaylistItems = true; 115 | 116 | settings = settings; 117 | if (settings.digitalzoom > 0) { 118 | settings.digitalzoom = 1; 119 | digiZoom.zoomResetPosition(); 120 | digiZoom.zoomNewPosition(); 121 | } 122 | pipResetPosition(); 123 | wjs.refreshMuteIcon(); 124 | } 125 | 126 | function pipClose() { 127 | vlcPlayer2.playlist.stop(); 128 | settings.pipClosed = true; 129 | } 130 | 131 | VlcPlayer { 132 | id: vlcPlayer2; 133 | } 134 | 135 | id: root; 136 | visible: settings.pipClosed ? false : settings.pip > 0 ? pipVisible : false; 137 | source: vlcPlayer2; 138 | anchors.top: parent.top; 139 | anchors.topMargin: pipTop; 140 | anchors.right: parent.right; 141 | anchors.rightMargin: pipRight; 142 | width: pipWidth; 143 | height: pipHeight; 144 | fillMode: VlcVideoSurface.PreserveAspectFit; 145 | 146 | Rectangle { 147 | color: "transparent" 148 | anchors.fill: parent 149 | Connections { 150 | target: vlcPlayer2 151 | onMediaPlayerMediaChanged: { 152 | if (settings.pip == 1) { 153 | pipVisible = false; 154 | hasMediaChanged = 1; 155 | } 156 | } 157 | onMediaPlayerPlaying: { 158 | if (hasMediaChanged == 1 && settings.pip == 1) { 159 | hasMediaChanged = 0; 160 | pipResetPosition(); 161 | } 162 | } 163 | } 164 | } 165 | 166 | MouseArea { 167 | id: pipHover 168 | cursorShape: Qt.PointingHandCursor 169 | hoverEnabled: true 170 | anchors.fill: parent 171 | focus: true 172 | acceptedButtons: Qt.LeftButton 173 | onPressed: { pipClicked(); } 174 | } 175 | 176 | Rectangle { 177 | visible: pipHover.containsMouse ? true : pipCloseBut.containsMouse ? true : false 178 | 179 | opacity: pipHover.containsMouse ? pipCloseBut.containsMouse ? 1 : 0.6 : pipCloseBut.containsMouse ? 1 : 0 180 | 181 | anchors.top: parent.top 182 | anchors.right: parent.right 183 | anchors.topMargin: 5 184 | anchors.rightMargin: 5 185 | color: "transparent" 186 | width: 20 187 | height: 20 188 | 189 | Behavior on visible { PropertyAnimation { duration: instantPipButEffect == 1 ? 0 : fullscreen ? 0: mousesurface.containsMouse ? 100 : 0 } } 190 | Behavior on opacity { PropertyAnimation { duration: instantPipButEffect == 1 ? 0 : fullscreen ? 0: 100 } } 191 | 192 | Text { 193 | anchors.centerIn: parent 194 | color: "#ffffff" 195 | text: settings.glyphsLoaded ? ui.icon.closePlaylist : "" 196 | font.family: fonts.icons.name 197 | font.pointSize: 14 198 | style: Text.Outline 199 | styleColor: "#000000" 200 | } 201 | MouseArea { 202 | id: pipCloseBut 203 | cursorShape: Qt.PointingHandCursor 204 | hoverEnabled: true 205 | anchors.fill: parent 206 | onClicked: pipClose(); 207 | } 208 | 209 | Timer { 210 | interval: 50; running: instantPipButEffect == 1 ? true : false; repeat: false 211 | onTriggered: { instantPipButEffect = 0; } 212 | } 213 | } 214 | } 215 | // End Picture in Picture Feature 216 | -------------------------------------------------------------------------------- /player/themes/sleek/components/PlaylistMenuItems.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.1 2 | import QmlVlc 0.1 3 | 4 | Rectangle { 5 | id: root 6 | anchors.top: parent.top 7 | anchors.topMargin: 0 8 | width: playlistblock.width < 694 ? (playlistblock.width -12) : 682 9 | height: 272 10 | color: "transparent" 11 | property var totalPlay: 0; 12 | property variant vplItems: []; 13 | 14 | function setYoutubeTitle(xhr,pli) { 15 | return function() { 16 | if (xhr.readyState == 4) { 17 | var plstring = xhr.responseText; 18 | plstring = plstring.substr(plstring.indexOf('"title":"')+9); 19 | plstring = plstring.substr(0,plstring.indexOf('"')); 20 | 21 | settings.titleCache[pli] = plstring; 22 | 23 | vlcPlayer.playlist.items[pli].title = "[custom]"+plstring; 24 | 25 | addPlaylistItems(); 26 | } 27 | }; 28 | } 29 | 30 | // Start Remove all Playlist Menu Items 31 | function clearAll() { 32 | var pli = 0; 33 | while (typeof vplItems[pli] !== 'undefined') { 34 | vplItems[pli].destroy(1); 35 | delete vplItems[pli]; 36 | pli++; 37 | } 38 | 39 | vplItems = []; 40 | totalPlay = 0; 41 | } 42 | // End Remove all Playlist Menu Items 43 | 44 | function addPlaylistItems() { 45 | // Remove Old Playlist Menu Items 46 | clearAll(); 47 | 48 | // Adding Playlist Menu Items 49 | var pli = 0; 50 | for (pli = 0; pli < vlcPlayer.playlist.itemCount; pli++) { 51 | var plstring = vlcPlayer.playlist.items[pli].title; 52 | 53 | if (plstring.indexOf("youtube.com") > 0) { 54 | var youtubeID = plstring.substr(plstring.lastIndexOf("/")+1).replace("watch?v=",""); 55 | if (youtubeID.indexOf("&") > 0) youtubeID = youtubeID.substr(0,youtubeID.IndexOf("&")); 56 | var xhr = new XMLHttpRequest; 57 | xhr.onreadystatechange = setYoutubeTitle(xhr,pli); 58 | xhr.open("get", 'http://gdata.youtube.com/feeds/api/videos/'+youtubeID+'?v=2&alt=jsonc', true); 59 | xhr.send(); 60 | } else { 61 | 62 | if (vlcPlayer.playlist.items[pli].title.indexOf("[custom]") == -1) { 63 | if (plstring.indexOf("http://") == 0) { 64 | // extract filename from url 65 | var tempPlstring = plstring.substring(plstring.lastIndexOf('/')+1); 66 | if (tempPlstring.length > 3) plstring = tempPlstring; 67 | delete tempPlstring; 68 | } 69 | if (plstring.indexOf(".") > -1) { 70 | // remove extension 71 | var tempPlstring = plstring.replace("."+plstring.split('.').pop(),""); 72 | if (tempPlstring.length > 3) plstring = tempPlstring; 73 | delete tempPlstring; 74 | } 75 | plstring = unescape(plstring); 76 | plstring = plstring.split('_').join(' '); 77 | plstring = plstring.split('.').join(' '); 78 | plstring = plstring.split(' ').join(' '); 79 | plstring = plstring.split(' ').join(' '); 80 | plstring = plstring.split(' ').join(' '); 81 | if (plstring != vlcPlayer.playlist.items[pli].title) vlcPlayer.playlist.items[pli].title = "[custom]"+plstring; 82 | } else { 83 | var plstring = vlcPlayer.playlist.items[pli].title.replace("[custom]",""); 84 | } 85 | 86 | if (plstring.indexOf("/") > 0) { 87 | plstring = unescape(plstring); 88 | plstring = plstring.substr(plstring.lastIndexOf("/")+1); 89 | } 90 | if (plstring.split('.').pop().length == 3) { 91 | plstring = plstring.slice(0, -4); 92 | vlcPlayer.playlist.items[pli].title = "[custom]"+plstring; 93 | } 94 | 95 | settings.titleCache[pli] = plstring; 96 | 97 | if (plstring.length > 85) plstring = plstring.substr(0,85) +'...'; 98 | 99 | vplItems[pli] = Qt.createQmlObject('import QtQuick 2.1; import QtQuick.Layouts 1.0; import QmlVlc 0.1; Rectangle { property var dragit: 0; property var mouseit: 0; id: itemBlock'+ pli +'; opacity: 1; anchors.left: parent.left; anchors.top: parent.top; anchors.topMargin: 32 + ('+ pli +' *40); color: "transparent"; width: playlistblock.width < 694 ? (playlistblock.width -56) : 638; height: 40; MouseArea { id: pitem'+ pli +'; cursorShape: dragit == 1 ? Qt.ClosedHandCursor : Qt.PointingHandCursor; hoverEnabled: true; anchors.fill: parent; onWheel: { openHand.opacity = 0; if (wheel.angleDelta.y > 0) wjs.movePlaylist(parseInt(playlistScroll.dragger.anchors.topMargin) + (parseInt(playlistScroll.dragger.height) /2) -5); if (wheel.angleDelta.y < 0) wjs.movePlaylist(parseInt(playlistScroll.dragger.anchors.topMargin) + (parseInt(playlistScroll.dragger.height) /2) +5); } onClicked: { vlcPlayer.playlist.playItem('+ pli +'); vlcPlayer.playlist.items['+ pli +'].disabled = false; plDot'+ pli +'.opacity = 1; itemBlock'+ pli +'.opacity = 1 } onPressAndHold: { dragit = 1; mouseit = mouse.y; itemBlock'+ pli +'.z = 100; itemBlock'+ pli +'.opacity = 0.7; itemShadow.anchors.topMargin = 32 + ('+ pli +' *40); itemShadow.visible = true } onPositionChanged: { if (dragit == 1) { itemBlock'+ pli +'.anchors.topMargin = itemBlock'+ pli +'.anchors.topMargin + mouse.y -mouseit; } } onReleased: { if (dragit == 1) { dragit = 0; var newid = Math.floor((itemBlock'+ pli +'.anchors.topMargin + mouse.y -32) / 40); if (newid > '+ pli +') { if (newid > vlcPlayer.playlist.itemCount -1) { var newcount = vlcPlayer.playlist.itemCount -1 - '+ pli +'; } else { var newcount = newid - '+ pli +'; } } else { if (newid < 0) { var newcount = '+ pli +' * (-1); } else { var newcount = ('+ pli +' - newid) * (-1); } } vlcPlayer.playlist.advanceItem('+ pli +',newcount); itemBlock'+ pli +'.z = 1; itemBlock'+ pli +'.opacity = 1; itemBlock'+ pli +'.parent.addPlaylistItems(); } itemShadow.visible = false } } Rectangle { id: backHover'+ pli +'; width: playlistblock.width < 694 ? (playlistblock.width -56) : 638; clip: true; height: 40; color: settings.refreshPlaylistItems ? vlcPlayer.playlist.currentItem == '+ pli +' ? pitem'+ pli +'.containsMouse || dragitem'+ pli +'.containsMouse || setIcon'+ pli +'.contains.Mouse ? "#3D3D3D" : "#e5e5e5" : pitem'+ pli +'.containsMouse || dragitem'+ pli +'.containsMouse || setIcon'+ pli +'.containsMouse || pipIcon'+ pli +'.containsMouse ? "#3D3D3D" : "transparent" : vlcPlayer.playlist.currentItem == '+ pli +' ? pitem'+ pli +'.containsMouse || dragitem'+ pli +'.containsMouse || setIcon'+ pli +'.containsMouse || pipIcon'+ pli +'.containsMouse ? "#3D3D3D" : "#e5e5e5" : pitem'+ pli +'.containsMouse || dragitem'+ pli +'.containsMouse || setIcon'+ pli +'.containsMouse || pipIcon'+ pli +'.containsMouse ? "#3D3D3D" : "transparent"; Text { id: plText'+ pli +'; anchors.left: parent.left; anchors.leftMargin: 42; anchors.verticalCenter: parent.verticalCenter; text: "'+ plstring +'"; font.pointSize: 10; color: settings.refreshPlaylistItems ? vlcPlayer.playlist.currentItem == '+ pli +' ? pitem'+ pli +'.containsMouse || dragitem'+ pli +'.containsMouse || setIcon'+ pli +'.containsMouse || pipIcon'+ pli +'.containsMouse ? "#e5e5e5" : "#2f2f2f" : pitem'+ pli +'.containsMouse || dragitem'+ pli +'.containsMouse || setIcon'+ pli +'.containsMouse || pipIcon'+ pli +'.containsMouse ? "#e5e5e5" : "#e5e5e5" : vlcPlayer.playlist.currentItem == '+ pli +' ? pitem'+ pli +'.containsMouse || dragitem'+ pli +'.containsMouse || setIcon'+ pli +'.containsMouse || pipIcon'+ pli +'.containsMouse ? "#e5e5e5" : "#2f2f2f" : pitem'+ pli +'.containsMouse || dragitem'+ pli +'.containsMouse || setIcon'+ pli +'.containsMouse || pipIcon'+ pli +'.containsMouse ? "#e5e5e5" : "#e5e5e5"; } } Rectangle { anchors.left: parent.left; anchors.verticalCenter: parent.verticalCenter; width:40; height: 40; color: "transparent"; Image { id: dragimg'+ pli +'; source: "../../../images/dragger.png"; anchors.left: parent.left; anchors.leftMargin: 3; anchors.verticalCenter: parent.verticalCenter; opacity: pitem'+ pli +'.containsMouse ? 1 : dragitem'+ pli +'.containsMouse ? 1 : 0 } MouseArea { id: dragitem'+ pli +'; anchors.fill: parent; cursorShape: dragit == 1 ? Qt.ClosedHandCursor : Qt.BlankCursor; hoverEnabled: true; onPressAndHold: { dragit = 1; openHand.opacity = 0; mouseit = mouse.y; itemBlock'+ pli +'.z = 100; itemBlock'+ pli +'.opacity = 0.7; itemShadow.anchors.topMargin = 32 + ('+ pli +' *40); itemShadow.visible = true } onReleased: { if (dragit == 1) { dragit = 0; var newid = Math.floor((itemBlock'+ pli +'.anchors.topMargin + mouse.y -32) / 40); if (newid > '+ pli +') { if (newid > vlcPlayer.playlist.itemCount -1) { var newcount = vlcPlayer.playlist.itemCount -1 - '+ pli +'; } else { var newcount = newid - '+ pli +'; } } else { if (newid < 0) { var newcount = '+ pli +' * (-1); } else { var newcount = ('+ pli +' - newid) * (-1); } } vlcPlayer.playlist.advanceItem('+ pli +',newcount); itemBlock'+ pli +'.z = 1; itemBlock'+ pli +'.opacity = 1; itemBlock'+ pli +'.parent.addPlaylistItems(); } itemShadow.visible = false } onPositionChanged: { if (dragit == 1) { openHand.opacity = 0; itemBlock'+ pli +'.anchors.topMargin = itemBlock'+ pli +'.anchors.topMargin + mouse.y -mouseit; } else { if (mouse.x > 40) { openHand.opacity = 0 } else { openHand.anchors.topMargin = mouse.y -4; openHand.anchors.leftMargin = mouse.x -8; openHand.opacity = 1 } } } onEntered: { openHand.anchors.top = itemBlock'+ pli +'.top; openHand.anchors.left = itemBlock'+ pli +'.left; openHand.anchors.topMargin = dragitem'+ pli +'.mouseY -4; openHand.anchors.leftMargin = dragitem'+ pli +'.mouseX -8; openHand.opacity = 1 } onExited: { openHand.opacity = 0 } onWheel: { openHand.opacity = 0; if (wheel.angleDelta.y > 0) wjs.movePlaylist(parseInt(playlistScroll.dragger.anchors.topMargin) + (parseInt(playlistScroll.dragger.height) /2) -5); if (wheel.angleDelta.y < 0) wjs.movePlaylist(parseInt(playlistScroll.dragger.anchors.topMargin) + (parseInt(playlistScroll.dragger.height) /2) +5); } onClicked: { if (vlcPlayer.playlist.items['+ pli +'].disabled) { vlcPlayer.playlist.items['+ pli +'].disabled = false; plDot'+ pli +'.opacity = 1; itemBlock'+ pli +'.opacity = 1 } else { vlcPlayer.playlist.items['+ pli +'].disabled = true; plDot'+ pli +'.opacity = 0; itemBlock'+ pli +'.opacity = 0.5 } } } Rectangle { anchors.verticalCenter: parent.verticalCenter; anchors.left: parent.left; anchors.leftMargin: 17; width: 14; height: 14; radius: width /2; color: "#131313"; Rectangle { id: plDot'+ pli +'; opacity: 1; anchors.verticalCenter: parent.verticalCenter; anchors.horizontalCenter: parent.horizontalCenter; width: 8; height: 8; radius: width /2; color: backHover'+ pli +'.color == "#e5e5e5" ? "#e5e5e5" : "#696969" } } } Rectangle { visible: settings.pip == 1 ? true : false; anchors.top: parent.top; anchors.right: setButPl'+ pli +'.visible ? setButPl'+ pli +'.left : parent.right; anchors.verticalCenter: parent.verticalCenter; height: parent.height; width: parent.height; color: parent.color; Text { anchors.centerIn: parent; font.family: fonts.icons.name; text: settings.glyphsLoaded ? ui.icon.pip : ""; font.pointSize: 15; opacity: pipIcon'+ pli +'.containsMouse ? 1 : backHover'+ pli +'.color == "#e5e5e5" ? 1 : 0.8; color: pipIcon'+ pli +'.containsMouse ? "#ffffff" : plText'+ pli +'.color } MouseArea { id: pipIcon'+ pli +'; cursorShape: Qt.PointingHandCursor; hoverEnabled: true; anchors.fill: parent; onClicked: { pip.playPip('+ pli +'); } } } Rectangle { id: setButPl'+ pli +'; visible: settings.debugPlaylist ? true : false; anchors.top: parent.top; anchors.right: parent.right; anchors.verticalCenter: parent.verticalCenter; height: parent.height; width: parent.height; color: parent.color; Text { anchors.centerIn: parent; font.family: fonts.icons.name; text: settings.glyphsLoaded ? ui.icon.settings : ""; font.pointSize: 15; opacity: setIcon'+ pli +'.containsMouse || pipIcon'+ pli +'.containsMouse ? 1 : backHover'+ pli +'.color == "#e5e5e5" ? 1 : 0.8; color: setIcon'+ pli +'.containsMouse || pipIcon'+ pli +'.containsMouse ? "#ffffff" : plText'+ pli +'.color } MouseArea { id: setIcon'+ pli +'; cursorShape: Qt.PointingHandCursor; hoverEnabled: true; anchors.fill: parent; onClicked: { if (inputAddBox.visible) { inputAddBox.visible = false; } settings.selectedItem = '+ pli +'; inputBox.textBox.text = vlcPlayer.playlist.items['+pli+'].mrl; inputBox.textBox.selectAll(); inputBox.visible = true; inputBox.textBox.forceActiveFocus(); } } } }', root, 'plmenustr' +pli); 100 | 101 | } 102 | } 103 | // End Adding Playlist Menu Items 104 | totalPlay = pli; 105 | } 106 | Rectangle { 107 | id: itemShadow 108 | color: "#000000" 109 | anchors.top: parent.top 110 | anchors.left: parent.left 111 | width: playlistblock.width < 694 ? (playlistblock.width -56) : 638 112 | height: 40 113 | z: 99 114 | opacity: 0.2 115 | visible: false 116 | } 117 | // hack for wrong open hand cursor (qt 5.4 bug) 118 | Image { 119 | id: openHand 120 | visible: platform == "OSX" ? false : true 121 | source: "../../../images/cursor-openhand.png" 122 | z: 101 123 | opacity: 0 124 | } 125 | // end hack for wrong open hand cursor (qt 5.4 bug) 126 | // This is where the Playlist Items will be loaded 127 | } 128 | -------------------------------------------------------------------------------- /player/themes/sleek/components/ProgressBar.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.1 2 | import QtQuick.Layouts 1.0 3 | import QmlVlc 0.1 4 | import QtGraphicalEffects 1.0 5 | 6 | Rectangle { 7 | property alias backgroundColor: progressBackground.color 8 | property alias viewedColor: movepos.color 9 | property alias positionColor: curpos.color 10 | property alias dragpos: dragpos 11 | property alias effectDuration: effect.duration 12 | property alias cache: cache 13 | signal pressed(string mouseX, string mouseY) 14 | signal changed(string mouseX, string mouseY) 15 | signal released(string mouseX, string mouseY) 16 | 17 | id: root 18 | anchors.fill: parent 19 | color: "transparent" 20 | visible: settings.uiVisible == 0 ? false : settings.toolbar == 0 ? false : true 21 | 22 | property var checkWheel: false; 23 | property var lastTimestamp: 0; 24 | property var lastCalc: 0; 25 | 26 | RowLayout { 27 | id: rowLayer 28 | anchors.left: parent.left 29 | anchors.right: parent.right 30 | anchors.bottom: parent.bottom 31 | anchors.bottomMargin: settings.multiscreen == 1 ? fullscreen ? 32 : -8 : fullscreen ? 32 : mousesurface.containsMouse ? 30 : 0 // Multiscreen - Edit 32 | opacity: settings.multiscreen == 1 ? fullscreen ? settings.ismoving > 5 ? 0 : 1 : 0 : fullscreen ? settings.ismoving > 5 ? 0 : 1 : 1 // Multiscreen - Edit 33 | Behavior on anchors.bottomMargin { 34 | PropertyAnimation { 35 | id: effect 36 | duration: settings.multiscreen == 0 ? 250 : 0 37 | } 38 | } 39 | Behavior on opacity { PropertyAnimation { duration: settings.multiscreen == 1 ? fullscreen ? 250 : 0 : 250 } } 40 | 41 | // Start Progress Bar Functionality (Time Chat Bubble, Seek) 42 | MouseArea { 43 | id: dragpos 44 | cursorShape: toolbar.opacity == 1 ? Qt.PointingHandCursor : mousesurface.cursorShape 45 | hoverEnabled: true 46 | anchors.fill: parent 47 | onPressed: root.pressed(mouse.x,mouse.y); 48 | onPositionChanged: root.changed(mouse.x,mouse.y); 49 | onReleased: root.released(mouse.x,mouse.y); 50 | onWheel: { 51 | settings.newProgress = (vlcPlayer.time + lastCalc) / wjs.getLength(); 52 | settings = settings; 53 | if (vlcPlayer.playing) vlcPlayer.togglePause(); 54 | lastTimestamp = Date.now(); 55 | checkWheel = true; 56 | if (wjs.getLength() > 0) var newDif = Math.floor(wjs.getLength() /100); 57 | else var newDif = 30000; 58 | 59 | if (wheel.angleDelta.y > 0) lastCalc = lastCalc +newDif; 60 | if (wheel.angleDelta.y < 0) lastCalc = lastCalc + (newDif * (-1)); 61 | 62 | } 63 | } 64 | Timer { 65 | interval: 1010; running: checkWheel ? true : false; repeat: true 66 | onTriggered: { 67 | if (lastTimestamp + 1000 < Date.now()) { 68 | checkWheel = false; 69 | if (!vlcPlayer.playing) vlcPlayer.togglePause(); 70 | vlcPlayer.time = wjs.getLength() * settings.newProgress; 71 | lastCalc = 0; 72 | } 73 | } 74 | } 75 | Rectangle { 76 | id: progressBackground 77 | anchors.left: parent.left 78 | anchors.right: parent.right 79 | height: 8 80 | anchors.verticalCenter: parent.verticalCenter 81 | Rectangle { 82 | id: cache 83 | visible: false 84 | height: 8 85 | anchors.left: parent.left 86 | anchors.bottom: parent.bottom 87 | color: "#3E3E3E" 88 | width: settings.downloaded > 0 ? vlcPlayer.state == 3 || vlcPlayer.state == 4 ? parent.width * settings.downloaded : 0 : vlcPlayer.state <= 1 ? 0 : settings.dragging ? 0 : ((parent.width - anchors.leftMargin - anchors.rightMargin) * settings.newProgress) + ((parent.width - anchors.leftMargin - anchors.rightMargin) * ((settings.cache / ((vlcPlayer.time * (1 / settings.newProgress)) /100)) /100) /100 * settings.buffering) 89 | // Behavior on width { PropertyAnimation { duration: settings.dragging ? 0 : vlcPlayer.time - lastTime > 0 ? vlcPlayer.time - lastTime : 0 } } 90 | } 91 | Rectangle { 92 | id: movepos 93 | width: vlcPlayer.state <= 1 ? 0 : settings.dragging ? dragpos.mouseX -4 : (parent.width - anchors.leftMargin - anchors.rightMargin) * settings.newProgress 94 | anchors.top: parent.top 95 | anchors.left: parent.left 96 | anchors.bottom: parent.bottom 97 | // Behavior on width { PropertyAnimation { duration: settings.dragging ? 0 : vlcPlayer.time - lastTime > 0 ? vlcPlayer.time - lastTime : 0 } } 98 | } 99 | } 100 | // End Progress Bar Functionality (Time Chat Bubble, Seek) 101 | } 102 | RowLayout { 103 | id: movecur 104 | spacing: 0 105 | anchors.left: parent.left 106 | anchors.right: parent.right 107 | anchors.bottom: parent.bottom 108 | anchors.leftMargin: vlcPlayer.state <= 1 ? 0 : settings.dragging ? dragpos.mouseX -4 > 0 ? dragpos.mouseX < parent.width -4 ? dragpos.mouseX -4 : parent.width -8 : 0 : (parent.width - anchors.rightMargin) * settings.newProgress > 0 ? (parent.width - anchors.rightMargin) * settings.newProgress < parent.width -8 ? (parent.width - anchors.rightMargin) * settings.newProgress : parent.width -8 : 0 109 | 110 | // Start Multiscreen - Edit 111 | anchors.bottomMargin: settings.multiscreen == 1 ? fullscreen ? toolbar.height : -16 : fullscreen ? toolbar.height : mousesurface.containsMouse ? toolbar.height : 0 112 | opacity: settings.multiscreen == 1 ? fullscreen ? settings.ismoving > 5 ? 0 : 1 : 0 : fullscreen ? settings.ismoving > 5 ? 0 : 1 : 1 113 | // End Multiscreen - Edit 114 | 115 | // Behavior on anchors.leftMargin { PropertyAnimation { duration: settings.dragging ? 0 : vlcPlayer.time - lastTime > 0 ? vlcPlayer.time - lastTime : 0 } } 116 | Behavior on anchors.bottomMargin { PropertyAnimation { duration: settings.multiscreen == 1 ? 0 : 250 } } 117 | Behavior on opacity { PropertyAnimation { duration: 250 } } 118 | Rectangle { 119 | Layout.fillWidth: true 120 | height: 8 121 | color: 'transparent' 122 | anchors.verticalCenter: parent.verticalCenter 123 | Rectangle { 124 | id: shadowEffect 125 | color: fullscreen ? Qt.rgba(0, 0, 0, 0.3) : mousesurface.containsMouse ? Qt.rgba(0, 0, 0, 0.3) : Qt.rgba(0, 0, 0, 0.2) 126 | height: fullscreen ? 16 : mousesurface.containsMouse ? 16 : 10 127 | width: fullscreen ? 16 : mousesurface.containsMouse ? 16 : 10 128 | radius: width == 10 ? 0 : width * 0.5 129 | anchors.bottom: parent.bottom 130 | anchors.bottomMargin: fullscreen ? -4 : mousesurface.containsMouse ? -4 : -2 131 | anchors.left: parent.left 132 | anchors.leftMargin: fullscreen ? -4 : mousesurface.containsMouse ? -4 : -1 133 | Behavior on anchors.bottomMargin { PropertyAnimation { duration: 250 } } 134 | Behavior on anchors.leftMargin { PropertyAnimation { duration: 250 } } 135 | Behavior on width { PropertyAnimation { duration: 250 } } 136 | Behavior on height { PropertyAnimation { duration: 250 } } 137 | Behavior on color { PropertyAnimation { duration: 250 } } 138 | } 139 | Rectangle { 140 | id: curpos 141 | height: fullscreen ? 14 : mousesurface.containsMouse ? 14 : 8 142 | width: fullscreen ? 14 : mousesurface.containsMouse ? 14 : 8 143 | radius: width == 8 ? 0 : width * 0.5 144 | anchors.bottom: parent.bottom 145 | anchors.bottomMargin: fullscreen ? -3 : mousesurface.containsMouse ? -3 : 0 146 | anchors.left: parent.left 147 | anchors.leftMargin: fullscreen ? -3 : mousesurface.containsMouse ? -3 : 0 148 | Behavior on anchors.bottomMargin { PropertyAnimation { duration: 250 } } 149 | Behavior on anchors.leftMargin { PropertyAnimation { duration: 250 } } 150 | Behavior on width { PropertyAnimation { duration: 250 } } 151 | Behavior on height { PropertyAnimation { duration: 250 } } 152 | Rectangle { 153 | height: fullscreen ? 6 : mousesurface.containsMouse ? 6 : 0 154 | width: fullscreen ? 6 : mousesurface.containsMouse ? 6 : 0 155 | radius: width * 0.5 156 | anchors.centerIn: parent 157 | color: cache.visible ? settings.dragging ? movepos.color : dragpos.containsMouse ? movepos.width -3 < dragpos.mouseX && dragpos.mouseX < movepos.width + 11 ? movepos.color : cache.color : cache.color : settings.dragging ? movepos.color : dragpos.containsMouse ? movepos.width -3 < dragpos.mouseX && dragpos.mouseX < movepos.width + 11 ? movepos.color : progressBackground.color : progressBackground.color 158 | Behavior on width { PropertyAnimation { duration: 250 } } 159 | Behavior on height { PropertyAnimation { duration: 250 } } 160 | } 161 | } 162 | } 163 | } 164 | } -------------------------------------------------------------------------------- /player/themes/sleek/components/ReplaceMRL.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.1 2 | import QtQuick.Controls 1.1 3 | import QtQuick.Layouts 1.0 4 | import QtQuick.Controls.Styles 1.1 5 | import QmlVlc 0.1 6 | 7 | Rectangle { 8 | property alias textBox: newURL 9 | 10 | visible: false 11 | anchors.centerIn: parent 12 | width: fullscreen ? 450 : (parent.width * 0.9) < 394 ? (parent.width * 0.9) : 394 13 | height: 80 14 | color: "transparent" 15 | focus: true 16 | 17 | MouseArea { 18 | hoverEnabled: true 19 | anchors.fill: parent 20 | } 21 | Rectangle { 22 | height: 30 23 | width: parent.width - 20 24 | anchors.top: parent.top 25 | anchors.horizontalCenter: parent.horizontalCenter 26 | color: "transparent" 27 | Text { 28 | text: "Replace Media URL" 29 | font.weight: Font.DemiBold 30 | font.pointSize: 10 31 | anchors.verticalCenter: parent.verticalCenter 32 | color: "#e5e5e5" 33 | } 34 | Rectangle { 35 | height: 20 36 | width: 20 37 | anchors.right: parent.right 38 | anchors.verticalCenter: parent.verticalCenter 39 | color: "transparent" 40 | Text { 41 | font.pointSize: 10 42 | color: urlClose.containsMouse ? ui.colors.playlistMenu.closeHover : ui.colors.playlistMenu.close 43 | anchors.right: parent.right 44 | anchors.verticalCenter: parent.verticalCenter 45 | font.family: fonts.icons.name 46 | text: settings.glyphsLoaded ? ui.icon.closePlaylist : "" 47 | } 48 | MouseArea { 49 | id: urlClose 50 | cursorShape: Qt.PointingHandCursor 51 | hoverEnabled: true 52 | anchors.fill: parent 53 | onClicked: { 54 | mousesurface.forceActiveFocus(); 55 | inputBox.visible = false; 56 | } 57 | } 58 | } 59 | } 60 | 61 | TextField { 62 | id: newURL 63 | readOnly: false 64 | placeholderText: "Media URL" 65 | width: (parent.width - 20) * 0.8 66 | height: parent.height - 40 67 | anchors.left: parent.left 68 | anchors.leftMargin: 10 69 | anchors.bottom: parent.bottom 70 | anchors.bottomMargin: 10 71 | style: TextFieldStyle { 72 | font.pixelSize: 14 73 | background: Rectangle { 74 | radius: 0 75 | color: "#e5e5e5" 76 | anchors.fill: parent 77 | } 78 | } 79 | Keys.onReturnPressed: { 80 | mousesurface.forceActiveFocus(); 81 | inputBox.visible = false; 82 | fireQmlMessage("[replace]"+settings.selectedItem+"[-|-]"+newURL.text); 83 | } 84 | Keys.onEscapePressed: { 85 | mousesurface.forceActiveFocus(); 86 | inputBox.visible = false; 87 | } 88 | Keys.onPressed: { 89 | if(event.modifiers == Qt.ControlModifier) { 90 | if (event.key == Qt.Key_A) { 91 | if (typeof settings.preventKey[Qt.ControlModifier+"+"+Qt.Key_A] === "undefined") { 92 | if (settings.debugPlaylist) { 93 | if (inputBox.visible) inputBox.visible = false 94 | inputAddBox.textBox.text = ""; 95 | inputAddBox.visible = true; 96 | inputAddBox.textBox.forceActiveFocus(); 97 | return; 98 | } 99 | } 100 | } 101 | } 102 | } 103 | } 104 | Rectangle { 105 | width: (parent.width - 20) * 0.2 106 | height: parent.height - 40 107 | anchors.right: parent.right 108 | anchors.rightMargin: 10 109 | anchors.bottom: parent.bottom 110 | anchors.bottomMargin: 10 111 | color: submitButton.containsMouse ? "#3D3D3D" : "#363636" 112 | Text { 113 | anchors.centerIn: parent 114 | text: "Save" 115 | font.pointSize: 12 116 | color: "#e5e5e5" 117 | } 118 | MouseArea { 119 | id: submitButton 120 | cursorShape: Qt.PointingHandCursor 121 | hoverEnabled: true 122 | anchors.fill: parent 123 | onClicked: { 124 | mousesurface.forceActiveFocus(); 125 | inputBox.visible = false; 126 | fireQmlMessage("[replace]"+settings.selectedItem+"[-|-]"+newURL.text); 127 | } 128 | } 129 | } 130 | } -------------------------------------------------------------------------------- /player/themes/sleek/components/SplashScreen.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.1 2 | import QmlVlc 0.1 3 | 4 | Rectangle { 5 | property alias fontColor: openingtext.color 6 | property alias fontShadow: loadingFont.styleColor 7 | property alias iconOpacity: playerlogo.opacity 8 | property alias changeText: loadingFont.text 9 | signal logoEffect 10 | 11 | id: root 12 | anchors.fill: parent 13 | visible: vlcPlayer.state < 3 ? true : false 14 | // If Playlist is Open Show Top Text 15 | Text { 16 | id: openingtext 17 | visible: playlistblock.visible === true || subMenublock.visible === true ? true : false 18 | anchors.top: parent.top 19 | anchors.topMargin: 10 20 | anchors.horizontalCenter: parent.horizontalCenter 21 | text: "Opening" 22 | font.pointSize: 15 23 | } 24 | // End If Playlist is Open Show Top Text 25 | 26 | Rectangle { 27 | anchors.centerIn: parent 28 | width: 1 29 | height: settings.multiscreen == 1 ? fullscreen ? 100 : 76 : 100 // Required for Multiscreen 30 | color: "transparent" 31 | Rectangle { 32 | Image { 33 | anchors.top: parent.top 34 | anchors.horizontalCenter: parent.horizontalCenter 35 | source: "http://webchimera.org/images/player/player_logo_small.png" 36 | } 37 | Image { 38 | id: playerlogo 39 | anchors.top: parent.top 40 | anchors.horizontalCenter: parent.horizontalCenter 41 | opacity: 0 42 | Behavior on opacity { PropertyAnimation { duration: 600} } 43 | source: "http://webchimera.org/images/player/player_logo_small_h.png" 44 | } 45 | Text { 46 | id: loadingFont 47 | visible: settings.multiscreen == 1 ? fullscreen ? vlcPlayer.state == 1 || vlcPlayer.state == 0 ? true : settings.buffering > 0 && settings.buffering < 100 ? true : false : false : vlcPlayer.state == 1 || vlcPlayer.state == 0 ? true : settings.buffering > 0 && settings.buffering < 100 ? true : false // Required for Multiscreen 48 | anchors.top: parent.top 49 | anchors.topMargin: 80 50 | anchors.horizontalCenter: parent.horizontalCenter 51 | text: settings.openingText 52 | font.pointSize: fullscreen ? 14 : 13 53 | font.weight: Font.DemiBold 54 | color: openingtext.color 55 | style: Text.Outline 56 | styleColor: UI.colors.fontShadow 57 | } 58 | // Start Loading Logo Fade Effect 59 | Timer { 60 | interval: 700; running: true; repeat: true 61 | onTriggered: root.logoEffect(); 62 | } 63 | // End Loading Logo Fade Effect 64 | } 65 | } 66 | } -------------------------------------------------------------------------------- /player/themes/sleek/components/SubtitleMenuItems.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.1 2 | import QmlVlc 0.1 3 | 4 | Rectangle { 5 | id: root 6 | anchors.top: parent.top 7 | anchors.topMargin: 0 8 | width: subMenublock.width < 694 ? (subMenublock.width -12) : 682 9 | height: 272 10 | color: "transparent" 11 | property var subPlaying: 0; 12 | 13 | property var currentSubtitle: -2; 14 | property var subtitles: []; 15 | 16 | property variant subItems: []; 17 | 18 | property var subVersion: 1; 19 | 20 | // Start Toggle Subtitle Menu (open/close) 21 | function toggleSubtitles() { 22 | if (!subMenublock.visible) { 23 | if (playlistblock.visible) playlistblock.visible = false; 24 | subMenublock.visible = true; 25 | } else subMenublock.visible = false; 26 | } 27 | // End Toggle Subtitle Menu (open/close) 28 | 29 | // Start External Subtitles (SRT, SUB) 30 | 31 | // Start Convert Time to Seconds (needed for External Subtitles) [part of old subtitle implementation] 32 | function toSeconds(t) { 33 | var s = 0.0 34 | if (t) { 35 | var p = t.split(':'); 36 | var i = 0; 37 | for (i=0;i=2) { 73 | if (st[0].split(' --> ')[0]) if (st[0].split(' --> ')[1]) { 74 | var is = Math.round(toSeconds(wjs.strip(st[0].split(' --> ')[0]))); 75 | var os = Math.round(toSeconds(wjs.strip(st[0].split(' --> ')[1]))); 76 | var t = st[2]; 77 | if( st.length > 2) { 78 | var j = 3; 79 | for (j=3; j=2) { 89 | var n = st[0]; 90 | if (st[1].split(' --> ')[0]) if (st[1].split(' --> ')[1]) { 91 | var is = Math.round(toSeconds(wjs.strip(st[1].split(' --> ')[0]))); 92 | var os = Math.round(toSeconds(wjs.strip(st[1].split(' --> ')[1]))); 93 | var t = st[2]; 94 | if( st.length > 2) { 95 | var j = 3; 96 | for (j=3; j=2) { 113 | var is = Math.round(st[0].substr(1) /10); 114 | var os = Math.round(st[1].split('}')[0] /10); 115 | var t = st[1].split('}')[1].replace('|', '\n'); 116 | if (is != 1 && os != 1) subtitles[is] = {i:is, o: os, t: t}; 117 | } 118 | } 119 | } 120 | currentSubtitle = -1; 121 | } 122 | } 123 | if (subtitleElement.indexOf("http://dl.opensubtitles.org/") == 0) subtitleElement = "http://dl.opensubtitles.org/en/download/subencoding-utf8/file/"+subtitleElement.split('/').pop(); 124 | xhr.open("get", subtitleElement); 125 | xhr.send(); 126 | } 127 | } 128 | // End External Subtitles (SRT, SUB) 129 | 130 | // External Subtitle Error Handler [part of new subtitle implementation] 131 | function subtitleError() { 132 | wjs.setText("Subtitle Error"); 133 | } 134 | // End External Subtitle Error Handler 135 | 136 | // Start Remove all Subtitles 137 | function clearAll() { 138 | var pli = 0; 139 | 140 | if (settings.totalSubs > 0) for (pli = 0; pli < settings.totalSubs; pli++) if (typeof subItems[pli] !== 'undefined') { 141 | subItems[pli].destroy(); 142 | delete subItems[pli]; 143 | } 144 | 145 | clearSubtitles(); 146 | subPlaying = 0; 147 | subItems = []; 148 | settings.totalSubs = 0; 149 | } 150 | // End Remove all Subtitles 151 | 152 | // save current subtitle to item settings to expose it to JS 153 | function saveSub(newSaved) { 154 | var itemSettings = {}; 155 | if (vlcPlayer.playlist.currentItem > -1) { 156 | if (wjs.isJson(vlcPlayer.playlist.items[vlcPlayer.playlist.currentItem].setting)) itemSettings = JSON.parse(vlcPlayer.playlist.items[vlcPlayer.playlist.currentItem].setting); 157 | itemSettings.subPlaying = newSaved; 158 | vlcPlayer.playlist.items[vlcPlayer.playlist.currentItem].setting = JSON.stringify(itemSettings); 159 | } 160 | } 161 | // end save current subtitle to item settings to expose it to JS 162 | 163 | // select subtitle 164 | function selectSubtitle(selSub) { 165 | if (selSub == 0) { 166 | clearSubtitles(); 167 | } else if (selSub < vlcPlayer.subtitle.count) { 168 | clearSubtitles(); 169 | subPlaying = selSub; 170 | saveSub(selSub); 171 | vlcPlayer.subtitle.track = selSub; 172 | } else { 173 | var getSettings = {}; 174 | if (wjs.isJson(vlcPlayer.playlist.items[vlcPlayer.playlist.currentItem].setting)) getSettings = JSON.parse(vlcPlayer.playlist.items[vlcPlayer.playlist.currentItem].setting); 175 | if (getSettings.subtitles) { 176 | var wjs_target = getSettings.subtitles; 177 | var wjs_keepIndex = vlcPlayer.subtitle.count; 178 | if (wjs_keepIndex == 0) wjs_keepIndex = 1; 179 | for (var newDesc in wjs_target) if (wjs_target.hasOwnProperty(newDesc)) { 180 | if (selSub == wjs_keepIndex) { 181 | vlcPlayer.subtitle.track = 0; 182 | playSubtitles(wjs_target[newDesc]); 183 | subPlaying = wjs_keepIndex; 184 | saveSub(wjs_keepIndex); 185 | return; 186 | } 187 | wjs_keepIndex++; 188 | } 189 | return; 190 | } 191 | } 192 | } 193 | // end select subtitle 194 | 195 | // Start Clear External Subtitles (SRT, SUB) 196 | function clearSubtitles() { 197 | subtitlebox.changeText = ""; 198 | currentSubtitle = -2; 199 | subtitles = []; 200 | vlcPlayer.subtitle.track = 0; 201 | subPlaying = 0; 202 | saveSub(0); 203 | } 204 | // End Clear External Subtitles (SRT, SUB) 205 | 206 | function addSubtitleItems(target) { 207 | // Remove Old Subtitle Menu Items 208 | clearAll(); 209 | 210 | // Adding Subtitle Menu Items 211 | var plstring = "None"; 212 | var pli = 0; 213 | 214 | subItems[pli] = Qt.createQmlObject('import QtQuick 2.1; import QtQuick.Layouts 1.0; import QmlVlc 0.1; Rectangle { id: dstitem'+ pli +'; anchors.left: parent.left; anchors.top: parent.top; anchors.topMargin: 32 + ('+ pli +' *40); color: "transparent"; width: subMenublock.width < 694 ? (subMenublock.width -56) : 638; height: 40; MouseArea { id: sitem'+ pli +'; cursorShape: Qt.PointingHandCursor; hoverEnabled: true; anchors.fill: parent; onWheel: { if (wheel.angleDelta.y > 0) wjs.moveSubMenu(parseInt(subMenuScroll.dragger.anchors.topMargin) + (parseInt(subMenuScroll.dragger.height) /2) -5); if (wheel.angleDelta.y < 0) wjs.moveSubMenu(parseInt(subMenuScroll.dragger.anchors.topMargin) + (parseInt(subMenuScroll.dragger.height) /2) +5); } onClicked: { toggleSubtitles(); clearSubtitles(); subPlaying = '+ pli +'; saveSub('+ pli +'); wjs.setText("Subtitle Unloaded"); vlcPlayer.subtitle.track = 0; } } Rectangle { width: subMenublock.width < 694 ? (subMenublock.width -56) : 638; clip: true; height: 40; color: vlcPlayer.state == 1 ? subPlaying == '+ pli +' ? sitem'+ pli +'.containsMouse ? "#3D3D3D" : "#e5e5e5" : sitem'+ pli +'.containsMouse ? "#3D3D3D" : "transparent" : subPlaying == '+ pli +' ? sitem'+ pli +'.containsMouse ? "#3D3D3D" : "#e5e5e5" : sitem'+ pli +'.containsMouse ? "#3D3D3D" : "transparent"; Text { anchors.left: parent.left; anchors.leftMargin: 12; anchors.verticalCenter: parent.verticalCenter; text: "'+ plstring +'"; font.pointSize: 10; color: vlcPlayer.state == 1 ? subPlaying == '+ pli +' ? sitem'+ pli +'.containsMouse ? "#e5e5e5" : "#2f2f2f" : sitem'+ pli +'.containsMouse ? "#e5e5e5" : "#e5e5e5" : subPlaying == '+ pli +' ? sitem'+ pli +'.containsMouse ? "#e5e5e5" : "#2f2f2f" : sitem'+ pli +'.containsMouse ? "#e5e5e5" : "#e5e5e5"; } } }', root, 'smenustr' +pli); 215 | pli++; 216 | 217 | var jli = 1; 218 | if (vlcPlayer.subtitle.count > 1) while (jli < vlcPlayer.subtitle.count) { 219 | var showThisSub = true; 220 | if (vlcPlayer.subtitle.description(jli).indexOf("Track ") > -1) { 221 | if (vlcPlayer.subtitle.description(jli).replace("Track ","").indexOf(" ") == -1) { 222 | if (isNaN(parseInt(vlcPlayer.subtitle.description(jli).replace("Track ",""))) === false) { 223 | showThisSub = false; 224 | } 225 | } 226 | } 227 | if (showThisSub === true) { 228 | subItems[pli] = Qt.createQmlObject('import QtQuick 2.1; import QtQuick.Layouts 1.0; import QmlVlc 0.1; Rectangle { id: dstitem'+ pli +'; anchors.left: parent.left; anchors.top: parent.top; anchors.topMargin: 32 + ('+ pli +' *40); color: "transparent"; width: subMenublock.width < 694 ? (subMenublock.width -56) : 638; height: 40; MouseArea { id: sitem'+ pli +'; cursorShape: Qt.PointingHandCursor; hoverEnabled: true; anchors.fill: parent; onWheel: { if (wheel.angleDelta.y > 0) wjs.moveSubMenu(parseInt(subMenuScroll.dragger.anchors.topMargin) + (parseInt(subMenuScroll.dragger.height) /2) -5); if (wheel.angleDelta.y < 0) wjs.moveSubMenu(parseInt(subMenuScroll.dragger.anchors.topMargin) + (parseInt(subMenuScroll.dragger.height) /2) +5); } onClicked: { toggleSubtitles(); clearSubtitles(); subPlaying = '+ pli +'; saveSub('+ pli +'); wjs.setText("Subtitle: '+ vlcPlayer.subtitle.description(jli) +'"); vlcPlayer.subtitle.track = '+ jli +'; } } Rectangle { width: subMenublock.width < 694 ? (subMenublock.width -56) : 638; clip: true; height: 40; color: vlcPlayer.state == 1 ? subPlaying == '+ pli +' ? sitem'+ pli +'.containsMouse ? "#3D3D3D" : "#e5e5e5" : sitem'+ pli +'.containsMouse ? "#3D3D3D" : "transparent" : subPlaying == '+ pli +' ? sitem'+ pli +'.containsMouse ? "#3D3D3D" : "#e5e5e5" : sitem'+ pli +'.containsMouse ? "#3D3D3D" : "transparent"; Text { anchors.left: parent.left; anchors.leftMargin: 12; anchors.verticalCenter: parent.verticalCenter; text: "'+ vlcPlayer.subtitle.description(jli) +'"; font.pointSize: 10; color: vlcPlayer.state == 1 ? subPlaying == '+ pli +' ? sitem'+ pli +'.containsMouse ? "#e5e5e5" : "#2f2f2f" : sitem'+ pli +'.containsMouse ? "#e5e5e5" : "#e5e5e5" : subPlaying == '+ pli +' ? sitem'+ pli +'.containsMouse ? "#e5e5e5" : "#2f2f2f" : sitem'+ pli +'.containsMouse ? "#e5e5e5" : "#e5e5e5"; } } }', root, 'smenustr' +pli); 229 | pli++; 230 | } 231 | jli++; 232 | } 233 | 234 | for (var k in target) if (target.hasOwnProperty(k)) { 235 | var plstring = k; 236 | if (plstring.length > 85) plstring = plstring.substr(0,85) +'...'; 237 | var slink = target[k]; 238 | 239 | subItems[pli] = Qt.createQmlObject('import QtQuick 2.1; import QtQuick.Layouts 1.0; import QmlVlc 0.1; Rectangle { id: dstitem'+ pli +'; anchors.left: parent.left; anchors.top: parent.top; anchors.topMargin: 32 + ('+ pli +' *40); color: "transparent"; width: subMenublock.width < 694 ? (subMenublock.width -56) : 638; height: 40; MouseArea { id: sitem'+ pli +'; cursorShape: Qt.PointingHandCursor; hoverEnabled: true; anchors.fill: parent; onWheel: { if (wheel.angleDelta.y > 0) wjs.moveSubMenu(parseInt(subMenuScroll.dragger.anchors.topMargin) + (parseInt(subMenuScroll.dragger.height) /2) -5); if (wheel.angleDelta.y < 0) wjs.moveSubMenu(parseInt(subMenuScroll.dragger.anchors.topMargin) + (parseInt(subMenuScroll.dragger.height) /2) +5); } onClicked: { vlcPlayer.subtitle.track = 0; toggleSubtitles(); playSubtitles("'+ slink +'"); subPlaying = '+ pli +'; saveSub('+ pli +'); wjs.setText("Subtitle: '+ plstring +'"); } } Rectangle { width: subMenublock.width < 694 ? (subMenublock.width -56) : 638; clip: true; height: 40; color: vlcPlayer.state == 1 ? subPlaying == '+ pli +' ? sitem'+ pli +'.containsMouse ? "#3D3D3D" : "#e5e5e5" : sitem'+ pli +'.containsMouse ? "#3D3D3D" : "transparent" : subPlaying == '+ pli +' ? sitem'+ pli +'.containsMouse ? "#3D3D3D" : "#e5e5e5" : sitem'+ pli +'.containsMouse ? "#3D3D3D" : "transparent"; Text { anchors.left: parent.left; anchors.leftMargin: 12; anchors.verticalCenter: parent.verticalCenter; text: "'+ plstring +'"; font.pointSize: 10; color: vlcPlayer.state == 1 ? subPlaying == '+ pli +' ? sitem'+ pli +'.containsMouse ? "#e5e5e5" : "#2f2f2f" : sitem'+ pli +'.containsMouse ? "#e5e5e5" : "#e5e5e5" : subPlaying == '+ pli +' ? sitem'+ pli +'.containsMouse ? "#e5e5e5" : "#2f2f2f" : sitem'+ pli +'.containsMouse ? "#e5e5e5" : "#e5e5e5"; } } }', root, 'smenustr' +pli); 240 | pli++ 241 | } 242 | settings.totalSubs = pli; 243 | saveSub(subPlaying); 244 | // End Adding Subtitle Menu Items 245 | } 246 | 247 | Connections { 248 | target: vlcPlayer 249 | onMediaPlayerTimeChanged: { 250 | // Start show subtitle text (external subtitles) 251 | var nowSecond = (vlcPlayer.time - settings.subDelay) /1000; 252 | if (currentSubtitle > -2) { 253 | var subtitle = -1; 254 | 255 | var os = 0; 256 | for (os in subtitles) { 257 | if (os > nowSecond) break; 258 | subtitle = os; 259 | } 260 | 261 | if (subtitle > 0) { 262 | if(subtitle != currentSubtitle) { 263 | if ((subtitles[subtitle].t.match(new RegExp("<", "g")) || []).length == 2) { 264 | if (subtitles[subtitle].t.substr(0,1) == "<" && subtitles[subtitle].t.slice(-1) == ">") { 265 | } else { 266 | subtitles[subtitle].t = subtitles[subtitle].t.replace(/<\/?[^>]+(>|$)/g, ""); 267 | } 268 | } else if ((subtitles[subtitle].t.match(new RegExp("<", "g")) || []).length > 2) { 269 | subtitles[subtitle].t = subtitles[subtitle].t.replace(/<\/?[^>]+(>|$)/g, ""); 270 | } 271 | subtitlebox.changeText = subtitles[subtitle].t; 272 | currentSubtitle = subtitle; 273 | } else if (subtitles[subtitle].o < nowSecond) { 274 | subtitlebox.changeText = ""; 275 | } 276 | } 277 | } 278 | // End show subtitle text (external subtitles) 279 | } 280 | } 281 | 282 | // This is where the Subtitle Items will be loaded 283 | } 284 | -------------------------------------------------------------------------------- /player/themes/sleek/components/SubtitleText.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.1 2 | import QmlVlc 0.1 3 | 4 | Rectangle { 5 | property alias fontColor: subtitlebox.color 6 | property alias fontShadow: subtitleboxShadow.color 7 | property alias changeText: subtitlebox.text 8 | 9 | anchors.fill: parent 10 | color: "transparent" 11 | Rectangle { 12 | visible: subtitlebox.text != "" ? true : false 13 | color: 'transparent' 14 | width: fullscreen ? parent.width -4 : parent.width -2 15 | anchors.bottom: parent.bottom 16 | anchors.bottomMargin: fullscreen ? subtitlebox.paintedHeight +46 : subtitlebox.paintedHeight +47 17 | anchors.left: parent.left 18 | anchors.leftMargin: fullscreen ? 4 : 2 19 | Text { 20 | id: subtitleboxShadow 21 | visible: subtitlebox.text != "" ? true : false 22 | anchors.horizontalCenter: parent.horizontalCenter 23 | horizontalAlignment: Text.AlignHCenter 24 | text: subtitlebox.text 25 | font.pointSize: fullscreen ? mousesurface.height * (parseFloat(settings.subPresets[settings.subSize]) -0.005) : mousesurface.height * parseFloat(settings.subPresets[settings.subSize]) 26 | style: Text.Outline 27 | styleColor: subtitleboxShadow.color 28 | font.family: fonts.secondaryFont.name 29 | smooth: true 30 | opacity: 0.5 31 | } 32 | } 33 | Rectangle { 34 | visible: subtitlebox.text != "" ? true : false 35 | color: 'transparent' 36 | width: parent.width 37 | anchors.bottom: parent.bottom 38 | anchors.bottomMargin: subtitlebox.paintedHeight +48 39 | Text { 40 | id: subtitlebox 41 | visible: subtitlebox.text != "" ? true : false 42 | anchors.horizontalCenter: parent.horizontalCenter 43 | horizontalAlignment: Text.AlignHCenter 44 | text: "" 45 | font.pointSize: fullscreen ? mousesurface.height * (parseFloat(settings.subPresets[settings.subSize]) -0.005) : mousesurface.height * parseFloat(settings.subPresets[settings.subSize]) 46 | style: Text.Outline 47 | styleColor: subtitleboxShadow.color 48 | font.weight: Font.DemiBold 49 | font.family: fonts.secondaryFont.name 50 | smooth: true 51 | } 52 | } 53 | } -------------------------------------------------------------------------------- /player/themes/sleek/components/TimeBubble.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.1 2 | import QmlVlc 0.1 3 | 4 | Rectangle { 5 | property alias srctime: srctime.text 6 | property alias fontColor: srctime.color 7 | property alias backgroundIcon: backgroundIcon.text 8 | property alias backgroundColor: backgroundIcon.color 9 | property alias backgroundBorder: backgroundIcon.styleColor 10 | property alias backgroundOpacity: backgroundIcon.opacity 11 | 12 | 13 | visible: settings.glyphsLoaded ? vlcPlayer.position > 0 ? settings.dragging ? true : progressBar.dragpos.containsMouse ? true : false : false : false 14 | anchors.bottom: parent.bottom 15 | anchors.bottomMargin: fullscreen ? 66 : 63 16 | anchors.left: parent.left 17 | anchors.leftMargin: srctime.text.length > 5 ? progressBar.dragpos.mouseX < 33 ? 3 : (progressBar.dragpos.mouseX +36) > theview.width ? (theview.width -65) : (progressBar.dragpos.mouseX -29) : progressBar.dragpos.mouseX < 23 ? -7 : (progressBar.dragpos.mouseX +25) > theview.width ? (theview.width -54) : (progressBar.dragpos.mouseX -30) // Move Time Chat Bubble dependant of Mouse Horizontal Position 18 | 19 | color: 'transparent' 20 | 21 | Rectangle { 22 | width: 62 23 | height: 25 24 | color: 'transparent' 25 | // Time Bubble Background Image 26 | Text { 27 | id: backgroundIcon 28 | anchors.centerIn: parent 29 | font.family: fonts.icons.name 30 | style: Text.Outline 31 | font.pointSize: 18 32 | } 33 | // End Time Bubble Background Image 34 | 35 | // Time Bubble Text 36 | Text { 37 | id: srctime 38 | anchors.top: parent.top 39 | anchors.topMargin: 3 40 | anchors.horizontalCenter: parent.horizontalCenter 41 | text: "" 42 | font.pointSize: 10 43 | } 44 | // End Time Bubble Text 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /player/themes/sleek/components/TitleBar.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.1 2 | import QmlVlc 0.1 3 | 4 | Rectangle { 5 | property alias fontColor: toptext.color 6 | property alias backgroundColor: topBarBackground.color 7 | property alias isVisible: topBarBackground.visible 8 | 9 | anchors.fill: parent 10 | color: "transparent" 11 | Rectangle { 12 | id: topBarBackground 13 | visible: (vlcPlayer.state == 3 || vlcPlayer.state == 4 || vlcPlayer.state == 6) ? fullscreen ? true : false : false 14 | width: parent.width 15 | height: 34 16 | anchors.top: parent.top 17 | opacity: pip.closeBut.containsMouse ? false : pip.hover.containsMouse ? false : digiZoom.mousepos.containsMouse ? false : vlcPlayer.Playing === false && vlcPlayer.Paused === false && vlcPlayer.Buffering === false ? 0 : fullscreen ? settings.ismoving > 5 ? 0 : 0.7 : 0.7 18 | Behavior on opacity { PropertyAnimation { duration: 250} } 19 | } 20 | Rectangle { 21 | visible: topBarBackground.visible 22 | width: parent.width 23 | height: 34 24 | color: 'transparent' 25 | anchors.top: parent.top 26 | opacity: pip.closeBut.containsMouse ? false : pip.hover.containsMouse ? false : digiZoom.mousepos.containsMouse ? false : vlcPlayer.Playing === false && vlcPlayer.Paused === false && vlcPlayer.Buffering === false? 0 : fullscreen ? settings.ismoving > 5 ? 0 : 1 : 1 27 | Behavior on opacity { PropertyAnimation { duration: 250} } 28 | Text { 29 | id: toptext 30 | anchors.verticalCenter: parent.verticalCenter 31 | anchors.left: parent.left; 32 | anchors.leftMargin: 14 33 | text: settings.title 34 | font.pointSize: 13 35 | font.family: fonts.defaultFont.name 36 | } 37 | } 38 | } -------------------------------------------------------------------------------- /player/themes/sleek/components/Toolbar.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.1 2 | import QmlVlc 0.1 3 | 4 | Rectangle { 5 | width: parent.width 6 | anchors.bottom: parent.bottom 7 | anchors.bottomMargin: fullscreen ? 0 : parent.containsMouse ? 0 : -height 8 | color: "transparent" 9 | visible: settings.uiVisible == 0 ? false : settings.toolbar == 0 ? false : settings.multiscreen == 1 ? fullscreen ? true : false : true // Multiscreen - Edit 10 | opacity: fullscreen ? settings.ismoving > 5 ? 0 : 1 : 1 11 | Behavior on anchors.bottomMargin { PropertyAnimation { duration: settings.multiscreen == 0 ? 250 : 0 } } 12 | Behavior on opacity { PropertyAnimation { duration: 250 } } 13 | } -------------------------------------------------------------------------------- /player/themes/sleek/components/ToolbarBackground.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.1 2 | import QmlVlc 0.1 3 | 4 | Rectangle { 5 | property alias bottomtab: bottomtab 6 | width: parent.width 7 | height: parent.height 8 | anchors.verticalCenter: parent.verticalCenter 9 | MouseArea { 10 | id: bottomtab 11 | hoverEnabled: true 12 | anchors.fill: parent 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /player/themes/sleek/components/ToolbarBorder.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.1 2 | import QtQuick.Layouts 1.0 3 | 4 | Rectangle { 5 | Layout.fillHeight: true 6 | width: 1 7 | } 8 | -------------------------------------------------------------------------------- /player/themes/sleek/components/ToolbarButton.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.1 2 | import QmlVlc 0.1 3 | import QtGraphicalEffects 1.0 4 | 5 | Rectangle { 6 | property alias icon: icon.text 7 | property alias iconSize: icon.font.pointSize 8 | property alias iconElem: icon 9 | property alias hover: mouseAreaButton 10 | property alias glow: glowEffect.visible 11 | signal buttonClicked 12 | signal buttonEntered 13 | signal buttonExited 14 | 15 | id: root 16 | height: parent.height 17 | width: buttonWidth 18 | clip: false 19 | color: 'transparent' 20 | Text { 21 | id: icon 22 | anchors.centerIn: parent 23 | font.family: fonts.icons.name 24 | color: mouseAreaButton.containsMouse ? ui.colors.toolbar.buttonHover : ui.colors.toolbar.button 25 | height: paintedHeight + (glowEffect.radius * 2) 26 | width: paintedWidth + (glowEffect.radius * 2) 27 | horizontalAlignment: Text.AlignHCenter 28 | verticalAlignment: Text.AlignVCenter 29 | } 30 | Glow { 31 | id: glowEffect 32 | anchors.fill: icon 33 | visible: mouseAreaButton.containsMouse ? true : false 34 | radius: 2 35 | samples: 4 36 | smooth: true 37 | color: Qt.rgba(255, 255, 255, 0.6) 38 | source: icon 39 | } 40 | MouseArea { 41 | id: mouseAreaButton 42 | cursorShape: toolbar.opacity == 1 ? Qt.PointingHandCursor : mousesurface.cursorShape 43 | anchors.fill: parent 44 | hoverEnabled: true 45 | onClicked: root.buttonClicked() 46 | onEntered: root.buttonEntered() 47 | onExited: root.buttonExited() 48 | } 49 | } -------------------------------------------------------------------------------- /player/themes/sleek/components/ToolbarLeft.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.1 2 | import QtQuick.Layouts 1.0 3 | 4 | RowLayout { 5 | spacing: 0 6 | height: toolbar.height 7 | } -------------------------------------------------------------------------------- /player/themes/sleek/components/ToolbarRight.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.1 2 | import QtQuick.Layouts 1.0 3 | 4 | RowLayout { 5 | spacing: 0 6 | height: parent.height 7 | anchors.right: parent.right 8 | } -------------------------------------------------------------------------------- /player/themes/sleek/components/ToolbarTimeLength.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.1 2 | import QmlVlc 0.1 3 | 4 | Text { 5 | anchors.left: mutebut.right 6 | anchors.leftMargin: mutebut.hover.containsMouse ? 131 + timeMargin : volumeMouse.dragger.containsMouse ? 131 + timeMargin : timeMargin 7 | opacity: vlcPlayer.time == 0 ? 0 : vlcPlayer.state > 1 ? 1 : 0 8 | font.pointSize: 9 9 | Behavior on anchors.leftMargin { PropertyAnimation { duration: 250} } 10 | } -------------------------------------------------------------------------------- /player/themes/sleek/components/TopCenterText.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.1 2 | import QmlVlc 0.1 3 | 4 | Rectangle { 5 | property alias fontColor: buftext.color 6 | property alias fontShadow: bufshadow.color 7 | property alias changeText: buftext.text 8 | 9 | anchors.fill: parent 10 | color: "transparent" 11 | Rectangle { 12 | visible: vlcPlayer.state == 1 ? true : settings.buffering > 0 && settings.buffering < 100 ? true : false 13 | color: 'transparent' 14 | width: fullscreen ? parent.width -4 : parent.width -2 15 | anchors.top: parent.top 16 | anchors.topMargin: fullscreen ? 37 : topText.isVisible ? 30 : 11 17 | anchors.horizontalCenter: parent.horizontalCenter 18 | Text { 19 | id: bufshadow 20 | visible: vlcPlayer.state == 1 ? true : settings.buffering > 0 && settings.buffering < 100 ? true : false 21 | anchors.horizontalCenter: parent.horizontalCenter 22 | text: buftext.text 23 | font.pointSize: buftext.font.pointSize 24 | style: Text.Outline 25 | styleColor: bufshadow.color 26 | font.weight: Font.DemiBold 27 | font.family: fonts.secondaryFont.name 28 | smooth: true 29 | opacity: 0.5 30 | } 31 | } 32 | Rectangle { 33 | visible: vlcPlayer.state == 1 ? true : settings.buffering > 0 && settings.buffering < 100 ? true : false 34 | color: 'transparent' 35 | width: parent.width 36 | anchors.top: parent.top 37 | anchors.topMargin: fullscreen ? 35 : topText.isVisible ? 28 : 10 38 | anchors.horizontalCenter: parent.horizontalCenter 39 | Text { 40 | id: buftext 41 | visible: vlcPlayer.state == 1 ? true : settings.buffering > 0 && settings.buffering < 100 ? true : false 42 | anchors.horizontalCenter: parent.horizontalCenter 43 | text: "" 44 | font.pointSize: fullscreen ? mousesurface.height * 0.030 : (mousesurface.height * 0.035) < 16 ? 16 : mousesurface.height * 0.035 45 | style: Text.Outline 46 | styleColor: bufshadow.color 47 | font.weight: Font.DemiBold 48 | font.family: fonts.secondaryFont.name 49 | smooth: true 50 | } 51 | } 52 | } -------------------------------------------------------------------------------- /player/themes/sleek/components/TopRightText.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.1 2 | import QmlVlc 0.1 3 | 4 | Rectangle { 5 | property alias fontColor: volumebox.color 6 | property alias fontShadow: volumeBoxShadow.color 7 | property alias changeText: volumebox.text 8 | property alias shadowEffectDuration: shadowTextEffect.duration 9 | property alias textEffectDuration: volTextEffect.duration 10 | property alias shadowHolder: shadowHolder 11 | property alias textHolder: textHolder 12 | 13 | 14 | anchors.fill: parent 15 | color: "transparent" 16 | Rectangle { 17 | id: shadowHolder 18 | color: "transparent" 19 | opacity: 0 20 | anchors.right: parent.right 21 | anchors.rightMargin: fullscreen ? volumebox.paintedWidth +38 : volumebox.paintedWidth +24 22 | anchors.top: parent.top 23 | anchors.topMargin: fullscreen ? 37 : topText.isVisible ? 30 : 11 24 | Behavior on opacity { PropertyAnimation { id: shadowTextEffect; duration: 500 } } 25 | Text { 26 | id: volumeBoxShadow 27 | horizontalAlignment: Text.AlignHRight 28 | text: volumebox.text 29 | font.pointSize: fullscreen ? mousesurface.height * 0.035 : mousesurface.height * 0.045 30 | style: Text.Outline 31 | styleColor: volumeBoxShadow.color 32 | font.weight: Font.DemiBold 33 | font.family: fonts.defaultFont.name 34 | smooth: true 35 | opacity: 0.5 36 | Behavior on visible { PropertyAnimation { duration: 0 } } 37 | } 38 | } 39 | Rectangle { 40 | id: textHolder 41 | visible: true 42 | color: 'transparent' 43 | anchors.right: parent.right 44 | anchors.rightMargin: fullscreen ? volumebox.paintedWidth +40 : volumebox.paintedWidth +25 45 | anchors.top: parent.top 46 | anchors.topMargin: fullscreen ? 35 : topText.isVisible ? 28 : 10 47 | opacity: 0 48 | Behavior on opacity { PropertyAnimation { id: volTextEffect; duration: 0 } } 49 | Text { 50 | id: volumebox 51 | horizontalAlignment: Text.AlignHRight 52 | text: "" 53 | font.pointSize: fullscreen ? mousesurface.height * 0.035 : mousesurface.height * 0.045 54 | style: Text.Outline 55 | styleColor: volumeBoxShadow.color 56 | font.weight: Font.DemiBold 57 | font.family: fonts.defaultFont.name 58 | smooth: true 59 | } 60 | } 61 | // Fade Out Top Right text box after 3 seconds 62 | Timer { 63 | interval: 3000; running: settings.timervolume == 1 ? true : false; repeat: false 64 | onTriggered: { 65 | shadowTextEffect.duration = 150; 66 | shadowHolder.opacity = 0; 67 | textHolder.opacity = 0; 68 | settings.timervolume = 0; 69 | } 70 | } 71 | // End Fade Out Top Right text box after 3 seconds 72 | } -------------------------------------------------------------------------------- /player/themes/sleek/components/VideoLayer.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.1 2 | import QmlVlc 0.1 3 | 4 | // Declare Video Layer 5 | VlcVideoSurface { 6 | property alias scale: zoomScale 7 | 8 | source: vlcPlayer; 9 | anchors.centerIn: parent; 10 | anchors.top: parent.top; 11 | anchors.left: parent.left; 12 | width: parent.width; 13 | height: parent.height; 14 | fillMode: VlcVideoSurface.PreserveAspectFit 15 | onWidthChanged: { digiZoom.zoomNewPosition(); pip.pipNewPosition(); } 16 | onHeightChanged: { digiZoom.zoomNewPosition(); pip.pipNewPosition(); } 17 | transform: Scale { 18 | id: zoomScale 19 | origin.x: 1; 20 | origin.y: 1; 21 | xScale: settings.digitalzoom == 0 ? 1 : settings.digitalzoom; 22 | yScale: settings.digitalzoom == 0 ? 1 : settings.digitalzoom; 23 | } 24 | } 25 | // End Video Layer -------------------------------------------------------------------------------- /player/themes/sleek/components/VolumeHeat.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.1 2 | 3 | Rectangle { 4 | clip: true 5 | height: parent.height 6 | width: settings.firstvolume == 1 ? 0 : vlcPlayer.state <= 1 && volumeBorder.anchors.leftMargin == 0 ? 0 : mutebut.hover.containsMouse ? 120 : volumeMouse.dragger.containsMouse ? 120 : 0 7 | anchors.verticalCenter: parent.verticalCenter 8 | anchors.left: mutebut.right 9 | color: 'transparent' 10 | Behavior on width { PropertyAnimation { duration: vlcPlayer.state <= 1 && volumeBorder.anchors.leftMargin == 0 && width > 0 ? 0 : 250 } } 11 | } 12 | -------------------------------------------------------------------------------- /player/themes/sleek/components/VolumeHeatColors.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.1 2 | 3 | Rectangle { 4 | property alias volColor: volColor.color 5 | 6 | height: 8 7 | width: 116 8 | color: "transparent" 9 | 10 | Rectangle { 11 | id: volColor 12 | height: parent.width 13 | width: parent.height 14 | anchors.centerIn: parent 15 | rotation: 90 16 | color: "transparent" 17 | } 18 | } -------------------------------------------------------------------------------- /player/themes/sleek/components/VolumeHeatGraphics.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.1 2 | import QmlVlc 0.1 3 | import "./" as Loader 4 | 5 | Rectangle { 6 | property alias volColor: backgroundColors.volColor 7 | property alias volume: moveposa.width 8 | property alias backgroundColor: root.color 9 | 10 | width: 120 11 | height: parent.height 12 | color: "transparent" 13 | 14 | Rectangle { 15 | id: root 16 | width: 120 17 | height: 8 18 | anchors.verticalCenter: parent.verticalCenter 19 | Rectangle { 20 | id: moveposa 21 | clip: true 22 | width: 0 23 | anchors.top: parent.top 24 | anchors.left: parent.left 25 | anchors.bottom: parent.bottom 26 | 27 | Loader.VolumeHeatColors { id: backgroundColors } // Draw Volume Heat Background Colors 28 | 29 | } 30 | Rectangle { 31 | id: movecura 32 | color: '#ffffff' 33 | width: 4 34 | height: 14 35 | anchors.verticalCenter: parent.verticalCenter 36 | anchors.left: parent.left 37 | anchors.leftMargin: moveposa.width 38 | } 39 | 40 | } 41 | } -------------------------------------------------------------------------------- /player/themes/sleek/components/VolumeHeatMouse.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.1 2 | 3 | Rectangle { 4 | property alias dragger: mouseAreaVl 5 | property alias hover: mouseAreaVol 6 | signal pressAndHold(string mouseX, string mouseY) 7 | signal positionChanged(string mouseX, string mouseY) 8 | signal released(string mouseX, string mouseY) 9 | 10 | id: root 11 | anchors.fill: parent 12 | color: "transparent" 13 | 14 | // Mouse Area for Dragging 15 | MouseArea { 16 | id: mouseAreaVl 17 | anchors.fill: parent 18 | anchors.left: parent.left 19 | hoverEnabled: true 20 | } 21 | // End Mouse Area for Dragging 22 | MouseArea { 23 | id: mouseAreaVol 24 | cursorShape: toolbar.opacity == 1 ? Qt.PointingHandCursor : mousesurface.cursorShape 25 | anchors.fill: parent 26 | anchors.left: parent.left 27 | onPressAndHold: root.pressAndHold(mouse.x,mouse.y); 28 | onPositionChanged: root.positionChanged(mouse.x,mouse.y); 29 | onReleased: root.released(mouse.x,mouse.y); 30 | } 31 | } -------------------------------------------------------------------------------- /player/themes/sleek/components/VolumeHeatScale.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.1 2 | import QtQuick.Layouts 1.0 3 | 4 | Rectangle { 5 | property alias linesColor: lines.color 6 | property alias linesOpacity: lines.opacity 7 | 8 | width: 120 9 | height: 20 10 | anchors.verticalCenter: parent.verticalCenter 11 | color: "transparent" 12 | RowLayout { 13 | spacing: 17 14 | height: 4 15 | anchors.left: parent.left 16 | anchors.leftMargin: 11 17 | Rectangle { id: lines; width: 2; height: parent.height; opacity: 0.7 } 18 | Rectangle { width: 2; height: parent.height; color: lines.color; opacity: lines.opacity } 19 | Rectangle { width: 2; height: parent.height; color: lines.color; opacity: lines.opacity } 20 | Rectangle { width: 2; height: parent.height; color: lines.color; opacity: lines.opacity } 21 | Rectangle { width: 2; height: parent.height; color: lines.color; opacity: lines.opacity } 22 | Rectangle { width: 2; height: parent.height; color: lines.color; opacity: lines.opacity } 23 | } 24 | RowLayout { 25 | spacing: 17 26 | height: 4 27 | anchors.bottom: parent.bottom 28 | anchors.left: parent.left 29 | anchors.leftMargin: 11 30 | Rectangle { width: 2; height: parent.height; color: lines.color; opacity: lines.opacity } 31 | Rectangle { width: 2; height: parent.height; color: lines.color; opacity: lines.opacity } 32 | Rectangle { width: 2; height: parent.height; color: lines.color; opacity: lines.opacity } 33 | Rectangle { width: 2; height: parent.height; color: lines.color; opacity: lines.opacity } 34 | Rectangle { width: 2; height: parent.height; color: lines.color; opacity: lines.opacity } 35 | Rectangle { width: 2; height: parent.height; color: lines.color; opacity: lines.opacity } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /player/themes/sleek/components/qmldir: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jaruba/WebChimeraPlayer/9d1f55dd89b93e9fc5a83e8d9ea86070fc7e0ae2/player/themes/sleek/components/qmldir -------------------------------------------------------------------------------- /player/themes/sleek/fonts/glyphicons.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jaruba/WebChimeraPlayer/9d1f55dd89b93e9fc5a83e8d9ea86070fc7e0ae2/player/themes/sleek/fonts/glyphicons.ttf -------------------------------------------------------------------------------- /player/themes/sleek/main.qml: -------------------------------------------------------------------------------- 1 | /***************************************************************************** 2 | * Copyright (c) 2014-2015 Branza Victor-Alexandru 3 | * 4 | * This program is free software; you can redistribute it and/or modify it 5 | * under the terms of the GNU Lesser General Public License as published by 6 | * the Free Software Foundation; either version 2.1 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with this program; if not, write to the Free Software Foundation, 16 | * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. 17 | *****************************************************************************/ 18 | 19 | import QtQuick 2.1 20 | import QmlVlc 0.1 21 | import "./" as LoadSettings 22 | import "../../core" as JsLogic 23 | import "components" as Loader 24 | 25 | Rectangle { 26 | 27 | // load core javascript functions and settings 28 | property variant ui: {} 29 | LoadSettings.UIsettings { id: skinData } 30 | property var borderVisible: skinData.variables.settings.toolbar.borderVisible; 31 | property var buttonWidth: skinData.variables.settings.toolbar.buttonWidth; 32 | property var timeMargin: skinData.variables.settings.toolbar.timeMargin; 33 | JsLogic.Settings { id: settings } 34 | JsLogic.Functions { id: wjs } 35 | JsLogic.Hotkeys { id: hotkeys } 36 | JsLogic.Buttons { id: buttons } 37 | // end load core javascript functions and settings 38 | 39 | id: theview; 40 | color: ui.colors.videoBackground; // Set Video Background Color 41 | 42 | Loader.Fonts { 43 | id: fonts 44 | icons.source: ui.settings.iconFont 45 | defaultFont.source: ui.settings.defaultFont 46 | secondaryFont.source: ui.settings.secondaryFont 47 | } 48 | 49 | Loader.ArtworkLayer { id: artwork } // Load Artwork Layer (if set with .addPlaylist) 50 | 51 | Loader.VideoLayer { id: videoSource } // Load Video Layer 52 | 53 | // Start Subtitle Text Box 54 | Loader.SubtitleText { 55 | id: subtitlebox 56 | fontColor: ui.colors.font 57 | fontShadow: ui.colors.fontShadow 58 | } 59 | // End Start Subtitle Text Box 60 | 61 | // Start Top Center Text Box (Opening, Buffering, etc.) 62 | Loader.TopCenterText { 63 | id: buftext 64 | fontColor: ui.colors.font 65 | fontShadow: ui.colors.fontShadow 66 | } 67 | // End Top Center Text Box 68 | 69 | // Draw Play Icon (appears in center of screen when Toggle Pause) 70 | Loader.BigPlayIcon { 71 | id: playtog 72 | color: ui.colors.bigIconBackground 73 | icon: ui.icon.bigPlay 74 | iconColor: ui.colors.bigIcon 75 | } 76 | // End Draw Play Icon (appears in center of screen when Toggle Pause) 77 | 78 | // Draw Pause Icon (appears in center of screen when Toggle Pause) 79 | Loader.BigPauseIcon { 80 | id: pausetog 81 | color: ui.colors.bigIconBackground 82 | icon: ui.icon.bigPause 83 | iconColor: ui.colors.bigIcon 84 | } 85 | // End Draw Pause Icon (appears in center of screen when Toggle Pause) 86 | 87 | // Start Loading Screen 88 | Loader.SplashScreen { 89 | id: splashScreen 90 | color: ui.colors.videoBackground 91 | fontColor: ui.colors.font 92 | fontShadow: ui.colors.fontShadow 93 | onLogoEffect: wjs.fadeLogo() 94 | } 95 | // End Loading Screen 96 | 97 | // Mouse Area over entire Surface (check mouse movement, toggle pause when clicked) includes Toolbar 98 | Loader.MouseSurface { 99 | id: mousesurface 100 | onWidthChanged: wjs.onSizeChanged(); 101 | onHeightChanged: wjs.onSizeChanged(); 102 | onPressed: hotkeys.mouseClick(mouse.button); 103 | onReleased: hotkeys.mouseRelease(mouse.button); 104 | onDoubleClicked: hotkeys.mouseDblClick(mouse.button); 105 | onPositionChanged: hotkeys.mouseMoved(mouse.x,mouse.y); 106 | onWheel: hotkeys.mouseScroll(wheel.angleDelta.x,wheel.angleDelta.y); 107 | Keys.onPressed: hotkeys.keys(event); 108 | 109 | // Draw Toolbar 110 | Loader.Toolbar { 111 | id: toolbar 112 | height: fullscreen ? 32 : 30 113 | 114 | Loader.ToolbarBackground { 115 | id: toolbarBackground 116 | color: ui.colors.background 117 | opacity: ui.settings.toolbar.opacity 118 | } 119 | 120 | // Start Left Side Buttons in Toolbar 121 | Loader.ToolbarLeft { 122 | 123 | // Start Playlist Previous Button 124 | Loader.ToolbarButton { 125 | id: prevBut 126 | icon: settings.glyphsLoaded ? ui.icon.prev : "" 127 | iconSize: fullscreen ? 8 : 7 128 | visible: vlcPlayer.playlist.itemCount > 1 ? true : false 129 | glow: ui.settings.buttonGlow 130 | onButtonClicked: buttons.clicked("prev"); 131 | } 132 | Loader.ToolbarBorder { 133 | color: ui.colors.toolbar.border 134 | anchors.left: prevBut.right 135 | visible: prevBut.visible ? borderVisible : false 136 | } 137 | // End Playlist Previous Button 138 | 139 | // Start Play/Pause Button 140 | Loader.ToolbarButton { 141 | id: playButton 142 | icon: settings.glyphsLoaded ? vlcPlayer.playing ? ui.icon.pause : vlcPlayer.state != 6 ? ui.icon.play : ui.icon.replay : "" 143 | iconSize: fullscreen ? 14 : 13 144 | anchors.left: prevBut.visible ? prevBut.right : parent.left 145 | anchors.leftMargin: prevBut.visible ? 1 : 0 146 | glow: ui.settings.buttonGlow 147 | onButtonClicked: buttons.clicked("play"); 148 | } 149 | Loader.ToolbarBorder { 150 | color: ui.colors.toolbar.border 151 | anchors.left: playButton.right 152 | visible: borderVisible 153 | } 154 | // End Play/Pause Button 155 | 156 | // Start Playlist Next Button 157 | Loader.ToolbarButton { 158 | id: nextBut 159 | icon: settings.glyphsLoaded ? ui.icon.next : "" 160 | iconSize: fullscreen ? 8 : 7 161 | anchors.left: playButton.right 162 | anchors.leftMargin: 1 163 | visible: vlcPlayer.playlist.itemCount > 1 ? true : false 164 | glow: ui.settings.buttonGlow 165 | onButtonClicked: buttons.clicked("next"); 166 | } 167 | Loader.ToolbarBorder { 168 | visible: nextBut.visible ? borderVisible : false 169 | anchors.left: nextBut.right 170 | color: ui.colors.toolbar.border 171 | } 172 | // End Playlist Next Button 173 | 174 | // Start Mute Button 175 | Loader.ToolbarButton { 176 | id: mutebut 177 | anchors.left: nextBut.visible ? nextBut.right : playButton.right 178 | anchors.leftMargin: 1 179 | icon: settings.glyphsLoaded ? vlcPlayer.state == 0 ? ui.icon.volume.medium : vlcPlayer.position == 0 && vlcPlayer.playlist.currentItem == 0 ? settings.automute == 0 ? ui.icon.volume.medium : ui.icon.mute : vlcPlayer.audio.mute ? ui.icon.mute : vlcPlayer.volume == 0 ? ui.icon.mute : vlcPlayer.volume <= 30 ? ui.icon.volume.low : vlcPlayer.volume > 30 && vlcPlayer.volume <= 134 ? ui.icon.volume.medium : ui.icon.volume.high : "" 180 | iconSize: fullscreen ? 17 : 16 181 | width: skinData.done === true ? ui.settings.toolbar.buttonMuteWidth : skinData.variables.settings.toolbar.buttonMuteWidth 182 | glow: ui.settings.buttonGlow 183 | onButtonClicked: buttons.clicked("mute"); 184 | onButtonEntered: wjs.refreshMuteIcon(); 185 | onButtonExited: wjs.refreshMuteIcon(); 186 | 187 | } 188 | // End Mute Button 189 | 190 | // Start Volume Control 191 | Loader.VolumeHeat { 192 | 193 | Loader.VolumeHeatMouse { 194 | id: volumeMouse 195 | onPressAndHold: wjs.hoverVolume(mouseX,mouseY) 196 | onPositionChanged: wjs.clickVolume(mouseX,mouseY) 197 | onReleased: wjs.clickVolume(mouseX,mouseY) 198 | } 199 | Loader.VolumeHeatGraphics { 200 | id: volheat 201 | backgroundColor: ui.colors.volumeHeat.background 202 | volColor: ui.colors.volumeHeat.color 203 | } 204 | 205 | } 206 | // End Volume Control 207 | 208 | Loader.ToolbarBorder { 209 | id: volumeBorder 210 | anchors.left: mutebut.right 211 | anchors.leftMargin: settings.firstvolume == 1 ? 0 : mutebut.hover.containsMouse ? 130 : volumeMouse.dragger.containsMouse ? 130 : 0 212 | color: ui.colors.toolbar.border 213 | visible: borderVisible 214 | Behavior on anchors.leftMargin { PropertyAnimation { duration: 250 } } 215 | } 216 | 217 | // Start "Time / Length" Text in Toolbar 218 | Loader.ToolbarTimeLength { 219 | id: showtime 220 | text: wjs.getTime(vlcPlayer.time) 221 | color: ui.colors.toolbar.currentTime 222 | } 223 | Loader.ToolbarTimeLength { 224 | anchors.left: showtime.right 225 | anchors.leftMargin: 0 226 | text: settings.refreshTime ? wjs.getLengthTime() != "" ? " / "+ wjs.getLengthTime() : "" : wjs.getLengthTime() != "" ? " / "+ wjs.getLengthTime() : "" 227 | color: ui.colors.toolbar.lengthTime 228 | } 229 | // End "Time / Length" Text in Toolbar 230 | } 231 | // End Left Side Buttons in Toolbar 232 | 233 | // Start Right Side Buttons in Toolbar 234 | Loader.ToolbarRight { 235 | // Start Open Subtitle Menu Button 236 | Loader.ToolbarBorder { 237 | color: ui.colors.toolbar.border 238 | visible: subButton.visible ? borderVisible : false 239 | } 240 | Loader.ToolbarButton { 241 | id: subButton 242 | icon: settings.glyphsLoaded ? ui.icon.subtitles : "" 243 | iconSize: fullscreen ? 17 : 16 244 | anchors.right: playlistButton.visible? playlistButton.left : fullscreenButton.left 245 | anchors.rightMargin: 1 246 | visible: false 247 | glow: ui.settings.buttonGlow 248 | onButtonClicked: buttons.clicked("subtitles"); 249 | } 250 | // End Open Subtitle Menu Button 251 | 252 | // Start Open Playlist Button 253 | Loader.ToolbarBorder { 254 | color: ui.colors.toolbar.border 255 | anchors.right: playlistButton.left 256 | visible: playlistButton.visible ? borderVisible : false 257 | } 258 | Loader.ToolbarButton { 259 | id: playlistButton 260 | icon: settings.glyphsLoaded ? ui.icon.playlist : "" 261 | iconSize: fullscreen ? 18 : 17 262 | visible: settings.debugPlaylist ? true : vlcPlayer.playlist.itemCount > 1 ? true : false 263 | anchors.right: fullscreenButton.left 264 | anchors.rightMargin: 1 265 | glow: ui.settings.buttonGlow 266 | onButtonClicked: buttons.clicked("playlist"); 267 | } 268 | // End Open Playlist Button 269 | 270 | // Fullscreen Button 271 | Loader.ToolbarBorder { 272 | color: ui.colors.toolbar.border 273 | anchors.right: fullscreenButton.left 274 | visible: borderVisible 275 | } 276 | Loader.ToolbarButton { 277 | id: fullscreenButton 278 | anchors.right: parent.right 279 | icon: settings.glyphsLoaded ? fullscreen ? ui.icon.minimize : ui.icon.maximize : "" 280 | iconSize: fullscreen ? 18 : 17 281 | iconElem.color: settings.allowfullscreen == 1 ? hover.containsMouse ? ui.colors.toolbar.buttonHover : ui.colors.toolbar.button : ui.colors.toolbar.buttonHover 282 | hover.cursorShape: settings.allowfullscreen == 1 ? toolbar.opacity == 1 ? Qt.PointingHandCursor : mousesurface.cursorShape : Qt.ForbiddenCursor 283 | opacity: settings.allowfullscreen == 1 ? 1 : 0.2 284 | color: settings.allowfullscreen == 1 ? "transparent" : "#000000" 285 | glow: ui.settings.buttonGlow 286 | onButtonClicked: buttons.clicked("fullscreen"); 287 | } 288 | // End Fullscreen Button 289 | } 290 | // End Right Side Buttons in Toolbar 291 | } 292 | // End Draw Toolbar 293 | 294 | // Draw Time Bubble (visible when hovering over Progress Bar) 295 | Loader.TimeBubble { 296 | id: timeBubble 297 | fontColor: ui.colors.timeBubble.font 298 | backgroundIcon: settings.glyphsLoaded ? timeBubble.srctime.length > 5 ? ui.icon.timeBubble.big : timeBubble.srctime.length == 0 ? "" : ui.icon.timeBubble.small : "" 299 | backgroundColor: ui.colors.timeBubble.background 300 | backgroundBorder: ui.colors.timeBubble.border 301 | backgroundOpacity: 0.9 302 | } 303 | // End Time Bubble 304 | 305 | // Draw Progression Bar 306 | Loader.ProgressBar { 307 | id: progressBar 308 | backgroundColor: ui.colors.progress.background 309 | viewedColor: ui.colors.progress.viewed 310 | positionColor: ui.colors.progress.position 311 | cache.visible: vlcPlayer.state > 0 ? ui.settings.caching : false // fix for non-notify issue 312 | cache.color: ui.colors.progress.cache 313 | onPressed: wjs.progressDrag(mouseX,mouseY); 314 | onChanged: wjs.progressChanged(mouseX,mouseY); 315 | onReleased: wjs.progressReleased(mouseX,mouseY); 316 | } 317 | // End Draw Progress Bar 318 | 319 | Loader.DigitalZoom { id: digiZoom } // Digital Zoom Feature 320 | 321 | Loader.PIP { id: pip } // Picture in Picture Feature 322 | 323 | // Start Top Right Text Box 324 | Loader.TopRightText { 325 | id: volumebox 326 | fontColor: ui.colors.font 327 | fontShadow: ui.colors.fontShadow 328 | } 329 | // End Top Right Text Box 330 | 331 | // Title Bar (top bar) 332 | Loader.TitleBar { 333 | id: topText 334 | fontColor: ui.colors.titleBar.font 335 | backgroundColor: ui.colors.titleBar.background 336 | isVisible: settings.uiVisible == 0 ? false : (vlcPlayer.state == 3 || vlcPlayer.state == 4 || vlcPlayer.state == 6) ? ui.settings.titleBar == "fullscreen" ? fullscreen ? true : false : ui.settings.titleBar == "minimized" ? fullscreen === false ? true : false : ui.settings.titleBar == "both" ? true : ui.settings.titleBar == "none" ? false : false : false 337 | } 338 | // End Title Bar (top bar) 339 | 340 | // Start Playlist Menu 341 | Loader.Menu { 342 | id: playlistblock 343 | background.color: ui.colors.playlistMenu.background 344 | 345 | // Start Playlist Menu Scroll 346 | Loader.MenuScroll { 347 | id: playlistScroll 348 | draggerColor: ui.colors.playlistMenu.drag 349 | backgroundColor: ui.colors.playlistMenu.scroller 350 | onDrag: wjs.movePlaylist(mouseY) 351 | dragger.height: (playlist.totalPlay * 40) < 240 ? 240 : (240 / (playlist.totalPlay * 40)) * 240 352 | } 353 | // End Playlist Menu Scroll 354 | 355 | Loader.MenuContent { 356 | width: playlistblock.width < 694 ? (playlistblock.width -12) : 682 357 | 358 | Loader.PlaylistMenuItems { id: playlist } // Playlist Items Holder (This is where the Playlist Items will be loaded) 359 | 360 | // Top Holder (Title + Close Button) 361 | Loader.MenuHeader { 362 | text: "Playlist Menu" 363 | textColor: ui.colors.playlistMenu.headerFont 364 | backgroundColor: ui.colors.playlistMenu.header 365 | 366 | // Start Close Playlist Button 367 | Loader.MenuClose { 368 | id: playlistClose 369 | icon: settings.glyphsLoaded ? ui.icon.closePlaylist : "" 370 | iconSize: 9 371 | iconColor: playlistClose.hover.containsMouse ? ui.colors.playlistMenu.closeHover : ui.colors.playlistMenu.close 372 | color: playlistClose.hover.containsMouse ? ui.colors.playlistMenu.closeBackgroundHover : ui.colors.playlistMenu.closeBackground 373 | hover.onClicked: { playlistblock.visible = false; } 374 | } 375 | // End Close Playlist Button 376 | } 377 | // End Top Holder (Title + Close Button) 378 | 379 | } 380 | } 381 | // End Playlist Menu 382 | 383 | // Start Replace MRL Text Box (for debug playlist feature) 384 | Loader.ReplaceMRL { 385 | color: "#111111" 386 | id: inputBox 387 | } 388 | // End Replace MRL Text Box (for debug playlist feature) 389 | 390 | // Start Add MRL Text Box (for debug playlist feature) 391 | Loader.AddMRL { 392 | color: "#111111" 393 | id: inputAddBox 394 | } 395 | // End Add MRL Text Box (for debug playlist feature) 396 | 397 | 398 | // Start Subtitle Menu 399 | Loader.Menu { 400 | id: subMenublock 401 | background.color: ui.colors.playlistMenu.background 402 | 403 | // Start Subtitle Menu Scroll 404 | Loader.MenuScroll { 405 | id: subMenuScroll 406 | draggerColor: ui.colors.playlistMenu.drag 407 | backgroundColor: ui.colors.playlistMenu.scroller 408 | onDrag: wjs.moveSubMenu(mouseY) 409 | dragger.height: (settings.totalSubs * 40) < 240 ? 240 : (240 / (settings.totalSubs * 40)) * 240 410 | } 411 | // End Subtitle Menu Scroll 412 | 413 | Loader.MenuContent { 414 | width: subMenublock.width < 694 ? (subMenublock.width -12) : 682 415 | 416 | Loader.SubtitleMenuItems { id: subMenu } // Subtitle Items Holder (This is where the Playlist Items will be loaded) 417 | 418 | // Top Holder (Title + Close Button) 419 | Loader.MenuHeader { 420 | text: "Subtitle Menu" 421 | textColor: ui.colors.playlistMenu.headerFont 422 | backgroundColor: ui.colors.playlistMenu.header 423 | 424 | // Start Close Subtitle Menu Button 425 | Loader.MenuClose { 426 | id: subMenuClose 427 | icon: settings.glyphsLoaded ? ui.icon.closePlaylist : "" 428 | iconSize: 9 429 | iconColor: subMenuClose.hover.containsMouse ? ui.colors.playlistMenu.closeHover : ui.colors.playlistMenu.close 430 | color: subMenuClose.hover.containsMouse ? ui.colors.playlistMenu.closeBackgroundHover : ui.colors.playlistMenu.closeBackground 431 | hover.onClicked: { subMenublock.visible = false; } 432 | } 433 | // End Close Subtitle Menu Button 434 | } 435 | // End Top Holder (Title + Close Button) 436 | 437 | } 438 | } 439 | // End Subtitle Menu 440 | 441 | // Start Context Menu 442 | Loader.ContextMenu { 443 | id: contextblock 444 | color: ui.colors.playlistMenu.background 445 | border.color: "#979595" 446 | } 447 | // End Context Menu 448 | 449 | } 450 | // End Mouse Area over entire Surface (check mouse movement, toggle pause when clicked) [includes Toolbar] 451 | 452 | Component.onCompleted: wjs.onQmlLoaded() 453 | } 454 | -------------------------------------------------------------------------------- /player/themes/sleek/qmldir: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jaruba/WebChimeraPlayer/9d1f55dd89b93e9fc5a83e8d9ea86070fc7e0ae2/player/themes/sleek/qmldir -------------------------------------------------------------------------------- /playlist.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | JS Playlist Demo - WebChimera Player 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 |

JavaScript Playlist Demo

18 | 19 |
20 | 21 | 22 | 32 | 33 | 34 | 35 | 36 | --------------------------------------------------------------------------------