1
0
mirror of https://github.com/KDE/latte-dock.git synced 2024-12-23 01:33:50 +03:00

initial commit for Latte !!!

-initial commit based on the latest Now Dock
from the corona branch and beautiful techniques
and designs from the Candil Dock
This commit is contained in:
Michail Vourlakos 2016-12-25 09:25:27 +02:00
commit f9ec1fa5b3
102 changed files with 20279 additions and 0 deletions

7
.gitignore vendored Normal file
View File

@ -0,0 +1,7 @@
*~
.*
!.gitignore
build
corona/build
*.kdev4

86
CMakeLists.txt Normal file
View File

@ -0,0 +1,86 @@
project(nowdock)
cmake_minimum_required(VERSION 3.0 FATAL_ERROR)
set (CMAKE_CXX_STANDARD 11)
set(VERSION 0.5.88)
set(AUTHOR "Michail Vourlakos")
set(EMAIL "mvourlakos@gmail.com")
set(WEBSITE "https://store.kde.org/p/1154578/")
set(QT_MIN_VERSION "5.6.0")
set(KF5_MIN_VERSION "5.26.0")
find_package(ECM 1.8.0 REQUIRED NO_MODULE)
set(CMAKE_MODULE_PATH ${ECM_MODULE_PATH} ${ECM_KDE_MODULE_DIR})
find_package(Qt5 ${QT_MIN_VERSION} CONFIG REQUIRED COMPONENTS
Quick QuickWidgets)
find_package(KF5 ${KF5_MIN_VERSION} REQUIRED COMPONENTS
Plasma PlasmaQuick WindowSystem Declarative
I18n CoreAddons XmlGui DBusAddons Notifications)
FIND_PROGRAM(GETTEXT_MSGFMT_EXECUTABLE msgfmt)
IF(NOT GETTEXT_MSGFMT_EXECUTABLE)
MESSAGE(
"------
NOTE: msgfmt not found. Translations will *not* be installed
------")
ELSE(NOT GETTEXT_MSGFMT_EXECUTABLE)
SET(catalogname plasma_applet_org.kde.nowdock.containment)
ADD_CUSTOM_TARGET(translations-containment ALL)
FILE(GLOB PO_FILES po/containment/*.po)
FOREACH(_poFile ${PO_FILES})
GET_FILENAME_COMPONENT(_poFileName ${_poFile} NAME)
STRING(REGEX REPLACE "^${catalogname}_?" "" _langCode ${_poFileName} )
STRING(REGEX REPLACE "\\.po$" "" _langCode ${_langCode} )
IF( _langCode )
GET_FILENAME_COMPONENT(_lang ${_poFile} NAME_WE)
SET(_gmoFile ${CMAKE_CURRENT_BINARY_DIR}/containment/${_lang}.gmo)
ADD_CUSTOM_COMMAND(TARGET translations-containment
COMMAND ${GETTEXT_MSGFMT_EXECUTABLE} --check -o ${_gmoFile} ${_poFile}
DEPENDS ${_poFile})
INSTALL(FILES ${_gmoFile} DESTINATION ${LOCALE_INSTALL_DIR}/${_langCode}/LC_MESSAGES/ RENAME ${catalogname}.mo)
ENDIF( _langCode )
ENDFOREACH(_poFile ${PO_FILES})
SET(catalogname2 plasma_applet_org.kde.store.nowdock.plasmoid)
ADD_CUSTOM_TARGET(translations-plasmoid ALL)
FILE(GLOB PO_FILES2 po/plasmoid/*.po)
FOREACH(_poFile ${PO_FILES2})
GET_FILENAME_COMPONENT(_poFileName ${_poFile} NAME)
STRING(REGEX REPLACE "^${catalogname2}_?" "" _langCode ${_poFileName} )
STRING(REGEX REPLACE "\\.po$" "" _langCode ${_langCode} )
IF( _langCode )
GET_FILENAME_COMPONENT(_lang ${_poFile} NAME_WE)
SET(_gmoFile ${CMAKE_CURRENT_BINARY_DIR}/plasmoid/${_lang}.gmo)
ADD_CUSTOM_COMMAND(TARGET translations-plasmoid
COMMAND ${GETTEXT_MSGFMT_EXECUTABLE} --check -o ${_gmoFile} ${_poFile}
DEPENDS ${_poFile})
INSTALL(FILES ${_gmoFile} DESTINATION ${LOCALE_INSTALL_DIR}/${_langCode}/LC_MESSAGES/ RENAME ${catalogname2}.mo)
ENDIF( _langCode )
ENDFOREACH(_poFile ${PO_FILES})
ENDIF(NOT GETTEXT_MSGFMT_EXECUTABLE)
add_subdirectory(libnowdock)
add_subdirectory(containment)
plasma_install_package(build/containment/release org.kde.nowdock.containment)
add_subdirectory(plasmoid)
plasma_install_package(build/plasmoid/release org.kde.store.nowdock.plasmoid)
plasma_install_package(shell org.kde.nowdock.shell shells shell)
add_subdirectory(corona)

674
LICENSE Normal file
View File

@ -0,0 +1,674 @@
GNU GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The GNU General Public License is a free, copyleft license for
software and other kinds of works.
The licenses for most software and other practical works are designed
to take away your freedom to share and change the works. By contrast,
the GNU General Public License is intended to guarantee your freedom to
share and change all versions of a program--to make sure it remains free
software for all its users. We, the Free Software Foundation, use the
GNU General Public License for most of our software; it applies also to
any other work released this way by its authors. You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
them if you wish), that you receive source code or can get it if you
want it, that you can change the software or use pieces of it in new
free programs, and that you know you can do these things.
To protect your rights, we need to prevent others from denying you
these rights or asking you to surrender the rights. Therefore, you have
certain responsibilities if you distribute copies of the software, or if
you modify it: responsibilities to respect the freedom of others.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must pass on to the recipients the same
freedoms that you received. You must make sure that they, too, receive
or can get the source code. And you must show them these terms so they
know their rights.
Developers that use the GNU GPL protect your rights with two steps:
(1) assert copyright on the software, and (2) offer you this License
giving you legal permission to copy, distribute and/or modify it.
For the developers' and authors' protection, the GPL clearly explains
that there is no warranty for this free software. For both users' and
authors' sake, the GPL requires that modified versions be marked as
changed, so that their problems will not be attributed erroneously to
authors of previous versions.
Some devices are designed to deny users access to install or run
modified versions of the software inside them, although the manufacturer
can do so. This is fundamentally incompatible with the aim of
protecting users' freedom to change the software. The systematic
pattern of such abuse occurs in the area of products for individuals to
use, which is precisely where it is most unacceptable. Therefore, we
have designed this version of the GPL to prohibit the practice for those
products. If such problems arise substantially in other domains, we
stand ready to extend this provision to those domains in future versions
of the GPL, as needed to protect the freedom of users.
Finally, every program is threatened constantly by software patents.
States should not allow patents to restrict development and use of
software on general-purpose computers, but in those that do, we wish to
avoid the special danger that patents applied to a free program could
make it effectively proprietary. To prevent this, the GPL assures that
patents cannot be used to render the program non-free.
The precise terms and conditions for copying, distribution and
modification follow.
TERMS AND CONDITIONS
0. Definitions.
"This License" refers to version 3 of the GNU General Public License.
"Copyright" also means copyright-like laws that apply to other kinds of
works, such as semiconductor masks.
"The Program" refers to any copyrightable work licensed under this
License. Each licensee is addressed as "you". "Licensees" and
"recipients" may be individuals or organizations.
To "modify" a work means to copy from or adapt all or part of the work
in a fashion requiring copyright permission, other than the making of an
exact copy. The resulting work is called a "modified version" of the
earlier work or a work "based on" the earlier work.
A "covered work" means either the unmodified Program or a work based
on the Program.
To "propagate" a work means to do anything with it that, without
permission, would make you directly or secondarily liable for
infringement under applicable copyright law, except executing it on a
computer or modifying a private copy. Propagation includes copying,
distribution (with or without modification), making available to the
public, and in some countries other activities as well.
To "convey" a work means any kind of propagation that enables other
parties to make or receive copies. Mere interaction with a user through
a computer network, with no transfer of a copy, is not conveying.
An interactive user interface displays "Appropriate Legal Notices"
to the extent that it includes a convenient and prominently visible
feature that (1) displays an appropriate copyright notice, and (2)
tells the user that there is no warranty for the work (except to the
extent that warranties are provided), that licensees may convey the
work under this License, and how to view a copy of this License. If
the interface presents a list of user commands or options, such as a
menu, a prominent item in the list meets this criterion.
1. Source Code.
The "source code" for a work means the preferred form of the work
for making modifications to it. "Object code" means any non-source
form of a work.
A "Standard Interface" means an interface that either is an official
standard defined by a recognized standards body, or, in the case of
interfaces specified for a particular programming language, one that
is widely used among developers working in that language.
The "System Libraries" of an executable work include anything, other
than the work as a whole, that (a) is included in the normal form of
packaging a Major Component, but which is not part of that Major
Component, and (b) serves only to enable use of the work with that
Major Component, or to implement a Standard Interface for which an
implementation is available to the public in source code form. A
"Major Component", in this context, means a major essential component
(kernel, window system, and so on) of the specific operating system
(if any) on which the executable work runs, or a compiler used to
produce the work, or an object code interpreter used to run it.
The "Corresponding Source" for a work in object code form means all
the source code needed to generate, install, and (for an executable
work) run the object code and to modify the work, including scripts to
control those activities. However, it does not include the work's
System Libraries, or general-purpose tools or generally available free
programs which are used unmodified in performing those activities but
which are not part of the work. For example, Corresponding Source
includes interface definition files associated with source files for
the work, and the source code for shared libraries and dynamically
linked subprograms that the work is specifically designed to require,
such as by intimate data communication or control flow between those
subprograms and other parts of the work.
The Corresponding Source need not include anything that users
can regenerate automatically from other parts of the Corresponding
Source.
The Corresponding Source for a work in source code form is that
same work.
2. Basic Permissions.
All rights granted under this License are granted for the term of
copyright on the Program, and are irrevocable provided the stated
conditions are met. This License explicitly affirms your unlimited
permission to run the unmodified Program. The output from running a
covered work is covered by this License only if the output, given its
content, constitutes a covered work. This License acknowledges your
rights of fair use or other equivalent, as provided by copyright law.
You may make, run and propagate covered works that you do not
convey, without conditions so long as your license otherwise remains
in force. You may convey covered works to others for the sole purpose
of having them make modifications exclusively for you, or provide you
with facilities for running those works, provided that you comply with
the terms of this License in conveying all material for which you do
not control copyright. Those thus making or running the covered works
for you must do so exclusively on your behalf, under your direction
and control, on terms that prohibit them from making any copies of
your copyrighted material outside their relationship with you.
Conveying under any other circumstances is permitted solely under
the conditions stated below. Sublicensing is not allowed; section 10
makes it unnecessary.
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
No covered work shall be deemed part of an effective technological
measure under any applicable law fulfilling obligations under article
11 of the WIPO copyright treaty adopted on 20 December 1996, or
similar laws prohibiting or restricting circumvention of such
measures.
When you convey a covered work, you waive any legal power to forbid
circumvention of technological measures to the extent such circumvention
is effected by exercising rights under this License with respect to
the covered work, and you disclaim any intention to limit operation or
modification of the work as a means of enforcing, against the work's
users, your or third parties' legal rights to forbid circumvention of
technological measures.
4. Conveying Verbatim Copies.
You may convey verbatim copies of the Program's source code as you
receive it, in any medium, provided that you conspicuously and
appropriately publish on each copy an appropriate copyright notice;
keep intact all notices stating that this License and any
non-permissive terms added in accord with section 7 apply to the code;
keep intact all notices of the absence of any warranty; and give all
recipients a copy of this License along with the Program.
You may charge any price or no price for each copy that you convey,
and you may offer support or warranty protection for a fee.
5. Conveying Modified Source Versions.
You may convey a work based on the Program, or the modifications to
produce it from the Program, in the form of source code under the
terms of section 4, provided that you also meet all of these conditions:
a) The work must carry prominent notices stating that you modified
it, and giving a relevant date.
b) The work must carry prominent notices stating that it is
released under this License and any conditions added under section
7. This requirement modifies the requirement in section 4 to
"keep intact all notices".
c) You must license the entire work, as a whole, under this
License to anyone who comes into possession of a copy. This
License will therefore apply, along with any applicable section 7
additional terms, to the whole of the work, and all its parts,
regardless of how they are packaged. This License gives no
permission to license the work in any other way, but it does not
invalidate such permission if you have separately received it.
d) If the work has interactive user interfaces, each must display
Appropriate Legal Notices; however, if the Program has interactive
interfaces that do not display Appropriate Legal Notices, your
work need not make them do so.
A compilation of a covered work with other separate and independent
works, which are not by their nature extensions of the covered work,
and which are not combined with it such as to form a larger program,
in or on a volume of a storage or distribution medium, is called an
"aggregate" if the compilation and its resulting copyright are not
used to limit the access or legal rights of the compilation's users
beyond what the individual works permit. Inclusion of a covered work
in an aggregate does not cause this License to apply to the other
parts of the aggregate.
6. Conveying Non-Source Forms.
You may convey a covered work in object code form under the terms
of sections 4 and 5, provided that you also convey the
machine-readable Corresponding Source under the terms of this License,
in one of these ways:
a) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by the
Corresponding Source fixed on a durable physical medium
customarily used for software interchange.
b) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by a
written offer, valid for at least three years and valid for as
long as you offer spare parts or customer support for that product
model, to give anyone who possesses the object code either (1) a
copy of the Corresponding Source for all the software in the
product that is covered by this License, on a durable physical
medium customarily used for software interchange, for a price no
more than your reasonable cost of physically performing this
conveying of source, or (2) access to copy the
Corresponding Source from a network server at no charge.
c) Convey individual copies of the object code with a copy of the
written offer to provide the Corresponding Source. This
alternative is allowed only occasionally and noncommercially, and
only if you received the object code with such an offer, in accord
with subsection 6b.
d) Convey the object code by offering access from a designated
place (gratis or for a charge), and offer equivalent access to the
Corresponding Source in the same way through the same place at no
further charge. You need not require recipients to copy the
Corresponding Source along with the object code. If the place to
copy the object code is a network server, the Corresponding Source
may be on a different server (operated by you or a third party)
that supports equivalent copying facilities, provided you maintain
clear directions next to the object code saying where to find the
Corresponding Source. Regardless of what server hosts the
Corresponding Source, you remain obligated to ensure that it is
available for as long as needed to satisfy these requirements.
e) Convey the object code using peer-to-peer transmission, provided
you inform other peers where the object code and Corresponding
Source of the work are being offered to the general public at no
charge under subsection 6d.
A separable portion of the object code, whose source code is excluded
from the Corresponding Source as a System Library, need not be
included in conveying the object code work.
A "User Product" is either (1) a "consumer product", which means any
tangible personal property which is normally used for personal, family,
or household purposes, or (2) anything designed or sold for incorporation
into a dwelling. In determining whether a product is a consumer product,
doubtful cases shall be resolved in favor of coverage. For a particular
product received by a particular user, "normally used" refers to a
typical or common use of that class of product, regardless of the status
of the particular user or of the way in which the particular user
actually uses, or expects or is expected to use, the product. A product
is a consumer product regardless of whether the product has substantial
commercial, industrial or non-consumer uses, unless such uses represent
the only significant mode of use of the product.
"Installation Information" for a User Product means any methods,
procedures, authorization keys, or other information required to install
and execute modified versions of a covered work in that User Product from
a modified version of its Corresponding Source. The information must
suffice to ensure that the continued functioning of the modified object
code is in no case prevented or interfered with solely because
modification has been made.
If you convey an object code work under this section in, or with, or
specifically for use in, a User Product, and the conveying occurs as
part of a transaction in which the right of possession and use of the
User Product is transferred to the recipient in perpetuity or for a
fixed term (regardless of how the transaction is characterized), the
Corresponding Source conveyed under this section must be accompanied
by the Installation Information. But this requirement does not apply
if neither you nor any third party retains the ability to install
modified object code on the User Product (for example, the work has
been installed in ROM).
The requirement to provide Installation Information does not include a
requirement to continue to provide support service, warranty, or updates
for a work that has been modified or installed by the recipient, or for
the User Product in which it has been modified or installed. Access to a
network may be denied when the modification itself materially and
adversely affects the operation of the network or violates the rules and
protocols for communication across the network.
Corresponding Source conveyed, and Installation Information provided,
in accord with this section must be in a format that is publicly
documented (and with an implementation available to the public in
source code form), and must require no special password or key for
unpacking, reading or copying.
7. Additional Terms.
"Additional permissions" are terms that supplement the terms of this
License by making exceptions from one or more of its conditions.
Additional permissions that are applicable to the entire Program shall
be treated as though they were included in this License, to the extent
that they are valid under applicable law. If additional permissions
apply only to part of the Program, that part may be used separately
under those permissions, but the entire Program remains governed by
this License without regard to the additional permissions.
When you convey a copy of a covered work, you may at your option
remove any additional permissions from that copy, or from any part of
it. (Additional permissions may be written to require their own
removal in certain cases when you modify the work.) You may place
additional permissions on material, added by you to a covered work,
for which you have or can give appropriate copyright permission.
Notwithstanding any other provision of this License, for material you
add to a covered work, you may (if authorized by the copyright holders of
that material) supplement the terms of this License with terms:
a) Disclaiming warranty or limiting liability differently from the
terms of sections 15 and 16 of this License; or
b) Requiring preservation of specified reasonable legal notices or
author attributions in that material or in the Appropriate Legal
Notices displayed by works containing it; or
c) Prohibiting misrepresentation of the origin of that material, or
requiring that modified versions of such material be marked in
reasonable ways as different from the original version; or
d) Limiting the use for publicity purposes of names of licensors or
authors of the material; or
e) Declining to grant rights under trademark law for use of some
trade names, trademarks, or service marks; or
f) Requiring indemnification of licensors and authors of that
material by anyone who conveys the material (or modified versions of
it) with contractual assumptions of liability to the recipient, for
any liability that these contractual assumptions directly impose on
those licensors and authors.
All other non-permissive additional terms are considered "further
restrictions" within the meaning of section 10. If the Program as you
received it, or any part of it, contains a notice stating that it is
governed by this License along with a term that is a further
restriction, you may remove that term. If a license document contains
a further restriction but permits relicensing or conveying under this
License, you may add to a covered work material governed by the terms
of that license document, provided that the further restriction does
not survive such relicensing or conveying.
If you add terms to a covered work in accord with this section, you
must place, in the relevant source files, a statement of the
additional terms that apply to those files, or a notice indicating
where to find the applicable terms.
Additional terms, permissive or non-permissive, may be stated in the
form of a separately written license, or stated as exceptions;
the above requirements apply either way.
8. Termination.
You may not propagate or modify a covered work except as expressly
provided under this License. Any attempt otherwise to propagate or
modify it is void, and will automatically terminate your rights under
this License (including any patent licenses granted under the third
paragraph of section 11).
However, if you cease all violation of this License, then your
license from a particular copyright holder is reinstated (a)
provisionally, unless and until the copyright holder explicitly and
finally terminates your license, and (b) permanently, if the copyright
holder fails to notify you of the violation by some reasonable means
prior to 60 days after the cessation.
Moreover, your license from a particular copyright holder is
reinstated permanently if the copyright holder notifies you of the
violation by some reasonable means, this is the first time you have
received notice of violation of this License (for any work) from that
copyright holder, and you cure the violation prior to 30 days after
your receipt of the notice.
Termination of your rights under this section does not terminate the
licenses of parties who have received copies or rights from you under
this License. If your rights have been terminated and not permanently
reinstated, you do not qualify to receive new licenses for the same
material under section 10.
9. Acceptance Not Required for Having Copies.
You are not required to accept this License in order to receive or
run a copy of the Program. Ancillary propagation of a covered work
occurring solely as a consequence of using peer-to-peer transmission
to receive a copy likewise does not require acceptance. However,
nothing other than this License grants you permission to propagate or
modify any covered work. These actions infringe copyright if you do
not accept this License. Therefore, by modifying or propagating a
covered work, you indicate your acceptance of this License to do so.
10. Automatic Licensing of Downstream Recipients.
Each time you convey a covered work, the recipient automatically
receives a license from the original licensors, to run, modify and
propagate that work, subject to this License. You are not responsible
for enforcing compliance by third parties with this License.
An "entity transaction" is a transaction transferring control of an
organization, or substantially all assets of one, or subdividing an
organization, or merging organizations. If propagation of a covered
work results from an entity transaction, each party to that
transaction who receives a copy of the work also receives whatever
licenses to the work the party's predecessor in interest had or could
give under the previous paragraph, plus a right to possession of the
Corresponding Source of the work from the predecessor in interest, if
the predecessor has it or can get it with reasonable efforts.
You may not impose any further restrictions on the exercise of the
rights granted or affirmed under this License. For example, you may
not impose a license fee, royalty, or other charge for exercise of
rights granted under this License, and you may not initiate litigation
(including a cross-claim or counterclaim in a lawsuit) alleging that
any patent claim is infringed by making, using, selling, offering for
sale, or importing the Program or any portion of it.
11. Patents.
A "contributor" is a copyright holder who authorizes use under this
License of the Program or a work on which the Program is based. The
work thus licensed is called the contributor's "contributor version".
A contributor's "essential patent claims" are all patent claims
owned or controlled by the contributor, whether already acquired or
hereafter acquired, that would be infringed by some manner, permitted
by this License, of making, using, or selling its contributor version,
but do not include claims that would be infringed only as a
consequence of further modification of the contributor version. For
purposes of this definition, "control" includes the right to grant
patent sublicenses in a manner consistent with the requirements of
this License.
Each contributor grants you a non-exclusive, worldwide, royalty-free
patent license under the contributor's essential patent claims, to
make, use, sell, offer for sale, import and otherwise run, modify and
propagate the contents of its contributor version.
In the following three paragraphs, a "patent license" is any express
agreement or commitment, however denominated, not to enforce a patent
(such as an express permission to practice a patent or covenant not to
sue for patent infringement). To "grant" such a patent license to a
party means to make such an agreement or commitment not to enforce a
patent against the party.
If you convey a covered work, knowingly relying on a patent license,
and the Corresponding Source of the work is not available for anyone
to copy, free of charge and under the terms of this License, through a
publicly available network server or other readily accessible means,
then you must either (1) cause the Corresponding Source to be so
available, or (2) arrange to deprive yourself of the benefit of the
patent license for this particular work, or (3) arrange, in a manner
consistent with the requirements of this License, to extend the patent
license to downstream recipients. "Knowingly relying" means you have
actual knowledge that, but for the patent license, your conveying the
covered work in a country, or your recipient's use of the covered work
in a country, would infringe one or more identifiable patents in that
country that you have reason to believe are valid.
If, pursuant to or in connection with a single transaction or
arrangement, you convey, or propagate by procuring conveyance of, a
covered work, and grant a patent license to some of the parties
receiving the covered work authorizing them to use, propagate, modify
or convey a specific copy of the covered work, then the patent license
you grant is automatically extended to all recipients of the covered
work and works based on it.
A patent license is "discriminatory" if it does not include within
the scope of its coverage, prohibits the exercise of, or is
conditioned on the non-exercise of one or more of the rights that are
specifically granted under this License. You may not convey a covered
work if you are a party to an arrangement with a third party that is
in the business of distributing software, under which you make payment
to the third party based on the extent of your activity of conveying
the work, and under which the third party grants, to any of the
parties who would receive the covered work from you, a discriminatory
patent license (a) in connection with copies of the covered work
conveyed by you (or copies made from those copies), or (b) primarily
for and in connection with specific products or compilations that
contain the covered work, unless you entered into that arrangement,
or that patent license was granted, prior to 28 March 2007.
Nothing in this License shall be construed as excluding or limiting
any implied license or other defenses to infringement that may
otherwise be available to you under applicable patent law.
12. No Surrender of Others' Freedom.
If conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot convey a
covered work so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you may
not convey it at all. For example, if you agree to terms that obligate you
to collect a royalty for further conveying from those to whom you convey
the Program, the only way you could satisfy both those terms and this
License would be to refrain entirely from conveying the Program.
13. Use with the GNU Affero General Public License.
Notwithstanding any other provision of this License, you have
permission to link or combine any covered work with a work licensed
under version 3 of the GNU Affero General Public License into a single
combined work, and to convey the resulting work. The terms of this
License will continue to apply to the part which is the covered work,
but the special requirements of the GNU Affero General Public License,
section 13, concerning interaction through a network will apply to the
combination as such.
14. Revised Versions of this License.
The Free Software Foundation may publish revised and/or new versions of
the GNU General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the
Program specifies that a certain numbered version of the GNU General
Public License "or any later version" applies to it, you have the
option of following the terms and conditions either of that numbered
version or of any later version published by the Free Software
Foundation. If the Program does not specify a version number of the
GNU General Public License, you may choose any version ever published
by the Free Software Foundation.
If the Program specifies that a proxy can decide which future
versions of the GNU General Public License can be used, that proxy's
public statement of acceptance of a version permanently authorizes you
to choose that version for the Program.
Later license versions may give you additional or different
permissions. However, no additional obligations are imposed on any
author or copyright holder as a result of your choosing to follow a
later version.
15. Disclaimer of Warranty.
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. Limitation of Liability.
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
SUCH DAMAGES.
17. Interpretation of Sections 15 and 16.
If the disclaimer of warranty and limitation of liability provided
above cannot be given local legal effect according to their terms,
reviewing courts shall apply local law that most closely approximates
an absolute waiver of all civil liability in connection with the
Program, unless a warranty or assumption of liability accompanies a
copy of the Program in return for a fee.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
state the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
{one line to give the program's name and a brief idea of what it does.}
Copyright (C) {year} {name of author}
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Also add information on how to contact you by electronic and paper mail.
If the program does terminal interaction, make it output a short
notice like this when it starts in an interactive mode:
{project} Copyright (C) {year} {fullname}
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, your program's commands
might be different; for a GUI interface, you would use an "about box".
You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary.
For more information on this, and how to apply and follow the GNU GPL, see
<http://www.gnu.org/licenses/>.
The GNU General Public License does not permit incorporating your program
into proprietary programs. If your program is a subroutine library, you
may consider it more useful to permit linking proprietary applications with
the library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License. But first, please read
<http://www.gnu.org/philosophy/why-not-lgpl.html>.

43
README.md Normal file
View File

@ -0,0 +1,43 @@
About
=====
This is a panel and plasmoid for Plasma 5 which is trying to implement a
mac style effect for its applets. It uses the Now Dock plasmoid
for its configuration and complements it as one single area
for which the user can add its applets. The applets as the user
windows are going to create a nice zoom effect on hovering.
Installation
============
- **Notice:** First uninstall any locally installed now dock components by using the **uninstall-local.sh** script
####installation script####
- _sh install-global.sh_
Now Dock Panel is now ready to be used from right-click menu in the Desktop
Translators
============
For translations you can use the **po/nowdockpanel/plasma_applet_org.kde.store.nowdock.panel.pot**, **po/nowdockplasmoid/plasma_applet_org.kde.store.nowdock.plasmoid.pot** files and either make a **Pull Request** for your language or upload the your language file at https://github.com/psifidotos/nowdock-panel/issues/17
Requirements
==========
* Plasma >= 5.8.0
**development packages for:**
* Qt5Core >= 5.6.0
* Qt5Qml >= 5.6.0
* Qt5Quick >= 5.6.0
* KF5Plasma >= 5.25.0
* KF5PlasmaQuick >= 5.25.0
* KF5WindowSystem >= 5.25.0
* KF5KDELibs4Support >= 5.25.0
* KF5CoreAddons >= 5.25.0

40
astylerc Normal file
View File

@ -0,0 +1,40 @@
#BracketStyleOptions
--style=stroustrup
--keep-one-line-blocks
--keep-one-line-statements
#TabOptions
# --indent=force-tab=4
--indent=spaces=4
#BracketModifyOptions
--attach-namespaces
--attach-inlines
#FormattingOptions
--convert-tabs
--max-code-length=80
--keep-one-line-blocks
--keep-one-line-statements
--close-templates
--max-code-length=200
#IndentationOptions
--indent-switches
--indent-preproc-block
--indent-preproc-define
--min-conditional-indent=1
--max-instatement-indent=40
#PaddingOptions
--break-blocks
--pad-oper
--unpad-paren
--pad-header
--fill-empty-lines
--align-pointer=name
--align-reference=name
#Others
--preserve-date
--verbose

View File

@ -0,0 +1,22 @@
[Desktop Entry]
Encoding=UTF-8
_Name=Now Dock
_Comment=A dock for Plasma that tries to animate its plasmoids on hovering
Type=Service
Keywords=
NoDisplay=true
X-KDE-PluginInfo-Author=@AUTHOR@
X-KDE-PluginInfo-Email=@EMAIL@
X-KDE-PluginInfo-Name=org.kde.nowdock.containment
X-KDE-PluginInfo-Version=@VERSION@
X-KDE-PluginInfo-Website=@WEBSITE@
X-KDE-PluginInfo-Category=
X-KDE-PluginInfo-Depends=
X-KDE-PluginInfo-License=GPL
X-KDE-PluginInfo-EnabledByDefault=true
X-KDE-ServiceTypes=Plasma/Applet,Plasma/Containment
X-Plasma-API=declarativeappletscript
X-Plasma-MainScript=ui/main.qml
X-Plasma-ContainmentType=Panel

View File

@ -0,0 +1,3 @@
file(COPY "contents" DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/release)
#update the version number in the configuration window
configure_file(metadata.desktop.cmake release/metadata.desktop)

View File

@ -0,0 +1,273 @@
/*
* Copyright 2013 Michail Vourlakos <mvourlakos@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 2.010-1301, USA.
*/
var layout;
var root;
var plasmoid;
var lastSpacer;
function restore() {
var configString = String(plasmoid.configuration.appletOrder)
//array, a cell for encoded item order
var itemsArray = configString.split(";");
//map applet id->order in panel
var idsOrder = new Object();
//map order in panel -> applet pointer
var appletsOrder = new Object();
for (var i = 0; i < itemsArray.length; i++) {
//property name: applet id
//property value: order
idsOrder[itemsArray[i]] = i;
}
for (var i = 0; i < plasmoid.applets.length; ++i) {
if (idsOrder[plasmoid.applets[i].id] !== undefined) {
appletsOrder[idsOrder[plasmoid.applets[i].id]] = plasmoid.applets[i];
//ones that weren't saved in AppletOrder go to the end
} else {
appletsOrder["unordered"+i] = plasmoid.applets[i];
}
}
//finally, restore the applets in the correct order
for (var i in appletsOrder) {
root.addApplet(appletsOrder[i], -1, -1)
}
//add the splitter in the correct position if it exists
if(plasmoid.configuration.splitterPosition !== -1){
root.addInternalViewSplitter(plasmoid.configuration.splitterPosition);
}
//rewrite, so if in the orders there were now invalid ids or if some were missing creates a correct list instead
save();
restoreLocks();
//update layouts in case there is a splitter in them
root.updateLayouts();
}
function restoreLocks() {
var configString = String(plasmoid.configuration.lockedZoomApplets)
//array, a cell for encoded item order
var itemsArray = configString.split(";");
for (var i = 0; i < itemsArray.length; i++) {
for (var j = 0; j < layout.children.length; ++j) {
var child = layout.children[j];
if (child.applet && (child.applet.id == itemsArray[i])) {
child.lockZoom = true;
}
}
}
}
function save() {
var ids = new Array();
var splitterExists = false;
for (var i = 0; i < layout.children.length; ++i) {
var child = layout.children[i];
if (child.applet) {
ids.push(child.applet.id);
}
else if(child.isInternalViewSplitter && plasmoid.configuration.panelPosition === 10){
splitterExists = true;
plasmoid.configuration.splitterPosition = i;
}
}
if(!splitterExists)
plasmoid.configuration.splitterPosition = -1;
plasmoid.configuration.appletOrder = ids.join(';');
}
function saveLocks() {
var ids = new Array();
for (var i = 0; i < layout.children.length; ++i) {
var child = layout.children[i];
if (child.applet && child.lockZoom) {
ids.push(child.applet.id);
}
}
plasmoid.configuration.lockedZoomApplets = ids.join(';');
}
function removeApplet (applet) {
for (var i = layout.children.length - 1; i >= 0; --i) {
var child = layout.children[i];
if (child.applet === applet) {
child.destroy();
}
}
}
//insert item2 before item1
function insertBefore(item1, item2) {
if (item1 === item2) {
return;
}
var removed = new Array();
var child;
var i;
for (i = layout.children.length - 1; i >= 0; --i) {
child = layout.children[i];
removed.push(child);
child.parent = root;
if (child === item1) {
break;
}
}
item2.parent = layout;
for (var j = removed.length - 1; j >= 0; --j) {
removed[j].parent = layout;
}
return i;
}
//insert item2 after item1
function insertAfter(item1, item2) {
if (item1 === item2) {
return;
}
var removed = new Array();
var child;
var i;
for (i = layout.children.length - 1; i >= 0; --i) {
child = layout.children[i];
//never ever insert after lastSpacer
if (child === lastSpacer && item1 === lastSpacer) {
removed.push(child);
child.parent = root;
break;
} else if (child === item1) {
//Already in position, do nothing
if (layout.children[i+1] === item2) {
return;
}
break;
}
removed.push(child);
child.parent = root;
}
item2.parent = layout;
for (var j = removed.length - 1; j >= 0; --j) {
removed[j].parent = layout;
}
return i;
}
function insertAtIndex(item, position) {
if (position < 0 || (position >= layout.children.length && position !== 0)) {
return;
}
//never ever insert after lastSpacer
var firstItem = (layout.children.length === 1) && (layout.children[0] === lastSpacer);
//Important !!! , this is used to add the first item
if(firstItem){
lastSpacer.parent = root;
position = 0;
}
if(layout.children.length > 0){
if (layout.children[position] === lastSpacer) {
--position;
}
}
var removedItems = new Array();
var totalChildren = layout.children.length;
for (var i = position; i < totalChildren; ++i) {
var child = layout.children[position];
child.parent = root;
removedItems.push(child);
}
item.parent = layout;
for (var i in removedItems) {
removedItems[i].parent = layout;
}
}
function insertAtCoordinates(item, x, y) {
if (root.isHorizontal) {
y = layout.height / 2;
} else {
x = layout.width / 2;
}
var child = layout.childAt(x, y);
//if we got a place inside the space between 2 applets, we have to find it manually
if (!child) {
if (root.isHorizontal) {
for (var i = 0; i < layout.children.length; ++i) {
var candidate = layout.children[i];
if (x >= candidate.x && x < candidate.x + candidate.width + layout.rowSpacing) {
child = candidate;
break;
}
}
} else {
for (var i = 0; i < layout.children.length; ++i) {
var candidate = layout.children[i];
if (y >= candidate.x && y < candidate.y + candidate.height + layout.columnSpacing) {
child = candidate;
break;
}
}
}
}
//already in position
if (child === item) {
return;
}
if (!child) {
child = layout.children[0];
}
item.parent = root;
//PlasmaCore.Types.Vertical = 3
if ((plasmoid.formFactor === 3 && y < child.y + child.height/2) ||
(plasmoid.formFactor !== 3 && x < child.x + child.width/2)) {
return insertBefore(child, item);
} else {
return insertAfter(child, item);
}
}

View File

@ -0,0 +1,67 @@
<?xml version="1.0" encoding="UTF-8"?>
<kcfg xmlns="http://www.kde.org/standards/kcfg/1.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.kde.org/standards/kcfg/1.0
http://www.kde.org/standards/kcfg/1.0/kcfg.xsd" >
<kcfgfile name=""/>
<group name="General">
<entry name="appletOrder" type="String">
<label>encoded order of items</label>
</entry>
<entry name="lockedZoomApplets" type="String">
<label>applets that lock the zoom effect</label>
</entry>
<entry name="panelPosition" type="Enum">
<choices>
<choice name="Center"/>
<choice name="Left"/>
<choice name="Right"/>
<choice name="Top"/>
<choice name="Bottom"/>
</choices>
<default>0</default>
</entry>
<entry name="panelVisibility" type="Enum">
<choices>
<choice name="BelowActive"/>
<choice name="BelowMaximized"/>
<choice name="LetWindowsCover"/>
<choice name="WindowsGoBelow"/>
<choice name="AutoHide"/>
<choice name="AlwaysVisible"/>
</choices>
<default>0</default>
</entry>
<entry name="zoomLevel" type="Int">
<default>10</default>
</entry>
<entry name="iconSize" type="Int">
<default>64</default>
</entry>
<entry name="useThemePanel" type="Bool">
<default>false</default>
</entry>
<entry name="panelSize" type="Int">
<default>58</default>
</entry>
<entry name="automaticIconSize" type="Bool">
<default>false</default>
</entry>
<entry name="smallAutomaticIconJumps" type="Bool">
<default>true</default>
</entry>
<entry name="splitterPosition" type="Int">
<default>-1</default>
</entry>
<entry name="shadows" type="Enum">
<label>Shadows for the applets</label>
<choices>
<choice name="None"/>
<choice name="Locked"/>
<choice name="All"/>
</choices>
<default>1</default>
</entry>
</group>
</kcfg>

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 792 B

View File

@ -0,0 +1,40 @@
/*
* Copyright 2013 Michail Vourlakos <mvourlakos@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 2.010-1301, USA.
*/
import QtQuick 2.1
Item{
id: newDroppedLauncherVisual
anchors.fill: parent
Rectangle{
anchors.fill: parent
radius: root.iconSize/10
property color tempColor: "#aa222222"
color: tempColor
border.width: 1
border.color: "#ff656565"
property int crossSize: Math.min(parent.width/2, parent.height/2)
Rectangle{width: parent.crossSize; height: 4; radius:2; anchors.centerIn: parent; color: theme.highlightColor}
Rectangle{width: 4; height: parent.crossSize; radius:2; anchors.centerIn: parent; color: theme.highlightColor}
}
}

View File

@ -0,0 +1,870 @@
/*
* Copyright 2013 Michail Vourlakos <mvourlakos@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 2.010-1301, USA.
*/
import QtQuick 2.1
import QtQuick.Layouts 1.1
import QtGraphicalEffects 1.0
import org.kde.plasma.plasmoid 2.0
import org.kde.plasma.core 2.0 as PlasmaCore
import org.kde.plasma.components 2.0 as PlasmaComponents
import org.kde.kquickcontrolsaddons 2.0
Item {
id: container
visible: false
width: root.isHorizontal ? computeWidth : computeWidth + shownAppletMargin
height: root.isVertical ? computeHeight : computeHeight + shownAppletMargin
property bool animationsEnabled: true
property bool animationWasSent: false //protection flag for animation broadcasting
property bool canBeHovered: true
property bool showZoomed: false
property bool lockZoom: false
property bool isInternalViewSplitter: false
property bool isZoomed: false
property int animationTime: root.durationTime* (1.2 *units.shortDuration) // 70
property int hoveredIndex: layoutsContainer.hoveredIndex
property int index: -1
property int appletMargin: (applet && (applet.pluginName === "org.kde.store.nowdock.plasmoid"))
|| isInternalViewSplitter
|| root.reverseLinesPosition ? 0 : root.statesLineSize
property int maxWidth: root.isHorizontal ? root.height : root.width
property int maxHeight: root.isHorizontal ? root.height : root.width
property int shownAppletMargin: applet && (applet.pluginName === "org.kde.plasma.systemtray") ? 0 : appletMargin
property int status: applet ? applet.status : -1
//property real animationStep: root.iconSize / 8
property real animationStep: 6
property real computeWidth: root.isVertical ? wrapper.width :
hiddenSpacerLeft.width+wrapper.width+hiddenSpacerRight.width
property real computeHeight: root.isVertical ? hiddenSpacerLeft.height + wrapper.height + hiddenSpacerRight.height :
wrapper.height
property string title: isInternalViewSplitter ? "Now Dock Splitter" : ""
property Item applet
property Item nowDock: applet && (applet.pluginName === "org.kde.store.nowdock.plasmoid") ?
(applet.children[0] ? applet.children[0] : null) : null
property Item appletWrapper: applet &&
((applet.pluginName === "org.kde.store.nowdock.plasmoid") ||
(applet.pluginName === "org.kde.plasma.systemtray")) ? wrapper : wrapperContainer
property alias containsMouse: appletMouseArea.containsMouse
property alias pressed: appletMouseArea.pressed
/*onComputeHeightChanged: {
if(index==0)
console.log(computeHeight);
}*/
/// BEGIN functions
function checkIndex(){
index = -1;
for(var i=0; i<mainLayout.count; ++i){
if(mainLayout.children[i] == container){
index = i;
break;
}
}
for(var i=0; i<secondLayout.count; ++i){
if(secondLayout.children[i] == container){
//create a very high index in order to not need to exchange hovering messages
//between mainLayout and secondLayout
index = secondLayout.beginIndex + i;
break;
}
}
if(container.nowDock){
if(index===0 || index===secondLayout.beginIndex)
nowDock.disableLeftSpacer = false;
else
nowDock.disableLeftSpacer = true;
if(index===mainLayout.count-1 || index === secondLayout.beginIndex + secondLayout.count - 1)
nowDock.disableRightSpacer = false;
else
nowDock.disableRightSpacer = true;
}
}
//this functions gets the signal from the plasmoid, it can be used for signal items
//outside the NowDock Plasmoid
//property int debCounter: 0;
function interceptNowDockUpdateScale(dIndex, newScale, step){
if(plasmoid.immutable){
if(dIndex === -1){
layoutsContainer.updateScale(index-1,newScale, step);
}
else if(dIndex === root.tasksCount){
// debCounter++;
// console.log(debCounter+ " "+dIndex+" "+newScale+" received...");
layoutsContainer.updateScale(index+1,newScale, step);
}
}
}
function clearZoom(){
if(wrapper)
wrapper.zoomScale = 1;
}
function checkCanBeHovered(){
if ( ((applet && (applet.Layout.minimumWidth > root.iconSize) && root.isHorizontal) ||
(applet && (applet.Layout.minimumHeight > root.iconSize) && root.isVertical))
&& (applet && applet.pluginName !== "org.kde.plasma.panelspacer") ){
canBeHovered = false;
}
else{
canBeHovered = true;
}
}
///END functions
//BEGIN connections
onAppletChanged: {
if (!applet) {
destroy();
}
}
onHoveredIndexChanged:{
if ( (Math.abs(hoveredIndex-index) > 1)||(hoveredIndex == -1) )
wrapper.zoomScale = 1;
}
onNowDockChanged: {
if(container.nowDock){
root.nowDock = container.nowDock;
root.nowDockContainer = container;
nowDock.nowDockPanel = root;
nowDock.forceHidePanel = true;
nowDock.updateScale.connect(interceptNowDockUpdateScale);
}
}
onShowZoomedChanged: {
if(showZoomed){
var newZ = container.maxHeight / root.iconSize;
wrapper.zoomScale = newZ;
}
else{
wrapper.zoomScale = 1;
}
}
Component.onCompleted: {
checkIndex();
root.updateIndexes.connect(checkIndex);
root.clearZoomSignal.connect(clearZoom);
}
Component.onDestruction: {
root.updateIndexes.disconnect(checkIndex);
root.clearZoomSignal.disconnect(clearZoom);
}
///END connections
PlasmaComponents.BusyIndicator {
z: 1000
visible: applet && applet.busy
running: visible
anchors.centerIn: parent
width: Math.min(parent.width, parent.height)
height: width
}
/* Rectangle{
anchors.fill: parent
color: "transparent"
border.color: "green"
border.width: 1
} */
Flow{
id: appletFlow
width: container.computeWidth
height: container.computeHeight
anchors.rightMargin: (nowDock || (showZoomed && !plasmoid.immutable)) ||
(plasmoid.location !== PlasmaCore.Types.RightEdge) ? 0 : shownAppletMargin
anchors.leftMargin: (nowDock || (showZoomed && !plasmoid.immutable)) ||
(plasmoid.location !== PlasmaCore.Types.LeftEdge) ? 0 : shownAppletMargin
anchors.topMargin: (nowDock || (showZoomed && !plasmoid.immutable)) ||
(plasmoid.location !== PlasmaCore.Types.TopEdge)? 0 : shownAppletMargin
anchors.bottomMargin: (nowDock || (showZoomed && !plasmoid.immutable)) ||
(plasmoid.location !== PlasmaCore.Types.BottomEdge) ? 0 : shownAppletMargin
// a hidden spacer for the first element to add stability
// IMPORTANT: hidden spacers must be tested on vertical !!!
Item{
id: hiddenSpacerLeft
//we add one missing pixel from calculations
width: root.isHorizontal ? nHiddenSize : wrapper.width
height: root.isHorizontal ? wrapper.height : nHiddenSize
///check also if this is the first plasmoid in secondLayout
visible: (container.index === 0) || (container.index === secondLayout.beginIndex)
property real nHiddenSize: (nScale > 0) ? (root.realSize * nScale) : 0
property real nScale: 0
Behavior on nScale {
NumberAnimation { duration: container.animationTime }
}
/* Rectangle{
width: 1
height: parent.height
x: parent.width/2
border.width: 1
border.color: "red"
color: "transparent"
} */
}
Item{
id: wrapper
width: Math.round( nowDock ? ((container.showZoomed && root.isVertical) ?
scaledWidth : nowDock.tasksWidth) : scaledWidth )
height: Math.round( nowDock ? ((container.showZoomed && root.isHorizontal) ?
scaledHeight : nowDock.tasksHeight ): scaledHeight )
property bool disableScaleWidth: false
property bool disableScaleHeight: false
property bool immutable: plasmoid.immutable
property int appletMinimumWidth: applet && applet.Layout ? applet.Layout.minimumWidth : -1
property int appletMinimumHeight: applet && applet.Layout ? applet.Layout.minimumHeight : -1
property int appletPreferredWidth: applet && applet.Layout ? applet.Layout.preferredWidth : -1
property int appletPreferredHeight: applet && applet.Layout ? applet.Layout.preferredHeight : -1
property int appletMaximumWidth: applet && applet.Layout ? applet.Layout.maximumWidth : -1
property int appletMaximumHeight: applet && applet.Layout ? applet.Layout.maximumHeight : -1
property int iconSize: root.iconSize
property real scaledWidth: zoomScaleWidth * (layoutWidth + root.iconMargin)
property real scaledHeight: zoomScaleHeight * (layoutHeight + root.iconMargin)
property real zoomScaleWidth: disableScaleWidth ? 1 : zoomScale
property real zoomScaleHeight: disableScaleHeight ? 1 : zoomScale
property int layoutWidthResult: 0
property int layoutWidth
property int layoutHeight
// property int localMoreSpace: root.reverseLinesPosition ? root.statesLineSize + 2 : appletMargin
property int localMoreSpace: appletMargin
property int moreHeight: ((applet && (applet.pluginName === "org.kde.plasma.systemtray")) || root.reverseLinesPosition)
&& root.isHorizontal ? localMoreSpace : 0
property int moreWidth: ((applet && (applet.pluginName === "org.kde.plasma.systemtray")) || root.reverseLinesPosition)
&& root.isVertical ? localMoreSpace : 0
property real center: width / 2
property real zoomScale: 1
property alias index: container.index
// property int pHeight: applet ? applet.Layout.preferredHeight : -10
/*function debugLayouts(){
if(applet){
console.log("---------- "+ applet.pluginName +" ----------");
console.log("MinW "+applet.Layout.minimumWidth);
console.log("PW "+applet.Layout.preferredWidth);
console.log("MaxW "+applet.Layout.maximumWidth);
console.log("FillW "+applet.Layout.fillWidth);
console.log("-----");
console.log("MinH "+applet.Layout.minimumHeight);
console.log("PH "+applet.Layout.preferredHeight);
console.log("MaxH "+applet.Layout.maximumHeight);
console.log("FillH "+applet.Layout.fillHeight);
console.log("-----");
console.log("LayoutW: " + layoutWidth);
console.log("LayoutH: " + layoutHeight);
}
}
onLayoutWidthChanged: {
debugLayouts();
}
onLayoutHeightChanged: {
debugLayouts();
}*/
onAppletMinimumWidthChanged: {
if(zoomScale == 1)
checkCanBeHovered();
updateLayoutWidth();
}
onAppletMinimumHeightChanged: {
if(zoomScale == 1)
checkCanBeHovered();
updateLayoutHeight();
}
onAppletPreferredWidthChanged: updateLayoutWidth();
onAppletPreferredHeightChanged: updateLayoutHeight();
onAppletMaximumWidthChanged: updateLayoutWidth();
onAppletMaximumHeightChanged: updateLayoutHeight();
onIconSizeChanged: {
updateLayoutWidth();
updateLayoutHeight();
}
onImmutableChanged: {
updateLayoutWidth();
updateLayoutHeight();
}
onZoomScaleChanged: {
if ((zoomScale > 1) && !container.isZoomed) {
container.isZoomed = true;
if (plasmoid.immutable && !animationWasSent) {
root.appletsAnimations++;
animationWasSent = true;
}
} else if ((zoomScale == 1) && container.isZoomed) {
container.isZoomed = false;
if (plasmoid.immutable && animationWasSent) {
root.appletsAnimations--;
animationWasSent = false;
}
}
}
function updateLayoutHeight(){
if(container.isInternalViewSplitter){
if(plasmoid.immutable)
layoutHeight = 0;
else
layoutHeight = root.iconSize;// + moreHeight + root.statesLineSize;
}
else if(applet && applet.pluginName === "org.kde.plasma.panelspacer"){
layoutHeight = root.iconSize + moreHeight;
}
else if(applet && applet.pluginName === "org.kde.plasma.systemtray" && root.isHorizontal){
layoutHeight = root.iconSize+root.iconMargin+root.statesLineSize/2;
}
else{
if(applet && (applet.Layout.minimumHeight > root.iconSize) && root.isVertical && (!canBeHovered)){
// return applet.Layout.minimumHeight;
layoutHeight = applet.Layout.minimumHeight;
} //it is used for plasmoids that need to scale only one axis... e.g. the Weather Plasmoid
else if(applet
&& ( (applet.Layout.maximumHeight < root.iconSize) || (applet.Layout.preferredHeight > root.iconSize))
&& root.isVertical
&& !disableScaleWidth
&& plasmoid.immutable ){
disableScaleHeight = true;
//this way improves performance, probably because during animation the preferred sizes update a lot
if((applet.Layout.maximumHeight < root.iconSize)){
layoutHeight = applet.Layout.maximumHeight;
}
else if (applet.Layout.minimumHeight > root.iconSize){
layoutHeight = applet.Layout.minimumHeight;
}
else if ((applet.Layout.preferredHeight > root.iconSize)){
layoutHeight = applet.Layout.preferredHeight;
}
else{
layoutHeight = root.iconSize + moreHeight;
}
}
else
layoutHeight = root.iconSize + moreHeight;
}
//return root.iconSize + moreHeight;
}
function updateLayoutWidth(){
if(container.isInternalViewSplitter){
if(plasmoid.immutable)
layoutWidth = 0;
else
layoutWidth = root.iconSize; //+ moreWidth+ root.statesLineSize;
}
else if(applet && applet.pluginName === "org.kde.plasma.panelspacer"){
layoutWidth = root.iconSize + moreWidth;
}
else if(applet && applet.pluginName === "org.kde.plasma.systemtray" && root.isVertical){
layoutWidth = root.iconSize+root.iconMargin+root.statesLineSize/2;
}
else{
if(applet && (applet.Layout.minimumWidth > root.iconSize) && root.isHorizontal && (!canBeHovered)){
layoutWidth = applet.Layout.minimumWidth;
} //it is used for plasmoids that need to scale only one axis... e.g. the Weather Plasmoid
else if(applet
&& ( (applet.Layout.maximumWidth < root.iconSize) || (applet.Layout.preferredWidth > root.iconSize))
&& root.isHorizontal
&& !disableScaleHeight
&& plasmoid.immutable){
disableScaleWidth = true;
//this way improves performance, probably because during animation the preferred sizes update a lot
if((applet.Layout.maximumWidth < root.iconSize)){
// return applet.Layout.maximumWidth;
layoutWidth = applet.Layout.maximumWidth;
}
else if (applet.Layout.minimumWidth > root.iconSize){
layoutWidth = applet.Layout.minimumWidth;
}
else if (applet.Layout.preferredWidth > root.iconSize){
layoutWidth = applet.Layout.preferredWidth;
}
else{
layoutWidth = root.iconSize + moreWidth;
}
}
else{
//return root.iconSize + moreWidth;
layoutWidth = root.iconSize + moreWidth;
}
}
}
Item{
id:wrapperContainer
width: Math.round( container.isInternalViewSplitter ? wrapper.layoutWidth : parent.zoomScaleWidth * wrapper.layoutWidth )
height: Math.round( container.isInternalViewSplitter ? wrapper.layoutHeight : parent.zoomScaleHeight * wrapper.layoutHeight )
anchors.centerIn: parent
}
//spacer background
Loader{
anchors.fill: wrapperContainer
active: applet && (applet.pluginName === "org.kde.plasma.panelspacer") && !plasmoid.immutable
sourceComponent: Rectangle{
anchors.fill: parent
border.width: 1
border.color: theme.textColor
color: "transparent"
opacity: 0.7
radius: root.iconMargin
Rectangle{
anchors.centerIn: parent
color: parent.border.color
width: parent.width - 1
height: parent.height - 1
opacity: 0.2
}
}
}
Loader{
anchors.fill: wrapperContainer
active: container.isInternalViewSplitter
&& !plasmoid.immutable
rotation: root.isVertical ? 90 : 0
sourceComponent: Image{
id:splitterImage
anchors.fill: parent
source:"../icons/splitter.png"
layer.enabled: true
layer.effect: DropShadow {
radius: shadowSize
samples: 2 * radius
color: "#ff080808"
verticalOffset: 2
property int shadowSize : Math.ceil(root.iconSize / 10)
}
Component.onCompleted: wrapper.zoomScale = 1.1
}
}
///Shadow in applets
Loader{
anchors.fill: container.appletWrapper
active: container.applet
&&((plasmoid.configuration.shadows === 1 /*Locked Applets*/
&& (!container.canBeHovered || (container.lockZoom && (applet.pluginName !== "org.kde.store.nowdock.plasmoid"))) )
|| (plasmoid.configuration.shadows === 2 /*All Applets*/
&& (applet.pluginName !== "org.kde.store.nowdock.plasmoid")))
sourceComponent: DropShadow{
anchors.fill: parent
color: "#ff080808"
samples: 2 * radius
source: container.applet
radius: shadowSize
verticalOffset: 2
property int shadowSize : Math.ceil(root.iconSize / 12)
}
}
BrightnessContrast{
id:hoveredImage
anchors.fill: wrapperContainer
enabled: opacity != 0 ? true : false
opacity: appletMouseArea.containsMouse ? 1 : 0
brightness: 0.25
source: wrapperContainer
Behavior on opacity {
NumberAnimation { duration: 300 }
}
}
BrightnessContrast {
id: clickedEffect
anchors.fill: wrapperContainer
source: wrapperContainer
}
/* onHeightChanged: {
if ((index == 1)|| (index==3)){
console.log("H: "+index+" ("+zoomScale+"). "+currentLayout.children[1].height+" - "+currentLayout.children[3].height+" - "+(currentLayout.children[1].height+currentLayout.children[3].height));
}
}
onZoomScaleChanged:{
if ((index == 1)|| (index==3)){
console.log(index+" ("+zoomScale+"). "+currentLayout.children[1].height+" - "+currentLayout.children[3].height+" - "+(currentLayout.children[1].height+currentLayout.children[3].height));
}
}*/
/* Rectangle{
anchors.fill: parent
color: "transparent"
border.color: "red"
border.width: 1
} */
Behavior on zoomScale {
NumberAnimation { duration: container.animationTime }
}
function calculateScales( currentMousePosition ){
var distanceFromHovered = Math.abs(index - layoutsContainer.hoveredIndex);
// A new algorithm tryig to make the zoom calculation only once
// and at the same time fixing glitches
if ((distanceFromHovered == 0)&&
(currentMousePosition > 0) ){
var rDistance = Math.abs(currentMousePosition - center);
//check if the mouse goes right or down according to the center
var positiveDirection = ((currentMousePosition - center) >= 0 );
//finding the zoom center e.g. for zoom:1.7, calculates 0.35
var zoomCenter = (root.zoomFactor - 1) / 2
//computes the in the scale e.g. 0...0.35 according to the mouse distance
//0.35 on the edge and 0 in the center
var firstComputation = (rDistance / center) * zoomCenter;
//calculates the scaling for the neighbour tasks
var bigNeighbourZoom = Math.min(1 + zoomCenter + firstComputation, root.zoomFactor);
var smallNeighbourZoom = Math.max(1 + zoomCenter - firstComputation, 1);
bigNeighbourZoom = Number(bigNeighbourZoom.toFixed(2));
smallNeighbourZoom = Number(smallNeighbourZoom.toFixed(2));
var leftScale;
var rightScale;
if(positiveDirection === true){
rightScale = bigNeighbourZoom;
leftScale = smallNeighbourZoom;
}
else {
rightScale = smallNeighbourZoom;
leftScale = bigNeighbourZoom;
}
// console.log("--------------")
// console.debug(leftScale + " " + rightScale + " " + index);
//activate messages to update the the neighbour scales
layoutsContainer.updateScale(index-1, leftScale, 0);
layoutsContainer.updateScale(index+1, rightScale, 0);
//these messages interfere when an applet is hidden, that is why I disabled them
// currentLayout.updateScale(index-2, 1, 0);
// currentLayout.updateScale(index+2, 1, 0);
//Left hiddenSpacer
if((index === 0 )&&(layoutsContainer.count > 1)){
hiddenSpacerLeft.nScale = leftScale - 1;
}
//Right hiddenSpacer ///there is one more item in the currentLayout ????
if((index === layoutsContainer.count - 1 )&&(layoutsContainer.count>1)){
hiddenSpacerRight.nScale = rightScale - 1;
}
zoomScale = root.zoomFactor;
}
} //scale
function signalUpdateScale(nIndex, nScale, step){
if(container && (container.index === nIndex)){
if ( ((canBeHovered && !lockZoom ) || container.nowDock)
&& (applet && applet.status !== PlasmaCore.Types.HiddenStatus)
//&& (index != currentLayout.hoveredIndex)
){
if(!container.nowDock){
if(nScale >= 0)
zoomScale = nScale + step;
else
zoomScale = zoomScale + step;
}
else{
if(layoutsContainer.hoveredIndex<container.index)
nowDock.updateScale(0, nScale, step);
else if(layoutsContainer.hoveredIndex>=container.index)
nowDock.updateScale(root.tasksCount-1, nScale, step);
}
} ///if the applet is hidden must forward its scale events to its neighbours
else if ((applet && (applet.status === PlasmaCore.Types.HiddenStatus))
|| container.isInternalViewSplitter){
if(layoutsContainer.hoveredIndex>index)
layoutsContainer.updateScale(index-1, nScale, step);
else if((layoutsContainer.hoveredIndex<index))
layoutsContainer.updateScale(index+1, nScale, step);
}
}
}
Component.onCompleted: {
layoutsContainer.updateScale.connect(signalUpdateScale);
}
}// Main task area // id:wrapper
// a hidden spacer on the right for the last item to add stability
Item{
id: hiddenSpacerRight
//we add one missing pixel from calculations
width: root.isHorizontal ? nHiddenSize : wrapper.width
height: root.isHorizontal ? wrapper.height : nHiddenSize
visible: (container.index === mainLayout.count - 1) || (container.index === secondLayout.beginIndex+secondLayout.count-1)
property real nHiddenSize: (nScale > 0) ? (root.realSize * nScale) : 0
property real nScale: 0
Behavior on nScale {
NumberAnimation { duration: container.animationTime }
}
/*Rectangle{
width: 1
height: parent.height
x:parent.width / 2
border.width: 1
border.color: "red"
color: "transparent"
}*/
}
}// Flow with hidden spacers inside
MouseArea{
id: appletMouseArea
anchors.fill: parent
enabled: (!nowDock)&&(canBeHovered)&&(!lockZoom)&&(plasmoid.immutable)
hoverEnabled: plasmoid.immutable && (!nowDock) && canBeHovered ? true : false
propagateComposedEvents: true
property bool pressed: false
onClicked: {
pressed = false;
mouse.accepted = false;
}
onContainsMouseChanged: {
if(!containsMouse){
hiddenSpacerLeft.nScale = 0;
hiddenSpacerRight.nScale = 0;
}
}
onEntered: {
layoutsContainer.hoveredIndex = index;
// mouseEntered = true;
/* icList.mouseWasEntered(index-2, false);
icList.mouseWasEntered(index+2, false);
icList.mouseWasEntered(index-1, true);
icList.mouseWasEntered(index+1, true); */
if (root.isHorizontal){
layoutsContainer.currentSpot = mouseX;
wrapper.calculateScales(mouseX);
}
else{
layoutsContainer.currentSpot = mouseY;
wrapper.calculateScales(mouseY);
}
}
onExited:{
checkListHovered.start();
}
onPositionChanged: {
if(!pressed){
if (root.isHorizontal){
var step = Math.abs(layoutsContainer.currentSpot-mouse.x);
if (step >= container.animationStep){
layoutsContainer.hoveredIndex = index;
layoutsContainer.currentSpot = mouse.x;
wrapper.calculateScales(mouse.x);
}
}
else{
var step = Math.abs(layoutsContainer.currentSpot-mouse.y);
if (step >= container.animationStep){
layoutsContainer.hoveredIndex = index;
layoutsContainer.currentSpot = mouse.y;
wrapper.calculateScales(mouse.y);
}
}
}
mouse.accepted = false;
}
onPressed: pressed = true;
}
//BEGIN states
states: [
State {
name: "left"
when: (plasmoid.location === PlasmaCore.Types.LeftEdge)
AnchorChanges {
target: appletFlow
anchors{ top:undefined; bottom:undefined; left:parent.left; right:undefined;}
}
},
State {
name: "right"
when: (plasmoid.location === PlasmaCore.Types.RightEdge)
AnchorChanges {
target: appletFlow
anchors{ top:undefined; bottom:undefined; left:undefined; right:parent.right;}
}
},
State {
name: "bottom"
when: (plasmoid.location === PlasmaCore.Types.BottomEdge)
AnchorChanges {
target: appletFlow
anchors{ top:undefined; bottom:parent.bottom; left:undefined; right:undefined;}
}
},
State {
name: "top"
when: (plasmoid.location === PlasmaCore.Types.TopEdge)
AnchorChanges {
target: appletFlow
anchors{ top:parent.top; bottom:undefined; left:undefined; right:undefined;}
}
}
]
//END states
//BEGIN animations
SequentialAnimation{
id: clickedAnimation
alwaysRunToEnd: true
running: appletMouseArea.pressed
ParallelAnimation{
PropertyAnimation {
target: clickedEffect
property: "brightness"
to: -0.35
duration: units.longDuration
easing.type: Easing.OutQuad
}
/* PropertyAnimation {
target: wrapper
property: "zoomScale"
to: wrapper.zoomScale - (root.zoomFactor - 1) / 10
duration: units.longDuration
easing.type: Easing.OutQuad
}*/
}
ParallelAnimation{
PropertyAnimation {
target: clickedEffect
property: "brightness"
to: 0
duration: units.longDuration
easing.type: Easing.OutQuad
}
/* PropertyAnimation {
target: wrapper
property: "zoomScale"
to: root.zoomFactor
duration: units.longDuration
easing.type: Easing.OutQuad
}*/
}
}
//END animations
}

View File

@ -0,0 +1,527 @@
/*
* Copyright 2013 Michail Vourlakos <mvourlakos@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 2.010-1301, USA.
*/
import QtQuick 2.1
import QtQuick.Layouts 1.0
import org.kde.plasma.core 2.0 as PlasmaCore
import org.kde.plasma.components 2.0 as PlasmaComponents
import org.kde.kquickcontrolsaddons 2.0
MouseArea {
id: configurationArea
z: 1000
anchors {
fill: parent
rightMargin: (plasmoid.formFactor !== PlasmaCore.Types.Vertical) ? toolBox.width : 0
bottomMargin: (plasmoid.formFactor === PlasmaCore.Types.Vertical) ? toolBox.height : 0
}
hoverEnabled: true
property bool isResizingLeft: false
property bool isResizingRight: false
property Item currentApplet
property Item previousCurrentApplet
property int lastX
property int lastY
property int appletX
property int appletY
readonly property int spacerHandleSize: units.smallSpacing
onHeightChanged: tooltip.visible = false;
onWidthChanged: tooltip.visible = false;
onPositionChanged: {
/*if (currentApplet && currentApplet.applet &&
currentApplet.applet.pluginName == "org.kde.plasma.panelspacer") {
if (plasmoid.formFactor === PlasmaCore.Types.Vertical) {
if ((mouse.y - handle.y) < spacerHandleSize ||
(mouse.y - handle.y) > (handle.height - spacerHandleSize)) {
configurationArea.cursorShape = Qt.SizeVerCursor;
} else {
configurationArea.cursorShape = Qt.ArrowCursor;
}
} else {
if ((mouse.x - handle.x) < spacerHandleSize ||
(mouse.x - handle.x) > (handle.width - spacerHandleSize)) {
configurationArea.cursorShape = Qt.SizeHorCursor;
} else {
configurationArea.cursorShape = Qt.ArrowCursor;
}
}
} else {
configurationArea.cursorShape = Qt.ArrowCursor;
}*/
if (pressed) {
/* if (currentApplet && currentApplet.applet &&
currentApplet.applet.pluginName == "org.kde.plasma.panelspacer") {
if (isResizingLeft) {
if (plasmoid.formFactor === PlasmaCore.Types.Vertical) {
handle.y += (mouse.y - lastY);
// handle.height = currentApplet.height + (currentApplet.y - handle.y);
} else {
handle.x += (mouse.x - lastX);
// handle.width = currentApplet.width + (currentApplet.x - handle.x);
}
lastX = mouse.x;
lastY = mouse.y;
return;
} else if (isResizingRight) {
/* if (plasmoid.formFactor === PlasmaCore.Types.Vertical) {
handle.height = mouse.y - handle.y;
} else {
handle.width = mouse.x - handle.x;
} */
/* lastX = mouse.x;
lastY = mouse.y;
return;
}
}*/
var padding = units.gridUnit * 3;
if (currentApplet && (mouse.x < -padding || mouse.y < -padding ||
mouse.x > width + padding || mouse.y > height + padding)) {
var newCont = plasmoid.containmentAt(mouse.x, mouse.y);
if (newCont && newCont != plasmoid) {
var newPos = newCont.mapFromApplet(plasmoid, mouse.x, mouse.y);
newCont.addApplet(currentApplet.applet, newPos.x, newPos.y);
root.dragOverlay.currentApplet = null;
return;
}
}
if(currentApplet){
if (plasmoid.formFactor === PlasmaCore.Types.Vertical) {
currentApplet.y += (mouse.y - lastY);
// handle.y = currentApplet.y;
} else {
currentApplet.x += (mouse.x - lastX);
// handle.x = currentApplet.x;
}
}
lastX = mouse.x;
lastY = mouse.y;
var relevantLayout = mapFromItem(mainLayout, 0, 0);
var item = mainLayout.childAt(mouse.x-relevantLayout.x, mouse.y-relevantLayout.y);
if (item && item !== placeHolder) {
// placeHolder.width = item.width;
// placeHolder.height = item.height;
placeHolder.parent = configurationArea;
var posInItem = mapToItem(item, mouse.x, mouse.y);
if ((plasmoid.formFactor === PlasmaCore.Types.Vertical && posInItem.y < item.height/2) ||
(plasmoid.formFactor !== PlasmaCore.Types.Vertical && posInItem.x < item.width/2)) {
root.layoutManager.insertBefore(item, placeHolder);
} else {
root.layoutManager.insertAfter(item, placeHolder);
}
}
} else {
var relevantLayout = mapFromItem(mainLayout,0,0);
var item = mainLayout.childAt(mouse.x-relevantLayout.x, mouse.y-relevantLayout.y);
if (root.dragOverlay && item && item !== lastSpacer) {
root.dragOverlay.currentApplet = item;
} else {
root.dragOverlay.currentApplet = null;
}
}
if (root.dragOverlay.currentApplet && !currentApplet.isInternalViewSplitter) {
hideTimer.stop();
tooltip.visible = true;
tooltip.raise();
}
}
onExited: hideTimer.restart();
onCurrentAppletChanged: {
if(previousCurrentApplet && previousCurrentApplet.showZoomed)
previousCurrentApplet.showZoomed = false;
previousCurrentApplet = currentApplet;
if (!currentApplet
|| !root.dragOverlay.currentApplet
|| (currentApplet &&currentApplet.isInternalViewSplitter)) {
hideTimer.restart();
return;
}
if(currentApplet.showZoomed !== undefined)
currentApplet.showZoomed = true;
var relevantLayout = mapFromItem(mainLayout, 0, 0);
handle.x = relevantLayout.x + currentApplet.x;
handle.y = relevantLayout.y + currentApplet.y;
handle.width = currentApplet.width;
handle.height = currentApplet.height;
lockButton.checked = currentApplet.lockZoom;
repositionHandler.restart();
}
onPressed: {
if (!root.dragOverlay.currentApplet) {
return;
}
/*
if (currentApplet.applet.pluginName == "org.kde.plasma.panelspacer") {
if (plasmoid.formFactor === PlasmaCore.Types.Vertical) {
if ((mouse.y - handle.y) < spacerHandleSize) {
configurationArea.isResizingLeft = true;
configurationArea.isResizingRight = false;
} else if ((mouse.y - handle.y) > (handle.height - spacerHandleSize)) {
configurationArea.isResizingLeft = false;
configurationArea.isResizingRight = true;
} else {
configurationArea.isResizingLeft = false;
configurationArea.isResizingRight = false;
}
} else {
if ((mouse.x - handle.x) < spacerHandleSize) {
configurationArea.isResizingLeft = true;
configurationArea.isResizingRight = false;
} else if ((mouse.x - handle.x) > (handle.width - spacerHandleSize)) {
configurationArea.isResizingLeft = false;
configurationArea.isResizingRight = true;
} else {
configurationArea.isResizingLeft = false;
configurationArea.isResizingRight = false;
}
}
}*/
var relevantApplet = mapFromItem(currentApplet, 0, 0);
appletX = mouse.x - relevantApplet.x;
appletY = mouse.y - relevantApplet.y;
lastX = mouse.x;
lastY = mouse.y;
placeHolder.width = currentApplet.width;
placeHolder.height = currentApplet.height;
handle.width = currentApplet.width;
handle.height = currentApplet.height;
root.layoutManager.insertBefore(currentApplet, placeHolder);
currentApplet.parent = root;
currentApplet.x = lastX-appletX;
currentApplet.y = lastY-appletY;
currentApplet.z = 900;
}
onReleased: {
if (!root.dragOverlay.currentApplet) {
return;
}
if(currentApplet && currentApplet.applet){
if (plasmoid.formFactor === PlasmaCore.Types.Vertical) {
currentApplet.applet.configuration.length = handle.height;
} else {
currentApplet.applet.configuration.length = handle.width;
}
}
configurationArea.isResizingLeft = false;
configurationArea.isResizingRight = false;
root.layoutManager.insertBefore(placeHolder, currentApplet);
placeHolder.parent = configurationArea;
currentApplet.z = 1;
var relevantLayout = mapFromItem(mainLayout, 0, 0);
handle.x = relevantLayout.x + currentApplet.x;
handle.y = relevantLayout.y + currentApplet.y;
// handle.width = currentApplet.width;
// handle.height = currentApplet.height;
root.layoutManager.save();
}
Item {
id: placeHolder
visible: configurationArea.containsMouse
Layout.fillWidth: currentApplet ? currentApplet.Layout.fillWidth : false
Layout.fillHeight: currentApplet ? currentApplet.Layout.fillHeight : false
}
//Because of the animations for the applets the handler can not catch up to
//reposition itself when the currentApplet position or size changes.
//This timer fixes that situation
Timer {
id: repositionHandler
interval: 100
onTriggered: handle.updatePlacement();
}
Timer {
id: hideTimer
interval: units.longDuration * 2
onTriggered: tooltip.visible = false;
}
Connections {
target: currentApplet
onXChanged: handle.updatePlacement();
onYChanged: handle.updatePlacement();
onWidthChanged: handle.updatePlacement();
onHeightChanged: handle.updatePlacement()
}
Rectangle {
id: handle
visible: configurationArea.containsMouse
color: theme.backgroundColor
radius: 3
opacity: currentApplet ? 0.5 : 0
//BEGIN functions
function updatePlacement(){
if(currentApplet){
var transformChoords = root.mapFromItem(currentApplet, 0, 0)
handle.x = transformChoords.x;
handle.y = transformChoords.y;
handle.width = currentApplet.width;
handle.height = currentApplet.height;
repositionHandler.restart();
}
}
//END functions
PlasmaCore.IconItem {
source: "transform-move"
width: Math.min(parent.width, parent.height)
height: width
anchors.centerIn: parent
}
/* Rectangle {
anchors {
left: parent.left
top: parent.top
bottom: (plasmoid.formFactor !== PlasmaCore.Types.Vertical) ? parent.bottom : undefined
right: (plasmoid.formFactor !== PlasmaCore.Types.Vertical) ? undefined : parent.right
}
visible: currentApplet && currentApplet.applet.pluginName == "org.kde.plasma.panelspacer"
opacity: visible && !xAnim.running && !yAnim.running ? 1.0 : 0
width: configurationArea.spacerHandleSize
height: configurationArea.spacerHandleSize
color: theme.textColor
Behavior on opacity {
NumberAnimation {
duration: units.longDuration
easing.type: Easing.InOutQuad
}
}
}
Rectangle {
anchors {
right: parent.right
top: (plasmoid.formFactor !== PlasmaCore.Types.Vertical) ? parent.top : undefined
bottom: parent.bottom
left: (plasmoid.formFactor !== PlasmaCore.Types.Vertical) ? undefined : parent.left
}
visible: currentApplet && currentApplet.applet.pluginName == "org.kde.plasma.panelspacer"
opacity: visible && !xAnim.running && !yAnim.running ? 1.0 : 0
width: configurationArea.spacerHandleSize
height: configurationArea.spacerHandleSize
color: theme.textColor
Behavior on opacity {
NumberAnimation {
duration: units.longDuration
easing.type: Easing.InOutQuad
}
}
}*/
PlasmaComponents.Button{
id: lockButton
checkable: true
iconSource: checked ? "lock" : "unlock"
width: units.iconSizes.large
visible: currentApplet &&
((currentApplet.applet &&
((currentApplet.applet.pluginName === "org.kde.plasma.systemtray")
|| (currentApplet.applet.pluginName === "org.kde.store.nowdock.plasmoid")) )
|| (currentApplet.isInternalViewSplitter))
? false : true
anchors.margins: 2*units.smallSpacing
tooltip: "Lock/Unlock zoom effect"
onCheckedChanged: {
currentApplet.lockZoom = checked;
root.layoutManager.saveLocks();
}
states: [
State {
name: "left"
when: plasmoid.location === PlasmaCore.Types.LeftEdge
AnchorChanges {
target: lockButton
anchors{ top:parent.top; bottom:undefined; left:undefined; right:parent.right; }
}
},
State {
name: "right"
when: plasmoid.location === PlasmaCore.Types.RightEdge
AnchorChanges {
target: lockButton
anchors{ top:parent.top; bottom:undefined; left:parent.left; right:undefined; }
}
},
State {
name: "bottom"
when: plasmoid.location === PlasmaCore.Types.BottomEdge
AnchorChanges {
target: lockButton
anchors{ top:parent.top; bottom:undefined; left:parent.left; right:undefined; }
}
},
State {
name: "top"
when: plasmoid.location === PlasmaCore.Types.TopEdge
AnchorChanges {
target: lockButton
anchors{ top:undefined; bottom:parent.bottom; left:undefined; right:parent.right; }
}
}
]
}
Behavior on x {
enabled: !configurationArea.pressed
NumberAnimation {
id: xAnim
duration: units.longDuration
easing.type: Easing.InOutQuad
}
}
Behavior on y {
id: yAnim
enabled: !configurationArea.pressed
NumberAnimation {
duration: units.longDuration
easing.type: Easing.InOutQuad
}
}
Behavior on width {
enabled: !configurationArea.pressed
NumberAnimation {
duration: units.longDuration
easing.type: Easing.InOutQuad
}
}
Behavior on height {
enabled: !configurationArea.pressed
NumberAnimation {
duration: units.longDuration
easing.type: Easing.InOutQuad
}
}
Behavior on opacity {
NumberAnimation {
duration: units.longDuration
easing.type: Easing.InOutQuad
}
}
}
PlasmaCore.Dialog {
id: tooltip
visualParent: currentApplet
type: PlasmaCore.Dialog.Dock
flags: Qt.WindowStaysOnTopHint|Qt.WindowDoesNotAcceptFocus|Qt.BypassWindowManagerHint
location: plasmoid.location
onVisualParentChanged: {
if (visualParent && currentApplet && currentApplet.applet) {
configureButton.visible = currentApplet.applet.action("configure") && currentApplet.applet.action("configure").enabled;
closeButton.visible = currentApplet.applet.action("remove") && currentApplet.applet.action("remove").enabled;
label.text = currentApplet.applet.title;
}
}
mainItem: MouseArea {
enabled: currentApplet
width: handleRow.childrenRect.width + (2 * handleRow.spacing)
height: Math.max(configureButton.height, label.contentHeight, closeButton.height)
hoverEnabled: true
onEntered: hideTimer.stop();
onExited: hideTimer.restart();
Row {
id: handleRow
anchors.horizontalCenter: parent.horizontalCenter
spacing: units.smallSpacing
PlasmaComponents.ToolButton {
id: configureButton
anchors.verticalCenter: parent.verticalCenter
iconSource: "configure"
onClicked: {
tooltip.visible = false;
currentApplet.applet.action("configure").trigger()
}
}
PlasmaComponents.Label {
id: label
anchors.verticalCenter: parent.verticalCenter
textFormat: Text.PlainText
maximumLineCount: 1
}
PlasmaComponents.ToolButton {
id: closeButton
anchors.verticalCenter: parent.verticalCenter
iconSource: "window-close"
onClicked: {
tooltip.visible = false;
if(currentApplet && currentApplet.applet)
currentApplet.applet.action("remove").trigger();
}
}
}
}
}
}

View File

@ -0,0 +1,507 @@
import QtQuick 2.1
import org.kde.plasma.core 2.0 as PlasmaCore
import org.kde.taskmanager 0.1 as TaskManager
import org.kde.nowdock 0.1 as NowDock
NowDock.PanelWindow{
id: window
property bool inStartup: root.inStartup
property bool normalState : false // this is being set from updateMaskArea
property int animationSpeed: root.durationTime * 1.2 * units.longDuration
property int length: root.isVertical ? screenGeometry.height : screenGeometry.width
//it is used in order to not break the calculations for the thickness placement
//especially in automatic icon sizes calculations
property int iconMarginOriginal: 0.12*plasmoid.configuration.iconSize
property int statesLineSizeOriginal: root.nowDock ? Math.ceil( plasmoid.configuration.iconSize/13 ) : 0
property int thicknessAutoHidden: 8
property int thicknessMid: root.statesLineSize + (1 + (0.65 * (root.zoomFactor-1)))*(root.iconSize+root.iconMargin) //needed in some animations
property int thicknessNormal: root.statesLineSize + root.iconSize + root.iconMargin + 1
property int thicknessZoom: root.statesLineSize + ((root.iconSize+root.iconMargin) * root.zoomFactor) + 2
//it is used to keep thickness solid e.g. when iconSize changes from auto functions
property int thicknessMidOriginal: statesLineSizeOriginal + (1 + (0.65 * (root.zoomFactor-1)))*(plasmoid.configuration.iconSize+iconMarginOriginal) //needed in some animations
property int thicknessNormalOriginal: root.useThemePanel ? Math.max(thicknessNormalOriginalValue, root.realPanelSize) : thicknessNormalOriginalValue
property int thicknessNormalOriginalValue: statesLineSizeOriginal + plasmoid.configuration.iconSize + iconMarginOriginal + 1
property int thicknessZoomOriginal: statesLineSizeOriginal + ((plasmoid.configuration.iconSize+iconMarginOriginal) * root.zoomFactor) + 2
childrenLength: root.isHorizontal ? mainLayout.width : mainLayout.height
immutable: plasmoid.immutable
location: plasmoid.location
panelVisibility: plasmoid.configuration.panelVisibility
//this is used especially in the wayland case or when the user might want
//not to make the dock to go below windows but to hide, e.g. intelligent auto-hide
//isDockWindowType: true
width: root.isHorizontal ? length : thicknessZoomOriginal
height: root.isHorizontal ? thicknessZoomOriginal : length
// it is used in order to restore applets after right click menu
onDisableHidingChanged: {
if (!disableHiding) {
checkListHovered.restart();
}
}
onImmutableChanged: updateMaskArea();
onInStartupChanged: {
if (!inStartup) {
delayAnimationTimer.start();
}
}
onIsHoveredChanged: {
if(isHovered) {
//stop parent window timer for auto hiding
if ((panelVisibility === NowDock.PanelWindow.AutoHide)|| isDockWindowType) {
if(hideMagicWindowInAutoHide.forcedDisableHiding) {
hideMagicWindowInAutoHide.forcedDisableHiding = false;
window.disableHiding = false;
}
hideMagicWindowInAutoHide.stop();
}
if (delayerTimer.running) {
delayerTimer.stop();
}
updateMaskArea();
} else {
// initialize the zoom
delayerTimer.start();
}
}
onMustBeRaised: {
if ((panelVisibility === NowDock.PanelWindow.AutoHide) || isDockWindowType) {
slidingAnimationAutoHiddenIn.init();
} else {
slidingAnimation.init(true,false);
}
}
onMustBeRaisedImmediately: {
slidingAnimation.init(true,true);
}
onMustBeLowered: {
if ((panelVisibility === NowDock.PanelWindow.AutoHide) || isDockWindowType ) {
slidingAnimationAutoHiddenOut.init();
} else {
slidingAnimation.init(false,false);
}
}
onNormalStateChanged: {
if(normalState && nowDock) {
nowDock.publishTasksGeometries();
}
if (normalState) {
root.updateAutomaticIconSize();
}
}
onPanelVisibilityChanged: {
if (panelVisibility !== NowDock.PanelWindow.AutoHide) {
isAutoHidden = false;
}
}
onWidthChanged: {
if (plasmoid.immutable) {
if (windowSystem.compositingActive) {
magicWin.initialize();
} else {
magicWin.updateTransientThickness();
}
updateMaskArea();
}
}
onHeightChanged: {
if (plasmoid.immutable) {
if (windowSystem.compositingActive) {
magicWin.initialize();
} else {
magicWin.updateTransientThickness();
}
updateMaskArea();
}
}
onVisibleChanged:{
if (visible) { //shrink the parent panel window
initialize();
}
}
function initializeSlidingInAnimation() {
// Hide in Startup in order to show the contents with beautiful sliding animation
var hiddenSpace;
if ((location===PlasmaCore.Types.LeftEdge)||(location===PlasmaCore.Types.TopEdge)) {
hiddenSpace = -thicknessNormal;
} else {
hiddenSpace = thicknessNormal;
}
if (root.isVertical) {
layoutsContainer.x = hiddenSpace;
} else {
layoutsContainer.y = hiddenSpace;
}
layoutsContainer.opacity = 1;
if (!inStartup) {initialize();
delayAnimationTimer.start();
}
}
function updateMaskArea() {
if (!windowSystem.compositingActive) {
return;
}
var localX = 0;
var localY = 0;
normalState = (root.nowDockHoveredIndex === -1) && (layoutsContainer.hoveredIndex === -1)
&& (root.appletsAnimations === 0)
&& (root.animationsNeedBothAxis === 0) && (root.animationsNeedLength === 0)
&& (!mainLayout.animatedLength)
// debug maskArea criteria
//console.log(root.nowDockHoveredIndex + ", " + layoutsContainer.hoveredIndex + ", "
// + root.appletsAnimations+ ", "
// + root.animationsNeedBothAxis + ", " + root.animationsNeedLength + ", " + root.animationsNeedThickness +", "
// + mainLayout.animatedLength);
var tempLength = root.isHorizontal ? width : height;
var tempThickness = root.isHorizontal ? height : width;
var space = root.panelEdgeSpacing + 10;
if (normalState) {
//count panel length
if(root.isHorizontal) {
tempLength = plasmoid.configuration.panelPosition === NowDock.PanelWindow.Double ? layoutsContainer.width + 0.5*space : mainLayout.width + space;
} else {
tempLength = plasmoid.configuration.panelPosition === NowDock.PanelWindow.Double ? layoutsContainer.height + 0.5*space : mainLayout.height + space;
}
tempThickness = thicknessNormalOriginal;
if (root.animationsNeedThickness > 0) {
tempThickness = thicknessMidOriginal;
}
if (window.isAutoHidden && ((panelVisibility === NowDock.PanelWindow.AutoHide) || window.isDockWindowType)) {
tempThickness = thicknessAutoHidden;
}
if (!immutable) {
tempThickness = 2;
}
//configure x,y based on plasmoid position and root.panelAlignment(Alignment)
if ((plasmoid.location === PlasmaCore.Types.BottomEdge) || (plasmoid.location === PlasmaCore.Types.TopEdge)) {
if (plasmoid.location === PlasmaCore.Types.BottomEdge) {
localY = window.height - tempThickness;
} else if (plasmoid.location === PlasmaCore.Types.TopEdge) {
localY = 0;
}
if (plasmoid.configuration.panelPosition === NowDock.PanelWindow.Double) {
localX = (window.width/2) - (layoutsContainer.width/2) - 0.25*space;
} else if (root.panelAlignment === NowDock.PanelWindow.Left) {
localX = 0;
} else if (root.panelAlignment === NowDock.PanelWindow.Center) {
localX = (window.width/2) - (mainLayout.width/2) - (space/2);
} else if (root.panelAlignment === NowDock.PanelWindow.Right) {
localX = window.width - mainLayout.width - (space/2);
}
} else if ((plasmoid.location === PlasmaCore.Types.LeftEdge) || (plasmoid.location === PlasmaCore.Types.RightEdge)){
if (plasmoid.location === PlasmaCore.Types.LeftEdge) {
localX = 0;
} else if (plasmoid.location === PlasmaCore.Types.RightEdge) {
localX = window.width - tempThickness;
}
if (plasmoid.configuration.panelPosition === NowDock.PanelWindow.Double) {
localY = (window.height/2) - (layoutsContainer.height/2) - 0.25*space;
} else if (root.panelAlignment === NowDock.PanelWindow.Top) {
localY = 0;
} else if (root.panelAlignment === NowDock.PanelWindow.Center) {
localY = (window.height/2) - (mainLayout.height/2) - (space/2);
} else if (root.panelAlignment === NowDock.PanelWindow.Bottom) {
localY = window.height - mainLayout.height - (space/2);
}
}
} else {
if(root.isHorizontal)
tempLength = screenGeometry.width;
else
tempLength = screenGeometry.height;
//grow only on length and not thickness
if(mainLayout.animatedLength) {
tempThickness = thicknessNormalOriginal;
if (root.animationsNeedThickness > 0) {
tempThickness = thicknessMidOriginal;
}
//configure the x,y position based on thickness
if(plasmoid.location === PlasmaCore.Types.RightEdge)
localX = window.width - tempThickness;
else if(plasmoid.location === PlasmaCore.Types.BottomEdge)
localY = window.height - tempThickness;
} else{
//use all thickness space
tempThickness = thicknessZoomOriginal;
}
}
var maskLength = maskArea.width; //in Horizontal
if (root.isVertical) {
maskLength = maskArea.height;
}
var maskThickness = maskArea.height; //in Horizontal
if (root.isVertical) {
maskThickness = maskArea.width;
}
// console.log("Not updating mask...");
if( maskArea.x !== localX || maskArea.y !== localY
|| maskLength !== tempLength || maskThickness !== tempThickness) {
// console.log("Updating mask...");
var newMaskArea = Qt.rect(-1,-1,0,0);
newMaskArea.x = localX;
newMaskArea.y = localY;
if (isHorizontal) {
newMaskArea.width = tempLength;
newMaskArea.height = tempThickness;
} else {
newMaskArea.width = tempThickness;
newMaskArea.height = tempLength;
}
maskArea = newMaskArea;
}
}
function updateTransientThickness() {
var thickness;
if (root.isVertical) {
thickness = root.width;
} else {
thickness = root.height;
}
var newThickness = statesLineSizeOriginal + plasmoid.configuration.iconSize + iconMarginOriginal;
if (!windowSystem.compositingActive) {
newThickness += iconMarginOriginal;
}
if (thickness<newThickness) {
setTransientThickness(newThickness);
}
}
Loader{
anchors.fill: parent
active: root.debugMode
sourceComponent: Item{
anchors.fill:parent
Rectangle{
id: windowBackground
anchors.fill: parent
border.color: "red"
border.width: 1
color: "transparent"
}
Rectangle{
x: maskArea.x
y: maskArea.y
height: maskArea.height
width: maskArea.width
border.color: "green"
border.width: 1
color: "transparent"
}
}
}
/***Hiding/Showing Animations*****/
SequentialAnimation{
id: slidingAnimation
property bool inHalf: false
property bool raiseFlag: false
property bool immediateShow: false
SequentialAnimation{
PropertyAnimation {
target: layoutsContainer
property: root.isVertical ? "x" : "y"
to: ((location===PlasmaCore.Types.LeftEdge)||(location===PlasmaCore.Types.TopEdge)) ? -thicknessNormal : thicknessNormal
duration: slidingAnimation.immediateShow ? 100 : window.animationSpeed
easing.type: Easing.OutQuad
}
PropertyAnimation {
target: slidingAnimation
property: "inHalf"
to: true
duration: 100
}
PropertyAnimation {
target: layoutsContainer
property: root.isVertical ? "x" : "y"
to: 0
duration: window.animationSpeed
easing.type: Easing.OutQuad
}
}
onStopped: {
inHalf = false;
raiseFlag = false;
immediateShow = false;
if (!plasmoid.immutable) {
updateTransientThickness();
}
}
onInHalfChanged: {
if (inHalf) {
if (raiseFlag) {
window.showOnTop();
} else {
window.showOnBottom();
}
}
}
function init(raise, immediate) {
if(window.visible) {
raiseFlag = raise;
immediateShow = immediate;
// if (!running) {
start();
// }
}
}
}
//////////////// Auto Hide Animations - Slide In - Out
SequentialAnimation{
id: slidingAnimationAutoHiddenOut
PropertyAnimation {
target: layoutsContainer
property: root.isVertical ? "x" : "y"
to: ((location===PlasmaCore.Types.LeftEdge)||(location===PlasmaCore.Types.TopEdge)) ? -thicknessNormal : thicknessNormal
duration: window.animationSpeed
easing.type: Easing.OutQuad
}
onStopped: {
window.isAutoHidden = true;
updateMaskArea();
}
function init() {
start();
}
}
SequentialAnimation{
id: slidingAnimationAutoHiddenIn
PropertyAnimation {
target: layoutsContainer
property: root.isVertical ? "x" : "y"
to: 0
duration: window.animationSpeed
easing.type: Easing.OutQuad
}
onStopped: {
if (!plasmoid.immutable) {
updateTransientThickness();
}
}
function init() {
window.isAutoHidden = false;
updateMaskArea();
start();
}
}
///////////// External Connections //////
TaskManager.ActivityInfo {
onCurrentActivityChanged: {
window.disableHiding = true;
if (window.isAutoHidden) {
window.mustBeRaised();
}
hideMagicWindowInAutoHide.forcedDisableHiding = true;
hideMagicWindowInAutoHide.start();
}
}
////////////// Timers //////
//Timer to delay onLeave event
Timer {
id: delayerTimer
interval: 400
onTriggered: {
root.clearZoom();
if (root.nowDock) {
nowDock.clearZoom();
}
}
}
//Timer to delay onLeave event
Timer {
id: delayAnimationTimer
interval: window.inStartup ? 1000 : 500
onTriggered: {
layoutsContainer.opacity = 1;
if ((window.panelVisibility !== NowDock.PanelWindow.AutoHide) && !window.isDockWindowType) {
slidingAnimation.init(true,false);
} else {
slidingAnimationAutoHiddenIn.init();
}
}
}
}

View File

@ -0,0 +1,414 @@
/*
* Copyright 2013 Michail Vourlakos <mvourlakos@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 2.010-1301, USA.
*/
import QtQuick 2.1
import QtQuick.Layouts 1.1
import QtQuick.Window 2.2
import org.kde.plasma.plasmoid 2.0
import org.kde.plasma.core 2.0 as PlasmaCore
import org.kde.plasma.components 2.0 as PlasmaComponents
import org.kde.kquickcontrolsaddons 2.0
import org.kde.nowdock 0.1 as NowDock
Item{
id:barLine
opacity: root.useThemePanel ? 1 : 0
// parent: root
z:0
property int panelWidth: secondLayout.count > 0 && root.isHorizontal && plasmoid.immutable ?
layoutsContainer.width + 2*spacing : mainLayout.width + spacing
property int panelHeight: secondLayout.count > 0 && root.isVertical && plasmoid.immutable ?
layoutsContainer.height + 2*spacing : mainLayout.height + spacing
width: root.isHorizontal ? panelWidth : smallSize
height: root.isVertical ? panelHeight : smallSize
property int spacing: (root.panelAlignment === NowDock.PanelWindow.Center
|| plasmoid.configuration.panelPosition === NowDock.PanelWindow.Double) ?
root.panelEdgeSpacing : root.panelEdgeSpacing/2
property int smallSize: Math.max(3.7*root.statesLineSize, 16)
Behavior on opacity{
NumberAnimation { duration: 150 }
}
/// plasmoid's default panel
/* BorderImage{
anchors.fill:parent
source: "../images/panel-west.png"
border { left:8; right:8; top:8; bottom:8 }
opacity: (!root.useThemePanel) ? 1 : 0
visible: (opacity == 0) ? false : true
horizontalTileMode: BorderImage.Stretch
verticalTileMode: BorderImage.Stretch
Behavior on opacity{
NumberAnimation { duration: 200 }
}
}*/
/// item which is used as anchors for the plasma's theme
Item{
id:belower
width: (plasmoid.location === PlasmaCore.Types.LeftEdge) ? shadowsSvgItem.margins.left : shadowsSvgItem.margins.right
height: (plasmoid.location === PlasmaCore.Types.BottomEdge)? shadowsSvgItem.margins.bottom : shadowsSvgItem.margins.top
}
/// the current theme's panel
PlasmaCore.FrameSvgItem{
id: shadowsSvgItem
width: root.isVertical ? panelSize + margins.left + margins.right: parent.width + margins.left + margins.right
height: root.isVertical ? parent.height + margins.left + margins.right : panelSize + margins.top + margins.bottom
imagePath: "translucent/widgets/panel-background"
prefix:"shadow"
opacity: root.useThemePanel ? 1 : 0
visible: (opacity == 0) ? false : true
property int panelSize: ((plasmoid.location === PlasmaCore.Types.BottomEdge) ||
(plasmoid.location === PlasmaCore.Types.TopEdge)) ?
root.themePanelSize + belower.height:
root.themePanelSize + belower.width
Behavior on opacity{
NumberAnimation { duration: 200 }
}
Binding {
target: root
property: "realPanelSize"
when: shadowsSvgItem
value: {
var space = ((plasmoid.location === PlasmaCore.Types.BottomEdge) ||
(plasmoid.location === PlasmaCore.Types.TopEdge)) ?
belower.height : belower.width
return shadowsSvgItem.panelSize + space;
}
}
PlasmaCore.FrameSvgItem{
anchors.margins: belower.width-1
anchors.fill:parent
// imagePath: root.transparentPanel ? "translucent/widgets/panel-background" :
// "widgets/panel-background"
imagePath: "widgets/panel-background"
}
}
//BEGIN states
//user set Panel Positions
//0-Center, 1-Left, 2-Right, 3-Top, 4-Bottom
states: [
///Left
State {
name: "leftCenter"
when: (plasmoid.location === PlasmaCore.Types.LeftEdge)&&(root.panelAlignment === NowDock.PanelWindow.Center)
AnchorChanges {
target: barLine
anchors{ top:undefined; bottom:undefined; left:parent.left; right:undefined; horizontalCenter:undefined; verticalCenter:parent.verticalCenter}
}
AnchorChanges {
target: belower
anchors{ top:undefined; bottom:undefined; left:undefined; right:parent.left; horizontalCenter:undefined; verticalCenter:parent.verticalCenter}
}
AnchorChanges {
target: shadowsSvgItem
anchors{ top:undefined; bottom:undefined; left:belower.left; right:undefined; horizontalCenter:undefined; verticalCenter:parent.verticalCenter}
}
},
///Left
State {
name: "leftTop"
when: (plasmoid.location === PlasmaCore.Types.LeftEdge)&&(root.panelAlignment === NowDock.PanelWindow.Top)
AnchorChanges {
target: barLine
anchors{ top:parent.top; bottom:undefined; left:parent.left; right:undefined; horizontalCenter:undefined; verticalCenter:undefined}
}
AnchorChanges {
target: belower
anchors{ top:undefined; bottom:parent.top; left:undefined; right:parent.left; horizontalCenter:undefined; verticalCenter:undefined}
}
AnchorChanges {
target: shadowsSvgItem
anchors{ top:belower.top; bottom:undefined; left:belower.left; right:undefined; horizontalCenter:undefined; verticalCenter:undefined}
}
},
///Left
State {
name: "leftBottom"
when: (plasmoid.location === PlasmaCore.Types.LeftEdge)&&(root.panelAlignment === NowDock.PanelWindow.Bottom)
AnchorChanges {
target: barLine
anchors{ top:undefined; bottom:parent.bottom; left:parent.left; right:undefined; horizontalCenter:undefined; verticalCenter:undefined}
}
AnchorChanges {
target: belower
anchors{ top:parent.bottom; bottom:undefined; left:undefined; right:parent.left; horizontalCenter:undefined; verticalCenter:undefined}
}
AnchorChanges {
target: shadowsSvgItem
anchors{ top:undefined; bottom:belower.bottom; left:belower.left; right:undefined; horizontalCenter:undefined; verticalCenter:undefined}
}
},
State {
name: "leftDouble"
when: (plasmoid.location === PlasmaCore.Types.LeftEdge)&&(root.panelAlignment === NowDock.PanelWindow.Double)
AnchorChanges {
target: barLine
anchors{ top:undefined; bottom:undefined; left:parent.left; right:undefined; horizontalCenter:undefined; verticalCenter:parent.verticalCenter}
}
AnchorChanges {
target: belower
anchors{ top:undefined; bottom:undefined; left:undefined; right:parent.left; horizontalCenter:undefined; verticalCenter:parent.verticalCenter}
}
AnchorChanges {
target: shadowsSvgItem
anchors{ top:undefined; bottom:undefined; left:belower.left; right:undefined; horizontalCenter:undefined; verticalCenter:parent.verticalCenter}
}
},
///Right
State {
name: "rightCenter"
when: (plasmoid.location === PlasmaCore.Types.RightEdge)&&(root.panelAlignment === NowDock.PanelWindow.Center)
AnchorChanges {
target: barLine
anchors{ top:undefined; bottom:undefined; left:undefined; right:parent.right; horizontalCenter:undefined; verticalCenter:parent.verticalCenter}
}
AnchorChanges {
target: belower
anchors{ top:undefined; bottom:undefined; left:parent.right; right:undefined; horizontalCenter:undefined; verticalCenter:parent.verticalCenter}
}
AnchorChanges {
target: shadowsSvgItem
anchors{ top:undefined; bottom:undefined; left:undefined; right:belower.right; horizontalCenter:undefined; verticalCenter:parent.verticalCenter}
}
},
State {
name: "rightTop"
when: (plasmoid.location === PlasmaCore.Types.RightEdge)&&(root.panelAlignment === NowDock.PanelWindow.Top)
AnchorChanges {
target: barLine
anchors{ top:parent.top; bottom:undefined; left:undefined; right:parent.right; horizontalCenter:undefined; verticalCenter:undefined}
}
AnchorChanges {
target: belower
anchors{ top:undefined; bottom:parent.top; left:parent.right; right:undefined; horizontalCenter:undefined; verticalCenter:undefined}
}
AnchorChanges {
target: shadowsSvgItem
anchors{ top:belower.top; bottom:undefined; left:undefined; right:belower.right; horizontalCenter:undefined; verticalCenter:undefined}
}
},
State {
name: "rightBottom"
when: (plasmoid.location === PlasmaCore.Types.RightEdge)&&(root.panelAlignment === NowDock.PanelWindow.Bottom)
AnchorChanges {
target: barLine
anchors{ top:undefined; bottom:parent.bottom; left:undefined; right:parent.right; horizontalCenter:undefined; verticalCenter:undefined }
}
AnchorChanges {
target: belower
anchors{ top:parent.bottom; bottom:undefined; left:parent.right; right:undefined; horizontalCenter:undefined; verticalCenter:undefined}
}
AnchorChanges {
target: shadowsSvgItem
anchors{ top:undefined; bottom:belower.bottom; left:undefined; right:belower.right; horizontalCenter:undefined; verticalCenter:undefined}
}
},
State {
name: "rightDouble"
when: (plasmoid.location === PlasmaCore.Types.RightEdge)&&(root.panelAlignment === NowDock.PanelWindow.Double)
AnchorChanges {
target: barLine
anchors{ top:undefined; bottom:undefined; left:undefined; right:parent.right; horizontalCenter:undefined; verticalCenter:parent.verticalCenter}
}
AnchorChanges {
target: belower
anchors{ top:undefined; bottom:undefined; left:parent.right; right:undefined; horizontalCenter:undefined; verticalCenter:parent.verticalCenter}
}
AnchorChanges {
target: shadowsSvgItem
anchors{ top:undefined; bottom:undefined; left:undefined; right:belower.right; horizontalCenter:undefined; verticalCenter:parent.verticalCenter}
}
},
///Bottom
State {
name: "bottomCenter"
when: (plasmoid.location === PlasmaCore.Types.BottomEdge)&&(root.panelAlignment === NowDock.PanelWindow.Center)
AnchorChanges {
target: barLine
anchors{ top:undefined; bottom:parent.bottom; left:undefined; right:undefined; horizontalCenter:parent.horizontalCenter; verticalCenter:undefined}
}
AnchorChanges {
target: belower
anchors{ top:parent.bottom; bottom:undefined; left:undefined; right:undefined; horizontalCenter:parent.horizontalCenter; verticalCenter:undefined}
}
AnchorChanges {
target: shadowsSvgItem
anchors{ top:undefined; bottom:belower.bottom; left:undefined; right:undefined; horizontalCenter:parent.horizontalCenter; verticalCenter:undefined}
}
},
State {
name: "bottomLeft"
when: (plasmoid.location === PlasmaCore.Types.BottomEdge)&&(root.panelAlignment === NowDock.PanelWindow.Left)
AnchorChanges {
target: barLine
anchors{ top:undefined; bottom:parent.bottom; left:parent.left; right:undefined; horizontalCenter:undefined; verticalCenter:undefined}
}
AnchorChanges {
target: belower
anchors{ top:parent.bottom; bottom:undefined; left:undefined; right:parent.left; horizontalCenter:undefined; verticalCenter:undefined}
}
AnchorChanges {
target: shadowsSvgItem
anchors{ top:undefined; bottom:belower.bottom; left:belower.left; right:undefined; horizontalCenter:undefined; verticalCenter:undefined}
}
},
State {
name: "bottomRight"
when: (plasmoid.location === PlasmaCore.Types.BottomEdge)&&(root.panelAlignment === NowDock.PanelWindow.Right)
AnchorChanges {
target: barLine
anchors{ top:undefined; bottom:parent.bottom; left:undefined; right:parent.right; horizontalCenter:undefined; verticalCenter:undefined}
}
AnchorChanges {
target: belower
anchors{ top:parent.bottom; bottom:undefined; left:parent.right; right:undefined; horizontalCenter:undefined; verticalCenter:undefined}
}
AnchorChanges {
target: shadowsSvgItem
anchors{ top:undefined; bottom:belower.bottom; left:undefined; right:belower.right; horizontalCenter:undefined; verticalCenter:undefined}
}
},
State {
name: "bottomDouble"
when: (plasmoid.location === PlasmaCore.Types.BottomEdge)&&(root.panelAlignment === NowDock.PanelWindow.Double)
AnchorChanges {
target: barLine
anchors{ top:undefined; bottom:parent.bottom; left:undefined; right:undefined; horizontalCenter:parent.horizontalCenter; verticalCenter:undefined}
}
AnchorChanges {
target: belower
anchors{ top:parent.bottom; bottom:undefined; left:undefined; right:undefined; horizontalCenter:parent.horizontalCenter; verticalCenter:undefined}
}
AnchorChanges {
target: shadowsSvgItem
anchors{ top:undefined; bottom:belower.bottom; left:undefined; right:undefined; horizontalCenter:parent.horizontalCenter; verticalCenter:undefined}
}
},
///Top
State {
name: "topCenter"
when: (plasmoid.location === PlasmaCore.Types.TopEdge)&&(root.panelAlignment === NowDock.PanelWindow.Center)
AnchorChanges {
target: barLine
anchors{ top:parent.top; bottom:undefined; left:undefined; right:undefined; horizontalCenter:parent.horizontalCenter; verticalCenter:undefined}
}
AnchorChanges {
target: belower
anchors{ top:undefined; bottom:parent.top; left:undefined; right:undefined; horizontalCenter:parent.horizontalCenter; verticalCenter:undefined}
}
AnchorChanges {
target: shadowsSvgItem
anchors{ top:belower.top; bottom:undefined; left:undefined; right:undefined; horizontalCenter:parent.horizontalCenter; verticalCenter:undefined}
}
},
State {
name: "topLeft"
when: (plasmoid.location === PlasmaCore.Types.TopEdge)&&(root.panelAlignment === NowDock.PanelWindow.Left)
AnchorChanges {
target: barLine
anchors{ top:parent.top; bottom:undefined; left:parent.left; right:undefined; horizontalCenter:undefined; verticalCenter:undefined}
}
AnchorChanges {
target: belower
anchors{ top:undefined; bottom:parent.top; left:undefined; right:parent.left; horizontalCenter:undefined; verticalCenter:undefined}
}
AnchorChanges {
target: shadowsSvgItem
anchors{ top:belower.top; bottom:undefined; left:belower.left; right:undefined; horizontalCenter:undefined; verticalCenter:undefined}
}
},
State {
name: "topRight"
when: (plasmoid.location === PlasmaCore.Types.TopEdge)&&(root.panelAlignment === NowDock.PanelWindow.Right)
AnchorChanges {
target: barLine
anchors{ top:parent.top; bottom:undefined; left:undefined; right:parent.right; horizontalCenter:undefined; verticalCenter:undefined}
}
AnchorChanges {
target: belower
anchors{ top:undefined; bottom:parent.top; left:parent.right; right:undefined; horizontalCenter:undefined; verticalCenter:undefined}
}
AnchorChanges {
target: shadowsSvgItem
anchors{ top:belower.top; bottom:undefined; left:undefined; right:belower.right; horizontalCenter:undefined; verticalCenter:undefined}
}
},
State {
name: "topDouble"
when: (plasmoid.location === PlasmaCore.Types.TopEdge)&&(root.panelAlignment === NowDock.PanelWindow.Double)
AnchorChanges {
target: barLine
anchors{ top:parent.top; bottom:undefined; left:undefined; right:undefined; horizontalCenter:parent.horizontalCenter; verticalCenter:undefined}
}
AnchorChanges {
target: belower
anchors{ top:undefined; bottom:parent.top; left:undefined; right:undefined; horizontalCenter:parent.horizontalCenter; verticalCenter:undefined}
}
AnchorChanges {
target: shadowsSvgItem
anchors{ top:belower.top; bottom:undefined; left:undefined; right:undefined; horizontalCenter:parent.horizontalCenter; verticalCenter:undefined}
}
}
]
//END states
}

View File

@ -0,0 +1,446 @@
import QtQuick 2.1
import QtQuick.Window 2.2
import org.kde.plasma.core 2.0 as PlasmaCore
import org.kde.plasma.plasmoid 2.0
import org.kde.taskmanager 0.1 as TaskManager
import org.kde.nowdock 0.1 as NowDock
Item{
id: manager
anchors.fill: parent
property QtObject window
property bool inStartup: root.inStartup
property bool normalState : false // this is being set from updateMaskArea
property int animationSpeed: root.durationTime * 1.2 * units.longDuration
property int length: root.isVertical ? Screen.height : Screen.width //screenGeometry.height : screenGeometry.width
//it is used in order to not break the calculations for the thickness placement
//especially in automatic icon sizes calculations
property int iconMarginOriginal: 0.12*plasmoid.configuration.iconSize
property int statesLineSizeOriginal: root.nowDock ? Math.ceil( plasmoid.configuration.iconSize/13 ) : 0
property int thicknessAutoHidden: 2
property int thicknessMid: root.statesLineSize + (1 + (0.65 * (root.zoomFactor-1)))*(root.iconSize+root.iconMargin) //needed in some animations
property int thicknessNormal: root.statesLineSize + root.iconSize + root.iconMargin + 1
property int thicknessZoom: root.statesLineSize + ((root.iconSize+root.iconMargin) * root.zoomFactor) + 2
//it is used to keep thickness solid e.g. when iconSize changes from auto functions
property int thicknessMidOriginal: statesLineSizeOriginal + (1 + (0.65 * (root.zoomFactor-1)))*(plasmoid.configuration.iconSize+iconMarginOriginal) //needed in some animations
property int thicknessNormalOriginal: root.useThemePanel ? Math.max(thicknessNormalOriginalValue, root.realPanelSize) : thicknessNormalOriginalValue
property int thicknessNormalOriginalValue: statesLineSizeOriginal + plasmoid.configuration.iconSize + iconMarginOriginal + 1
property int thicknessZoomOriginal: statesLineSizeOriginal + ((plasmoid.configuration.iconSize+iconMarginOriginal) * root.zoomFactor) + 2
Binding{
//this is way to avoid warnings for null during initialization phase
target: window ? window.visibility : manager
property:"panelVisibility"
when: window && window.visibility
value: plasmoid.configuration.panelVisibility
}
Binding{
target: window
property:"maxThickness"
when: window
value: thicknessZoomOriginal
}
onWindowChanged: {
if(window) {
window.visibility.onDisableHidingChanged.connect(slotDisableHidingChanged);
window.visibility.onIsHoveredChanged.connect(slotIsHoveredChanged);
window.visibility.onMustBeLowered.connect(slotMustBeLowered);
window.visibility.onMustBeRaised.connect(slotMustBeRaised);
window.visibility.onMustBeRaisedImmediately.connect(slotMustBeRaisedImmediately);
window.visibility.onPanelVisibilityChanged.connect(slotPanelVisibilityChanged);
}
}
onInStartupChanged: {
if (!inStartup) {
delayAnimationTimer.start();
}
}
onNormalStateChanged: {
if(normalState && nowDock) {
nowDock.publishTasksGeometries();
}
if (normalState) {
root.updateAutomaticIconSize();
}
}
onThicknessZoomOriginalChanged: updateMaskArea();
function slotDisableHidingChanged() {
if (!window.disableHiding) {
checkListHovered.restart();
}
}
function slotIsHoveredChanged() {
if(window.isHovered) {
//stop parent window timer for auto hiding
if ((window.visibility.panelVisibility === NowDock.PanelWindow.AutoHide)|| window.visibility.isDockWindowType) {
if(hideMagicWindowInAutoHide.forcedDisableHiding) {
hideMagicWindowInAutoHide.forcedDisableHiding = false;
window.visibility.disableHiding = false;
}
hideMagicWindowInAutoHide.stop();
}
if (delayerTimer.running) {
delayerTimer.stop();
}
updateMaskArea();
} else {
// initialize the zoom
delayerTimer.start();
}
}
function slotMustBeRaised() {
if ((window.visibility.panelVisibility === NowDock.PanelWindow.AutoHide) || window.visibility.isDockWindowType) {
slidingAnimationAutoHiddenIn.init();
} else {
slidingAnimation.init(true,false);
}
}
function slotMustBeRaisedImmediately() {
slidingAnimation.init(true,true);
}
function slotMustBeLowered() {
if ((window.visibility.panelVisibility === NowDock.PanelWindow.AutoHide) || window.visibility.isDockWindowType ) {
slidingAnimationAutoHiddenOut.init();
} else {
slidingAnimation.init(false,false);
}
}
function slotPanelVisibilityChanged() {
if (window.visibility.panelVisibility !== NowDock.PanelWindow.AutoHide) {
window.visibility.isAutoHidden = false;
}
}
///test maskArea
function updateMaskArea() {
if (!windowSystem.compositingActive || !window) {
return;
}
var localX = 0;
var localY = 0;
normalState = (root.nowDockHoveredIndex === -1) && (layoutsContainer.hoveredIndex === -1)
&& (root.appletsAnimations === 0)
&& (root.animationsNeedBothAxis === 0) && (root.animationsNeedLength === 0)
&& (!mainLayout.animatedLength)
// debug maskArea criteria
// console.log(root.nowDockHoveredIndex + ", " + layoutsContainer.hoveredIndex + ", "
// + root.appletsAnimations+ ", "
// + root.animationsNeedBothAxis + ", " + root.animationsNeedLength + ", " + root.animationsNeedThickness +", "
// + mainLayout.animatedLength);
var tempLength = root.isHorizontal ? width : height;
var tempThickness = root.isHorizontal ? height : width;
var space = root.panelEdgeSpacing + 10;
if (normalState && plasmoid.immutable) {
//count panel length
if(root.isHorizontal) {
tempLength = plasmoid.configuration.panelPosition === NowDock.Types.Double ? layoutsContainer.width + 0.5*space : mainLayout.width + space;
} else {
tempLength = plasmoid.configuration.panelPosition === NowDock.Types.Double ? layoutsContainer.height + 0.5*space : mainLayout.height + space;
}
tempThickness = thicknessNormalOriginal;
if (root.animationsNeedThickness > 0) {
tempThickness = thicknessMidOriginal;
}
if (window.visibility.isAutoHidden && ((window.visibility.panelVisibility === NowDock.Types.AutoHide) || window.visibility.isDockWindowType)) {
tempThickness = thicknessAutoHidden;
}
//configure x,y based on plasmoid position and root.panelAlignment(Alignment)
if ((plasmoid.location === PlasmaCore.Types.BottomEdge) || (plasmoid.location === PlasmaCore.Types.TopEdge)) {
if (plasmoid.location === PlasmaCore.Types.BottomEdge) {
localY = window.height - tempThickness;
} else if (plasmoid.location === PlasmaCore.Types.TopEdge) {
localY = 0;
}
if (plasmoid.configuration.panelPosition === NowDock.Types.Double) {
localX = (window.width/2) - (layoutsContainer.width/2) - 0.25*space;
} else if (root.panelAlignment === NowDock.Types.Left) {
localX = 0;
} else if (root.panelAlignment === NowDock.Types.Center) {
localX = (window.width/2) - (mainLayout.width/2) - (space/2);
} else if (root.panelAlignment === NowDock.Types.Right) {
localX = window.width - mainLayout.width - (space/2);
}
} else if ((plasmoid.location === PlasmaCore.Types.LeftEdge) || (plasmoid.location === PlasmaCore.Types.RightEdge)){
if (plasmoid.location === PlasmaCore.Types.LeftEdge) {
localX = 0;
} else if (plasmoid.location === PlasmaCore.Types.RightEdge) {
localX = window.width - tempThickness;
}
if (plasmoid.configuration.panelPosition === NowDock.Types.Double) {
localY = (window.height/2) - (layoutsContainer.height/2) - 0.25*space;
} else if (root.panelAlignment === NowDock.Types.Top) {
localY = 0;
} else if (root.panelAlignment === NowDock.Types.Center) {
localY = (window.height/2) - (mainLayout.height/2) - (space/2);
} else if (root.panelAlignment === NowDock.Types.Bottom) {
localY = window.height - mainLayout.height - (space/2);
}
}
} else {
if(root.isHorizontal)
tempLength = Screen.width; //screenGeometry.width;
else
tempLength = Screen.height; //screenGeometry.height;
//grow only on length and not thickness
if(mainLayout.animatedLength || !plasmoid.immutable) {
tempThickness = thicknessNormalOriginal;
if (root.animationsNeedThickness > 0) {
tempThickness = thicknessMidOriginal;
}
//configure the x,y position based on thickness
if(plasmoid.location === PlasmaCore.Types.RightEdge)
localX = window.width - tempThickness;
else if(plasmoid.location === PlasmaCore.Types.BottomEdge)
localY = window.height - tempThickness;
} else{
//use all thickness space
tempThickness = thicknessZoomOriginal;
}
}
var maskArea = window.maskArea;
var maskLength = maskArea.width; //in Horizontal
if (root.isVertical) {
maskLength = maskArea.height;
}
var maskThickness = maskArea.height; //in Horizontal
if (root.isVertical) {
maskThickness = maskArea.width;
}
// console.log("Not updating mask...");
if( maskArea.x !== localX || maskArea.y !== localY
|| maskLength !== tempLength || maskThickness !== tempThickness) {
// console.log("Updating mask...");
var newMaskArea = Qt.rect(-1,-1,0,0);
newMaskArea.x = localX;
newMaskArea.y = localY;
if (isHorizontal) {
newMaskArea.width = tempLength;
newMaskArea.height = tempThickness;
} else {
newMaskArea.width = tempThickness;
newMaskArea.height = tempLength;
}
window.maskArea = newMaskArea;
}
}
Loader{
anchors.fill: parent
active: root.debugMode
sourceComponent: Item{
anchors.fill:parent
Rectangle{
id: windowBackground
anchors.fill: parent
border.color: "red"
border.width: 1
color: "transparent"
}
Rectangle{
x: window ? window.maskArea.x : 0
y: window ? window.maskArea.y : 0
height: window ? window.maskArea.height : -1
width: window ? window.maskArea.width : -1
border.color: "green"
border.width: 1
color: "transparent"
}
}
}
/***Hiding/Showing Animations*****/
SequentialAnimation{
id: slidingAnimation
property bool inHalf: false
property bool raiseFlag: false
property bool immediateShow: false
SequentialAnimation{
PropertyAnimation {
target: layoutsContainer
property: root.isVertical ? "x" : "y"
to: ((plasmoid.location===PlasmaCore.Types.LeftEdge)||(plasmoid.location===PlasmaCore.Types.TopEdge)) ? -thicknessNormal : thicknessNormal
duration: slidingAnimation.immediateShow ? 100 : manager.animationSpeed
easing.type: Easing.OutQuad
}
PropertyAnimation {
target: slidingAnimation
property: "inHalf"
to: true
duration: 100
}
PropertyAnimation {
target: layoutsContainer
property: root.isVertical ? "x" : "y"
to: 0
duration: manager.animationSpeed
easing.type: Easing.OutQuad
}
}
onStopped: {
inHalf = false;
raiseFlag = false;
immediateShow = false;
}
onInHalfChanged: {
if (inHalf) {
if (raiseFlag) {
window.visibility.showOnTop();
} else {
window.visibility.showOnBottom();
}
}
}
function init(raise, immediate) {
// if(window.visible) {
raiseFlag = raise;
immediateShow = immediate;
start();
// }
}
}
//////////////// Auto Hide Animations - Slide In - Out
SequentialAnimation{
id: slidingAnimationAutoHiddenOut
PropertyAnimation {
target: layoutsContainer
property: root.isVertical ? "x" : "y"
to: ((plasmoid.location===PlasmaCore.Types.LeftEdge)||(plasmoid.location===PlasmaCore.Types.TopEdge)) ? -thicknessNormal : thicknessNormal
duration: manager.animationSpeed
easing.type: Easing.OutQuad
}
onStopped: {
window.visibility.isAutoHidden = true;
updateMaskArea();
}
function init() {
start();
}
}
SequentialAnimation{
id: slidingAnimationAutoHiddenIn
PropertyAnimation {
target: layoutsContainer
property: root.isVertical ? "x" : "y"
to: 0
duration: manager.animationSpeed
easing.type: Easing.OutQuad
}
onStopped: {
if (!plasmoid.immutable) {
// updateTransientThickness();
}
}
function init() {
window.visibility.isAutoHidden = false;
updateMaskArea();
start();
}
}
///////////// External Connections //////
TaskManager.ActivityInfo {
onCurrentActivityChanged: {
window.visibility.disableHiding = true;
if (window.visibility.isAutoHidden) {
window.visibility.mustBeRaised();
}
hideMagicWindowInAutoHide.forcedDisableHiding = true;
hideMagicWindowInAutoHide.start();
}
}
////////////// Timers //////
//Timer to delay onLeave event
Timer {
id: delayerTimer
interval: 400
onTriggered: {
root.clearZoom();
if (root.nowDock) {
nowDock.clearZoom();
}
}
}
//Timer to delay onLeave event
Timer {
id: delayAnimationTimer
interval: manager.inStartup ? 1000 : 500
onTriggered: {
layoutsContainer.opacity = 1;
if ((window.visibility.panelVisibility !== NowDock.PanelWindow.AutoHide) && !window.visibility.isDockWindowType) {
slidingAnimation.init(true,false);
} else {
slidingAnimationAutoHiddenIn.init();
}
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,22 @@
[Desktop Entry]
Encoding=UTF-8
Name=Now Dock
Comment=A dock for Plasma that tries to animate its plasmoids on hovering
Type=Service
Keywords=
NoDisplay=true
X-KDE-PluginInfo-Author=@AUTHOR@
X-KDE-PluginInfo-Email=@EMAIL@
X-KDE-PluginInfo-Name=org.kde.nowdock.containment
X-KDE-PluginInfo-Version=@VERSION@
X-KDE-PluginInfo-Website=@WEBSITE@
X-KDE-PluginInfo-Category=
X-KDE-PluginInfo-Depends=
X-KDE-PluginInfo-License=GPL
X-KDE-PluginInfo-EnabledByDefault=true
X-KDE-ServiceTypes=Plasma/Applet,Plasma/Containment
X-Plasma-API=declarativeappletscript
X-Plasma-MainScript=ui/main.qml
X-Plasma-ContainmentType=Panel

47
corona/CMakeLists.txt Normal file
View File

@ -0,0 +1,47 @@
include(KDEInstallDirs)
include(KDECMakeSettings)
#include(KDECompilerSettings NO_POLICY_SCOPE)
#include(ECMPackageConfigHelpers)
include(CMakePackageConfigHelpers)
include(WriteBasicConfigVersionFile)
include(CheckIncludeFiles)
include(ECMOptionalAddSubdirectory)
include(ECMQtDeclareLoggingCategory)
include(KDEPackageAppTemplates)
set(nowdock-app_SRCS
../libnowdock/types.cpp
abstractinterface.cpp
xwindowinterface.cpp
visibilitymanager.cpp
nowdockconfigview.cpp
nowdockview.cpp
packageplugins/shell/nowdockpackage.cpp
nowdockcorona.cpp
main.cpp
)
#add_subdirectory(packageplugins)
add_executable(nowdock ${nowdock-app_SRCS})
target_link_libraries(
nowdock
Qt5::Widgets
Qt5::Quick
Qt5::Qml
KF5::I18n
KF5::CoreAddons
KF5::XmlGui
KF5::PlasmaQuick
KF5::Plasma
KF5::QuickAddons
KF5::DBusAddons
KF5::Notifications
)
install(TARGETS nowdock ${KDE_INSTALL_TARGETS_DEFAULT_ARGS})
#even if hidden, the desktop file is needed anyways for kdbusservice::unique
install(FILES nowdock.desktop DESTINATION ${KDE_INSTALL_APPDIR})

View File

@ -0,0 +1,42 @@
#include "abstractinterface.h"
#include <QObject>
#include <QQuickWindow>
namespace NowDock {
AbstractInterface::AbstractInterface(QQuickWindow *dock) :
QObject(dock),
m_isDockWindowType(false),
m_dockNumber(0)
{
m_dockWindow = dock;
}
void AbstractInterface::setDockNumber(unsigned int no)
{
if (m_dockNumber == no) {
return;
}
m_dockNumber = no;
emit dockNumberChanged(m_dockNumber);
}
unsigned int AbstractInterface::dockNumber() const
{
return m_dockNumber;
}
void AbstractInterface::setMaskArea(QRect area)
{
if (m_maskArea == area) {
return;
}
m_maskArea = area;
}
}

View File

@ -0,0 +1,56 @@
#ifndef ABSTRACTINTERFACE_H
#define ABSTRACTINTERFACE_H
#include <QObject>
#include <QQuickWindow>
namespace NowDock {
class AbstractInterface : public QObject {
Q_OBJECT
public:
explicit AbstractInterface(QQuickWindow *dock);
virtual bool activeIsDialog() const = 0;
virtual bool activeIsMaximized() const = 0;
virtual bool desktopIsActive() const = 0;
virtual bool dockIntersectsActiveWindow() const = 0;
virtual bool dockIsCovered(bool totally = false) const = 0;
virtual bool dockIsCovering() const = 0;
virtual bool dockIsOnTop() const = 0;
virtual bool dockInNormalState() const = 0;
virtual bool dockIsBelow() const = 0;
//FIXME: This may not be needed, it would be better to investigate in KWindowSystem
//its behavior when setting the window type to NET::Dock
virtual void setDockDefaultFlags(bool dock = false) = 0;
virtual void setDockToAllDesktops() = 0;
virtual void showDockAsNormal() = 0;
virtual void showDockOnBottom() = 0;
virtual void showDockOnTop() = 0;
void setDockNumber(unsigned int no);
unsigned int dockNumber() const;
void setMaskArea(QRect area);
Q_SIGNALS:
void activeWindowChanged();
void dockNumberChanged(unsigned int no);
void windowInAttention(bool);
//FIXME: there is a chance that this signal is not needed at all
void windowChanged();
protected:
bool m_isDockWindowType;
int m_dockNumber;
QRect m_maskArea;
QQuickWindow *m_dockWindow;
};
}
#endif

77
corona/main.cpp Normal file
View File

@ -0,0 +1,77 @@
/*
* Copyright 2014 Bhushan Shah <bhush94@gmail.com>
* Copyright 2014 Marco Martin <notmart@gmail.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License or (at your option) version 3 or any later version
* accepted by the membership of KDE e.V. (or its successor approved
* by the membership of KDE e.V.), which shall act as a proxy
* defined in Section 14 of version 3 of the license.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>
*/
#include "nowdockcorona.h"
#include <memory>
#include <QApplication>
#include <QQuickWindow>
#include <qcommandlineparser.h>
#include <qcommandlineoption.h>
#include <QDebug>
#include <KLocalizedString>
//! COLORS
#define CNORMAL "\e[0m"
#define CIGREEN "\e[1;32m"
#define CGREEN "\e[0;32m"
#define CICYAN "\e[1;36m"
#define CCYAN "\e[0;36m"
#define CIRED "\e[1;31m"
#define CRED "\e[0;31m"
#ifdef QT_NO_DEBUG
#define DEPTH "1"
#else
#define DEPTH "8"
#endif
static const char version[] = "0.1";
int main(int argc, char **argv)
{
QQuickWindow::setDefaultAlphaBuffer(true);
QApplication app(argc, argv);
app.setApplicationVersion(version);
app.setOrganizationDomain(QStringLiteral("nowdock"));
app.setApplicationName(QStringLiteral("NowDock"));
//! set pattern for debug messages
//! [%{type}] [%{function}:%{line}] - %{message} [%{backtrace}]
qSetMessagePattern(QStringLiteral(
CIGREEN "[%{type} " CGREEN "%{time h:mm:ss.zzzz}" CIGREEN "]" CNORMAL
#ifndef QT_NO_DEBUG
CIRED " [" CCYAN "%{function}" CIRED ":" CCYAN "%{line}" CIRED "]"
#endif
CICYAN " - " CNORMAL "%{message}"
CIRED "%{if-fatal}\n%{backtrace depth=" DEPTH " separator=\"\n\"}%{endif}"
"%{if-warning}\n%{backtrace depth=" DEPTH " separator=\"\n\"}%{endif}"
"%{if-critical}\n%{backtrace depth=" DEPTH " separator=\"\n\"}%{endif}" CNORMAL));
// qputenv("QT_QUICK_CONTROLS_1_STYLE", "Desktop");
NowDockCorona corona;
return app.exec();
}

16
corona/nowdock.desktop Normal file
View File

@ -0,0 +1,16 @@
[Desktop Entry]
Name=Now Dock
Comment=Now Dock Application
Exec=nowdock %u
Hidden=true
Icon=plasma
InitialPreference=1
Path=
StartupNotify=true
Terminal=false
TerminalOptions=
Type=Application
X-DBUS-ServiceName=
X-DBUS-StartupType=unique
X-KDE-SubstituteUID=false
X-KDE-Username=

View File

@ -0,0 +1,204 @@
/*
* Copyright 2016 Smith AR <audoban@openmailbox.org>
*
* This file is part of Candil-Dock
*
* Candil-Dock is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 3 of
* the License, or (at your option) any later version.
*
* Candil-Dock is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "nowdockconfigview.h"
#include "nowdockview.h"
#include <QQuickItem>
#include <QQmlContext>
#include <QScreen>
#include <KWindowSystem>
#include <KWindowEffects>
#include <plasma/package.h>
NowDockConfigView::NowDockConfigView(Plasma::Containment *containment, NowDockView *dockView, QWindow *parent)
: PlasmaQuick::ConfigView(containment, parent), m_containment(containment), m_dockView(dockView)
{
m_deleterTimer.setSingleShot(true);
m_deleterTimer.setInterval(10 * 1000);
connect(&m_deleterTimer, &QTimer::timeout, this, &QObject::deleteLater);
connect(dockView, &QObject::destroyed, this, &QObject::deleteLater);
m_screenSyncTimer.setSingleShot(true);
m_screenSyncTimer.setInterval(100);
connect(dockView, SIGNAL(screenChanged(QScreen *)), &m_screenSyncTimer, SLOT(start()));
connect(&m_screenSyncTimer, &QTimer::timeout, this, [this]() {
setScreen(m_dockView->screen());
setFlags(wFlags());
syncGeometry();
syncSlideEffect();
});
//containment->setLocation(Plasma::Types::LeftEdge);
/*connect(containment, &Plasma::Containment::immutabilityChanged
, [&](Plasma::Types::ImmutabilityType type) {
if (type != Plasma::Types::Mutable && isVisible())
hide();
});*/
}
NowDockConfigView::~NowDockConfigView()
{
}
void NowDockConfigView::init()
{
setDefaultAlphaBuffer(true);
setColor(Qt::transparent);
rootContext()->setContextProperty(QStringLiteral("dock"), m_dockView);
auto source = QUrl::fromLocalFile(m_containment->corona()->kPackage().filePath("nowdockconfigurationui"));
setSource(source);
syncSlideEffect();
}
inline Qt::WindowFlags NowDockConfigView::wFlags() const
{
return (flags() | Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint) & ~Qt::WindowDoesNotAcceptFocus;
}
void NowDockConfigView::syncGeometry()
{
if (!m_containment || !rootObject())
return;
const auto location = m_containment->location();
const auto sGeometry = screen()->geometry();
switch (m_containment->formFactor()) {
case Plasma::Types::Horizontal: {
const QSize size(rootObject()->width(), rootObject()->height());
setMaximumSize(size);
setMinimumSize(size);
resize(size);
if (location == Plasma::Types::TopEdge) {
setPosition(sGeometry.center().x() - size.width() / 2
, m_dockView->currentThickness());
} else if (location == Plasma::Types::BottomEdge) {
setPosition(sGeometry.center().x() - size.width() / 2
, sGeometry.height() - m_dockView->currentThickness() - size.height());
}
}
break;
case Plasma::Types::Vertical: {
const QSize size(rootObject()->width(), rootObject()->height());
setMaximumSize(size);
setMinimumSize(size);
resize(size);
if (location == Plasma::Types::LeftEdge) {
setPosition(m_dockView->currentThickness()
, sGeometry.center().y() - size.height() / 2);
} else if (location == Plasma::Types::RightEdge) {
setPosition(sGeometry.width() - m_dockView->currentThickness() - size.width()
, sGeometry.center().y() - size.height() / 2);
}
}
break;
default:
qWarning() << "no sync geometry, wrong formFactor";
//<< qEnumToStr(m_containment->formFactor());
break;
}
}
void NowDockConfigView::syncSlideEffect()
{
if (!m_containment)
return;
KWindowEffects::SlideFromLocation slideLocation{KWindowEffects::NoEdge};
switch (m_containment->location()) {
case Plasma::Types::TopEdge:
slideLocation = KWindowEffects::TopEdge;
break;
case Plasma::Types::RightEdge:
slideLocation = KWindowEffects::RightEdge;
break;
case Plasma::Types::BottomEdge:
slideLocation = KWindowEffects::BottomEdge;
break;
case Plasma::Types::LeftEdge:
slideLocation = KWindowEffects::LeftEdge;
break;
default:
qDebug() << staticMetaObject.className() << "wrong location";// << qEnumToStr(m_containment->location());
break;
}
KWindowEffects::slideWindow(winId(), slideLocation, -1);
}
void NowDockConfigView::showEvent(QShowEvent *ev)
{
KWindowSystem::setType(winId(), NET::Dock);
setFlags(wFlags());
KWindowSystem::setState(winId(), NET::KeepAbove | NET::SkipPager | NET::SkipTaskbar);
KWindowSystem::forceActiveWindow(winId());
KWindowEffects::enableBlurBehind(winId(), true);
syncGeometry();
syncSlideEffect();
if (m_containment)
m_containment->setUserConfiguring(true);
// m_dockView->visibility()->forceShow(true);
// m_dockView->visibility()->showImmediately();
m_screenSyncTimer.start();
m_deleterTimer.stop();
ConfigView::showEvent(ev);
}
void NowDockConfigView::hideEvent(QHideEvent *ev)
{
// m_dockView->visibility()->forceShow(false);
// m_dockView->visibility()->restore();
m_deleterTimer.start();
if (m_containment) {
m_dockView->saveConfig();
m_containment->setUserConfiguring(false);
}
ConfigView::hideEvent(ev);
}
void NowDockConfigView::focusOutEvent(QFocusEvent *ev)
{
Q_UNUSED(ev);
const auto *focusWindow = qGuiApp->focusWindow();
if (focusWindow && focusWindow->flags().testFlag(Qt::Popup))
return;
hide();
}
// kate: indent-mode cstyle; indent-width 4; replace-tabs on;

View File

@ -0,0 +1,63 @@
/*
* Copyright 2016 Smith AR <audoban@openmailbox.org>
*
* This file is part of Candil-Dock
*
* Candil-Dock is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 3 of
* the License, or (at your option) any later version.
*
* Candil-Dock is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef NOWDOCKCONFIGVIEW_H
#define NOWDOCKCONFIGVIEW_H
#include "plasmaquick/configview.h"
#include <QObject>
#include <QWindow>
#include <QPointer>
#include <QTimer>
namespace Plasma {
class Applet;
class Containment;
}
class NowDockView;
class NowDockConfigView : public PlasmaQuick::ConfigView {
Q_OBJECT
public:
NowDockConfigView(Plasma::Containment *containment, NowDockView *dockView, QWindow *parent = nullptr);
~NowDockConfigView() override;
void init() override;
Qt::WindowFlags wFlags() const;
protected:
void showEvent(QShowEvent *ev) override;
void hideEvent(QHideEvent *ev) override;
void focusOutEvent(QFocusEvent *ev) override;
void syncGeometry();
void syncSlideEffect();
private:
Plasma::Containment *m_containment{nullptr};
QPointer<NowDockView> m_dockView;
QTimer m_deleterTimer;
QTimer m_screenSyncTimer;
};
#endif //DOCKCONFIGVIEW_H
// kate: indent-mode cstyle; indent-width 4; replace-tabs on;

231
corona/nowdockcorona.cpp Normal file
View File

@ -0,0 +1,231 @@
/*
* Copyright 2014 Bhushan Shah <bhush94@gmail.com>
* Copyright 2014 Marco Martin <notmart@gmail.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License or (at your option) version 3 or any later version
* accepted by the membership of KDE e.V. (or its successor approved
* by the membership of KDE e.V.), which shall act as a proxy
* defined in Section 14 of version 3 of the license.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>
*/
#include "nowdockcorona.h"
#include "nowdockview.h"
//#include "visibilitymanager.h"
#include "packageplugins/shell/nowdockpackage.h"
#include <QAction>
#include <QScreen>
#include <QDebug>
#include <KActionCollection>
#include <KPluginMetaData>
#include <Plasma>
#include <Plasma/Corona>
#include <Plasma/Containment>
#include <KLocalizedString>
#include <KPackage/Package>
#include <KPackage/PackageLoader>
NowDockCorona::NowDockCorona(QObject *parent)
: Plasma::Corona(parent)
{
KPackage::Package package(new NowDockPackage(this));
if (!package.isValid()) {
qWarning() << staticMetaObject.className()
<< "the package" << package.metadata().rawData() << "is invalid!";
return;
} else {
qDebug() << staticMetaObject.className()
<< "the package" << package.metadata().rawData() << "is valid!";
}
setKPackage(package);
qmlRegisterTypes();
connect(this, &Corona::containmentAdded, this, &NowDockCorona::addDock);
loadLayout();
/*QAction *addDock = actions()->add<QAction>(QStringLiteral("add dock"));
connect(addDock, &QAction::triggered, this, &NowDockCorona::loadDefaultLayout);
addDock->setText(i18n("Add New Dock"));
addDock->setAutoRepeat(true);
addDock->setStatusTip(tr("Adds a new dock in the environment"));
addDock->setVisible(true);
addDock->setEnabled(true);
addDock->setIcon(QIcon::fromTheme(QStringLiteral("object-locked")));
addDock->setData(Plasma::Types::ControlAction);
addDock->setShortcut(QKeySequence(QStringLiteral("alt+d, l")));
addDock->setShortcutContext(Qt::ApplicationShortcut);*/
}
NowDockCorona::~NowDockCorona()
{
for (auto c : m_containments)
c->deleteLater();
qDebug() << "deleted" << this;
}
int NowDockCorona::numScreens() const
{
return qGuiApp->screens().count();
}
QRect NowDockCorona::screenGeometry(int id) const
{
const auto screens = qGuiApp->screens();
if (id >= 0 && id < screens.count()) {
return screens[id]->geometry();
}
return qGuiApp->primaryScreen()->geometry();
}
QRegion NowDockCorona::availableScreenRegion(int id) const
{
const auto screens = qGuiApp->screens();
if (id >= 0 && id < screens.count()) {
return screens[id]->geometry();
}
return qGuiApp->primaryScreen()->availableGeometry();
}
QRect NowDockCorona::availableScreenRect(int id) const
{
const auto screens = qGuiApp->screens();
if (id >= 0 && id < screens.count()) {
return screens[id]->availableGeometry();
}
return qGuiApp->primaryScreen()->availableGeometry();
}
QList<Plasma::Types::Location> NowDockCorona::freeEdges(int screen) const
{
using Plasma::Types;
QList<Types::Location> edges{Types::TopEdge, Types::BottomEdge
, Types::LeftEdge, Types::RightEdge};
for (const NowDockView *cont : m_containments) {
if (cont && cont->containment()->screen() == screen)
edges.removeOne(cont->location());
}
return edges;
}
int NowDockCorona::screenForContainment(const Plasma::Containment *containment) const
{
return 0;
while (const auto *parentCont = qobject_cast<const Plasma::Applet *>(containment->parent())) {
if (parentCont->isContainment())
containment = qobject_cast<const Plasma::Containment *>(parentCont);
}
for (auto *view : m_containments) {
if (view && view->containment() == containment)
return containment->screen();
}
return -1;
}
void NowDockCorona::addDock(Plasma::Containment *containment)
{
if (!containment || !containment->kPackage().isValid()) {
qWarning() << "the requested containment plugin can not be located or loaded";
return;
}
qWarning() << "Adding dock for container...";
auto dockView = new NowDockView(this);
dockView->init();
dockView->setContainment(containment);
dockView->show();
//dockView->showNormal();
m_containments.push_back(dockView);
}
void NowDockCorona::loadDefaultLayout()
{
qDebug() << "loading default layout";
//! Settting mutable for create a containment
setImmutability(Plasma::Types::Mutable);
QVariantList args;
auto defaultContainment = createContainmentDelayed("org.kde.nowdock.containment", args);
//auto defaultContainment = createContainmentDelayed("org.kde.panel", args);
defaultContainment->setContainmentType(Plasma::Types::PanelContainment);
defaultContainment->init();
if (!defaultContainment || !defaultContainment->kPackage().isValid()) {
qWarning() << "the requested containment plugin can not be located or loaded";
return;
}
auto config = defaultContainment->config();
config.writeEntry("dock", "initial");
// config.writeEntry("alignment", (int)Dock::Center);
// config.deleteEntry("wallpaperplugin");
switch (containments().size()) {
case 0:
defaultContainment->setLocation(Plasma::Types::LeftEdge);
break;
case 1:
defaultContainment->setLocation(Plasma::Types::RightEdge);
break;
case 2:
defaultContainment->setLocation(Plasma::Types::TopEdge);
break;
default:
defaultContainment->setLocation(Plasma::Types::BottomEdge);
break;
}
auto cfg = defaultContainment->config();
defaultContainment->save(cfg);
addDock(defaultContainment);
defaultContainment->createApplet(QStringLiteral("org.kde.store.nowdock.plasmoid"));
defaultContainment->createApplet(QStringLiteral("org.kde.plasma.analogclock"));
}
inline void NowDockCorona::qmlRegisterTypes() const
{
constexpr auto uri = "org.kde.nowdock.shell";
constexpr auto vMajor = 0;
constexpr auto vMinor = 2;
// qmlRegisterUncreatableType<Candil::Dock>(uri, vMajor, vMinor, "Dock", "class Dock uncreatable");
// qmlRegisterUncreatableType<Candil::VisibilityManager>(uri, vMajor, vMinor, "VisibilityManager", "class VisibilityManager uncreatable");
// qmlRegisterUncreatableType<NowDockView>(uri, vMajor, vMinor, "DockView", "class DockView uncreatable");
qmlRegisterType<QScreen>();
}

64
corona/nowdockcorona.h Normal file
View File

@ -0,0 +1,64 @@
/*
* Copyright 2014 Bhushan Shah <bhush94@gmail.com>
* Copyright 2014 Marco Martin <notmart@gmail.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License or (at your option) version 3 or any later version
* accepted by the membership of KDE e.V. (or its successor approved
* by the membership of KDE e.V.), which shall act as a proxy
* defined in Section 14 of version 3 of the license.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>
*/
#ifndef NOWDOCKCORONA_H
#define NOWDOCKCORONA_H
#include <QObject>
#include "nowdockview.h"
namespace Plasma {
class Corona;
class Containment;
class Types;
}
class NowDockCorona : public Plasma::Corona {
Q_OBJECT
public:
NowDockCorona(QObject *parent = nullptr);
~NowDockCorona() override;
int numScreens() const override;
QRect screenGeometry(int id) const override;
QRegion availableScreenRegion(int id) const override;
QRect availableScreenRect(int id) const override;
QList<Plasma::Types::Location> freeEdges(int screen) const;
int screenForContainment(const Plasma::Containment *containment) const override;
void addDock(Plasma::Containment *containment);
public slots:
void loadDefaultLayout() override;
private:
void qmlRegisterTypes() const;
std::vector<NowDockView *> m_containments;
};
#endif

553
corona/nowdockview.cpp Normal file
View File

@ -0,0 +1,553 @@
/*
* Copyright 2014 Bhushan Shah <bhush94@gmail.com>
* Copyright 2014 Marco Martin <notmart@gmail.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License or (at your option) version 3 or any later version
* accepted by the membership of KDE e.V. (or its successor approved
* by the membership of KDE e.V.), which shall act as a proxy
* defined in Section 14 of version 3 of the license.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>
*/
#include "nowdockview.h"
#include "nowdockconfigview.h"
#include "visibilitymanager.h"
#include <QQmlContext>
#include <QQmlProperty>
#include <QQuickItem>
#include <QMetaEnum>
//#include <QtX11Extras/QX11Info>
#include <NETWM>
#include <KWindowSystem>
#include <Plasma/Containment>
#include <KActionCollection>
#include "nowdockcorona.h"
//using Candil::Dock;
NowDockView::NowDockView(Plasma::Corona *corona, QScreen *targetScreen)
: PlasmaQuick::ContainmentView(corona),
m_corona(corona)
{
KWindowSystem::setType(winId(), NET::Dock);
KWindowSystem::setState(winId(), NET::SkipTaskbar | NET::SkipPager);
setVisible(false);
setTitle(corona->kPackage().metadata().name());
setIcon(QIcon::fromTheme(corona->kPackage().metadata().iconName()));
setResizeMode(QuickViewSharedEngine::SizeRootObjectToView);
setClearBeforeRendering(true);
/* setFlags(Qt::FramelessWindowHint
| Qt::WindowStaysOnTopHint
| Qt::NoDropShadowWindowHint
| Qt::WindowDoesNotAcceptFocus);*/
// NETWinInfo winfo(QX11Info::connection(), winId(), winId(), 0, 0);
// winfo.setAllowedActions(NET::ActionChangeDesktop);
if (targetScreen)
adaptToScreen(targetScreen);
else
adaptToScreen(qGuiApp->primaryScreen());
m_timerGeometry.setSingleShot(true);
m_timerGeometry.setInterval(400);
m_lockGeometry.setSingleShot(true);
m_lockGeometry.setInterval(700);
connect(this, &NowDockView::containmentChanged
, this, [&]() {
if (!containment())
return;
if (!m_visibility) {
m_visibility = new VisibilityManager(this);
}
m_visibility->setContainment(containment());
}, Qt::DirectConnection);
}
NowDockView::~NowDockView()
{
}
void NowDockView::init()
{
connect(this, &NowDockView::screenChanged
, this, &NowDockView::adaptToScreen
, Qt::QueuedConnection);
connect(&m_timerGeometry, &QTimer::timeout, [&]() {
initWindow();
});
connect(this, &NowDockView::locationChanged, [&]() {
//! avoid glitches
m_timerGeometry.start();
});
connect(KWindowSystem::self(), &KWindowSystem::compositingChanged
, this, [&]() {
emit compositingChanged();
} , Qt::QueuedConnection);
connect(this, &NowDockView::screenGeometryChanged
, this, &NowDockView::updateDockPosition
, Qt::QueuedConnection);
connect(this, SIGNAL(widthChanged(int)), this, SIGNAL(widthChanged()));
connect(this, SIGNAL(heightChanged(int)), this, SIGNAL(heightChanged()));
rootContext()->setContextProperty(QStringLiteral("panel"), this);
setSource(corona()->kPackage().filePath("nowdockui"));
connect(this, SIGNAL(xChanged(int)), this, SLOT(updateDockPositionSlot()));
connect(this, SIGNAL(yChanged(int)), this, SLOT(updateDockPositionSlot()));
connect(&m_lockGeometry, &QTimer::timeout, [&]() {
updateDockPosition();
});
qDebug() << "SOURCE:" << source();
initialize();
}
void NowDockView::initialize()
{
m_secondInitPass = true;
m_timerGeometry.start();
}
void NowDockView::initWindow()
{
// m_visibility->updateVisibilityFlags();
updateDockPosition();
resizeWindow();
// The initialization phase makes two passes because
// changing the window style and type wants a small delay
// and afterwards the second pass positions them correctly
if (m_secondInitPass) {
m_timerGeometry.start();
m_secondInitPass = false;
setVisible(true);
}
}
void NowDockView::updateDockPositionSlot()
{
if (!m_lockGeometry.isActive()) {
m_lockGeometry.start();
}
}
//!BEGIN SLOTS
void NowDockView::adaptToScreen(QScreen *screen)
{
setScreen(screen);
if (formFactor() == Plasma::Types::Vertical)
m_maxLength = screen->size().height();
else
m_maxLength = screen->size().width();
// KWindowSystem::setOnAllDesktops(winId(), true);
// KWindowSystem::setType(winId(), NET::Dock);
if (containment())
containment()->reactToScreenChange();
m_timerGeometry.start();
}
void NowDockView::addNewDock()
{
NowDockCorona *corona = dynamic_cast<NowDockCorona *>(m_corona);
if (corona) {
corona->loadDefaultLayout();
}
}
QQmlListProperty<QScreen> NowDockView::screens()
{
return QQmlListProperty<QScreen>(this, nullptr, &countScreens, &atScreens);
}
int NowDockView::countScreens(QQmlListProperty<QScreen> *property)
{
Q_UNUSED(property)
return qGuiApp->screens().count();
}
QScreen *NowDockView::atScreens(QQmlListProperty<QScreen> *property, int index)
{
Q_UNUSED(property)
return qGuiApp->screens().at(index);
}
void NowDockView::showConfigurationInterface(Plasma::Applet *applet)
{
if (!applet || !applet->containment())
return;
Plasma::Containment *c = qobject_cast<Plasma::Containment *>(applet);
if (m_configView && c && c->isContainment() && c == containment()) {
if (m_configView->isVisible()) {
m_configView->hide();
} else {
m_configView->show();
m_configView->requestActivate();
}
return;
} else if (m_configView) {
if (m_configView->applet() == applet) {
m_configView->show();
m_configView->requestActivate();
return;
} else {
m_configView->hide();
m_configView->deleteLater();
}
}
if (c && containment() && c->isContainment() && c->id() == containment()->id()) {
m_configView = new NowDockConfigView(c, this);
} else {
m_configView = new PlasmaQuick::ConfigView(applet);
}
m_configView->init();
m_configView->show();
m_configView->requestActivate();
}
void NowDockView::resizeWindow()
{
setVisible(true);
QSize screenSize = screen()->size();
if (formFactor() == Plasma::Types::Vertical) {
const QSize size{maxThickness(), screenSize.height()};
setMinimumSize(size);
setMaximumSize(size);
resize(size);
qDebug() << "dock size:" << size;
} else {
const QSize size{screenSize.width(), maxThickness()};
setMinimumSize(size);
setMaximumSize(size);
resize(size);
qDebug() << "dock size:" << size;
}
}
inline void NowDockView::updateDockPosition()
{
if (!containment())
return;
const QRect screenGeometry = screen()->geometry();
QPoint position;
qDebug() << "current dock geometry: " << geometry();
// containment()->setFormFactor(Plasma::Types::Horizontal);
position = {0, 0};
m_maxLength = screenGeometry.width();
switch (location()) {
case Plasma::Types::TopEdge:
containment()->setFormFactor(Plasma::Types::Horizontal);
position = {screenGeometry.x(), screenGeometry.y()};
m_maxLength = screenGeometry.width();
break;
case Plasma::Types::BottomEdge:
containment()->setFormFactor(Plasma::Types::Horizontal);
position = {screenGeometry.x(), screenGeometry.y() + screenGeometry.height() - height()};
m_maxLength = screenGeometry.width();
break;
case Plasma::Types::RightEdge:
containment()->setFormFactor(Plasma::Types::Vertical);
position = {screenGeometry.x() + screenGeometry.width() - width(), screenGeometry.y()};
m_maxLength = screenGeometry.height();
break;
case Plasma::Types::LeftEdge:
containment()->setFormFactor(Plasma::Types::Vertical);
position = {screenGeometry.x(), screenGeometry.y()};
m_maxLength = screenGeometry.height();
break;
default:
qWarning() << "wrong location, couldn't update the panel position"
<< location();
}
emit maxLengthChanged();
setX(position.x());
setY(position.y());
//setPosition(position);
qDebug() << "dock position:" << position;
}
int NowDockView::currentThickness() const
{
if (containment()->formFactor() == Plasma::Types::Vertical) {
return m_maskArea.isNull() ? width() : m_maskArea.width();
} else {
return m_maskArea.isNull() ? height() : m_maskArea.height();
}
}
bool NowDockView::compositing() const
{
return KWindowSystem::compositingActive();
}
/*Candil::VisibilityManager *NowDockView::visibility()
{
return m_visibility.data();
}*/
int NowDockView::maxThickness() const
{
return m_maxThickness;
}
void NowDockView::setMaxThickness(int thickness)
{
if (m_maxThickness == thickness)
return;
m_maxThickness = thickness;
m_timerGeometry.start();
emit maxThicknessChanged();
}
int NowDockView::length() const
{
return m_length;
}
void NowDockView::setLength(int length)
{
if (m_length == length)
return;
if (length > m_maxLength)
m_length = m_maxLength;
else
m_length = length;
m_timerGeometry.start();
emit lengthChanged();
}
int NowDockView::maxLength() const
{
return m_maxLength;
}
void NowDockView::setMaxLength(int maxLength)
{
if (m_maxLength == maxLength)
return;
m_maxLength = maxLength;
emit maxLengthChanged();
}
QRect NowDockView::maskArea() const
{
return m_maskArea;
}
void NowDockView::setMaskArea(QRect area)
{
if (m_maskArea == area) {
return;
}
m_maskArea = area;
m_visibility->setMaskArea(area);
setMask(m_maskArea);
//qDebug() << "dock mask set:" << m_maskArea;
emit maskAreaChanged();
}
/*Dock::Alignment NowDockView::alignment() const
{
return m_alignment;
}
void NowDockView::setAlignment(Dock::Alignment align)
{
if (m_alignment == align)
return;
m_alignment = align;
emit alignmentChanged();
}
*/
int NowDockView::offset() const
{
return m_offset;
}
void NowDockView::setOffset(int offset)
{
if (m_offset == offset)
return;
m_offset = offset;
m_timerGeometry.start();
emit offsetChanged();
}
void NowDockView::updateOffset()
{
if (!containment())
return;
const float offsetPercent = containment()->config().readEntry("offset").toFloat();
const int offset = offsetPercent * (m_maxLength - m_length) / 2;
if (offset == m_offset)
return;
m_offset = offset;
emit offsetChanged();
}
VisibilityManager *NowDockView::visibility()
{
return m_visibility;
}
bool NowDockView::event(QEvent *e)
{
/* if (ev->type() == QEvent::Enter) {
m_visibility->show();
emit entered();
} else if (ev->type() == QEvent::Leave) {
m_visibility->restore();
emit exited();
} */
//return QQuickWindow::event(e);
if (m_visibility) {
m_visibility->event(e);
}
return ContainmentView::event(e);
}
/*void NowDockView::showEvent(QShowEvent *ev)
{
KWindowSystem::setType(winId(), NET::Dock);
KWindowSystem::setOnAllDesktops(winId(), true);
//QQuickWindow::showEvent(ev);
ContainmentView::showEvent(ev);
}*/
bool NowDockView::containmentContainsPosition(const QPointF &point) const
{
QQuickItem *containmentItem = containment()->property("_plasma_graphicObject").value<QQuickItem *>();
if (!containmentItem) {
return false;
}
return QRectF(containmentItem->mapToScene(QPoint(0, 0)), QSizeF(containmentItem->width(), containmentItem->height())).contains(point);
}
QPointF NowDockView::positionAdjustedForContainment(const QPointF &point) const
{
QQuickItem *containmentItem = containment()->property("_plasma_graphicObject").value<QQuickItem *>();
if (!containmentItem) {
return point;
}
QRectF containmentRect(containmentItem->mapToScene(QPoint(0, 0)), QSizeF(containmentItem->width(), containmentItem->height()));
return QPointF(qBound(containmentRect.left() + 2, point.x(), containmentRect.right() - 2),
qBound(containmentRect.top() + 2, point.y(), containmentRect.bottom() - 2));
}
void NowDockView::saveConfig()
{
if (!containment())
return;
const auto writeEntry = [&](const char *entry, const QVariant & value) {
containment()->config().writeEntry(entry, value);
};
//! convert offset to percent, range [-1,1] 0 is Centered
//! offsetPercent = offset * 2 / (maxLength - length)
// const float offsetPercent = m_offset * 2.0f / (m_maxLength - m_length);
// writeEntry("offset", offsetPercent);
// writeEntry("iconSize", m_iconSize);
// writeEntry("zoomFactor", m_zoomFactor);
// writeEntry("alignment", static_cast<int>(m_alignment));
}
void NowDockView::restoreConfig()
{
if (!containment())
return;
const auto readEntry = [&](const char *entry, QVariant defaultValue) -> QVariant {
return containment()->config().readEntry(entry, defaultValue);
};
//! convert offset-percent to pixels
//! offset = offsetPercent * (maxLength - length) / 2
// const float offsetPercent {readEntry("offset", 0).toFloat()};
// const int offset {static_cast<int>(offsetPercent * (m_maxLength - m_length) / 2)};
// setOffset(offset);
// setIconSize(readEntry("iconSize", 32).toInt());
// setZoomFactor(readEntry("zoomFactor", 1.0).toFloat());
// setAlignment(static_cast<Dock::Alignment>(readEntry("alignment", Dock::Center).toInt()));
}
//!END SLOTS
//!END namespace

163
corona/nowdockview.h Normal file
View File

@ -0,0 +1,163 @@
/*
* Copyright 2014 Bhushan Shah <bhush94@gmail.com>
* Copyright 2014 Marco Martin <notmart@gmail.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License or (at your option) version 3 or any later version
* accepted by the membership of KDE e.V. (or its successor approved
* by the membership of KDE e.V.), which shall act as a proxy
* defined in Section 14 of version 3 of the license.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>
*/
#ifndef NOWDOCKVIEW_H
#define NOWDOCKVIEW_H
#include <climits>
#include "plasmaquick/configview.h"
#include "plasmaquick/containmentview.h"
#include "visibilitymanager.h"
#include <QQuickView>
#include <QQmlListProperty>
#include <QScreen>
#include <QPointer>
#include <QTimer>
namespace Plasma {
class Types;
class Corona;
class Containment;
}
/*namespace Candil {
class Dock;
class DockView;
class DockConfigView;
class VisibilityManager;
}*/
class NowDockView : public PlasmaQuick::ContainmentView {
Q_OBJECT
Q_PROPERTY(bool compositing READ compositing NOTIFY compositingChanged)
Q_PROPERTY(int height READ height NOTIFY heightChanged)
Q_PROPERTY(int length READ length WRITE setLength NOTIFY lengthChanged)
Q_PROPERTY(int maxLength READ maxLength WRITE setMaxLength NOTIFY maxLengthChanged)
Q_PROPERTY(int maxThickness READ maxThickness WRITE setMaxThickness NOTIFY maxThicknessChanged)
Q_PROPERTY(int offset READ offset WRITE setOffset NOTIFY offsetChanged)
Q_PROPERTY(int width READ width NOTIFY widthChanged)
Q_PROPERTY(QRect maskArea READ maskArea WRITE setMaskArea NOTIFY maskAreaChanged)
Q_PROPERTY(VisibilityManager *visibility READ visibility NOTIFY visibilityChanged)
Q_PROPERTY(QQmlListProperty<QScreen> screens READ screens)
public:
NowDockView(Plasma::Corona *corona, QScreen *targetScreen = nullptr);
virtual ~NowDockView();
void init();
// Candil::VisibilityManager *visibility();
int maxThickness() const;
void setMaxThickness(int thickness);
int length() const;
void setLength(int length);
QRect maskArea() const;
void setMaskArea(QRect area);
int maxLength() const;
void setMaxLength(int maxLength);
// Dock::Alignment alignment() const;
// void setAlignment(Dock::Alignment align);
int offset() const;
void setOffset(int offset);
void updateOffset();
VisibilityManager *visibility();
bool compositing() const;
int currentThickness() const;
void adaptToScreen(QScreen *screen);
QQmlListProperty<QScreen> screens();
static int countScreens(QQmlListProperty<QScreen> *property);
static QScreen *atScreens(QQmlListProperty<QScreen> *property, int index);
public slots:
Q_INVOKABLE void addNewDock();
Q_INVOKABLE void initialize();
void resizeWindow();
void restoreConfig();
void saveConfig();
void updateDockPosition();
protected slots:
void showConfigurationInterface(Plasma::Applet *applet) override;
protected:
bool event(QEvent *ev) override;
// void showEvent(QShowEvent *ev) override;
signals:
// void visibilityChanged();
void alignmentChanged();
void compositingChanged();
void heightChanged();
void lengthChanged();
void maskAreaChanged();
void maxLengthChanged();
void maxThicknessChanged();
void offsetChanged();
void visibilityChanged();
void widthChanged();
public Q_SLOTS:
void updateDockPositionSlot();
private:
bool m_secondInitPass;
int m_offset{0};
int m_maxThickness{24};
int m_length{0};
int m_maxLength{INT_MAX};
QRect m_dockGeometry;
QRect m_maskArea;
QPointer<PlasmaQuick::ConfigView> m_configView;
QTimer m_timerGeometry;
QTimer m_lockGeometry;
Plasma::Theme *theme{nullptr};
Plasma::Corona *m_corona;
QPointer<VisibilityManager> m_visibility;
bool containmentContainsPosition(const QPointF &point) const;
QPointF positionAdjustedForContainment(const QPointF &point) const;
void initWindow();
};
#endif

View File

@ -0,0 +1 @@
add_subdirectory(shell)

View File

@ -0,0 +1 @@
set(nowdock-app_SRCS nowdockpackage.cpp)

View File

@ -0,0 +1,43 @@
#include "nowdockpackage.h"
#include <KPackage/PackageLoader>
#include <KI18n/KLocalizedString>
#include <QDebug>
NowDockPackage::NowDockPackage(QObject *parent, const QVariantList &args)
: KPackage::PackageStructure(parent, args)
{
}
NowDockPackage::~NowDockPackage()
{
}
void NowDockPackage::initPackage(KPackage::Package *package)
{
auto fallback = KPackage::PackageLoader::self()->loadPackage("Plasma/Shell", "org.kde.plasma.desktop");
package->setDefaultPackageRoot(QStringLiteral("plasma/shells/"));
package->setPath("org.kde.nowdock.shell");
package->addFileDefinition("nowdockui", QStringLiteral("views/Panel.qml"), i18n("Now Dock panel"));
//Configuration
package->addFileDefinition("nowdockconfigurationui", QStringLiteral("configuration/NowDockConfiguration.qml"), i18n("Dock configuration UI"));
package->addFileDefinition("configmodel", QStringLiteral("configuration/config.qml"), i18n("Config model"));
package->setFallbackPackage(fallback);
qDebug() << "package is valid" << package->isValid();
}
void NowDockPackage::pathChanged(KPackage::Package *package)
{
if (!package->metadata().isValid())
return;
const QString pluginName = package->metadata().pluginId();
if (!pluginName.isEmpty() && pluginName != "org.kde.nowdock.shell") {
auto fallback = KPackage::PackageLoader::self()->loadPackage("NowDock/Shell", "org.kde.nowdock.shell");
package->setFallbackPackage(fallback);
} else if (pluginName.isEmpty() || pluginName == "org.kde.nowdock.shell") {
package->setFallbackPackage(KPackage::Package());
}
}

View File

@ -0,0 +1,18 @@
#ifndef NOWDOCKPACKAGE_H
#define NOWDOCKPACKAGE_H
#include <QObject>
#include <KPackage/PackageStructure>
class NowDockPackage : public KPackage::PackageStructure {
Q_OBJECT
public:
explicit NowDockPackage(QObject *parent = 0, const QVariantList &args = QVariantList());
~NowDockPackage() override;
void initPackage(KPackage::Package *package) override;
void pathChanged(KPackage::Package *package) override;
};
#endif // NOWDOCKPACKAGE_H

View File

@ -0,0 +1,89 @@
/*
* Copyright 2013 Marco Martin <mart@kde.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library General Public License as
* published by the Free Software Foundation; either version 2, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details
*
* You should have received a copy of the GNU Library General Public
* License along with this program; if not, write to the
* Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef CONFIGVIEW_H
#define CONFIGVIEW_H
#include <QQuickView>
//
// W A R N I N G
// -------------
//
// This file is not part of the public Plasma API. It exists purely as an
// implementation detail. This header file may change from version to
// version without notice, or even be removed.
//
// We mean it.
//
namespace Plasma {
class Applet;
}
namespace PlasmaQuick {
class ConfigViewPrivate;
class ConfigModel;
class ConfigView : public QQuickView {
Q_OBJECT
Q_PROPERTY(PlasmaQuick::ConfigModel *configModel READ configModel CONSTANT)
Q_PROPERTY(QString appletGlobalShortcut READ appletGlobalShortcut WRITE setAppletGlobalShortcut NOTIFY appletGlobalShortcutChanged)
public:
/**
* @param applet the applet of this ConfigView
* @param parent the QWindow in which this ConfigView is parented to
**/
ConfigView(Plasma::Applet *applet, QWindow *parent = 0);
~ConfigView() override;
virtual void init();
Plasma::Applet *applet();
QString appletGlobalShortcut() const;
void setAppletGlobalShortcut(const QString &shortcut);
/**
* @return the ConfigModel of the ConfigView
**/
PlasmaQuick::ConfigModel *configModel() const;
Q_SIGNALS:
void appletGlobalShortcutChanged();
protected:
void hideEvent(QHideEvent *ev) override;
void resizeEvent(QResizeEvent *re) override;
private:
ConfigViewPrivate *const d;
Q_PRIVATE_SLOT(d, void updateMinimumWidth())
Q_PRIVATE_SLOT(d, void updateMinimumHeight())
Q_PRIVATE_SLOT(d, void updateMaximumWidth())
Q_PRIVATE_SLOT(d, void updateMaximumHeight())
};
}
#endif // multiple inclusion guard

View File

@ -0,0 +1,133 @@
/*
* Copyright 2012 Marco Martin <mart@kde.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef PLASMAQUICKCONTAINMENTVIEW_H
#define PLASMAQUICKCONTAINMENTVIEW_H
#include <kquickaddons/quickviewsharedengine.h>
#include "plasma/corona.h"
#include "plasma/containment.h"
//
// W A R N I N G
// -------------
//
// This file is not part of the public Plasma API. It exists purely as an
// implementation detail. This header file may change from version to
// version without notice, or even be removed.
//
// We mean it.
//
namespace PlasmaQuick {
class ContainmentViewPrivate;
class ContainmentView : public KQuickAddons::QuickViewSharedEngine {
Q_OBJECT
Q_PROPERTY(Plasma::Types::Location location READ location WRITE setLocation NOTIFY locationChanged)
Q_PROPERTY(Plasma::Types::FormFactor formFactor READ formFactor NOTIFY formFactorChanged)
Q_PROPERTY(QRectF screenGeometry READ screenGeometry NOTIFY screenGeometryChanged)
public:
/**
* @param corona the corona of this view
* @param parent the QWindow this ContainmentView is parented to
**/
explicit ContainmentView(Plasma::Corona *corona, QWindow *parent = 0);
~ContainmentView() override;
/**
* @return the corona of this view
**/
Plasma::Corona *corona() const;
/**
* @return the KConfigGroup of this view
**/
virtual KConfigGroup config() const;
/**
* sets the containment for this view
* @param cont the containment of this view
**/
void setContainment(Plasma::Containment *cont);
/**
* @return the containment of this ContainmentView
**/
Plasma::Containment *containment() const;
/**
* @return the location of this ContainmentView
**/
Plasma::Types::Location location() const;
/**
* Sets the location of the ContainmentView
* @param location the location of the ContainmentView
**/
void setLocation(Plasma::Types::Location location);
/**
* @return the formfactor of the ContainmentView
**/
Plasma::Types::FormFactor formFactor() const;
/**
* @return the screenGeometry of the ContainmentView
**/
QRectF screenGeometry();
protected Q_SLOTS:
/**
* It will be called when the configuration is requested
*/
virtual void showConfigurationInterface(Plasma::Applet *applet);
Q_SIGNALS:
/**
* emitted when the location is changed
**/
void locationChanged(Plasma::Types::Location location);
/**
* emitted when the formfactor is changed
**/
void formFactorChanged(Plasma::Types::FormFactor formFactor);
/**
* emitted when the containment is changed
**/
void containmentChanged();
/**
* emitted when the screenGeometry is changed
**/
void screenGeometryChanged();
private:
ContainmentViewPrivate *const d;
Q_PRIVATE_SLOT(d, void updateDestroyed(bool))
friend class ContainmentViewPrivate;
};
}
#endif // CONTAINMENTVIEW_H

132
corona/plasmaquick/view.h Normal file
View File

@ -0,0 +1,132 @@
/*
* Copyright 2012 Marco Martin <mart@kde.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef PLASMAQUICKVIEW_H
#define PLASMAQUICKVIEW_H
#include <QtQuick/QQuickView>
#include "plasma/corona.h"
#include "plasma/containment.h"
//
// W A R N I N G
// -------------
//
// This file is not part of the public Plasma API. It exists purely as an
// implementation detail. This header file may change from version to
// version without notice, or even be removed.
//
// We mean it.
//
namespace PlasmaQuick {
class ViewPrivate;
class View : public QQuickView {
Q_OBJECT
Q_PROPERTY(Plasma::Types::Location location READ location WRITE setLocation NOTIFY locationChanged)
Q_PROPERTY(Plasma::Types::FormFactor formFactor READ formFactor NOTIFY formFactorChanged)
Q_PROPERTY(QRectF screenGeometry READ screenGeometry NOTIFY screenGeometryChanged)
public:
/**
* @param corona the corona of this view
* @param parent the QWindow this View is parented to
**/
explicit View(Plasma::Corona *corona, QWindow *parent = 0);
~View() override;
/**
* @return the corona of this view
**/
Plasma::Corona *corona() const;
/**
* @return the KConfigGroup of this view
**/
virtual KConfigGroup config() const;
/**
* sets the containment for this view
* @param cont the containment of this view
**/
void setContainment(Plasma::Containment *cont);
/**
* @return the containment of this View
**/
Plasma::Containment *containment() const;
/**
* @return the location of this View
**/
Plasma::Types::Location location() const;
/**
* Sets the location of the View
* @param location the location of the View
**/
void setLocation(Plasma::Types::Location location);
/**
* @return the formfactor of the View
**/
Plasma::Types::FormFactor formFactor() const;
/**
* @return the screenGeometry of the View
**/
QRectF screenGeometry();
protected Q_SLOTS:
/**
* It will be called when the configuration is requested
*/
virtual void showConfigurationInterface(Plasma::Applet *applet);
Q_SIGNALS:
/**
* emitted when the location is changed
**/
void locationChanged(Plasma::Types::Location location);
/**
* emitted when the formfactor is changed
**/
void formFactorChanged(Plasma::Types::FormFactor formFactor);
/**
* emitted when the containment is changed
**/
void containmentChanged();
/**
* emitted when the screenGeometry is changed
**/
void screenGeometryChanged();
private:
ViewPrivate *const d;
friend class ViewPrivate;
};
}
#endif // View_H

View File

@ -0,0 +1,450 @@
#include "visibilitymanager.h"
#include "abstractinterface.h"
#include "xwindowinterface.h"
#include "plasmaquick/containmentview.h"
#include "../libnowdock/types.h"
#include <QDebug>
#include <Plasma/Containment>
VisibilityManager::VisibilityManager(PlasmaQuick::ContainmentView *view) :
QObject(view),
m_disableHiding(false),
m_isAutoHidden(false),
m_isDockWindowType(true),
m_isHovered(false),
m_secondInitPass(false),
m_windowIsInAttention(false),
m_childrenLength(-1),
m_view(view)
{
// m_windowSystem = new WindowSystem(this);
// connect(m_windowSystem, SIGNAL(compositingChanged()), this, SLOT(compositingChanged()));
m_interface = new NowDock::XWindowInterface(m_view);
connect(m_interface, SIGNAL(windowInAttention(bool)), this, SLOT(setWindowInAttention(bool)));
connect(m_interface, SIGNAL(activeWindowChanged()), this, SLOT(activeWindowChanged()));
m_interface->setDockToAllDesktops();
//fixes a bug in plasma-framework with wrong popups placement
m_interface->setDockNumber(2);
// connect(this, SIGNAL(screenChanged(QScreen *)), this, SLOT(screenChanged(QScreen *)));
// setPanelScreen(screen());
m_updateStateTimer.setSingleShot(true);
m_updateStateTimer.setInterval(900);
connect(&m_updateStateTimer, &QTimer::timeout, this, &VisibilityManager::updateState);
m_initTimer.setSingleShot(true);
m_initTimer.setInterval(400);
connect(&m_initTimer, &QTimer::timeout, this, &VisibilityManager::initWindow);
connect(this, SIGNAL(panelVisibilityChanged()), this, SLOT(updateVisibilityFlags()));
setPanelVisibility(NowDock::Types::BelowActive);
// updateVisibilityFlags();
// connect(this, SIGNAL(locationChanged()), this, SLOT(updateWindowPosition()));
connect(this, SIGNAL(windowInAttentionChanged()), this, SLOT(updateState()));
initialize();
}
VisibilityManager::~VisibilityManager()
{
}
void VisibilityManager::setContainment(Plasma::Containment *containment)
{
if (containment == m_containment) {
return;
}
m_containment = containment;
// setVisibility(mode);
}
NowDock::Types::Visibility VisibilityManager::panelVisibility() const
{
return m_panelVisibility;
}
void VisibilityManager::setPanelVisibility(NowDock::Types::Visibility state)
{
if (m_panelVisibility == state) {
return;
}
m_panelVisibility = state;
emit panelVisibilityChanged();
}
bool VisibilityManager::isAutoHidden() const
{
return m_isAutoHidden;
}
void VisibilityManager::setIsAutoHidden(bool state)
{
if (m_isAutoHidden == state) {
return;
}
m_isAutoHidden = state;
emit isAutoHiddenChanged();
}
bool VisibilityManager::windowInAttention() const
{
return m_windowIsInAttention;
}
void VisibilityManager::setWindowInAttention(bool state)
{
if (m_windowIsInAttention == state) {
return;
}
m_windowIsInAttention = state;
emit windowInAttentionChanged();
}
bool VisibilityManager::disableHiding() const
{
return m_disableHiding;
}
void VisibilityManager::setDisableHiding(bool value)
{
if (m_disableHiding == value) {
return;
}
m_disableHiding = value;
emit disableHidingChanged();
if (!m_disableHiding) {
m_updateStateTimer.start();
}
}
bool VisibilityManager::isDockWindowType() const
{
return m_isDockWindowType;
}
void VisibilityManager::setIsDockWindowType(bool state)
{
if (m_isDockWindowType == state) {
return;
}
m_isDockWindowType = state;
updateVisibilityFlags();
emit isDockWindowTypeChanged();
m_updateStateTimer.start();
}
bool VisibilityManager::isHovered() const
{
return m_isHovered;
}
void VisibilityManager::setIsHovered(bool state)
{
if (m_isHovered == state) {
return;
}
m_isHovered = state;
emit isHoveredChanged();
}
void VisibilityManager::setMaskArea(QRect area)
{
m_interface->setMaskArea(area);
}
/*******************************/
void VisibilityManager::initialize()
{
m_secondInitPass = true;
m_initTimer.start();
}
void VisibilityManager::initWindow()
{
updateVisibilityFlags();
// updateWindowPosition();
// The initialization phase makes two passes because
// changing the window style and type wants a small delay
// and afterwards the second pass positions them correctly
if (m_secondInitPass) {
m_initTimer.start();
m_secondInitPass = false;
}
}
/*void VisibilityManager::updateWindowPosition()
{
//setPanelScreen(screen());
// qDebug() << "updateWindowPosition: start...";
if (!transientParent() || !transientParent()->screen()) {
// qDebug() << "updateWindowPosition: break transient...";
return;
}
// qDebug() << "updateWindowPosition: transientParent setting screen position...";
setPanelScreen(transientParent()->screen());
if (!m_screen || m_screenGeometry.isNull()) {
// qDebug() << "updateWindowPosition: break m_screen...";
return;
}
// qDebug() << "updateWindowPosition: check passed...";
// qDebug() << m_screen->geometry().x() << " - " << m_screen->geometry().y() << " - " << m_screen->geometry().width() << " - " << m_screen->geometry().height();
if (m_location == Plasma::Types::BottomEdge) {
setX(m_screenGeometry.x());
setY(m_screenGeometry.y()+m_screenGeometry.height() - height());
} else if (m_location == Plasma::Types::TopEdge) {
setX(m_screenGeometry.x());
setY(m_screenGeometry.y());
} else if (m_location == Plasma::Types::LeftEdge) {
setX(m_screenGeometry.x());
setY(m_screenGeometry.y());
} else if (m_location == Plasma::Types::RightEdge) {
setX(m_screenGeometry.x()+m_screenGeometry.width() - width());
setY(m_screenGeometry.y());
}
///FIXME: in come cases the below can not catch up and this may be the reason
//that on start up in some cases dock's contents are not shown,
//needs a timer maybe?
/*if (m_screen != screen()) {
setScreen(m_screen);
}*/
//}
void VisibilityManager::updateVisibilityFlags()
{
m_interface->setDockToAllDesktops();
/* if ((m_panelVisibility == AutoHide)||(m_isDockWindowType)) {
m_updateStateTimer.setInterval(2500);
} else {
m_updateStateTimer.setInterval(1500);
}*/
m_interface->setDockDefaultFlags(m_isDockWindowType);
// updateWindowPosition();
if (!m_isDockWindowType) {
showOnTop();
}
m_updateStateTimer.start();
}
/*
* It is used from the m_updateStateTimer in order to check the dock's
* visibility and trigger events and actions which are needed to
* respond accordingly
*/
void VisibilityManager::updateState()
{
// qDebug() << "in update state disableHiding:" <<m_disableHiding;
//update the dock behavior
switch (m_panelVisibility) {
case NowDock::Types::BelowActive:
if (!m_interface->desktopIsActive() && m_interface->dockIntersectsActiveWindow()) {
if (m_interface->dockIsOnTop() || (m_isDockWindowType && !m_isAutoHidden)) {
// qDebug() << m_isHovered << " - " << m_windowIsInAttention << " - "<< m_disableHiding;
if (!m_isHovered && !m_windowIsInAttention && !m_disableHiding) {
// qDebug() << "must be lowered....";
emit mustBeLowered(); //showNormal();
}
} else {
if (m_windowIsInAttention) {
if (!m_isDockWindowType || (m_isDockWindowType && m_isAutoHidden)) {
emit mustBeRaised(); //showOnTop();
}
}
}
} else {
if (!m_interface->activeIsDialog()) {
if ((!m_interface->desktopIsActive() && m_interface->dockIsCovered())
|| (m_isDockWindowType && m_isAutoHidden)) {
// qDebug() << "must be raised....";
emit mustBeRaised();
} else {
showOnTop();
}
}
}
break;
case NowDock::Types::BelowMaximized:
if (!m_interface->desktopIsActive() && m_interface->activeIsMaximized() && m_interface->dockIntersectsActiveWindow()) {
if (m_interface->dockIsOnTop() || (m_isDockWindowType && !m_isAutoHidden)) {
if (!m_isHovered && !m_windowIsInAttention && !m_disableHiding) {
emit mustBeLowered(); //showNormal();
}
} else {
if (m_windowIsInAttention) {
if (!m_isDockWindowType || (m_isDockWindowType && m_isAutoHidden)) {
emit mustBeRaised(); //showOnTop();
}
}
}
} else {
if ((!m_interface->desktopIsActive() && m_interface->dockIsCovered())
|| (m_isDockWindowType && m_isAutoHidden)) {
emit mustBeRaised();
} else {
showOnTop();
}
}
break;
case NowDock::Types::LetWindowsCover:
//this is not supported in clean Dock Window Types such as in wayland case
if (m_isDockWindowType) {
return;
}
if (!m_isHovered && m_interface->dockIsOnTop()) {
if (m_interface->dockIsCovering()) {
if (!m_disableHiding) {
emit mustBeLowered();
}
} else {
showOnBottom();
}
} else if (m_windowIsInAttention) {
if (!m_interface->dockIsOnTop()) {
if (m_interface->dockIsCovered()) {
emit mustBeRaised();
} else {
showOnTop();
}
}
}
break;
case NowDock::Types::WindowsGoBelow:
//Do nothing, the dock is OnTop state in every case
break;
case NowDock::Types::AutoHide:
if (m_windowIsInAttention && m_isAutoHidden) {
emit mustBeRaised();
} else if (!m_isHovered && !m_disableHiding) {
emit mustBeLowered();
}
break;
case NowDock::Types::AlwaysVisible:
//Do nothing, the dock in OnTop state in every case
break;
}
}
void VisibilityManager::showOnTop()
{
// qDebug() << "reached make top...";
m_interface->showDockOnTop();
}
void VisibilityManager::showNormal()
{
// qDebug() << "reached make normal...";
m_interface->showDockAsNormal();
}
void VisibilityManager::showOnBottom()
{
// qDebug() << "reached make bottom...";
m_interface->showDockOnBottom();
}
/***************/
void VisibilityManager::activeWindowChanged()
{
if ((m_panelVisibility == NowDock::Types::WindowsGoBelow)
|| (m_panelVisibility == NowDock::Types::AlwaysVisible)
|| (m_panelVisibility == NowDock::Types::AutoHide)) {
return;
}
//this check is important because otherwise the signals are so often
//that the timer is never triggered
if (!m_updateStateTimer.isActive()) {
m_updateStateTimer.start();
}
}
//It is used in order to trigger a beautiful slide in effect when
//the dock is totally hidden underneath
void VisibilityManager::showOnTopCheck()
{
if ((m_panelVisibility == NowDock::Types::BelowActive) || (m_panelVisibility == NowDock::Types::BelowMaximized)
|| (m_panelVisibility == NowDock::Types::LetWindowsCover)) {
if (m_interface->dockIsCovered(true)) {
m_updateStateTimer.stop();
setIsHovered(true);
emit mustBeRaisedImmediately();
} else {
showOnTop();
}
}
}
bool VisibilityManager::event(QEvent *event)
{
if (!event) {
return false;
}
if ((event->type() == QEvent::Enter) && !m_isHovered) {
m_updateStateTimer.stop();
setIsHovered(true);
if ((m_panelVisibility == NowDock::Types::AutoHide) || (m_isDockWindowType)) {
if (m_isAutoHidden) {
emit mustBeRaised();
}
} else {
showOnTop();
}
} else if (event->type() == QEvent::Leave) {
setIsHovered(false);
if ((m_panelVisibility != NowDock::Types::WindowsGoBelow)
&& (m_panelVisibility != NowDock::Types::AlwaysVisible)) {
m_updateStateTimer.start();
}
}
return true;
}

106
corona/visibilitymanager.h Normal file
View File

@ -0,0 +1,106 @@
#ifndef VISIBILITYMANAGER_H
#define VISIBILITYMANAGER_H
#include <QObject>
#include "../libnowdock/types.h"
#include "abstractinterface.h"
#include "plasmaquick/containmentview.h"
#include <QTimer>
#include <Plasma/Containment>
class VisibilityManager : public QObject {
Q_OBJECT
Q_PROPERTY(bool disableHiding READ disableHiding WRITE setDisableHiding NOTIFY disableHidingChanged)
//Q_PROPERTY(bool immutable READ immutable WRITE setImmutable NOTIFY immutableChanged)
Q_PROPERTY(bool isAutoHidden READ isAutoHidden WRITE setIsAutoHidden NOTIFY isAutoHiddenChanged)
Q_PROPERTY(bool isDockWindowType READ isDockWindowType WRITE setIsDockWindowType NOTIFY isDockWindowTypeChanged)
Q_PROPERTY(bool isHovered READ isHovered NOTIFY isHoveredChanged)
Q_PROPERTY(bool windowInAttention READ windowInAttention WRITE setWindowInAttention NOTIFY windowInAttentionChanged)
Q_PROPERTY(NowDock::Types::Visibility panelVisibility READ panelVisibility WRITE setPanelVisibility NOTIFY panelVisibilityChanged)
public:
explicit VisibilityManager(PlasmaQuick::ContainmentView *view);
~VisibilityManager();
bool disableHiding() const;
void setDisableHiding(bool state);
bool isAutoHidden() const;
void setIsAutoHidden(bool state);
bool isDockWindowType() const;
void setIsDockWindowType(bool state);
bool isHovered() const;
bool windowInAttention() const;
NowDock::Types::Visibility panelVisibility() const;
void setContainment(Plasma::Containment *contaiment);
void setMaskArea(QRect area);
void setPanelVisibility(NowDock::Types::Visibility state);
public slots:
Q_INVOKABLE void initialize();
Q_INVOKABLE void showNormal();
Q_INVOKABLE void showOnTop();
Q_INVOKABLE void showOnTopCheck();
Q_INVOKABLE void showOnBottom();
bool event(QEvent *event);
void setWindowInAttention(bool state);
void updateVisibilityFlags();
Q_SIGNALS:
void disableHidingChanged();
void isAutoHiddenChanged();
void isDockWindowTypeChanged();
void isHoveredChanged();
void mustBeLowered(); //are used to triger the sliding animations from the qml part
void mustBeRaised();
void mustBeRaisedImmediately();
void panelVisibilityChanged();
void windowInAttentionChanged();
private Q_SLOTS:
void activeWindowChanged();
//void compositingChanged();
void updateState();
void initWindow();
void setIsHovered(bool state);
//void screenChanged(QScreen *screen);
//void setScreenGeometry(QRect geometry);
//void updateWindowPosition();
private:
bool m_disableHiding;
bool m_isAutoHidden;
bool m_isDockWindowType;
bool m_isHovered;
//second pass of the initialization
bool m_secondInitPass;
bool m_windowIsInAttention;
int m_childrenLength;
QRect m_maskArea;
QTimer m_initTimer;
QTimer m_updateStateTimer;
Plasma::Containment *m_containment;
PlasmaQuick::ContainmentView *m_view;
NowDock::AbstractInterface *m_interface;
NowDock::Types::Visibility m_panelVisibility;
};
#endif

361
corona/xwindowinterface.cpp Normal file
View File

@ -0,0 +1,361 @@
#include "xwindowinterface.h"
#include <QDebug>
#include <KWindowInfo>
#include <KWindowSystem>
namespace NowDock {
XWindowInterface::XWindowInterface(QQuickWindow *parent) :
AbstractInterface(parent),
m_demandsAttention(0)
{
m_activeWindow = KWindowSystem::activeWindow();
connect(KWindowSystem::self(), SIGNAL(activeWindowChanged(WId)), this, SLOT(activeWindowChanged(WId)));
connect(KWindowSystem::self(), SIGNAL(windowChanged(WId, NET::Properties, NET::Properties2)), this, SLOT(windowChanged(WId, NET::Properties, NET::Properties2)));
connect(KWindowSystem::self(), SIGNAL(windowRemoved(WId)), this, SLOT(windowRemoved(WId)));
connect(this, SIGNAL(dockNumberChanged(uint)), this, SLOT(dockNumberChanged(uint)));
}
XWindowInterface::~XWindowInterface()
{
}
void XWindowInterface::dockNumberChanged(unsigned int no)
{
if (no == 1) {
m_dockWindow->setFlags(Qt::Tool | Qt::WindowDoesNotAcceptFocus | Qt::FramelessWindowHint);
}
}
void XWindowInterface::setDockToAllDesktops()
{
KWindowSystem::setOnAllDesktops(m_dockWindow->winId(), true);
}
void XWindowInterface::setDockDefaultFlags(bool dock)
{
//Notice: the Qt::Tool flag even though it works perfectly for a single Now Dock
//it creates a strange situation when there are two and more Now Dock's
//in that case it is used only for the first created Now Dock
m_isDockWindowType = dock;
if ((m_dockNumber == 1) && (!m_isDockWindowType)) {
m_dockWindow->setFlags(Qt::Tool | Qt::WindowDoesNotAcceptFocus | Qt::FramelessWindowHint);
} else {
KWindowSystem::setType(m_dockWindow->winId(), NET::Dock);
KWindowSystem::setState(m_dockWindow->winId(), NET::SkipTaskbar | NET::SkipPager);
}
}
void XWindowInterface::showDockOnTop()
{
//this is the only way in order to not break the case of two and more NowDocks
//there is a small issue that the pop ups from locked plasmoids are opened
//on the maximum thickness
//qDebug() << "Docknumber:" << m_dockNumber;
if (m_isDockWindowType) {
return;
}
if (m_dockNumber != 1) {
KWindowSystem::setType(m_dockWindow->winId(), NET::Dock);
}
KWindowSystem::clearState(m_dockWindow->winId(), NET::KeepBelow);
KWindowSystem::setState(m_dockWindow->winId(), NET::KeepAbove);
}
void XWindowInterface::showDockAsNormal()
{
// qDebug() << "reached make normal...";
if (m_isDockWindowType) {
return;
}
if (m_dockNumber != 1) {
m_dockWindow->setFlags(Qt::Tool | Qt::WindowDoesNotAcceptFocus | Qt::FramelessWindowHint);
}
KWindowSystem::clearState(m_dockWindow->winId(), NET::KeepAbove);
KWindowSystem::clearState(m_dockWindow->winId(), NET::KeepBelow);
}
void XWindowInterface::showDockOnBottom()
{
// qDebug() << "reached make bottom...";
if (m_isDockWindowType) {
return;
}
if (m_dockNumber != 1) {
m_dockWindow->setFlags(Qt::Tool | Qt::WindowDoesNotAcceptFocus | Qt::FramelessWindowHint);
}
KWindowSystem::clearState(m_dockWindow->winId(), NET::KeepAbove);
KWindowSystem::setState(m_dockWindow->winId(), NET::KeepBelow);
}
bool XWindowInterface::isDesktop(WId id) const
{
KWindowInfo info(id, NET::WMWindowType);
if (!info.valid()) {
return false;
}
NET::WindowType type = info.windowType(NET::DesktopMask | NET::DockMask | NET::DialogMask);
return type == NET::Desktop;
}
bool XWindowInterface::isDialog(WId id) const
{
KWindowInfo info(id, NET::WMWindowType);
if (!info.valid()) {
return false;
}
NET::WindowType type = info.windowType(NET::DesktopMask | NET::DockMask | NET::DialogMask);
return type == NET::Dialog;
}
bool XWindowInterface::isMaximized(WId id) const
{
KWindowInfo info(id, NET::WMState);
if (!info.valid()) {
return false;
}
return (info.hasState(NET::Max));
}
bool XWindowInterface::isNormal(WId id) const
{
return (!isOnBottom(id) && !isOnTop(id));
}
bool XWindowInterface::isOnBottom(WId id) const
{
KWindowInfo info(id, NET::WMState);
if (!info.valid()) {
return false;
}
return (info.hasState(NET::KeepBelow));
}
bool XWindowInterface::isOnTop(WId id) const
{
KWindowInfo info(id, NET::WMState);
if (!info.valid()) {
return false;
}
return (info.hasState(NET::KeepAbove));
}
bool XWindowInterface::activeIsDialog() const
{
return isDialog(m_activeWindow);
}
bool XWindowInterface::activeIsMaximized() const
{
return isMaximized(m_activeWindow);
}
bool XWindowInterface::desktopIsActive() const
{
return isDesktop(m_activeWindow);
}
bool XWindowInterface::dockIsOnTop() const
{
return isOnTop(m_dockWindow->winId());
}
bool XWindowInterface::dockInNormalState() const
{
return isNormal(m_dockWindow->winId());
}
bool XWindowInterface::dockIsBelow() const
{
return isOnBottom(m_dockWindow->winId());
}
bool XWindowInterface::dockIntersectsActiveWindow() const
{
KWindowInfo activeInfo(m_activeWindow, NET::WMGeometry);
if (activeInfo.valid()) {
QRect maskSize;
if (!m_maskArea.isNull()) {
maskSize = QRect(m_dockWindow->x() + m_maskArea.x(), m_dockWindow->y() + m_maskArea.y(), m_maskArea.width(), m_maskArea.height());
} else {
maskSize = QRect(m_dockWindow->x(), m_dockWindow->y(), m_dockWindow->width(), m_dockWindow->height());
}
return maskSize.intersects(activeInfo.geometry());
} else {
return false;
}
}
bool XWindowInterface::dockIsCovered(bool totally) const
{
int currentDockPos = -1;
QList<WId> windows = KWindowSystem::stackingOrder();
int size = windows.count();
for (int i = size - 1; i >= 0; --i) {
WId window = windows.at(i);
if (window == m_dockWindow->winId()) {
currentDockPos = i;
break;
}
}
if (currentDockPos >= 0) {
QRect maskSize;
if (!m_maskArea.isNull()) {
maskSize = QRect(m_dockWindow->x() + m_maskArea.x(), m_dockWindow->y() + m_maskArea.y(), m_maskArea.width(), m_maskArea.height());
} else {
maskSize = QRect(m_dockWindow->x(), m_dockWindow->y(), m_dockWindow->width(), m_dockWindow->height());
}
WId transient = 0;
if (m_dockWindow->transientParent()) {
transient = m_dockWindow->transientParent()->winId();
}
for (int j = size - 1; j > currentDockPos; --j) {
WId window = windows.at(j);
KWindowInfo info(window, NET::WMState | NET::XAWMState | NET::WMGeometry);
if (info.valid() && !isDesktop(window) && transient != window && !info.isMinimized()) {
if (totally) {
QRect winGeometry = info.geometry();
if ((maskSize.left() >= winGeometry.left()) && (maskSize.top() >= winGeometry.top())
&& (maskSize.right() <= winGeometry.right()) && (maskSize.bottom() <= winGeometry.bottom())) {
return true;
}
} else {
if (maskSize.intersects(info.geometry())) {
return true;
}
}
}
}
}
return false;
}
bool XWindowInterface::dockIsCovering() const
{
int currentDockPos = -1;
QList<WId> windows = KWindowSystem::stackingOrder();
int size = windows.count();
for (int i = size - 1; i >= 0; --i) {
WId window = windows.at(i);
if (window == m_dockWindow->winId()) {
currentDockPos = i;
break;
}
}
if (currentDockPos >= 0) {
QRect maskSize;
if (!m_maskArea.isNull()) {
maskSize = QRect(m_dockWindow->x() + m_maskArea.x(), m_dockWindow->y() + m_maskArea.y(), m_maskArea.width(), m_maskArea.height());
} else {
maskSize = QRect(m_dockWindow->x(), m_dockWindow->y(), m_dockWindow->width(), m_dockWindow->height());
}
WId transient = 0;
if (m_dockWindow->transientParent()) {
transient = m_dockWindow->transientParent()->winId();
}
for (int j = currentDockPos - 1; j >= 0; --j) {
WId window = windows.at(j);
KWindowInfo info(window, NET::WMState | NET::XAWMState | NET::WMGeometry);
if (info.valid() && !isDesktop(window) && transient != window && !info.isMinimized() && maskSize.intersects(info.geometry())) {
return true;
}
}
}
return false;
}
/*
* SLOTS
*/
void XWindowInterface::activeWindowChanged(WId win)
{
m_activeWindow = win;
emit AbstractInterface::activeWindowChanged();
}
void XWindowInterface::windowChanged(WId id, NET::Properties properties, NET::Properties2 properties2)
{
KWindowInfo info(id, NET::WMState | NET::CloseWindow);
if (info.valid()) {
if ((m_demandsAttention == 0) && info.hasState(NET::DemandsAttention)) {
m_demandsAttention = id;
emit windowInAttention(true);
} else if ((m_demandsAttention == id) && !info.hasState(NET::DemandsAttention)) {
m_demandsAttention = 0;
emit windowInAttention(false);
}
}
// emit AbstractInterface::windowChanged();
if (id == m_activeWindow) {
emit AbstractInterface::activeWindowChanged();
}
}
void XWindowInterface::windowRemoved(WId id)
{
if (id == m_demandsAttention) {
m_demandsAttention = 0;
emit AbstractInterface::windowInAttention(false);
}
}
}

60
corona/xwindowinterface.h Normal file
View File

@ -0,0 +1,60 @@
#ifndef XWINDOWINTERFACE_H
#define XWINDOWINTERFACE_H
#include <QObject>
#include <KWindowInfo>
#include "abstractinterface.h"
namespace NowDock {
class XWindowInterface : public AbstractInterface {
Q_OBJECT
public:
explicit XWindowInterface(QQuickWindow *parent);
~XWindowInterface();
bool activeIsDialog() const;
bool activeIsMaximized() const;
bool dockIntersectsActiveWindow() const;
bool desktopIsActive() const;
bool dockIsCovered(bool totally = false) const;
bool dockIsCovering() const;
bool dockIsOnTop() const;
bool dockInNormalState() const;
bool dockIsBelow() const;
void setDockDefaultFlags(bool dock = false);
void setDockToAllDesktops();
void setDockToAlwaysVisible();
void showDockAsNormal();
void showDockOnBottom();
void showDockOnTop();
private Q_SLOTS:
void activeWindowChanged(WId win);
void dockNumberChanged(unsigned int no);
void windowChanged(WId id, NET::Properties properties, NET::Properties2 properties2);
void windowRemoved(WId id);
private:
WId m_activeWindow;
WId m_demandsAttention;
bool isDesktop(WId id) const;
bool isDialog(WId id) const;
bool isMaximized(WId id) const;
bool isNormal(WId id) const;
bool isOnBottom(WId id) const;
bool isOnTop(WId id) const;
};
}
#endif

3
formatter.sh Normal file
View File

@ -0,0 +1,3 @@
#!/bin/bash
astyle --options='astylerc' `find -maxdepth 3 -name '*.cpp' -o -name '*.h'`

14
install.sh Normal file
View File

@ -0,0 +1,14 @@
#!/bin/bash
#Author: Michail Vourlakos
#Summary: Installation script for Now Dock Panel
#This script was written and tested on openSuSe Leap 42.1
set -e
if ! [ -a build ] ; then
mkdir build
fi
cd build
cmake -DCMAKE_INSTALL_PREFIX=/usr -DCMAKE_BUILD_TYPE=RELEASE ..
make
sudo make install

39
libnowdock/CMakeLists.txt Normal file
View File

@ -0,0 +1,39 @@
set (REQUIRED_QT_VERSION "5.6.0")
find_package(ECM 1.8.0 REQUIRED NO_MODULE)
find_package(Qt5 ${REQUIRED_QT_VERSION} REQUIRED NO_MODULE COMPONENTS Quick Qml)
find_package(KF5 REQUIRED COMPONENTS
Plasma
PlasmaQuick
WindowSystem
KDELibs4Support
CoreAddons
)
set(CMAKE_AUTOMOC ON)
set(nowdock_SRCS
nowdockplugin.cpp
panelwindow.cpp
windowsystem.cpp
xwindowinterface.cpp
abstractinterface.cpp
types.cpp
)
add_library(nowdockplugin SHARED ${nowdock_SRCS})
target_link_libraries(nowdockplugin
Qt5::Quick
Qt5::Qml
KF5::Plasma
KF5::PlasmaQuick
KF5::WindowSystem
KF5::KDELibs4Support
KF5::CoreAddons
)
install(TARGETS nowdockplugin DESTINATION ${KDE_INSTALL_QMLDIR}/org/kde/nowdock)
install(FILES qmldir DESTINATION ${KDE_INSTALL_QMLDIR}/org/kde/nowdock)

View File

@ -0,0 +1,42 @@
#include "abstractinterface.h"
#include <QObject>
#include <QQuickWindow>
namespace NowDock {
AbstractInterface::AbstractInterface(QQuickWindow *dock) :
QObject(dock),
m_isDockWindowType(false),
m_dockNumber(0)
{
m_dockWindow = dock;
}
void AbstractInterface::setDockNumber(unsigned int no)
{
if (m_dockNumber == no) {
return;
}
m_dockNumber = no;
emit dockNumberChanged(m_dockNumber);
}
unsigned int AbstractInterface::dockNumber() const
{
return m_dockNumber;
}
void AbstractInterface::setMaskArea(QRect area)
{
if (m_maskArea == area) {
return;
}
m_maskArea = area;
}
}

View File

@ -0,0 +1,56 @@
#ifndef ABSTRACTINTERFACE_H
#define ABSTRACTINTERFACE_H
#include <QObject>
#include <QQuickWindow>
namespace NowDock {
class AbstractInterface : public QObject {
Q_OBJECT
public:
explicit AbstractInterface(QQuickWindow *dock);
virtual bool activeIsDialog() const = 0;
virtual bool activeIsMaximized() const = 0;
virtual bool desktopIsActive() const = 0;
virtual bool dockIntersectsActiveWindow() const = 0;
virtual bool dockIsCovered(bool totally = false) const = 0;
virtual bool dockIsCovering() const = 0;
virtual bool dockIsOnTop() const = 0;
virtual bool dockInNormalState() const = 0;
virtual bool dockIsBelow() const = 0;
//FIXME: This may not be needed, it would be better to investigate in KWindowSystem
//its behavior when setting the window type to NET::Dock
virtual void setDockDefaultFlags(bool dock = false) = 0;
virtual void setDockToAllDesktops() = 0;
virtual void showDockAsNormal() = 0;
virtual void showDockOnBottom() = 0;
virtual void showDockOnTop() = 0;
void setDockNumber(unsigned int no);
unsigned int dockNumber() const;
void setMaskArea(QRect area);
Q_SIGNALS:
void activeWindowChanged();
void dockNumberChanged(unsigned int no);
void windowInAttention(bool);
//FIXME: there is a chance that this signal is not needed at all
void windowChanged();
protected:
bool m_isDockWindowType;
int m_dockNumber;
QRect m_maskArea;
QQuickWindow *m_dockWindow;
};
}
#endif

View File

@ -0,0 +1,17 @@
#include "nowdockplugin.h"
#include "panelwindow.h"
#include "windowsystem.h"
#include "types.h"
#include <qqml.h>
void NowDockPlugin::registerTypes(const char *uri)
{
Q_ASSERT(uri == QLatin1String("org.kde.nowdock"));
qmlRegisterUncreatableType<NowDock::Types>(uri, 0, 1, "Types", "NowDock Types uncreatable");
qmlRegisterType<NowDock::PanelWindow>(uri, 0, 1, "PanelWindow");
qmlRegisterType<NowDock::WindowSystem>(uri, 0, 1, "WindowSystem");
}

View File

@ -0,0 +1,14 @@
#ifndef NOWDOCKPLUGIN_H
#define NOWDOCKPLUGIN_H
#include <QQmlExtensionPlugin>
class NowDockPlugin : public QQmlExtensionPlugin {
Q_OBJECT
Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface")
public:
void registerTypes(const char *uri);
};
#endif

1120
libnowdock/panelwindow.cpp Normal file

File diff suppressed because it is too large Load Diff

203
libnowdock/panelwindow.h Normal file
View File

@ -0,0 +1,203 @@
#ifndef PANELWINDOW_H
#define PANELWINDOW_H
#include <QMenu>
#include <QQuickWindow>
#include <QTimer>
#include <plasma/plasma.h>
#include <Plasma/Applet>
#include <Plasma/Containment>
#include <PlasmaQuick/AppletQuickItem>
#include "abstractinterface.h"
#include "windowsystem.h"
namespace NowDock {
class PanelWindow : public QQuickWindow {
Q_OBJECT
Q_ENUMS(PanelVisibility)
Q_ENUMS(Alignment)
Q_PROPERTY(bool disableHiding READ disableHiding WRITE setDisableHiding NOTIFY disableHidingChanged)
Q_PROPERTY(bool immutable READ immutable WRITE setImmutable NOTIFY immutableChanged)
Q_PROPERTY(bool isAutoHidden READ isAutoHidden WRITE setIsAutoHidden NOTIFY isAutoHiddenChanged)
Q_PROPERTY(bool isDockWindowType READ isDockWindowType WRITE setIsDockWindowType NOTIFY isDockWindowTypeChanged)
Q_PROPERTY(bool isHovered READ isHovered NOTIFY isHoveredChanged)
Q_PROPERTY(bool windowInAttention READ windowInAttention WRITE setWindowInAttention NOTIFY windowInAttentionChanged)
Q_PROPERTY(int childrenLength READ childrenLength WRITE setChildrenLength NOTIFY childrenLengthChanged)
Q_PROPERTY(unsigned int maximumLength READ maximumLength NOTIFY maximumLengthChanged)
/**
* the window mask, can be used in real transparent panels that set only the visual area
* of the window
* @since 5.8
*/
Q_PROPERTY(QRect maskArea READ maskArea WRITE setMaskArea NOTIFY maskAreaChanged)
/**
* the dock's screen geometry, e.g. it is used to set correctly x, y values
*/
Q_PROPERTY(QRect screenGeometry READ screenGeometry NOTIFY screenGeometryChanged)
Q_PROPERTY(Plasma::Types::Location location READ location WRITE setLocation NOTIFY locationChanged)
Q_PROPERTY(PanelVisibility panelVisibility READ panelVisibility WRITE setPanelVisibility NOTIFY panelVisibilityChanged)
public:
enum PanelVisibility {
BelowActive = 0, /** always visible except if ovelaps with the active window, no area reserved */
BelowMaximized, /** always visible except if ovelaps with an active maximize window, no area reserved */
LetWindowsCover, /** always visible, windows will go over the panel, no area reserved */
WindowsGoBelow, /** default, always visible, windows will go under the panel, no area reserved */
AutoHide, /** the panel will be shownn only if the mouse cursor is on screen edges */
AlwaysVisible, /** always visible panel, "Normal" plasma panel, accompanies plasma's "Always Visible" */
};
enum Alignment {
Center = 0,
Left,
Right,
Top,
Bottom,
Double = 10
};
explicit PanelWindow(QQuickWindow *parent = Q_NULLPTR);
~PanelWindow();
bool disableHiding() const;
void setDisableHiding(bool state);
bool immutable() const;
void setImmutable(bool state);
bool isAutoHidden() const;
void setIsAutoHidden(bool state);
bool isDockWindowType() const;
void setIsDockWindowType(bool state);
bool isHovered() const;
bool windowInAttention() const;
// void setWindowInAttention(bool state);
int childrenLength() const;
void setChildrenLength(int value);
unsigned int maximumLength() const;
QRect maskArea() const;
void setMaskArea(QRect area);
QRect screenGeometry() const;
Plasma::Types::Location location() const;
void setLocation(Plasma::Types::Location location);
PanelVisibility panelVisibility() const;
void setPanelVisibility(PanelVisibility state);
Q_SIGNALS:
void childrenLengthChanged();
void disableHidingChanged();
void immutableChanged();
void isAutoHiddenChanged();
void isDockWindowTypeChanged();
void isHoveredChanged();
void locationChanged();
void maskAreaChanged();
void maximumLengthChanged();
void mustBeLowered();
void mustBeRaised(); //are used to triger the sliding animations from the qml part
void mustBeRaisedImmediately();
void panelVisibilityChanged();
void screenGeometryChanged();
void windowInAttentionChanged();
public slots:
Q_INVOKABLE void addAppletItem(QObject *item);
Q_INVOKABLE void initialize();
Q_INVOKABLE void removeAppletItem(QObject *item);
Q_INVOKABLE void setTransientThickness(unsigned int thickness);
Q_INVOKABLE void showNormal();
Q_INVOKABLE void showOnTop();
Q_INVOKABLE void showOnTopCheck();
Q_INVOKABLE void showOnBottom();
void setWindowInAttention(bool state);
protected:
bool event(QEvent *event) override;
void mousePressEvent(QMouseEvent *event) Q_DECL_OVERRIDE;
void mouseReleaseEvent(QMouseEvent *event) Q_DECL_OVERRIDE;
private Q_SLOTS:
void activeWindowChanged();
void compositingChanged();
void updateState();
void initWindow();
void menuAboutToHide();
void setIsHovered(bool state);
void screenChanged(QScreen *screen);
void setScreenGeometry(QRect geometry);
void shrinkTransient();
void transientPositionChanged();
void updateVisibilityFlags();
void updateWindowPosition();
private:
bool m_disableHiding;
bool m_immutable;
bool m_isAutoHidden;
bool m_isDockWindowType;
bool m_isHovered;
//second pass of the initialization
bool m_secondInitPass;
bool m_windowIsInAttention;
int m_childrenLength;
int m_tempThickness;
unsigned int m_maximumLength;
QPointer<Plasma::Containment> m_containment;
QRect m_maskArea;
QRect m_screenGeometry;
QScreen *m_screen;
QList<PlasmaQuick::AppletQuickItem *> m_appletItems;
QTimer m_initTimer;
QTimer m_triggerShrinkTransient;
QTimer m_updateStateTimer;
QWeakPointer<QMenu> m_contextMenu;
QWindow *m_transient;
Qt::Orientations m_panelOrientation;
Plasma::Types::Location m_location;
PanelVisibility m_panelVisibility;
AbstractInterface *m_interface;
WindowSystem *m_windowSystem;
void addAppletActions(QMenu *desktopMenu, Plasma::Applet *applet, QEvent *event);
void addContainmentActions(QMenu *desktopMenu, QEvent *event);
void setPanelOrientation(Plasma::Types::Location location);
void setPanelScreen(QScreen *screen);
void updateMaximumLength();
void updateTransient();
};
} //NowDock namespace
#endif

2
libnowdock/qmldir Normal file
View File

@ -0,0 +1,2 @@
module org.kde.nowdock
plugin nowdockplugin

1
libnowdock/types.cpp Normal file
View File

@ -0,0 +1 @@
#include "types.h"

53
libnowdock/types.h Normal file
View File

@ -0,0 +1,53 @@
#ifndef TYPES_H
#define TYPES_H
#include <QObject>
#include <QMetaEnum>
#include <QMetaType>
namespace NowDock {
class Types {
Q_GADGET
public:
Types() = delete;
~Types() {}
enum Visibility {
BelowActive = 0, /** always visible except if ovelaps with the active window, no area reserved */
BelowMaximized, /** always visible except if ovelaps with an active maximize window, no area reserved */
LetWindowsCover, /** always visible, windows will go over the panel, no area reserved */
WindowsGoBelow, /** default, always visible, windows will go under the panel, no area reserved */
AutoHide, /** the panel will be shownn only if the mouse cursor is on screen edges */
AlwaysVisible, /** always visible panel, "Normal" plasma panel, accompanies plasma's "Always Visible" */
};
Q_ENUM(Visibility)
enum Alignment {
Center = 0,
Left,
Right,
Top,
Bottom,
Double = 10
};
Q_ENUM(Alignment)
enum VisibilityState {
/*!
* @brief the dock is visible
*/
Visible = 1,
/*!
* @brief the dock is hidden
*/
Hidden = 0
};
Q_ENUM(VisibilityState)
};
}//end of namespace
#endif

View File

@ -0,0 +1,27 @@
#include "windowsystem.h"
#include <KWindowSystem>
namespace NowDock {
WindowSystem::WindowSystem(QObject *parent) :
QObject(parent)
{
connect(KWindowSystem::self(), SIGNAL(compositingChanged(bool)), this, SLOT(compositingChanged(bool)));
}
WindowSystem::~WindowSystem()
{
}
bool WindowSystem::compositingActive() const
{
return KWindowSystem::compositingActive();
}
void WindowSystem::compositingChanged(bool state)
{
emit compositingChanged();
}
}

28
libnowdock/windowsystem.h Normal file
View File

@ -0,0 +1,28 @@
#ifndef WINDOWSYSTEM_H
#define WINDOWSYSTEM_H
#include "abstractinterface.h"
namespace NowDock {
class WindowSystem : public QObject {
Q_OBJECT
Q_PROPERTY(bool compositingActive READ compositingActive NOTIFY compositingChanged)
public:
explicit WindowSystem(QObject *parent = Q_NULLPTR);
~WindowSystem();
bool compositingActive() const;
Q_SIGNALS:
void compositingChanged();
private Q_SLOTS:
void compositingChanged(bool state);
};
}//NowDock namespace
#endif

View File

@ -0,0 +1,361 @@
#include "xwindowinterface.h"
#include <QDebug>
#include <KWindowInfo>
#include <KWindowSystem>
namespace NowDock {
XWindowInterface::XWindowInterface(QQuickWindow *parent) :
AbstractInterface(parent),
m_demandsAttention(0)
{
m_activeWindow = KWindowSystem::activeWindow();
connect(KWindowSystem::self(), SIGNAL(activeWindowChanged(WId)), this, SLOT(activeWindowChanged(WId)));
connect(KWindowSystem::self(), SIGNAL(windowChanged(WId, NET::Properties, NET::Properties2)), this, SLOT(windowChanged(WId, NET::Properties, NET::Properties2)));
connect(KWindowSystem::self(), SIGNAL(windowRemoved(WId)), this, SLOT(windowRemoved(WId)));
connect(this, SIGNAL(dockNumberChanged(uint)), this, SLOT(dockNumberChanged(uint)));
}
XWindowInterface::~XWindowInterface()
{
}
void XWindowInterface::dockNumberChanged(unsigned int no)
{
if (no == 1) {
m_dockWindow->setFlags(Qt::Tool | Qt::WindowDoesNotAcceptFocus | Qt::FramelessWindowHint);
}
}
void XWindowInterface::setDockToAllDesktops()
{
KWindowSystem::setOnAllDesktops(m_dockWindow->winId(), true);
}
void XWindowInterface::setDockDefaultFlags(bool dock)
{
//Notice: the Qt::Tool flag even though it works perfectly for a single Now Dock
//it creates a strange situation when there are two and more Now Dock's
//in that case it is used only for the first created Now Dock
m_isDockWindowType = dock;
if ((m_dockNumber == 1) && (!m_isDockWindowType)) {
m_dockWindow->setFlags(Qt::Tool | Qt::WindowDoesNotAcceptFocus | Qt::FramelessWindowHint);
} else {
KWindowSystem::setType(m_dockWindow->winId(), NET::Dock);
KWindowSystem::setState(m_dockWindow->winId(), NET::SkipTaskbar | NET::SkipPager);
}
}
void XWindowInterface::showDockOnTop()
{
//this is the only way in order to not break the case of two and more NowDocks
//there is a small issue that the pop ups from locked plasmoids are opened
//on the maximum thickness
//qDebug() << "Docknumber:" << m_dockNumber;
if (m_isDockWindowType) {
return;
}
if (m_dockNumber != 1) {
KWindowSystem::setType(m_dockWindow->winId(), NET::Dock);
}
KWindowSystem::clearState(m_dockWindow->winId(), NET::KeepBelow);
KWindowSystem::setState(m_dockWindow->winId(), NET::KeepAbove);
}
void XWindowInterface::showDockAsNormal()
{
// qDebug() << "reached make normal...";
if (m_isDockWindowType) {
return;
}
if (m_dockNumber != 1) {
m_dockWindow->setFlags(Qt::Tool | Qt::WindowDoesNotAcceptFocus | Qt::FramelessWindowHint);
}
KWindowSystem::clearState(m_dockWindow->winId(), NET::KeepAbove);
KWindowSystem::clearState(m_dockWindow->winId(), NET::KeepBelow);
}
void XWindowInterface::showDockOnBottom()
{
// qDebug() << "reached make bottom...";
if (m_isDockWindowType) {
return;
}
if (m_dockNumber != 1) {
m_dockWindow->setFlags(Qt::Tool | Qt::WindowDoesNotAcceptFocus | Qt::FramelessWindowHint);
}
KWindowSystem::clearState(m_dockWindow->winId(), NET::KeepAbove);
KWindowSystem::setState(m_dockWindow->winId(), NET::KeepBelow);
}
bool XWindowInterface::isDesktop(WId id) const
{
KWindowInfo info(id, NET::WMWindowType);
if (!info.valid()) {
return false;
}
NET::WindowType type = info.windowType(NET::DesktopMask | NET::DockMask | NET::DialogMask);
return type == NET::Desktop;
}
bool XWindowInterface::isDialog(WId id) const
{
KWindowInfo info(id, NET::WMWindowType);
if (!info.valid()) {
return false;
}
NET::WindowType type = info.windowType(NET::DesktopMask | NET::DockMask | NET::DialogMask);
return type == NET::Dialog;
}
bool XWindowInterface::isMaximized(WId id) const
{
KWindowInfo info(id, NET::WMState);
if (!info.valid()) {
return false;
}
return (info.hasState(NET::Max));
}
bool XWindowInterface::isNormal(WId id) const
{
return (!isOnBottom(id) && !isOnTop(id));
}
bool XWindowInterface::isOnBottom(WId id) const
{
KWindowInfo info(id, NET::WMState);
if (!info.valid()) {
return false;
}
return (info.hasState(NET::KeepBelow));
}
bool XWindowInterface::isOnTop(WId id) const
{
KWindowInfo info(id, NET::WMState);
if (!info.valid()) {
return false;
}
return (info.hasState(NET::KeepAbove));
}
bool XWindowInterface::activeIsDialog() const
{
return isDialog(m_activeWindow);
}
bool XWindowInterface::activeIsMaximized() const
{
return isMaximized(m_activeWindow);
}
bool XWindowInterface::desktopIsActive() const
{
return isDesktop(m_activeWindow);
}
bool XWindowInterface::dockIsOnTop() const
{
return isOnTop(m_dockWindow->winId());
}
bool XWindowInterface::dockInNormalState() const
{
return isNormal(m_dockWindow->winId());
}
bool XWindowInterface::dockIsBelow() const
{
return isOnBottom(m_dockWindow->winId());
}
bool XWindowInterface::dockIntersectsActiveWindow() const
{
KWindowInfo activeInfo(m_activeWindow, NET::WMGeometry);
if (activeInfo.valid()) {
QRect maskSize;
if (!m_maskArea.isNull()) {
maskSize = QRect(m_dockWindow->x() + m_maskArea.x(), m_dockWindow->y() + m_maskArea.y(), m_maskArea.width(), m_maskArea.height());
} else {
maskSize = QRect(m_dockWindow->x(), m_dockWindow->y(), m_dockWindow->width(), m_dockWindow->height());
}
return maskSize.intersects(activeInfo.geometry());
} else {
return false;
}
}
bool XWindowInterface::dockIsCovered(bool totally) const
{
int currentDockPos = -1;
QList<WId> windows = KWindowSystem::stackingOrder();
int size = windows.count();
for (int i = size - 1; i >= 0; --i) {
WId window = windows.at(i);
if (window == m_dockWindow->winId()) {
currentDockPos = i;
break;
}
}
if (currentDockPos >= 0) {
QRect maskSize;
if (!m_maskArea.isNull()) {
maskSize = QRect(m_dockWindow->x() + m_maskArea.x(), m_dockWindow->y() + m_maskArea.y(), m_maskArea.width(), m_maskArea.height());
} else {
maskSize = QRect(m_dockWindow->x(), m_dockWindow->y(), m_dockWindow->width(), m_dockWindow->height());
}
WId transient = 0;
if (m_dockWindow->transientParent()) {
transient = m_dockWindow->transientParent()->winId();
}
for (int j = size - 1; j > currentDockPos; --j) {
WId window = windows.at(j);
KWindowInfo info(window, NET::WMState | NET::XAWMState | NET::WMGeometry);
if (info.valid() && !isDesktop(window) && transient != window && !info.isMinimized()) {
if (totally) {
QRect winGeometry = info.geometry();
if ((maskSize.left() >= winGeometry.left()) && (maskSize.top() >= winGeometry.top())
&& (maskSize.right() <= winGeometry.right()) && (maskSize.bottom() <= winGeometry.bottom())) {
return true;
}
} else {
if (maskSize.intersects(info.geometry())) {
return true;
}
}
}
}
}
return false;
}
bool XWindowInterface::dockIsCovering() const
{
int currentDockPos = -1;
QList<WId> windows = KWindowSystem::stackingOrder();
int size = windows.count();
for (int i = size - 1; i >= 0; --i) {
WId window = windows.at(i);
if (window == m_dockWindow->winId()) {
currentDockPos = i;
break;
}
}
if (currentDockPos >= 0) {
QRect maskSize;
if (!m_maskArea.isNull()) {
maskSize = QRect(m_dockWindow->x() + m_maskArea.x(), m_dockWindow->y() + m_maskArea.y(), m_maskArea.width(), m_maskArea.height());
} else {
maskSize = QRect(m_dockWindow->x(), m_dockWindow->y(), m_dockWindow->width(), m_dockWindow->height());
}
WId transient = 0;
if (m_dockWindow->transientParent()) {
transient = m_dockWindow->transientParent()->winId();
}
for (int j = currentDockPos - 1; j >= 0; --j) {
WId window = windows.at(j);
KWindowInfo info(window, NET::WMState | NET::XAWMState | NET::WMGeometry);
if (info.valid() && !isDesktop(window) && transient != window && !info.isMinimized() && maskSize.intersects(info.geometry())) {
return true;
}
}
}
return false;
}
/*
* SLOTS
*/
void XWindowInterface::activeWindowChanged(WId win)
{
m_activeWindow = win;
emit AbstractInterface::activeWindowChanged();
}
void XWindowInterface::windowChanged(WId id, NET::Properties properties, NET::Properties2 properties2)
{
KWindowInfo info(id, NET::WMState | NET::CloseWindow);
if (info.valid()) {
if ((m_demandsAttention == 0) && info.hasState(NET::DemandsAttention)) {
m_demandsAttention = id;
emit windowInAttention(true);
} else if ((m_demandsAttention == id) && !info.hasState(NET::DemandsAttention)) {
m_demandsAttention = 0;
emit windowInAttention(false);
}
}
// emit AbstractInterface::windowChanged();
if (id == m_activeWindow) {
emit AbstractInterface::activeWindowChanged();
}
}
void XWindowInterface::windowRemoved(WId id)
{
if (id == m_demandsAttention) {
m_demandsAttention = 0;
emit AbstractInterface::windowInAttention(false);
}
}
}

View File

@ -0,0 +1,60 @@
#ifndef XWINDOWINTERFACE_H
#define XWINDOWINTERFACE_H
#include <QObject>
#include <KWindowInfo>
#include "abstractinterface.h"
namespace NowDock {
class XWindowInterface : public AbstractInterface {
Q_OBJECT
public:
explicit XWindowInterface(QQuickWindow *parent);
~XWindowInterface();
bool activeIsDialog() const;
bool activeIsMaximized() const;
bool dockIntersectsActiveWindow() const;
bool desktopIsActive() const;
bool dockIsCovered(bool totally = false) const;
bool dockIsCovering() const;
bool dockIsOnTop() const;
bool dockInNormalState() const;
bool dockIsBelow() const;
void setDockDefaultFlags(bool dock = false);
void setDockToAllDesktops();
void setDockToAlwaysVisible();
void showDockAsNormal();
void showDockOnBottom();
void showDockOnTop();
private Q_SLOTS:
void activeWindowChanged(WId win);
void dockNumberChanged(unsigned int no);
void windowChanged(WId id, NET::Properties properties, NET::Properties2 properties2);
void windowRemoved(WId id);
private:
WId m_activeWindow;
WId m_demandsAttention;
bool isDesktop(WId id) const;
bool isDialog(WId id) const;
bool isMaximized(WId id) const;
bool isNormal(WId id) const;
bool isOnBottom(WId id) const;
bool isOnTop(WId id) const;
};
}
#endif

View File

@ -0,0 +1,23 @@
[Desktop Entry]
_Name=Now Dock
_Comment=Switch between running applications
Type=Service
Icon=preferences-system-windows
X-KDE-ServiceTypes=Plasma/Applet
X-Plasma-API=declarativeappletscript
X-Plasma-MainScript=ui/main.qml
X-Plasma-Provides=org.kde.plasma.multitasking
X-KDE-PluginInfo-Author=@AUTHOR@
X-KDE-PluginInfo-Email=@EMAIL@
X-KDE-PluginInfo-Name=org.kde.store.nowdock.plasmoid
X-KDE-PluginInfo-Version=@VERSION@
X-KDE-PluginInfo-Website=@WEBSITE@
X-KDE-PluginInfo-Category=Windows and Tasks
X-KDE-PluginInfo-Depends=
X-KDE-PluginInfo-License=GPL v2+
X-KDE-PluginInfo-EnabledByDefault=true

6
plasmoid/CMakeLists.txt Normal file
View File

@ -0,0 +1,6 @@
file(COPY "contents" DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/release)
#update the version number in the configuration window
file(REMOVE ${CMAKE_CURRENT_BINARY_DIR}/release/contents/ui/ConfigAppearance.qml.cmake)
configure_file(metadata.desktop.cmake release/metadata.desktop)
configure_file(contents/ui/ConfigAppearance.qml.cmake release/contents/ui/ConfigAppearance.qml)

View File

@ -0,0 +1,335 @@
/*
* Copyright 2013 Michail Vourlakos <mvourlakos@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 2.010-1301, USA.
*/
var currentActivity;
var launchersOnActivities;
//it is used as the first item in the stringList in order to check the list is ok
var indicator = 'multi';
var plasmoid;
function restoreLaunchers(){
///this is a stringlist of types activityId, number of launchers, launchers
if(plasmoid && plasmoid.configuration && currentActivity != "00000000-0000-0000-0000-000000000000"){
var values = plasmoid.configuration.launchers;
values = values.split(";");
var returnedStringList = [];
// console.log("----------------------- Restoring ---------------------");
// console.log("Full Restoration:"+values);
var type = values.splice(0,1);
// console.log("Pass 1 - " +type);
if (type == indicator){
// console.log("Pass 2");
while (values.length > 2){
// console.log("Pass 3 - "+values);
var actId = values[0];
var subLaunchers = values.splice(2,values[1]);
// console.log("To Be Restored launchers, "+actId+ ", "+subLaunchers.length+", "+subLaunchers);
var activityRecord = get(actId);
if(activityRecord){
// console.log("Activity item found...");
if(activityRecord.launchers)
activityRecord.launchers.splice(0,activityRecord.launchers.length);
activityRecord.launchers = subLaunchers;
}
else{
// console.log("Activity item is added...");
var res = {id:values[0], launchers:subLaunchers};
launchersOnActivities.push(res);
}
values.splice(0,2);
}
}
if (get('*'))
returnedStringList = returnedStringList.concat(get('*').launchers);
else{
var result = {id:'*', launchers:[]};
launchersOnActivities.push(result);
}
if (get(currentActivity))
returnedStringList = returnedStringList.concat(get(currentActivity).launchers);
// console.log("Restored Strings:"+returnedStringList);
return returnedStringList;
}
else
return [];
}
function saveLaunchers(){
// console.log("----------------------- Saving ---------------------");
var returnedStringList = [];
returnedStringList.push(indicator);
// console.log("Array Size:"+launchersOnActivities.length);
var size = launchersOnActivities.length;
for(var i=size-1; i>=0; --i){
var activitySaving = get(launchersOnActivities[i].id);
// console.log("Saving, "+activitySaving.id + " - "+activitySaving.launchers.length+" - "+activitySaving.launchers);
if(activitySaving.launchers.length>0){
/* console.log("------- "+activitySaving.id+" ----------");
for(var j=0; j<activitySaving.launchers.length; ++j){
console.log(activitySaving.launchers[j]);
}*/
returnedStringList = returnedStringList.concat(String(activitySaving.id));
returnedStringList = returnedStringList.concat(String(activitySaving.launchers.length));
// this creates segmentation faults in some cases!!!!
// returnedStringList = returnedStringList.concat(activitySaving.launchers);
//this fixes the segmentation fault of previous command....
for(var j=0; j<activitySaving.launchers.length; ++j){
returnedStringList.push(String(activitySaving.launchers[j]));
}
///check returnedStringList integrity
/* for(var j=0; j<returnedStringList.length; ++j){
console.log("--- "+j+". "+returnedStringList[j]);
}*/
}
}
/* console.log("I am out..... "+returnedStringList.length);
for(var i=0; i<returnedStringList.length; ++i){
console.log(i+". "+returnedStringList[i]);
}*/
// console.log("IMPORTANT SAVED LIST: "+returnedStringList);
plasmoid.configuration.launchers = returnedStringList.join(";");
}
function updateLaunchers(launcherList){
// console.log("----------------------- Updating ---------------------");
// console.log("---- Full Launchers ------");
/* for(var j=0; j<launcherList.length; ++j){
console.log(launcherList[j]);
} */
var tempList;
if(launcherList.length > 0){
tempList = launcherList.slice(0);
}
else{
tempList =[];
}
// console.log("IMPORTANT SENT LIST: "+tempList.length+" - "+launcherList.length+" - "+tempList);
//
// console.log("In memory Defaults:" + get('*').launchers);
// if(get(currentActivity))
// console.log("In memory Current: "+get(currentActivity).launchers.length+ ' - ' + get(currentActivity).launchers);
var currentList = get(currentActivity);
var resultedCurrent = [];
// console.log("-------------");
for(var i=tempList.length-1; i>=0; --i){
var index=-1;
if(currentList){
index = getIndex(String(tempList[i]), currentList.launchers);
}
if(index >=0 || isInSpecificActivity(tempList[i])){
var result = tempList.splice(i,1);
resultedCurrent.unshift(String(result));
}
}
// console.log("Resulted Current: "+resultedCurrent);
/* console.log("---- To Be Set List ------");
for(var j=0; j<resultedCurrent.length; ++j){
console.log(resultedCurrent[j]);
}*/
setActivityLaunchers(resultedCurrent, currentActivity);
setDefaultLaunchers(tempList);
saveLaunchers();
}
/////////////
function cleanupRecords(activities){
for(var i=0; i<launchersOnActivities.length; ++i){
if(launchersOnActivities[i].id != '*'){
var index = getIndex(launchersOnActivities[i].id, activities);
if(index < 0){
console.log("Orphaned Activity Settings removed:"+launchersOnActivities[i].id);
launchersOnActivities.splice(index,1);
}
}
}
saveLaunchers();
}
function getIndex(id, list){
if(list){
for(var i=0; i<list.length; ++i){
if(id == list[i])
return i;
}
}
return -1;
}
function get(actId){
for(var i=0; i<launchersOnActivities.length; ++i){
if(launchersOnActivities[i].id == actId)
return launchersOnActivities[i];
}
return;
}
function isOnAllActivities(id){
var defaults = get('*').launchers;
var index = getIndex(String(id),defaults);
if (index>=0)
return true;
// console.log("Check exists:"+id+ " - "+ "pos:"+index+" ,,, "+ get('*').activities);
return false;
}
function isInSpecificActivity(id){
for(var i=0; i<launchersOnActivities.length; ++i){
var activity = launchersOnActivities[i];
if(activity.id != "*"){
var launchers = activity.launchers;
var index = getIndex(String(id),launchers)
if (index>=0)
return true;
}
}
return false;
}
function setDefaultLaunchers(launchersList){
// console.log("Set Default Launchers");
if(!get('*')){
var result = {id:'*', launchers:launchersList};
launchersOnActivities.push(result);
}
else{
if (get('*').launchers)
get('*').launchers.splice(0,get('*').launchers.length);
get('*').launchers=launchersList;
}
// console.log("Default:::: "+get('*').launchers);
}
function setActivityLaunchers(launchersList, actId){
// console.log("Set Activity Launchers");
var currentList = get(actId);
// console.log("-------------");
// console.log("ResultedForMemory: "+launchersList);
if(currentList){
if(currentList.launchers)
currentList.launchers.splice(0,currentList.launchers.length);
// console.log("list exists");
currentList.launchers=launchersList;
}
else{
// console.log("new list");
var res = {id:actId, launchers:launchersList};
launchersOnActivities.push(res);
}
/* console.log("New Memory List: "+get(actId).launchers);
for(var j=0; j<get(actId).launchers.length; ++j){
console.log(get(actId).launchers[j]);
} */
}
///from launcher to All Activities to the current only and vice versa
function toggleLauncherState(id){
if (isOnAllActivities(id)){
removeFromList(id,'*')
addToList(id, currentActivity);
}
else{
removeFromAllSimpleLists(id);
addToList(id, '*');
}
saveLaunchers();
}
function removeLauncher(id){
if(get(currentActivity))
removeFromList(id, currentActivity);
removeFromList(id, '*');
}
function removeFromAllSimpleLists(id){
for(var i=0; i<launchersOnActivities.length; ++i){
var activity = launchersOnActivities[i];
if(activity.id != "*"){
removeFromList(id, activity.id);
}
}
}
function removeFromList(id, activityId){
var list = get(activityId);
if(list){
var activityList = list.launchers;
var index = getIndex(String(id),activityList);
if(index >= 0){
activityList.splice(index, 1);
}
}
}
function addToList(id, activityId){
var activity = get(activityId);
if(!activity){
var res = {id:activityId, launchers:[]};
res.launchers.push(id);
launchersOnActivities.push(res);
}
else{
var launcherList = activity.launchers;
var index = getIndex(id,launcherList);
if(index<0){
launcherList.push(id);
}
}
}

View File

@ -0,0 +1,205 @@
/*
* Copyright 2013 Michail Vourlakos <mvourlakos@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 2.010-1301, USA.
*/
function horizontalMargins() {
return taskFrame.margins.left + taskFrame.margins.right;
}
function verticalMargins() {
return taskFrame.margins.top + taskFrame.margins.bottom;
}
function adjustMargin(height, margin) {
var available = height - verticalMargins();
if (available < units.iconSizes.small) {
return Math.floor((margin * (units.iconSizes.small / available)) / 3);
}
return margin;
}
function launcherLayoutTasks() {
return Math.round(tasksModel.launcherCount / Math.floor(preferredMinWidth() / launcherWidth()));
}
function launcherLayoutWidthDiff() {
return (launcherLayoutTasks() * taskWidth()) - (tasksModel.launcherCount * launcherWidth());
}
function logicalTaskCount() {
var count = (tasksModel.count - tasksModel.launcherCount) + launcherLayoutTasks();
return Math.max(tasksModel.count ? 1 : 0, count);
}
function maxStripes() {
var length = tasks.vertical ? taskList.width : taskList.height;
var minimum = tasks.vertical ? preferredMinWidth() : preferredMinHeight();
return Math.min(plasmoid.configuration.maxStripes, Math.max(1, Math.floor(length / minimum)));
}
function tasksPerStripe() {
if (plasmoid.configuration.forceStripes) {
return Math.ceil(logicalTaskCount() / maxStripes());
} else {
var length = tasks.vertical ? taskList.height : taskList.width;
var minimum = tasks.vertical ? preferredMinHeight() : preferredMinWidth();
return Math.floor(length / minimum);
}
}
function calculateStripes() {
var stripes = plasmoid.configuration.forceStripes ? plasmoid.configuration.maxStripes : Math.min(plasmoid.configuration.maxStripes, Math.ceil(logicalTaskCount() / tasksPerStripe()));
return Math.min(stripes, maxStripes());
}
function full() {
return (maxStripes() == calculateStripes());
}
function optimumCapacity(width, height) {
var length = tasks.vertical ? height : width;
var maximum = tasks.vertical ? preferredMaxHeight() : preferredMaxWidth();
return (Math.ceil(length / maximum) * maxStripes());
}
function layoutWidth() {
if (plasmoid.configuration.forceStripes && !tasks.vertical) {
return Math.min(tasks.width, Math.max(preferredMaxWidth(), tasksPerStripe() * preferredMaxWidth()));
} else {
return tasks.width;
}
}
function layoutHeight() {
if (plasmoid.configuration.forceStripes && tasks.vertical) {
return Math.min(tasks.height, Math.max(preferredMaxHeight(), tasksPerStripe() * preferredMaxHeight()));
} else {
return tasks.height;
}
}
function preferredMinWidth() {
var width = launcherWidth();
if (!tasks.vertical && !tasks.iconsOnly) {
width += (units.smallSpacing * 2) + (theme.mSize(theme.defaultFont).width * 12);
}
return width;
}
function preferredMaxWidth() {
if (tasks.iconsOnly) {
if (tasks.vertical) {
return tasks.width + verticalMargins();
} else {
return tasks.height + horizontalMargins();
}
}
if (plasmoid.configuration.groupingStrategy != 0 && !plasmoid.configuration.groupPopups) {
return preferredMinWidth();
}
return Math.floor(preferredMinWidth() * 1.6);
}
function preferredMinHeight() {
// TODO FIXME UPSTREAM: Port to proper font metrics for descenders once we have access to them.
return theme.mSize(theme.defaultFont).height + 4;
}
function preferredMaxHeight() {
return verticalMargins() + Math.min(units.iconSizes.small * 3, theme.mSize(theme.defaultFont).height * 3);
}
function taskWidth() {
if (tasks.vertical) {
return Math.floor(taskList.width / calculateStripes());
} else {
if (full() && Math.max(1, logicalTaskCount()) > tasksPerStripe()) {
return Math.floor(taskList.width / Math.ceil(logicalTaskCount() / maxStripes()));
} else {
return Math.min(preferredMaxWidth(), Math.floor(taskList.width / Math.min(logicalTaskCount(), tasksPerStripe())));
}
}
}
function taskHeight() {
if (tasks.vertical) {
if (full() && Math.max(1, logicalTaskCount()) > tasksPerStripe()) {
return Math.floor(taskList.height / Math.ceil(logicalTaskCount() / maxStripes()));
} else {
return Math.min(preferredMaxHeight(), Math.floor(taskList.height / Math.min(logicalTaskCount(), tasksPerStripe())));
}
} else {
return Math.floor(taskList.height / calculateStripes());
}
}
function launcherWidth() {
var baseWidth = tasks.vertical ? preferredMinHeight() : Math.min(tasks.height, units.iconSizes.small * 3);
return (baseWidth + horizontalMargins())
- (adjustMargin(baseWidth, taskFrame.margins.top) + adjustMargin(baseWidth, taskFrame.margins.bottom));
}
function layout(container) {
var item;
var stripes = calculateStripes();
var taskCount = tasksModel.count - tasksModel.launcherCount;
var width = taskWidth();
var adjustedWidth = width;
var height = taskHeight();
if (!tasks.vertical && stripes == 1 && taskCount)
{
var shrink = ((tasksModel.count - tasksModel.launcherCount) * preferredMaxWidth())
+ (tasksModel.launcherCount * launcherWidth()) > taskList.width;
width = Math.min(shrink ? width + Math.floor(launcherLayoutWidthDiff() / taskCount) : width,
preferredMaxWidth());
}
for (var i = 0; i < container.count; ++i) {
item = container.itemAt(i);
if (!item) {
continue;
}
adjustedWidth = width;
if (!tasks.vertical && !tasks.iconsOnly && (plasmoid.configuration.separateLaunchers || stripes == 1)) {
if (item.m.IsLauncher === true) {
adjustedWidth = launcherWidth();
} else if (stripes > 1 && i == tasksModel.launcherCount) {
adjustedWidth += launcherLayoutWidthDiff();
}
}
item.width = adjustedWidth;
item.height = height;
item.visible = true;
}
}

View File

@ -0,0 +1,144 @@
/*
* Copyright 2013 Michail Vourlakos <mvourlakos@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 2.010-1301, USA.
*/
function wheelActivateNextPrevTask(wheelDelta, eventDelta) {
// magic number 120 for common "one click"
// See: http://qt-project.org/doc/qt-5/qml-qtquick-wheelevent.html#angleDelta-prop
wheelDelta += eventDelta;
var increment = 0;
while (wheelDelta >= 120) {
wheelDelta -= 120;
increment++;
}
while (wheelDelta <= -120) {
wheelDelta += 120;
increment--;
}
while (increment != 0) {
activateNextPrevTask(increment < 0)
increment += (increment < 0) ? 1 : -1;
}
return wheelDelta;
}
function activateNextPrevTask(next) {
// FIXME TODO: Unnecessarily convoluted and costly; optimize.
var taskIndexList = [];
var activeTaskIndex = tasksModel.activeTask;
for (var i = 0; i < taskList.children.length - 1; ++i) {
var task = taskList.children[i];
var modelIndex = task.modelIndex(i);
if (task !== undefined){
if (task.IsLauncher !== true && task.IsStartup !== true) {
if (task.m.IsGroupParent === true) {
for (var j = 0; j < tasksModel.rowCount(modelIndex); ++j) {
taskIndexList.push(tasksModel.makeModelIndex(i, j));
}
} else {
taskIndexList.push(modelIndex);
}
}
}
}
if (!taskIndexList.length) {
return;
}
var target = taskIndexList[0];
for (var i = 0; i < taskIndexList.length; ++i) {
if (taskIndexList[i] === activeTaskIndex)
{
if (next && i < (taskIndexList.length - 1)) {
target = taskIndexList[i + 1];
} else if (!next) {
if (i) {
target = taskIndexList[i - 1];
} else {
target = taskIndexList[taskIndexList.length - 1];
}
}
break;
}
}
tasksModel.requestActivate(target);
}
function insertIndexAt(above, x, y) {
if (above && above.itemIndex) {
return above.itemIndex;
} else {
var distance = panel.vertical ? y : x;
//var step = panel.vertical ? LayoutManager.taskWidth() : LayoutManager.taskHeight();
var step = panel.realSize;
var stripe = Math.ceil(distance / step);
/* if (stripe === LayoutManager.calculateStripes()) {
return tasksModel.count - 1;
} else {
return stripe * LayoutManager.tasksPerStripe();
}*/
return stripe-1;
}
}
function publishIconGeometries(taskItems) {
for (var i = 0; i < taskItems.length - 1; ++i) {
var task = taskItems[i];
if (task !== undefined){
if (task.IsLauncher !== true && task.IsStartup !== true) {
tasksModel.requestPublishDelegateGeometry(tasksModel.makeModelIndex(task.itemIndex),
backend.globalRect(task), task);
}
}
}
}
function taskPrefix(prefix) {
var effectivePrefix;
switch (plasmoid.location) {
case PlasmaCore.Types.LeftEdge:
effectivePrefix = "west-" + prefix;
break;
case PlasmaCore.Types.TopEdge:
effectivePrefix = "north-" + prefix;
break;
case PlasmaCore.Types.RightEdge:
effectivePrefix = "east-" + prefix;
break;
default:
effectivePrefix = "south-" + prefix;
}
if (!frame.hasElementPrefix(effectivePrefix)) {
return prefix;
}
return effectivePrefix;
}

View File

@ -0,0 +1,40 @@
/*
* Copyright 2013 Michail Vourlakos <mvourlakos@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 2.010-1301, USA.
*/
import QtQuick 2.0
import org.kde.plasma.configuration 2.0
ConfigModel {
ConfigCategory {
name: i18n("Appearance")
icon: "preferences-desktop-display-color"
source: "ConfigAppearance.qml"
}
ConfigCategory {
name: i18n("Panel")
icon: "window-duplicate"
source: "ConfigPanel.qml"
}
ConfigCategory {
name: i18n("Interaction")
icon: "preferences-system-windows-move"
source: "ConfigInteraction.qml"
}
}

View File

@ -0,0 +1,108 @@
<?xml version="1.0" encoding="UTF-8"?>
<kcfg xmlns="http://www.kde.org/standards/kcfg/1.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.kde.org/standards/kcfg/1.0
http://www.kde.org/standards/kcfg/1.0/kcfg.xsd" >
<kcfgfile name=""/>
<group name="General">
<entry name="showOnlyCurrentScreen" type="Bool">
<default>false</default>
</entry>
<entry name="showOnlyCurrentDesktop" type="Bool">
<default>false</default>
</entry>
<entry name="showOnlyCurrentActivity" type="Bool">
<default>true</default>
</entry>
<entry name="groupingAppIdBlacklist" type="StringList">
<default></default>
</entry>
<entry name="groupingLauncherUrlBlacklist" type="StringList">
<default></default>
</entry>
<entry name="separateLaunchers" type="Bool">
<default>true</default>
</entry>
<entry name="wheelEnabled" type="Bool">
<default>true</default>
</entry>
<entry name="launchers" type="String">
<default></default>
</entry>
<entry name="middleClickAction" type="Enum">
<choices>
<choice name="None"/>
<choice name="Close"/>
<choice name="NewInstance"/>
<choice name="ToggleMinimized"/>
</choices>
<default>2</default>
</entry>
<entry name="plasmoidPosition" type="Enum">
<choices>
<choice name="Center"/>
<choice name="Left"/>
<choice name="Right"/>
<choice name="Top"/>
<choice name="Bottom"/>
</choices>
<default>0</default>
</entry>
<entry name="smartLaunchersEnabled" type="Bool">
<default>true</default>
</entry>
<entry name="showBarLine" type="Bool">
<default>true</default>
</entry>
<entry name="showShadows" type="Bool">
<default>true</default>
</entry>
<entry name="showGlow" type="Bool">
<default>true</default>
</entry>
<entry name="zoomLevel" type="Int">
<default>14</default>
</entry>
<entry name="iconSize" type="Int">
<default>48</default>
</entry>
<entry name="zoomHelper" type="Bool">
<default>false</default>
</entry>
<entry name="threeColorsWindows" type="Bool">
<default>false</default>
</entry>
<entry name="dotsOnActive" type="Bool">
<default>false</default>
</entry>
<entry name="useThemePanel" type="Bool">
<default>true</default>
</entry>
<entry name="panelSize" type="Int">
<default>10</default>
</entry>
<entry name="transparentPanel" type="Bool">
<default>false</default>
</entry>
<entry name="highlightWindows" type="Bool">
<default>false</default>
</entry>
<entry name="isInNowDockPanel" type="Bool">
<default>false</default>
</entry>
<entry name="showToolTips" type="Bool">
<default>false</default>
</entry>
<entry name="durationTime" type="Int">
<default>2</default>
</entry>
<entry name="reverseLinesPosition" type="Bool">
<default>false</default>
</entry>
<entry name="showWindowActions" type="Bool">
<default>false</default>
</entry>
</group>
</kcfg>

Binary file not shown.

After

Width:  |  Height:  |  Size: 792 B

View File

@ -0,0 +1,124 @@
/*
* Copyright 2013 Michail Vourlakos <mvourlakos@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 2.010-1301, USA.
*/
import QtQuick 2.2
import QtGraphicalEffects 1.0
Item {
property double proportion
property string valueLabel
property string numberValue
property bool fullCircle
property bool showNumber
property bool showLabel
property double circleOpacity: 1
property double fontPixelSize: partSize // * 0.55
property double stdThickness: partSize < 0 ? 0 : partSize // "/2.1"
property double circleThicknessAttr: fullCircle ? 0 : stdThickness * 0.9
property double partSize: height / 2
property double pi2: Math.PI * 2
onProportionChanged: {
repaint()
}
function repaint() {
canvas.requestPaint()
}
Canvas {
id: canvas
property int lineWidth: 1
property bool fill: true
property bool stroke: true
property real alpha: 1.0
// edge bleeding fix
readonly property double filler: 0.01
width: parent.width
height: parent.height
antialiasing: true
opacity: 1.0
onPaint: {
var ctx = getContext('2d')
ctx.clearRect(0, 0, canvas.width, canvas.height)
ctx.fillStyle = theme.highlightColor
var startRadian = - Math.PI / 2
var radians = pi2 * proportion
ctx.beginPath();
ctx.arc(width/2, height/2, stdThickness, startRadian, startRadian + radians + filler, false)
ctx.arc(width/2, height/2, circleThicknessAttr, startRadian + radians + filler, startRadian, true)
ctx.closePath()
ctx.fill()
}
}
DropShadow {
anchors.fill: canvas
radius: 4
samples: 8
spread: 0.5
fast: true
color: theme.backgroundColor
source: canvas
}
Text {
id: valueText
anchors.centerIn: parent
text: numberValue
font.pixelSize: fontPixelSize
color: theme.textColor
visible: showNumber
}
DropShadow {
anchors.fill: valueText
radius: 3
samples: 8
spread: 0.6
fast: true
color: theme.backgroundColor
source: valueText
visible: showNumber
}
Text {
id: valueTextLabel
anchors.bottom: parent.bottom
anchors.bottomMargin: -2
anchors.right: parent.right
text: valueLabel
font.pixelSize: fontPixelSize * 0.65
color: theme.textColor
visible: true
}
}

View File

@ -0,0 +1,333 @@
/*
* Copyright 2013 Michail Vourlakos <mvourlakos@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 2.010-1301, USA.
*/
import QtQuick 2.0
import QtQuick.Controls 1.0
import QtQuick.Layouts 1.0
import QtGraphicalEffects 1.0
import org.kde.plasma.core 2.0 as PlasmaCore
import org.kde.plasma.components 2.0 as PlasmaComponents
Item {
id: mainItem
width: childrenRect.width
height: childrenRect.height
property bool vertical: (plasmoid.formFactor == PlasmaCore.Types.Vertical)
property alias cfg_zoomHelper: zoomHelper.checked
property alias cfg_zoomLevel: zoomLevel.value
property alias cfg_showShadows: showShadows.checked
property alias cfg_showGlow: showGlow.checked
property alias cfg_iconSize: iconSizeCmb.realValue
property alias cfg_threeColorsWindows: threeColorsWindows.checked
property alias cfg_dotsOnActive: dotsOnActive.checked
property alias cfg_durationTime : durationTime.value
property alias cfg_reverseLinesPosition : reverseLinesPosition.checked
property alias cfg_isInNowDockPanel: mainItem.isInNowDockPanel
property bool isInNowDockPanel
ColumnLayout {
id:mainColumn
spacing: 15
width: parent.width-40
//Layout.fillWidth: true
GroupBox {
title: ""
flat: true
Layout.fillWidth: true
ColumnLayout {
Layout.fillWidth: true
width: mainItem.width-40
RowLayout{
Label {
text: i18n("Icon size: ")
}
ComboBox {
// 16, 22, 32, 48, 64,128, 256
id: iconSizeCmb
enabled: !mainItem.isInNowDockPanel
property int realValue
property bool startup: true
model: ["16px.", "22px.", "32px.", "48px.", "64px.", "96px", "128px.", "256px."]
onCurrentIndexChanged: {
switch(currentIndex){
case 0:
realValue = 16;
break;
case 1:
realValue = 22;
break;
case 2:
realValue = 32;
break;
case 3:
realValue = 48;
break;
case 4:
realValue = 64;
break;
case 5:
realValue = 96;
break;
case 6:
realValue = 128;
break;
case 7:
realValue = 256;
break;
default:
realValue = 64;
break
}
}
onRealValueChanged: {
if(startup){
switch (realValue){
case 16:
currentIndex = 0;
break;
case 22:
currentIndex = 1;
break;
case 32:
currentIndex = 2;
break;
case 48:
currentIndex = 3;
break;
case 64:
currentIndex = 4;
break;
case 96:
currentIndex = 5;
break;
case 128:
currentIndex = 6;
break;
case 256:
currentIndex = 7;
break;
default:
currentIndex = 4;
break
}
startup = false;
}
}
}
Label {
id: versionLabel
font.italic: true
horizontalAlignment: Text.AlignRight
Layout.alignment: Qt.AlignRight
Layout.fillWidth: true
text: i18n("ver: ") + "@VERSION@"
}
}
CheckBox {
id: showShadows
text: i18n("Enable shadows for icons")
enabled: true
}
CheckBox {
id: showGlow
text: i18n("Show glow around windows points")
enabled: true
}
CheckBox {
id: threeColorsWindows
text: i18n("Different color for minimized windows")
enabled: true
}
CheckBox {
id: dotsOnActive
text: i18n("Dots on active window")
enabled: true
}
CheckBox {
id: reverseLinesPosition
text: i18n("Reverse position for lines and dots")
enabled: true
}
}
}
GridLayout{
id: animationsGridLayout
Layout.fillWidth: true
columns: 3
Label {
id: durationTimeLabel
Layout.alignment: Qt.AlignHCenter
horizontalAlignment: Text.AlignHCenter
text: i18n("Animations: ")
}
Slider {
id: durationTime
enabled: true
Layout.fillWidth: true
minimumValue: 0
maximumValue: 3
stepSize: 1
tickmarksEnabled: true
}
Label {
enabled: durationTime.value > 0
Layout.alignment: Qt.AlignHCenter
horizontalAlignment: Text.AlignHCenter
font.italic: durationTime.value > 0 ? false : true
property string textUsed: durationTime.value > 0 ? i18n("duration") : i18n("disabled")
text: (durationTime.value > 0 ? ("x" + durationTime.value) + " " + textUsed : textUsed )
}
Label{Layout.columnSpan: 3}
Item{
enabled: !mainItem.isInNowDockPanel
Layout.columnSpan: 3
Layout.fillWidth: true
Label {
text: i18n("Zoom")
anchors.centerIn: parent
font.bold: true
font.italic: true
}
}
//////
Label {
enabled: !mainItem.isInNowDockPanel
Layout.alignment: Qt.AlignHCenter
horizontalAlignment: Text.AlignHCenter
text: i18n("Level: ")
}
Slider {
id: zoomLevel
enabled: !mainItem.isInNowDockPanel
Layout.fillWidth: true
minimumValue: 0
maximumValue: 20
stepSize: 1
tickmarksEnabled: true
}
Label {
id:zoomLevelText
enabled: !mainItem.isInNowDockPanel
Layout.minimumWidth: metricsLabel2.width
Layout.maximumWidth: metricsLabel2.width
Layout.alignment: Qt.AlignHCenter
horizontalAlignment: Text.AlignHCenter
//Layout.alignment: Qt.AlignRight
property real fixedZoom: (1 + (zoomLevel.value / 20))
text: "x"+ fixedZoom.toFixed(2)
Label{
id:metricsLabel2
visible: false
text: "x1.50"
}
}
/////
//spacer to set a minimumWidth for sliders
//Layout.minimumWidth didnt work
Label{}
// Label{Layout.maximumWidth: 275}
Label{}
////////
CheckBox {
id: zoomHelper
enabled: !mainItem.isInNowDockPanel
text: i18n("Show a red line on the limit needed for animations")
Layout.columnSpan: 3
}
}
}
DropShadow {
id:shadowText
anchors.fill: inNowDockLabel
enabled: isInNowDockPanel
radius: 3
samples: 5
color: "#cc080808"
source: inNowDockLabel
verticalOffset: 2
horizontalOffset: -1
visible: isInNowDockPanel
}
Label {
id:inNowDockLabel
anchors.horizontalCenter: mainItem.horizontalCenter
anchors.bottom: mainColumn.bottom
anchors.bottomMargin: mainColumn.height / 12
// anchors.verticalCenterOffset: (mainColumn.height / 4)
width: 0.85 * mainItem.width
text: i18n("For the disabled settings you should use the Now Dock Panel Configuration Window")
visible: mainItem.isInNowDockPanel
horizontalAlignment: Text.AlignHCenter
// font.bold: true
font.italic: true
font.pointSize: 1.2 * theme.defaultFont.pointSize
wrapMode: Text.WordWrap
}
}

View File

@ -0,0 +1,133 @@
/*
* Copyright 2013 Michail Vourlakos <mvourlakos@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 2.010-1301, USA.
*/
import QtQuick 2.0
import QtQuick.Controls 1.0
import QtQuick.Layouts 1.0
import org.kde.plasma.core 2.0 as PlasmaCore
import org.kde.plasma.components 2.0 as PlasmaComponents
Item {
width: childrenRect.width
height: childrenRect.height
property bool vertical: (plasmoid.formFactor == PlasmaCore.Types.Vertical)
property alias cfg_wheelEnabled: wheelEnabled.checked
property alias cfg_middleClickAction: middleClickAction.currentIndex
property alias cfg_showOnlyCurrentScreen: showOnlyCurrentScreen.checked
property alias cfg_showOnlyCurrentDesktop: showOnlyCurrentDesktop.checked
property alias cfg_showOnlyCurrentActivity: showOnlyCurrentActivity.checked
property alias cfg_highlightWindows: highlightWindowsChk.checked
property alias cfg_smartLaunchersEnabled: smartLaunchersChk.checked
property alias cfg_showToolTips: showPreviewsChk.checked
property alias cfg_showWindowActions: windowActionsChk.checked
ColumnLayout{
spacing: 15
GroupBox {
title: ""
flat: true
Layout.fillWidth: true
ColumnLayout {
Layout.fillWidth: true
CheckBox {
id: wheelEnabled
text: i18n("Cycle through tasks with mouse wheel")
enabled: false
}
CheckBox {
id: showPreviewsChk
Layout.fillWidth: true
text: i18n("Preview windows on hovering")
}
CheckBox {
id: highlightWindowsChk
Layout.fillWidth: true
text: i18n("Highlight windows on hovering")
}
CheckBox {
id: windowActionsChk
Layout.fillWidth: true
text: i18n("Show window actions in the context menu")
}
CheckBox {
id: smartLaunchersChk
Layout.fillWidth: true
text: i18n("Show progress information in task buttons")
}
RowLayout {
Label {
text: i18n("On middle-click:")
}
ComboBox {
id: middleClickAction
Layout.fillWidth: true
model: [i18nc("The click action", "None"), i18n("Close Window or Group"), i18n("New Instance"), i18n("Minimize/Restore Window or Group")]
}
}
}
}
ColumnLayout {
Layout.fillWidth: true
Label {
text: i18n("Filters")
// Layout.fillWidth: true
anchors.horizontalCenter: parent.horizontalCenter
// anchors.centerIn: parent
font.bold: true
font.italic: true
}
CheckBox {
id: showOnlyCurrentScreen
text: i18n("Show only tasks from the current screen")
}
CheckBox {
id: showOnlyCurrentDesktop
text: i18n("Show only tasks from the current desktop")
}
CheckBox {
id: showOnlyCurrentActivity
text: i18n("Show only tasks from the current activity")
}
}
}
}

View File

@ -0,0 +1,180 @@
/*
* Copyright 2013 Michail Vourlakos <mvourlakos@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 2.010-1301, USA.
*/
import QtQuick 2.0
import QtQuick.Controls 1.0
import QtQuick.Layouts 1.0
import QtGraphicalEffects 1.0
import org.kde.plasma.core 2.0 as PlasmaCore
import org.kde.plasma.components 2.0 as PlasmaComponents
Item {
id: mainItem
width: childrenRect.width
height: childrenRect.height
property bool vertical: (plasmoid.formFactor == PlasmaCore.Types.Vertical)
property alias cfg_showBarLine: showBarLine.checked
property alias cfg_useThemePanel: useThemePanel.checked
property alias cfg_panelSize: panelSize.value
property alias cfg_transparentPanel: transparentPanel.checked
property alias cfg_plasmoidPosition: panelPositionCmb.currentIndex
property alias cfg_isInNowDockPanel: mainItem.isInNowDockPanel
property bool isInNowDockPanel
ColumnLayout {
id:mainColumn
spacing: 15
Layout.fillWidth: true
GridLayout{
enabled: !mainItem.isInNowDockPanel
Layout.fillWidth: true
columns: 3
property bool panelConfigEnabled: showBarLine.checked && useThemePanel.checked
Label {
text: i18n("Position: ")
}
ComboBox {
// 16, 22, 32, 48, 64,128, 256
id: panelPositionCmb
Layout.fillWidth: true
model: [i18n("Center"), i18n("Left"), i18n("Right"), i18n("Top"), i18n("Bottom")]
}
Label{}
CheckBox {
id: showBarLine
Layout.columnSpan: 3
text: i18n("Show bar line for tasks")
enabled: true
}
CheckBox {
id: useThemePanel
Layout.columnSpan: 3
text: i18n("Use plasma theme panel")
enabled: showBarLine.checked
}
CheckBox {
id: transparentPanel
Layout.columnSpan: 3
text: i18n("Use transparency in the panel")
enabled: parent.panelConfigEnabled
}
Label {
id: panelLabel
text: i18n("Size: ")
enabled: parent.panelConfigEnabled
}
Slider {
id: panelSize
enabled: parent.panelConfigEnabled
Layout.fillWidth: true
minimumValue: 0
maximumValue: 256
stepSize: 2
tickmarksEnabled: false
}
Label {
enabled: parent.panelConfigEnabled
Layout.minimumWidth: metricsLabel.width
Layout.maximumWidth: metricsLabel.width
Layout.alignment: Qt.AlignRight
horizontalAlignment: Text.AlignRight
text: ( panelSize.value + " px." )
Label{
id:metricsLabel
visible: false
text: panelSize.maximumValue+" px."
}
}
/* Label{
Layout.columnSpan: 3
Layout.fillWidth: false
Layout.alignment: Qt.AlignRight
Layout.maximumWidth: zoomLevel.width + zoomLevelText.width + panelLabel.width
horizontalAlignment: Text.AlignRight
text: i18n("in panel placement, themes that have set a <b>specific</b> panel transparent work better")
wrapMode: Text.WordWrap
font.italic: true
enabled: parent.panelConfigEnabled
}*/
/////
//spacer to set a minimumWidth for sliders
//Layout.minimumWidth didnt work
Label{}
Label{Layout.minimumWidth: 280}
Label{}
}
}
DropShadow {
id:shadowText
anchors.fill: inNowDockLabel
enabled: isInNowDockPanel
radius: 3
samples: 5
color: "#cc080808"
source: inNowDockLabel
verticalOffset: 2
horizontalOffset: -1
visible: isInNowDockPanel
}
Label {
id:inNowDockLabel
anchors.horizontalCenter: mainItem.horizontalCenter
anchors.verticalCenter: mainColumn.verticalCenter
// anchors.verticalCenterOffset: (mainColumn.height / 4)
width: 0.85 * mainItem.width
text: i18n("For the disabled settings you should use the Now Dock Panel Configuration Window")
visible: mainItem.isInNowDockPanel
horizontalAlignment: Text.AlignHCenter
// font.bold: true
font.italic: true
font.pointSize: 1.2 * theme.defaultFont.pointSize
wrapMode: Text.WordWrap
}
}

View File

@ -0,0 +1,624 @@
/*
* Copyright 2013 Michail Vourlakos <mvourlakos@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 2.010-1301, USA.
*/
import QtQuick 2.0
import org.kde.plasma.plasmoid 2.0
import org.kde.plasma.core 2.0 as PlasmaCore
import org.kde.plasma.components 2.0 as PlasmaComponents
import org.kde.activities 0.1 as Activities
import "../code/activitiesTools.js" as ActivitiesTools
PlasmaComponents.ContextMenu {
id: menu
property QtObject mpris2Source
placement: {
if (plasmoid.location == PlasmaCore.Types.LeftEdge) {
return PlasmaCore.Types.RightPosedTopAlignedPopup;
} else if (plasmoid.location == PlasmaCore.Types.TopEdge) {
return PlasmaCore.Types.BottomPosedLeftAlignedPopup;
} else {
return PlasmaCore.Types.TopPosedLeftAlignedPopup;
}
}
minimumWidth: visualParent ? visualParent.width : 1
property bool isOnAllActivitiesLauncher: true
property int activitiesCount: 0
onStatusChanged: {
if (visualParent && visualParent.m.LauncherUrlWithoutIcon != null && status == PlasmaComponents.DialogStatus.Open) {
launcherToggleAction.checked = (tasksModel.launcherPosition(visualParent.m.LauncherUrlWithoutIcon) != -1);
updateOnAllActivitiesLauncher();
} else if (status == PlasmaComponents.DialogStatus.Closed) {
checkListHovered.start();
menu.destroy();
}
}
function show() {
//trying to use the dragging mechanism in order to not hide the dock
panel.disableRestoreZoom = true;
panel.signalDraggingState(true);
loadDynamicLaunchActions(visualParent.m.LauncherUrlWithoutIcon);
// backend.ungrabMouse(visualParent);
openRelative();
}
function newMenuItem(parent) {
return Qt.createQmlObject(
"import org.kde.plasma.components 2.0 as PlasmaComponents;" +
"PlasmaComponents.MenuItem {}",
parent);
}
function newSeparator(parent) {
return Qt.createQmlObject(
"import org.kde.plasma.components 2.0 as PlasmaComponents;" +
"PlasmaComponents.MenuItem { separator: true }",
parent);
}
function loadDynamicLaunchActions(launcherUrl) {
var actionList = backend.jumpListActions(launcherUrl, menu);
for (var i = 0; i < actionList.length; ++i) {
var item = newMenuItem(menu);
item.action = actionList[i];
menu.addMenuItem(item, virtualDesktopsMenuItem);
}
if (actionList.length > 0) {
menu.addMenuItem(newSeparator(menu), virtualDesktopsMenuItem);
}
var actionList = backend.recentDocumentActions(launcherUrl, menu);
for (var i = 0; i < actionList.length; ++i) {
var item = newMenuItem(menu);
item.action = actionList[i];
menu.addMenuItem(item, virtualDesktopsMenuItem);
}
if (actionList.length > 0) {
menu.addMenuItem(newSeparator(menu), virtualDesktopsMenuItem);
}
// Add Media Player control actions
var sourceName = mpris2Source.sourceNameForLauncherUrl(launcherUrl);
if (sourceName) {
var playerData = mpris2Source.data[sourceName]
if (playerData.CanControl) {
var menuItem = menu.newMenuItem(menu);
menuItem.text = i18nc("Play previous track", "Previous Track");
menuItem.icon = "media-skip-backward";
menuItem.enabled = Qt.binding(function() {
return playerData.CanGoPrevious;
});
menuItem.clicked.connect(function() {
mpris2Source.goPrevious(sourceName);
});
menu.addMenuItem(menuItem, virtualDesktopsMenuItem);
menuItem = menu.newMenuItem(menu);
// PlasmaCore Menu doesn't actually handle icons or labels changing at runtime...
menuItem.text = Qt.binding(function() {
return playerData.PlaybackStatus === "Playing" ? i18nc("Pause playback", "Pause") : i18nc("Start playback", "Play");
});
menuItem.icon = Qt.binding(function() {
return playerData.PlaybackStatus === "Playing" ? "media-playback-pause" : "media-playback-start";
});
menuItem.clicked.connect(function() {
mpris2Source.playPause(sourceName);
});
menu.addMenuItem(menuItem, virtualDesktopsMenuItem);
menuItem = menu.newMenuItem(menu);
menuItem.text = i18nc("Stop playback", "Stop");
menuItem.icon = "media-playback-stop";
menuItem.clicked.connect(function() {
mpris2Source.stop(sourceName);
});
menu.addMenuItem(menuItem, virtualDesktopsMenuItem);
menuItem = menu.newMenuItem(menu);
menuItem.text = i18nc("Play next track", "Next Track");
menuItem.icon = "media-skip-forward";
menuItem.enabled = Qt.binding(function() {
return playerData.CanGoNext;
});
menuItem.clicked.connect(function() {
mpris2Source.goNext(sourceName);
});
menu.addMenuItem(menuItem, virtualDesktopsMenuItem);
menu.addMenuItem(newSeparator(menu), virtualDesktopsMenuItem);
// If we don't have a window associated with the player but we can quit
// it through MPRIS we'll offer a "Quit" option instead of "Close"
if (!closeWindowItem.visible && playerData.CanQuit) {
menuItem = menu.newMenuItem(menu);
menuItem.text = i18nc("Quit media player app", "Quit");
menuItem.icon = "application-exit";
menuItem.visible = Qt.binding(function() {
return !closeWindowItem.visible;
});
menuItem.clicked.connect(function() {
mpris2Source.quit(sourceName);
});
menu.addMenuItem(menuItem);
}
// If we don't have a window associated with the player but we can raise
// it through MPRIS we'll offer a "Restore" option
if (!startNewInstanceItem.visible && playerData.CanRaise) {
menuItem = menu.newMenuItem(menu);
menuItem.text = i18nc("Open or bring to the front window of media player app", "Restore");
menuItem.icon = playerData["Desktop Icon Name"];
menuItem.visible = Qt.binding(function() {
return !startNewInstanceItem.visible;
});
menuItem.clicked.connect(function() {
mpris2Source.raise(sourceName);
});
menu.addMenuItem(menuItem, startNewInstanceItem);
}
}
}
}
function updateOnAllActivitiesLauncher(){
isOnAllActivitiesLauncher = ActivitiesTools.isOnAllActivities(visualParent.m.LauncherUrlWithoutIcon);
}
Component.onCompleted: {
ActivitiesTools.launchersOnActivities = panel.launchersOnActivities
ActivitiesTools.currentActivity = activityInfo.currentActivity;
ActivitiesTools.plasmoid = plasmoid;
// updateOnAllActivitiesLauncher();
}
Component.onDestruction: {
backend.ungrabMouse(visualParent);
panel.signalDraggingState(false);
panel.disableRestoreZoom = false;
checkListHovered.start();
}
/// Sub Items
PlasmaComponents.MenuItem {
id: virtualDesktopsMenuItem
visible: virtualDesktopInfo.numberOfDesktops > 1
&& (visualParent && visualParent.m.IsLauncher !== true
&& visualParent.m.IsStartup !== true
&& visualParent.m.IsVirtualDesktopChangeable === true)
enabled: visible
text: i18n("Move To Desktop")
Connections {
target: virtualDesktopInfo
onNumberOfDesktopsChanged: virtualDesktopsMenu.refresh()
onDesktopNamesChanged: virtualDesktopsMenu.refresh()
}
PlasmaComponents.ContextMenu {
id: virtualDesktopsMenu
visualParent: virtualDesktopsMenuItem.action
function refresh() {
clearMenuItems();
if (virtualDesktopInfo.numberOfDesktops <= 1) {
return;
}
var menuItem = menu.newMenuItem(virtualDesktopsMenu);
menuItem.text = i18n("Move To Current Desktop");
menuItem.enabled = Qt.binding(function() {
return menu.visualParent && menu.visualParent.m.VirtualDesktop != virtualDesktopInfo.currentDesktop;
});
menuItem.clicked.connect(function() {
tasksModel.requestVirtualDesktop(menu.visualParent.modelIndex(), 0);
});
menuItem = menu.newMenuItem(virtualDesktopsMenu);
menuItem.text = i18n("All Desktops");
menuItem.checkable = true;
menuItem.checked = Qt.binding(function() {
return menu.visualParent && menu.visualParent.m.IsOnAllVirtualDesktops === true;
});
menuItem.clicked.connect(function() {
tasksModel.requestVirtualDesktop(menu.visualParent.modelIndex(), 0);
});
backend.setActionGroup(menuItem.action);
menu.newSeparator(virtualDesktopsMenu);
for (var i = 0; i < virtualDesktopInfo.desktopNames.length; ++i) {
menuItem = menu.newMenuItem(virtualDesktopsMenu);
//menuItem.text = i18nc("1 = number of desktop, 2 = desktop name", "%1 Desktop %2", i + 1, virtualDesktopInfo.desktopNames[i]);
menuItem.text = (i + 1) + ". " + virtualDesktopInfo.desktopNames[i];
menuItem.checkable = true;
menuItem.checked = Qt.binding((function(i) {
return function() { return menu.visualParent && menu.visualParent.m.VirtualDesktop == (i + 1) };
})(i));
menuItem.clicked.connect((function(i) {
return function() { return tasksModel.requestVirtualDesktop(menu.visualParent.modelIndex(), i + 1); };
})(i));
backend.setActionGroup(menuItem.action);
}
menu.newSeparator(virtualDesktopsMenu);
menuItem = menu.newMenuItem(virtualDesktopsMenu);
menuItem.text = i18n("New Desktop");
menuItem.clicked.connect(function() {
tasksModel.requestVirtualDesktop(menu.visualParent.modelIndex(), virtualDesktopInfo.numberOfDesktops + 1)
});
}
Component.onCompleted: refresh()
}
}
PlasmaComponents.MenuItem {
id: activitiesDesktopsMenuItem
visible: activityInfo.numberOfRunningActivities > 1
&& (visualParent && !visualParent.m.IsLauncher
&& !visualParent.m.IsStartup)
enabled: visible
text: i18n("Move To &Activity")
Connections {
target: activityInfo
onNumberOfRunningActivitiesChanged: activitiesDesktopsMenu.refresh()
}
PlasmaComponents.ContextMenu {
id: activitiesDesktopsMenu
visualParent: activitiesDesktopsMenuItem.action
function refresh() {
clearMenuItems();
if (activityInfo.numberOfRunningActivities <= 1) {
return;
}
var menuItem = menu.newMenuItem(activitiesDesktopsMenu);
menuItem.text = i18n("Add To Current Activity");
menuItem.enabled = Qt.binding(function() {
return menu.visualParent && menu.visualParent.m.Activities.length > 0 &&
menu.visualParent.m.Activities.indexOf(activityInfo.currentActivity) < 0;
});
menuItem.clicked.connect(function() {
tasksModel.requestActivities(menu.visualParent.modelIndex(), menu.visualParent.m.Activities.concat(activityInfo.currentActivity));
});
menuItem = menu.newMenuItem(activitiesDesktopsMenu);
menuItem.text = i18n("All Activities");
menuItem.checkable = true;
menuItem.checked = Qt.binding(function() {
return menu.visualParent && menu.visualParent.m.Activities.length === 0;
});
menuItem.clicked.connect(function() {
var checked = menuItem.checked;
var newActivities = menu.visualParent.m.Activities;
var size = newActivities.length;
newActivities = undefined; // will cast to an empty QStringList i.e all activities
if (size === 0) {
newActivities = new Array(activityInfo.currentActivity);
}
tasksModel.requestActivities(menu.visualParent.modelIndex(), newActivities);
});
menu.newSeparator(activitiesDesktopsMenu);
var runningActivities = activityInfo.runningActivities();
for (var i = 0; i < runningActivities.length; ++i) {
var activityId = runningActivities[i];
menuItem = menu.newMenuItem(activitiesDesktopsMenu);
menuItem.text = activityInfo.activityName(runningActivities[i]);
menuItem.checkable = true;
menuItem.checked = Qt.binding( (function(activityId) {
return function() {
return menu.visualParent && menu.visualParent.m.Activities.indexOf(activityId) >= 0;
};
})(activityId));
menuItem.clicked.connect((function(activityId) {
return function () {
var checked = menuItem.checked;
var newActivities = menu.visualParent.m.Activities;
var index = newActivities.indexOf(activityId)
if (index < 0) {
newActivities = newActivities.concat(activityId);
} else {
//newActivities = newActivities.splice(index, 1); //this does not work!!!
newActivities.splice(index, 1);
}
return tasksModel.requestActivities(menu.visualParent.modelIndex(), newActivities);
};
})(activityId));
}
menu.newSeparator(activitiesDesktopsMenu);
}
Component.onCompleted: refresh()
}
}
PlasmaComponents.MenuItem {
visible: (visualParent
&& visualParent.m.IsLauncher !== true
&& visualParent.m.IsStartup !== true
&& plasmoid.configuration.showWindowActions)
enabled: visualParent && visualParent.m.IsMinimizable === true
checkable: true
checked: visualParent && visualParent.m.IsMinimized === true
text: i18n("Minimize")
onClicked: tasksModel.requestToggleMinimized(visualParent.modelIndex())
}
PlasmaComponents.MenuItem {
visible: (visualParent
&& visualParent.m.IsLauncher !== true
&& visualParent.m.IsStartup !== true
&& plasmoid.configuration.showWindowActions)
enabled: visualParent && visualParent.m.IsMaximizable === true
checkable: true
checked: visualParent && visualParent.m.IsMaximized === true
text: i18n("Maximize")
onClicked: tasksModel.requestToggleMaximized(visualParent.modelIndex())
}
PlasmaComponents.MenuItem {
id: moreActionsMenuItem
visible: (visualParent
&& visualParent.m.IsLauncher !== true
&& visualParent.m.IsStartup !== true
&& plasmoid.configuration.showWindowActions)
enabled: visible
text: i18n("More Actions")
PlasmaComponents.ContextMenu {
visualParent: moreActionsMenuItem.action
PlasmaComponents.MenuItem {
enabled: menu.visualParent && menu.visualParent.m.IsMovable === true
text: i18n("Move")
icon: "transform-move"
onClicked: tasksModel.requestMove(menu.visualParent.modelIndex())
}
PlasmaComponents.MenuItem {
enabled: menu.visualParent && menu.visualParent.m.IsResizable === true
text: i18n("Resize")
onClicked: tasksModel.requestResize(menu.visualParent.modelIndex())
}
PlasmaComponents.MenuItem {
checkable: true
checked: menu.visualParent && menu.visualParent.m.IsKeepAbove === true
text: i18n("Keep Above Others")
icon: "go-up"
onClicked: tasksModel.requestToggleKeepAbove(menu.visualParent.modelIndex())
}
PlasmaComponents.MenuItem {
checkable: true
checked: menu.visualParent && menu.visualParent.m.IsKeepBelow === true
text: i18n("Keep Below Others")
icon: "go-down"
onClicked: tasksModel.requestToggleKeepBelow(menu.visualParent.modelIndex())
}
PlasmaComponents.MenuItem {
enabled: menu.visualParent && menu.visualParent.m.IsFullScreenable === true
checkable: true
checked: menu.visualParent && menu.visualParent.m.IsFullScreen === true
text: i18n("Fullscreen")
icon: "view-fullscreen"
onClicked: tasksModel.requestToggleFullScreen(menu.visualParent.modelIndex())
}
PlasmaComponents.MenuItem {
enabled: menu.visualParent && menu.visualParent.m.IsShadeable === true
checkable: true
checked: menu.visualParent && menu.visualParent.m.IsShaded === true
text: i18n("Shade")
onClicked: tasksModel.requestToggleShaded(menu.visualParent.modelIndex())
}
PlasmaComponents.MenuItem {
separator: true
}
PlasmaComponents.MenuItem {
visible: (plasmoid.configuration.groupingStrategy != 0) && menu.visualParent.m.IsWindow === true
checkable: true
checked: menu.visualParent && menu.visualParent.m.IsGroupable === true
text: i18n("Allow this program to be grouped")
onClicked: tasksModel.requestToggleGrouping(menu.visualParent.modelIndex())
}
}
}
PlasmaComponents.MenuItem {
id: startNewInstanceItem
visible: (visualParent && visualParent.m.IsLauncher !== true && visualParent.m.IsStartup !== true)
enabled: visualParent && visualParent.m.LauncherUrlWithoutIcon != null
text: i18n("Start New Instance")
icon: "system-run"
onClicked: tasksModel.requestNewInstance(visualParent.modelIndex())
}
PlasmaComponents.MenuItem {
separator: true
visible: (visualParent
&& visualParent.m.IsLauncher !== true
&& visualParent.m.IsStartup !== true
&& plasmoid.configuration.showWindowActions)
}
PlasmaComponents.MenuItem {
id: launcherToggleOnAllActivitiesAction
visible: launcherToggleAction.visible && launcherToggleAction.checked && activitiesCount > 1
enabled: visualParent && visualParent.m.LauncherUrlWithoutIcon != null
checkable: true
checked: isOnAllActivitiesLauncher
text: i18n("Show Launcher On All Activities")
onClicked:{
ActivitiesTools.toggleLauncherState(visualParent.m.LauncherUrlWithoutIcon);
updateOnAllActivitiesLauncher();
}
}
PlasmaComponents.MenuItem {
id: launcherToggleAction
visible: (visualParent && visualParent.m.IsLauncher !== true && visualParent.m.IsStartup !== true)
enabled: visualParent && visualParent.m.LauncherUrlWithoutIcon != null
checkable: true
text: i18n("Show Launcher When Not Running")
onClicked: {
if (tasksModel.launcherPosition(visualParent.m.LauncherUrlWithoutIcon) != -1) {
tasksModel.requestRemoveLauncher(visualParent.m.LauncherUrlWithoutIcon);
} else {
tasksModel.requestAddLauncher(visualParent.m.LauncherUrl);
}
}
}
PlasmaComponents.MenuItem {
visible: (visualParent && visualParent.m.IsLauncher === true) && activitiesCount > 1
checkable: true
checked: isOnAllActivitiesLauncher
text: i18n("Show Launcher On All Activities")
onClicked:{
ActivitiesTools.toggleLauncherState(visualParent.m.LauncherUrlWithoutIcon);
updateOnAllActivitiesLauncher();
}
}
PlasmaComponents.MenuItem {
visible: (visualParent && visualParent.m.IsLauncher === true)
text: i18n("Remove Launcher")
onClicked: tasksModel.requestRemoveLauncher(visualParent.m.LauncherUrlWithoutIcon);
}
PlasmaComponents.MenuItem {
property QtObject configureAction: null
enabled: configureAction && configureAction.enabled
text: configureAction ? configureAction.text : ""
icon: configureAction ? configureAction.icon : ""
onClicked: configureAction.trigger()
Component.onCompleted: configureAction = plasmoid.action("configure")
}
PlasmaComponents.MenuItem {
separator: true
}
PlasmaComponents.MenuItem {
id: closeWindowItem
visible: (visualParent && visualParent.m.IsLauncher !== true && visualParent.m.IsStartup !== true)
enabled: visualParent && visualParent.m.IsClosable === true
text: i18n("Close")
icon: "window-close"
onClicked: tasksModel.requestClose(visualParent.modelIndex())
}
}

View File

@ -0,0 +1,102 @@
/*
* Copyright 2013 Michail Vourlakos <mvourlakos@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 2.010-1301, USA.
*/
import QtQuick 2.0
import org.kde.plasma.core 2.0 as PlasmaCore
import org.kde.plasma.components 2.0 as Components
import QtGraphicalEffects 1.0
Item{
// property string color
id: glowItem
property bool roundCorners: true
property bool showAttention: false
property int animation: plasmoid.configuration.durationTime*units.longDuration
property color attentionColor: colorScopePalette.negativeTextColor // "#ffff1717"
property color basicColor: "blue"
onShowAttentionChanged: {
if(showAttention == false){
smallCircle.color = basicColor;
}
}
Item{
id:mainGlow
anchors.fill: parent
Rectangle {
id: smallCircle
anchors.centerIn: parent
anchors.fill: parent
color: glowItem.basicColor
radius: glowItem.roundCorners ? Math.min(width,height) / 2 : 0
SequentialAnimation{
running: (glowItem.showAttention == true)
loops: Animation.Infinite
PropertyAnimation {
target: smallCircle
property: "color"
to: glowItem.attentionColor
duration: glowItem.animation
easing.type: Easing.InOutQuad
}
PropertyAnimation {
target:smallCircle
property: "color"
to: glowItem.basicColor
duration: glowItem.animation
easing.type: Easing.InOutQuad
}
}
}
RectangularGlow {
id:recGlow
anchors.fill: smallCircle
glowRadius: 2 * Math.min(smallCircle.width, smallCircle.height)
spread: 0.2
color: smallCircle.color
//color: "#cc222222"
// cornerRadius: smallCircle.radius + glowRadius
opacity: panel.showBarLine ? 0.25 : 0.45
visible: panel.glow
}
/* BrightnessContrast {
anchors.fill: recGlow
source: recGlow
anchors.margins: 1
brightness: 0.4
contrast: 0.3
visible: panel.glow
}*/
}
}

View File

@ -0,0 +1,193 @@
/*
* Copyright 2013 Michail Vourlakos <mvourlakos@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 2.010-1301, USA.
*/
import QtQuick 2.0
import org.kde.draganddrop 2.0
import org.kde.taskmanager 0.1 as TaskManager
//import "../code/layout.js" as LayoutManager
import "../code/tools.js" as TaskTools
Item {
// signal urlDropped(url url)
signal urlsDropped(var urls)
property Item target
property Item ignoredItem
property bool moved: false
property alias hoveredItem: dropHandler.hoveredItem
property alias onlyLaunchers: dropHandler.onlyLaunchers
Timer {
id: ignoreItemTimer
repeat: false
interval: 120
onTriggered: {
ignoredItem = null;
}
}
Connections {
target: panel
onDragSourceChanged: {
if (!dragSource) {
ignoredItem = null;
ignoreItemTimer.stop();
}
}
}
DropArea {
id: dropHandler
anchors.fill: parent
preventStealing: true;
property int droppedPosition: -1;
property bool onlyLaunchers: false;
property Item hoveredItem
onDragEnter:{
if(panel.dragSource == null){
panel.dropNewLauncher = true;
var createLaunchers = event.mimeData.urls.every(function (item) {
return backend.isApplication(item)
});
if (createLaunchers)
onlyLaunchers = true;
}
}
onDragMove: {
if(panel.dragSource == null){
panel.dropNewLauncher = true;
}
if (target.animating) {
return;
}
var above = target.childAtPos(event.x, event.y);
// If we're mixing launcher tasks with other tasks and are moving
// a (small) launcher task across a non-launcher task, don't allow
// the latter to be the move target twice in a row for a while, as
// it will naturally be moved underneath the cursor as result of the
// initial move, due to being far larger than the launcher delegate.
// TODO: This restriction (minus the timer, which improves things)
// has been proven out in the EITM fork, but could be improved later
// by tracking the cursor movement vector and allowing the drag if
// the movement direction has reversed, etablishing user intent to
// move back.
/* if (panel.dragSource != null
&& panel.dragSource.m.IsLauncher === true && above != null
&& above.m != null
&& above.m.IsLauncher !== true && above == ignoredItem) {
return;
} else {
ignoredItem = null;
}*/
if (panel.dragSource == null
&& ignoredItem == above)
return;
//at some point it was needed the following && above != ignoredItem
//but know not... strange... && above != ignoredItem
//I use the ignoredItem in order to reduce the move calls as much
//as possible
if (tasksModel.sortMode == TaskManager.TasksModel.SortManual && panel.dragSource && ignoredItem == null) {
var insertAt = TaskTools.insertIndexAt(above, event.x, event.y);
if (panel.dragSource != above && panel.dragSource.itemIndex != insertAt) {
// console.log(panel.dragSource.itemIndex + " - "+insertAt);
tasksModel.move(panel.dragSource.itemIndex, insertAt);
ignoredItem = above;
ignoreItemTimer.restart();
}
} else if (!panel.dragSource && above && hoveredItem != above) {
hoveredItem = above;
panel.dropNewLauncher = true;
// activationTimer.restart();
} else if (!above) {
panel.dropNewLauncher = true;
hoveredItem = null;
// activationTimer.stop();
}
}
onDragLeave: {
hoveredItem = null;
panel.dropNewLauncher = false;
onlyLaunchers = false;
activationTimer.stop();
}
onDrop: {
// Reject internal drops.
panel.dropNewLauncher = false;
onlyLaunchers = false;
if (event.mimeData.formats.indexOf("application/x-orgkdeplasmataskmanager_taskbuttonitem") >= 0) {
return;
}
if (event.mimeData.hasUrls) {
parent.urlsDropped(event.mimeData.urls);
}
}
Timer {
id: activationTimer
interval: 250
repeat: false
onTriggered: {
/* if (parent.hoveredItem.m.IsGroupParent === true) {
groupDialog.visualParent = parent.hoveredItem;
groupDialog.visible = true;
} else if (parent.hoveredItem.m.IsLauncher !== true) {
tasksModel.requestActivate(parent.hoveredItem.modelIndex());
}*/
}
}
}
/*
MouseArea {
id: wheelHandler
anchors.fill: parent
property int wheelDelta: 0;
enabled: plasmoid.configuration.wheelEnabled
onWheel: wheelDelta = TaskTools.wheelActivateNextPrevTask(wheelDelta, wheel.angleDelta.y);
} */
}

View File

@ -0,0 +1,45 @@
/*
* Copyright 2013 Michail Vourlakos <mvourlakos@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 2.010-1301, USA.
*/
import QtQuick 2.0
import QtQuick.Layouts 1.1
import QtGraphicalEffects 1.0
import org.kde.plasma.core 2.0 as PlasmaCore
import org.kde.plasma.components 2.0 as PlasmaComponents
Item{
width: ( icList.orientation === Qt.Horizontal ) ? wrapper.regulatorWidth : 6
height: ( icList.orientation === Qt.Vertical ) ? wrapper.regulatorHeight : 6
Rectangle{
opacity: m.IsActive ? 1 : 0
visible: false
color: theme.buttonFocusColor
width: ( icList.orientation === Qt.Horizontal ) ? parent.width : 3
height: ( icList.orientation === Qt.Vertical ) ? parent.height : 3
anchors.bottom: (panel.position === PlasmaCore.Types.BottomPositioned) ? parent.bottom : undefined
anchors.top: (panel.position === PlasmaCore.Types.TopPositioned) ? parent.top : undefined
anchors.left: (panel.position === PlasmaCore.Types.LeftPositioned) ? parent.left : undefined
anchors.right: (panel.position === PlasmaCore.Types.RightPositioned) ? parent.right : undefined
}
}// active indicator

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,171 @@
/*
* Copyright 2013 Michail Vourlakos <mvourlakos@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 2.010-1301, USA.
*/
import QtQuick 2.0
import QtQuick.Layouts 1.1
import QtGraphicalEffects 1.0
import org.kde.plasma.core 2.0 as PlasmaCore
import org.kde.plasma.components 2.0 as PlasmaComponents
Item{
id:glowFrame
width: ( icList.orientation === Qt.Horizontal ) ? wrapper.regulatorWidth : size
height: ( icList.orientation === Qt.Vertical ) ? wrapper.regulatorHeight : size
//property int size: Math.ceil( panel.iconSize/13 ) //5
property int size: panel.statesLineSize
//SystemPalette { id: myPalette; colorGroup: SystemPalette.Active }
property color isActiveColor: theme.buttonFocusColor
//property color isShownColor: plasmoid.configuration.threeColorsWindows ? panel.shownDotColor : isActiveColor
property color isShownColor: isActiveColor
property color minimizedColor: plasmoid.configuration.threeColorsWindows ? panel.minimizedDotColor : isActiveColor
property color notActiveColor: mainItemContainer.hasMinimized ? minimizedColor : isShownColor
/* Rectangle{
anchors.fill: parent
border.width: 1
border.color: "yellow"
color: "transparent"
opacity:0.6
}*/
Item{
anchors.centerIn: parent
width: flowItem.width
height: flowItem.height
Flow{
id: flowItem
flow: ( icList.orientation === Qt.Vertical ) ? Flow.TopToBottom : Flow.LeftToRight
GlowPoint{
id:firstPoint
visible: ( !IsLauncher ) ? true: false
basicColor: (mainItemContainer.hasActive) ?
glowFrame.isActiveColor : glowFrame.notActiveColor
roundCorners: true
showAttention: model.IsDemandingAttention ? true : false
property int stateWidth: mainItemContainer.isGroupParent ? (wrapper.regulatorWidth - secondPoint.width) : wrapper.regulatorWidth - spacer.width
property int stateHeight: mainItemContainer.isGroupParent ? wrapper.regulatorHeight - secondPoint.height : wrapper.regulatorHeight - spacer.height
property int animationTime: plasmoid.configuration.durationTime* (0.7*units.longDuration)
property bool isActive: mainItemContainer.hasActive
|| (panel.showPreviews && windowsPreviewDlg.activeItem && (windowsPreviewDlg.activeItem === mainItemContainer))
property bool vertical: panel.vertical
property real scaleFactor: wrapper.scale
function updateInitialSizes(){
if(glowFrame){
if(vertical)
width = glowFrame.size;
else
height = glowFrame.size;
if(vertical && isActive)
height = stateHeight;
else
height = glowFrame.size;
if(!vertical && isActive)
width = stateWidth;
else
width = glowFrame.size;
}
}
onIsActiveChanged: {
// if(mainItemContainer.hasActive || windowsPreviewDlg.visible)
activeAndReverseAnimation.start();
}
onScaleFactorChanged: {
if(!activeAndReverseAnimation.running && !panel.vertical && isActive){
width = stateWidth;
}
else if (!activeAndReverseAnimation.running && panel.vertical && isActive){
height = stateHeight;
}
}
onStateWidthChanged:{
if(!activeAndReverseAnimation.running && !vertical && isActive)
width = stateWidth;
}
onStateHeightChanged:{
if(!activeAndReverseAnimation.running && vertical && isActive)
height = stateHeight;
}
onVerticalChanged: updateInitialSizes();
Component.onCompleted: {
updateInitialSizes();
panel.onIconSizeChanged.connect(updateInitialSizes);
}
NumberAnimation{
id: activeAndReverseAnimation
target: firstPoint
property: panel.vertical ? "height" : "width"
to: mainItemContainer.hasActive
|| (panel.showPreviews && windowsPreviewDlg.activeItem && (windowsPreviewDlg.activeItem === mainItemContainer))
? (panel.vertical ? firstPoint.stateHeight : firstPoint.stateWidth) : glowFrame.size
duration: firstPoint.animationTime
easing.type: Easing.InQuad
onStopped: firstPoint.updateInitialSizes()
}
}
Item{
id:spacer
width: mainItemContainer.isGroupParent ? 0.5*glowFrame.size : 0
height: mainItemContainer.isGroupParent ? 0.5*glowFrame.size : 0
}
GlowPoint{
id:secondPoint
width: visible ? glowFrame.size : 0
height: width
basicColor: ((mainItemContainer.hasActive)&&(!(mainItemContainer.hasMinimized))) ? state2Color : state1Color
roundCorners: true
visible: ( mainItemContainer.isGroupParent && plasmoid.configuration.dotsOnActive )
|| (mainItemContainer.isGroupParent && !mainItemContainer.hasActive)? true: false
//when there is no active window
property color state1Color: mainItemContainer.hasShown ? glowFrame.isShownColor : glowFrame.minimizedColor
//when there is active window
property color state2Color: mainItemContainer.hasMinimized ? glowFrame.minimizedColor : glowFrame.isShownColor
}
}
}
}// number of windows indicator

View File

@ -0,0 +1,146 @@
import QtQuick 2.0
import QtGraphicalEffects 1.0
import org.kde.plasma.core 2.0 as PlasmaCore
import org.kde.plasma.components 2.0 as PlasmaComponents
import org.kde.kquickcontrolsaddons 2.0 as KQuickControlAddons
Component {
id: imageBufferingComponent
Item {
id: yourImageWithLoadedIconContainer
anchors.fill: parent
visible: false
property QtObject imageTimer
function updateImage(){
if(!imageTimer)
imageTimer = tttTimer.createObject(iconImage);
else{
imageTimer.loop = 1;
imageTimer.restart();
}
}
Item{
id:fixedIcon
width: panel.iconSize + 2*shadowImageNoActive.radius
height: width
visible:false
KQuickControlAddons.QIconItem{
id: iconImage
width: panel.iconSize
height: width
anchors.centerIn: parent
icon: decoration
state: KQuickControlAddons.QIconItem.DefaultState
enabled: true
visible: true
smooth: true
// onIconChanged: updateBuffers();
property int counter: 0
function updateBuffers(){
if((index !== -1) &&(!centralItem.toBeDestroyed) &&(!mainItemContainer.delayingRemove)){
if(panel.initializationStep){
panel.initializationStep = false;
}
centralItem.firstDrawed = true;
// counter++;
// console.log(counter);
if(shadowedImage && shadowedImage.source)
shadowedImage.source.destroy();
if(panel.enableShadows == true){
shadowImageNoActive.grabToImage(function(result) {
shadowedImage.source = result.url
result.destroy();
}, Qt.size(fixedIcon.width,fixedIcon.height) );
}
else{
fixedIcon.grabToImage(function(result) {
shadowedImage.source = result.url;
result.destroy();
}, Qt.size(fixedIcon.width,fixedIcon.height) );
}
mainItemContainer.buffersAreReady = true;
if(!panel.initializatedBuffers)
panel.noInitCreatedBuffers++;
iconImageBuffer.opacity = 1;
}
}
Component{
id:tttTimer
Timer{
id:ttt
repeat: true
interval: loop <= 1 ? centralItem.shadowInterval : 2500
property int loop: 0;
onTriggered: {
iconImage.updateBuffers();
loop++;
// console.log(loop+' - '+interval);
if(loop > 2)
ttt.destroy(300);
}
Component.onCompleted: ttt.start();
}// end of timer
}//end of component of timer
Component.onCompleted: {
yourImageWithLoadedIconContainer.updateImage();
}
Component.onDestruction: {
if(yourImageWithLoadedIconContainer.imageTimer)
yourImageWithLoadedIconContainer.imageTimer.destroy();
}
}
}
DropShadow {
id:shadowImageNoActive
visible: false
width: fixedIcon.width
height: fixedIcon.height
anchors.centerIn: fixedIcon
radius: centralItem.shadowSize
samples: 2 * radius
color: "#ff080808"
source: fixedIcon
verticalOffset: 2
}
Component.onDestruction: {
if(yourImageWithLoadedIconContainer.imageTimer)
yourImageWithLoadedIconContainer.imageTimer.destroy();
}
}
}

View File

@ -0,0 +1,864 @@
/*
* Copyright 2013 Michail Vourlakos <mvourlakos@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 2.010-1301, USA.
*/
import QtQuick 2.0
import QtQuick.Layouts 1.1
import QtGraphicalEffects 1.0
import org.kde.plasma.core 2.0 as PlasmaCore
import org.kde.plasma.components 2.0 as PlasmaComponents
import org.kde.plasma.private.taskmanager 0.1 as TaskManagerApplet
import org.kde.kquickcontrolsaddons 2.0 as KQuickControlAddons
//I am using KQuickControlAddons.QIconItem even though onExit it triggers the following error
//QObject::~QObject: Timers cannot be stopped from another thread
//but it increases performance almost to double during animation
Item{
id: centralItem
width: wrapper.regulatorWidth
height: wrapper.regulatorHeight
//big interval to show shadows only after all the crappy adds and removes of tasks
//have happened
property bool firstDrawed: true
property bool toBeDestroyed: false
// three intervals in order to create the necessarty buffers from the
// PlasmaCore.IconItem, one big interval for the first creation of the
// plasmoid, a second one for the first creation of a task and a small one
// for simple updates.
// This is done before especially on initialization stage some visuals
// are not ready and empty buffers are created
//property int firstDrawedInterval: panel.initializationStep ? 2000 : 1000
// property int shadowInterval: firstDrawed ? firstDrawedInterval : 250
property int shadowInterval: firstDrawed ? 1000 : 250
property int shadowSize : Math.ceil(panel.iconSize / 10)
readonly property bool smartLauncherEnabled: ((mainItemContainer.isStartup === false) && (plasmoid.configuration.smartLaunchersEnabled))
readonly property variant iconDecoration: decoration
property QtObject buffers: null
property QtObject smartLauncherItem: null
/* Rectangle{
anchors.fill: parent
border.width: 1
border.color: "green"
color: "transparent"
} */
Connections{
target: panel
onZoomFactorChanged: updateImages()
onIconSizeChanged: updateImages()
onEnableShadowsChanged: updateImages()
}
onIconDecorationChanged: {
updateImages();
}
Rectangle{
id: draggedRectangle
width: iconImageBuffer.width+1
height: iconImageBuffer.height+1
anchors.centerIn: iconImageBuffer
opacity: 0
radius: 3
anchors.margins: 5
property color tempColor: theme.highlightColor
color: tempColor
border.width: 1
border.color: theme.highlightColor
onTempColorChanged: tempColor.a = 0.35;
}
//temporary buffers containing the normal Image icon and the zoomed Image icon
// Image{id:zoomedImage; visible:false}
// Image{id:normalImage; visible:false}
Image{
id:shadowedImage
anchors.centerIn:iconImageBuffer
// anchors.horizontalCenter: iconImageBuffer.horizontalCenter
//anchors.verticalCenter: iconImageBuffer.verticalCenter
width:iconImageBuffer.width+2*shadowSize
height:iconImageBuffer.height+2*shadowSize
//visible: plasmoid.configuration.showShadows
visible: false
states: State {
name: "reparented"
ParentChange { target: shadowedImage; parent: panel; }
}
//Corize to use when a window is removed....
/* Colorize{
id: removeImageColorizer
source: parent
anchors.fill: parent
enabled: false
visible: false
hue: 0
saturation: 0
lightness: 0
}*/
}
/* Rectangle{
anchors.fill: iconImageBuffer
border.width: 1
border.color: "red"
color: "transparent"
}*/
KQuickControlAddons.QIconItem{
id: iconImageBuffer
// anchors.centerIn: parent
width: Math.round(newTempSize) //+ 2*centralItem.shadowSize
height: Math.round(width)
icon: decoration
property int zoomedSize: panel.zoomFactor * panel.iconSize
property real basicScalingWidth : wrapper.inTempScaling ? (panel.iconSize * wrapper.scaleWidth) :
panel.iconSize * wrapper.scale
property real basicScalingHeight : wrapper.inTempScaling ? (panel.iconSize * wrapper.scaleHeight) :
panel.iconSize * wrapper.scale
property real newTempSize: (wrapper.opacity == 1) ? Math.min(basicScalingWidth, basicScalingHeight) :
Math.max(basicScalingWidth, basicScalingHeight)
///states for launcher animation
states: [
State{
name: "*"
when: !launcherAnimation.running && !newWindowAnimation.running
AnchorChanges{
target:iconImageBuffer;
anchors.horizontalCenter: parent.horizontalCenter;
anchors.verticalCenter: parent.verticalCenter;
anchors.right: undefined;
anchors.left: undefined;
anchors.top: undefined;
anchors.bottom: undefined;
}
},
State{
name: "animating"
when: launcherAnimation.running || newWindowAnimation.running
AnchorChanges{
target:iconImageBuffer;
anchors.horizontalCenter: undefined;
anchors.verticalCenter: undefined;
anchors.right: panel.position === PlasmaCore.Types.LeftPositioned ? parent.right : undefined;
anchors.left: panel.position === PlasmaCore.Types.RightPositioned ? parent.left : undefined;
anchors.top: panel.position === PlasmaCore.Types.BottomPositioned ? parent.top : undefined;
anchors.bottom: panel.position === PlasmaCore.Types.TopPositioned ? parent.bottom : undefined;
}
}
]
///transitions, basic for the anchor changes
transitions: [
Transition{
from: "animating"
to: "*"
AnchorAnimation { duration: 1.5*plasmoid.configuration.durationTime*units.longDuration }
}
]
}
///Shadow in tasks
Loader{
anchors.fill: iconImageBuffer
active: plasmoid.configuration.showShadows
sourceComponent: DropShadow{
anchors.fill: parent
color: "#ff080808"
samples: 2 * radius
source: iconImageBuffer
radius: centralItem.shadowSize
verticalOffset: 2
}
}
VisualAddItem{
id: dropFilesVisual
anchors.fill: iconImageBuffer
visible: opacity == 0 ? false : true
opacity: panel.dropNewLauncher && !mouseHandler.onlyLaunchers
&& (panel.dragSource == null) && (mouseHandler.hoveredItem === mainItemContainer) ? 1 : 0
}
BrightnessContrast{
id:hoveredImage
opacity: mainItemContainer.containsMouse ? 1 : 0
anchors.fill: iconImageBuffer
brightness: 0.25
source: iconImageBuffer
Behavior on opacity {
NumberAnimation { duration: plasmoid.configuration.durationTime*units.longDuration }
}
}
BrightnessContrast {
id: brightnessTaskEffect
anchors.fill: iconImageBuffer
source: iconImageBuffer
visible: clickedAnimation.running
}
Colorize{
id: stateColorizer
source: iconImageBuffer
anchors.fill: iconImageBuffer
//visible: false
opacity:0
hue:0
saturation:0
lightness:0
}
//Something to show until the buffers are updated
//KQuickControlAddons.QIconItem{
/*
PlasmaCore.IconItem{
id: iconImageBackground
//property real relatedSize: panel.iconSize * ( (doubleSize - 7) / doubleSize );
// width: (visible) ? relatedSize * wrapper.scale : panel.iconSize
width: (visible) ? panel.iconSize * wrapper.scale : panel.iconSize
height: width
anchors.centerIn: parent
// state: wrapper.containsMouse ? KQuickControlAddons.QIconItem.ActiveState : KQuickControlAddons.QIconItem.DefaultState
// icon: decoration
active: wrapper.containsMouse
enabled: true
source: decoration
usesPlasmaTheme: false
visible: ((iconImageBuffer.opacity == 1) && (panel.enableShadows)) ? false : true
Component{
id:hideBackTimer
Timer{
id:hideBackgroundTimer
repeat:false
interval: centralItem.shadowInterval
onTriggered: {
// iconImageBackground.visible = false;
iconImageBuffer.opacity = 1;
hideBackgroundTimer.destroy();
// iconImageBuffer.visible = false;
}
Component.onCompleted: hideBackgroundTimer.start();
}
}
}*/
Loader{
id:defaultWithShadow
//sourceComponent: imageBufferingComponent
sourceComponent: TaskIconBuffers{}
active: mainItemContainer.isStartup ? false : true
}
Loader {
anchors.fill: iconImageBuffer
asynchronous: true
source: "TaskProgressOverlay.qml"
active: (centralItem.smartLauncherEnabled && centralItem.smartLauncherItem
&& centralItem.smartLauncherItem.progressVisible)
}
///////Activate animation/////
SequentialAnimation{
id: clickedAnimation
property bool pressed: mainItemContainer.pressed
property int speed: plasmoid.configuration.durationTime*units.longDuration
ParallelAnimation{
PropertyAnimation {
target: brightnessTaskEffect
property: "brightness"
to: -0.5
duration: clickedAnimation.speed
easing.type: Easing.OutQuad
}
PropertyAnimation {
target: wrapper
property: "scale"
to: panel.taskInAnimation ? 0.9 : wrapper.scale - (panel.zoomFactor - 1) / 2
duration: clickedAnimation.speed
easing.type: Easing.OutQuad
}
}
ParallelAnimation{
PropertyAnimation {
target: brightnessTaskEffect
property: "brightness"
to: 0
duration: clickedAnimation.speed
easing.type: Easing.OutQuad
}
PropertyAnimation {
target: wrapper
property: "scale"
to: panel.taskInAnimation ? 1 : panel.zoomFactor
duration: clickedAnimation.speed
easing.type: Easing.OutQuad
}
}
onPressedChanged: {
if( (pressed)&&
((mainItemContainer.lastButtonClicked == Qt.LeftButton)||(mainItemContainer.lastButtonClicked == Qt.MidButton)) ){
mainItemContainer.animationStarted();
start();
}
}
onStopped: {
if( !mainItemContainer.isDragged){
mainItemContainer.animationEnded();
checkListHovered.startDuration(6*units.longDuration);
}
}
}
Component.onCompleted: {
if (smartLauncherEnabled && !smartLauncherItem) {
var smartLauncher = Qt.createQmlObject(
" import org.kde.plasma.private.taskmanager 0.1 as TaskManagerApplet; TaskManagerApplet.SmartLauncherItem { }",
centralItem);
smartLauncher.launcherUrl = Qt.binding(function() { return model.LauncherUrlWithoutIcon; });
smartLauncherItem = smartLauncher;
}
}
Component.onDestruction: {
centralItem.toBeDestroyed = true;
if(shadowedImage && shadowedImage.source)
shadowedImage.source.destroy();
if(removingAnimation.removingItem)
removingAnimation.removingItem.destroy();
gc();
}
////end of activate animation////
////bouncing task, e.g. on launcher activating and when a new window is
////added in a group task
SequentialAnimation{
id:launcherAnimation
property bool launchedAlready: false
property int speed: plasmoid.configuration.durationTime * 0.8 * units.longDuration
SequentialAnimation{
ParallelAnimation{
PropertyAnimation {
target: wrapper
property: (icList.orientation == Qt.Vertical) ? "tempScaleWidth" : "tempScaleHeight"
to: panel.zoomFactor
duration: launcherAnimation.speed
easing.type: Easing.OutQuad
}
PropertyAnimation {
target: wrapper
property: (icList.orientation == Qt.Horizontal) ? "tempScaleWidth" : "tempScaleHeight"
to: 1
duration: launcherAnimation.speed
easing.type: Easing.OutQuad
}
}
PropertyAnimation {
target: wrapper
property: (icList.orientation == Qt.Vertical) ? "tempScaleWidth" : "tempScaleHeight"
to: 1
duration: 3*plasmoid.configuration.durationTime*launcherAnimation.speed
easing.type: Easing.OutBounce
}
ParallelAnimation{
PropertyAnimation {
target: wrapper
property: (icList.orientation == Qt.Vertical) ? "tempScaleHeight" : "tempScaleWidth"
to: 1
duration: plasmoid.configuration.durationTime*launcherAnimation.speed
easing.type: Easing.OutBounce
}
PropertyAnimation {
target: wrapper
property: "scale"
to: 1
duration: plasmoid.configuration.durationTime*launcherAnimation.speed
easing.type: Easing.OutQuad
}
}
}
onStopped: {
//wrapper.scale = 1;
/* if ( panel.noTasksInAnimation>0 ) {
panel.noTasksInAnimation--;
}
if ( panel.animations>0 ) {
panel.animations--;
}*/
//console.log ("Nooo 2: "+panel.noTasksInAnimation + " - "+panel.animations);
clearAnimationsSignals();
mainItemContainer.setBlockingAnimation(false);
mainItemContainer.animationEnded();
mainItemContainer.launcherAction();
}
function clearAnimationsSignals() {
if ( launchedAlready && panel.noTasksInAnimation>0 ) {
panel.noTasksInAnimation--;
}
if ( launchedAlready && panel.animationsNeedThickness>0 ) {
panel.setAnimationsNeedThickness( panel.animationsNeedThickness-1 );
}
launchedAlready = false;
}
function init(){
//console.log ("Nooo 1 : "+panel.noTasksInAnimation);
if(!launchedAlready) {
launchedAlready = true;
panel.setAnimationsNeedThickness( panel.animationsNeedThickness+1 );
panel.noTasksInAnimation++;
mainItemContainer.setBlockingAnimation(true);
}
wrapper.tempScaleWidth = wrapper.scale;
wrapper.tempScaleHeight = wrapper.scale;
icList.hoveredIndex = -1;
}
function bounceLauncher(){
if(panel.zoomFactor > 1){
mainItemContainer.animationStarted();
init();
start();
}
else
stopped();
}
Component.onCompleted: {
wrapper.runLauncherAnimation.connect(bounceLauncher);
}
Component.onDestruction: {
clearAnimationsSignals();
}
}
/////////////////// end of launcher animation
////////////////// new window and needs attention animation
SequentialAnimation{
id:newWindowAnimation
property int speed: plasmoid.configuration.durationTime*units.longDuration
property bool isDemandingAttention: (IsDemandingAttention === true) ? true : false
property bool entered: mainItemContainer.mouseEntered
property bool needsThicknessSent: false //flag to check if the signal for thickness was sent
SequentialAnimation{
ParallelAnimation{
PropertyAnimation {
target: wrapper
property: (icList.orientation == Qt.Vertical) ? "tempScaleWidth" : "tempScaleHeight"
to: 1 + (0.6 * (panel.zoomFactor-1))
duration: newWindowAnimation.speed
easing.type: Easing.OutQuad
}
PropertyAnimation {
target: wrapper
property: (icList.orientation == Qt.Horizontal) ? "tempScaleWidth" : "tempScaleHeight"
to: 1
duration: newWindowAnimation.speed
easing.type: Easing.OutQuad
}
}
PropertyAnimation {
target: wrapper
property: (icList.orientation == Qt.Vertical) ? "tempScaleWidth" : "tempScaleHeight"
to: 1
duration: 3*plasmoid.configuration.durationTime*newWindowAnimation.speed
easing.type: Easing.OutBounce
}
}
function clear(){
loops = 1;
newWindowAnimation.stop();
// iconImageBuffer.anchors.centerIn = iconImageBuffer.parent;
wrapper.tempScaleWidth = 1;
wrapper.tempScaleHeight = 1;
}
onStopped: {
sendEndOfNeedThicknessAnimation();
clear();
}
onIsDemandingAttentionChanged: {
if( (!isDemandingAttention)&&(running)){
clear();
// wrapper.animationEnded();
}
else if(isDemandingAttention){
bounceNewWindow();
}
}
function sendEndOfNeedThicknessAnimation(){
if (needsThicknessSent) {
needsThicknessSent = false;
if (panel.animationsNeedThickness > 0) {
panel.setAnimationsNeedThickness( panel.animationsNeedThickness-1 );
}
}
}
function init(){
wrapper.tempScaleWidth = wrapper.scale;
wrapper.tempScaleHeight = wrapper.scale;
if(!isDemandingAttention)
loops = 2;
else
loops = 20;
if (!needsThicknessSent) {
needsThicknessSent = true;
panel.setAnimationsNeedThickness( panel.animationsNeedThickness+1 );
}
// icList.hoveredIndex = -1;
}
function bounceNewWindow(){
newWindowAnimation.init();
start();
}
Component.onCompleted: {
mainItemContainer.groupWindowAdded.connect(bounceNewWindow);
}
Component.onDestruction: {
sendEndOfNeedThicknessAnimation();
}
}
/////Removing a Window from a group////
Item{
id:removingAnimation
function init(){
var relavantPoint
if(plasmoid.configuration.showShadows)
relavantPoint = panel.mapFromItem(shadowedImage,0,0);
else
relavantPoint = panel.mapFromItem(iconImageBuffer,0,0);
var removingItem = removeTaskComponent.createObject(panel);
removingItem.x = relavantPoint.x;
removingItem.y = relavantPoint.y;
removingItem.start();
}
function removeTask(){
if(centralItem.firstDrawed && !centralItem.toBeDestroyed
&& mainItemContainer.buffersAreReady && plasmoid.configuration.showShadows
&& windowSystem.compositingActive){
removingAnimation.init();
}
}
Component.onCompleted: {
mainItemContainer.groupWindowRemoved.connect(removeTask);
}
///////////// Component for animating removing window from group
Component {
id: removeTaskComponent
Item{
id: removeTask
width: plasmoid.configuration.showShadows ? shadowedImage.width : iconImageBuffer.width
height: plasmoid.configuration.showShadows ? shadowedImage.height : iconImageBuffer.height
//parent: panel
visible: false
Image {
id: tempRemoveIcon
source: plasmoid.configuration.showShadows ? shadowedImage.source : iconImageBuffer.source
anchors.fill: parent
}
Colorize{
source: tempRemoveIcon
anchors.fill: tempRemoveIcon
hue: 0
saturation: 0
lightness: 0
}
ParallelAnimation{
id: componentRemoveAnimation
property int speed: 2*plasmoid.configuration.durationTime*units.longDuration
property Item removingItem: parent
property int toPoint: 0
PropertyAnimation {
target: removeTask
property: "opacity"
to: 0
duration: componentRemoveAnimation.speed
easing.type: Easing.InQuad
}
PropertyAnimation {
target: removeTask
property: (icList.orientation == Qt.Horizontal) ? "y" : "x"
to: componentRemoveAnimation.toPoint
duration: componentRemoveAnimation.speed
easing.type: Easing.InQuad
}
onStopped: {
removeTask.destroy();
gc();
}
}
function start(){
var tempPoint = 0;
if(icList.orientation == Qt.Horizontal)
tempPoint = y;
else
tempPoint = x;
if( (panel.position === PlasmaCore.Types.BottomPositioned) ||
(panel.position === PlasmaCore.Types.RightPositioned) ){
componentRemoveAnimation.toPoint = tempPoint + panel.iconSize;
}
else{
componentRemoveAnimation.toPoint = tempPoint - panel.iconSize;
}
visible = true;
componentRemoveAnimation.start();
}
}
}
}
//////////// States ////////////////////
states: [
State{
name: "*"
when: !mainItemContainer.isDragged
},
State{
name: "isDragged"
when: ( (mainItemContainer.isDragged) && (plasmoid.immutable) )
// PropertyChanges { target: clickedAnimation; running:false }
PropertyChanges { target: wrapper; scale:1 + ((panel.zoomFactor - 1) / 2)}
}
]
//////////// Transitions //////////////
transitions: [
Transition{
id: isDraggedTransition
to: "isDragged"
property int speed: plasmoid.configuration.durationTime*units.longDuration
SequentialAnimation{
ParallelAnimation{
PropertyAnimation {
target: draggedRectangle
property: "opacity"
to: 1
duration: isDraggedTransition.speed
easing.type: Easing.OutQuad
}
PropertyAnimation {
target: iconImageBuffer
property: "opacity"
to: 0
duration: isDraggedTransition.speed
easing.type: Easing.OutQuad
}
PropertyAnimation {
target: stateColorizer
property: "opacity"
to: 1
duration: isDraggedTransition.speed
easing.type: Easing.OutQuad
}
}
}
onRunningChanged: {
if(running){
mainItemContainer.animationStarted();
//panel.animations++;
panel.updateScale(index-1, 1, 0);
panel.updateScale(index+1, 1, 0);
}
}
},
Transition{
id: defaultTransition
from: "isDragged"
to: "*"
property int speed: plasmoid.configuration.durationTime*units.longDuration
SequentialAnimation{
ParallelAnimation{
PropertyAnimation {
target: draggedRectangle
property: "opacity"
to: 0
duration: defaultTransition.speed
easing.type: Easing.OutQuad
}
PropertyAnimation {
target: iconImageBuffer
property: "opacity"
to: 1
duration: defaultTransition.speed
easing.type: Easing.OutQuad
}
PropertyAnimation {
target: stateColorizer
property: "opacity"
to: 0
duration: isDraggedTransition.speed
easing.type: Easing.OutQuad
}
}
PropertyAnimation {
target: wrapper
property: "scale"
to: 1;
duration: isDraggedTransition.speed
easing.type: Easing.OutQuad
}
}
onRunningChanged: {
if(!running){
var halfZoom = 1 + ((panel.zoomFactor - 1) / 2);
panel.updateScale(index-1, halfZoom, 0);
panel.updateScale(index+1, halfZoom, 0);
mainItemContainer.animationEnded();
// panel.animations--;
}
}
}
]
//////////////////////////
function updateImages(){
if(panel){
if(defaultWithShadow.item){
defaultWithShadow.item.updateImage();
}
}
}
}// Icon Item

View File

@ -0,0 +1,75 @@
/*
* Copyright 2013 Michail Vourlakos <mvourlakos@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 2.010-1301, USA.
*/
import QtQuick 2.0
import org.kde.plasma.core 2.0 as PlasmaCore
Item {
id: background
anchors.fill: parent
CircleText {
id: progressCircle
width: 0.42 * parent.height
height: width
numberValue: centralItem.smartLauncherItem.count
fullCircle: true
showNumber: true
proportion: centralItem.smartLauncherItem.progress / 100
states: [
State {
name: "left"
when: (panel.position === PlasmaCore.Types.LeftPositioned)
AnchorChanges {
target: progressCircle
anchors{ top:background.top; bottom:undefined; left:undefined; right:background.right;}
}
},
State {
name: "right"
when: (panel.position === PlasmaCore.Types.RightPositioned)
AnchorChanges {
target: progressCircle
anchors{ top:background.top; bottom:undefined; left:background.left; right:undefined;}
}
},
State {
name: "bottom"
when: (panel.position === PlasmaCore.Types.BottomPositioned)
AnchorChanges {
target: progressCircle
anchors{ top:background.top; bottom:undefined; left:undefined; right:background.right;}
}
},
State {
name: "top"
when: (panel.position === PlasmaCore.Types.TopPositioned)
AnchorChanges {
target: progressCircle
anchors{ top:background.top; bottom:undefined; left:undefined; right:background.right;}
}
}
]
}
}

View File

@ -0,0 +1,159 @@
/*
* Copyright 2013 Michail Vourlakos <mvourlakos@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 2.010-1301, USA.
*/
import QtQuick 2.0
import QtQml.Models 2.2
//trying to do a very simple thing to count how many windows does
//a task instace has...
//Workaround the mess with launchers, startups, windows etc.
Item{
id: windowsContainer
property int windowsCount: 0
property bool isLauncher: IsLauncher ? true : false
property bool isStartup: IsStartup ? true : false
property bool isWindow: IsWindow ? true : false
onIsLauncherChanged: updateCounter();
// onIsStartupChanged: updateCounter();
// onIsWindowChanged: updateCounter();
//states that exist in windows in a Group of windows
property bool hasMinimized: false;
property bool hasShown: false;
property bool hasActive: false;
//FIXME: For some reason the index is not updated correctly in some cases (e.g. window dragging, repositioning launchers)
// and this way much beautiful information are lost, an activity change back and return,
// it fixes this sometimes...
DelegateModel {
id: windowsLocalModel
model: tasksModel //icList.model
rootIndex: tasksModel.makeModelIndex(currentIndex >=0 ? currentIndex : index)
property int currentIndex: -1
delegate: Item{
property string title: model.display
}
onCountChanged:{
windowsContainer.updateCounter();
}
}
function initializeStates(){
hasMinimized = false;
hasShown = false;
hasActive = false;
if(IsGroupParent){
checkInternalStates();
}
else{
if(mainItemContainer.isMinimized){
hasMinimized = true;
}
else if(mainItemContainer.isActive)
hasActive = true;
else
hasShown = true;
}
}
function checkInternalStates(){
windowsLocalModel.currentIndex = index;
var childs = windowsLocalModel.items;
for(var i=0; i<childs.count; ++i){
var kid = childs.get(i);
if(kid.model.IsMinimized)
hasMinimized = true;
else if (kid.model.IsActive)
hasActive = true;
else
hasShown = true;
}
}
function windowsTitles() {
var result = new Array;
windowsLocalModel.currentIndex = index;
var childs = windowsLocalModel.items;
for(var i=0; i<childs.count; ++i){
var kid = childs.get(i);
var title = kid.model.display
//console.log(title);
// FIXME: we may need a way to remove the app name from the end
/* var lst = title.lastIndexOf(" - ");
if (lst > 0) {
title = title.substring(0, lst);
}*/
result.push(title);
}
return result;
}
Component.onCompleted: {
mainItemContainer.checkWindowsStates.connect(initializeStates);
updateCounter();
}
function updateCounter(){
// console.log("--------- "+ index+" -------");
if(index>=0){
if(IsGroupParent){
windowsLocalModel.currentIndex = index;
var tempC = windowsLocalModel.count;
if (tempC == 0){
if(isLauncher){
windowsCount = 0;
}
else if(isWindow || isStartup){
windowsCount = 1;
}
}
else{
windowsCount = tempC;
}
}
else{
if(isLauncher){
windowsCount = 0;
}
else if(isWindow || isStartup){
windowsCount = 1;
}
}
initializeStates();
}
}
}

View File

@ -0,0 +1,438 @@
/*
* Copyright 2013 by Sebastian Kügler <sebas@kde.org>
* Copyright 2014 by Martin Gräßlin <mgraesslin@kde.org>
* Copyright 2016 by Kai Uwe Broulik <kde@privat.broulik.de>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library General Public License as
* published by the Free Software Foundation; either version 2, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Library General Public License for more details
*
* You should have received a copy of the GNU Library General Public
* License along with this program; if not, write to the
* Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 2.010-1301, USA.
*/
import QtQuick 2.0
import QtQuick.Layouts 1.1
import QtGraphicalEffects 1.0
import org.kde.plasma.core 2.0 as PlasmaCore
import org.kde.plasma.components 2.0 as PlasmaComponents
import org.kde.plasma.extras 2.0 as PlasmaExtras
import org.kde.kquickcontrolsaddons 2.0 as KQuickControlsAddons
//Column {
MouseArea{
id: tooltipContentItem
hoverEnabled: true
property Item toolTip
property var parentIndex
property var titles
property var windows
property string mainText
property string subText
property variant icon
property url launcherUrl
property bool group: windows ? (windows.length > 1) : false
readonly property int thumbnailWidth: units.gridUnit * 15
readonly property int thumbnailHeight: units.gridUnit * 10
property int preferredTextWidth: theme.mSize(theme.defaultFont).width * 30
property int _s: units.largeSpacing / 2
Layout.minimumWidth: Math.max(thumbnailWidth, windowRow.width, appLabelRow.width) + _s
Layout.minimumHeight: childrenRect.height
Layout.maximumWidth: Layout.minimumWidth
Layout.maximumHeight: Layout.minimumHeight
onContainsMouseChanged: {
checkMouseInside();
}
function checkMouseInside(){
var isInside = containsMouse || windowRow.containsMouse();
if (isInside){
toolTipDelegate.currentItem = parentIndex;
}
else{
toolTipDelegate.currentItem = -1;
checkListHovered.restart();
}
}
states: State {
when: mpris2Source.hasPlayer
PropertyChanges {
target: thumbnailSourceItem
opacity: 0 // cannot set visible to false or else WindowThumbnail won't provide thumbnail
}
PropertyChanges {
target: playerControlsOpacityMask
visible: true
source: thumbnailSourceItem
maskSource: playerControlsShadowMask
}
PropertyChanges {
target: playerControlsRow
visible: mpris2Source.hasPlayer
}
}
PlasmaCore.DataSource {
id: mpris2Source
readonly property string current: {
var desktopFileName = launcherUrl.toString().split('/').pop().replace(".desktop", "")
for (var i = 0, length = sources.length; i < length; ++i) {
var source = sources[i];
var sourceData = data[source];
if (sourceData && sourceData.DesktopEntry === desktopFileName) {
return source
}
}
return ""
}
readonly property bool hasPlayer: !!current
readonly property bool playing: hasPlayer && data[current].PlaybackStatus === "Playing"
readonly property bool canControl: hasPlayer && data[current].CanControl
readonly property bool canGoBack: hasPlayer && data[current].CanGoPrevious
readonly property bool canGoNext: hasPlayer && data[current].CanGoNext
readonly property bool canRaise: hasPlayer && data[current].CanRaise
readonly property var currentMetadata: hasPlayer ? data[current].Metadata : ({})
readonly property string track: {
var xesamTitle = currentMetadata["xesam:title"]
if (xesamTitle) {
return xesamTitle
}
// if no track title is given, print out the file name
var xesamUrl = currentMetadata["xesam:url"] ? currentMetadata["xesam:url"].toString() : ""
if (!xesamUrl) {
return ""
}
var lastSlashPos = xesamUrl.lastIndexOf('/')
if (lastSlashPos < 0) {
return ""
}
var lastUrlPart = xesamUrl.substring(lastSlashPos + 1)
return decodeURIComponent(lastUrlPart)
}
readonly property string artist: currentMetadata["xesam:artist"] || ""
readonly property string albumArt: currentMetadata["mpris:artUrl"] || ""
function goPrevious() {
startOperation("Previous")
}
function goNext() {
startOperation("Next")
}
function playPause() {
startOperation("PlayPause")
}
function raise() {
startOperation("Raise")
}
function startOperation(op) {
var service = mpris2Source.serviceForSource(current)
var operation = service.operationDescription(op)
return service.startOperationCall(operation)
}
engine: "mpris2"
connectedSources: sources
}
Column{
spacing: _s
Item {
id: thumbnailContainer
width: Math.max(tooltipContentItem.width, windowRow.width)
height: albumArtImage.available ? albumArtImage.height :
raisePlayerArea.visible ? raisePlayerArea.height :
windowRow.height
Item {
id: thumbnailSourceItem
anchors.fill: parent
PlasmaExtras.ScrollArea {
id: scrollArea
anchors.horizontalCenter: parent.horizontalCenter
width: Math.max(windowRow.width, thumbnailWidth)
height: parent.height
visible: !albumArtImage.available
verticalScrollBarPolicy: Qt.ScrollBarAlwaysOff
horizontalScrollBarPolicy: Qt.ScrollBarAlwaysOff
Component.onCompleted: {
flickableItem.interactive = Qt.binding(function() {
return contentItem.width > viewport.width;
});
}
Row {
id: windowRow
width: childrenRect.width
height: childrenRect.height
spacing: units.largeSpacing
Repeater {
model: (plasmoid.configuration.showToolTips && !albumArtImage.available)
|| !windowSystem.compositingActive ? windows : null
Column{
PlasmaCore.WindowThumbnail {
id: windowThumbnail
width: thumbnailWidth
height: thumbnailHeight
winId: modelData
ToolTipWindowMouseArea {
anchors.fill: parent
modelIndex: tasksModel.makeModelIndex(parentIndex, group ? index : -1)
winId: modelData
thumbnailItem: parent
}
}
PlasmaComponents.Label{
text: titles && titles[index] ? titles[index] : ""
wrapMode: Text.Wrap
font.italic: true
elide: Text.ElideRight
opacity: 0.7
textFormat: Text.PlainText
verticalAlignment: Text.AlignVCenter
width: thumbnailWidth
}
}
}
function containsMouse(){
for(var i=0; i<children.length-1; ++i){
if(children[i].children[0].containsMouse)
return true;
}
return false;
}
}
}
Image {
id: albumArtImage
// also Image.Loading to prevent loading thumbnails just because the album art takes a split second to load
readonly property bool available: status === Image.Ready || status === Image.Loading
anchors.centerIn: parent
width: parent.width
height: thumbnailHeight
sourceSize: Qt.size(thumbnailWidth, thumbnailHeight)
asynchronous: true
source: mpris2Source.albumArt
fillMode: Image.PreserveAspectCrop
visible: available
ToolTipWindowMouseArea {
id: albumMouseArea
anchors.fill: parent
modelIndex: tasksModel.makeModelIndex(parentIndex)//, group ? (index ? index : -1) : -1)
winId: windows != undefined ? (windows[0] || 0) : 0
}
}
MouseArea {
id: raisePlayerArea
anchors.centerIn: parent
width: thumbnailWidth
height: thumbnailHeight
// if there's no window associated with this task, we might still be able to raise the player
visible: windows == undefined || !windows[0] && mpris2Source.canRaise
onClicked: mpris2Source.raise()
PlasmaCore.IconItem {
anchors.fill: parent
source: icon
animated: false
usesPlasmaTheme: false
visible: !albumArtImage.available
}
}
}
Item {
id: playerControlsShadowMask
anchors.fill: thumbnailSourceItem
visible: false // OpacityMask would render it
Rectangle {
width: parent.width
height: parent.height - playerControlsRow.height
}
Rectangle {
anchors.bottom: parent.bottom
width: parent.width
height: playerControlsRow.height
opacity: 0.2
}
}
OpacityMask {
id: playerControlsOpacityMask
anchors.fill: thumbnailSourceItem
visible: false
}
// prevent accidental click-through when a control is disabled
MouseArea {
anchors.fill: playerControlsRow
enabled: playerControlsRow.visible
}
RowLayout {
id: playerControlsRow
anchors {
horizontalCenter: parent.horizontalCenter
bottom: thumbnailSourceItem.bottom
}
width: thumbnailWidth
spacing: 0
enabled: mpris2Source.canControl
visible: false
ColumnLayout {
Layout.fillWidth: true
spacing: 0
PlasmaExtras.Heading {
Layout.fillWidth: true
level: 4
wrapMode: Text.NoWrap
elide: Text.ElideRight
text: mpris2Source.track || ""
}
PlasmaExtras.Heading {
Layout.fillWidth: true
level: 5
wrapMode: Text.NoWrap
elide: Text.ElideRight
text: mpris2Source.artist || ""
}
}
PlasmaComponents.ToolButton {
enabled: mpris2Source.canGoBack
iconName: "media-skip-backward"
tooltip: i18nc("Go to previous song", "Previous")
Accessible.name: tooltip
onClicked: mpris2Source.goPrevious()
}
PlasmaComponents.ToolButton {
Layout.fillHeight: true
Layout.preferredWidth: height // make this button bigger
iconName: mpris2Source.playing ? "media-playback-pause" : "media-playback-start"
tooltip: mpris2Source.playing ? i18nc("Pause player", "Pause") : i18nc("Start player", "Play")
Accessible.name: tooltip
onClicked: mpris2Source.playPause()
}
PlasmaComponents.ToolButton {
enabled: mpris2Source.canGoNext
iconName: "media-skip-forward"
tooltip: i18nc("Go to next song", "Next")
Accessible.name: tooltip
onClicked: mpris2Source.goNext()
}
}
}
Row {
id: appLabelRow
width: childrenRect.width + _s
height: childrenRect.height + units.largeSpacing
spacing: units.largeSpacing
Item {
id: imageContainer
width: tooltipIcon.width
height: tooltipIcon.height
y: _s
PlasmaCore.IconItem {
id: tooltipIcon
x: _s
width: units.iconSizes.desktop
height: width
animated: false
usesPlasmaTheme: false
source: icon
}
}
Column {
id: mainColumn
y: _s
//This instance is purely for metrics
PlasmaExtras.Heading {
id: tooltipMaintextPlaceholder
visible: false
level: 3
text: mainText
textFormat: Text.PlainText
}
PlasmaExtras.Heading {
id: tooltipMaintext
level: 3
width: Math.min(tooltipMaintextPlaceholder.width, preferredTextWidth)
//width: 400
elide: Text.ElideRight
text: mainText
textFormat: Text.PlainText
}
PlasmaComponents.Label {
id: tooltipSubtext
width: tooltipContentItem.preferredTextWidth
height: Math.min(theme.mSize(theme.defaultFont), contentHeight)
wrapMode: Text.WordWrap
text: subText
textFormat: Text.PlainText
opacity: 0.5
visible: text !== ""
}
}
}
}
}

View File

@ -0,0 +1,61 @@
/*
* Copyright 2013 by Sebastian Kügler <sebas@kde.org>
* Copyright 2014 by Martin Gräßlin <mgraesslin@kde.org>
* Copyright 2016 by Kai Uwe Broulik <kde@privat.broulik.de>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library General Public License as
* published by the Free Software Foundation; either version 2, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Library General Public License for more details
*
* You should have received a copy of the GNU Library General Public
* License along with this program; if not, write to the
* Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 2.010-1301, USA.
*/
import QtQuick 2.0
import org.kde.plasma.components 2.0 as PlasmaComponents
MouseArea {
property var modelIndex
property int winId // FIXME Legacy
property Item thumbnailItem
acceptedButtons: Qt.LeftButton
hoverEnabled: true
enabled: winId != 0
onClicked: {
tasksModel.requestActivate(modelIndex);
windowsPreviewDlg.hide();
//toolTip.hideToolTip();
}
onContainsMouseChanged: {
tooltipContentItem.checkMouseInside();
panel.windowsHovered([winId], containsMouse);
}
PlasmaComponents.ToolButton {
anchors {
top: parent.top
topMargin: thumbnailItem ? (thumbnailItem.height - thumbnailItem.paintedHeight) / 2 : 0
right: parent.right
rightMargin: thumbnailItem ? (thumbnailItem.width - thumbnailItem.paintedWidth) / 2 : 0
}
iconSource: "window-close"
visible: parent.containsMouse && winId != 0
tooltip: i18nc("close this window", "Close")
onClicked: tasksModel.requestClose(modelIndex);
}
}

View File

@ -0,0 +1,44 @@
/*
* Copyright 2013 Michail Vourlakos <mvourlakos@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 2.010-1301, USA.
*/
import QtQuick 2.0
import org.kde.plasma.core 2.0 as PlasmaCore
Item{
Rectangle{
anchors.fill: parent
anchors.bottom: (panel.position === PlasmaCore.Types.TopPositioned) ? parent.bottom : undefined
anchors.top: (panel.position === PlasmaCore.Types.BottomPositioned) ? parent.top : undefined
anchors.left: (panel.position === PlasmaCore.Types.RightPositioned) ? parent.left : undefined
anchors.right: (panel.position === PlasmaCore.Types.LeftPositioned) ? parent.right : undefined
radius: panel.iconSize/10
property color tempColor: "#aa222222"
color: tempColor
border.width: 1
border.color: "#ff656565"
property int crossSize: Math.min(parent.width/2, parent.height/2)
Rectangle{width: parent.crossSize; height: 4; anchors.centerIn: parent; color: theme.highlightColor}
Rectangle{width: 4; height: parent.crossSize; anchors.centerIn: parent; color: theme.highlightColor}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,29 @@
[Desktop Entry]
Name=Now Dock
Name[el]=Now Dock
Name[pl]=Now Dock
Name[zh_TW]=Now Dock
Comment=Switch between running applications
Comment[el]=Εναλλαγή μεταξύ ενεργών εφαρμογών
Comment[pl]=Przełączanie między uruchomionymi aplikacjami
Comment[zh_TW]=
Type=Service
Icon=preferences-system-windows
X-KDE-ServiceTypes=Plasma/Applet
X-Plasma-API=declarativeappletscript
X-Plasma-MainScript=ui/main.qml
X-Plasma-Provides=org.kde.plasma.multitasking
X-KDE-PluginInfo-Author=@AUTHOR@
X-KDE-PluginInfo-Email=@EMAIL@
X-KDE-PluginInfo-Name=org.kde.store.nowdock.plasmoid
X-KDE-PluginInfo-Version=@VERSION@
X-KDE-PluginInfo-Website=@WEBSITE@
X-KDE-PluginInfo-Category=Windows and Tasks
X-KDE-PluginInfo-Depends=
X-KDE-PluginInfo-License=GPL v2+
X-KDE-PluginInfo-EnabledByDefault=true

113
po/Messages.sh Normal file
View File

@ -0,0 +1,113 @@
#!/bin/sh
BASEDIR="../.." # root of translatable sources
PROJECT="plasma_applet_org.kde.nowdock.containment" # project name
PROJECTPATH="../../containment" # project path
BUGADDR="https://github.com/psifidotos/nowdock-panel/" # MSGID-Bugs
WDIR="`pwd`/containment" # working dir
PROJECTPLASMOID="plasma_applet_org.kde.store.nowdock.plasmoid" # project name
PROJECTPATHPLASMOID="../../plasmoid" # project path
WDIRPLASMOID="`pwd`/plasmoid" # working di
echo "Preparing rc files for panel"
cd containment
# we use simple sorting to make sure the lines do not jump around too much from system to system
find "${PROJECTPATH}" -name '*.rc' -o -name '*.ui' -o -name '*.kcfg' | sort > "${WDIR}/rcfiles.list"
xargs --arg-file="${WDIR}/rcfiles.list" extractrc > "${WDIR}/rc.cpp"
# additional string for KAboutData
# echo 'i18nc("NAME OF TRANSLATORS","Your names");' >> "${WDIR}/rc.cpp"
# echo 'i18nc("EMAIL OF TRANSLATORS","Your emails");' >> "${WDIR}/rc.cpp"
intltool-extract --quiet --type=gettext/ini ../../containment.metadata.desktop.template
cat ../../containment.metadata.desktop.template.h >> ${WDIR}/rc.cpp
rm ../../containment.metadata.desktop.template.h
echo "Done preparing rc files for panel"
echo "Extracting messages for panel"
# see above on sorting
find "${PROJECTPATH}" -name '*.cpp' -o -name '*.h' -o -name '*.c' -o -name '*.qml' -o -name '*.qml.cmake' | sort > "${WDIR}/infiles.list"
echo "rc.cpp" >> "${WDIR}/infiles.list"
xgettext --from-code=UTF-8 -C -kde -ci18n -ki18n:1 -ki18nc:1c,2 -ki18np:1,2 -ki18ncp:1c,2,3 \
-ktr2i18n:1 -kI18N_NOOP:1 -kI18N_NOOP2:1c,2 -kN_:1 -kaliasLocale -kki18n:1 -kki18nc:1c,2 \
-kki18np:1,2 -kki18ncp:1c,2,3 --msgid-bugs-address="${BUGADDR}" --files-from=infiles.list \
-D "${BASEDIR}" -D "${WDIR}" -o "${PROJECT}.pot" || \
{ echo "error while calling xgettext. aborting."; exit 1; }
echo "Done extracting messages for panel"
echo "Merging translations for panel"
catalogs=`find . -name '*.po'`
for cat in $catalogs; do
echo "$cat"
msgmerge -o "$cat.new" "$cat" "${WDIR}/${PROJECT}.pot"
mv "$cat.new" "$cat"
done
intltool-merge --quiet --desktop-style . ../../containment.metadata.desktop.template "${PROJECTPATH}"/metadata.desktop.cmake
echo "Done merging translations for panel"
echo "Cleaning up"
rm "${WDIR}/rcfiles.list"
rm "${WDIR}/infiles.list"
rm "${WDIR}/rc.cpp"
echo "Done translations for panel"
#---------------------- Plasmoid section ----------------#
#!/bin/sh
#BASEDIR=".." # root of translatable sources
echo "Preparing rc files for plasmoid"
cd ../plasmoid
# we use simple sorting to make sure the lines do not jump around too much from system to system
find "${PROJECTPATHPLASMOID}" -name '*.rc' -o -name '*.ui' -o -name '*.kcfg' | sort > "${WDIRPLASMOID}/rcfiles.list"
xargs --arg-file="${WDIRPLASMOID}/rcfiles.list" extractrc > "${WDIRPLASMOID}/rc.cpp"
intltool-extract --quiet --type=gettext/ini ../../plasmoid.metadata.desktop.template
cat ../../plasmoid.metadata.desktop.template.h >> ${WDIRPLASMOID}/rc.cpp
rm ../../plasmoid.metadata.desktop.template.h
echo "Done preparing rc files for plasmoid"
echo "Extracting messages for plasmoid"
# see above on sorting
find "${PROJECTPATHPLASMOID}" -name '*.cpp' -o -name '*.h' -o -name '*.c' -o -name '*.qml' -o -name '*.qml.cmake' | sort > "${WDIRPLASMOID}/infiles.list"
echo "rc.cpp" >> "${WDIRPLASMOID}/infiles.list"
xgettext --from-code=UTF-8 -C -kde -ci18n -ki18n:1 -ki18nc:1c,2 -ki18np:1,2 -ki18ncp:1c,2,3 \
-ktr2i18n:1 -kI18N_NOOP:1 -kI18N_NOOP2:1c,2 -kN_:1 -kaliasLocale -kki18n:1 -kki18nc:1c,2 \
-kki18np:1,2 -kki18ncp:1c,2,3 --msgid-bugs-address="${BUGADDR}" --files-from=infiles.list \
-D "${BASEDIR}" -D "${WDIRPLASMOID}" -o "${PROJECTPLASMOID}.pot" || \
{ echo "error while calling xgettext. aborting."; exit 1; }
echo "Done extracting messages for plasmoid"
echo "Merging translations for plasmoid"
catalogs=`find . -name '*.po'`
for cat in $catalogs; do
echo "$cat"
msgmerge -o "$cat.new" "$cat" "${WDIRPLASMOID}/${PROJECTPLASMOID}.pot"
mv "$cat.new" "$cat"
done
intltool-merge --quiet --desktop-style . ../../plasmoid.metadata.desktop.template "${PROJECTPATHPLASMOID}"/metadata.desktop.cmake
echo "Done merging translations for plasmoid"
echo "Cleaning up for plasmoid"
rm "${WDIRPLASMOID}/rcfiles.list"
rm "${WDIRPLASMOID}/infiles.list"
rm "${WDIRPLASMOID}/rc.cpp"
echo "Done"

113
po/containment/el.po Normal file
View File

@ -0,0 +1,113 @@
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
#
# Michail Vοurlakos <mvourlakos@gmail.com>, 2016.
msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: https://github.com/psifidotos/nowdock-panel/\n"
"POT-Creation-Date: 2016-12-23 15:19+0200\n"
"PO-Revision-Date: 2016-11-25 00:08+0200\n"
"Last-Translator: Michail Vοurlakos <mvourlakos@gmail.com>\n"
"Language-Team: Greek <kde-i18n-doc@kde.org>\n"
"Language: el_GR\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"X-Generator: Lokalize 2.0\n"
#: rc.cpp:1
#, fuzzy
msgid "Now Dock"
msgstr "Now Dock Πίνακας"
#: rc.cpp:2
#, fuzzy
msgid "A dock for Plasma that tries to animate its plasmoids on hovering"
msgstr ""
"Ένας πίνακας του Plasma που χρησιμοποιεί ποικίλα εφέ για τις εφαρμογές του"
#~ msgid "Applets Alignment"
#~ msgstr "Στοίχιση Εφαρμογών"
#~ msgid "ver: "
#~ msgstr "εκδ: "
#~ msgid "Top"
#~ msgstr "Πάνω"
#~ msgid "Left"
#~ msgstr "Αριστερά"
#~ msgid "Center"
#~ msgstr "Κέντρο"
#~ msgid "Bottom"
#~ msgstr "Κάτω"
#~ msgid "Right"
#~ msgstr "Δεξιά"
#~ msgid "Visibility"
#~ msgstr "Ορατότητα"
#~ msgid "Below Active"
#~ msgstr "Κάτω από Ενεργό"
#~ msgid "Below Maximized"
#~ msgstr "Κάτω από Μεγιστοποίηση"
#~ msgid "Let Windows Cover"
#~ msgstr "Παράθυρα από Πάνω"
#~ msgid "Windows Go Below"
#~ msgstr "Παράθυρα από Κάτω"
#~ msgid "Auto Hide"
#~ msgstr "Αυτόματη Απόκρυψη"
#~ msgid "Always Visible"
#~ msgstr "Πάντα Ορατό"
#~ msgid "Applets Size"
#~ msgstr "Μέγεθος Εφαρμογών"
#~ msgid "Zoom On Hover"
#~ msgstr "Εστίαση"
#~ msgid "Zoom Factor"
#~ msgstr "Συντελεστής Εστίασης"
#~ msgid "Background"
#~ msgstr "Παρασκήνιο"
#~ msgid "Show Panel Background"
#~ msgstr "Εμφάνιση Παρασκηνίου"
#~ msgid "Size"
#~ msgstr "Μέγεθος"
#~ msgid "Shadows"
#~ msgstr "Σκιές"
#~ msgid "None"
#~ msgstr "Καμία"
#~ msgid "Only for locked applets"
#~ msgstr "Μόνο κλειδωμένες εφαρμογές"
#~ msgid "All applets"
#~ msgstr "Παντού"
#~ msgid "Now Dock Default Panel"
#~ msgstr "Προκαθορισμένος Now Dock"
#~ msgid "Empty Now Dock Panel"
#~ msgstr "Κενός Now Dock"
#~ msgid "Automatic"
#~ msgstr "Αυτόματα"
#~ msgid "Small steps for icon sizes in automatic modes"
#~ msgstr "Μικρά βήματα στην αυτόματη εναλλαγή μεγέθους"

84
po/containment/pl.po Normal file
View File

@ -0,0 +1,84 @@
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
#
# Damian Kopeć <damikope@gmail.com>, 2016.
msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: https://github.com/psifidotos/nowdock-panel/\n"
"POT-Creation-Date: 2016-12-23 15:19+0200\n"
"PO-Revision-Date: 2016-10-14 14:20+0100\n"
"Last-Translator: Damian Kopeć <damikope@gmail.com>\n"
"Language-Team: Polish <kde-i18n-doc@kde.org>\n"
"Language: pl\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"X-Generator: Lokalize 2.0\n"
#: rc.cpp:1
#, fuzzy
msgid "Now Dock"
msgstr "Panel Now Dock"
#: rc.cpp:2
#, fuzzy
msgid "A dock for Plasma that tries to animate its plasmoids on hovering"
msgstr "Panel plazmy próbujący animowac plazmoidy podczas najechania na nie"
#~ msgid "Applets Alignment"
#~ msgstr "Wyrównanie Apletów "
#~ msgid "Top"
#~ msgstr "Góra"
#~ msgid "Left"
#~ msgstr "Lewa"
#~ msgid "Center"
#~ msgstr "Środek"
#~ msgid "Bottom"
#~ msgstr "Dół"
#~ msgid "Right"
#~ msgstr "Prawa"
#~ msgid "Applets Size"
#~ msgstr "Wielkość Apletów"
#~ msgid "Zoom On Hover"
#~ msgstr "Zbliżenie Przy Najechaniu"
#~ msgid "Zoom Factor"
#~ msgstr "Stopień Zbliżenia"
#~ msgid "Background"
#~ msgstr "Tło"
#~ msgid "Show Panel Background"
#~ msgstr "Pokaż Tło Panelu"
#~ msgid "Size"
#~ msgstr "Rozmiar"
#, fuzzy
#~ msgid "Only for locked applets"
#~ msgstr "Cień dla zablokowanych apletów"
#, fuzzy
#~ msgid "All applets"
#~ msgstr "Wielkość Apletów"
#~ msgid "Now Dock Default Panel"
#~ msgstr "Domyślny Panel Now Dock"
#~ msgid "Empty Now Dock Panel"
#~ msgstr "Pusty Panel Now Dock"
#~ msgid "Automatic"
#~ msgstr "Automatyczna"
#~ msgid "Small steps for icon sizes in automatic modes"
#~ msgstr "Mały skok wielkości ikon w tryb automatycznym"

View File

@ -0,0 +1,26 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: https://github.com/psifidotos/nowdock-panel/\n"
"POT-Creation-Date: 2016-12-23 15:19+0200\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"Language: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=CHARSET\n"
"Content-Transfer-Encoding: 8bit\n"
#: rc.cpp:1
msgid "Now Dock"
msgstr ""
#: rc.cpp:2
msgid "A dock for Plasma that tries to animate its plasmoids on hovering"
msgstr ""

View File

@ -0,0 +1,34 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: https://github.com/psifidotos/nowdock-panel/\n"
"POT-Creation-Date: 2016-12-22 18:00+0200\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"Language: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=CHARSET\n"
"Content-Transfer-Encoding: 8bit\n"
#: rc.cpp:1
msgid "Now Dock"
msgstr ""
#: rc.cpp:2
msgid "A dock for Plasma that tries to animate its plasmoids on hovering"
msgstr ""
#: rc.cpp:3
msgid "Now Dock Default Panel"
msgstr ""
#: rc.cpp:4
msgid "Empty Now Dock Panel"
msgstr ""

85
po/containment/ro.po Normal file
View File

@ -0,0 +1,85 @@
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
#
# Viorel-Cătălin Răpițeanu <rapiteanu.catalin@gmail.com>, 2016.
msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: https://github.com/psifidotos/nowdock-panel/\n"
"POT-Creation-Date: 2016-12-23 15:19+0200\n"
"PO-Revision-Date: 2016-09-25 04:15+0300\n"
"Last-Translator: Viorel-Cătălin Răpițeanu <rapiteanu DOT catalin AT gmail "
"DOT com>\n"
"Language-Team: Romanian <kde-i18n-doc@kde.org>\n"
"Language: ro_RO\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=3; plural=(n==1?0:(((n%100>19)||((n%100==0)&&(n!=0)))?"
"2:1));\n"
"X-Generator: Poedit 1.8.9\n"
#: rc.cpp:1
#, fuzzy
msgid "Now Dock"
msgstr "Panou Now Dock"
#: rc.cpp:2
#, fuzzy
msgid "A dock for Plasma that tries to animate its plasmoids on hovering"
msgstr ""
"Un panou plasma care încearcă să animeze miniaplicațiile la trecerea peste"
#~ msgid "Applets Alignment"
#~ msgstr "Alinierea miniaplicațiilor"
#~ msgid "Top"
#~ msgstr "Sus"
#~ msgid "Left"
#~ msgstr "Stânga"
#~ msgid "Center"
#~ msgstr "Centru"
#~ msgid "Bottom"
#~ msgstr "Jos"
#~ msgid "Right"
#~ msgstr "Dreapta"
#~ msgid "Applets Size"
#~ msgstr "Dimensiunea miniaplicațiilor"
#~ msgid "Zoom On Hover"
#~ msgstr "Panoramează la trecerea peste"
#~ msgid "Zoom Factor"
#~ msgstr "Factor de panoramare"
#~ msgid "Background"
#~ msgstr "Fundal"
#~ msgid "Show Panel Background"
#~ msgstr "Arată fundalul panoului"
#~ msgid "Size"
#~ msgstr "Dimensiune"
#, fuzzy
#~ msgid "All applets"
#~ msgstr "Dimensiunea miniaplicațiilor"
#, fuzzy
#~ msgid "Now Dock Default Panel"
#~ msgstr "Panou Now Dock"
#, fuzzy
#~ msgid "Empty Now Dock Panel"
#~ msgstr "Panou Now Dock"
#~ msgid "Automatic"
#~ msgstr "Automat"
#~ msgid "Small steps for icon sizes in automatic modes"
#~ msgstr "Pași mici pentru dimensiunea pictogramelor în modurile automate"

112
po/containment/zh_TW.po Normal file
View File

@ -0,0 +1,112 @@
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
#
# Jeff Huang <s8321414@gmail.com>, 2016.
msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: https://github.com/psifidotos/nowdock-panel/\n"
"POT-Creation-Date: 2016-12-23 15:19+0200\n"
"PO-Revision-Date: 2016-11-26 17:31+0800\n"
"Last-Translator: Jeff Huang <s8321414@gmail.com>\n"
"Language-Team: Chinese <kde-i18n-doc@kde.org>\n"
"Language: zh_TW\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
"X-Generator: Lokalize 2.0\n"
#: rc.cpp:1
#, fuzzy
msgid "Now Dock"
msgstr "Now Dock 面板"
#: rc.cpp:2
#, fuzzy
msgid "A dock for Plasma that tries to animate its plasmoids on hovering"
msgstr "一個嘗試讓滑鼠游標停在上面時會讓它的 plasmoid 產生動畫的 plasma 面板"
#~ msgid "Applets Alignment"
#~ msgstr "小程式對齊"
#~ msgid "ver: "
#~ msgstr "版本:"
#~ msgid "Top"
#~ msgstr "頂部"
#~ msgid "Left"
#~ msgstr "左邊"
#~ msgid "Center"
#~ msgstr "置中"
#~ msgid "Bottom"
#~ msgstr "底部"
#~ msgid "Right"
#~ msgstr "右邊"
#~ msgid "Visibility"
#~ msgstr "可見度"
#~ msgid "Below Active"
#~ msgstr "在作用中的視窗後"
#~ msgid "Below Maximized"
#~ msgstr "在最大化的視窗後"
#~ msgid "Let Windows Cover"
#~ msgstr " 讓視窗蓋過"
#~ msgid "Windows Go Below"
#~ msgstr "視窗在下面"
#~ msgid "Auto Hide"
#~ msgstr "自動隱藏"
#~ msgid "Always Visible"
#~ msgstr "永遠可見"
#~ msgid "Applets Size"
#~ msgstr "小程式大小"
#~ msgid "Zoom On Hover"
#~ msgstr "滑鼠游標置於其上時縮放"
#~ msgid "Zoom Factor"
#~ msgstr "縮放係數"
#~ msgid "Background"
#~ msgstr "背景"
#~ msgid "Show Panel Background"
#~ msgstr "顯示面板背景"
#~ msgid "Size"
#~ msgstr "大小"
#~ msgid "Shadows"
#~ msgstr "陰影"
#~ msgid "None"
#~ msgstr "無"
#~ msgid "Only for locked applets"
#~ msgstr "僅鎖定小程式"
#~ msgid "All applets"
#~ msgstr "所有小程式"
#~ msgid "Now Dock Default Panel"
#~ msgstr "Now Dock 預設面板"
#~ msgid "Empty Now Dock Panel"
#~ msgstr "空的 Now Dock 面板"
#~ msgid "Automatic"
#~ msgstr "自動"
#~ msgid "Small steps for icon sizes in automatic modes"
#~ msgstr "自動模式中,圖示大小少量步進"

364
po/plasmoid/el.po Normal file
View File

@ -0,0 +1,364 @@
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
#
# Michail Vοurlakos <mvourlakos@gmail.com>, 2016.
msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: https://github.com/psifidotos/nowdock-panel/\n"
"POT-Creation-Date: 2016-12-23 15:19+0200\n"
"PO-Revision-Date: 2016-11-25 00:01+0200\n"
"Last-Translator: Michail Vοurlakos <mvourlakos@gmail.com>\n"
"Language-Team: Greek <kde-i18n-doc@kde.org>\n"
"Language: el_GR\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"X-Generator: Lokalize 2.0\n"
#: ../../plasmoid/contents/config/config.qml:26
msgid "Appearance"
msgstr "Εμφάνιση"
#: ../../plasmoid/contents/config/config.qml:31
msgid "Panel"
msgstr "Πίνακας"
#: ../../plasmoid/contents/config/config.qml:36
msgid "Interaction"
msgstr "Αλληλεπίδραση"
#: ../../plasmoid/contents/ui/ConfigAppearance.qml.cmake:68
msgid "Icon size: "
msgstr "Μέγεθος: "
#: ../../plasmoid/contents/ui/ConfigAppearance.qml.cmake:156
msgid "ver: "
msgstr "εκδ: "
#: ../../plasmoid/contents/ui/ConfigAppearance.qml.cmake:163
msgid "Enable shadows for icons"
msgstr "Σκιές στα εικονίδια"
#: ../../plasmoid/contents/ui/ConfigAppearance.qml.cmake:169
msgid "Show glow around windows points"
msgstr "Λάμψη στα σημεία κατάστασης των παραθύρων"
#: ../../plasmoid/contents/ui/ConfigAppearance.qml.cmake:175
msgid "Different color for minimized windows"
msgstr "Διαφορετικό χρώμα για ελαχιστοποιημένα παράθυρα"
#: ../../plasmoid/contents/ui/ConfigAppearance.qml.cmake:181
msgid "Dots on active window"
msgstr "Τελείες στο ενεργό παράθυρο"
#: ../../plasmoid/contents/ui/ConfigAppearance.qml.cmake:187
msgid "Reverse position for lines and dots"
msgstr "Αντίστροφη θέση για γραμμές και τελείες"
#: ../../plasmoid/contents/ui/ConfigAppearance.qml.cmake:205
msgid "Animations: "
msgstr "Εφέ: "
#: ../../plasmoid/contents/ui/ConfigAppearance.qml.cmake:223
msgid "duration"
msgstr "διάρκεια"
#: ../../plasmoid/contents/ui/ConfigAppearance.qml.cmake:223
msgid "disabled"
msgstr "ανενεργό"
#: ../../plasmoid/contents/ui/ConfigAppearance.qml.cmake:235
msgid "Zoom"
msgstr "Εστίαση"
#: ../../plasmoid/contents/ui/ConfigAppearance.qml.cmake:249
msgid "Level: "
msgstr "Επίπεδο:"
#: ../../plasmoid/contents/ui/ConfigAppearance.qml.cmake:293
msgid "Show a red line on the limit needed for animations"
msgstr "Εμφάνιση κόκκινης γραμμής στο όριο των εφέ"
#: ../../plasmoid/contents/ui/ConfigAppearance.qml.cmake:323
#: ../../plasmoid/contents/ui/ConfigPanel.qml:169
msgid ""
"For the disabled settings you should use the Now Dock Panel Configuration "
"Window"
msgstr ""
"Για τις ανενεργές ρυθμίσεις πρέπει να χρησιμοποιήσετε το Παράθυρο Ρυθμίσεων "
"του Πίνακα Now Dock"
#: ../../plasmoid/contents/ui/ConfigInteraction.qml:58
msgid "Cycle through tasks with mouse wheel"
msgstr "Περιήγηση στις εργασίες με τη ροδέλα του ποντικιού"
#: ../../plasmoid/contents/ui/ConfigInteraction.qml:65
msgid "Preview windows on hovering"
msgstr "Προεπισκοπήσεις παραθύρων"
#: ../../plasmoid/contents/ui/ConfigInteraction.qml:71
msgid "Highlight windows on hovering"
msgstr "Τονισμός παραθύρων"
#: ../../plasmoid/contents/ui/ConfigInteraction.qml:77
msgid "Show window actions in the context menu"
msgstr "Ενέργειες παραθύρου στο μενού επιλογών"
#: ../../plasmoid/contents/ui/ConfigInteraction.qml:83
msgid "Show progress information in task buttons"
msgstr "Εμφάνιση προόδου εργασιών"
#: ../../plasmoid/contents/ui/ConfigInteraction.qml:88
msgid "On middle-click:"
msgstr "Στο μεσαίο κλικ:"
#: ../../plasmoid/contents/ui/ConfigInteraction.qml:94
msgctxt "The click action"
msgid "None"
msgstr "Καμία"
#: ../../plasmoid/contents/ui/ConfigInteraction.qml:94
msgid "Close Window or Group"
msgstr "Κλείσιμο παραθύρου ή ομάδας"
#: ../../plasmoid/contents/ui/ConfigInteraction.qml:94
msgid "New Instance"
msgstr "Νέο στιγμιότυπο"
#: ../../plasmoid/contents/ui/ConfigInteraction.qml:94
msgid "Minimize/Restore Window or Group"
msgstr "Ελαχιστοποίηση/Επαναφορά παραθύρου ή ομάδας"
#: ../../plasmoid/contents/ui/ConfigInteraction.qml:106
msgid "Filters"
msgstr "Φίλτρα"
#: ../../plasmoid/contents/ui/ConfigInteraction.qml:117
msgid "Show only tasks from the current screen"
msgstr "Εμφάνιση εργασιών μόνο της τρέχουσας οθόνης"
#: ../../plasmoid/contents/ui/ConfigInteraction.qml:122
msgid "Show only tasks from the current desktop"
msgstr "Εμφάνιση εργασιών μόνο της τρέχουσας επιφάνειας εργασίας"
#: ../../plasmoid/contents/ui/ConfigInteraction.qml:127
msgid "Show only tasks from the current activity"
msgstr "Εμφάνιση εργασιών μόνο της τρέχουσας δραστηριότητας"
#: ../../plasmoid/contents/ui/ConfigPanel.qml:58
msgid "Position: "
msgstr "Θέση: "
#: ../../plasmoid/contents/ui/ConfigPanel.qml:66
msgid "Center"
msgstr "Κέντρο"
#: ../../plasmoid/contents/ui/ConfigPanel.qml:66
msgid "Left"
msgstr "Αριστερά"
#: ../../plasmoid/contents/ui/ConfigPanel.qml:66
msgid "Right"
msgstr "Δεξιά"
#: ../../plasmoid/contents/ui/ConfigPanel.qml:66
msgid "Top"
msgstr "Πάνω"
#: ../../plasmoid/contents/ui/ConfigPanel.qml:66
msgid "Bottom"
msgstr "Κάτω"
#: ../../plasmoid/contents/ui/ConfigPanel.qml:74
msgid "Show bar line for tasks"
msgstr "Εμφάνιση υποβάθρου για τις εργασίες"
#: ../../plasmoid/contents/ui/ConfigPanel.qml:81
msgid "Use plasma theme panel"
msgstr "Πίνακας από το θέμα του Plasma"
#: ../../plasmoid/contents/ui/ConfigPanel.qml:88
msgid "Use transparency in the panel"
msgstr "Πίνακας με διαφάνεια"
#: ../../plasmoid/contents/ui/ConfigPanel.qml:95
msgid "Size: "
msgstr "Μέγεθος: "
#: ../../plasmoid/contents/ui/ContextMenu.qml:115
msgctxt "Play previous track"
msgid "Previous Track"
msgstr "Προηγούμενο"
#: ../../plasmoid/contents/ui/ContextMenu.qml:128
msgctxt "Pause playback"
msgid "Pause"
msgstr "Παύση"
#: ../../plasmoid/contents/ui/ContextMenu.qml:128
msgctxt "Start playback"
msgid "Play"
msgstr "Έναρξη"
#: ../../plasmoid/contents/ui/ContextMenu.qml:139
msgctxt "Stop playback"
msgid "Stop"
msgstr "Διακοπή"
#: ../../plasmoid/contents/ui/ContextMenu.qml:147
msgctxt "Play next track"
msgid "Next Track"
msgstr "Επόμενο"
#: ../../plasmoid/contents/ui/ContextMenu.qml:163
msgctxt "Quit media player app"
msgid "Quit"
msgstr "Έξοδος"
#: ../../plasmoid/contents/ui/ContextMenu.qml:178
msgctxt "Open or bring to the front window of media player app"
msgid "Restore"
msgstr "Επαναφορά"
#: ../../plasmoid/contents/ui/ContextMenu.qml:223
msgid "Move To Desktop"
msgstr "Στην Επιφάνεια Εργασίας"
#: ../../plasmoid/contents/ui/ContextMenu.qml:245
msgid "Move To Current Desktop"
msgstr "Στην Τρέχουσα Επιφάνεια Εργασίας"
#: ../../plasmoid/contents/ui/ContextMenu.qml:254
msgid "All Desktops"
msgstr "Όλες οι Επιφάνειες Εργασίας"
#: ../../plasmoid/contents/ui/ContextMenu.qml:283
msgid "New Desktop"
msgstr "Νέα Επιφάνεια Εργασίας"
#: ../../plasmoid/contents/ui/ContextMenu.qml:303
msgid "Move To &Activity"
msgstr "Δραστηριότητες"
#: ../../plasmoid/contents/ui/ContextMenu.qml:324
msgid "Add To Current Activity"
msgstr "Στην Τρέχουσα Δραστηριότητα"
#: ../../plasmoid/contents/ui/ContextMenu.qml:334
msgid "All Activities"
msgstr "Όλες τις Δραστηριότητες"
#: ../../plasmoid/contents/ui/ContextMenu.qml:403
msgid "Minimize"
msgstr "Ελαχιστοποίηση"
#: ../../plasmoid/contents/ui/ContextMenu.qml:419
msgid "Maximize"
msgstr "Μεγιστοποίηση"
#: ../../plasmoid/contents/ui/ContextMenu.qml:434
msgid "More Actions"
msgstr "Περισσότερες ενέργειες"
#: ../../plasmoid/contents/ui/ContextMenu.qml:442
msgid "Move"
msgstr "Μετακίνηση"
#: ../../plasmoid/contents/ui/ContextMenu.qml:451
msgid "Resize"
msgstr "Αλλαγή μεγέθους"
#: ../../plasmoid/contents/ui/ContextMenu.qml:460
msgid "Keep Above Others"
msgstr "Διατήρηση πάνω από τα άλλα"
#: ../../plasmoid/contents/ui/ContextMenu.qml:470
msgid "Keep Below Others"
msgstr "Διατήρηση κάτω από τα άλλα"
#: ../../plasmoid/contents/ui/ContextMenu.qml:482
msgid "Fullscreen"
msgstr "Πλήρης οθόνη"
#: ../../plasmoid/contents/ui/ContextMenu.qml:494
msgid "Shade"
msgstr "Τύλιγμα"
#: ../../plasmoid/contents/ui/ContextMenu.qml:509
msgid "Allow this program to be grouped"
msgstr "Να επιτρέπεται η ομαδοποίηση του προγράμματος"
#: ../../plasmoid/contents/ui/ContextMenu.qml:522
msgid "Start New Instance"
msgstr "Νέο Στιγμιότυπο"
#: ../../plasmoid/contents/ui/ContextMenu.qml:544
#: ../../plasmoid/contents/ui/ContextMenu.qml:577
msgid "Show Launcher On All Activities"
msgstr "Εκκινητής σε Όλες τις Δραστηριότητες"
#: ../../plasmoid/contents/ui/ContextMenu.qml:561
msgid "Show Launcher When Not Running"
msgstr "Εκκινητής όταν δεν είναι Ενεργό"
#: ../../plasmoid/contents/ui/ContextMenu.qml:588
msgid "Remove Launcher"
msgstr "Αφαίρεση Εκκινητή"
#: ../../plasmoid/contents/ui/ContextMenu.qml:619
msgid "Close"
msgstr "Κλείσιμο"
#: ../../plasmoid/contents/ui/TaskDelegate.qml:773
msgid "On %1"
msgstr "Σε %1"
#: ../../plasmoid/contents/ui/TaskDelegate.qml:782
msgctxt "Which virtual desktop a window is currently on"
msgid "Available on all activities"
msgstr "Σε όλες τις δραστηριότητες"
#: ../../plasmoid/contents/ui/TaskDelegate.qml:801
msgctxt "Activities a window is currently on (apart from the current one)"
msgid "Also available on %1"
msgstr "Διαθέσιμο επίσης σε %1"
#: ../../plasmoid/contents/ui/TaskDelegate.qml:805
msgctxt "Which activities a window is currently on"
msgid "Available on %1"
msgstr "Διαθέσιμο σε %1"
#: ../../plasmoid/contents/ui/ToolTipDelegate.qml:356
msgctxt "Go to previous song"
msgid "Previous"
msgstr "Προηγούμενο"
#: ../../plasmoid/contents/ui/ToolTipDelegate.qml:365
msgctxt "Pause player"
msgid "Pause"
msgstr "Παύση"
#: ../../plasmoid/contents/ui/ToolTipDelegate.qml:365
msgctxt "Start player"
msgid "Play"
msgstr "Έναρξη"
#: ../../plasmoid/contents/ui/ToolTipDelegate.qml:373
msgctxt "Go to next song"
msgid "Next"
msgstr "Επόμενο"
#: ../../plasmoid/contents/ui/ToolTipWindowMouseArea.qml:57
msgctxt "close this window"
msgid "Close"
msgstr "Κλείσιμο"
#: rc.cpp:1
msgid "Now Dock"
msgstr "Now Dock"
#: rc.cpp:2
msgid "Switch between running applications"
msgstr "Εναλλαγή μεταξύ ενεργών εφαρμογών"

364
po/plasmoid/pl.po Normal file
View File

@ -0,0 +1,364 @@
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
#
# Damian Kopeć <damikope@gmail.com>, 2016.
msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: https://github.com/psifidotos/nowdock-panel/\n"
"POT-Creation-Date: 2016-12-23 15:19+0200\n"
"PO-Revision-Date: 2016-10-16 13:14+0100\n"
"Last-Translator: Damian Kopeć <damikope@gmail.com>\n"
"Language-Team: Polish <kde-i18n-doc@kde.org>\n"
"Language: pl\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 "
"|| n%100>=20) ? 1 : 2);\n"
"X-Generator: Lokalize 2.0\n"
#: ../../plasmoid/contents/config/config.qml:26
msgid "Appearance"
msgstr "Wygląd "
#: ../../plasmoid/contents/config/config.qml:31
msgid "Panel"
msgstr "Panel"
# może być lepsze/kontekst
#: ../../plasmoid/contents/config/config.qml:36
msgid "Interaction"
msgstr "Interakcja"
#: ../../plasmoid/contents/ui/ConfigAppearance.qml.cmake:68
msgid "Icon size: "
msgstr "Rozmiar ikon:"
#: ../../plasmoid/contents/ui/ConfigAppearance.qml.cmake:156
msgid "ver: "
msgstr ""
#: ../../plasmoid/contents/ui/ConfigAppearance.qml.cmake:163
msgid "Enable shadows for icons"
msgstr "Włącz wyświetlanie cieni ikon"
#: ../../plasmoid/contents/ui/ConfigAppearance.qml.cmake:169
msgid "Show glow around windows points"
msgstr "Pokaż poświatę przy punktach okien"
#: ../../plasmoid/contents/ui/ConfigAppearance.qml.cmake:175
msgid "Different color for minimized windows"
msgstr "Inny kolor zminimalizowanych okien"
#: ../../plasmoid/contents/ui/ConfigAppearance.qml.cmake:181
msgid "Dots on active window"
msgstr "Kropki na aktywnych oknach"
#: ../../plasmoid/contents/ui/ConfigAppearance.qml.cmake:187
msgid "Reverse position for lines and dots"
msgstr ""
#: ../../plasmoid/contents/ui/ConfigAppearance.qml.cmake:205
msgid "Animations: "
msgstr "Animacje:"
#: ../../plasmoid/contents/ui/ConfigAppearance.qml.cmake:223
msgid "duration"
msgstr "czas trwania"
#: ../../plasmoid/contents/ui/ConfigAppearance.qml.cmake:223
msgid "disabled"
msgstr "wyłączone"
#: ../../plasmoid/contents/ui/ConfigAppearance.qml.cmake:235
msgid "Zoom"
msgstr "Zbliżenie"
#: ../../plasmoid/contents/ui/ConfigAppearance.qml.cmake:249
msgid "Level: "
msgstr "Poziom:"
#: ../../plasmoid/contents/ui/ConfigAppearance.qml.cmake:293
msgid "Show a red line on the limit needed for animations"
msgstr "Pokaż czerwoną linię określającą miejsce potrzebne dla animacji"
#: ../../plasmoid/contents/ui/ConfigAppearance.qml.cmake:323
#: ../../plasmoid/contents/ui/ConfigPanel.qml:169
msgid ""
"For the disabled settings you should use the Now Dock Panel Configuration "
"Window"
msgstr "Dla niedostępnych ustawień użyj Okna Konfiguracji Panelu Now Dock"
#: ../../plasmoid/contents/ui/ConfigInteraction.qml:58
msgid "Cycle through tasks with mouse wheel"
msgstr "Zmiana aktywnego zadania kółkiem myszy"
#: ../../plasmoid/contents/ui/ConfigInteraction.qml:65
msgid "Preview windows on hovering"
msgstr "Podgląd okna przy najechaniu kursorem"
#: ../../plasmoid/contents/ui/ConfigInteraction.qml:71
msgid "Highlight windows on hovering"
msgstr "Zaznaczenie okna przy najechaniu kursorem"
#: ../../plasmoid/contents/ui/ConfigInteraction.qml:77
msgid "Show window actions in the context menu"
msgstr ""
#: ../../plasmoid/contents/ui/ConfigInteraction.qml:83
msgid "Show progress information in task buttons"
msgstr "Pokaż informacje o postępie na przyciskach"
#: ../../plasmoid/contents/ui/ConfigInteraction.qml:88
msgid "On middle-click:"
msgstr "Środkowy Przycisk Myszy:"
#: ../../plasmoid/contents/ui/ConfigInteraction.qml:94
msgctxt "The click action"
msgid "None"
msgstr "Nic"
#: ../../plasmoid/contents/ui/ConfigInteraction.qml:94
msgid "Close Window or Group"
msgstr "Zamknij Okno lub Grupę"
#: ../../plasmoid/contents/ui/ConfigInteraction.qml:94
msgid "New Instance"
msgstr "Nowa instancja"
#: ../../plasmoid/contents/ui/ConfigInteraction.qml:94
msgid "Minimize/Restore Window or Group"
msgstr "Zminimalizuj/Przywróć Okno lub Grupę"
#: ../../plasmoid/contents/ui/ConfigInteraction.qml:106
msgid "Filters"
msgstr "Filtry"
#: ../../plasmoid/contents/ui/ConfigInteraction.qml:117
msgid "Show only tasks from the current screen"
msgstr "Pokaż tylko zadania z obecnego ekranu"
#: ../../plasmoid/contents/ui/ConfigInteraction.qml:122
msgid "Show only tasks from the current desktop"
msgstr "Pokaż tylko zadania z obecnego pulpitu"
#: ../../plasmoid/contents/ui/ConfigInteraction.qml:127
msgid "Show only tasks from the current activity"
msgstr "Pokaż tylko zadania z obecnej aktywności"
#: ../../plasmoid/contents/ui/ConfigPanel.qml:58
msgid "Position: "
msgstr "Pozycja:"
#: ../../plasmoid/contents/ui/ConfigPanel.qml:66
msgid "Center"
msgstr "Środek"
#: ../../plasmoid/contents/ui/ConfigPanel.qml:66
msgid "Left"
msgstr "Lewa"
#: ../../plasmoid/contents/ui/ConfigPanel.qml:66
msgid "Right"
msgstr "Prawa"
#: ../../plasmoid/contents/ui/ConfigPanel.qml:66
msgid "Top"
msgstr "Góra"
#: ../../plasmoid/contents/ui/ConfigPanel.qml:66
msgid "Bottom"
msgstr "Dół"
#: ../../plasmoid/contents/ui/ConfigPanel.qml:74
msgid "Show bar line for tasks"
msgstr "Pokaż linie rozdzielające dla zadań"
#: ../../plasmoid/contents/ui/ConfigPanel.qml:81
msgid "Use plasma theme panel"
msgstr "Użyj motywu panelu plazmy"
#: ../../plasmoid/contents/ui/ConfigPanel.qml:88
msgid "Use transparency in the panel"
msgstr "Użyj przezroczystości w panelu"
#: ../../plasmoid/contents/ui/ConfigPanel.qml:95
msgid "Size: "
msgstr "Rozmiar:"
#: ../../plasmoid/contents/ui/ContextMenu.qml:115
msgctxt "Play previous track"
msgid "Previous Track"
msgstr "Poprzedni utwór"
#: ../../plasmoid/contents/ui/ContextMenu.qml:128
msgctxt "Pause playback"
msgid "Pause"
msgstr "Pauza"
#: ../../plasmoid/contents/ui/ContextMenu.qml:128
msgctxt "Start playback"
msgid "Play"
msgstr "Odtwórz"
#: ../../plasmoid/contents/ui/ContextMenu.qml:139
msgctxt "Stop playback"
msgid "Stop"
msgstr "Zatrzymaj"
#: ../../plasmoid/contents/ui/ContextMenu.qml:147
msgctxt "Play next track"
msgid "Next Track"
msgstr "Następny utwór"
#: ../../plasmoid/contents/ui/ContextMenu.qml:163
msgctxt "Quit media player app"
msgid "Quit"
msgstr "Wyjdź"
#: ../../plasmoid/contents/ui/ContextMenu.qml:178
msgctxt "Open or bring to the front window of media player app"
msgid "Restore"
msgstr "Przywróć"
#: ../../plasmoid/contents/ui/ContextMenu.qml:223
msgid "Move To Desktop"
msgstr "Przenieś Na Pulpit"
#: ../../plasmoid/contents/ui/ContextMenu.qml:245
msgid "Move To Current Desktop"
msgstr "Przenieś Na Obecny Pulpit"
#: ../../plasmoid/contents/ui/ContextMenu.qml:254
msgid "All Desktops"
msgstr "Wszystkie Pulpity"
#: ../../plasmoid/contents/ui/ContextMenu.qml:283
msgid "New Desktop"
msgstr "Nowy Pulpit"
#: ../../plasmoid/contents/ui/ContextMenu.qml:303
msgid "Move To &Activity"
msgstr "Przenieś do &Activity"
#: ../../plasmoid/contents/ui/ContextMenu.qml:324
msgid "Add To Current Activity"
msgstr "Dodaj Do Obecnej Aktywności"
#: ../../plasmoid/contents/ui/ContextMenu.qml:334
msgid "All Activities"
msgstr "Wszystkie Aktywności"
#: ../../plasmoid/contents/ui/ContextMenu.qml:403
msgid "Minimize"
msgstr ""
#: ../../plasmoid/contents/ui/ContextMenu.qml:419
msgid "Maximize"
msgstr ""
#: ../../plasmoid/contents/ui/ContextMenu.qml:434
msgid "More Actions"
msgstr ""
#: ../../plasmoid/contents/ui/ContextMenu.qml:442
msgid "Move"
msgstr ""
#: ../../plasmoid/contents/ui/ContextMenu.qml:451
msgid "Resize"
msgstr ""
#: ../../plasmoid/contents/ui/ContextMenu.qml:460
msgid "Keep Above Others"
msgstr ""
#: ../../plasmoid/contents/ui/ContextMenu.qml:470
msgid "Keep Below Others"
msgstr ""
#: ../../plasmoid/contents/ui/ContextMenu.qml:482
msgid "Fullscreen"
msgstr ""
#: ../../plasmoid/contents/ui/ContextMenu.qml:494
msgid "Shade"
msgstr ""
#: ../../plasmoid/contents/ui/ContextMenu.qml:509
msgid "Allow this program to be grouped"
msgstr ""
#: ../../plasmoid/contents/ui/ContextMenu.qml:522
msgid "Start New Instance"
msgstr "Utwórz nową instancję"
#: ../../plasmoid/contents/ui/ContextMenu.qml:544
#: ../../plasmoid/contents/ui/ContextMenu.qml:577
msgid "Show Launcher On All Activities"
msgstr "Pokaż Skrót Na Wszystkich Aktywnościach"
#: ../../plasmoid/contents/ui/ContextMenu.qml:561
msgid "Show Launcher When Not Running"
msgstr "Pokaż Skrót Kiedy Aplikacja Nie Jest Uruchomiona"
#: ../../plasmoid/contents/ui/ContextMenu.qml:588
msgid "Remove Launcher"
msgstr "Usuń Skrót"
#: ../../plasmoid/contents/ui/ContextMenu.qml:619
msgid "Close"
msgstr "Zamknij"
#: ../../plasmoid/contents/ui/TaskDelegate.qml:773
msgid "On %1"
msgstr "Na %1"
#: ../../plasmoid/contents/ui/TaskDelegate.qml:782
msgctxt "Which virtual desktop a window is currently on"
msgid "Available on all activities"
msgstr "Dostępne We Wszystkich Aktywnościach"
#: ../../plasmoid/contents/ui/TaskDelegate.qml:801
msgctxt "Activities a window is currently on (apart from the current one)"
msgid "Also available on %1"
msgstr "Dostępne Także na %1"
#: ../../plasmoid/contents/ui/TaskDelegate.qml:805
msgctxt "Which activities a window is currently on"
msgid "Available on %1"
msgstr "Dostępne na %1"
#: ../../plasmoid/contents/ui/ToolTipDelegate.qml:356
msgctxt "Go to previous song"
msgid "Previous"
msgstr "Poprzedni"
#: ../../plasmoid/contents/ui/ToolTipDelegate.qml:365
msgctxt "Pause player"
msgid "Pause"
msgstr "Pauza"
#: ../../plasmoid/contents/ui/ToolTipDelegate.qml:365
msgctxt "Start player"
msgid "Play"
msgstr "Odtwórz"
#: ../../plasmoid/contents/ui/ToolTipDelegate.qml:373
msgctxt "Go to next song"
msgid "Next"
msgstr "Następny"
#: ../../plasmoid/contents/ui/ToolTipWindowMouseArea.qml:57
msgctxt "close this window"
msgid "Close"
msgstr "Zamknij"
#: rc.cpp:1
msgid "Now Dock"
msgstr "Now Dock"
#: rc.cpp:2
msgid "Switch between running applications"
msgstr "Przełączanie między uruchomionymi aplikacjami"

View File

@ -0,0 +1,362 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: https://github.com/psifidotos/nowdock-panel/\n"
"POT-Creation-Date: 2016-12-23 15:19+0200\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"Language: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=CHARSET\n"
"Content-Transfer-Encoding: 8bit\n"
#: ../../plasmoid/contents/config/config.qml:26
msgid "Appearance"
msgstr ""
#: ../../plasmoid/contents/config/config.qml:31
msgid "Panel"
msgstr ""
#: ../../plasmoid/contents/config/config.qml:36
msgid "Interaction"
msgstr ""
#: ../../plasmoid/contents/ui/ConfigAppearance.qml.cmake:68
msgid "Icon size: "
msgstr ""
#: ../../plasmoid/contents/ui/ConfigAppearance.qml.cmake:156
msgid "ver: "
msgstr ""
#: ../../plasmoid/contents/ui/ConfigAppearance.qml.cmake:163
msgid "Enable shadows for icons"
msgstr ""
#: ../../plasmoid/contents/ui/ConfigAppearance.qml.cmake:169
msgid "Show glow around windows points"
msgstr ""
#: ../../plasmoid/contents/ui/ConfigAppearance.qml.cmake:175
msgid "Different color for minimized windows"
msgstr ""
#: ../../plasmoid/contents/ui/ConfigAppearance.qml.cmake:181
msgid "Dots on active window"
msgstr ""
#: ../../plasmoid/contents/ui/ConfigAppearance.qml.cmake:187
msgid "Reverse position for lines and dots"
msgstr ""
#: ../../plasmoid/contents/ui/ConfigAppearance.qml.cmake:205
msgid "Animations: "
msgstr ""
#: ../../plasmoid/contents/ui/ConfigAppearance.qml.cmake:223
msgid "duration"
msgstr ""
#: ../../plasmoid/contents/ui/ConfigAppearance.qml.cmake:223
msgid "disabled"
msgstr ""
#: ../../plasmoid/contents/ui/ConfigAppearance.qml.cmake:235
msgid "Zoom"
msgstr ""
#: ../../plasmoid/contents/ui/ConfigAppearance.qml.cmake:249
msgid "Level: "
msgstr ""
#: ../../plasmoid/contents/ui/ConfigAppearance.qml.cmake:293
msgid "Show a red line on the limit needed for animations"
msgstr ""
#: ../../plasmoid/contents/ui/ConfigAppearance.qml.cmake:323
#: ../../plasmoid/contents/ui/ConfigPanel.qml:169
msgid ""
"For the disabled settings you should use the Now Dock Panel Configuration "
"Window"
msgstr ""
#: ../../plasmoid/contents/ui/ConfigInteraction.qml:58
msgid "Cycle through tasks with mouse wheel"
msgstr ""
#: ../../plasmoid/contents/ui/ConfigInteraction.qml:65
msgid "Preview windows on hovering"
msgstr ""
#: ../../plasmoid/contents/ui/ConfigInteraction.qml:71
msgid "Highlight windows on hovering"
msgstr ""
#: ../../plasmoid/contents/ui/ConfigInteraction.qml:77
msgid "Show window actions in the context menu"
msgstr ""
#: ../../plasmoid/contents/ui/ConfigInteraction.qml:83
msgid "Show progress information in task buttons"
msgstr ""
#: ../../plasmoid/contents/ui/ConfigInteraction.qml:88
msgid "On middle-click:"
msgstr ""
#: ../../plasmoid/contents/ui/ConfigInteraction.qml:94
msgctxt "The click action"
msgid "None"
msgstr ""
#: ../../plasmoid/contents/ui/ConfigInteraction.qml:94
msgid "Close Window or Group"
msgstr ""
#: ../../plasmoid/contents/ui/ConfigInteraction.qml:94
msgid "New Instance"
msgstr ""
#: ../../plasmoid/contents/ui/ConfigInteraction.qml:94
msgid "Minimize/Restore Window or Group"
msgstr ""
#: ../../plasmoid/contents/ui/ConfigInteraction.qml:106
msgid "Filters"
msgstr ""
#: ../../plasmoid/contents/ui/ConfigInteraction.qml:117
msgid "Show only tasks from the current screen"
msgstr ""
#: ../../plasmoid/contents/ui/ConfigInteraction.qml:122
msgid "Show only tasks from the current desktop"
msgstr ""
#: ../../plasmoid/contents/ui/ConfigInteraction.qml:127
msgid "Show only tasks from the current activity"
msgstr ""
#: ../../plasmoid/contents/ui/ConfigPanel.qml:58
msgid "Position: "
msgstr ""
#: ../../plasmoid/contents/ui/ConfigPanel.qml:66
msgid "Center"
msgstr ""
#: ../../plasmoid/contents/ui/ConfigPanel.qml:66
msgid "Left"
msgstr ""
#: ../../plasmoid/contents/ui/ConfigPanel.qml:66
msgid "Right"
msgstr ""
#: ../../plasmoid/contents/ui/ConfigPanel.qml:66
msgid "Top"
msgstr ""
#: ../../plasmoid/contents/ui/ConfigPanel.qml:66
msgid "Bottom"
msgstr ""
#: ../../plasmoid/contents/ui/ConfigPanel.qml:74
msgid "Show bar line for tasks"
msgstr ""
#: ../../plasmoid/contents/ui/ConfigPanel.qml:81
msgid "Use plasma theme panel"
msgstr ""
#: ../../plasmoid/contents/ui/ConfigPanel.qml:88
msgid "Use transparency in the panel"
msgstr ""
#: ../../plasmoid/contents/ui/ConfigPanel.qml:95
msgid "Size: "
msgstr ""
#: ../../plasmoid/contents/ui/ContextMenu.qml:115
msgctxt "Play previous track"
msgid "Previous Track"
msgstr ""
#: ../../plasmoid/contents/ui/ContextMenu.qml:128
msgctxt "Pause playback"
msgid "Pause"
msgstr ""
#: ../../plasmoid/contents/ui/ContextMenu.qml:128
msgctxt "Start playback"
msgid "Play"
msgstr ""
#: ../../plasmoid/contents/ui/ContextMenu.qml:139
msgctxt "Stop playback"
msgid "Stop"
msgstr ""
#: ../../plasmoid/contents/ui/ContextMenu.qml:147
msgctxt "Play next track"
msgid "Next Track"
msgstr ""
#: ../../plasmoid/contents/ui/ContextMenu.qml:163
msgctxt "Quit media player app"
msgid "Quit"
msgstr ""
#: ../../plasmoid/contents/ui/ContextMenu.qml:178
msgctxt "Open or bring to the front window of media player app"
msgid "Restore"
msgstr ""
#: ../../plasmoid/contents/ui/ContextMenu.qml:223
msgid "Move To Desktop"
msgstr ""
#: ../../plasmoid/contents/ui/ContextMenu.qml:245
msgid "Move To Current Desktop"
msgstr ""
#: ../../plasmoid/contents/ui/ContextMenu.qml:254
msgid "All Desktops"
msgstr ""
#: ../../plasmoid/contents/ui/ContextMenu.qml:283
msgid "New Desktop"
msgstr ""
#: ../../plasmoid/contents/ui/ContextMenu.qml:303
msgid "Move To &Activity"
msgstr ""
#: ../../plasmoid/contents/ui/ContextMenu.qml:324
msgid "Add To Current Activity"
msgstr ""
#: ../../plasmoid/contents/ui/ContextMenu.qml:334
msgid "All Activities"
msgstr ""
#: ../../plasmoid/contents/ui/ContextMenu.qml:403
msgid "Minimize"
msgstr ""
#: ../../plasmoid/contents/ui/ContextMenu.qml:419
msgid "Maximize"
msgstr ""
#: ../../plasmoid/contents/ui/ContextMenu.qml:434
msgid "More Actions"
msgstr ""
#: ../../plasmoid/contents/ui/ContextMenu.qml:442
msgid "Move"
msgstr ""
#: ../../plasmoid/contents/ui/ContextMenu.qml:451
msgid "Resize"
msgstr ""
#: ../../plasmoid/contents/ui/ContextMenu.qml:460
msgid "Keep Above Others"
msgstr ""
#: ../../plasmoid/contents/ui/ContextMenu.qml:470
msgid "Keep Below Others"
msgstr ""
#: ../../plasmoid/contents/ui/ContextMenu.qml:482
msgid "Fullscreen"
msgstr ""
#: ../../plasmoid/contents/ui/ContextMenu.qml:494
msgid "Shade"
msgstr ""
#: ../../plasmoid/contents/ui/ContextMenu.qml:509
msgid "Allow this program to be grouped"
msgstr ""
#: ../../plasmoid/contents/ui/ContextMenu.qml:522
msgid "Start New Instance"
msgstr ""
#: ../../plasmoid/contents/ui/ContextMenu.qml:544
#: ../../plasmoid/contents/ui/ContextMenu.qml:577
msgid "Show Launcher On All Activities"
msgstr ""
#: ../../plasmoid/contents/ui/ContextMenu.qml:561
msgid "Show Launcher When Not Running"
msgstr ""
#: ../../plasmoid/contents/ui/ContextMenu.qml:588
msgid "Remove Launcher"
msgstr ""
#: ../../plasmoid/contents/ui/ContextMenu.qml:619
msgid "Close"
msgstr ""
#: ../../plasmoid/contents/ui/TaskDelegate.qml:773
msgid "On %1"
msgstr ""
#: ../../plasmoid/contents/ui/TaskDelegate.qml:782
msgctxt "Which virtual desktop a window is currently on"
msgid "Available on all activities"
msgstr ""
#: ../../plasmoid/contents/ui/TaskDelegate.qml:801
msgctxt "Activities a window is currently on (apart from the current one)"
msgid "Also available on %1"
msgstr ""
#: ../../plasmoid/contents/ui/TaskDelegate.qml:805
msgctxt "Which activities a window is currently on"
msgid "Available on %1"
msgstr ""
#: ../../plasmoid/contents/ui/ToolTipDelegate.qml:356
msgctxt "Go to previous song"
msgid "Previous"
msgstr ""
#: ../../plasmoid/contents/ui/ToolTipDelegate.qml:365
msgctxt "Pause player"
msgid "Pause"
msgstr ""
#: ../../plasmoid/contents/ui/ToolTipDelegate.qml:365
msgctxt "Start player"
msgid "Play"
msgstr ""
#: ../../plasmoid/contents/ui/ToolTipDelegate.qml:373
msgctxt "Go to next song"
msgid "Next"
msgstr ""
#: ../../plasmoid/contents/ui/ToolTipWindowMouseArea.qml:57
msgctxt "close this window"
msgid "Close"
msgstr ""
#: rc.cpp:1
msgid "Now Dock"
msgstr ""
#: rc.cpp:2
msgid "Switch between running applications"
msgstr ""

362
po/plasmoid/zh_TW.po Normal file
View File

@ -0,0 +1,362 @@
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
#
# Jeff Huang <s8321414@gmail.com>, 2016.
msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: https://github.com/psifidotos/nowdock-panel/\n"
"POT-Creation-Date: 2016-12-23 15:19+0200\n"
"PO-Revision-Date: 2016-11-26 17:34+0800\n"
"Last-Translator: Jeff Huang <s8321414@gmail.com>\n"
"Language-Team: Chinese <kde-i18n-doc@kde.org>\n"
"Language: zh_TW\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
"X-Generator: Lokalize 2.0\n"
#: ../../plasmoid/contents/config/config.qml:26
msgid "Appearance"
msgstr "外觀"
#: ../../plasmoid/contents/config/config.qml:31
msgid "Panel"
msgstr "面板"
#: ../../plasmoid/contents/config/config.qml:36
msgid "Interaction"
msgstr "反應"
#: ../../plasmoid/contents/ui/ConfigAppearance.qml.cmake:68
msgid "Icon size: "
msgstr "圖示大小:"
#: ../../plasmoid/contents/ui/ConfigAppearance.qml.cmake:156
msgid "ver: "
msgstr "版本:"
#: ../../plasmoid/contents/ui/ConfigAppearance.qml.cmake:163
msgid "Enable shadows for icons"
msgstr "啟用圖示陰影"
#: ../../plasmoid/contents/ui/ConfigAppearance.qml.cmake:169
msgid "Show glow around windows points"
msgstr "在視窗點周圍顯示光暈"
#: ../../plasmoid/contents/ui/ConfigAppearance.qml.cmake:175
msgid "Different color for minimized windows"
msgstr "最小化視窗使用不同的顏色"
#: ../../plasmoid/contents/ui/ConfigAppearance.qml.cmake:181
msgid "Dots on active window"
msgstr "作用中的視窗顯示點"
#: ../../plasmoid/contents/ui/ConfigAppearance.qml.cmake:187
msgid "Reverse position for lines and dots"
msgstr "線與點位置反轉"
#: ../../plasmoid/contents/ui/ConfigAppearance.qml.cmake:205
msgid "Animations: "
msgstr "動畫:"
#: ../../plasmoid/contents/ui/ConfigAppearance.qml.cmake:223
msgid "duration"
msgstr "期間"
#: ../../plasmoid/contents/ui/ConfigAppearance.qml.cmake:223
msgid "disabled"
msgstr "已停用"
#: ../../plasmoid/contents/ui/ConfigAppearance.qml.cmake:235
msgid "Zoom"
msgstr "縮放"
#: ../../plasmoid/contents/ui/ConfigAppearance.qml.cmake:249
msgid "Level: "
msgstr "等級:"
#: ../../plasmoid/contents/ui/ConfigAppearance.qml.cmake:293
msgid "Show a red line on the limit needed for animations"
msgstr "在需要限制的動畫上顯示紅線"
#: ../../plasmoid/contents/ui/ConfigAppearance.qml.cmake:323
#: ../../plasmoid/contents/ui/ConfigPanel.qml:169
msgid ""
"For the disabled settings you should use the Now Dock Panel Configuration "
"Window"
msgstr "為了已停用的設定,您必須使用 Now Dock 面板設定視窗"
#: ../../plasmoid/contents/ui/ConfigInteraction.qml:58
msgid "Cycle through tasks with mouse wheel"
msgstr "使用滑鼠滾輪循環切換工作"
#: ../../plasmoid/contents/ui/ConfigInteraction.qml:65
msgid "Preview windows on hovering"
msgstr "在滑鼠游標停留其上時預覽視窗"
#: ../../plasmoid/contents/ui/ConfigInteraction.qml:71
msgid "Highlight windows on hovering"
msgstr "在滑鼠游標停留其上時突顯視窗"
#: ../../plasmoid/contents/ui/ConfigInteraction.qml:77
msgid "Show window actions in the context menu"
msgstr "在右鍵選單中顯示視窗動作"
#: ../../plasmoid/contents/ui/ConfigInteraction.qml:83
msgid "Show progress information in task buttons"
msgstr "在工具按鍵裡顯示進度資訊"
#: ../../plasmoid/contents/ui/ConfigInteraction.qml:88
msgid "On middle-click:"
msgstr "點擊滑鼠中鍵:"
#: ../../plasmoid/contents/ui/ConfigInteraction.qml:94
msgctxt "The click action"
msgid "None"
msgstr "無"
#: ../../plasmoid/contents/ui/ConfigInteraction.qml:94
msgid "Close Window or Group"
msgstr "關閉視窗或群組"
#: ../../plasmoid/contents/ui/ConfigInteraction.qml:94
msgid "New Instance"
msgstr "新的實體"
#: ../../plasmoid/contents/ui/ConfigInteraction.qml:94
msgid "Minimize/Restore Window or Group"
msgstr "最小化/復原視窗"
#: ../../plasmoid/contents/ui/ConfigInteraction.qml:106
msgid "Filters"
msgstr "過濾器"
#: ../../plasmoid/contents/ui/ConfigInteraction.qml:117
msgid "Show only tasks from the current screen"
msgstr "只顯示目前螢幕上的工作"
#: ../../plasmoid/contents/ui/ConfigInteraction.qml:122
msgid "Show only tasks from the current desktop"
msgstr "只顯示目前桌面上的工作"
#: ../../plasmoid/contents/ui/ConfigInteraction.qml:127
msgid "Show only tasks from the current activity"
msgstr "只顯示目前活動裡的工作"
#: ../../plasmoid/contents/ui/ConfigPanel.qml:58
msgid "Position: "
msgstr "位置:"
#: ../../plasmoid/contents/ui/ConfigPanel.qml:66
msgid "Center"
msgstr "置中"
#: ../../plasmoid/contents/ui/ConfigPanel.qml:66
msgid "Left"
msgstr "左邊"
#: ../../plasmoid/contents/ui/ConfigPanel.qml:66
msgid "Right"
msgstr "右邊"
#: ../../plasmoid/contents/ui/ConfigPanel.qml:66
msgid "Top"
msgstr "頂部"
#: ../../plasmoid/contents/ui/ConfigPanel.qml:66
msgid "Bottom"
msgstr "底部"
#: ../../plasmoid/contents/ui/ConfigPanel.qml:74
msgid "Show bar line for tasks"
msgstr "為工作顯示條狀列"
#: ../../plasmoid/contents/ui/ConfigPanel.qml:81
msgid "Use plasma theme panel"
msgstr "使用 Plasma 主題面板"
#: ../../plasmoid/contents/ui/ConfigPanel.qml:88
msgid "Use transparency in the panel"
msgstr "在面板中使用漸層"
#: ../../plasmoid/contents/ui/ConfigPanel.qml:95
msgid "Size: "
msgstr "大小:"
#: ../../plasmoid/contents/ui/ContextMenu.qml:115
msgctxt "Play previous track"
msgid "Previous Track"
msgstr "前一軌"
#: ../../plasmoid/contents/ui/ContextMenu.qml:128
msgctxt "Pause playback"
msgid "Pause"
msgstr "暫停"
#: ../../plasmoid/contents/ui/ContextMenu.qml:128
msgctxt "Start playback"
msgid "Play"
msgstr "播放"
#: ../../plasmoid/contents/ui/ContextMenu.qml:139
msgctxt "Stop playback"
msgid "Stop"
msgstr "停止"
#: ../../plasmoid/contents/ui/ContextMenu.qml:147
msgctxt "Play next track"
msgid "Next Track"
msgstr "下一軌"
#: ../../plasmoid/contents/ui/ContextMenu.qml:163
msgctxt "Quit media player app"
msgid "Quit"
msgstr "離開"
#: ../../plasmoid/contents/ui/ContextMenu.qml:178
msgctxt "Open or bring to the front window of media player app"
msgid "Restore"
msgstr "恢復"
#: ../../plasmoid/contents/ui/ContextMenu.qml:223
msgid "Move To Desktop"
msgstr "移動到桌面"
#: ../../plasmoid/contents/ui/ContextMenu.qml:245
msgid "Move To Current Desktop"
msgstr "移到目前桌面"
#: ../../plasmoid/contents/ui/ContextMenu.qml:254
msgid "All Desktops"
msgstr "所有桌面"
#: ../../plasmoid/contents/ui/ContextMenu.qml:283
msgid "New Desktop"
msgstr "新增桌面"
#: ../../plasmoid/contents/ui/ContextMenu.qml:303
msgid "Move To &Activity"
msgstr "移動到活動(&A)"
#: ../../plasmoid/contents/ui/ContextMenu.qml:324
msgid "Add To Current Activity"
msgstr "加入到目前的活動"
#: ../../plasmoid/contents/ui/ContextMenu.qml:334
msgid "All Activities"
msgstr "所有的活動"
#: ../../plasmoid/contents/ui/ContextMenu.qml:403
msgid "Minimize"
msgstr "最小化"
#: ../../plasmoid/contents/ui/ContextMenu.qml:419
msgid "Maximize"
msgstr "最大化"
#: ../../plasmoid/contents/ui/ContextMenu.qml:434
msgid "More Actions"
msgstr "更多動作"
#: ../../plasmoid/contents/ui/ContextMenu.qml:442
msgid "Move"
msgstr "移動"
#: ../../plasmoid/contents/ui/ContextMenu.qml:451
msgid "Resize"
msgstr "調整大小"
#: ../../plasmoid/contents/ui/ContextMenu.qml:460
msgid "Keep Above Others"
msgstr "顯示在最上層"
#: ../../plasmoid/contents/ui/ContextMenu.qml:470
msgid "Keep Below Others"
msgstr "顯示在最下層"
#: ../../plasmoid/contents/ui/ContextMenu.qml:482
msgid "Fullscreen"
msgstr "全螢幕"
#: ../../plasmoid/contents/ui/ContextMenu.qml:494
msgid "Shade"
msgstr "陰影"
#: ../../plasmoid/contents/ui/ContextMenu.qml:509
msgid "Allow this program to be grouped"
msgstr "允許此程式被歸類"
#: ../../plasmoid/contents/ui/ContextMenu.qml:522
msgid "Start New Instance"
msgstr "開啟新的實體"
#: ../../plasmoid/contents/ui/ContextMenu.qml:544
#: ../../plasmoid/contents/ui/ContextMenu.qml:577
msgid "Show Launcher On All Activities"
msgstr "在所有活動中顯示啟動器"
#: ../../plasmoid/contents/ui/ContextMenu.qml:561
msgid "Show Launcher When Not Running"
msgstr "當未執行時顯示啟動器"
#: ../../plasmoid/contents/ui/ContextMenu.qml:588
msgid "Remove Launcher"
msgstr "移除啟動器"
#: ../../plasmoid/contents/ui/ContextMenu.qml:619
msgid "Close"
msgstr "關閉"
#: ../../plasmoid/contents/ui/TaskDelegate.qml:773
msgid "On %1"
msgstr "於 %1"
#: ../../plasmoid/contents/ui/TaskDelegate.qml:782
msgctxt "Which virtual desktop a window is currently on"
msgid "Available on all activities"
msgstr "所有活動都可使用"
#: ../../plasmoid/contents/ui/TaskDelegate.qml:801
msgctxt "Activities a window is currently on (apart from the current one)"
msgid "Also available on %1"
msgstr "也可在 %1 上使用"
#: ../../plasmoid/contents/ui/TaskDelegate.qml:805
msgctxt "Which activities a window is currently on"
msgid "Available on %1"
msgstr "於 %1 上使用"
#: ../../plasmoid/contents/ui/ToolTipDelegate.qml:356
msgctxt "Go to previous song"
msgid "Previous"
msgstr "前一個"
#: ../../plasmoid/contents/ui/ToolTipDelegate.qml:365
msgctxt "Pause player"
msgid "Pause"
msgstr "暫停"
#: ../../plasmoid/contents/ui/ToolTipDelegate.qml:365
msgctxt "Start player"
msgid "Play"
msgstr "啟動"
#: ../../plasmoid/contents/ui/ToolTipDelegate.qml:373
msgctxt "Go to next song"
msgid "Next"
msgstr "下一個"
#: ../../plasmoid/contents/ui/ToolTipWindowMouseArea.qml:57
msgctxt "close this window"
msgid "Close"
msgstr "關閉"
#: rc.cpp:1
msgid "Now Dock"
msgstr "Now Dock"
#: rc.cpp:2
msgid "Switch between running applications"
msgstr "在執行中的應用程式間切換"

17
po/update-metadata.sh Normal file
View File

@ -0,0 +1,17 @@
#!/bin/sh
BASEDIR=".." # root of translatable sources
PROJECT="plasma_applet_org.kde.store.nowdock.panel" # project name
PROJECTPATH="../../containment" # project path
PROJECTPATHPLASMOID="../../plasmoid" # project path
BUGADDR="https://github.com/psifidotos/nowdock-panel/" # MSGID-Bugs
WDIR="`pwd`/containment" # working dir
cd containment
intltool-merge --quiet --desktop-style . ../../containment.metadata.desktop.template "${PROJECTPATH}"/metadata.desktop.cmake
echo "metadata.desktop files for panel were updated..."
cd ../plasmoid
intltool-merge --quiet --desktop-style . ../../plasmoid.metadata.desktop.template "${PROJECTPATHPLASMOID}"/metadata.desktop.cmake
echo "metadata.desktop files for plasmoid were updated..."

View File

@ -0,0 +1,366 @@
/*
* Copyright 2016 Smith AR <audoban@openmailbox.org>
*
* This file is part of Candil-Dock
*
* Candil-Dock is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 3 of
* the License, or (at your option) any later version.
*
* Candil-Dock is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
import QtQuick 2.5
import QtQuick.Window 2.2
import QtQuick.Controls 1.4
import QtQuick.Controls.Styles.Plasma 2.0 as Styles
import QtQuick.Layouts 1.1
import org.kde.plasma.plasmoid 2.0
import org.kde.plasma.core 2.0 as PlasmaCore
import org.kde.plasma.components 2.0 as PlasmaComponents
import org.kde.plasma.extras 2.0 as PlasmaExtras
//import org.candildock.shell 1.0
//import "../controls" as Controls
PlasmaCore.FrameSvgItem {
id: root
imagePath: "dialogs/background"
Component.onCompleted: {
console.log("showing candil dock configuration")
}
property Item dock;
width: content.width + units.largeSpacing * 2
height: content.height + units.smallSpacing * 2
//! BEGIN: UI Components
GridLayout {
id: content
anchors.centerIn: parent
width: implicitWidth
height: implicitHeight
Layout.minimumWidth: width
Layout.minimumHeight: height
rowSpacing: units.smallSpacing
columnSpacing: units.largeSpacing
columns: 2
PlasmaExtras.Heading {
id: appearanceHeading
Layout.columnSpan: 2
Layout.fillWidth: true
text: i18nc("@title:group config ui", "Appearance")
level: 2
}
//! BEGIN: Location
PlasmaComponents.Label {
Layout.row: 1
Layout.alignment: Qt.AlignRight
text: i18nc("@label:listbox config ui", "Location:")
}
PlasmaComponents.ButtonRow {
Layout.fillWidth: true
spacing: 1
exclusive: true
PlasmaComponents.ToolButton {
text: i18nc("@item:inlistbox config ui, location", "Top")
flat: false
checked: dock.location === edge
checkable: true
property int edge: PlasmaCore.Types.TopEdge
}
PlasmaComponents.ToolButton {
text: i18nc("@item:inlistbox config ui, location", "Bottom")
flat: false
checked: dock.location === edge
checkable: true
property int edge: PlasmaCore.Types.BottomEdge
}
PlasmaComponents.ToolButton {
text: i18nc("@item:inlistbox config ui, location", "Left")
flat: false
checked: dock.location === edge
checkable: true
property int edge: PlasmaCore.Types.LeftEdge
}
PlasmaComponents.ToolButton {
text: i18nc("@item:inlistbox config ui, location", "Right")
flat: false
checked: dock.location === edge
checkable: true
property int edge: PlasmaCore.Types.RightEdge
}
onCheckedButtonChanged: {
dock.location = checkedButton.edge
}
}
//! END: Location
//! BEGIN: Alignment
PlasmaComponents.Label {
Layout.row: 2
Layout.alignment: Qt.AlignRight
text: i18nc("@label:listbox config ui", "Alignment:")
}
PlasmaComponents.ButtonRow {
Layout.fillWidth: true
spacing: 1
exclusive: true
PlasmaComponents.ToolButton {
text: i18nc("@item:inlistbox config ui, alignment", "Begin")
flat: false
checked: dock.alignment === align
checkable: true
property int align: Dock.Begin
}
PlasmaComponents.ToolButton {
text: i18nc("@item:inlistbox config ui, alignment", "Center")
flat: false
checked: dock.alignment === align
checkable: true
property int align: Dock.Center
}
PlasmaComponents.ToolButton {
text: i18nc("@item:inlistbox config ui, alignment", "End")
flat: false
checked: dock.alignment === align
checkable: true
property int align: Dock.End
}
PlasmaComponents.ToolButton {
text: i18nc("@item:inlistbox config ui, alignment", "Fill")
flat: false
checked: dock.alignment === align
checkable: true
property int align: Dock.Fill
}
onCheckedButtonChanged: {
dock.alignment = checkedButton.align
}
}
PlasmaComponents.Label {
Layout.row: 3
Layout.alignment: Qt.AlignRight
text: i18nc("@label:slider config ui, align icons",
"Alignment of icons:")
}
RowLayout {
Layout.fillWidth: true
spacing: units.largeSpacing
readonly property int maxOffset: (dock.maxLength - dock.length) / 2
PlasmaComponents.Slider {
id: alignmentSlider
Layout.fillWidth: true
enabled: dock.alignment === Dock.Center
maximumValue: 200
minimumValue: 0
stepSize: 2
Component.onCompleted: {
value = 100 * (dock.offset / parent.maxOffset + 1)
dock.offset = Qt.binding(function () {
return parent.maxOffset * (value / 100 - 1)
})
}
updateValueWhileDragging: true
}
PlasmaComponents.Label {
Layout.alignment: Qt.AlignLeft
Layout.minimumWidth: theme.mSize(theme.defaultFont).width * 4
Layout.maximumWidth: Layout.minimumWidth
horizontalAlignment: Text.AlignLeft
text: i18nc("@label:slider percent", "%1%", (100 * dock.offset / parent.maxOffset) | 0)
}
}
//! END: Alignment
//! BEGIN: Icons
PlasmaComponents.Label {
Layout.row: 4
Layout.alignment: Qt.AlignRight
text: i18nc("@label:spinbox config ui, size icons", "Size icons:")
}
RowLayout {
Layout.fillWidth: true
spacing: units.largeSpacing
/* Controls.SpinBox {
suffix: i18nc(
"@item:spinbox config ui, size icons, suffix in pixels",
" pixels")
maximumValue: 128
minimumValue: 48
stepSize: 2
value: dock.iconSize
onValueChanged: {
dock.iconSize = value
}
}*/
PlasmaComponents.Label {
text: i18nc("@label:slider config ui, icons zoom", "Zoom:")
Layout.alignment: Qt.AlignRight
}
PlasmaComponents.Slider {
Layout.fillWidth: true
value: 100
maximumValue: 200
minimumValue: 100
stepSize: 1
updateValueWhileDragging: true
Component.onCompleted: {
value = (dock.zoomFactor * 100) | 0
dock.zoomFactor = Qt.binding(function(){
return value / 100
})
}
}
}
//! END: Icons
PlasmaExtras.Heading {
Layout.row: 5
Layout.columnSpan: 2
Layout.fillWidth: true
text: i18nc("@title:group config ui", "Behavior")
level: 2
}
//! BEGIN: Visibility
PlasmaComponents.Label {
Layout.row: 6
Layout.alignment: Qt.AlignRight
text: i18nc("@label:listbox config ui", "Visibility:")
}
PlasmaComponents.ComboBox {
Layout.fillWidth: true
model: [i18nc("@item:inlistbox config ui, visibility",
"Normal"), i18nc(
"@item:inlistbox config ui, visibility",
"Auto hide"), i18nc(
"@item:inlistbox config ui, visibility",
"Dodge active window"), i18nc(
"@item:inlistbox config ui, visibility", "Dodge windows")]
currentIndex: dock.visibility.mode
onActivated: {
dock.visibility.mode = index
}
}
RowLayout {
Layout.row: 7
Layout.column: 1
Layout.fillWidth: true
spacing: units.largeSpacing
PlasmaComponents.Label {
Layout.fillWidth: false
horizontalAlignment: Text.AlignRight
text: i18nc("@label:spinbox config ui, timers",
"Delay in show:")
}
/* Controls.SpinBox {
enabled: dock.visibility.mode !== Dock.Normal
Layout.fillWidth: false
Layout.maximumWidth: implicitWidth
maximumValue: 3000
minimumValue: 0
value: dock.visibility.timerShow
stepSize: 100
onValueChanged: {
dock.visibility.timerShow = value
}
suffix: i18nc(
"@item:spinbox config ui, suffix in milliseconds",
" ms")
}*/
PlasmaComponents.Label {
Layout.fillWidth: true
horizontalAlignment: Text.AlignRight
text: i18nc("@label:spinbox config ui, timers",
"Delay in hidding:")
}
/* Controls.SpinBox {
enabled: dock.visibility.mode !== Dock.Normal
Layout.fillWidth: false
Layout.maximumWidth: implicitWidth
maximumValue: 3000
minimumValue: 0
value: dock.visibility.timerHide
stepSize: 100
onValueChanged: {
dock.visibility.timerHide = value
}
suffix: i18nc(
"@item:spinbox config ui, suffix in milliseconds",
" ms")
}*/
}
RowLayout {
Layout.row: 8
Layout.column: 1
Layout.fillWidth: true
spacing: units.largeSpacing
PlasmaComponents.Label {
text: i18nc("@option:check config ui", "Show in all screens:")
Layout.alignment: Qt.AlignRight
}
Switch {
id: switchScreen
// TODO: Show on all screens
style: Styles.SwitchStyle {
property bool checked: switchScreen.checked
}
}
PlasmaComponents.ComboBox {
Layout.fillWidth: true
Component.onCompleted: {
var screens = []
for (var i = 0; i < dock.screens.length; i++) {
screens.push(dock.screens[i].name)
}
model = screens
}
}
}
//! END: Visibility
}
//! END: UI Components
}

View File

@ -0,0 +1,606 @@
import QtQuick 2.0
import QtQuick.Controls 1.4
import QtQuick.Layouts 1.3
import QtGraphicalEffects 1.0
import org.kde.plasma.core 2.0 as PlasmaCore
import org.kde.plasma.components 2.0 as PlasmaComponents
import org.kde.plasma.plasmoid 2.0
import org.kde.nowdock 0.1 as NowDock
PlasmaCore.FrameSvgItem {
imagePath: "dialogs/background"
width: Math.max(420,noneShadow.width + lockedAppletsShadow.width + allAppletsShadow.width)
height: mainColumn.height+10
property bool panelIsVertical: plasmoid.formFactor === PlasmaCore.Types.Vertical
signal updateThickness();
signal removeInternalViewSplitter();
signal addInternalViewSplitter();
Column{
id:mainColumn
anchors.horizontalCenter: parent.horizontalCenter
spacing: 1.5*theme.defaultFont.pointSize
width: parent.width - 10
Column{
width:parent.width
spacing: 0.8*theme.defaultFont.pointSize
RowLayout{
width: parent.width
PlasmaComponents.Label{
text: i18n("Applets Alignment")
font.pointSize: 1.5 * theme.defaultFont.pointSize
Layout.alignment: Qt.AlignLeft
}
PlasmaComponents.Label{
font.pointSize: theme.defaultFont.pointSize
font.italic: true
opacity: 0.6
Layout.alignment: Qt.AlignRight
horizontalAlignment: Text.AlignRight
// width: parent.width
text: i18n("ver: ") +"@VERSION@"
}
}
//user set Panel Positions
// 0-Center, 1-Left, 2-Right, 3-Top, 4-Bottom
Flow{
width: parent.width
spacing: 2
property bool inStartup: true
property int panelPosition: plasmoid.configuration.panelPosition
function updatePanelPositionVisual(){
if((panelPosition == NowDock.Types.Left)||(panelPosition == NowDock.Types.Top)){
firstPosition.checked = true;
centerPosition.checked = false;
lastPosition.checked = false;
splitTwoPosition.checked = false;
removeInternalViewSplitter();
}
else if(panelPosition == NowDock.Types.Center){
firstPosition.checked = false;
centerPosition.checked = true;
lastPosition.checked = false;
splitTwoPosition.checked = false;
removeInternalViewSplitter();
}
else if((panelPosition == NowDock.Types.Right)||(panelPosition == NowDock.Types.Bottom)){
firstPosition.checked = false;
centerPosition.checked = false;
lastPosition.checked = true;
splitTwoPosition.checked = false;
removeInternalViewSplitter();
}
else if (panelPosition == NowDock.Types.Double){
firstPosition.checked = false;
centerPosition.checked = false;
lastPosition.checked = false;
splitTwoPosition.checked = true;
//add the splitter visual
addInternalViewSplitter(-1);
}
}
onPanelPositionChanged: updatePanelPositionVisual();
Component.onCompleted: {
updatePanelPositionVisual();
inStartup = false;
}
PlasmaComponents.Button{
id: firstPosition
checkable: true
text: panelIsVertical ? i18n("Top") : i18n("Left")
width: (parent.width / 3) - 1
onCheckedChanged: {
if(checked && !parent.inStartup){
if(panelIsVertical)
plasmoid.configuration.panelPosition = NowDock.Types.Top
else
plasmoid.configuration.panelPosition = NowDock.Types.Left
}
}
onClicked: checked=true;
}
PlasmaComponents.Button{
id: centerPosition
checkable: true
text: i18n("Center")
width: (parent.width / 3) - 1
onCheckedChanged: {
if(checked && !parent.inStartup){
plasmoid.configuration.panelPosition = NowDock.Types.Center
}
}
onClicked: checked=true;
}
PlasmaComponents.Button{
id: lastPosition
checkable: true
text: panelIsVertical ? i18n("Bottom") : i18n("Right")
width: (parent.width / 3) - 2
onCheckedChanged: {
if(checked && !parent.inStartup){
if(panelIsVertical)
plasmoid.configuration.panelPosition = NowDock.Types.Bottom
else
plasmoid.configuration.panelPosition = NowDock.Types.Right
}
}
onClicked: checked=true;
}
PlasmaComponents.Button{
id: splitTwoPosition
checkable: true
text: panelIsVertical ? i18n("Top")+ " | "+ i18n("Bottom") : i18n("Left") +" | "+ i18n("Right")
width: parent.width
onCheckedChanged: {
if(checked && !parent.inStartup){
plasmoid.configuration.panelPosition = NowDock.Types.Double;
}
}
onClicked: checked=true;
}
}
}
// BelowActive = 0, /** always visible except if ovelaps with the active window, no area reserved */
// BelowMaximized, /** always visible except if ovelaps with an active maximize window, no area reserved */
// LetWindowsCover, /** always visible, windows will go over the panel, no area reserved */
// WindowsGoBelow, /** default, always visible, windows will go under the panel, no area reserved */
// AutoHide, /** the panel will be shownn only if the mouse cursor is on screen edges */
// AlwaysVisible, /** always visible panel, "Normal" plasma panel, accompanies plasma's "Always Visible" */
/********** Panel Visibility ****************/
Column{
width:parent.width
spacing: 0.8*theme.defaultFont.pointSize
PlasmaComponents.Label{
text: i18n("Visibility")
font.pointSize: 1.5 * theme.defaultFont.pointSize
}
//user set Panel Visibility
// 0-BelowActive, 1-BelowMaximized, 2-LetWindowsCover, 3-WindowsGoBelow, 4-AutoHide, 5-AlwaysVisible
Flow{
width: parent.width
spacing: 2
property bool inStartup: true
property int panelVisibility: plasmoid.configuration.panelVisibility
function updatePanelVisibilityVisual(){
if (panelVisibility === 0)
firstState.checked = true;
else
firstState.checked = false;
if (panelVisibility === 1)
secondState.checked = true;
else
secondState.checked = false;
if (panelVisibility === 2)
thirdState.checked = true;
else
thirdState.checked = false;
if (panelVisibility === 3)
fourthState.checked = true;
else
fourthState.checked = false;
if (panelVisibility === 4)
fifthState.checked = true;
else
fifthState.checked = false;
if (panelVisibility === 5)
sixthState.checked = true;
else
sixthState.checked = false;
}
onPanelVisibilityChanged: updatePanelVisibilityVisual();
Component.onCompleted: {
updatePanelVisibilityVisual();
inStartup = false;
}
PlasmaComponents.Button{
id: firstState
checkable: true
text: i18n("Below Active")
width: (parent.width / 2) - 1
onCheckedChanged: {
if(checked && !parent.inStartup){
plasmoid.configuration.panelVisibility = 0
}
}
onClicked: checked=true;
}
PlasmaComponents.Button{
id: secondState
checkable: true
text: i18n("Below Maximized")
width: (parent.width / 2) - 1
onCheckedChanged: {
if(checked && !parent.inStartup){
plasmoid.configuration.panelVisibility = 1
}
}
onClicked: checked=true;
}
PlasmaComponents.Button{
id: thirdState
checkable: true
text: i18n("Let Windows Cover")
width: (parent.width / 2) - 1
onCheckedChanged: {
if(checked && !parent.inStartup){
plasmoid.configuration.panelVisibility = 2
}
}
onClicked: checked=true;
}
PlasmaComponents.Button{
id: fourthState
checkable: true
text: i18n("Windows Go Below")
width: (parent.width/2) - 1
onCheckedChanged: {
if(checked && !parent.inStartup){
plasmoid.configuration.panelVisibility = 3
}
}
onClicked: checked=true;
}
PlasmaComponents.Button{
id: fifthState
checkable: true
text: i18n("Auto Hide")
width: (parent.width/2) - 1
onCheckedChanged: {
if(checked && !parent.inStartup){
plasmoid.configuration.panelVisibility = 4
}
}
onClicked: checked=true;
}
PlasmaComponents.Button{
id: sixthState
checkable: true
text: i18n("Always Visible")
width: (parent.width/2) - 1
onCheckedChanged: {
if(checked && !parent.inStartup){
plasmoid.configuration.panelVisibility = 5
}
}
onClicked: checked=true;
}
}
}
//////////////// Applets Size
Column{
width:parent.width
spacing: 0.8*theme.defaultFont.pointSize
PlasmaComponents.Label{
text: i18n("Applets Size")
font.pointSize: 1.5 * theme.defaultFont.pointSize
}
RowLayout{
width: parent.width
property int step: 8
PlasmaComponents.Button{
text:"-"
Layout.preferredWidth: parent.height
Layout.preferredHeight: parent.height
onClicked: appletsSizeSlider.value -= parent.step
}
PlasmaComponents.Slider{
id:appletsSizeSlider
valueIndicatorText: i18n("Applets Size")
valueIndicatorVisible: true
minimumValue: 16
maximumValue: 128
stepSize: parent.step
Layout.fillWidth:true
property bool inStartup:true
Component.onCompleted: {
value = plasmoid.configuration.iconSize;
inStartup = false;
}
onValueChanged:{
if(!inStartup){
plasmoid.configuration.iconSize = value;
updateThickness();
}
}
}
PlasmaComponents.Button{
text:"+"
Layout.preferredWidth: parent.height
Layout.preferredHeight: parent.height
onClicked: appletsSizeSlider.value += parent.step;
}
PlasmaComponents.Label{
text: plasmoid.configuration.iconSize + " px."
}
}
}
/********** Zoom On Hover ****************/
Column{
width: parent.width
spacing: 0.8*theme.defaultFont.pointSize
PlasmaComponents.Label{
text: i18n("Zoom On Hover")
font.pointSize: 1.5 * theme.defaultFont.pointSize
}
RowLayout{
width: parent.width
PlasmaComponents.Button{
text:"-"
Layout.preferredWidth: parent.height
Layout.preferredHeight: parent.height
onClicked: zoomSlider.value -= 0.05
}
PlasmaComponents.Slider{
id:zoomSlider
valueIndicatorText: i18n("Zoom Factor")
valueIndicatorVisible: true
minimumValue: 1
maximumValue: 2
stepSize: 0.05
Layout.fillWidth:true
property bool inStartup:true
Component.onCompleted: {
value = Number(1 + plasmoid.configuration.zoomLevel/20).toFixed(2)
inStartup = false;
// console.log("Slider:"+value);
}
onValueChanged:{
if(!inStartup){
var result = Math.round((value - 1)*20)
plasmoid.configuration.zoomLevel = result
// console.log("Store:"+result);
}
}
}
PlasmaComponents.Button{
text:"+"
Layout.preferredWidth: parent.height
Layout.preferredHeight: parent.height
onClicked: zoomSlider.value += 0.05
}
PlasmaComponents.Label{
enabled: showBackground.checked
text: " "+Number(zoomSlider.value).toFixed(2)
}
}
}
Column{
width: parent.width
spacing: 0.8*theme.defaultFont.pointSize
PlasmaComponents.Label{
text: i18n("Background")
font.pointSize: 1.5 * theme.defaultFont.pointSize
}
PlasmaComponents.CheckBox{
id: showBackground
text: i18n("Show Panel Background")
property bool inStartup: true
onCheckedChanged:{
if(!inStartup)
plasmoid.configuration.useThemePanel = checked;
}
Component.onCompleted: {
checked = plasmoid.configuration.useThemePanel;
inStartup = false;
}
}
RowLayout{
width: parent.width
PlasmaComponents.Button{
enabled: showBackground.checked
text:"-"
Layout.preferredWidth: parent.height
Layout.preferredHeight: parent.height
onClicked: panelSizeSlider.value -= 2
}
PlasmaComponents.Slider{
id:panelSizeSlider
enabled: showBackground.checked
valueIndicatorText: i18n("Size")
valueIndicatorVisible: true
minimumValue: 0
maximumValue: 256
stepSize: 2
Layout.fillWidth:true
property bool inStartup: true
Component.onCompleted: {
value = plasmoid.configuration.panelSize
inStartup = false;
}
onValueChanged: {
if(!inStartup)
plasmoid.configuration.panelSize = value;
}
}
PlasmaComponents.Button{
enabled: showBackground.checked
text:"+"
Layout.preferredWidth: parent.height
Layout.preferredHeight: parent.height
onClicked: panelSizeSlider.value += 2
}
PlasmaComponents.Label{
enabled: showBackground.checked
text: panelSizeSlider.value + " px."
}
}
}
Column{
width: parent.width
spacing: 0.8*theme.defaultFont.pointSize
PlasmaComponents.Label{
text: i18n("Shadows")
font.pointSize: 1.5 * theme.defaultFont.pointSize
}
RowLayout {
width: parent.width
ExclusiveGroup {
id: shadowsGroup
property bool inStartup: true
onCurrentChanged: {
if (!inStartup) {
if (current === noneShadow){
plasmoid.configuration.shadows = 0; /*No Shadows*/
} else if (current === lockedAppletsShadow){
plasmoid.configuration.shadows = 1; /*Locked Applets Shadows*/
} else if (current === allAppletsShadow){
plasmoid.configuration.shadows = 2; /*All Applets Shadows*/
}
}
}
Component.onCompleted: {
if (plasmoid.configuration.shadows === 0 /*No Shadows*/){
noneShadow.checked = true;
} else if (plasmoid.configuration.shadows === 1 /*Locked Applets*/) {
lockedAppletsShadow.checked = true;
} else if (plasmoid.configuration.shadows === 2 /*All Applets*/) {
allAppletsShadow.checked = true;
}
inStartup = false;
}
}
PlasmaComponents.RadioButton {
id: noneShadow
text: i18n("None")
exclusiveGroup: shadowsGroup
}
PlasmaComponents.RadioButton {
id: lockedAppletsShadow
text: i18n("Only for locked applets")
exclusiveGroup: shadowsGroup
}
PlasmaComponents.RadioButton {
id: allAppletsShadow
text: i18n("All applets")
exclusiveGroup: shadowsGroup
}
}
}
PlasmaComponents.Button{
enabled: true
text: i18n("Add New Dock")
onClicked: dock.addNewDock();
}
}
}

View File

@ -0,0 +1,30 @@
/*
* Copyright 2016 Smith AR <audoban@openmailbox.org>
*
* This file is part of Candil-Dock
*
* Candil-Dock is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 3 of
* the License, or (at your option) any later version.
*
* Candil-Dock is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
import QtQuick 2.0
import org.kde.plasma.configuration 2.0
ConfigModel {
ConfigCategory {
name: i18n("General")
icon: "preferences-system-windows"
source: "NowDockConfiguration.qml"
}
}

View File

@ -0,0 +1,114 @@
/*
* Copyright 2012 Marco Martin <mart@kde.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 2.010-1301, USA.
*/
import QtQuick 2.0
import QtQuick.Layouts 1.1
import org.kde.plasma.core 2.0 as PlasmaCore
PlasmaCore.FrameSvgItem {
id: root
//imagePath: containment && containment.backgroundHints === PlasmaCore.Types.NoBackground ? "" : "widgets/panel-background"
//imagePath: "widgets/panel-background"
imagePath: ""
prefix:""
// onRepaintNeeded: adjustPrefix();
//enabledBorders: panel.enabledBorders
property Item containment
property Item dockLayout
readonly property bool verticalPanel: containment && containment.formFactor === PlasmaCore.Types.Vertical
/* Rectangle{
anchors.fill: parent
color: "transparent"
border.color: "blue"
border.width: 1
}*/
function adjustPrefix() {
if (!containment) {
return "";
}
var pre;
switch (containment.location) {
case PlasmaCore.Types.LeftEdge:
pre = "west";
break;
case PlasmaCore.Types.TopEdge:
pre = "north";
break;
case PlasmaCore.Types.RightEdge:
pre = "east";
break;
case PlasmaCore.Types.BottomEdge:
pre = "south";
break;
default:
prefix = "";
}
if (hasElementPrefix(pre)) {
prefix = pre;
} else {
prefix = "";
}
}
onContainmentChanged: {
if (!containment) {
return;
}
containment.parent = containmentParent;
containment.visible = true;
containment.anchors.fill = containmentParent;
containment.locationChanged.connect(adjustPrefix);
adjustPrefix();
for(var i=0; i<containment.children.length; ++i){
if (containment.children[i].objectName === "dockLayoutView") {
dockLayout = containment.children[i];
dockLayout.dockView = panel;
}
}
}
Binding {
target: panel
property: "length"
when: containment
value: {
if (!containment) {
return;
}
if (verticalPanel) {
return containment.Layout.preferredHeight
} else {
return containment.Layout.preferredWidth
}
}
}
Item {
id: containmentParent
anchors.fill: parent
}
}

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