Add support for auto-generated widget bindings
Additionally fix an update problem occurring with custom views
This commit is contained in:
parent
e5b5459d42
commit
d8de611510
8
.github/ISSUE_TEMPLATE/component_request.yml
vendored
8
.github/ISSUE_TEMPLATE/component_request.yml
vendored
@ -12,14 +12,6 @@ body:
|
||||
validations:
|
||||
required: false
|
||||
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Name the equivalents in Libadwaita.
|
||||
placeholder: >-
|
||||
A list of the equivalents in the Libadwaita library (see dependencies).
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Describe your idea for the implementation.
|
||||
|
@ -160,3 +160,6 @@ type_contents_order:
|
||||
- view_life_cycle_method
|
||||
- ib_action
|
||||
- other_method
|
||||
|
||||
excluded:
|
||||
- Sources/Adwaita/View/Generated/
|
@ -36,6 +36,8 @@ Open the project folder in GNOME Builder, Xcode or another IDE.
|
||||
- `User Interface` contains protocols and structures that are the basis of presenting content to the user.
|
||||
- `View` contains structures that conform to the `View` protocol and provide an easier-to-use wrapper around a GTUI `NativeWidgetPeer` type.
|
||||
- `Window` contains structures that conform to the `Window` protocol and simplify the creation of different types of windows.
|
||||
- `CAdw` contains the reference to the C library.
|
||||
- `Generation` contains the code for the auto-generation of Adwaita and Gtk widgets.
|
||||
- `Tests` contains an example application for testing `Adwaita`.
|
||||
|
||||
### 4. Edit the Code
|
||||
|
696
LICENSE.md
696
LICENSE.md
@ -1,675 +1,21 @@
|
||||
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:
|
||||
|
||||
<program> Copyright (C) <year> <name of author>
|
||||
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>.
|
||||
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2024 david-swift
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
@ -15,25 +15,39 @@ let package = Package(
|
||||
.library(
|
||||
name: "Adwaita",
|
||||
targets: ["Adwaita"]
|
||||
),
|
||||
.library(
|
||||
name: "CAdw",
|
||||
targets: ["CAdw"]
|
||||
)
|
||||
],
|
||||
dependencies: [
|
||||
.package(url: "https://github.com/AparokshaUI/Libadwaita", from: "0.1.6"),
|
||||
.package(
|
||||
url: "https://github.com/david-swift/LevenshteinTransformations",
|
||||
from: "0.1.1"
|
||||
)
|
||||
),
|
||||
.package(url: "https://github.com/CoreOffice/XMLCoder", from: "0.17.1")
|
||||
],
|
||||
targets: [
|
||||
.systemLibrary(
|
||||
name: "CAdw",
|
||||
pkgConfig: "libadwaita-1"
|
||||
),
|
||||
.target(
|
||||
name: "Adwaita",
|
||||
dependencies: [
|
||||
.product(name: "Libadwaita", package: "Libadwaita"),
|
||||
"CAdw",
|
||||
.product(name: "LevenshteinTransformations", package: "LevenshteinTransformations")
|
||||
]
|
||||
),
|
||||
.executableTarget(
|
||||
name: "Swift Adwaita Demo",
|
||||
name: "Generation",
|
||||
dependencies: [
|
||||
.product(name: "XMLCoder", package: "XMLCoder")
|
||||
]
|
||||
),
|
||||
.executableTarget(
|
||||
name: "Demo",
|
||||
dependencies: ["Adwaita"],
|
||||
path: "Tests"
|
||||
)
|
||||
|
10
README.md
10
README.md
@ -1,6 +1,6 @@
|
||||
<p align="center">
|
||||
<img width="256" alt="Adwaita Icon" src="Icons/AdwaitaIcon.png">
|
||||
<h1 align="center">Adwaita</h1>
|
||||
<h1 align="center">Adwaita for Swift</h1>
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
@ -110,15 +110,17 @@ I recommend using the [template repository](https://github.com/AparokshaUI/Adwai
|
||||
### Information
|
||||
|
||||
* [Widgets](user-manual/Information/Widgets.md)
|
||||
* [Auto-Generated Widgets](user-manual/Information/AutoGeneratedWidgets.md)
|
||||
|
||||
## Thanks
|
||||
|
||||
### Dependencies
|
||||
- [Libadwaita][18] licensed under the [GPL-3.0 license][19]
|
||||
- [XMLCoder][18] licensed under the [MIT license][19]
|
||||
- [Levenshtein Transformations](https://github.com/david-swift/LevenshteinTransformations) licensed under the [MIT license](https://github.com/david-swift/LevenshteinTransformations/blob/main/LICENSE.md)
|
||||
|
||||
### Other Thanks
|
||||
- The [contributors][20]
|
||||
- The auto-generation of widgets is based on [Swift Cross UI](https://github.com/stackotter/swift-cross-ui)
|
||||
- [SwiftLint][21] for checking whether code style conventions are violated
|
||||
- The programming language [Swift][22]
|
||||
- [SourceDocs][23] used for generating the [docs][24]
|
||||
@ -140,8 +142,8 @@ I recommend using the [template repository](https://github.com/AparokshaUI/Adwai
|
||||
[15]: user-manual/Basics/Windows.md
|
||||
[16]: user-manual/Basics/KeyboardShortcuts.md
|
||||
[17]: user-manual/Advanced/CreatingWidgets.md
|
||||
[18]: https://github.com/AparokshaUI/Libadwaita
|
||||
[19]: https://github.com/AparokshaUI/Libadwaita/blob/main/LICENSE.md
|
||||
[18]: https://github.com/CoreOffice/XMLCoder
|
||||
[19]: https://github.com/CoreOffice/XMLCoder/blob/main/LICENSE
|
||||
[20]: Contributors.md
|
||||
[21]: https://github.com/realm/SwiftLint
|
||||
[22]: https://github.com/apple/swift
|
||||
|
@ -17,6 +17,7 @@
|
||||
## Information
|
||||
|
||||
* [Widgets](user-manual/Information/Widgets.md)
|
||||
* [Auto-Generated Widgets](user-manual/Information/AutoGeneratedWidgets.md)
|
||||
|
||||
[1]: README.md
|
||||
[2]: user-manual/GettingStarted.md
|
||||
|
@ -5,7 +5,7 @@
|
||||
// Created by david-swift on 22.10.23.
|
||||
//
|
||||
|
||||
import Libadwaita
|
||||
import CAdw
|
||||
|
||||
/// A button widget for menus.
|
||||
public struct MenuButton: MenuItem {
|
||||
@ -19,6 +19,9 @@ public struct MenuButton: MenuItem {
|
||||
/// Whether to prefer adding the action to the application window.
|
||||
var preferApplicationWindow: Bool
|
||||
|
||||
/// The action label.
|
||||
var filteredLabel: String { label.filter { $0.isLetter || $0.isNumber || $0 == "-" || $0 == "." } }
|
||||
|
||||
/// Initialize a menu button.
|
||||
/// - Parameters:
|
||||
/// - label: The buttons label.
|
||||
@ -35,11 +38,13 @@ public struct MenuButton: MenuItem {
|
||||
/// - menu: The menu.
|
||||
/// - app: The application containing the menu.
|
||||
/// - window: The application window containing the menu.
|
||||
public func addMenuItem(menu: Libadwaita.Menu, app: GTUIApp, window: GTUIApplicationWindow?) {
|
||||
public func addMenuItem(menu: OpaquePointer?, app: GTUIApp, window: GTUIApplicationWindow?) {
|
||||
if let window, preferApplicationWindow {
|
||||
_ = menu.append(label, window: window, shortcut: shortcut, handler: handler)
|
||||
window.addKeyboardShortcut(shortcut, id: filteredLabel, handler: handler)
|
||||
g_menu_append(menu, label, "win." + filteredLabel)
|
||||
} else {
|
||||
_ = menu.append(label, app: app, shortcut: shortcut, handler: handler)
|
||||
app.addKeyboardShortcut(shortcut, id: filteredLabel, handler: handler)
|
||||
g_menu_append(menu, label, "app." + filteredLabel)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -5,7 +5,7 @@
|
||||
// Created by david-swift on 22.10.23.
|
||||
//
|
||||
|
||||
import Libadwaita
|
||||
import CAdw
|
||||
|
||||
/// A section for menus.
|
||||
public struct MenuSection: MenuItem {
|
||||
@ -24,9 +24,9 @@ public struct MenuSection: MenuItem {
|
||||
/// - menu: The menu.
|
||||
/// - app: The application containing the menu.
|
||||
/// - window: The application window containing the menu.
|
||||
public func addMenuItem(menu: Libadwaita.Menu, app: GTUIApp, window: GTUIApplicationWindow?) {
|
||||
let section = Libadwaita.Menu()
|
||||
_ = menu.append("", section: section)
|
||||
public func addMenuItem(menu: OpaquePointer?, app: GTUIApp, window: GTUIApplicationWindow?) {
|
||||
let section = g_menu_new()
|
||||
g_menu_append_section(menu, nil, section?.cast())
|
||||
for element in sectionContent {
|
||||
element.addMenuItems(menu: section, app: app, window: window)
|
||||
}
|
||||
|
@ -5,7 +5,7 @@
|
||||
// Created by david-swift on 22.10.23.
|
||||
//
|
||||
|
||||
import Libadwaita
|
||||
import CAdw
|
||||
|
||||
/// A submenu widget.
|
||||
public struct Submenu: MenuItem {
|
||||
@ -29,9 +29,9 @@ public struct Submenu: MenuItem {
|
||||
/// - menu: The menu.
|
||||
/// - app: The application containing the menu.
|
||||
/// - window: The application window containing the menu.
|
||||
public func addMenuItem(menu: Libadwaita.Menu, app: GTUIApp, window: GTUIApplicationWindow?) {
|
||||
let submenu = Libadwaita.Menu()
|
||||
_ = menu.append(label, submenu: submenu)
|
||||
public func addMenuItem(menu: OpaquePointer?, app: GTUIApp, window: GTUIApplicationWindow?) {
|
||||
let submenu = g_menu_new()
|
||||
g_menu_append_submenu(menu, label, submenu?.cast())
|
||||
for element in submenuContent {
|
||||
element.addMenuItems(menu: submenu, app: app, window: window)
|
||||
}
|
||||
|
@ -9,8 +9,6 @@
|
||||
// https://gist.github.com/JadenGeller/c375fc15ad5900a0ddac4ed8ba8307a9
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
/// The ``ArrayBuilder`` is a simple result builder that outputs an array of any type.
|
||||
///
|
||||
/// You can define any array using Swift's DSL:
|
||||
|
@ -5,8 +5,8 @@
|
||||
// Created by david-swift on 06.08.23.
|
||||
//
|
||||
|
||||
import CAdw
|
||||
import Foundation
|
||||
import Libadwaita
|
||||
|
||||
/// A property wrapper for properties in a view that should be stored throughout view updates.
|
||||
@propertyWrapper
|
||||
@ -110,11 +110,23 @@ public struct State<Value>: StateProtocol {
|
||||
}
|
||||
}
|
||||
|
||||
/// The directory used for storing user data.
|
||||
/// - Returns: The URL.
|
||||
public static func userDataDir() -> URL {
|
||||
.init(fileURLWithPath: .init(cString: g_get_user_data_dir()))
|
||||
}
|
||||
|
||||
/// Copy a text to the clipboard.
|
||||
/// - Parameter text: The text.
|
||||
public static func copy(_ text: String) {
|
||||
let clipboard = gdk_display_get_clipboard(gdk_display_get_default())
|
||||
gdk_clipboard_set_text(clipboard, text)
|
||||
}
|
||||
|
||||
/// Get the settings directory path.
|
||||
/// - Returns: The path.
|
||||
private func dirPath() -> URL {
|
||||
NativePeer
|
||||
.getUserDataDirectory()
|
||||
Self.userDataDir()
|
||||
.appendingPathComponent(content.storage.folder ?? GTUIApp.appID, isDirectory: true)
|
||||
}
|
||||
|
||||
|
44
Sources/Adwaita/Model/Enumerations/Alignment.swift
Normal file
44
Sources/Adwaita/Model/Enumerations/Alignment.swift
Normal file
@ -0,0 +1,44 @@
|
||||
//
|
||||
// Alignment.swift
|
||||
// Adwaita
|
||||
//
|
||||
// Created by david-swift on 21.01.24.
|
||||
//
|
||||
|
||||
import CAdw
|
||||
|
||||
/// The alignment for a widget.
|
||||
public enum Alignment: Int {
|
||||
|
||||
/// The widget will fill the available space.
|
||||
case fill
|
||||
/// The widget will start at the beginning of the available space.
|
||||
case start
|
||||
/// The widget will end at the end of the available space.
|
||||
case end
|
||||
/// The widget will be centered in the available space.
|
||||
case center
|
||||
/// The widget will be baseline aligned in the available space.
|
||||
case baselineFill
|
||||
/// The widget will be baseline aligned at the start of the available space.
|
||||
case baselineCenter
|
||||
|
||||
/// Get the GtkAlign alignment.
|
||||
public var cAlign: GtkAlign {
|
||||
switch self {
|
||||
case .fill:
|
||||
return GTK_ALIGN_FILL
|
||||
case .start:
|
||||
return GTK_ALIGN_START
|
||||
case .end:
|
||||
return GTK_ALIGN_END
|
||||
case .center:
|
||||
return GTK_ALIGN_CENTER
|
||||
case .baselineFill:
|
||||
return GTK_ALIGN_BASELINE_FILL
|
||||
case .baselineCenter:
|
||||
return GTK_ALIGN_BASELINE_CENTER
|
||||
}
|
||||
}
|
||||
|
||||
}
|
20
Sources/Adwaita/Model/Enumerations/Edge.swift
Normal file
20
Sources/Adwaita/Model/Enumerations/Edge.swift
Normal file
@ -0,0 +1,20 @@
|
||||
//
|
||||
// Edge.swift
|
||||
// Adwaita
|
||||
//
|
||||
// Created by david-swift on 21.01.24.
|
||||
//
|
||||
|
||||
/// The edges for a widget.
|
||||
public enum Edge {
|
||||
|
||||
/// The leading (start) edge.
|
||||
case leading
|
||||
/// The trailing (end) edge.
|
||||
case trailing
|
||||
/// The top edge.
|
||||
case top
|
||||
/// The bottom edge.
|
||||
case bottom
|
||||
|
||||
}
|
767
Sources/Adwaita/Model/Enumerations/Icon.swift
Normal file
767
Sources/Adwaita/Model/Enumerations/Icon.swift
Normal file
@ -0,0 +1,767 @@
|
||||
//
|
||||
// Icon.swift
|
||||
// Adwaita
|
||||
//
|
||||
// Created by david-swift on 21.01.24.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
// swiftlint:disable type_body_length file_length
|
||||
/// An icon.
|
||||
public enum Icon {
|
||||
|
||||
/// A preinstalled icon.
|
||||
/// - Parameter icon: The default icon.
|
||||
case `default`(icon: DefaultIcon)
|
||||
/// A custom icon.
|
||||
/// - Parameter name: The icon's name.
|
||||
case custom(name: String)
|
||||
|
||||
/// A string representation of the icon.
|
||||
public var string: String {
|
||||
switch self {
|
||||
case let .default(icon):
|
||||
return icon.string
|
||||
case let .custom(name):
|
||||
return name
|
||||
}
|
||||
}
|
||||
|
||||
/// A preinstalled icon.
|
||||
public enum DefaultIcon: String {
|
||||
// swiftlint:disable missing_docs identifier_name
|
||||
case acAdapter
|
||||
case accessoriesCalculator
|
||||
case accessoriesCharacterMap
|
||||
case accessoriesDictionary
|
||||
case accessoriesTextEditor
|
||||
case actionUnavailable
|
||||
case addressBookNew
|
||||
case airplaneMode
|
||||
case alarm
|
||||
case appRemove
|
||||
case appletsScreenshooter
|
||||
case applicationCertificate
|
||||
case applicationExitRtl
|
||||
case applicationExit
|
||||
case applicationRss_plus_xml
|
||||
case applicationXAddon
|
||||
case applicationXAppliance
|
||||
case applicationXExecutable
|
||||
case applicationXFirmware
|
||||
case applicationXSharedlib
|
||||
case applicationsEngineering
|
||||
case applicationsGames
|
||||
case applicationsGraphics
|
||||
case applicationsMultimedia
|
||||
case applicationsScience
|
||||
case applicationsSystem
|
||||
case applicationsUtilities
|
||||
case appointmentMissed
|
||||
case appointmentNew
|
||||
case appointmentSoon
|
||||
case audioCard
|
||||
case audioHeadphones
|
||||
case audioHeadset
|
||||
case audioInputMicrophone
|
||||
case audioSpeakersRtl
|
||||
case audioSpeakers
|
||||
case audioVolumeHighRtl
|
||||
case audioVolumeHigh
|
||||
case audioVolumeLowRtl
|
||||
case audioVolumeLow
|
||||
case audioVolumeMediumRtl
|
||||
case audioVolumeMedium
|
||||
case audioVolumeMutedRtl
|
||||
case audioVolumeMuted
|
||||
case audioVolumeOveramplifiedRtl
|
||||
case audioVolumeOveramplified
|
||||
case audioXGeneric
|
||||
case authFace
|
||||
case authFingerprint
|
||||
case authSimLocked
|
||||
case authSimMissing
|
||||
case authSim
|
||||
case authSmartcard
|
||||
case avatarDefault
|
||||
case batteryAction
|
||||
case batteryCautionCharging
|
||||
case batteryCaution
|
||||
case batteryEmptyCharging
|
||||
case batteryEmpty
|
||||
case batteryFullCharged
|
||||
case batteryFullCharging
|
||||
case batteryFull
|
||||
case batteryGoodCharging
|
||||
case batteryGood
|
||||
case batteryLevel_0Charging
|
||||
case batteryLevel_0
|
||||
case batteryLevel_10Charging
|
||||
case batteryLevel_10
|
||||
case batteryLevel_100Charged
|
||||
case batteryLevel_100
|
||||
case batteryLevel_20Charging
|
||||
case batteryLevel_20
|
||||
case batteryLevel_30Charging
|
||||
case batteryLevel_30
|
||||
case batteryLevel_40Charging
|
||||
case batteryLevel_40
|
||||
case batteryLevel_50Charging
|
||||
case batteryLevel_50
|
||||
case batteryLevel_60Charging
|
||||
case batteryLevel_60
|
||||
case batteryLevel_70Charging
|
||||
case batteryLevel_70
|
||||
case batteryLevel_80Charging
|
||||
case batteryLevel_80
|
||||
case batteryLevel_90Charging
|
||||
case batteryLevel_90
|
||||
case batteryLowCharging
|
||||
case batteryLow
|
||||
case batteryMissing
|
||||
case battery
|
||||
case bluetoothAcquiring
|
||||
case bluetoothActive
|
||||
case bluetoothDisabled
|
||||
case bluetoothDisconnected
|
||||
case bluetoothHardwareDisabled
|
||||
case bluetooth
|
||||
case bookmarkNew
|
||||
case callIncoming
|
||||
case callMissed
|
||||
case callOutgoing
|
||||
case callStart
|
||||
case callStop
|
||||
case cameraDisabled
|
||||
case cameraHardwareDisabled
|
||||
case cameraPhoto
|
||||
case cameraSwitch
|
||||
case cameraVideo
|
||||
case cameraWeb
|
||||
case capsLock
|
||||
case changesAllow
|
||||
case changesPrevent
|
||||
case channelInsecure
|
||||
case channelSecure
|
||||
case chatMessageNew
|
||||
case checkboxChecked
|
||||
case checkboxMixed
|
||||
case checkbox
|
||||
case colorSelect
|
||||
case colorimeterColorhug
|
||||
case completionSnippet
|
||||
case completionWord
|
||||
case computerAppleIpad
|
||||
case computerFail
|
||||
case computer
|
||||
case contactNew
|
||||
case contentLoading
|
||||
case daytimeSunrise
|
||||
case daytimeSunset
|
||||
case dialogError
|
||||
case dialogInformation
|
||||
case dialogPassword
|
||||
case dialogQuestion
|
||||
case dialogWarning
|
||||
case displayBrightness
|
||||
case displayProjector
|
||||
case documentEdit
|
||||
case documentNew
|
||||
case documentOpenRecent
|
||||
case documentOpen
|
||||
case documentPageSetup
|
||||
case documentPrintPreview
|
||||
case documentPrint
|
||||
case documentProperties
|
||||
case documentRevertRtl
|
||||
case documentRevert
|
||||
case documentSaveAs
|
||||
case documentSave
|
||||
case documentSend
|
||||
case driveHarddiskIeee1394
|
||||
case driveHarddiskSolidstate
|
||||
case driveHarddisk
|
||||
case driveHarddiskSystem
|
||||
case driveHarddiskUsb
|
||||
case driveMultidisk
|
||||
case driveOptical
|
||||
case driveRemovableMedia
|
||||
case editClearAll
|
||||
case editClearRtl
|
||||
case editClear
|
||||
case editCopy
|
||||
case editCut
|
||||
case editDelete
|
||||
case editFindReplace
|
||||
case editFind
|
||||
case editPaste
|
||||
case editRedo
|
||||
case editSelectAll
|
||||
case editSelect
|
||||
case editUndo
|
||||
case emblemDefault
|
||||
case emblemDocuments
|
||||
case emblemFavorite
|
||||
case emblemImportant
|
||||
case emblemMusic
|
||||
case emblemOk
|
||||
case emblemPhotos
|
||||
case emblemShared
|
||||
case emblemSynchronizing
|
||||
case emblemSystem
|
||||
case emblemVideos
|
||||
case emojiActivities
|
||||
case emojiBody
|
||||
case emojiFlags
|
||||
case emojiFood
|
||||
case emojiNature
|
||||
case emojiObjects
|
||||
case emojiPeople
|
||||
case emojiRecent
|
||||
case emojiSymbols
|
||||
case emojiTravel
|
||||
case emoteLove
|
||||
case errorCorrect
|
||||
case faceAngel
|
||||
case faceAngry
|
||||
case faceConfused
|
||||
case faceCool
|
||||
case faceCrying
|
||||
case faceDevilish
|
||||
case faceEmbarrassed
|
||||
case faceGlasses
|
||||
case faceKiss
|
||||
case faceLaugh
|
||||
case faceMonkey
|
||||
case facePlain
|
||||
case faceRaspberry
|
||||
case faceSad
|
||||
case faceShutmouth
|
||||
case faceSick
|
||||
case faceSmileBig
|
||||
case faceSmile
|
||||
case faceSmirk
|
||||
case faceSurprise
|
||||
case faceTired
|
||||
case faceUncertain
|
||||
case faceWink
|
||||
case faceWorried
|
||||
case faceYawn
|
||||
case findLocation
|
||||
case focusLegacySystray
|
||||
case focusTopBar
|
||||
case focusWindows
|
||||
case folderDocuments
|
||||
case folderDownload
|
||||
case folderDragAccept
|
||||
case folderMusic
|
||||
case folderNew
|
||||
case folderOpen
|
||||
case folderPictures
|
||||
case folderPublicshare
|
||||
case folderRemote
|
||||
case folderSavedSearch
|
||||
case folder
|
||||
case folderTemplates
|
||||
case folderVideos
|
||||
case folderVisiting
|
||||
case fontSelect
|
||||
case fontXGeneric
|
||||
case formatIndentLessRtl
|
||||
case formatIndentLess
|
||||
case formatIndentMoreRtl
|
||||
case formatIndentMore
|
||||
case formatJustifyCenter
|
||||
case formatJustifyFill
|
||||
case formatJustifyLeft
|
||||
case formatJustifyRight
|
||||
case formatTextBold
|
||||
case formatTextDirectionLtr
|
||||
case formatTextDirectionRtl
|
||||
case formatTextDirection
|
||||
case formatTextItalic
|
||||
case formatTextPlaintext
|
||||
case formatTextRich
|
||||
case formatTextStrikethrough
|
||||
case formatTextUnderline
|
||||
case functionLinear
|
||||
case gestureSwipeLeft
|
||||
case gestureSwipeRight
|
||||
case gnomeDisksStateStandby
|
||||
case gnomePowerManager
|
||||
case goBottom
|
||||
case goDown
|
||||
case goFirst
|
||||
case goHome
|
||||
case goJumpRtl
|
||||
case goJump
|
||||
case goLast
|
||||
case goNext
|
||||
case goPrevious
|
||||
case goTop
|
||||
case goUp
|
||||
case goaAccountExchange
|
||||
case goaAccountGoogle
|
||||
case goaAccountLastfm
|
||||
case goaAccountMsn
|
||||
case goaAccountOwncloud
|
||||
case goaAccount
|
||||
case goaPanel
|
||||
case gtk3Demo
|
||||
case gtk3WidgetFactory
|
||||
case helpAbout
|
||||
case helpBrowser
|
||||
case helpContents
|
||||
case helpFaq
|
||||
case imageLoading
|
||||
case imageMissing
|
||||
case imageXGeneric
|
||||
case info
|
||||
case inodeDirectory
|
||||
case inputDialpad
|
||||
case inputGaming
|
||||
case inputKeyboard
|
||||
case inputMouse
|
||||
case inputTablet
|
||||
case inputTouchpad
|
||||
case insertImage
|
||||
case insertLink
|
||||
case insertObject
|
||||
case insertText
|
||||
case keyboardBrightness
|
||||
case langClass
|
||||
case langDefine
|
||||
case langEnum
|
||||
case langEnumValue
|
||||
case langFunction
|
||||
case langInclude
|
||||
case langMethod
|
||||
case langNamespace
|
||||
case langStructField
|
||||
case langStruct
|
||||
case langTypedef
|
||||
case langUnion
|
||||
case langVariable
|
||||
case libreofficeBase
|
||||
case libreofficeCalc
|
||||
case libreofficeDraw
|
||||
case libreofficeImpress
|
||||
case libreofficeMain
|
||||
case libreofficeMath
|
||||
case libreofficeWriter
|
||||
case listAdd
|
||||
case listDragHandle
|
||||
case listRemoveAll
|
||||
case listRemove
|
||||
case locationServicesActive
|
||||
case locationServicesDisabled
|
||||
case mailAttachment
|
||||
case mailForward
|
||||
case mailMarkImportant
|
||||
case mailMarkJunk
|
||||
case mailMarkNotjunk
|
||||
case mailMessageNew
|
||||
case mailRead
|
||||
case mailRepliedRtl
|
||||
case mailReplied
|
||||
case mailReplyAllRtl
|
||||
case mailReplyAll
|
||||
case mailReplySender
|
||||
case mailSendReceive
|
||||
case mailSend
|
||||
case mailUnread
|
||||
case markLocation
|
||||
case mediaEject
|
||||
case mediaFlash
|
||||
case mediaFloppy
|
||||
case mediaOpticalBd
|
||||
case mediaOpticalCdAudio
|
||||
case mediaOpticalCd
|
||||
case mediaOpticalDvd
|
||||
case mediaOptical
|
||||
case mediaPlaybackPause
|
||||
case mediaPlaybackStart
|
||||
case mediaPlaybackStop
|
||||
case mediaPlaylistConsecutive
|
||||
case mediaPlaylistRepeatSong
|
||||
case mediaPlaylistRepeat
|
||||
case mediaPlaylistShuffle
|
||||
case mediaRecord
|
||||
case mediaRemovable
|
||||
case mediaSeekBackward
|
||||
case mediaSeekForward
|
||||
case mediaSkipBackward
|
||||
case mediaSkipForward
|
||||
case mediaTape
|
||||
case mediaViewSubtitles
|
||||
case mediaZip
|
||||
case microphoneDisabled
|
||||
case microphoneHardwareDisabled
|
||||
case microphoneSensitivityHigh
|
||||
case microphoneSensitivityLow
|
||||
case microphoneSensitivityMedium
|
||||
case microphoneSensitivityMuted
|
||||
case modem
|
||||
case multimediaPlayerAppleIpodTouch
|
||||
case multimediaPlayer
|
||||
case multimediaVolumeControl
|
||||
case networkCellular_2g
|
||||
case networkCellular_3g
|
||||
case networkCellular_4g
|
||||
case networkCellular_5g
|
||||
case networkCellularAcquiringRtl
|
||||
case networkCellularAcquiring
|
||||
case networkCellularConnected
|
||||
case networkCellularDisabledRtl
|
||||
case networkCellularDisabled
|
||||
case networkCellularEdge
|
||||
case networkCellularGprs
|
||||
case networkCellularHardwareDisabledRtl
|
||||
case networkCellularHardwareDisabled
|
||||
case networkCellularHspa
|
||||
case networkCellularNoRouteRtl
|
||||
case networkCellularNoRoute
|
||||
case networkCellularOfflineRtl
|
||||
case networkCellularOffline
|
||||
case networkCellularSignalExcellentRtl
|
||||
case networkCellularSignalExcellent
|
||||
case networkCellularSignalGoodRtl
|
||||
case networkCellularSignalGood
|
||||
case networkCellularSignalNoneRtl
|
||||
case networkCellularSignalNone
|
||||
case networkCellularSignalOkRtl
|
||||
case networkCellularSignalOk
|
||||
case networkCellularSignalWeakRtl
|
||||
case networkCellularSignalWeak
|
||||
case networkCellular
|
||||
case networkError
|
||||
case networkIdle
|
||||
case networkNoRoute
|
||||
case networkOffline
|
||||
case networkReceive
|
||||
case networkServer
|
||||
case networkTransmitReceive
|
||||
case networkTransmit
|
||||
case networkVpnAcquiring
|
||||
case networkVpnDisabled
|
||||
case networkVpnDisconnected
|
||||
case networkVpnNoRoute
|
||||
case networkVpn
|
||||
case networkWiredAcquiring
|
||||
case networkWiredDisconnected
|
||||
case networkWiredNoRoute
|
||||
case networkWired
|
||||
case networkWirelessAcquiring
|
||||
case networkWirelessConnected
|
||||
case networkWirelessDisabled
|
||||
case networkWirelessEncrypted
|
||||
case networkWirelessHardwareDisabled
|
||||
case networkWirelessHotspot
|
||||
case networkWirelessNoRoute
|
||||
case networkWirelessOffline
|
||||
case networkWirelessSignalExcellent
|
||||
case networkWirelessSignalGood
|
||||
case networkWirelessSignalNone
|
||||
case networkWirelessSignalOk
|
||||
case networkWirelessSignalWeak
|
||||
case networkWireless
|
||||
case networkWorkgroup
|
||||
case nightLightDisabled
|
||||
case nightLight
|
||||
case nmDeviceWiredSecure
|
||||
case nmDeviceWired
|
||||
case nmDeviceWwan
|
||||
case nonStarred
|
||||
case notificationsDisabled
|
||||
case objectFlipHorizontal
|
||||
case objectFlipVertical
|
||||
case objectRotateLeft
|
||||
case objectRotateRight
|
||||
case objectSelect
|
||||
case openMenu
|
||||
case orca
|
||||
case fedoraprojectAnacondaInstaller = "org.fedoraproject.AnacondaInstaller"
|
||||
case freedesktopMalcontentControl = "org.freedesktop.MalcontentControl"
|
||||
case gnomeAdwaita1Demo = "org.gnome.Adwaita1.Demo"
|
||||
case gnomeBoxes = "org.gnome.Boxes"
|
||||
case gnomeBuilder = "org.gnome.Builder"
|
||||
case gnomeCalculator = "org.gnome.Calculator"
|
||||
case gnomeCharacters = "org.gnome.Characters"
|
||||
case gnomeCheese = "org.gnome.Cheese"
|
||||
case gnomeConsole = "org.gnome.Console"
|
||||
case gnomeDiskUtility = "org.gnome.DiskUtility"
|
||||
case gnomeEpiphany = "org.gnome.Epiphany"
|
||||
case gnomeEvince = "org.gnome.Evince"
|
||||
case gnomeLogs = "org.gnome.Logs"
|
||||
case gnomeMaps = "org.gnome.Maps"
|
||||
case gnomeNautilus = "org.gnome.Nautilus"
|
||||
case gnomePhotos = "org.gnome.Photos"
|
||||
case gnomeRhythmbox3 = "org.gnome.Rhythmbox3"
|
||||
case gnomeSettingsAbout = "org.gnome.Settings-about"
|
||||
case gnomeSettingsAccessibility = "org.gnome.Settings-accessibility"
|
||||
case gnomeSettingsAppearance = "org.gnome.Settings-appearance"
|
||||
case gnomeSettingsApplications = "org.gnome.Settings-applications"
|
||||
case gnomeSettingsBluetooth = "org.gnome.Settings-bluetooth"
|
||||
case gnomeSettingsCamera = "org.gnome.Settings-camera"
|
||||
case gnomeSettingsColor = "org.gnome.Settings-color"
|
||||
case gnomeSettingsDefaultApps = "org.gnome.Settings-default-apps"
|
||||
case gnomeSettingsDiagnostics = "org.gnome.Settings-diagnostics"
|
||||
case gnomeSettingsDisplay = "org.gnome.Settings-display"
|
||||
case gnomeSettingsFileHistory = "org.gnome.Settings-file-history"
|
||||
case gnomeSettingsKeyboard = "org.gnome.Settings-keyboard"
|
||||
case gnomeSettingsLocation = "org.gnome.Settings-location"
|
||||
case gnomeSettingsMicrophone = "org.gnome.Settings-microphone"
|
||||
case gnomeSettingsMobileNetwork = "org.gnome.Settings-mobile-network"
|
||||
case gnomeSettingsMouse = "org.gnome.Settings-mouse"
|
||||
case gnomeSettingsMultitasking = "org.gnome.Settings-multitasking"
|
||||
case gnomeSettingsNetwork = "org.gnome.Settings-network"
|
||||
case gnomeSettingsNotifications = "org.gnome.Settings-notifications"
|
||||
case gnomeSettingsOnlineAccounts = "org.gnome.Settings-online-accounts"
|
||||
case gnomeSettingsPower = "org.gnome.Settings-power"
|
||||
case gnomeSettingsPinters = "org.gnome.Setting-printers"
|
||||
case gnomeSettingsRegion = "org.gnome.Settings-region"
|
||||
case gnomeSettingsRemovableMedia = "org.gnome.Settings-removable-media"
|
||||
case gnomeSettingsSearch = "org.gnome.Settings-search"
|
||||
case gnomeSettingsSharing = "org.gnome.Settings-sharing"
|
||||
case gnomeSettingsSound = "org.gnome.Settings-sound"
|
||||
case gnomeSettings = "org.gnome.Settings"
|
||||
case gnomeSettingsSystemLockScreen = "org.gnome.Settings-system-lock-screen"
|
||||
case gnomeSettingsThunderbolt = "org.gnome.Settings-thunderbolt"
|
||||
case gnomeSettingsTime = "org.gnome.Settings-time"
|
||||
case gnomeSettingsUsers = "org.gnome.Settings-users"
|
||||
case gnomeSettingsWacom = "org.gnome.Settings-wacom"
|
||||
case gnomeShellExtensions = "org.gnome.Shell.Extensions"
|
||||
case gnomeSoftware = "org.gnome.Software"
|
||||
case gnomeSystemMonitor = "org.gnome.SystemMonitor"
|
||||
case gnomeTextEditor = "org.gnome.TextEditor"
|
||||
case gnomeTotem = "org.gnome.Totem"
|
||||
case gnomeWeather = "org.gnome.Weather"
|
||||
case gnomeYelp = "org.gnome.Yelp"
|
||||
case gnomeBaobab = "org.gnome.baobab"
|
||||
case gnomeClocks = "org.gnome.clocks"
|
||||
case gnomeDesignIconLibrary = "org.gnome.design.IconLibrary"
|
||||
case gnomeEog = "org.gnome.eog"
|
||||
case gnomeFontViewer = "org.gnome.font-viewer"
|
||||
case gnomeTweaks = "org.gnome.tweaks"
|
||||
case gtkDemo4 = "org.gtk.Demo4"
|
||||
case gtkIconBrowser4 = "org.gtk.IconBrowser4"
|
||||
case gtkPrintEditor4 = "org.gtk.PrintEditor4"
|
||||
case gtkWidgetFactory4 = "org.gtk.WidgetFactory4"
|
||||
case gtkGtk4NodeEditor = "org.gtk.gtk4.NodeEditor"
|
||||
case orientationLandscapeInverse
|
||||
case orientationLandscape
|
||||
case orientationPortraitInverse
|
||||
case orientationPortraitLeft
|
||||
case orientationPortraitRight
|
||||
case orientationProtrait
|
||||
case packageXGeneric
|
||||
case panDown
|
||||
case panEnd
|
||||
case panStart
|
||||
case panUp
|
||||
case panelBottom
|
||||
case panelCenter
|
||||
case panelLeft
|
||||
case panelModified
|
||||
case panelRight
|
||||
case panelTop
|
||||
case pda
|
||||
case phoneAppleIphone
|
||||
case phoneOld
|
||||
case phone
|
||||
case powerProfileBalancedRtl
|
||||
case powerProfileBalanced
|
||||
case powerProfilePerformanceRtl
|
||||
case powerProfilePerformance
|
||||
case powerProfilePowerSaverRtl
|
||||
case powerProfilePowerSaver
|
||||
case preferencesColor
|
||||
case preferencesDesktopAccessibility
|
||||
case preferencesDesktopAppearance
|
||||
case preferencesDesktopApps
|
||||
case preferencesDesktopDisplay
|
||||
case preferencesDesktopFont
|
||||
case preferencesDesktopKeyboardShortcuts
|
||||
case preferencesDesktopKeyboard
|
||||
case preferencesDesktopLocale
|
||||
case preferencesDesktopMultitasking
|
||||
case preferencesDesktopRemoteDesktop
|
||||
case preferencesDesktopScreensaver
|
||||
case preferencesDesktopWallpaper
|
||||
case preferencesOther
|
||||
case preferencesSystemDetails
|
||||
case preferencesSystemDevices
|
||||
case preferencesSystemNetworkProxy
|
||||
case preferencesSystemNetwork
|
||||
case preferencesSystemNotifications
|
||||
case preferencesSystemParentalControls
|
||||
case preferencesSystemPrivacy
|
||||
case preferencesSystemSearch
|
||||
case preferencesSystemSharing
|
||||
case preferencesSystem
|
||||
case preferencesSystemTime
|
||||
case printerError
|
||||
case printerNetwork
|
||||
case printerPrinting
|
||||
case printer
|
||||
case printerWarning
|
||||
case processStop
|
||||
case processWorking
|
||||
case radioChecked
|
||||
case radioMixed
|
||||
case radio
|
||||
case rotationAllowed
|
||||
case rotationLocked
|
||||
case scanner
|
||||
case screenShared
|
||||
case securityHigh
|
||||
case securityLow
|
||||
case securityMediumRtl
|
||||
case securityMedium
|
||||
case selectionEnd
|
||||
case selectionMode
|
||||
case selectionStart
|
||||
case semiStarredRtl
|
||||
case semiStarred
|
||||
case sendTo
|
||||
case sidebarShowRight
|
||||
case sidebarShow
|
||||
case softwareUpdateAvailable
|
||||
case softwareUpdateUrgent
|
||||
case speedometer
|
||||
case starNew
|
||||
case starred
|
||||
case startHere
|
||||
case switchOff
|
||||
case switchOn
|
||||
case systemFileManager
|
||||
case systemHelp
|
||||
case systemLockScreen
|
||||
case systemLogOutRtl
|
||||
case systemLogOut
|
||||
case systemReboot
|
||||
case systemRun
|
||||
case systemSearch
|
||||
case systemShutdown
|
||||
case systemSoftwareInstall
|
||||
case systemSwitchUserRtl
|
||||
case systemSwitchUser
|
||||
case systemUsers
|
||||
case tabNew
|
||||
case tablet
|
||||
case taskDue
|
||||
case taskPastDue
|
||||
case temperature
|
||||
case textEditor
|
||||
case textXGeneric
|
||||
case thunderboltAcquiring
|
||||
case thunderbolt
|
||||
case toolsCheckSpelling
|
||||
case totemTv
|
||||
case touchDisabled
|
||||
case touchpadDisabled
|
||||
case tv
|
||||
case uninterruptiblePowerSupply
|
||||
case userAvailable
|
||||
case userAway
|
||||
case userBookmarks
|
||||
case userBusy
|
||||
case userDesktop
|
||||
case userHome
|
||||
case userIdle
|
||||
case userInfo
|
||||
case userInvisible
|
||||
case userNotTracked
|
||||
case userOffline
|
||||
case userStatusPending
|
||||
case userTrashFull
|
||||
case userTrash
|
||||
case utilitiesTerminal
|
||||
case valueDecrease
|
||||
case valueIncrease
|
||||
case videoDisplay
|
||||
case videoJoineDisplays
|
||||
case videoSingleDisplay
|
||||
case videoXGeneric
|
||||
case viewAppGrid
|
||||
case viewConceal
|
||||
case viewContinuous
|
||||
case viewDual
|
||||
case viewFullscreen
|
||||
case viewGrid
|
||||
case viewListBulletRtl
|
||||
case viewListBullet
|
||||
case viewListOrderedRtl
|
||||
case viewListOrdered
|
||||
case viewListRtl
|
||||
case viewList
|
||||
case viewMirror
|
||||
case viewMoreHorizontal
|
||||
case viewMore
|
||||
case viewPagedRtl
|
||||
case viewPaged
|
||||
case viewPin
|
||||
case viewRefresh
|
||||
case viewRestore
|
||||
case viewReveal
|
||||
case viewSortAscendingRtl
|
||||
case viewSortAscending
|
||||
case viewSortDescendingRtl
|
||||
case viewSortDescending
|
||||
case viewWrappedRtl
|
||||
case viewWrapped
|
||||
case weatherClearNight
|
||||
case weatherClear
|
||||
case weatherFewCloudsNight
|
||||
case weatherFewClouds
|
||||
case weatherFog
|
||||
case weatherHourly
|
||||
case weatherOvercast
|
||||
case weatherSevereAlert
|
||||
case weatherShowersScattered
|
||||
case weatherShowers
|
||||
case weatherSnow
|
||||
case weatherStorm
|
||||
case weatherTornado
|
||||
case weatherWindy
|
||||
case webBrowser
|
||||
case windowClose
|
||||
case windowMaximize
|
||||
case windowMinimize
|
||||
case windowNew
|
||||
case windowRestore
|
||||
case xOfficeAddressBook
|
||||
case xOfficeCalendar
|
||||
case xOfficeDocument
|
||||
case xOfficeDrawing
|
||||
case xOfficePresentation
|
||||
case xOfficeSpreadsheet
|
||||
case zoomFitBest
|
||||
case zoomIn
|
||||
case zoomOriginal
|
||||
case zoomOut
|
||||
// swiftlint:enable missing_docs identifier_name
|
||||
|
||||
/// A string representation of the icon.
|
||||
public var string: String {
|
||||
var string = rawValue
|
||||
if !string.hasPrefix("org.") {
|
||||
let result = string
|
||||
.map { letter in
|
||||
if letter.isUppercase {
|
||||
return "-\(letter)"
|
||||
} else {
|
||||
return "\(letter)"
|
||||
}
|
||||
}
|
||||
.joined()
|
||||
string = result.lowercased()
|
||||
}
|
||||
string = string.replacingOccurrences(of: "_plus_", with: "+")
|
||||
string = string.replacingOccurrences(of: "_", with: "-")
|
||||
return string + "-symbolic"
|
||||
}
|
||||
}
|
||||
}
|
||||
// swiftlint:enable type_body_length file_length
|
75
Sources/Adwaita/Model/Enumerations/Transition.swift
Normal file
75
Sources/Adwaita/Model/Enumerations/Transition.swift
Normal file
@ -0,0 +1,75 @@
|
||||
//
|
||||
// Transition.swift
|
||||
// Adwaita
|
||||
//
|
||||
// Created by david-swift on 21.01.24.
|
||||
//
|
||||
|
||||
import CAdw
|
||||
|
||||
/// A transition for a stack.
|
||||
public enum Transition: Int {
|
||||
|
||||
// swiftlint:disable missing_docs discouraged_none_name
|
||||
case none
|
||||
case crossfade
|
||||
case slideRight, slideLeft, slideUp, slideDown, slideLeftRight, slideUpDown
|
||||
case coverUp, coverDown, coverLeft, coverRight
|
||||
case uncoverUp, uncoverDown, uncoverLeft, uncoverRight
|
||||
case coverUpDown, coverDownUp, coverLeftRight, coverRightLeft
|
||||
case rotateLeft, rotateRight, rotateLeftRight
|
||||
// swiftlint:enable missing_docs discouraged_none_name
|
||||
|
||||
/// Get the GtkStackTransitionType transition.
|
||||
public var cTransition: GtkStackTransitionType {
|
||||
switch self {
|
||||
case .none:
|
||||
return GTK_STACK_TRANSITION_TYPE_NONE
|
||||
case .crossfade:
|
||||
return GTK_STACK_TRANSITION_TYPE_CROSSFADE
|
||||
case .slideRight:
|
||||
return GTK_STACK_TRANSITION_TYPE_SLIDE_RIGHT
|
||||
case .slideLeft:
|
||||
return GTK_STACK_TRANSITION_TYPE_SLIDE_LEFT
|
||||
case .slideUp:
|
||||
return GTK_STACK_TRANSITION_TYPE_SLIDE_UP
|
||||
case .slideDown:
|
||||
return GTK_STACK_TRANSITION_TYPE_SLIDE_DOWN
|
||||
case .slideLeftRight:
|
||||
return GTK_STACK_TRANSITION_TYPE_SLIDE_LEFT_RIGHT
|
||||
case .slideUpDown:
|
||||
return GTK_STACK_TRANSITION_TYPE_SLIDE_UP_DOWN
|
||||
case .coverUp:
|
||||
return GTK_STACK_TRANSITION_TYPE_OVER_UP
|
||||
case .coverDown:
|
||||
return GTK_STACK_TRANSITION_TYPE_OVER_DOWN
|
||||
case .coverLeft:
|
||||
return GTK_STACK_TRANSITION_TYPE_OVER_LEFT
|
||||
case .coverRight:
|
||||
return GTK_STACK_TRANSITION_TYPE_OVER_RIGHT
|
||||
case .uncoverUp:
|
||||
return GTK_STACK_TRANSITION_TYPE_UNDER_UP
|
||||
case .uncoverDown:
|
||||
return GTK_STACK_TRANSITION_TYPE_UNDER_DOWN
|
||||
case .uncoverLeft:
|
||||
return GTK_STACK_TRANSITION_TYPE_UNDER_LEFT
|
||||
case .uncoverRight:
|
||||
return GTK_STACK_TRANSITION_TYPE_UNDER_RIGHT
|
||||
case .coverUpDown:
|
||||
return GTK_STACK_TRANSITION_TYPE_OVER_UP_DOWN
|
||||
case .coverDownUp:
|
||||
return GTK_STACK_TRANSITION_TYPE_OVER_DOWN_UP
|
||||
case .coverLeftRight:
|
||||
return GTK_STACK_TRANSITION_TYPE_OVER_LEFT_RIGHT
|
||||
case .coverRightLeft:
|
||||
return GTK_STACK_TRANSITION_TYPE_OVER_RIGHT_LEFT
|
||||
case .rotateLeft:
|
||||
return GTK_STACK_TRANSITION_TYPE_ROTATE_LEFT
|
||||
case .rotateRight:
|
||||
return GTK_STACK_TRANSITION_TYPE_ROTATE_RIGHT
|
||||
case .rotateLeftRight:
|
||||
return GTK_STACK_TRANSITION_TYPE_ROTATE_LEFT_RIGHT
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -5,7 +5,7 @@
|
||||
// Created by david-swift on 06.08.23.
|
||||
//
|
||||
|
||||
import Libadwaita
|
||||
import Foundation
|
||||
|
||||
extension Array: View where Element == View {
|
||||
|
||||
@ -22,7 +22,7 @@ extension Array: View where Element == View {
|
||||
var modified = self
|
||||
for (index, view) in modified.enumerated() {
|
||||
for modifier in modifiers {
|
||||
modified[index] = modifier(view)
|
||||
modified[safe: index] = modifier(view)
|
||||
}
|
||||
}
|
||||
return VStack { modified }
|
||||
@ -53,6 +53,28 @@ extension Array where Element == WindowSceneGroup {
|
||||
|
||||
}
|
||||
|
||||
extension Array where Element == String {
|
||||
|
||||
/// Get the C version of the array.
|
||||
var cArray: UnsafePointer<UnsafePointer<CChar>?>? {
|
||||
let cStrings = self.map { $0.utf8CString }
|
||||
let cStringPointers = cStrings.map { $0.withUnsafeBufferPointer { $0.baseAddress } }
|
||||
let optionalCStringPointers = cStringPointers + [nil]
|
||||
var optionalCStringPointersCopy = optionalCStringPointers
|
||||
optionalCStringPointersCopy.withUnsafeMutableBufferPointer { bufferPointer in
|
||||
bufferPointer.baseAddress?.advanced(by: cStrings.count).pointee = nil
|
||||
}
|
||||
let flatArray = optionalCStringPointersCopy.compactMap { $0 }
|
||||
let pointer = UnsafeMutablePointer<UnsafePointer<CChar>?>.allocate(capacity: flatArray.count + 1)
|
||||
for (index, element) in flatArray.enumerated() {
|
||||
pointer.advanced(by: index).pointee = element
|
||||
}
|
||||
pointer.advanced(by: flatArray.count).pointee = nil
|
||||
return UnsafePointer(pointer)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
extension Array {
|
||||
|
||||
/// Accesses the element at the specified position safely.
|
||||
|
15
Sources/Adwaita/Model/Extensions/Bool.swift
Normal file
15
Sources/Adwaita/Model/Extensions/Bool.swift
Normal file
@ -0,0 +1,15 @@
|
||||
//
|
||||
// Bool.swift
|
||||
// Adwaita
|
||||
//
|
||||
// Created by david-swift on 15.01.24.
|
||||
//
|
||||
|
||||
extension Bool {
|
||||
|
||||
/// Get the gboolean for C.
|
||||
public var cBool: Int32 {
|
||||
self ? 1 : 0
|
||||
}
|
||||
|
||||
}
|
17
Sources/Adwaita/Model/Extensions/Int.swift
Normal file
17
Sources/Adwaita/Model/Extensions/Int.swift
Normal file
@ -0,0 +1,17 @@
|
||||
//
|
||||
// Int.swift
|
||||
// Adwaita
|
||||
//
|
||||
// Created by david-swift on 15.01.24.
|
||||
//
|
||||
|
||||
extension Int: Identifiable {
|
||||
|
||||
/// Get the integer itself as the identifier.
|
||||
public var id: Int { self }
|
||||
/// The C integer.
|
||||
public var cInt: Int32 {
|
||||
.init(self)
|
||||
}
|
||||
|
||||
}
|
@ -1,74 +0,0 @@
|
||||
//
|
||||
// Libadwaita.FileDialog.swift
|
||||
// Adwaita
|
||||
//
|
||||
// Created by david-swift on 09.12.23.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import Libadwaita
|
||||
|
||||
extension Libadwaita.FileDialog: WindowType {
|
||||
|
||||
/// An ID for the importer field.
|
||||
static var importer: String { "importer" }
|
||||
/// An ID for the folder field.
|
||||
static var folder: String { "folder" }
|
||||
/// An ID for the result field.
|
||||
static var result: String { "result" }
|
||||
/// An ID for the cancel field.
|
||||
static var cancel: String { "cancel" }
|
||||
|
||||
/// Whether the file dialog is an importer.
|
||||
var isImporter: Bool {
|
||||
get {
|
||||
fields[Self.importer] as? Bool ?? true
|
||||
}
|
||||
set {
|
||||
fields[Self.importer] = newValue
|
||||
}
|
||||
}
|
||||
/// The selected folder in the file dialog.
|
||||
var folder: URL? {
|
||||
get {
|
||||
fields[Self.folder] as? URL
|
||||
}
|
||||
set {
|
||||
fields[Self.folder] = newValue
|
||||
}
|
||||
}
|
||||
/// A closure triggered on selecting a file in the dialog.
|
||||
var onResult: ((URL) -> Void) {
|
||||
get {
|
||||
fields[Self.result] as? (URL) -> Void ?? { _ in }
|
||||
}
|
||||
set {
|
||||
fields[Self.result] = newValue
|
||||
}
|
||||
}
|
||||
/// A closure triggered when the dialog is canceled.
|
||||
var onCancel: (() -> Void) {
|
||||
get {
|
||||
fields[Self.cancel] as? () -> Void ?? { }
|
||||
}
|
||||
set {
|
||||
fields[Self.cancel] = newValue
|
||||
}
|
||||
}
|
||||
|
||||
/// Set the window's parent window.
|
||||
/// - Parameter parent: The parent window.
|
||||
///
|
||||
/// Currently not implemented.
|
||||
public func setParentWindow(_ parent: WindowType) { }
|
||||
|
||||
/// Display the file dialog.
|
||||
public func show() {
|
||||
if isImporter {
|
||||
self.open(folder: folder, onResult, onClose: onCancel)
|
||||
} else {
|
||||
self.save(folder: folder, onResult, onClose: onCancel)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -1,37 +0,0 @@
|
||||
//
|
||||
// NativeWidgetPeer.swift
|
||||
// Adwaita
|
||||
//
|
||||
// Created by david-swift on 05.08.23.
|
||||
//
|
||||
|
||||
import Libadwaita
|
||||
|
||||
extension NativeWidgetPeer: Widget {
|
||||
|
||||
/// A `Libadwaita.NativeWidgetPeer` is static.
|
||||
/// - Parameters:
|
||||
/// - storage: The view storage.
|
||||
/// - modifiers: Modify views before being updated.
|
||||
public func update(_ storage: ViewStorage, modifiers: [(View) -> View]) { }
|
||||
|
||||
/// A `Libadwaita.NativeWidgetPeer`'s container is itself.
|
||||
/// - Parameter modifiers: Modify views before being updated.
|
||||
/// - Returns: The view storage.
|
||||
public func container(modifiers: [(View) -> View]) -> ViewStorage {
|
||||
let bold = "\(modifier(code: 1))"
|
||||
let yellow = 33
|
||||
let warning = "\(modifier(code: yellow))\(bold)"
|
||||
let reset = modifier(code: 0)
|
||||
print("\(warning)warning: \(reset)discouraged use of GTUI widgets (here: \(bold)\(Self.self)\(reset)) in views")
|
||||
return .init(self)
|
||||
}
|
||||
|
||||
/// Get a modifier stirng.
|
||||
/// - Parameter code: The modifier.
|
||||
/// - Returns: The string.
|
||||
private func modifier(code: Int) -> String {
|
||||
"\u{001B}[\(code)m"
|
||||
}
|
||||
|
||||
}
|
16
Sources/Adwaita/Model/Extensions/OpaquePointer.swift
Normal file
16
Sources/Adwaita/Model/Extensions/OpaquePointer.swift
Normal file
@ -0,0 +1,16 @@
|
||||
//
|
||||
// OpaquePointer.swift
|
||||
// Adwaita
|
||||
//
|
||||
// Created by david-swift on 15.01.23.
|
||||
//
|
||||
|
||||
extension OpaquePointer {
|
||||
|
||||
/// Convert an opaque pointer into an unsafe mutable pointer with a defined type.
|
||||
/// - Returns: The unsafe mutable pointer.
|
||||
public func cast<T>() -> UnsafeMutablePointer<T> {
|
||||
.init(self)
|
||||
}
|
||||
|
||||
}
|
35
Sources/Adwaita/Model/Extensions/Set.swift
Normal file
35
Sources/Adwaita/Model/Extensions/Set.swift
Normal file
@ -0,0 +1,35 @@
|
||||
//
|
||||
// Set.swift
|
||||
// Adwaita
|
||||
//
|
||||
// Created by david-swift on 21.01.24.
|
||||
//
|
||||
|
||||
extension Set where Element == Edge {
|
||||
|
||||
/// Horizontal and vertical edges.
|
||||
public static var all: Self { vertical.union(horizontal) }
|
||||
|
||||
/// Top and bottom edges.
|
||||
public static var vertical: Self { top.union(bottom) }
|
||||
|
||||
/// Leading and trailing edges.
|
||||
public static var horizontal: Self { leading.union(trailing) }
|
||||
|
||||
/// Top edge.
|
||||
public static var top: Self { [.top] }
|
||||
|
||||
/// Bottom edge.
|
||||
public static var bottom: Self { [.bottom] }
|
||||
|
||||
/// Leading edge.
|
||||
public static var leading: Self { [.leading] }
|
||||
|
||||
/// Trailing edge.
|
||||
public static var trailing: Self { [.trailing] }
|
||||
|
||||
/// Add a collection of edges to a collection of edges.
|
||||
/// - Parameter edges: The collection of edges.
|
||||
/// - Returns: Both collections combined.
|
||||
public func add(_ edges: Self) -> Self { union(edges) }
|
||||
}
|
@ -14,4 +14,28 @@ extension String {
|
||||
/// A label for the navigation label in a GTUI widget's fields.
|
||||
static var navigationLabel: Self { "navigation-label" }
|
||||
|
||||
/// Add the Ctrl key to a shortcut.
|
||||
/// - Returns: The shortcut.
|
||||
public func ctrl() -> String { "<Ctrl>\(self)" }
|
||||
|
||||
/// Add the Shift key to a shortcut.
|
||||
/// - Returns: The shortcut.
|
||||
public func shift() -> String { "<Shift>\(self)" }
|
||||
|
||||
/// Add the Alt key to a shortcut.
|
||||
/// - Returns: The shortcut.
|
||||
public func alt() -> String { "<Alt>\(self)" }
|
||||
|
||||
/// Add the Meta key to a shortcut.
|
||||
/// - Returns: The shortcut.
|
||||
public func meta() -> String { "<Meta>\(self)" }
|
||||
|
||||
/// Add the Super key to a shortcut.
|
||||
/// - Returns: The shortcut.
|
||||
public func `super`() -> String { "<Super>\(self)" }
|
||||
|
||||
/// Add the Hyper key to a shortcut.
|
||||
/// - Returns: The shortcut.
|
||||
public func hyper() -> String { "<Hyper>\(self)" }
|
||||
|
||||
}
|
||||
|
15
Sources/Adwaita/Model/Extensions/UInt.swift
Normal file
15
Sources/Adwaita/Model/Extensions/UInt.swift
Normal file
@ -0,0 +1,15 @@
|
||||
//
|
||||
// UInt.swift
|
||||
// Adwaita
|
||||
//
|
||||
// Created by david-swift on 19.01.24.
|
||||
//
|
||||
|
||||
extension UInt {
|
||||
|
||||
/// Convert an unsigned integer into the C form.
|
||||
public var cInt: UInt32 {
|
||||
.init(self)
|
||||
}
|
||||
|
||||
}
|
23
Sources/Adwaita/Model/Extensions/UnsafeMutablePointer.swift
Normal file
23
Sources/Adwaita/Model/Extensions/UnsafeMutablePointer.swift
Normal file
@ -0,0 +1,23 @@
|
||||
//
|
||||
// UnsafeMutablePointer.swift
|
||||
// Adwaita
|
||||
//
|
||||
// Created by david-swift on 15.01.24.
|
||||
//
|
||||
|
||||
extension UnsafeMutablePointer {
|
||||
|
||||
/// Convert into an opaque pointer.
|
||||
/// - Returns: The opaque pointer.
|
||||
public func opaque() -> OpaquePointer {
|
||||
.init(self)
|
||||
}
|
||||
|
||||
/// Convert into an unsafe mutable pointer of another type.
|
||||
/// - Returns: The unsafe mutable pointer.
|
||||
public func cast<T>() -> UnsafeMutablePointer<T> {
|
||||
let pointer = UnsafeMutableRawPointer(self).bindMemory(to: T.self, capacity: 1)
|
||||
return UnsafeMutablePointer<T>(mutating: pointer)
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,17 @@
|
||||
//
|
||||
// UnsafeMutableRawPointer.swift
|
||||
// Adwaita
|
||||
//
|
||||
// Created by david-swift on 15.01.24.
|
||||
//
|
||||
|
||||
extension UnsafeMutableRawPointer {
|
||||
|
||||
/// Convert into an unsafe mutable pointer of a certain type.
|
||||
/// - Returns: The unsafe mutable pointer.
|
||||
public func cast<T>() -> UnsafeMutablePointer<T> {
|
||||
let pointer = UnsafeMutableRawPointer(self).bindMemory(to: T.self, capacity: 1)
|
||||
return UnsafeMutablePointer<T>(mutating: pointer)
|
||||
}
|
||||
|
||||
}
|
@ -5,8 +5,6 @@
|
||||
// Created by david-swift on 05.08.23.
|
||||
//
|
||||
|
||||
import Libadwaita
|
||||
|
||||
/// A structure conforming to `App` is the entry point of your app.
|
||||
///
|
||||
/// ```swift
|
||||
|
@ -5,16 +5,21 @@
|
||||
// Created by david-swift on 05.08.23.
|
||||
//
|
||||
|
||||
import Libadwaita
|
||||
import CAdw
|
||||
|
||||
/// The GTUI application.
|
||||
public class GTUIApp: Application {
|
||||
public class GTUIApp {
|
||||
|
||||
/// The handlers which are called when a state changes.
|
||||
static var updateHandlers: [() -> Void] = []
|
||||
/// The app's id for the file name for storing the data.
|
||||
static var appID = "temporary"
|
||||
|
||||
/// The pointer to the application.
|
||||
public var pointer: UnsafeMutablePointer<GtkApplication>?
|
||||
/// Fields for additional information.
|
||||
public var fields: [String: Any] = [:]
|
||||
|
||||
/// The app's content.
|
||||
var body: () -> App
|
||||
/// The scenes that are displayed.
|
||||
@ -28,11 +33,11 @@ public class GTUIApp: Application {
|
||||
/// - body: The application's content.
|
||||
init(_ id: String, body: @escaping () -> App) {
|
||||
self.body = body
|
||||
super.init(name: id)
|
||||
self.pointer = adw_application_new(id, G_APPLICATION_DEFAULT_FLAGS)?.cast()
|
||||
}
|
||||
|
||||
/// The entry point of the application.
|
||||
override public func onActivate() {
|
||||
public func onActivate() {
|
||||
let body = body()
|
||||
for windowScene in body.scene.windows() {
|
||||
for _ in 0..<windowScene.open {
|
||||
@ -42,6 +47,53 @@ public class GTUIApp: Application {
|
||||
}
|
||||
}
|
||||
|
||||
/// Run the application.
|
||||
public func run() {
|
||||
let data = ViewStorage.SignalData { self.onActivate() }
|
||||
fields["run"] = data
|
||||
g_signal_connect_data(
|
||||
pointer?.cast(),
|
||||
"activate",
|
||||
unsafeBitCast(data.handler, to: GCallback.self),
|
||||
Unmanaged.passUnretained(data).toOpaque().cast(),
|
||||
nil,
|
||||
G_CONNECT_AFTER
|
||||
)
|
||||
g_application_run(pointer?.cast(), 0, nil)
|
||||
}
|
||||
|
||||
/// Add a keyboard shortcut to the application.
|
||||
/// - Parameters:
|
||||
/// - shortcut: The keyboard shortcut.
|
||||
/// - id: The action's id.
|
||||
/// - window: Optionally an application window.
|
||||
/// - handler: The action's handler.
|
||||
public func addKeyboardShortcut(
|
||||
_ shortcut: String,
|
||||
id: String,
|
||||
window: GTUIApplicationWindow? = nil,
|
||||
handler: @escaping () -> Void
|
||||
) {
|
||||
let action = g_simple_action_new(id, nil)
|
||||
let data = ViewStorage.SignalData(closure: handler)
|
||||
g_signal_connect_data(
|
||||
action?.cast(),
|
||||
"activate",
|
||||
unsafeBitCast(data.threeParamsHandler, to: GCallback.self),
|
||||
Unmanaged.passUnretained(data).toOpaque().cast(),
|
||||
nil,
|
||||
G_CONNECT_AFTER
|
||||
)
|
||||
if let window {
|
||||
g_action_map_add_action(.init(window.pointer), action)
|
||||
window.fields[id] = data
|
||||
} else {
|
||||
g_action_map_add_action(.init(pointer), action)
|
||||
fields[id] = data
|
||||
}
|
||||
gtk_application_set_accels_for_action(pointer, (window == nil ? "app." : "win.") + id, [shortcut].cArray)
|
||||
}
|
||||
|
||||
/// Focus the window with a certain id. Create the window if it doesn't already exist.
|
||||
/// - Parameters:
|
||||
/// - id: The window's id.
|
||||
@ -75,4 +127,10 @@ public class GTUIApp: Application {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Terminate the application.
|
||||
public func quit() {
|
||||
g_application_quit(pointer?.cast())
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -5,7 +5,7 @@
|
||||
// Created by david-swift on 22.10.23.
|
||||
//
|
||||
|
||||
import Libadwaita
|
||||
import CAdw
|
||||
|
||||
/// A structure representing the content for a certain menu item type.
|
||||
public protocol MenuItem: MenuItemGroup {
|
||||
@ -15,7 +15,7 @@ public protocol MenuItem: MenuItemGroup {
|
||||
/// - menu: The menu.
|
||||
/// - app: The application containing the menu.
|
||||
/// - window: The application window containing the menu.
|
||||
func addMenuItem(menu: Libadwaita.Menu, app: GTUIApp, window: GTUIApplicationWindow?)
|
||||
func addMenuItem(menu: OpaquePointer?, app: GTUIApp, window: GTUIApplicationWindow?)
|
||||
|
||||
}
|
||||
|
||||
|
@ -5,7 +5,7 @@
|
||||
// Created by david-swift on 22.10.23.
|
||||
//
|
||||
|
||||
import Libadwaita
|
||||
import CAdw
|
||||
|
||||
/// A structure conforming to `MenuItemGroup` can be added to the content accepting a menu.
|
||||
public protocol MenuItemGroup {
|
||||
@ -19,7 +19,7 @@ extension MenuItemGroup {
|
||||
|
||||
/// Add the menu items described by the group to a menu.
|
||||
/// - Parameter menu: The menu.
|
||||
func addMenuItems(menu: Libadwaita.Menu, app: GTUIApp, window: GTUIApplicationWindow?) {
|
||||
func addMenuItems(menu: OpaquePointer?, app: GTUIApp, window: GTUIApplicationWindow?) {
|
||||
for element in content {
|
||||
if let item = element as? MenuItem {
|
||||
item.addMenuItem(menu: menu, app: app, window: window)
|
||||
|
@ -5,8 +5,6 @@
|
||||
// Created by david-swift on 05.08.23.
|
||||
//
|
||||
|
||||
import Libadwaita
|
||||
|
||||
/// A structure conforming to `View` is referred to as a view.
|
||||
/// It can be part of a body.
|
||||
///
|
||||
@ -37,13 +35,7 @@ extension View {
|
||||
if let peer = modified as? Widget {
|
||||
return peer
|
||||
} else {
|
||||
var state: [String: StateProtocol] = [:]
|
||||
for property in Mirror(reflecting: self).children {
|
||||
if let label = property.label, let value = property.value as? StateProtocol {
|
||||
state[label] = value
|
||||
}
|
||||
}
|
||||
return StateWrapper(content: { view }, state: state)
|
||||
return StateWrapper(content: { view }, state: getState())
|
||||
}
|
||||
}
|
||||
|
||||
@ -56,10 +48,20 @@ extension View {
|
||||
if let widget = modified as? Widget {
|
||||
widget.update(storage, modifiers: modifiers)
|
||||
} else {
|
||||
StateWrapper { self }.update(storage, modifiers: modifiers)
|
||||
StateWrapper(content: { view }, state: getState()).update(storage, modifiers: modifiers)
|
||||
}
|
||||
}
|
||||
|
||||
func getState() -> [String: StateProtocol] {
|
||||
var state: [String: StateProtocol] = [:]
|
||||
for property in Mirror(reflecting: self).children {
|
||||
if let label = property.label, let value = property.value as? StateProtocol {
|
||||
state[label] = value
|
||||
}
|
||||
}
|
||||
return state
|
||||
}
|
||||
|
||||
/// Get a storage.
|
||||
/// - Parameter modifiers: Modify views before being updated.
|
||||
/// - Returns: The storage.
|
||||
|
@ -5,31 +5,194 @@
|
||||
// Created by david-swift on 31.08.23.
|
||||
//
|
||||
|
||||
import Libadwaita
|
||||
import CAdw
|
||||
|
||||
/// Store a rendered view in a view storage.
|
||||
public class ViewStorage {
|
||||
|
||||
/// The GTUI widget.
|
||||
public var view: NativeWidgetPeer
|
||||
/// The pointer.
|
||||
public var pointer: OpaquePointer?
|
||||
/// The view's content.
|
||||
public var content: [String: [ViewStorage]]
|
||||
/// The view's state (used in `StateWrapper`).
|
||||
public var state: [String: StateProtocol]
|
||||
/// The signal handlers.
|
||||
public var handlers: [String: SignalData] = [:]
|
||||
/// Other properties.
|
||||
public var fields: [String: Any] = [:]
|
||||
|
||||
/// Initialize a view storage.
|
||||
/// - Parameters:
|
||||
/// - view: The GTUI widget.
|
||||
/// - pointer: The pointer to the Gtk widget.
|
||||
/// - content: The view's content.
|
||||
/// - state: The view's state.
|
||||
public init(
|
||||
_ view: NativeWidgetPeer,
|
||||
_ pointer: OpaquePointer?,
|
||||
content: [String: [ViewStorage]] = [:],
|
||||
state: [String: StateProtocol] = [:]
|
||||
) {
|
||||
self.view = view
|
||||
self.pointer = pointer
|
||||
self.content = content
|
||||
self.state = state
|
||||
}
|
||||
|
||||
/// Data to pass to signal handlers.
|
||||
public class SignalData {
|
||||
|
||||
/// The closure.
|
||||
public var closure: ([UnsafeMutableRawPointer]) -> Void
|
||||
|
||||
/// The closure as a C handler.
|
||||
var handler: @convention(c) (UnsafeMutableRawPointer, UnsafeMutableRawPointer) -> Void {
|
||||
{ _, data in
|
||||
let data = unsafeBitCast(data, to: SignalData.self)
|
||||
data.closure([])
|
||||
}
|
||||
}
|
||||
|
||||
/// The closure as a C handler with three parameters.
|
||||
var threeParamsHandler: @convention(c) (
|
||||
UnsafeMutableRawPointer,
|
||||
UnsafeMutableRawPointer,
|
||||
UnsafeMutableRawPointer
|
||||
) -> Void {
|
||||
{ _, arg1, data in
|
||||
let data = unsafeBitCast(data, to: SignalData.self)
|
||||
data.closure([arg1])
|
||||
}
|
||||
}
|
||||
|
||||
/// The closure as a C handler with four parameters.
|
||||
var fourParamsHandler: @convention(c) (
|
||||
UnsafeMutableRawPointer,
|
||||
UnsafeMutableRawPointer,
|
||||
UnsafeMutableRawPointer,
|
||||
UnsafeMutableRawPointer
|
||||
) -> Void {
|
||||
{ _, arg1, arg2, data in
|
||||
let data = unsafeBitCast(data, to: SignalData.self)
|
||||
data.closure([arg1, arg2])
|
||||
}
|
||||
}
|
||||
|
||||
/// The closure as a C handler with five parameters.
|
||||
var fiveParamsHandler: @convention(c) (
|
||||
UnsafeMutableRawPointer,
|
||||
UnsafeMutableRawPointer,
|
||||
UnsafeMutableRawPointer,
|
||||
UnsafeMutableRawPointer,
|
||||
UnsafeMutableRawPointer
|
||||
) -> Void {
|
||||
{ _, arg1, arg2, arg3, data in
|
||||
let data = unsafeBitCast(data, to: SignalData.self)
|
||||
data.closure([arg1, arg2, arg3])
|
||||
print("Hi")
|
||||
}
|
||||
}
|
||||
|
||||
/// Initialize the signal data.
|
||||
/// - Parameter closure: The signal's closure.
|
||||
public convenience init(closure: @escaping () -> Void) {
|
||||
self.init { _ in closure() }
|
||||
}
|
||||
|
||||
/// Initialize the signal data.
|
||||
/// - Parameter closure: The signal's closure.
|
||||
public init(closure: @escaping ([UnsafeMutableRawPointer]) -> Void) {
|
||||
self.closure = closure
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// Connect a handler to the observer of a property.
|
||||
/// - Parameters:
|
||||
/// - name: The property's name.
|
||||
/// - id: The handlers id to separate form others connecting to the signal.
|
||||
/// - connectFlags: The GConnectFlags.
|
||||
/// - handler: The signal's handler.
|
||||
public func notify(
|
||||
name: String,
|
||||
id: String = "",
|
||||
connectFlags: GConnectFlags = G_CONNECT_AFTER,
|
||||
handler: @escaping () -> Void
|
||||
) {
|
||||
let name = "notify::" + name
|
||||
connectSignal(name: name, id: id, connectFlags: connectFlags, argCount: 1, handler: handler)
|
||||
}
|
||||
|
||||
/// Connect a handler to a signal.
|
||||
/// - Parameters:
|
||||
/// - name: The signal's name.
|
||||
/// - id: The handlers id to separate form others connecting to the signal.
|
||||
/// - connectFlags: The GConnectFlags.
|
||||
/// - argCount: The number of additional arguments (without the first and the last one).
|
||||
/// - handler: The signal's handler.
|
||||
public func connectSignal(
|
||||
name: String,
|
||||
id: String = "",
|
||||
connectFlags: GConnectFlags = G_CONNECT_AFTER,
|
||||
argCount: Int = 0,
|
||||
handler: @escaping () -> Void
|
||||
) {
|
||||
connectSignal(name: name, id: id, connectFlags: connectFlags, argCount: argCount) { _ in
|
||||
handler()
|
||||
}
|
||||
}
|
||||
|
||||
/// Connect a handler to a signal.
|
||||
/// - Parameters:
|
||||
/// - name: The signal's name.
|
||||
/// - id: The handlers id to separate form others connecting to the signal.
|
||||
/// - connectFlags: The GConnectFlags.
|
||||
/// - argCount: The number of additional arguments (without the first and the last one).
|
||||
/// - handler: The signal's handler.
|
||||
public func connectSignal(
|
||||
name: String,
|
||||
id: String = "",
|
||||
connectFlags: GConnectFlags = G_CONNECT_AFTER,
|
||||
argCount: Int = 0,
|
||||
handler: @escaping ([UnsafeMutableRawPointer]) -> Void
|
||||
) {
|
||||
if let data = handlers[name + id] {
|
||||
data.closure = handler
|
||||
} else {
|
||||
let data = SignalData(closure: handler)
|
||||
handlers[name + id] = data
|
||||
let callback: GCallback
|
||||
let three = 3
|
||||
let two = 2
|
||||
if argCount >= three {
|
||||
callback = unsafeBitCast(data.fiveParamsHandler, to: GCallback.self)
|
||||
} else if argCount == two {
|
||||
callback = unsafeBitCast(data.fourParamsHandler, to: GCallback.self)
|
||||
} else if argCount == 1 {
|
||||
callback = unsafeBitCast(data.threeParamsHandler, to: GCallback.self)
|
||||
} else {
|
||||
callback = unsafeBitCast(data.handler, to: GCallback.self)
|
||||
}
|
||||
g_signal_connect_data(
|
||||
pointer?.cast(),
|
||||
name,
|
||||
callback,
|
||||
Unmanaged.passUnretained(data).toOpaque().cast(),
|
||||
nil,
|
||||
connectFlags
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/// Modify the view.
|
||||
/// - Parameter modify: The modification function.
|
||||
public func modify(_ modify: (OpaquePointer?) -> Void) {
|
||||
modify(pointer)
|
||||
}
|
||||
|
||||
/// Convert the pointer to a pointer of a certain type and modify the view.
|
||||
/// - Parameters:
|
||||
/// - type: The pointer's type.
|
||||
/// - modify: The modification function.
|
||||
public func modify<T>(_ type: T.Type, _ modify: (UnsafeMutablePointer<T>?) -> Void) {
|
||||
modify(pointer?.cast())
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -5,8 +5,6 @@
|
||||
// Created by david-swift on 16.08.23.
|
||||
//
|
||||
|
||||
import Libadwaita
|
||||
|
||||
/// A widget is a view that know about its GTUI widget.
|
||||
public protocol Widget: View {
|
||||
|
||||
|
@ -0,0 +1,49 @@
|
||||
//
|
||||
// GTUIAboutWindow.swift
|
||||
// Adwaita
|
||||
//
|
||||
// Created by david-swift on 21.01.24.
|
||||
//
|
||||
|
||||
import CAdw
|
||||
|
||||
/// A GTUI about window.
|
||||
public class GTUIAboutWindow: GTUIWindow {
|
||||
|
||||
/// Initialize an about window using the AppStream metadata.
|
||||
/// - Parameter filePath: The path.
|
||||
public init(filePath: String? = nil) {
|
||||
super.init(fields: [:])
|
||||
if let filePath {
|
||||
pointer = adw_about_window_new_from_appdata(filePath, nil)?.cast()
|
||||
} else {
|
||||
pointer = adw_about_window_new()?.cast()
|
||||
}
|
||||
}
|
||||
|
||||
/// Set the general data.
|
||||
/// - Parameters:
|
||||
/// - title: The app name.
|
||||
/// - icon: The app icon.
|
||||
/// - developer: The app's developer.
|
||||
/// - version: The app's version.
|
||||
public func generalData(title: String, icon: Icon, developer: String, version: String) {
|
||||
adw_about_window_set_application_name(.init(pointer), title)
|
||||
adw_about_window_set_application_icon(.init(pointer), icon.string)
|
||||
adw_about_window_set_developer_name(.init(pointer), developer)
|
||||
adw_about_window_set_version(.init(pointer), version)
|
||||
}
|
||||
|
||||
/// Set the website.
|
||||
/// - Parameter url: The website.
|
||||
public func website(url: String) {
|
||||
adw_about_window_set_website(.init(pointer), url)
|
||||
}
|
||||
|
||||
/// Set the URL for issues.
|
||||
/// - Parameter issues: The issues website.
|
||||
public func issues(url: String) {
|
||||
adw_about_window_set_issue_url(.init(pointer), url)
|
||||
}
|
||||
|
||||
}
|
@ -5,7 +5,35 @@
|
||||
// Created by david-swift on 19.10.23.
|
||||
//
|
||||
|
||||
import Libadwaita
|
||||
import CAdw
|
||||
|
||||
/// A GTUI application window.
|
||||
public typealias GTUIApplicationWindow = Libadwaita.ApplicationWindow
|
||||
public class GTUIApplicationWindow: GTUIWindow {
|
||||
|
||||
/// The window's parent app.
|
||||
public var app: GTUIApp
|
||||
|
||||
/// Initialize the application window.
|
||||
/// - Parameter app: The application.
|
||||
public init(app: GTUIApp) {
|
||||
self.app = app
|
||||
super.init(fields: [:])
|
||||
pointer = adw_application_window_new(app.pointer)?.cast()
|
||||
}
|
||||
|
||||
/// Add a keyboard shortcut.
|
||||
/// - Parameters:
|
||||
/// - shortcut: The keyboard shortcut.
|
||||
/// - id: The action's id.
|
||||
/// - handler: The action's handler.
|
||||
public func addKeyboardShortcut(_ shortcut: String, id: String, handler: @escaping () -> Void) {
|
||||
app.addKeyboardShortcut(shortcut, id: id, window: self, handler: handler)
|
||||
}
|
||||
|
||||
/// Set the window's child.
|
||||
/// - Parameter child: The child.
|
||||
override public func setChild(_ child: OpaquePointer?) {
|
||||
adw_application_window_set_content(pointer?.cast(), child?.cast())
|
||||
}
|
||||
|
||||
}
|
||||
|
138
Sources/Adwaita/Model/User Interface/Window/GTUIFileDialog.swift
Normal file
138
Sources/Adwaita/Model/User Interface/Window/GTUIFileDialog.swift
Normal file
@ -0,0 +1,138 @@
|
||||
//
|
||||
// GTUIFileDialog.swift
|
||||
// Adwaita
|
||||
//
|
||||
// Created by david-swift on 09.12.23.
|
||||
//
|
||||
|
||||
import CAdw
|
||||
import Foundation
|
||||
|
||||
/// A GTUI file dialog window.
|
||||
public class GTUIFileDialog: WindowType {
|
||||
|
||||
/// The file dialog's pointer.
|
||||
public var pointer: OpaquePointer?
|
||||
/// Fields for additional data.
|
||||
public var fields: [String: Any] = [:]
|
||||
/// A link to the file dialog.
|
||||
var selfAddr: UInt64 {
|
||||
unsafeBitCast(self, to: UInt64.self)
|
||||
}
|
||||
/// The parent window.
|
||||
var parent: OpaquePointer?
|
||||
/// Whether the file dialog is an importer.
|
||||
var isImporter = false
|
||||
/// The selected folder in the file dialog.
|
||||
var folder: URL?
|
||||
/// A closure triggered on selecting a file in the dialog.
|
||||
var onResult: (URL) -> Void = { _ in }
|
||||
/// A closure triggered when the dialog is canceled.
|
||||
var onCancel: () -> Void = { }
|
||||
|
||||
/// Initialize the window.
|
||||
public init() {
|
||||
pointer = gtk_file_dialog_new()
|
||||
}
|
||||
|
||||
/// Set the window's parent window.
|
||||
/// - Parameter parent: The parent window.
|
||||
public func setParentWindow(_ parent: WindowType) {
|
||||
if let window = parent as? GTUIWindow {
|
||||
self.parent = .init(window.pointer)
|
||||
}
|
||||
}
|
||||
|
||||
/// Set the initial name.
|
||||
/// - Parameter name: The parent window.
|
||||
public func setInitialName(_ name: String) {
|
||||
gtk_file_dialog_set_initial_name(pointer, name)
|
||||
}
|
||||
|
||||
// swiftlint:disable discouraged_optional_collection
|
||||
/// Set the allowed file extensions.
|
||||
/// - Parameters:
|
||||
/// - extensions: The file extensions.
|
||||
public func setExtensions(_ extensions: [String]?) {
|
||||
if let extensions {
|
||||
let filter = gtk_file_filter_new()
|
||||
for name in extensions {
|
||||
gtk_file_filter_add_suffix(filter, name)
|
||||
}
|
||||
gtk_file_dialog_set_default_filter(pointer, filter)
|
||||
} else {
|
||||
gtk_file_dialog_set_default_filter(pointer, nil)
|
||||
}
|
||||
}
|
||||
// swiftlint:enable discouraged_optional_collection
|
||||
|
||||
/// Display the file dialog.
|
||||
public func show() {
|
||||
if let folder {
|
||||
gtk_file_dialog_set_initial_folder(pointer, g_file_new_for_path(folder.absoluteString))
|
||||
}
|
||||
if isImporter {
|
||||
gtui_filedialog_open(UInt64(Int(bitPattern: pointer)), selfAddr, UInt64(Int(bitPattern: parent)))
|
||||
} else {
|
||||
gtui_filedialog_save(UInt64(Int(bitPattern: pointer)), selfAddr, UInt64(Int(bitPattern: parent)))
|
||||
}
|
||||
}
|
||||
|
||||
/// Run this when a file gets opened.
|
||||
/// - Parameter path: The file path.
|
||||
func onOpen(_ path: String) {
|
||||
let url = URL(fileURLWithPath: path)
|
||||
onResult(url)
|
||||
}
|
||||
|
||||
/// Run this when a file gets saved.
|
||||
/// - Parameter path: The file path.
|
||||
func onSave(_ path: String) {
|
||||
let url = URL(fileURLWithPath: path)
|
||||
onResult(url)
|
||||
}
|
||||
|
||||
/// Run this when the user cancels the action.
|
||||
func onClose() {
|
||||
onCancel()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// Run when a file should be opened.
|
||||
/// - Parameters:
|
||||
/// - ptr: The pointer.
|
||||
/// - file: The path to the file.
|
||||
/// - userData: The file dialog data.
|
||||
@_cdecl("filedialog_on_open_cb")
|
||||
func filedialog_on_open_cb(
|
||||
ptr: UnsafeMutableRawPointer,
|
||||
file: UnsafePointer<CChar>?,
|
||||
userData: UnsafeMutableRawPointer
|
||||
) {
|
||||
let dialog = Unmanaged<GTUIFileDialog>.fromOpaque(userData).takeUnretainedValue()
|
||||
if let file {
|
||||
dialog.onOpen(.init(cString: file))
|
||||
} else {
|
||||
dialog.onClose()
|
||||
}
|
||||
}
|
||||
|
||||
/// Run when a file should be saved.
|
||||
/// - Parameters:
|
||||
/// - ptr: The pointer.
|
||||
/// - file: The path to the file.
|
||||
/// - userData: The file dialog data.
|
||||
@_cdecl("filedialog_on_save_cb")
|
||||
func filedialog_on_save_cb(
|
||||
ptr: UnsafeMutableRawPointer,
|
||||
file: UnsafePointer<CChar>?,
|
||||
userData: UnsafeMutableRawPointer
|
||||
) {
|
||||
let dialog = Unmanaged<GTUIFileDialog>.fromOpaque(userData).takeUnretainedValue()
|
||||
if let file {
|
||||
dialog.onSave(.init(cString: file))
|
||||
} else {
|
||||
dialog.onClose()
|
||||
}
|
||||
}
|
@ -5,19 +5,93 @@
|
||||
// Created by david-swift on 12.10.23.
|
||||
//
|
||||
|
||||
import Libadwaita
|
||||
import CAdw
|
||||
|
||||
/// A GTUI window.
|
||||
public typealias GTUIWindow = Libadwaita.Window
|
||||
public class GTUIWindow: WindowType {
|
||||
|
||||
extension GTUIWindow: WindowType {
|
||||
/// The window's pointer.
|
||||
public var pointer: UnsafeMutablePointer<GtkWindow>?
|
||||
/// Fields for additional information.
|
||||
public var fields: [String: Any] = [:]
|
||||
|
||||
/// Initialize the window.
|
||||
public init() {
|
||||
pointer = adw_window_new()?.cast()
|
||||
}
|
||||
|
||||
/// Initialize the window, but not the pointer.
|
||||
/// - Parameter fields: The fields.
|
||||
init(fields: [String: Any]) {
|
||||
self.fields = fields
|
||||
}
|
||||
|
||||
/// Set the default window size.
|
||||
/// - Parameters:
|
||||
/// - width: The width.
|
||||
/// - height: The height.
|
||||
public func setDefaultSize(width: Int?, height: Int?) {
|
||||
gtk_window_set_default_size(pointer, width?.cInt ?? -1, height?.cInt ?? -1)
|
||||
}
|
||||
|
||||
/// Set the resizability.
|
||||
/// - Parameter resizable: Whether the window is resizable.
|
||||
public func setResizability(_ resizable: Bool) {
|
||||
gtk_window_set_resizable(pointer, resizable.cBool)
|
||||
}
|
||||
|
||||
/// Set the deletability.
|
||||
/// - Parameter deletable: Whether the window is deletable.
|
||||
public func setDeletability(_ deletable: Bool) {
|
||||
gtk_window_set_deletable(pointer, deletable.cBool)
|
||||
}
|
||||
|
||||
/// Set the window title.
|
||||
/// - Parameter title: The window's title.
|
||||
public func setTitle(_ title: String) {
|
||||
gtk_window_set_title(pointer, title)
|
||||
}
|
||||
|
||||
/// Set the window's child.
|
||||
/// - Parameter child: The child.
|
||||
public func setChild(_ child: OpaquePointer?) {
|
||||
gtk_window_set_child(pointer, child?.cast())
|
||||
}
|
||||
|
||||
/// Present the window.
|
||||
public func show() {
|
||||
gtk_window_present(pointer)
|
||||
}
|
||||
|
||||
/// Observe when the window is being closed.
|
||||
/// - Parameter observer: The signal closure.
|
||||
public func observeHide(observer: @escaping () -> Void) {
|
||||
let hideObserver = ViewStorage.SignalData(closure: observer)
|
||||
self.fields["observe-hide"] = hideObserver
|
||||
g_signal_connect_data(
|
||||
pointer?.cast(),
|
||||
"destroy",
|
||||
unsafeBitCast(hideObserver.handler, to: GCallback.self),
|
||||
Unmanaged.passUnretained(hideObserver).toOpaque().cast(),
|
||||
nil,
|
||||
G_CONNECT_AFTER
|
||||
)
|
||||
}
|
||||
|
||||
/// Close the window.
|
||||
public func close() {
|
||||
gtk_window_close(pointer)
|
||||
}
|
||||
|
||||
/// Set the window's parent window.
|
||||
/// - Parameter parent: The parent window.
|
||||
public func setParentWindow(_ parent: WindowType) {
|
||||
// swiftlint:disable prefer_self_in_static_references
|
||||
if let window = parent as? GTUIWindow {
|
||||
self.setParent(window)
|
||||
gtk_window_set_modal(pointer, 1)
|
||||
gtk_window_set_transient_for(pointer, window.pointer)
|
||||
}
|
||||
// swiftlint:enable prefer_self_in_static_references
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -5,8 +5,6 @@
|
||||
// Created by david-swift on 05.08.23.
|
||||
//
|
||||
|
||||
import Libadwaita
|
||||
|
||||
/// A structure representing the content for a certain window type.
|
||||
public protocol WindowScene: WindowSceneGroup {
|
||||
|
||||
|
@ -5,8 +5,6 @@
|
||||
// Created by david-swift on 31.08.23.
|
||||
//
|
||||
|
||||
import Libadwaita
|
||||
|
||||
/// A storage for an app's window.
|
||||
public class WindowStorage {
|
||||
|
||||
|
@ -5,8 +5,6 @@
|
||||
// Created by david-swift on 09.12.23.
|
||||
//
|
||||
|
||||
import Libadwaita
|
||||
|
||||
/// A window type.
|
||||
public protocol WindowType {
|
||||
|
||||
|
33
Sources/Adwaita/View/Banner+.swift
Normal file
33
Sources/Adwaita/View/Banner+.swift
Normal file
@ -0,0 +1,33 @@
|
||||
//
|
||||
// Banner+.swift
|
||||
// Adwaita
|
||||
//
|
||||
// Created by david-swift on 17.01.24.
|
||||
//
|
||||
|
||||
import CAdw
|
||||
|
||||
extension Banner {
|
||||
|
||||
/// Initialize a text widget.
|
||||
/// - Parameters:
|
||||
/// - title: The content.
|
||||
/// - visible: Whether the banner is visible.
|
||||
public init(_ title: String, visible: Bool) {
|
||||
self.init(title: title)
|
||||
self = self.revealed(visible)
|
||||
}
|
||||
|
||||
/// Configure the banner's button.
|
||||
/// - Parameters:
|
||||
/// - label: The button's title.
|
||||
/// - handler: The button's handler.
|
||||
/// - Returns: The banner.
|
||||
public func button(_ label: String, handler: @escaping () -> Void) -> Self {
|
||||
buttonLabel(label)
|
||||
.buttonClicked {
|
||||
handler()
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -1,76 +0,0 @@
|
||||
//
|
||||
// Banner.swift
|
||||
// Adwaita
|
||||
//
|
||||
// Created by david-swift on 03.01.24.
|
||||
//
|
||||
|
||||
import Libadwaita
|
||||
|
||||
/// A banner widget.
|
||||
public struct Banner: Widget {
|
||||
|
||||
/// The content.
|
||||
var title: String
|
||||
/// Whether the banner is visible.
|
||||
var visible: Bool
|
||||
/// The button's label.
|
||||
var buttonLabel: String?
|
||||
/// The button's handler.
|
||||
var handler: () -> Void = { }
|
||||
|
||||
/// Initialize a text widget.
|
||||
/// - Parameters:
|
||||
/// - title: The content.
|
||||
/// - visible: Whether the banner is visible.
|
||||
public init(_ title: String, visible: Bool) {
|
||||
self.title = title
|
||||
self.visible = visible
|
||||
}
|
||||
|
||||
/// Update the view storage of the text widget.
|
||||
/// - Parameters:
|
||||
/// - storage: The view storage.
|
||||
/// - modifiers: Modify views before being updated.
|
||||
public func update(_ storage: ViewStorage, modifiers: [(View) -> View]) {
|
||||
if let banner = storage.view as? Libadwaita.Banner {
|
||||
update(banner: banner)
|
||||
}
|
||||
}
|
||||
|
||||
/// Get the container of the text widget.
|
||||
/// - Returns: The view storage.
|
||||
public func container(modifiers: [(View) -> View]) -> ViewStorage {
|
||||
let banner = Libadwaita.Banner(title)
|
||||
update(banner: banner)
|
||||
return .init(banner)
|
||||
}
|
||||
|
||||
/// Update the banner.
|
||||
/// - Parameter banner: The banner.
|
||||
func update(banner: Libadwaita.Banner) {
|
||||
_ = banner.title(title)
|
||||
if let buttonLabel {
|
||||
_ = banner.buttonLabel(buttonLabel)
|
||||
_ = banner.buttonHandler(handler)
|
||||
}
|
||||
if visible {
|
||||
banner.show()
|
||||
} else {
|
||||
banner.hide()
|
||||
}
|
||||
}
|
||||
|
||||
/// Configure the banner's button.
|
||||
/// - Parameters:
|
||||
/// - label: The button's title.
|
||||
/// - handler: The button's handler.
|
||||
/// - Returns: The banner.
|
||||
public func button(_ label: String, handler: @escaping () -> Void) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.buttonLabel = label
|
||||
newSelf.handler = handler
|
||||
return newSelf
|
||||
}
|
||||
|
||||
}
|
64
Sources/Adwaita/View/Button+.swift
Normal file
64
Sources/Adwaita/View/Button+.swift
Normal file
@ -0,0 +1,64 @@
|
||||
//
|
||||
// Button+.swift
|
||||
// Adwaita
|
||||
//
|
||||
// Created by david-swift on 15.01.24.
|
||||
//
|
||||
|
||||
import CAdw
|
||||
|
||||
/// A button widget.
|
||||
extension Button {
|
||||
|
||||
// swiftlint:disable function_default_parameter_at_end
|
||||
/// Initialize a button.
|
||||
/// - Parameters:
|
||||
/// - label: The button's label.
|
||||
/// - icon: The button's icon.
|
||||
/// - handler: The button's action handler.
|
||||
public init(_ label: String? = nil, icon: Icon, handler: @escaping () -> Void) {
|
||||
self.init()
|
||||
self = self.child {
|
||||
ButtonContent()
|
||||
.label(label)
|
||||
.iconName(icon.string)
|
||||
}
|
||||
self = self.clicked(handler)
|
||||
}
|
||||
// swiftlint:enable function_default_parameter_at_end
|
||||
|
||||
/// Initialize a button.
|
||||
/// - Parameters:
|
||||
/// - label: The buttons label.
|
||||
/// - handler: The button's action handler.
|
||||
public init(_ label: String, handler: @escaping () -> Void) {
|
||||
self.init()
|
||||
self = self.label(label)
|
||||
self = self.clicked(handler)
|
||||
}
|
||||
|
||||
/// Create a keyboard shortcut for an application window from a button.
|
||||
///
|
||||
/// Note that the keyboard shortcut is available after the view has been visible for the first time.
|
||||
/// - Parameters:
|
||||
/// - shortcut: The keyboard shortcut.
|
||||
/// - window: The application window.
|
||||
/// - Returns: The button.
|
||||
public func keyboardShortcut(_ shortcut: String, window: GTUIApplicationWindow) -> Self {
|
||||
window.addKeyboardShortcut(shortcut, id: shortcut) { self.clicked?() }
|
||||
return self
|
||||
}
|
||||
|
||||
/// Create a keyboard shortcut for an application from a button.
|
||||
///
|
||||
/// Note that the keyboard shortcut is available after the view has been visible for the first time.
|
||||
/// - Parameters:
|
||||
/// - shortcut: The keyboard shortcut.
|
||||
/// - window: The application.
|
||||
/// - Returns: The button.
|
||||
public func keyboardShortcut(_ shortcut: String, app: GTUIApp) -> Self {
|
||||
app.addKeyboardShortcut(shortcut, id: shortcut) { self.clicked?() }
|
||||
return self
|
||||
}
|
||||
|
||||
}
|
@ -1,98 +0,0 @@
|
||||
//
|
||||
// Button.swift
|
||||
// Adwaita
|
||||
//
|
||||
// Created by david-swift on 10.09.23.
|
||||
//
|
||||
|
||||
import Libadwaita
|
||||
|
||||
/// A button widget.
|
||||
public struct Button: Widget {
|
||||
|
||||
/// The button's label.
|
||||
var label: String?
|
||||
/// The button's icon.
|
||||
var icon: Icon?
|
||||
/// The button's action handler.
|
||||
var handler: () -> Void
|
||||
|
||||
// swiftlint:disable function_default_parameter_at_end
|
||||
/// Initialize a button.
|
||||
/// - Parameters:
|
||||
/// - label: The button's label.
|
||||
/// - icon: The button's icon.
|
||||
/// - handler: The button's action handler.
|
||||
public init(_ label: String? = nil, icon: Icon, handler: @escaping () -> Void) {
|
||||
self.label = label
|
||||
self.icon = icon
|
||||
self.handler = handler
|
||||
}
|
||||
// swiftlint:enable function_default_parameter_at_end
|
||||
|
||||
/// Initialize a button.
|
||||
/// - Parameters:
|
||||
/// - label: The buttons label.
|
||||
/// - handler: The button's action handler.
|
||||
public init(_ label: String, handler: @escaping () -> Void) {
|
||||
self.label = label
|
||||
self.handler = handler
|
||||
}
|
||||
|
||||
/// Update a button's view storage.
|
||||
/// - Parameters:
|
||||
/// - storage: The view storage.
|
||||
/// - modifiers: Modify views before being updated.
|
||||
public func update(_ storage: ViewStorage, modifiers: [(View) -> View]) {
|
||||
if let button = storage.view as? Libadwaita.Button {
|
||||
let content = button.getContent()
|
||||
if let label {
|
||||
if icon == nil {
|
||||
button.setLabel(label)
|
||||
} else {
|
||||
content?.setLabel(label)
|
||||
}
|
||||
}
|
||||
if let icon {
|
||||
content?.setIcon(icon)
|
||||
}
|
||||
_ = button.handler(handler)
|
||||
}
|
||||
}
|
||||
|
||||
/// Get a button's view storage.
|
||||
/// - Parameter modifiers: Modify views before being updated.
|
||||
/// - Returns: The button's view storage.
|
||||
public func container(modifiers: [(View) -> View]) -> ViewStorage {
|
||||
if let icon {
|
||||
return .init(Libadwaita.Button(label, icon: icon).handler(handler))
|
||||
} else {
|
||||
return .init(Libadwaita.Button(label ?? .init()).handler(handler))
|
||||
}
|
||||
}
|
||||
|
||||
/// Create a keyboard shortcut for an application window from a button.
|
||||
///
|
||||
/// Note that the keyboard shortcut is available after the view has been visible for the first time.
|
||||
/// - Parameters:
|
||||
/// - shortcut: The keyboard shortcut.
|
||||
/// - window: The application window.
|
||||
/// - Returns: The button.
|
||||
public func keyboardShortcut(_ shortcut: String, window: GTUIApplicationWindow) -> Self {
|
||||
window.addKeyboardShortcut(shortcut, id: shortcut, handler: handler)
|
||||
return self
|
||||
}
|
||||
|
||||
/// Create a keyboard shortcut for an application from a button.
|
||||
///
|
||||
/// Note that the keyboard shortcut is available after the view has been visible for the first time.
|
||||
/// - Parameters:
|
||||
/// - shortcut: The keyboard shortcut.
|
||||
/// - window: The application.
|
||||
/// - Returns: The button.
|
||||
public func keyboardShortcut(_ shortcut: String, app: GTUIApp) -> Self {
|
||||
app.addKeyboardShortcut(shortcut, id: shortcut, handler: handler)
|
||||
return self
|
||||
}
|
||||
|
||||
}
|
17
Sources/Adwaita/View/Carousel+.swift
Normal file
17
Sources/Adwaita/View/Carousel+.swift
Normal file
@ -0,0 +1,17 @@
|
||||
//
|
||||
// Carousel+.swift
|
||||
// Adwaita
|
||||
//
|
||||
// Created by david-swift on 18.01.24.
|
||||
//
|
||||
|
||||
extension Carousel {
|
||||
|
||||
/// Set whether long swipes are allowed or not.
|
||||
/// - Parameter longSwipes: Whether long swipes are allowed.
|
||||
/// - Returns: The carousel.
|
||||
public func longSwipes(_ longSwipes: Bool = true) -> Self {
|
||||
allowLongSwipes(longSwipes)
|
||||
}
|
||||
|
||||
}
|
@ -1,49 +0,0 @@
|
||||
//
|
||||
// Carousel.swift
|
||||
// Adwaita
|
||||
//
|
||||
// Created by david-swift on 01.01.24.
|
||||
//
|
||||
|
||||
import Libadwaita
|
||||
|
||||
/// A carousel view.
|
||||
public struct Carousel<Element>: View where Element: Identifiable {
|
||||
|
||||
/// The elements.
|
||||
var elements: [Element]
|
||||
/// The content.
|
||||
var content: (Element) -> Body
|
||||
/// Whether long swipes are allowed.
|
||||
var allowLongSwipes = false
|
||||
|
||||
/// The view.
|
||||
public var view: Body {
|
||||
Container(elements, content: content) {
|
||||
Libadwaita.Carousel()
|
||||
}
|
||||
.inspect { _ = ($0 as? Libadwaita.Carousel)?.longSwipes(allowLongSwipes) }
|
||||
}
|
||||
|
||||
/// Initialize `Carousel`.
|
||||
/// - Parameters:
|
||||
/// - elements: The elements.
|
||||
/// - content: The view for an element.
|
||||
public init(
|
||||
_ elements: [Element],
|
||||
@ViewBuilder content: @escaping (Element) -> Body
|
||||
) {
|
||||
self.content = content
|
||||
self.elements = elements
|
||||
}
|
||||
|
||||
/// Set whether long swipes are allowed or not.
|
||||
/// - Parameter longSwipes: Whether long swipes are allowed.
|
||||
/// - Returns: The carousel.
|
||||
public func longSwipes(_ longSwipes: Bool = true) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.allowLongSwipes = longSwipes
|
||||
return newSelf
|
||||
}
|
||||
|
||||
}
|
@ -1,101 +0,0 @@
|
||||
//
|
||||
// Container.swift
|
||||
// Adwaita
|
||||
//
|
||||
// Created by david-swift on 01.01.24.
|
||||
//
|
||||
|
||||
import LevenshteinTransformations
|
||||
import Libadwaita
|
||||
|
||||
/// A container widget.
|
||||
public struct Container<Type, Element>: Widget
|
||||
where Element: Identifiable, Type: InsertableContainer, Type: NativeWidgetPeer {
|
||||
|
||||
/// The elements.
|
||||
var elements: [Element]
|
||||
/// The content.
|
||||
var content: (Element) -> Body
|
||||
/// Get the container for initialization.
|
||||
var container: () -> Type
|
||||
|
||||
/// The identifier of the elements storage.
|
||||
let elementsID = "elements"
|
||||
|
||||
/// Initialize `Container`.
|
||||
/// - Parameters:
|
||||
/// - elements: The elements.
|
||||
/// - content: The view for an element.
|
||||
/// - container: Get the initial Libadwaita container widget.
|
||||
public init(
|
||||
_ elements: [Element],
|
||||
@ViewBuilder content: @escaping (Element) -> Body,
|
||||
container: @escaping () -> Type
|
||||
) {
|
||||
self.content = content
|
||||
self.elements = elements
|
||||
self.container = container
|
||||
}
|
||||
|
||||
/// Update a view storage.
|
||||
/// - Parameters:
|
||||
/// - storage: The view storage.
|
||||
/// - modifiers: Modify views before being updated.
|
||||
public func update(_ storage: ViewStorage, modifiers: [(View) -> View]) {
|
||||
if let container = storage.view as? Type {
|
||||
var content: [ViewStorage] = storage.content[.mainContent] ?? []
|
||||
updateContainer(container, content: .init { content } set: { content = $0 }, modifiers: modifiers)
|
||||
storage.content[.mainContent] = content
|
||||
for (index, element) in elements.enumerated() {
|
||||
self.content(element).widget(modifiers: modifiers).update(content[index], modifiers: modifiers)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Get a view storage.
|
||||
/// - Parameter modifiers: Modify views before being updated.
|
||||
/// - Returns: The view storage.
|
||||
public func container(modifiers: [(View) -> View]) -> ViewStorage {
|
||||
let container = self.container()
|
||||
var content: [ViewStorage] = []
|
||||
updateContainer(container, content: .init { content } set: { content = $0 }, modifiers: modifiers)
|
||||
return .init(container, content: [.mainContent: content])
|
||||
}
|
||||
|
||||
/// Update the container's content.
|
||||
/// - Parameters:
|
||||
/// - container: The container.
|
||||
/// - content: The content's view storage.
|
||||
/// - modifiers: The view modifiers.
|
||||
func updateContainer(_ container: Type, content: Binding<[ViewStorage]>, modifiers: [(View) -> View]) {
|
||||
let old = container.fields[elementsID] as? [Element] ?? []
|
||||
old.identifiableTransform(
|
||||
to: elements,
|
||||
functions: .init { index, element in
|
||||
let widget = getWidget(element: element, modifiers: modifiers)
|
||||
_ = container.removeWidgets([content.wrappedValue[index].view])
|
||||
_ = container.insert(widget.view, at: index)
|
||||
content.wrappedValue.remove(at: index)
|
||||
content.wrappedValue.insert(widget, at: index)
|
||||
} delete: { index in
|
||||
_ = container.removeWidgets([content.wrappedValue[index].view])
|
||||
content.wrappedValue.remove(at: index)
|
||||
} insert: { index, element in
|
||||
let widget = getWidget(element: element, modifiers: modifiers)
|
||||
_ = container.insert(widget.view, at: index)
|
||||
content.wrappedValue.insert(widget, at: index)
|
||||
}
|
||||
)
|
||||
container.fields[elementsID] = elements
|
||||
}
|
||||
|
||||
/// Get the view storage of an element.
|
||||
/// - Parameters:
|
||||
/// - element: The element.
|
||||
/// - modifiers: The modifiers.
|
||||
/// - Returns: The view storage.
|
||||
func getWidget(element: Element, modifiers: [(View) -> View]) -> ViewStorage {
|
||||
self.content(element).widget(modifiers: modifiers).container(modifiers: modifiers)
|
||||
}
|
||||
|
||||
}
|
17
Sources/Adwaita/View/Forms/ActionRow+.swift
Normal file
17
Sources/Adwaita/View/Forms/ActionRow+.swift
Normal file
@ -0,0 +1,17 @@
|
||||
//
|
||||
// ActionRow+.swift
|
||||
// Adwaita
|
||||
//
|
||||
// Created by david-swift on 20.01.24.
|
||||
//
|
||||
|
||||
/// A form content row showing a title and optionally a subtitle and widgets.
|
||||
extension ActionRow {
|
||||
|
||||
/// Initialize an action row.
|
||||
/// - Parameter title: The row's title.
|
||||
public init(_ title: String) {
|
||||
self = self.title(title)
|
||||
}
|
||||
|
||||
}
|
@ -1,99 +0,0 @@
|
||||
//
|
||||
// ActionRow.swift
|
||||
// Adwaita
|
||||
//
|
||||
// Created by david-swift on 03.01.24.
|
||||
//
|
||||
|
||||
import Libadwaita
|
||||
|
||||
/// A form content row showing a title and optionally a subtitle and widgets.
|
||||
public struct ActionRow: Widget {
|
||||
|
||||
/// The title.
|
||||
var title: String
|
||||
/// The subtitle.
|
||||
var subtitle = ""
|
||||
/// The prefix.
|
||||
var prefix: Body = []
|
||||
/// The suffix.
|
||||
var suffix: Body = []
|
||||
|
||||
/// The identifier for the prefix content.
|
||||
let prefixID = "prefix"
|
||||
/// The identifier for the suffix content.
|
||||
let suffixID = "suffix"
|
||||
|
||||
/// Initialize an action row.
|
||||
/// - Parameter title: The row's title.
|
||||
public init(_ title: String) {
|
||||
self.title = title
|
||||
}
|
||||
|
||||
/// Update a view storage.
|
||||
/// - Parameters:
|
||||
/// - storage: The view storage.
|
||||
/// - modifiers: Modify views before being updated.
|
||||
public func update(_ storage: ViewStorage, modifiers: [(View) -> View]) {
|
||||
if let row = storage.view as? Libadwaita.ActionRow {
|
||||
update(row: row)
|
||||
}
|
||||
if let prefixStorage = storage.content[prefixID]?.first {
|
||||
prefix.widget(modifiers: modifiers).update(prefixStorage, modifiers: modifiers)
|
||||
}
|
||||
if let suffixStorage = storage.content[suffixID]?.first {
|
||||
suffix.widget(modifiers: modifiers).update(suffixStorage, modifiers: modifiers)
|
||||
}
|
||||
}
|
||||
|
||||
/// Get a view storage.
|
||||
/// - Parameter modifiers: Modify views before being updated.
|
||||
/// - Returns: The view storage.
|
||||
public func container(modifiers: [(View) -> View]) -> ViewStorage {
|
||||
let row: Libadwaita.ActionRow = .init(title: title, subtitle: subtitle)
|
||||
let prefixContent = prefix.widget(modifiers: modifiers).container(modifiers: modifiers)
|
||||
let suffixContent = suffix.widget(modifiers: modifiers).container(modifiers: modifiers)
|
||||
if !prefix.isEmpty {
|
||||
_ = row.addPrefix(prefixContent.view)
|
||||
}
|
||||
if !suffix.isEmpty {
|
||||
_ = row.addSuffix(suffixContent.view)
|
||||
}
|
||||
return .init(row, content: [prefixID: [prefixContent], suffixID: [suffixContent]])
|
||||
}
|
||||
|
||||
/// Update the action row.
|
||||
/// - Parameter row: The action row.
|
||||
func update(row: Libadwaita.ActionRow) {
|
||||
_ = row.title(title)
|
||||
_ = row.subtitle(subtitle)
|
||||
}
|
||||
|
||||
/// Set the action row's subtitle.
|
||||
/// - Parameter subtitle: The subtitle.
|
||||
/// - Returns: The action row.
|
||||
public func subtitle(_ subtitle: String) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.subtitle = subtitle
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// Set the action row's prefix view.
|
||||
/// - Parameter prefix: The prefix.
|
||||
/// - Returns: The action row.
|
||||
public func prefix(@ViewBuilder _ prefix: @escaping () -> Body) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.prefix = prefix()
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// Set the action row's suffix view.
|
||||
/// - Parameter suffix: The suffix.
|
||||
/// - Returns: The action row.
|
||||
public func suffix(@ViewBuilder _ suffix: @escaping () -> Body) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.suffix = suffix()
|
||||
return newSelf
|
||||
}
|
||||
|
||||
}
|
61
Sources/Adwaita/View/Forms/ComboRow+.swift
Normal file
61
Sources/Adwaita/View/Forms/ComboRow+.swift
Normal file
@ -0,0 +1,61 @@
|
||||
//
|
||||
// ComboRow+.swift
|
||||
// Adwaita
|
||||
//
|
||||
// Created by david-swift on 20.01.24.
|
||||
//
|
||||
|
||||
import CAdw
|
||||
import LevenshteinTransformations
|
||||
|
||||
/// A row for selecting an element out of a list of elements.
|
||||
extension ComboRow {
|
||||
|
||||
static var values: String { "values" }
|
||||
static var stringList: String { "string-list" }
|
||||
|
||||
/// Initialize a combo row.
|
||||
/// - Parameters:
|
||||
/// - title: The row's title.
|
||||
/// - selection: The selected value.
|
||||
/// - values: The available values.
|
||||
public init<Element>(
|
||||
_ title: String,
|
||||
selection: Binding<Element.ID>,
|
||||
values: [Element]
|
||||
) where Element: Identifiable, Element: CustomStringConvertible {
|
||||
self = self.title(title)
|
||||
self = self.selected(.init {
|
||||
.init(values.firstIndex { $0.id == selection.wrappedValue } ?? 0)
|
||||
} set: { index in
|
||||
if let id = values[safe: .init(index)]?.id {
|
||||
selection.wrappedValue = id
|
||||
}
|
||||
})
|
||||
appearFunctions.append { storage in
|
||||
let list = gtk_string_list_new(nil)
|
||||
storage.fields[Self.stringList] = list
|
||||
adw_combo_row_set_model(storage.pointer?.cast(), list)
|
||||
}
|
||||
updateFunctions.append { storage in
|
||||
if let list = storage.fields[Self.stringList] as? OpaquePointer {
|
||||
let old = storage.fields[Self.values] as? [Element] ?? []
|
||||
var new = values.filter { element in !old.contains { $0.id == element.id } }
|
||||
new = old + new
|
||||
old.identifiableTransform(
|
||||
to: new,
|
||||
functions: .init { index, element in
|
||||
gtk_string_list_remove(list, .init(index))
|
||||
gtk_string_list_append(list, element.description)
|
||||
} delete: { index in
|
||||
gtk_string_list_remove(list, .init(index))
|
||||
} insert: { _, element in
|
||||
gtk_string_list_append(list, element.description)
|
||||
}
|
||||
)
|
||||
storage.fields[Self.values] = new
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -1,132 +0,0 @@
|
||||
//
|
||||
// ComboRow.swift
|
||||
// Adwaita
|
||||
//
|
||||
// Created by david-swift on 04.01.24.
|
||||
//
|
||||
|
||||
import Libadwaita
|
||||
|
||||
/// A row for selecting an element out of a list of elements.
|
||||
public struct ComboRow<Element>: Widget
|
||||
where Element: CustomStringConvertible, Element: Identifiable, Element: Equatable {
|
||||
|
||||
/// The title.
|
||||
var title: String
|
||||
/// The selected element.
|
||||
@Binding var selection: Element.ID
|
||||
/// The content.
|
||||
var content: [Element]
|
||||
/// The subtitle.
|
||||
var subtitle = ""
|
||||
/// The prefix.
|
||||
var prefix: Body = []
|
||||
/// The suffix.
|
||||
var suffix: Body = []
|
||||
|
||||
/// The identifier for the prefix content.
|
||||
let prefixID = "prefix"
|
||||
/// The identifier for the suffix content.
|
||||
let suffixID = "suffix"
|
||||
|
||||
/// The identifier for the elements.
|
||||
let elementsID = "elements"
|
||||
|
||||
/// Initialize a combo row.
|
||||
/// - Parameters:
|
||||
/// - title: The row's title.
|
||||
/// - selection: The selected value.
|
||||
/// - values: The available values.
|
||||
public init(_ title: String, selection: Binding<Element.ID>, values: [Element]) {
|
||||
self.title = title
|
||||
self._selection = selection
|
||||
content = values
|
||||
}
|
||||
|
||||
/// Update a view storage.
|
||||
/// - Parameters:
|
||||
/// - storage: The view storage.
|
||||
/// - modifiers: Modify views before being updated.
|
||||
public func update(_ storage: ViewStorage, modifiers: [(View) -> View]) {
|
||||
if let row = storage.view as? Libadwaita.ComboRow {
|
||||
update(row: row)
|
||||
}
|
||||
if let prefixStorage = storage.content[prefixID]?.first {
|
||||
prefix.widget(modifiers: modifiers).update(prefixStorage, modifiers: modifiers)
|
||||
}
|
||||
if let suffixStorage = storage.content[suffixID]?.first {
|
||||
suffix.widget(modifiers: modifiers).update(suffixStorage, modifiers: modifiers)
|
||||
}
|
||||
}
|
||||
|
||||
/// Get a view storage.
|
||||
/// - Parameter modifiers: Modify views before being updated.
|
||||
/// - Returns: The view storage.
|
||||
public func container(modifiers: [(View) -> View]) -> ViewStorage {
|
||||
let row: Libadwaita.ComboRow = .init(title: title, subtitle: subtitle)
|
||||
let prefixContent = prefix.widget(modifiers: modifiers).container(modifiers: modifiers)
|
||||
let suffixContent = suffix.widget(modifiers: modifiers).container(modifiers: modifiers)
|
||||
if !prefix.isEmpty {
|
||||
_ = row.addPrefix(prefixContent.view)
|
||||
}
|
||||
if !suffix.isEmpty {
|
||||
_ = row.addSuffix(suffixContent.view)
|
||||
}
|
||||
update(row: row)
|
||||
_ = row.onChange {
|
||||
if let element = content.first(where: { $0.description == row.selected() }), element.id != selection {
|
||||
selection = element.id
|
||||
}
|
||||
}
|
||||
return .init(row, content: [prefixID: [prefixContent], suffixID: [suffixContent]])
|
||||
}
|
||||
|
||||
/// Update the combo row.
|
||||
/// - Parameter row: The combo row.
|
||||
func update(row: Libadwaita.ComboRow) {
|
||||
_ = row.title(title)
|
||||
_ = row.subtitle(subtitle)
|
||||
let oldElements = row.fields[elementsID] as? [Element] ?? []
|
||||
if oldElements != content {
|
||||
for element in oldElements {
|
||||
row.remove(at: 0)
|
||||
}
|
||||
for element in content {
|
||||
row.append(element.description)
|
||||
}
|
||||
}
|
||||
let index = content.firstIndex { $0.id == selection } ?? 0
|
||||
if row.selected() != content[safe: index]?.description {
|
||||
row.select(at: index)
|
||||
}
|
||||
row.fields[elementsID] = content
|
||||
}
|
||||
|
||||
/// Set the combo row's subtitle.
|
||||
/// - Parameter subtitle: The subtitle.
|
||||
/// - Returns: The combo row.
|
||||
public func subtitle(_ subtitle: String) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.subtitle = subtitle
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// Set the combo row's prefix view.
|
||||
/// - Parameter prefix: The prefix.
|
||||
/// - Returns: The combo row.
|
||||
public func prefix(@ViewBuilder _ prefix: @escaping () -> Body) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.prefix = prefix()
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// Set the combo row's suffix view.
|
||||
/// - Parameter suffix: The suffix.
|
||||
/// - Returns: The combo row.
|
||||
public func suffix(@ViewBuilder _ suffix: @escaping () -> Body) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.suffix = suffix()
|
||||
return newSelf
|
||||
}
|
||||
|
||||
}
|
59
Sources/Adwaita/View/Forms/EntryRow+.swift
Normal file
59
Sources/Adwaita/View/Forms/EntryRow+.swift
Normal file
@ -0,0 +1,59 @@
|
||||
//
|
||||
// EntryRow+.swift
|
||||
// Adwaita
|
||||
//
|
||||
// Created by david-swift on 20.01.24.
|
||||
//
|
||||
|
||||
import CAdw
|
||||
|
||||
extension EntryRow {
|
||||
|
||||
static var textField: String { "text" }
|
||||
|
||||
/// Initialize an entry row.
|
||||
/// - Parameters:
|
||||
/// - title: The row's title.
|
||||
/// - text: The text.
|
||||
public init(_ title: String, text: Binding<String>) {
|
||||
self.init()
|
||||
self = self.title(title)
|
||||
appearFunctions.append { storage in
|
||||
storage.fields[Self.textField] = text
|
||||
storage.notify(name: "text") {
|
||||
if let binding = storage.fields[Self.textField] as? Binding<String> {
|
||||
binding.wrappedValue = .init(cString: gtk_editable_get_text(storage.pointer))
|
||||
}
|
||||
}
|
||||
}
|
||||
updateFunctions.append { storage in
|
||||
if text.wrappedValue != .init(cString: gtk_editable_get_text(storage.pointer)) {
|
||||
gtk_editable_set_text(storage.pointer, text.wrappedValue)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Set the entry row's subtitle.
|
||||
/// - Parameter subtitle: The subtitle.
|
||||
/// - Returns: The entry row.
|
||||
public func onSubmit(_ onSubmit: @escaping () -> Void) -> Self {
|
||||
showApplyButton()
|
||||
.apply(onSubmit)
|
||||
}
|
||||
|
||||
/// Let the user securely enter private text.
|
||||
/// - Parameter: The text.
|
||||
/// - Returns: The entry row.
|
||||
public func secure(text: Binding<String>? = nil) -> PasswordEntryRow {
|
||||
.init(title ?? "", text: text ?? .constant(""))
|
||||
.activatesDefault(activatesDefault)
|
||||
.enableEmojiCompletion(enableEmojiCompletion)
|
||||
.showApplyButton(showApplyButton)
|
||||
.titleSelectable(titleSelectable)
|
||||
.useMarkup(useMarkup)
|
||||
.useUnderline(useUnderline)
|
||||
.apply(apply ?? { })
|
||||
.entryActivated(entryActivated ?? { })
|
||||
}
|
||||
|
||||
}
|
@ -1,136 +0,0 @@
|
||||
//
|
||||
// EntryRow.swift
|
||||
// Adwaita
|
||||
//
|
||||
// Created by david-swift on 04.01.24.
|
||||
//
|
||||
|
||||
import Libadwaita
|
||||
|
||||
/// A form content row accepting text input.
|
||||
public struct EntryRow: Widget {
|
||||
|
||||
/// The title.
|
||||
var title: String
|
||||
/// The text.
|
||||
@Binding var text: String
|
||||
/// The prefix.
|
||||
var prefix: Body = []
|
||||
/// The suffix.
|
||||
var suffix: Body = []
|
||||
/// The handler that gets executed when the user submits the content.
|
||||
var onSubmit: (() -> Void)?
|
||||
/// Whether the password entry row should be used.
|
||||
var password = false
|
||||
|
||||
/// The identifier for the prefix content.
|
||||
let prefixID = "prefix"
|
||||
/// The identifier for the suffix content.
|
||||
let suffixID = "suffix"
|
||||
|
||||
/// The identifier for the title.
|
||||
let titleID = "title"
|
||||
|
||||
/// Initialize an entry row.
|
||||
/// - Parameters:
|
||||
/// - title: The row's title.
|
||||
/// - text: The text.
|
||||
public init(_ title: String, text: Binding<String>) {
|
||||
self.title = title
|
||||
self._text = text
|
||||
}
|
||||
|
||||
/// Update a view storage.
|
||||
/// - Parameters:
|
||||
/// - storage: The view storage.
|
||||
/// - modifiers: Modify views before being updated.
|
||||
public func update(_ storage: ViewStorage, modifiers: [(View) -> View]) {
|
||||
if let row = storage.view as? Libadwaita.EntryRow {
|
||||
update(row: row)
|
||||
}
|
||||
if let prefixStorage = storage.content[prefixID]?.first {
|
||||
prefix.widget(modifiers: modifiers).update(prefixStorage, modifiers: modifiers)
|
||||
}
|
||||
if let suffixStorage = storage.content[suffixID]?.first {
|
||||
suffix.widget(modifiers: modifiers).update(suffixStorage, modifiers: modifiers)
|
||||
}
|
||||
}
|
||||
|
||||
/// Get a view storage.
|
||||
/// - Parameter modifiers: Modify views before being updated.
|
||||
/// - Returns: The view storage.
|
||||
public func container(modifiers: [(View) -> View]) -> ViewStorage {
|
||||
let row: Libadwaita.EntryRow
|
||||
if password {
|
||||
row = PasswordEntryRow(title: title)
|
||||
} else {
|
||||
row = .init(title: title)
|
||||
}
|
||||
let prefixContent = prefix.widget(modifiers: modifiers).container(modifiers: modifiers)
|
||||
let suffixContent = suffix.widget(modifiers: modifiers).container(modifiers: modifiers)
|
||||
if !prefix.isEmpty {
|
||||
_ = row.addPrefix(prefixContent.view)
|
||||
}
|
||||
if !suffix.isEmpty {
|
||||
_ = row.addSuffix(suffixContent.view)
|
||||
}
|
||||
_ = row.changeHandler {
|
||||
if row.contents() != text {
|
||||
text = row.contents()
|
||||
}
|
||||
}
|
||||
update(row: row)
|
||||
return .init(row, content: [prefixID: [prefixContent], suffixID: [suffixContent]])
|
||||
}
|
||||
|
||||
/// Update the entry row.
|
||||
/// - Parameter row: The entry row.
|
||||
func update(row: Libadwaita.EntryRow) {
|
||||
if row.fields[titleID] as? String != title {
|
||||
_ = row.title(title)
|
||||
row.fields[titleID] = title
|
||||
}
|
||||
if row.contents() != text {
|
||||
row.setContents(text)
|
||||
}
|
||||
if let onSubmit {
|
||||
_ = row.submitHandler(onSubmit)
|
||||
}
|
||||
}
|
||||
|
||||
/// Set the entry row's subtitle.
|
||||
/// - Parameter subtitle: The subtitle.
|
||||
/// - Returns: The entry row.
|
||||
public func onSubmit(_ onSubmit: @escaping () -> Void) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.onSubmit = onSubmit
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// Set the entry row's prefix view.
|
||||
/// - Parameter prefix: The prefix.
|
||||
/// - Returns: The entry row.
|
||||
public func prefix(@ViewBuilder _ prefix: @escaping () -> Body) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.prefix = prefix()
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// Set the entry row's suffix view.
|
||||
/// - Parameter suffix: The suffix.
|
||||
/// - Returns: The entry row.
|
||||
public func suffix(@ViewBuilder _ suffix: @escaping () -> Body) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.suffix = suffix()
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// Let the user securely enter private text.
|
||||
/// - Returns: The entry row.
|
||||
public func secure() -> Self {
|
||||
var newSelf = self
|
||||
newSelf.password = true
|
||||
return newSelf
|
||||
}
|
||||
|
||||
}
|
@ -5,43 +5,24 @@
|
||||
// Created by david-swift on 03.01.24.
|
||||
//
|
||||
|
||||
import Libadwaita
|
||||
import CAdw
|
||||
|
||||
/// A list with no dynamic content styled as a boxed list.
|
||||
public struct Form: Widget {
|
||||
public struct Form: View {
|
||||
|
||||
/// The content.
|
||||
var content: () -> Body
|
||||
var content: Body
|
||||
|
||||
/// The view's body.
|
||||
public var view: Body {
|
||||
List([Int](content.indices), selection: nil) { index in content[index] }
|
||||
.style("boxed-list")
|
||||
}
|
||||
|
||||
/// Initialize a `Form`.
|
||||
/// - Parameter content: The view content, usually different kind of rows.
|
||||
public init(@ViewBuilder content: @escaping () -> Body) {
|
||||
self.content = content
|
||||
}
|
||||
|
||||
/// Update a view storage.
|
||||
/// - Parameters:
|
||||
/// - storage: The view storage.
|
||||
/// - modifiers: Modify views before being updated.
|
||||
public func update(_ storage: ViewStorage, modifiers: [(View) -> View]) {
|
||||
content().update(storage.content[.mainContent] ?? [], modifiers: modifiers)
|
||||
}
|
||||
|
||||
/// Get a view storage.
|
||||
/// - Parameter modifiers: Modify views before being updated.
|
||||
/// - Returns: The view storage.
|
||||
public func container(modifiers: [(View) -> View]) -> ViewStorage {
|
||||
let form: ListBox = .init()
|
||||
_ = form
|
||||
.noSelection()
|
||||
.addStyle("boxed-list")
|
||||
var content: [ViewStorage] = []
|
||||
for element in self.content() {
|
||||
let widget = element.storage(modifiers: modifiers)
|
||||
_ = form.append(widget.view)
|
||||
content.append(widget)
|
||||
}
|
||||
return .init(form, content: [.mainContent: content])
|
||||
self.content = content()
|
||||
}
|
||||
|
||||
}
|
||||
|
30
Sources/Adwaita/View/Forms/FormSection+.swift
Normal file
30
Sources/Adwaita/View/Forms/FormSection+.swift
Normal file
@ -0,0 +1,30 @@
|
||||
//
|
||||
// FormSection+.swift
|
||||
// Adwaita
|
||||
//
|
||||
// Created by david-swift on 20.01.24.
|
||||
//
|
||||
|
||||
/// A section usually groups forms.
|
||||
public typealias FormSection = PreferencesGroup
|
||||
|
||||
extension FormSection {
|
||||
|
||||
/// Initialize a form section.
|
||||
/// - Parameters:
|
||||
/// - title: The title.
|
||||
/// - content: The content, usually one or more forms.
|
||||
public init(_ title: String, @ViewBuilder content: @escaping () -> Body) {
|
||||
self.init()
|
||||
self = self.title(title)
|
||||
self = self.child(content)
|
||||
}
|
||||
|
||||
/// Set the form section's suffix view.
|
||||
/// - Parameter suffix: The suffix.
|
||||
/// - Returns: The form section.
|
||||
public func suffix(@ViewBuilder _ suffix: @escaping () -> Body) -> Self {
|
||||
headerSuffix(suffix)
|
||||
}
|
||||
|
||||
}
|
@ -1,89 +0,0 @@
|
||||
//
|
||||
// FormSection.swift
|
||||
// Adwaita
|
||||
//
|
||||
// Created by david-swift on 03.01.24.
|
||||
//
|
||||
|
||||
import Libadwaita
|
||||
|
||||
/// A section usually groups forms.
|
||||
public struct FormSection: Widget {
|
||||
|
||||
/// The title.
|
||||
var title: String
|
||||
/// The content.
|
||||
var content: Body
|
||||
/// The description.
|
||||
var description = ""
|
||||
/// The suffix.
|
||||
var suffix: Body = []
|
||||
|
||||
/// The identifier for the suffix content.
|
||||
let suffixID = "suffix"
|
||||
|
||||
/// Initialize a form section.
|
||||
/// - Parameters:
|
||||
/// - title: The title.
|
||||
/// - content: The content, usually one or more forms.
|
||||
public init(_ title: String, @ViewBuilder content: () -> Body) {
|
||||
self.title = title
|
||||
self.content = content()
|
||||
}
|
||||
|
||||
/// Update a view storage.
|
||||
/// - Parameters:
|
||||
/// - storage: The view storage.
|
||||
/// - modifiers: Modify views before being updated.
|
||||
public func update(_ storage: ViewStorage, modifiers: [(View) -> View]) {
|
||||
if let group = storage.view as? Libadwaita.PreferencesGroup {
|
||||
update(group: group)
|
||||
}
|
||||
if let storage = storage.content[.mainContent]?.first {
|
||||
content.widget(modifiers: modifiers).update(storage, modifiers: modifiers)
|
||||
}
|
||||
if let suffixStorage = storage.content[suffixID]?.first {
|
||||
suffix.widget(modifiers: modifiers).update(suffixStorage, modifiers: modifiers)
|
||||
}
|
||||
}
|
||||
|
||||
/// Get a view storage.
|
||||
/// - Parameter modifiers: Modify views before being updated.
|
||||
/// - Returns: The view storage.
|
||||
public func container(modifiers: [(View) -> View]) -> ViewStorage {
|
||||
let group: Libadwaita.PreferencesGroup = .init(name: title, description: description)
|
||||
let content = content.widget(modifiers: modifiers).container(modifiers: modifiers)
|
||||
let suffixContent = suffix.widget(modifiers: modifiers).container(modifiers: modifiers)
|
||||
group.add(content.view)
|
||||
if !suffix.isEmpty {
|
||||
_ = group.headerSuffix(suffixContent.view)
|
||||
}
|
||||
return .init(group, content: [.mainContent: [content], suffixID: [suffixContent]])
|
||||
}
|
||||
|
||||
/// Update the form section.
|
||||
/// - Parameter group: The form section.
|
||||
func update(group: Libadwaita.PreferencesGroup) {
|
||||
_ = group.title(title)
|
||||
_ = group.description(description)
|
||||
}
|
||||
|
||||
/// Set the form section's description.
|
||||
/// - Parameter description: The description.
|
||||
/// - Returns: The form section.
|
||||
public func description(_ description: String) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.description = description
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// Set the form section's suffix view.
|
||||
/// - Parameter suffix: The suffix.
|
||||
/// - Returns: The form section.
|
||||
public func suffix(@ViewBuilder _ suffix: @escaping () -> Body) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.suffix = suffix()
|
||||
return newSelf
|
||||
}
|
||||
|
||||
}
|
43
Sources/Adwaita/View/Forms/PasswordEntryRow+.swift
Normal file
43
Sources/Adwaita/View/Forms/PasswordEntryRow+.swift
Normal file
@ -0,0 +1,43 @@
|
||||
//
|
||||
// PasswordEntryRow+.swift
|
||||
// Adwaita
|
||||
//
|
||||
// Created by david-swift on 20.01.24.
|
||||
//
|
||||
|
||||
import CAdw
|
||||
|
||||
extension PasswordEntryRow {
|
||||
|
||||
static var textField: String { "text" }
|
||||
|
||||
/// Initialize an entry row.
|
||||
/// - Parameters:
|
||||
/// - title: The row's title.
|
||||
/// - text: The text.
|
||||
public init(_ title: String, text: Binding<String>) {
|
||||
self.init()
|
||||
self = self.title(title)
|
||||
appearFunctions.append { storage in
|
||||
storage.fields[Self.textField] = text
|
||||
storage.notify(name: "text") {
|
||||
if let binding = storage.fields[Self.textField] as? Binding<String> {
|
||||
binding.wrappedValue = .init(cString: gtk_editable_get_text(storage.pointer))
|
||||
}
|
||||
}
|
||||
}
|
||||
updateFunctions.append { storage in
|
||||
if text.wrappedValue != .init(cString: gtk_editable_get_text(storage.pointer)) {
|
||||
gtk_editable_set_text(storage.pointer, text.wrappedValue)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Set the entry row's subtitle.
|
||||
/// - Parameter subtitle: The subtitle.
|
||||
/// - Returns: The entry row.
|
||||
public func onSubmit(_ onSubmit: @escaping () -> Void) -> Self {
|
||||
apply(onSubmit)
|
||||
}
|
||||
|
||||
}
|
62
Sources/Adwaita/View/Forms/SpinRow+.swift
Normal file
62
Sources/Adwaita/View/Forms/SpinRow+.swift
Normal file
@ -0,0 +1,62 @@
|
||||
//
|
||||
// SpinRow+.swift
|
||||
// Adwaita
|
||||
//
|
||||
// Created by david-swift on 20.01.24.
|
||||
//
|
||||
|
||||
import CAdw
|
||||
|
||||
extension SpinRow {
|
||||
|
||||
/// Initialize a spin row.
|
||||
/// - Parameters:
|
||||
/// - title: The row's title.
|
||||
/// - value: The selected value.
|
||||
/// - min: The minimum value.
|
||||
/// - max: The maximum value.
|
||||
public init(_ title: String, value: Binding<Int>, min: Int, max: Int) {
|
||||
self.init(
|
||||
title,
|
||||
value: .init { .init(value.wrappedValue) } set: { value.wrappedValue = .init($0) },
|
||||
min: .init(min),
|
||||
max: .init(max)
|
||||
)
|
||||
}
|
||||
|
||||
/// Initialize a spin row.
|
||||
/// - Parameters:
|
||||
/// - title: The row's title.
|
||||
/// - value: The selected value.
|
||||
/// - min: The minimum value.
|
||||
/// - max: The maximum value.
|
||||
public init(_ title: String, value: Binding<Double>, min: Double, max: Double) {
|
||||
self.init(climbRate: 1, digits: 0)
|
||||
self = self.title(title)
|
||||
self = self.value(value)
|
||||
self = self.step(1)
|
||||
updateFunctions.append { storage in
|
||||
adw_spin_row_set_range(storage.pointer, min, max)
|
||||
}
|
||||
}
|
||||
|
||||
/// Set the difference a single click on the increase/decrease buttons makes.
|
||||
/// - Parameter step: The increase/decrease step.
|
||||
/// - Returns: The spin row.
|
||||
public func step(_ step: Int) -> Self {
|
||||
self.step(.init(step))
|
||||
}
|
||||
|
||||
/// Set the difference a single click on the increase/decrease buttons makes.
|
||||
/// - Parameter step: The increase/decrease step.
|
||||
/// - Returns: The spin row.
|
||||
public func step(_ step: Double) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.updateFunctions.append { storage in
|
||||
let adjustment = adw_spin_row_get_adjustment(storage.pointer)
|
||||
gtk_adjustment_set_step_increment(adjustment, step)
|
||||
}
|
||||
return newSelf
|
||||
}
|
||||
|
||||
}
|
@ -1,149 +0,0 @@
|
||||
//
|
||||
// SpinRow.swift
|
||||
// Adwaita
|
||||
//
|
||||
// Created by david-swift on 04.01.24.
|
||||
//
|
||||
|
||||
import Libadwaita
|
||||
|
||||
/// A spin row lets the user select an integer in a certain range.
|
||||
public struct SpinRow: Widget {
|
||||
|
||||
/// The title.
|
||||
var title: String
|
||||
/// The selected value.
|
||||
@Binding var value: Int
|
||||
/// The minimum value.
|
||||
var min: Int
|
||||
/// The maximum value.
|
||||
var max: Int
|
||||
/// The increase/decrease step.
|
||||
var step = 1
|
||||
/// The subtitle.
|
||||
var subtitle = ""
|
||||
/// The prefix.
|
||||
var prefix: Body = []
|
||||
/// The suffix.
|
||||
var suffix: Body = []
|
||||
|
||||
/// The identifier for the prefix content.
|
||||
let prefixID = "prefix"
|
||||
/// The identifier for the suffix content.
|
||||
let suffixID = "suffix"
|
||||
|
||||
/// The identifier of the configuration field.
|
||||
let configID = "config"
|
||||
|
||||
/// Initialize a spin row.
|
||||
/// - Parameters:
|
||||
/// - title: The row's title.
|
||||
/// - value: The selected value.
|
||||
/// - min: The minimum value.
|
||||
/// - max: The maximum value.
|
||||
public init(_ title: String, value: Binding<Int>, min: Int, max: Int) {
|
||||
self.title = title
|
||||
self._value = value
|
||||
self.min = min
|
||||
self.max = max
|
||||
}
|
||||
|
||||
/// Update a view storage.
|
||||
/// - Parameters:
|
||||
/// - storage: The view storage.
|
||||
/// - modifiers: Modify views before being updated.
|
||||
public func update(_ storage: ViewStorage, modifiers: [(View) -> View]) {
|
||||
if let row = storage.view as? Libadwaita.SpinRow {
|
||||
update(row: row)
|
||||
}
|
||||
if let prefixStorage = storage.content[prefixID]?.first {
|
||||
prefix.widget(modifiers: modifiers).update(prefixStorage, modifiers: modifiers)
|
||||
}
|
||||
if let suffixStorage = storage.content[suffixID]?.first {
|
||||
suffix.widget(modifiers: modifiers).update(suffixStorage, modifiers: modifiers)
|
||||
}
|
||||
}
|
||||
|
||||
/// Get a view storage.
|
||||
/// - Parameter modifiers: Modify views before being updated.
|
||||
/// - Returns: The view storage.
|
||||
public func container(modifiers: [(View) -> View]) -> ViewStorage {
|
||||
let row: Libadwaita.SpinRow = .init(
|
||||
title: title,
|
||||
subtitle: subtitle,
|
||||
min: .init(min),
|
||||
max: .init(max),
|
||||
step: .init(step)
|
||||
)
|
||||
row.fields[configID] = (min, max, step)
|
||||
let prefixContent = prefix.widget(modifiers: modifiers).container(modifiers: modifiers)
|
||||
let suffixContent = suffix.widget(modifiers: modifiers).container(modifiers: modifiers)
|
||||
if !prefix.isEmpty {
|
||||
_ = row.addPrefix(prefixContent.view)
|
||||
}
|
||||
if !suffix.isEmpty {
|
||||
_ = row.addSuffix(suffixContent.view)
|
||||
}
|
||||
_ = row.onChange {
|
||||
let value = Int(row.getValue().rounded())
|
||||
if self.value != value {
|
||||
self.value = value
|
||||
}
|
||||
}
|
||||
update(row: row)
|
||||
return .init(row, content: [prefixID: [prefixContent], suffixID: [suffixContent]])
|
||||
}
|
||||
|
||||
// swiftlint:disable large_tuple
|
||||
/// Update the spin row.
|
||||
/// - Parameter row: The spin row.
|
||||
func update(row: Libadwaita.SpinRow) {
|
||||
_ = row.title(title)
|
||||
_ = row.subtitle(subtitle)
|
||||
if row.fields[configID] as? (Int, Int, Int) ?? (0, 0, 0) != (min, max, step) {
|
||||
_ = row.configuration(min: .init(min), max: .init(max), step: .init(step))
|
||||
row.fields[configID] = (min, max, step)
|
||||
}
|
||||
if row.getValue() != .init(value) {
|
||||
row.setValue(.init(value))
|
||||
}
|
||||
}
|
||||
// swiftlint:enable large_tuple
|
||||
|
||||
/// Set the spin row's subtitle.
|
||||
/// - Parameter subtitle: The subtitle.
|
||||
/// - Returns: The spin row.
|
||||
public func subtitle(_ subtitle: String) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.subtitle = subtitle
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// Set the spin row's prefix view.
|
||||
/// - Parameter prefix: The prefix.
|
||||
/// - Returns: The spin row.
|
||||
public func prefix(@ViewBuilder _ prefix: @escaping () -> Body) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.prefix = prefix()
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// Set the spin row's suffix view.
|
||||
/// - Parameter suffix: The suffix.
|
||||
/// - Returns: The spin row.
|
||||
public func suffix(@ViewBuilder _ suffix: @escaping () -> Body) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.suffix = suffix()
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// Set the difference a single click on the increase/decrease buttons makes.
|
||||
/// - Parameter step: The increase/decrease step.
|
||||
/// - Returns: The spin row.
|
||||
public func step(_ step: Int) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.step = step
|
||||
return newSelf
|
||||
}
|
||||
|
||||
}
|
21
Sources/Adwaita/View/Forms/SwitchRow+.swift
Normal file
21
Sources/Adwaita/View/Forms/SwitchRow+.swift
Normal file
@ -0,0 +1,21 @@
|
||||
//
|
||||
// SwitchRow+.swift
|
||||
// Adwaita
|
||||
//
|
||||
// Created by david-swift on 20.01.24.
|
||||
//
|
||||
|
||||
/// A row representing a boolean state.
|
||||
extension SwitchRow {
|
||||
|
||||
/// Initialize a switch row.
|
||||
/// - Parameters:
|
||||
/// - title: The row's title.
|
||||
/// - isOn: Whether the switch is on.
|
||||
public init(_ title: String, isOn: Binding<Bool>) {
|
||||
self.init()
|
||||
self = self.title(title)
|
||||
self = self.active(isOn)
|
||||
}
|
||||
|
||||
}
|
@ -1,113 +0,0 @@
|
||||
//
|
||||
// SwitchRow.swift
|
||||
// Adwaita
|
||||
//
|
||||
// Created by david-swift on 04.01.24.
|
||||
//
|
||||
|
||||
import Libadwaita
|
||||
|
||||
/// A row representing a boolean state.
|
||||
public struct SwitchRow: Widget {
|
||||
|
||||
/// The title.
|
||||
var title: String
|
||||
/// Whether the switch is activated.
|
||||
@Binding var isOn: Bool
|
||||
/// The subtitle.
|
||||
var subtitle = ""
|
||||
/// The prefix.
|
||||
var prefix: Body = []
|
||||
/// The suffix.
|
||||
var suffix: Body = []
|
||||
|
||||
/// The identifier for the prefix content.
|
||||
let prefixID = "prefix"
|
||||
/// The identifier for the suffix content.
|
||||
let suffixID = "suffix"
|
||||
|
||||
/// Initialize a switch row.
|
||||
/// - Parameters:
|
||||
/// - title: The row's title.
|
||||
/// - isOn: Whether the switch is on.
|
||||
public init(_ title: String, isOn: Binding<Bool>) {
|
||||
self.title = title
|
||||
self._isOn = isOn
|
||||
}
|
||||
|
||||
/// Update a view storage.
|
||||
/// - Parameters:
|
||||
/// - storage: The view storage.
|
||||
/// - modifiers: Modify views before being updated.
|
||||
public func update(_ storage: ViewStorage, modifiers: [(View) -> View]) {
|
||||
if let row = storage.view as? Libadwaita.SwitchRow {
|
||||
update(row: row)
|
||||
}
|
||||
if let prefixStorage = storage.content[prefixID]?.first {
|
||||
prefix.widget(modifiers: modifiers).update(prefixStorage, modifiers: modifiers)
|
||||
}
|
||||
if let suffixStorage = storage.content[suffixID]?.first {
|
||||
suffix.widget(modifiers: modifiers).update(suffixStorage, modifiers: modifiers)
|
||||
}
|
||||
}
|
||||
|
||||
/// Get a view storage.
|
||||
/// - Parameter modifiers: Modify views before being updated.
|
||||
/// - Returns: The view storage.
|
||||
public func container(modifiers: [(View) -> View]) -> ViewStorage {
|
||||
let row: Libadwaita.SwitchRow = .init(title: title, subtitle: subtitle)
|
||||
let prefixContent = prefix.widget(modifiers: modifiers).container(modifiers: modifiers)
|
||||
let suffixContent = suffix.widget(modifiers: modifiers).container(modifiers: modifiers)
|
||||
if !prefix.isEmpty {
|
||||
_ = row.addPrefix(prefixContent.view)
|
||||
}
|
||||
if !suffix.isEmpty {
|
||||
_ = row.addSuffix(suffixContent.view)
|
||||
}
|
||||
_ = row.onChange {
|
||||
if row.getActive() != isOn {
|
||||
isOn = row.getActive()
|
||||
}
|
||||
}
|
||||
update(row: row)
|
||||
return .init(row, content: [prefixID: [prefixContent], suffixID: [suffixContent]])
|
||||
}
|
||||
|
||||
/// Update the switch row.
|
||||
/// - Parameter row: The switch row.
|
||||
func update(row: Libadwaita.SwitchRow) {
|
||||
_ = row.title(title)
|
||||
_ = row.subtitle(subtitle)
|
||||
if row.getActive() != isOn {
|
||||
row.setActive(isOn)
|
||||
}
|
||||
}
|
||||
|
||||
/// Set the switch row's subtitle.
|
||||
/// - Parameter subtitle: The subtitle.
|
||||
/// - Returns: The switch row.
|
||||
public func subtitle(_ subtitle: String) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.subtitle = subtitle
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// Set the switch row's prefix view.
|
||||
/// - Parameter prefix: The prefix.
|
||||
/// - Returns: The switch row.
|
||||
public func prefix(@ViewBuilder _ prefix: @escaping () -> Body) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.prefix = prefix()
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// Set the switch row's suffix view.
|
||||
/// - Parameter suffix: The suffix.
|
||||
/// - Returns: The switch row.
|
||||
public func suffix(@ViewBuilder _ suffix: @escaping () -> Body) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.suffix = suffix()
|
||||
return newSelf
|
||||
}
|
||||
|
||||
}
|
334
Sources/Adwaita/View/Generated/ActionRow.swift
Normal file
334
Sources/Adwaita/View/Generated/ActionRow.swift
Normal file
@ -0,0 +1,334 @@
|
||||
//
|
||||
// ActionRow.swift
|
||||
// Adwaita
|
||||
//
|
||||
// Created by auto-generation on 22.01.24.
|
||||
//
|
||||
|
||||
import CAdw
|
||||
import LevenshteinTransformations
|
||||
|
||||
/// A [class@Gtk.ListBoxRow] used to present actions.
|
||||
///
|
||||
/// <picture><source srcset="action-row-dark.png" media="(prefers-color-scheme: dark)"><img src="action-row.png" alt="action-row"></picture>
|
||||
///
|
||||
/// The `AdwActionRow` widget can have a title, a subtitle and an icon. The row
|
||||
/// can receive additional widgets at its end, or prefix widgets at its start.
|
||||
///
|
||||
/// It is convenient to present a preference and its related actions.
|
||||
///
|
||||
/// `AdwActionRow` is unactivatable by default, giving it an activatable widget
|
||||
/// will automatically make it activatable, but unsetting it won't change the
|
||||
/// row's activatability.
|
||||
///
|
||||
/// ## AdwActionRow as GtkBuildable
|
||||
///
|
||||
/// The `AdwActionRow` implementation of the [iface@Gtk.Buildable] interface
|
||||
/// supports adding a child at its end by specifying “suffix” or omitting the
|
||||
/// “type” attribute of a <child> element.
|
||||
///
|
||||
/// It also supports adding a child as a prefix widget by specifying “prefix” as
|
||||
/// the “type” attribute of a <child> element.
|
||||
///
|
||||
/// ## CSS nodes
|
||||
///
|
||||
/// `AdwActionRow` has a main CSS node with name `row`.
|
||||
///
|
||||
/// It contains the subnode `box.header` for its main horizontal box, and
|
||||
/// `box.title` for the vertical box containing the title and subtitle labels.
|
||||
///
|
||||
/// It contains subnodes `label.title` and `label.subtitle` representing
|
||||
/// respectively the title label and subtitle label.
|
||||
public struct ActionRow: Widget {
|
||||
|
||||
/// Additional update functions for type extensions.
|
||||
var updateFunctions: [(ViewStorage) -> Void] = []
|
||||
/// Additional appear functions for type extensions.
|
||||
var appearFunctions: [(ViewStorage) -> Void] = []
|
||||
|
||||
/// The widget to activate when the row is activated.
|
||||
///
|
||||
/// The row can be activated either by clicking on it, calling
|
||||
/// [method@ActionRow.activate], or via mnemonics in the title.
|
||||
/// See the [property@PreferencesRow:use-underline] property to enable
|
||||
/// mnemonics.
|
||||
///
|
||||
/// The target widget will be activated by emitting the
|
||||
/// [signal@Gtk.Widget::mnemonic-activate] signal on it.
|
||||
var activatableWidget: (() -> Body)?
|
||||
/// The icon name for this row.
|
||||
var iconName: String?
|
||||
/// The subtitle for this row.
|
||||
///
|
||||
/// The subtitle is interpreted as Pango markup unless
|
||||
/// [property@PreferencesRow:use-markup] is set to `FALSE`.
|
||||
var subtitle: String?
|
||||
/// The number of lines at the end of which the subtitle label will be
|
||||
/// ellipsized.
|
||||
///
|
||||
/// If the value is 0, the number of lines won't be limited.
|
||||
var subtitleLines: Int?
|
||||
/// Whether the user can copy the subtitle from the label.
|
||||
///
|
||||
/// See also [property@Gtk.Label:selectable].
|
||||
var subtitleSelectable: Bool?
|
||||
/// The number of lines at the end of which the title label will be ellipsized.
|
||||
///
|
||||
/// If the value is 0, the number of lines won't be limited.
|
||||
var titleLines: Int?
|
||||
/// The title of the preference represented by this row.
|
||||
///
|
||||
/// The title is interpreted as Pango markup unless
|
||||
/// [property@PreferencesRow:use-markup] is set to `FALSE`.
|
||||
var title: String?
|
||||
/// Whether the user can copy the title from the label.
|
||||
///
|
||||
/// See also [property@Gtk.Label:selectable].
|
||||
var titleSelectable: Bool?
|
||||
/// Whether to use Pango markup for the title label.
|
||||
///
|
||||
/// Subclasses may also use it for other labels, such as subtitle.
|
||||
///
|
||||
/// See also [func@Pango.parse_markup].
|
||||
var useMarkup: Bool?
|
||||
/// Whether an embedded underline in the title indicates a mnemonic.
|
||||
var useUnderline: Bool?
|
||||
/// This signal is emitted after the row has been activated.
|
||||
var activated: (() -> Void)?
|
||||
/// The body for the widget "suffix".
|
||||
var suffix: () -> Body = { [] }
|
||||
/// The body for the widget "prefix".
|
||||
var prefix: () -> Body = { [] }
|
||||
/// The application.
|
||||
var app: GTUIApp?
|
||||
/// The window.
|
||||
var window: GTUIApplicationWindow?
|
||||
|
||||
/// Initialize `ActionRow`.
|
||||
public init() {
|
||||
}
|
||||
|
||||
/// Get the widget's view storage.
|
||||
/// - Parameter modifiers: The view modifiers.
|
||||
/// - Returns: The view storage.
|
||||
public func container(modifiers: [(View) -> View]) -> ViewStorage {
|
||||
let storage = ViewStorage(adw_action_row_new()?.opaque())
|
||||
update(storage, modifiers: modifiers)
|
||||
if let activatableWidgetStorage = activatableWidget?().widget(modifiers: modifiers).storage(modifiers: modifiers) {
|
||||
storage.content["activatableWidget"] = [activatableWidgetStorage]
|
||||
adw_action_row_set_activatable_widget(storage.pointer?.cast(), activatableWidgetStorage.pointer?.cast())
|
||||
}
|
||||
|
||||
var suffixStorage: [ViewStorage] = []
|
||||
for view in suffix() {
|
||||
suffixStorage.append(view.storage(modifiers: modifiers))
|
||||
adw_action_row_add_suffix(storage.pointer?.cast(), suffixStorage.last?.pointer?.cast())
|
||||
}
|
||||
storage.content["suffix"] = suffixStorage
|
||||
var prefixStorage: [ViewStorage] = []
|
||||
for view in prefix() {
|
||||
prefixStorage.append(view.storage(modifiers: modifiers))
|
||||
adw_action_row_add_prefix(storage.pointer?.cast(), prefixStorage.last?.pointer?.cast())
|
||||
}
|
||||
storage.content["prefix"] = prefixStorage
|
||||
|
||||
for function in appearFunctions {
|
||||
function(storage)
|
||||
}
|
||||
return storage
|
||||
}
|
||||
|
||||
/// Update the widget's view storage.
|
||||
/// - Parameters:
|
||||
/// - storage: The view storage.
|
||||
/// - modifiers: The view modifiers.
|
||||
public func update(_ storage: ViewStorage, modifiers: [(View) -> View]) {
|
||||
if let activated {
|
||||
storage.connectSignal(name: "activated") {
|
||||
activated()
|
||||
}
|
||||
}
|
||||
storage.modify { widget in
|
||||
if let widget = storage.content["activatableWidget"]?.first {
|
||||
activatableWidget?().widget(modifiers: modifiers).update(widget, modifiers: modifiers)
|
||||
}
|
||||
if let iconName {
|
||||
adw_action_row_set_icon_name(widget?.cast(), iconName)
|
||||
}
|
||||
if let subtitle {
|
||||
adw_action_row_set_subtitle(widget?.cast(), subtitle)
|
||||
}
|
||||
if let subtitleLines {
|
||||
adw_action_row_set_subtitle_lines(widget?.cast(), subtitleLines.cInt)
|
||||
}
|
||||
if let subtitleSelectable {
|
||||
adw_action_row_set_subtitle_selectable(widget?.cast(), subtitleSelectable.cBool)
|
||||
}
|
||||
if let titleLines {
|
||||
adw_action_row_set_title_lines(widget?.cast(), titleLines.cInt)
|
||||
}
|
||||
if let title {
|
||||
adw_preferences_row_set_title(widget?.cast(), title)
|
||||
}
|
||||
if let titleSelectable {
|
||||
adw_preferences_row_set_title_selectable(widget?.cast(), titleSelectable.cBool)
|
||||
}
|
||||
if let useMarkup {
|
||||
adw_preferences_row_set_use_markup(widget?.cast(), useMarkup.cBool)
|
||||
}
|
||||
if let useUnderline {
|
||||
adw_preferences_row_set_use_underline(widget?.cast(), useUnderline.cBool)
|
||||
}
|
||||
|
||||
if let suffixStorage = storage.content["suffix"] {
|
||||
for (index, view) in suffix().enumerated() {
|
||||
if let storage = suffixStorage[safe: index] {
|
||||
view.updateStorage(storage, modifiers: modifiers)
|
||||
}
|
||||
}
|
||||
}
|
||||
if let prefixStorage = storage.content["prefix"] {
|
||||
for (index, view) in prefix().enumerated() {
|
||||
if let storage = prefixStorage[safe: index] {
|
||||
view.updateStorage(storage, modifiers: modifiers)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
for function in updateFunctions {
|
||||
function(storage)
|
||||
}
|
||||
}
|
||||
|
||||
/// The widget to activate when the row is activated.
|
||||
///
|
||||
/// The row can be activated either by clicking on it, calling
|
||||
/// [method@ActionRow.activate], or via mnemonics in the title.
|
||||
/// See the [property@PreferencesRow:use-underline] property to enable
|
||||
/// mnemonics.
|
||||
///
|
||||
/// The target widget will be activated by emitting the
|
||||
/// [signal@Gtk.Widget::mnemonic-activate] signal on it.
|
||||
public func activatableWidget(@ViewBuilder _ activatableWidget: @escaping (() -> Body)) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.activatableWidget = activatableWidget
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// The icon name for this row.
|
||||
public func iconName(_ iconName: String?) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.iconName = iconName
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// The subtitle for this row.
|
||||
///
|
||||
/// The subtitle is interpreted as Pango markup unless
|
||||
/// [property@PreferencesRow:use-markup] is set to `FALSE`.
|
||||
public func subtitle(_ subtitle: String?) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.subtitle = subtitle
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// The number of lines at the end of which the subtitle label will be
|
||||
/// ellipsized.
|
||||
///
|
||||
/// If the value is 0, the number of lines won't be limited.
|
||||
public func subtitleLines(_ subtitleLines: Int?) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.subtitleLines = subtitleLines
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// Whether the user can copy the subtitle from the label.
|
||||
///
|
||||
/// See also [property@Gtk.Label:selectable].
|
||||
public func subtitleSelectable(_ subtitleSelectable: Bool? = true) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.subtitleSelectable = subtitleSelectable
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// The number of lines at the end of which the title label will be ellipsized.
|
||||
///
|
||||
/// If the value is 0, the number of lines won't be limited.
|
||||
public func titleLines(_ titleLines: Int?) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.titleLines = titleLines
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// The title of the preference represented by this row.
|
||||
///
|
||||
/// The title is interpreted as Pango markup unless
|
||||
/// [property@PreferencesRow:use-markup] is set to `FALSE`.
|
||||
public func title(_ title: String?) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.title = title
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// Whether the user can copy the title from the label.
|
||||
///
|
||||
/// See also [property@Gtk.Label:selectable].
|
||||
public func titleSelectable(_ titleSelectable: Bool? = true) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.titleSelectable = titleSelectable
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// Whether to use Pango markup for the title label.
|
||||
///
|
||||
/// Subclasses may also use it for other labels, such as subtitle.
|
||||
///
|
||||
/// See also [func@Pango.parse_markup].
|
||||
public func useMarkup(_ useMarkup: Bool? = true) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.useMarkup = useMarkup
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// Whether an embedded underline in the title indicates a mnemonic.
|
||||
public func useUnderline(_ useUnderline: Bool? = true) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.useUnderline = useUnderline
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// This signal is emitted after the row has been activated.
|
||||
public func activated(_ activated: @escaping () -> Void) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.activated = activated
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// Set the body for "suffix".
|
||||
/// - Parameter body: The body.
|
||||
/// - Returns: The widget.
|
||||
public func suffix(@ViewBuilder _ body: @escaping () -> Body) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.suffix = body
|
||||
return newSelf
|
||||
}
|
||||
/// Set the body for "prefix".
|
||||
/// - Parameter body: The body.
|
||||
/// - Returns: The widget.
|
||||
public func prefix(@ViewBuilder _ body: @escaping () -> Body) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.prefix = body
|
||||
return newSelf
|
||||
}
|
||||
}
|
139
Sources/Adwaita/View/Generated/Avatar.swift
Normal file
139
Sources/Adwaita/View/Generated/Avatar.swift
Normal file
@ -0,0 +1,139 @@
|
||||
//
|
||||
// Avatar.swift
|
||||
// Adwaita
|
||||
//
|
||||
// Created by auto-generation on 22.01.24.
|
||||
//
|
||||
|
||||
import CAdw
|
||||
import LevenshteinTransformations
|
||||
|
||||
/// A widget displaying an image, with a generated fallback.
|
||||
///
|
||||
/// <picture><source srcset="avatar-dark.png" media="(prefers-color-scheme: dark)"><img src="avatar.png" alt="avatar"></picture>
|
||||
///
|
||||
/// `AdwAvatar` is a widget that shows a round avatar.
|
||||
///
|
||||
/// `AdwAvatar` generates an avatar with the initials of the
|
||||
/// [property@Avatar:text] on top of a colored background.
|
||||
///
|
||||
/// The color is picked based on the hash of the [property@Avatar:text].
|
||||
///
|
||||
/// If [property@Avatar:show-initials] is set to `FALSE`,
|
||||
/// [property@Avatar:icon-name] or `avatar-default-symbolic` is shown instead of
|
||||
/// the initials.
|
||||
///
|
||||
/// Use [property@Avatar:custom-image] to set a custom image.
|
||||
///
|
||||
/// ## CSS nodes
|
||||
///
|
||||
/// `AdwAvatar` has a single CSS node with name `avatar`.
|
||||
public struct Avatar: Widget {
|
||||
|
||||
/// Additional update functions for type extensions.
|
||||
var updateFunctions: [(ViewStorage) -> Void] = []
|
||||
/// Additional appear functions for type extensions.
|
||||
var appearFunctions: [(ViewStorage) -> Void] = []
|
||||
|
||||
/// The name of an icon to use as a fallback.
|
||||
///
|
||||
/// If no name is set, `avatar-default-symbolic` will be used.
|
||||
var iconName: String?
|
||||
/// Whether initials are used instead of an icon on the fallback avatar.
|
||||
///
|
||||
/// See [property@Avatar:icon-name] for how to change the fallback icon.
|
||||
var showInitials: Bool
|
||||
/// The size of the avatar.
|
||||
var size: Int
|
||||
/// Sets the text used to generate the fallback initials and color.
|
||||
///
|
||||
/// It's only used to generate the color if [property@Avatar:show-initials] is
|
||||
/// `FALSE`.
|
||||
var text: String?
|
||||
/// The application.
|
||||
var app: GTUIApp?
|
||||
/// The window.
|
||||
var window: GTUIApplicationWindow?
|
||||
|
||||
/// Initialize `Avatar`.
|
||||
public init(showInitials: Bool, size: Int) {
|
||||
self.showInitials = showInitials
|
||||
self.size = size
|
||||
}
|
||||
|
||||
/// Get the widget's view storage.
|
||||
/// - Parameter modifiers: The view modifiers.
|
||||
/// - Returns: The view storage.
|
||||
public func container(modifiers: [(View) -> View]) -> ViewStorage {
|
||||
let storage = ViewStorage(adw_avatar_new(size.cInt, text, showInitials.cBool)?.opaque())
|
||||
update(storage, modifiers: modifiers)
|
||||
|
||||
|
||||
for function in appearFunctions {
|
||||
function(storage)
|
||||
}
|
||||
return storage
|
||||
}
|
||||
|
||||
/// Update the widget's view storage.
|
||||
/// - Parameters:
|
||||
/// - storage: The view storage.
|
||||
/// - modifiers: The view modifiers.
|
||||
public func update(_ storage: ViewStorage, modifiers: [(View) -> View]) {
|
||||
storage.modify { widget in
|
||||
if let iconName {
|
||||
adw_avatar_set_icon_name(widget, iconName)
|
||||
}
|
||||
adw_avatar_set_show_initials(widget, showInitials.cBool)
|
||||
adw_avatar_set_size(widget, size.cInt)
|
||||
if let text {
|
||||
adw_avatar_set_text(widget, text)
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
for function in updateFunctions {
|
||||
function(storage)
|
||||
}
|
||||
}
|
||||
|
||||
/// The name of an icon to use as a fallback.
|
||||
///
|
||||
/// If no name is set, `avatar-default-symbolic` will be used.
|
||||
public func iconName(_ iconName: String?) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.iconName = iconName
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// Whether initials are used instead of an icon on the fallback avatar.
|
||||
///
|
||||
/// See [property@Avatar:icon-name] for how to change the fallback icon.
|
||||
public func showInitials(_ showInitials: Bool) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.showInitials = showInitials
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// The size of the avatar.
|
||||
public func size(_ size: Int) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.size = size
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// Sets the text used to generate the fallback initials and color.
|
||||
///
|
||||
/// It's only used to generate the color if [property@Avatar:show-initials] is
|
||||
/// `FALSE`.
|
||||
public func text(_ text: String?) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.text = text
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
}
|
161
Sources/Adwaita/View/Generated/Banner.swift
Normal file
161
Sources/Adwaita/View/Generated/Banner.swift
Normal file
@ -0,0 +1,161 @@
|
||||
//
|
||||
// Banner.swift
|
||||
// Adwaita
|
||||
//
|
||||
// Created by auto-generation on 22.01.24.
|
||||
//
|
||||
|
||||
import CAdw
|
||||
import LevenshteinTransformations
|
||||
|
||||
/// A bar with contextual information.
|
||||
///
|
||||
/// <picture><source srcset="banner-dark.png" media="(prefers-color-scheme: dark)"><img src="banner.png" alt="banner"></picture>
|
||||
///
|
||||
/// Banners are hidden by default, use [property@Banner:revealed] to show them.
|
||||
///
|
||||
/// Banners have a title, set with [property@Banner:title]. Titles can be marked
|
||||
/// up with Pango markup, use [property@Banner:use-markup] to enable it.
|
||||
///
|
||||
/// The title will be shown centered or left-aligned depending on available
|
||||
/// space.
|
||||
///
|
||||
/// Banners can optionally have a button with text on it, set through
|
||||
/// [property@Banner:button-label]. The button can be used with a `GAction`,
|
||||
/// or with the [signal@Banner::button-clicked] signal.
|
||||
///
|
||||
/// ## CSS nodes
|
||||
///
|
||||
/// `AdwBanner` has a main CSS node with the name `banner`.
|
||||
public struct Banner: Widget {
|
||||
|
||||
/// Additional update functions for type extensions.
|
||||
var updateFunctions: [(ViewStorage) -> Void] = []
|
||||
/// Additional appear functions for type extensions.
|
||||
var appearFunctions: [(ViewStorage) -> Void] = []
|
||||
|
||||
/// The label to show on the button.
|
||||
///
|
||||
/// If set to `""` or `NULL`, the button won't be shown.
|
||||
///
|
||||
/// The button can be used with a `GAction`, or with the
|
||||
/// [signal@Banner::button-clicked] signal.
|
||||
var buttonLabel: String?
|
||||
/// Whether the banner is currently revealed.
|
||||
var revealed: Bool?
|
||||
/// The title for this banner.
|
||||
///
|
||||
/// See also: [property@Banner:use-markup].
|
||||
var title: String
|
||||
/// Whether to use Pango markup for the banner title.
|
||||
///
|
||||
/// See also [func@Pango.parse_markup].
|
||||
var useMarkup: Bool?
|
||||
/// This signal is emitted after the action button has been clicked.
|
||||
///
|
||||
/// It can be used as an alternative to setting an action.
|
||||
var buttonClicked: (() -> Void)?
|
||||
/// The application.
|
||||
var app: GTUIApp?
|
||||
/// The window.
|
||||
var window: GTUIApplicationWindow?
|
||||
|
||||
/// Initialize `Banner`.
|
||||
public init(title: String) {
|
||||
self.title = title
|
||||
}
|
||||
|
||||
/// Get the widget's view storage.
|
||||
/// - Parameter modifiers: The view modifiers.
|
||||
/// - Returns: The view storage.
|
||||
public func container(modifiers: [(View) -> View]) -> ViewStorage {
|
||||
let storage = ViewStorage(adw_banner_new(title)?.opaque())
|
||||
update(storage, modifiers: modifiers)
|
||||
|
||||
|
||||
for function in appearFunctions {
|
||||
function(storage)
|
||||
}
|
||||
return storage
|
||||
}
|
||||
|
||||
/// Update the widget's view storage.
|
||||
/// - Parameters:
|
||||
/// - storage: The view storage.
|
||||
/// - modifiers: The view modifiers.
|
||||
public func update(_ storage: ViewStorage, modifiers: [(View) -> View]) {
|
||||
if let buttonClicked {
|
||||
storage.connectSignal(name: "button-clicked") {
|
||||
buttonClicked()
|
||||
}
|
||||
}
|
||||
storage.modify { widget in
|
||||
if let buttonLabel {
|
||||
adw_banner_set_button_label(widget, buttonLabel)
|
||||
}
|
||||
if let revealed {
|
||||
adw_banner_set_revealed(widget, revealed.cBool)
|
||||
}
|
||||
adw_banner_set_title(widget, title)
|
||||
if let useMarkup {
|
||||
adw_banner_set_use_markup(widget, useMarkup.cBool)
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
for function in updateFunctions {
|
||||
function(storage)
|
||||
}
|
||||
}
|
||||
|
||||
/// The label to show on the button.
|
||||
///
|
||||
/// If set to `""` or `NULL`, the button won't be shown.
|
||||
///
|
||||
/// The button can be used with a `GAction`, or with the
|
||||
/// [signal@Banner::button-clicked] signal.
|
||||
public func buttonLabel(_ buttonLabel: String?) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.buttonLabel = buttonLabel
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// Whether the banner is currently revealed.
|
||||
public func revealed(_ revealed: Bool? = true) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.revealed = revealed
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// The title for this banner.
|
||||
///
|
||||
/// See also: [property@Banner:use-markup].
|
||||
public func title(_ title: String) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.title = title
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// Whether to use Pango markup for the banner title.
|
||||
///
|
||||
/// See also [func@Pango.parse_markup].
|
||||
public func useMarkup(_ useMarkup: Bool? = true) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.useMarkup = useMarkup
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// This signal is emitted after the action button has been clicked.
|
||||
///
|
||||
/// It can be used as an alternative to setting an action.
|
||||
public func buttonClicked(_ buttonClicked: @escaping () -> Void) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.buttonClicked = buttonClicked
|
||||
return newSelf
|
||||
}
|
||||
|
||||
}
|
81
Sources/Adwaita/View/Generated/Bin.swift
Normal file
81
Sources/Adwaita/View/Generated/Bin.swift
Normal file
@ -0,0 +1,81 @@
|
||||
//
|
||||
// Bin.swift
|
||||
// Adwaita
|
||||
//
|
||||
// Created by auto-generation on 22.01.24.
|
||||
//
|
||||
|
||||
import CAdw
|
||||
import LevenshteinTransformations
|
||||
|
||||
/// A widget with one child.
|
||||
///
|
||||
/// <picture><source srcset="bin-dark.png" media="(prefers-color-scheme: dark)"><img src="bin.png" alt="bin"></picture>
|
||||
///
|
||||
/// The `AdwBin` widget has only one child, set with the [property@Bin:child]
|
||||
/// property.
|
||||
///
|
||||
/// It is useful for deriving subclasses, since it provides common code needed
|
||||
/// for handling a single child widget.
|
||||
public struct Bin: Widget {
|
||||
|
||||
/// Additional update functions for type extensions.
|
||||
var updateFunctions: [(ViewStorage) -> Void] = []
|
||||
/// Additional appear functions for type extensions.
|
||||
var appearFunctions: [(ViewStorage) -> Void] = []
|
||||
|
||||
/// The child widget of the `AdwBin`.
|
||||
var child: (() -> Body)?
|
||||
/// The application.
|
||||
var app: GTUIApp?
|
||||
/// The window.
|
||||
var window: GTUIApplicationWindow?
|
||||
|
||||
/// Initialize `Bin`.
|
||||
public init() {
|
||||
}
|
||||
|
||||
/// Get the widget's view storage.
|
||||
/// - Parameter modifiers: The view modifiers.
|
||||
/// - Returns: The view storage.
|
||||
public func container(modifiers: [(View) -> View]) -> ViewStorage {
|
||||
let storage = ViewStorage(adw_bin_new()?.opaque())
|
||||
update(storage, modifiers: modifiers)
|
||||
if let childStorage = child?().widget(modifiers: modifiers).storage(modifiers: modifiers) {
|
||||
storage.content["child"] = [childStorage]
|
||||
adw_bin_set_child(storage.pointer?.cast(), childStorage.pointer?.cast())
|
||||
}
|
||||
|
||||
|
||||
for function in appearFunctions {
|
||||
function(storage)
|
||||
}
|
||||
return storage
|
||||
}
|
||||
|
||||
/// Update the widget's view storage.
|
||||
/// - Parameters:
|
||||
/// - storage: The view storage.
|
||||
/// - modifiers: The view modifiers.
|
||||
public func update(_ storage: ViewStorage, modifiers: [(View) -> View]) {
|
||||
storage.modify { widget in
|
||||
if let widget = storage.content["child"]?.first {
|
||||
child?().widget(modifiers: modifiers).update(widget, modifiers: modifiers)
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
for function in updateFunctions {
|
||||
function(storage)
|
||||
}
|
||||
}
|
||||
|
||||
/// The child widget of the `AdwBin`.
|
||||
public func child(@ViewBuilder _ child: @escaping (() -> Body)) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.child = child
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
}
|
173
Sources/Adwaita/View/Generated/Box.swift
Normal file
173
Sources/Adwaita/View/Generated/Box.swift
Normal file
@ -0,0 +1,173 @@
|
||||
//
|
||||
// Box.swift
|
||||
// Adwaita
|
||||
//
|
||||
// Created by auto-generation on 22.01.24.
|
||||
//
|
||||
|
||||
import CAdw
|
||||
import LevenshteinTransformations
|
||||
|
||||
/// The `GtkBox` widget arranges child widgets into a single row or column.
|
||||
///
|
||||
/// ![An example GtkBox](box.png)
|
||||
///
|
||||
/// Whether it is a row or column depends on the value of its
|
||||
/// [property@Gtk.Orientable:orientation] property. Within the other
|
||||
/// dimension, all children are allocated the same size. Of course, the
|
||||
/// [property@Gtk.Widget:halign] and [property@Gtk.Widget:valign] properties
|
||||
/// can be used on the children to influence their allocation.
|
||||
///
|
||||
/// Use repeated calls to [method@Gtk.Box.append] to pack widgets into a
|
||||
/// `GtkBox` from start to end. Use [method@Gtk.Box.remove] to remove widgets
|
||||
/// from the `GtkBox`. [method@Gtk.Box.insert_child_after] can be used to add
|
||||
/// a child at a particular position.
|
||||
///
|
||||
/// Use [method@Gtk.Box.set_homogeneous] to specify whether or not all children
|
||||
/// of the `GtkBox` are forced to get the same amount of space.
|
||||
///
|
||||
/// Use [method@Gtk.Box.set_spacing] to determine how much space will be minimally
|
||||
/// placed between all children in the `GtkBox`. Note that spacing is added
|
||||
/// *between* the children.
|
||||
///
|
||||
/// Use [method@Gtk.Box.reorder_child_after] to move a child to a different
|
||||
/// place in the box.
|
||||
///
|
||||
/// # CSS nodes
|
||||
///
|
||||
/// `GtkBox` uses a single CSS node with name box.
|
||||
///
|
||||
/// # Accessibility
|
||||
///
|
||||
/// Until GTK 4.10, `GtkBox` used the `GTK_ACCESSIBLE_ROLE_GROUP` role.
|
||||
///
|
||||
/// Starting from GTK 4.12, `GtkBox` uses the `GTK_ACCESSIBLE_ROLE_GENERIC` role.
|
||||
public struct Box: Widget {
|
||||
|
||||
/// Additional update functions for type extensions.
|
||||
var updateFunctions: [(ViewStorage) -> Void] = []
|
||||
/// Additional appear functions for type extensions.
|
||||
var appearFunctions: [(ViewStorage) -> Void] = []
|
||||
|
||||
/// The child that determines the baseline, in vertical orientation.
|
||||
var baselineChild: Int?
|
||||
/// Whether the children should all be the same size.
|
||||
var homogeneous: Bool?
|
||||
/// The amount of space between children.
|
||||
var spacing: Int
|
||||
/// The body for the widget "append".
|
||||
var append: () -> Body = { [] }
|
||||
/// The body for the widget "prepend".
|
||||
var prepend: () -> Body = { [] }
|
||||
/// The application.
|
||||
var app: GTUIApp?
|
||||
/// The window.
|
||||
var window: GTUIApplicationWindow?
|
||||
|
||||
/// Initialize `Box`.
|
||||
public init(spacing: Int) {
|
||||
self.spacing = spacing
|
||||
}
|
||||
|
||||
/// Get the widget's view storage.
|
||||
/// - Parameter modifiers: The view modifiers.
|
||||
/// - Returns: The view storage.
|
||||
public func container(modifiers: [(View) -> View]) -> ViewStorage {
|
||||
let storage = ViewStorage(gtk_box_new(GTK_ORIENTATION_VERTICAL, spacing.cInt)?.opaque())
|
||||
update(storage, modifiers: modifiers)
|
||||
|
||||
var appendStorage: [ViewStorage] = []
|
||||
for view in append() {
|
||||
appendStorage.append(view.storage(modifiers: modifiers))
|
||||
gtk_box_append(storage.pointer?.cast(), appendStorage.last?.pointer?.cast())
|
||||
}
|
||||
storage.content["append"] = appendStorage
|
||||
var prependStorage: [ViewStorage] = []
|
||||
for view in prepend() {
|
||||
prependStorage.append(view.storage(modifiers: modifiers))
|
||||
gtk_box_prepend(storage.pointer?.cast(), prependStorage.last?.pointer?.cast())
|
||||
}
|
||||
storage.content["prepend"] = prependStorage
|
||||
|
||||
for function in appearFunctions {
|
||||
function(storage)
|
||||
}
|
||||
return storage
|
||||
}
|
||||
|
||||
/// Update the widget's view storage.
|
||||
/// - Parameters:
|
||||
/// - storage: The view storage.
|
||||
/// - modifiers: The view modifiers.
|
||||
public func update(_ storage: ViewStorage, modifiers: [(View) -> View]) {
|
||||
storage.modify { widget in
|
||||
if let baselineChild {
|
||||
gtk_box_set_baseline_child(widget?.cast(), baselineChild.cInt)
|
||||
}
|
||||
if let homogeneous {
|
||||
gtk_box_set_homogeneous(widget?.cast(), homogeneous.cBool)
|
||||
}
|
||||
gtk_box_set_spacing(widget?.cast(), spacing.cInt)
|
||||
|
||||
if let appendStorage = storage.content["append"] {
|
||||
for (index, view) in append().enumerated() {
|
||||
if let storage = appendStorage[safe: index] {
|
||||
view.updateStorage(storage, modifiers: modifiers)
|
||||
}
|
||||
}
|
||||
}
|
||||
if let prependStorage = storage.content["prepend"] {
|
||||
for (index, view) in prepend().enumerated() {
|
||||
if let storage = prependStorage[safe: index] {
|
||||
view.updateStorage(storage, modifiers: modifiers)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
for function in updateFunctions {
|
||||
function(storage)
|
||||
}
|
||||
}
|
||||
|
||||
/// The child that determines the baseline, in vertical orientation.
|
||||
public func baselineChild(_ baselineChild: Int?) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.baselineChild = baselineChild
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// Whether the children should all be the same size.
|
||||
public func homogeneous(_ homogeneous: Bool? = true) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.homogeneous = homogeneous
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// The amount of space between children.
|
||||
public func spacing(_ spacing: Int) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.spacing = spacing
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// Set the body for "append".
|
||||
/// - Parameter body: The body.
|
||||
/// - Returns: The widget.
|
||||
public func append(@ViewBuilder _ body: @escaping () -> Body) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.append = body
|
||||
return newSelf
|
||||
}
|
||||
/// Set the body for "prepend".
|
||||
/// - Parameter body: The body.
|
||||
/// - Returns: The widget.
|
||||
public func prepend(@ViewBuilder _ body: @escaping () -> Body) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.prepend = body
|
||||
return newSelf
|
||||
}
|
||||
}
|
221
Sources/Adwaita/View/Generated/Button.swift
Normal file
221
Sources/Adwaita/View/Generated/Button.swift
Normal file
@ -0,0 +1,221 @@
|
||||
//
|
||||
// Button.swift
|
||||
// Adwaita
|
||||
//
|
||||
// Created by auto-generation on 22.01.24.
|
||||
//
|
||||
|
||||
import CAdw
|
||||
import LevenshteinTransformations
|
||||
|
||||
/// The `GtkButton` widget is generally used to trigger a callback function that is
|
||||
/// called when the button is pressed.
|
||||
///
|
||||
/// ![An example GtkButton](button.png)
|
||||
///
|
||||
/// The `GtkButton` widget can hold any valid child widget. That is, it can hold
|
||||
/// almost any other standard `GtkWidget`. The most commonly used child is the
|
||||
/// `GtkLabel`.
|
||||
///
|
||||
/// # CSS nodes
|
||||
///
|
||||
/// `GtkButton` has a single CSS node with name button. The node will get the
|
||||
/// style classes .image-button or .text-button, if the content is just an
|
||||
/// image or label, respectively. It may also receive the .flat style class.
|
||||
/// When activating a button via the keyboard, the button will temporarily
|
||||
/// gain the .keyboard-activating style class.
|
||||
///
|
||||
/// Other style classes that are commonly used with `GtkButton` include
|
||||
/// .suggested-action and .destructive-action. In special cases, buttons
|
||||
/// can be made round by adding the .circular style class.
|
||||
///
|
||||
/// Button-like widgets like [class@Gtk.ToggleButton], [class@Gtk.MenuButton],
|
||||
/// [class@Gtk.VolumeButton], [class@Gtk.LockButton], [class@Gtk.ColorButton]
|
||||
/// or [class@Gtk.FontButton] use style classes such as .toggle, .popup, .scale,
|
||||
/// .lock, .color on the button node to differentiate themselves from a plain
|
||||
/// `GtkButton`.
|
||||
///
|
||||
/// # Accessibility
|
||||
///
|
||||
/// `GtkButton` uses the %GTK_ACCESSIBLE_ROLE_BUTTON role.
|
||||
public struct Button: Widget {
|
||||
|
||||
/// Additional update functions for type extensions.
|
||||
var updateFunctions: [(ViewStorage) -> Void] = []
|
||||
/// Additional appear functions for type extensions.
|
||||
var appearFunctions: [(ViewStorage) -> Void] = []
|
||||
|
||||
/// Whether the size of the button can be made smaller than the natural
|
||||
/// size of its contents.
|
||||
///
|
||||
/// For text buttons, setting this property will allow ellipsizing the label.
|
||||
///
|
||||
/// If the contents of a button are an icon or a custom widget, setting this
|
||||
/// property has no effect.
|
||||
var canShrink: Bool?
|
||||
/// The child widget.
|
||||
var child: (() -> Body)?
|
||||
/// Whether the button has a frame.
|
||||
var hasFrame: Bool?
|
||||
/// The name of the icon used to automatically populate the button.
|
||||
var iconName: String?
|
||||
/// Text of the label inside the button, if the button contains a label widget.
|
||||
var label: String?
|
||||
/// If set, an underline in the text indicates that the following character is
|
||||
/// to be used as mnemonic.
|
||||
var useUnderline: Bool?
|
||||
/// Emitted to animate press then release.
|
||||
///
|
||||
/// This is an action signal. Applications should never connect
|
||||
/// to this signal, but use the [signal@Gtk.Button::clicked] signal.
|
||||
///
|
||||
/// The default bindings for this signal are all forms of the
|
||||
/// <kbd>␣</kbd> and <kbd>Enter</kbd> keys.
|
||||
var activate: (() -> Void)?
|
||||
/// Emitted when the button has been activated (pressed and released).
|
||||
var clicked: (() -> Void)?
|
||||
/// The application.
|
||||
var app: GTUIApp?
|
||||
/// The window.
|
||||
var window: GTUIApplicationWindow?
|
||||
|
||||
/// Initialize `Button`.
|
||||
public init() {
|
||||
}
|
||||
|
||||
/// Get the widget's view storage.
|
||||
/// - Parameter modifiers: The view modifiers.
|
||||
/// - Returns: The view storage.
|
||||
public func container(modifiers: [(View) -> View]) -> ViewStorage {
|
||||
let storage = ViewStorage(gtk_button_new()?.opaque())
|
||||
update(storage, modifiers: modifiers)
|
||||
if let childStorage = child?().widget(modifiers: modifiers).storage(modifiers: modifiers) {
|
||||
storage.content["child"] = [childStorage]
|
||||
gtk_button_set_child(storage.pointer?.cast(), childStorage.pointer?.cast())
|
||||
}
|
||||
|
||||
|
||||
for function in appearFunctions {
|
||||
function(storage)
|
||||
}
|
||||
return storage
|
||||
}
|
||||
|
||||
/// Update the widget's view storage.
|
||||
/// - Parameters:
|
||||
/// - storage: The view storage.
|
||||
/// - modifiers: The view modifiers.
|
||||
public func update(_ storage: ViewStorage, modifiers: [(View) -> View]) {
|
||||
if let activate {
|
||||
storage.connectSignal(name: "activate") {
|
||||
activate()
|
||||
}
|
||||
}
|
||||
if let clicked {
|
||||
storage.connectSignal(name: "clicked") {
|
||||
clicked()
|
||||
}
|
||||
}
|
||||
storage.modify { widget in
|
||||
if let canShrink {
|
||||
gtk_button_set_can_shrink(widget?.cast(), canShrink.cBool)
|
||||
}
|
||||
if let widget = storage.content["child"]?.first {
|
||||
child?().widget(modifiers: modifiers).update(widget, modifiers: modifiers)
|
||||
}
|
||||
if let hasFrame {
|
||||
gtk_button_set_has_frame(widget?.cast(), hasFrame.cBool)
|
||||
}
|
||||
if let iconName {
|
||||
gtk_button_set_icon_name(widget?.cast(), iconName)
|
||||
}
|
||||
if let label, storage.content["child"] == nil {
|
||||
gtk_button_set_label(widget?.cast(), label)
|
||||
}
|
||||
if let useUnderline {
|
||||
gtk_button_set_use_underline(widget?.cast(), useUnderline.cBool)
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
for function in updateFunctions {
|
||||
function(storage)
|
||||
}
|
||||
}
|
||||
|
||||
/// Whether the size of the button can be made smaller than the natural
|
||||
/// size of its contents.
|
||||
///
|
||||
/// For text buttons, setting this property will allow ellipsizing the label.
|
||||
///
|
||||
/// If the contents of a button are an icon or a custom widget, setting this
|
||||
/// property has no effect.
|
||||
public func canShrink(_ canShrink: Bool? = true) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.canShrink = canShrink
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// The child widget.
|
||||
public func child(@ViewBuilder _ child: @escaping (() -> Body)) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.child = child
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// Whether the button has a frame.
|
||||
public func hasFrame(_ hasFrame: Bool? = true) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.hasFrame = hasFrame
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// The name of the icon used to automatically populate the button.
|
||||
public func iconName(_ iconName: String?) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.iconName = iconName
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// Text of the label inside the button, if the button contains a label widget.
|
||||
public func label(_ label: String?) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.label = label
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// If set, an underline in the text indicates that the following character is
|
||||
/// to be used as mnemonic.
|
||||
public func useUnderline(_ useUnderline: Bool? = true) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.useUnderline = useUnderline
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// Emitted to animate press then release.
|
||||
///
|
||||
/// This is an action signal. Applications should never connect
|
||||
/// to this signal, but use the [signal@Gtk.Button::clicked] signal.
|
||||
///
|
||||
/// The default bindings for this signal are all forms of the
|
||||
/// <kbd>␣</kbd> and <kbd>Enter</kbd> keys.
|
||||
public func activate(_ activate: @escaping () -> Void) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.activate = activate
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// Emitted when the button has been activated (pressed and released).
|
||||
public func clicked(_ clicked: @escaping () -> Void) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.clicked = clicked
|
||||
return newSelf
|
||||
}
|
||||
|
||||
}
|
162
Sources/Adwaita/View/Generated/ButtonContent.swift
Normal file
162
Sources/Adwaita/View/Generated/ButtonContent.swift
Normal file
@ -0,0 +1,162 @@
|
||||
//
|
||||
// ButtonContent.swift
|
||||
// Adwaita
|
||||
//
|
||||
// Created by auto-generation on 22.01.24.
|
||||
//
|
||||
|
||||
import CAdw
|
||||
import LevenshteinTransformations
|
||||
|
||||
/// A helper widget for creating buttons.
|
||||
///
|
||||
/// <picture><source srcset="button-content-dark.png" media="(prefers-color-scheme: dark)"><img src="button-content.png" alt="button-content"></picture>
|
||||
///
|
||||
/// `AdwButtonContent` is a box-like widget with an icon and a label.
|
||||
///
|
||||
/// It's intended to be used as a direct child of [class@Gtk.Button],
|
||||
/// [class@Gtk.MenuButton] or [class@SplitButton], when they need to have both an
|
||||
/// icon and a label, as follows:
|
||||
///
|
||||
/// ```xml
|
||||
/// <object class="GtkButton"><property name="child"><object class="AdwButtonContent"><property name="icon-name">document-open-symbolic</property><property name="label" translatable="yes">_Open</property><property name="use-underline">True</property></object></property></object>
|
||||
/// ```
|
||||
///
|
||||
/// `AdwButtonContent` handles style classes and connecting the mnemonic to the
|
||||
/// button automatically.
|
||||
///
|
||||
/// ## CSS nodes
|
||||
///
|
||||
/// ```
|
||||
/// buttoncontent
|
||||
/// ├── image
|
||||
/// ╰── label
|
||||
/// ```
|
||||
///
|
||||
/// `AdwButtonContent`'s CSS node is called `buttoncontent`. It contains the
|
||||
/// subnodes `image` and `label`.
|
||||
///
|
||||
/// When inside a `GtkButton` or `AdwSplitButton`, the button will receive the
|
||||
/// `.image-text-button` style class. When inside a `GtkMenuButton`, the
|
||||
/// internal `GtkButton` will receive it instead.
|
||||
///
|
||||
/// ## Accessibility
|
||||
///
|
||||
/// `AdwButtonContent` uses the `GTK_ACCESSIBLE_ROLE_GROUP` role.
|
||||
public struct ButtonContent: Widget {
|
||||
|
||||
/// Additional update functions for type extensions.
|
||||
var updateFunctions: [(ViewStorage) -> Void] = []
|
||||
/// Additional appear functions for type extensions.
|
||||
var appearFunctions: [(ViewStorage) -> Void] = []
|
||||
|
||||
/// Whether the button can be smaller than the natural size of its contents.
|
||||
///
|
||||
/// If set to `TRUE`, the label will ellipsize.
|
||||
///
|
||||
/// See [property@Gtk.Button:can-shrink].
|
||||
var canShrink: Bool?
|
||||
/// The name of the displayed icon.
|
||||
///
|
||||
/// If empty, the icon is not shown.
|
||||
var iconName: String?
|
||||
/// The displayed label.
|
||||
var label: String?
|
||||
/// Whether an underline in the text indicates a mnemonic.
|
||||
///
|
||||
/// The mnemonic can be used to activate the parent button.
|
||||
///
|
||||
/// See [property@ButtonContent:label].
|
||||
var useUnderline: Bool?
|
||||
/// The application.
|
||||
var app: GTUIApp?
|
||||
/// The window.
|
||||
var window: GTUIApplicationWindow?
|
||||
|
||||
/// Initialize `ButtonContent`.
|
||||
public init() {
|
||||
}
|
||||
|
||||
/// Get the widget's view storage.
|
||||
/// - Parameter modifiers: The view modifiers.
|
||||
/// - Returns: The view storage.
|
||||
public func container(modifiers: [(View) -> View]) -> ViewStorage {
|
||||
let storage = ViewStorage(adw_button_content_new()?.opaque())
|
||||
update(storage, modifiers: modifiers)
|
||||
|
||||
|
||||
for function in appearFunctions {
|
||||
function(storage)
|
||||
}
|
||||
return storage
|
||||
}
|
||||
|
||||
/// Update the widget's view storage.
|
||||
/// - Parameters:
|
||||
/// - storage: The view storage.
|
||||
/// - modifiers: The view modifiers.
|
||||
public func update(_ storage: ViewStorage, modifiers: [(View) -> View]) {
|
||||
storage.modify { widget in
|
||||
if let canShrink {
|
||||
adw_button_content_set_can_shrink(widget, canShrink.cBool)
|
||||
}
|
||||
if let iconName {
|
||||
adw_button_content_set_icon_name(widget, iconName)
|
||||
}
|
||||
if let label {
|
||||
adw_button_content_set_label(widget, label)
|
||||
}
|
||||
if let useUnderline {
|
||||
adw_button_content_set_use_underline(widget, useUnderline.cBool)
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
for function in updateFunctions {
|
||||
function(storage)
|
||||
}
|
||||
}
|
||||
|
||||
/// Whether the button can be smaller than the natural size of its contents.
|
||||
///
|
||||
/// If set to `TRUE`, the label will ellipsize.
|
||||
///
|
||||
/// See [property@Gtk.Button:can-shrink].
|
||||
public func canShrink(_ canShrink: Bool? = true) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.canShrink = canShrink
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// The name of the displayed icon.
|
||||
///
|
||||
/// If empty, the icon is not shown.
|
||||
public func iconName(_ iconName: String?) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.iconName = iconName
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// The displayed label.
|
||||
public func label(_ label: String?) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.label = label
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// Whether an underline in the text indicates a mnemonic.
|
||||
///
|
||||
/// The mnemonic can be used to activate the parent button.
|
||||
///
|
||||
/// See [property@ButtonContent:label].
|
||||
public func useUnderline(_ useUnderline: Bool? = true) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.useUnderline = useUnderline
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
}
|
229
Sources/Adwaita/View/Generated/Carousel.swift
Normal file
229
Sources/Adwaita/View/Generated/Carousel.swift
Normal file
@ -0,0 +1,229 @@
|
||||
//
|
||||
// Carousel.swift
|
||||
// Adwaita
|
||||
//
|
||||
// Created by auto-generation on 22.01.24.
|
||||
//
|
||||
|
||||
import CAdw
|
||||
import LevenshteinTransformations
|
||||
|
||||
/// A paginated scrolling widget.
|
||||
///
|
||||
/// <picture><source srcset="carousel-dark.png" media="(prefers-color-scheme: dark)"><img src="carousel.png" alt="carousel"></picture>
|
||||
///
|
||||
/// The `AdwCarousel` widget can be used to display a set of pages with
|
||||
/// swipe-based navigation between them.
|
||||
///
|
||||
/// [class@CarouselIndicatorDots] and [class@CarouselIndicatorLines] can be used
|
||||
/// to provide page indicators for `AdwCarousel`.
|
||||
///
|
||||
/// ## CSS nodes
|
||||
///
|
||||
/// `AdwCarousel` has a single CSS node with name `carousel`.
|
||||
public struct Carousel<Element>: Widget where Element: Identifiable {
|
||||
|
||||
/// Additional update functions for type extensions.
|
||||
var updateFunctions: [(ViewStorage) -> Void] = []
|
||||
/// Additional appear functions for type extensions.
|
||||
var appearFunctions: [(ViewStorage) -> Void] = []
|
||||
|
||||
/// Whether to allow swiping for more than one page at a time.
|
||||
///
|
||||
/// If the value is `FALSE`, each swipe can only move to the adjacent pages.
|
||||
var allowLongSwipes: Bool?
|
||||
/// Sets whether the `AdwCarousel` can be dragged with mouse pointer.
|
||||
///
|
||||
/// If the value is `FALSE`, dragging is only available on touch.
|
||||
var allowMouseDrag: Bool?
|
||||
/// Whether the widget will respond to scroll wheel events.
|
||||
///
|
||||
/// If the value is `FALSE`, wheel events will be ignored.
|
||||
var allowScrollWheel: Bool?
|
||||
/// Whether the carousel can be navigated.
|
||||
///
|
||||
/// This can be used to temporarily disable the carousel to only allow
|
||||
/// navigating it in a certain state.
|
||||
var interactive: Bool?
|
||||
/// The number of pages in a `AdwCarousel`.
|
||||
var nPages: UInt?
|
||||
/// Page reveal duration, in milliseconds.
|
||||
///
|
||||
/// Reveal duration is used when animating adding or removing pages.
|
||||
var revealDuration: UInt?
|
||||
/// Spacing between pages in pixels.
|
||||
var spacing: UInt?
|
||||
/// This signal is emitted after a page has been changed.
|
||||
///
|
||||
/// It can be used to implement "infinite scrolling" by amending the pages
|
||||
/// after every scroll. Note that an empty carousel is indicated by
|
||||
/// `(int)index == -1`.
|
||||
var pageChanged: (() -> Void)?
|
||||
/// The dynamic widget elements.
|
||||
var elements: [Element]
|
||||
/// The dynamic widget content.
|
||||
var content: (Element) -> Body
|
||||
/// The application.
|
||||
var app: GTUIApp?
|
||||
/// The window.
|
||||
var window: GTUIApplicationWindow?
|
||||
|
||||
/// Initialize `Carousel`.
|
||||
public init(_ elements: [Element], @ViewBuilder content: @escaping (Element) -> Body) {
|
||||
self.elements = elements
|
||||
self.content = content
|
||||
}
|
||||
|
||||
/// Get the widget's view storage.
|
||||
/// - Parameter modifiers: The view modifiers.
|
||||
/// - Returns: The view storage.
|
||||
public func container(modifiers: [(View) -> View]) -> ViewStorage {
|
||||
let storage = ViewStorage(adw_carousel_new()?.opaque())
|
||||
update(storage, modifiers: modifiers)
|
||||
|
||||
|
||||
for function in appearFunctions {
|
||||
function(storage)
|
||||
}
|
||||
return storage
|
||||
}
|
||||
|
||||
/// Update the widget's view storage.
|
||||
/// - Parameters:
|
||||
/// - storage: The view storage.
|
||||
/// - modifiers: The view modifiers.
|
||||
public func update(_ storage: ViewStorage, modifiers: [(View) -> View]) {
|
||||
if let pageChanged {
|
||||
storage.connectSignal(name: "page-changed") {
|
||||
pageChanged()
|
||||
}
|
||||
}
|
||||
storage.modify { widget in
|
||||
if let allowLongSwipes {
|
||||
adw_carousel_set_allow_long_swipes(widget, allowLongSwipes.cBool)
|
||||
}
|
||||
if let allowMouseDrag {
|
||||
adw_carousel_set_allow_mouse_drag(widget, allowMouseDrag.cBool)
|
||||
}
|
||||
if let allowScrollWheel {
|
||||
adw_carousel_set_allow_scroll_wheel(widget, allowScrollWheel.cBool)
|
||||
}
|
||||
if let interactive {
|
||||
adw_carousel_set_interactive(widget, interactive.cBool)
|
||||
}
|
||||
if let revealDuration {
|
||||
adw_carousel_set_reveal_duration(widget, revealDuration.cInt)
|
||||
}
|
||||
if let spacing {
|
||||
adw_carousel_set_spacing(widget, spacing.cInt)
|
||||
}
|
||||
|
||||
var contentStorage: [ViewStorage] = storage.content[.mainContent] ?? []
|
||||
let old = storage.fields["element"] as? [Element] ?? []
|
||||
old.identifiableTransform(
|
||||
to: elements,
|
||||
functions: .init { index, element in
|
||||
let child = content(element).widget(modifiers: modifiers).container(modifiers: modifiers)
|
||||
adw_carousel_remove(widget, adw_carousel_get_nth_page(widget, UInt(index).cInt))
|
||||
adw_carousel_insert(widget, child.pointer?.cast(), index.cInt)
|
||||
contentStorage.remove(at: index)
|
||||
contentStorage.insert(child, at: index)
|
||||
} delete: { index in
|
||||
adw_carousel_remove(widget, adw_carousel_get_nth_page(widget, UInt(index).cInt))
|
||||
contentStorage.remove(at: index)
|
||||
} insert: { index, element in
|
||||
let child = content(element).widget(modifiers: modifiers).container(modifiers: modifiers)
|
||||
adw_carousel_insert(widget, child.pointer?.cast(), index.cInt)
|
||||
contentStorage.insert(child, at: index)
|
||||
}
|
||||
)
|
||||
storage.fields["element"] = elements
|
||||
storage.content[.mainContent] = contentStorage
|
||||
for (index, element) in elements.enumerated() {
|
||||
content(element).widget(modifiers: modifiers).update(contentStorage[index], modifiers: modifiers)
|
||||
}
|
||||
}
|
||||
for function in updateFunctions {
|
||||
function(storage)
|
||||
}
|
||||
}
|
||||
|
||||
/// Whether to allow swiping for more than one page at a time.
|
||||
///
|
||||
/// If the value is `FALSE`, each swipe can only move to the adjacent pages.
|
||||
public func allowLongSwipes(_ allowLongSwipes: Bool? = true) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.allowLongSwipes = allowLongSwipes
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// Sets whether the `AdwCarousel` can be dragged with mouse pointer.
|
||||
///
|
||||
/// If the value is `FALSE`, dragging is only available on touch.
|
||||
public func allowMouseDrag(_ allowMouseDrag: Bool? = true) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.allowMouseDrag = allowMouseDrag
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// Whether the widget will respond to scroll wheel events.
|
||||
///
|
||||
/// If the value is `FALSE`, wheel events will be ignored.
|
||||
public func allowScrollWheel(_ allowScrollWheel: Bool? = true) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.allowScrollWheel = allowScrollWheel
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// Whether the carousel can be navigated.
|
||||
///
|
||||
/// This can be used to temporarily disable the carousel to only allow
|
||||
/// navigating it in a certain state.
|
||||
public func interactive(_ interactive: Bool? = true) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.interactive = interactive
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// The number of pages in a `AdwCarousel`.
|
||||
public func nPages(_ nPages: UInt?) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.nPages = nPages
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// Page reveal duration, in milliseconds.
|
||||
///
|
||||
/// Reveal duration is used when animating adding or removing pages.
|
||||
public func revealDuration(_ revealDuration: UInt?) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.revealDuration = revealDuration
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// Spacing between pages in pixels.
|
||||
public func spacing(_ spacing: UInt?) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.spacing = spacing
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// This signal is emitted after a page has been changed.
|
||||
///
|
||||
/// It can be used to implement "infinite scrolling" by amending the pages
|
||||
/// after every scroll. Note that an empty carousel is indicated by
|
||||
/// `(int)index == -1`.
|
||||
public func pageChanged(_ pageChanged: @escaping () -> Void) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.pageChanged = pageChanged
|
||||
return newSelf
|
||||
}
|
||||
|
||||
}
|
183
Sources/Adwaita/View/Generated/CenterBox.swift
Normal file
183
Sources/Adwaita/View/Generated/CenterBox.swift
Normal file
@ -0,0 +1,183 @@
|
||||
//
|
||||
// CenterBox.swift
|
||||
// Adwaita
|
||||
//
|
||||
// Created by auto-generation on 22.01.24.
|
||||
//
|
||||
|
||||
import CAdw
|
||||
import LevenshteinTransformations
|
||||
|
||||
/// `GtkCenterBox` arranges three children in a row, keeping the middle child
|
||||
/// centered as well as possible.
|
||||
///
|
||||
/// ![An example GtkCenterBox](centerbox.png)
|
||||
///
|
||||
/// To add children to `GtkCenterBox`, use [method@Gtk.CenterBox.set_start_widget],
|
||||
/// [method@Gtk.CenterBox.set_center_widget] and
|
||||
/// [method@Gtk.CenterBox.set_end_widget].
|
||||
///
|
||||
/// The sizing and positioning of children can be influenced with the
|
||||
/// align and expand properties of the children.
|
||||
///
|
||||
/// # GtkCenterBox as GtkBuildable
|
||||
///
|
||||
/// The `GtkCenterBox` implementation of the `GtkBuildable` interface
|
||||
/// supports placing children in the 3 positions by specifying “start”, “center”
|
||||
/// or “end” as the “type” attribute of a `<child>` element.
|
||||
///
|
||||
/// # CSS nodes
|
||||
///
|
||||
/// `GtkCenterBox` uses a single CSS node with the name “box”,
|
||||
///
|
||||
/// The first child of the `GtkCenterBox` will be allocated depending on the
|
||||
/// text direction, i.e. in left-to-right layouts it will be allocated on the
|
||||
/// left and in right-to-left layouts on the right.
|
||||
///
|
||||
/// In vertical orientation, the nodes of the children are arranged from top to
|
||||
/// bottom.
|
||||
///
|
||||
/// # Accessibility
|
||||
///
|
||||
/// Until GTK 4.10, `GtkCenterBox` used the `GTK_ACCESSIBLE_ROLE_GROUP` role.
|
||||
///
|
||||
/// Starting from GTK 4.12, `GtkCenterBox` uses the `GTK_ACCESSIBLE_ROLE_GENERIC` role.
|
||||
public struct CenterBox: Widget {
|
||||
|
||||
/// Additional update functions for type extensions.
|
||||
var updateFunctions: [(ViewStorage) -> Void] = []
|
||||
/// Additional appear functions for type extensions.
|
||||
var appearFunctions: [(ViewStorage) -> Void] = []
|
||||
|
||||
/// The widget that is placed at the center position.
|
||||
var centerWidget: (() -> Body)?
|
||||
/// The widget that is placed at the end position.
|
||||
///
|
||||
/// In vertical orientation, the end position is at the bottom.
|
||||
/// In horizontal orientation, the end position is at the trailing
|
||||
/// edge wrt. to the text direction.
|
||||
var endWidget: (() -> Body)?
|
||||
/// Whether to shrink the center widget after other children.
|
||||
///
|
||||
/// By default, when there's no space to give all three children their
|
||||
/// natural widths, the start and end widgets start shrinking and the
|
||||
/// center child keeps natural width until they reach minimum width.
|
||||
///
|
||||
/// If set to `FALSE`, start and end widgets keep natural width and the
|
||||
/// center widget starts shrinking instead.
|
||||
var shrinkCenterLast: Bool?
|
||||
/// The widget that is placed at the start position.
|
||||
///
|
||||
/// In vertical orientation, the start position is at the top.
|
||||
/// In horizontal orientation, the start position is at the leading
|
||||
/// edge wrt. to the text direction.
|
||||
var startWidget: (() -> Body)?
|
||||
/// The application.
|
||||
var app: GTUIApp?
|
||||
/// The window.
|
||||
var window: GTUIApplicationWindow?
|
||||
|
||||
/// Initialize `CenterBox`.
|
||||
public init() {
|
||||
}
|
||||
|
||||
/// Get the widget's view storage.
|
||||
/// - Parameter modifiers: The view modifiers.
|
||||
/// - Returns: The view storage.
|
||||
public func container(modifiers: [(View) -> View]) -> ViewStorage {
|
||||
let storage = ViewStorage(gtk_center_box_new()?.opaque())
|
||||
update(storage, modifiers: modifiers)
|
||||
if let centerWidgetStorage = centerWidget?().widget(modifiers: modifiers).storage(modifiers: modifiers) {
|
||||
storage.content["centerWidget"] = [centerWidgetStorage]
|
||||
gtk_center_box_set_center_widget(storage.pointer, centerWidgetStorage.pointer?.cast())
|
||||
}
|
||||
if let endWidgetStorage = endWidget?().widget(modifiers: modifiers).storage(modifiers: modifiers) {
|
||||
storage.content["endWidget"] = [endWidgetStorage]
|
||||
gtk_center_box_set_end_widget(storage.pointer, endWidgetStorage.pointer?.cast())
|
||||
}
|
||||
if let startWidgetStorage = startWidget?().widget(modifiers: modifiers).storage(modifiers: modifiers) {
|
||||
storage.content["startWidget"] = [startWidgetStorage]
|
||||
gtk_center_box_set_start_widget(storage.pointer, startWidgetStorage.pointer?.cast())
|
||||
}
|
||||
|
||||
|
||||
for function in appearFunctions {
|
||||
function(storage)
|
||||
}
|
||||
return storage
|
||||
}
|
||||
|
||||
/// Update the widget's view storage.
|
||||
/// - Parameters:
|
||||
/// - storage: The view storage.
|
||||
/// - modifiers: The view modifiers.
|
||||
public func update(_ storage: ViewStorage, modifiers: [(View) -> View]) {
|
||||
storage.modify { widget in
|
||||
if let widget = storage.content["centerWidget"]?.first {
|
||||
centerWidget?().widget(modifiers: modifiers).update(widget, modifiers: modifiers)
|
||||
}
|
||||
if let widget = storage.content["endWidget"]?.first {
|
||||
endWidget?().widget(modifiers: modifiers).update(widget, modifiers: modifiers)
|
||||
}
|
||||
if let shrinkCenterLast {
|
||||
gtk_center_box_set_shrink_center_last(widget, shrinkCenterLast.cBool)
|
||||
}
|
||||
if let widget = storage.content["startWidget"]?.first {
|
||||
startWidget?().widget(modifiers: modifiers).update(widget, modifiers: modifiers)
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
for function in updateFunctions {
|
||||
function(storage)
|
||||
}
|
||||
}
|
||||
|
||||
/// The widget that is placed at the center position.
|
||||
public func centerWidget(@ViewBuilder _ centerWidget: @escaping (() -> Body)) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.centerWidget = centerWidget
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// The widget that is placed at the end position.
|
||||
///
|
||||
/// In vertical orientation, the end position is at the bottom.
|
||||
/// In horizontal orientation, the end position is at the trailing
|
||||
/// edge wrt. to the text direction.
|
||||
public func endWidget(@ViewBuilder _ endWidget: @escaping (() -> Body)) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.endWidget = endWidget
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// Whether to shrink the center widget after other children.
|
||||
///
|
||||
/// By default, when there's no space to give all three children their
|
||||
/// natural widths, the start and end widgets start shrinking and the
|
||||
/// center child keeps natural width until they reach minimum width.
|
||||
///
|
||||
/// If set to `FALSE`, start and end widgets keep natural width and the
|
||||
/// center widget starts shrinking instead.
|
||||
public func shrinkCenterLast(_ shrinkCenterLast: Bool? = true) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.shrinkCenterLast = shrinkCenterLast
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// The widget that is placed at the start position.
|
||||
///
|
||||
/// In vertical orientation, the start position is at the top.
|
||||
/// In horizontal orientation, the start position is at the leading
|
||||
/// edge wrt. to the text direction.
|
||||
public func startWidget(@ViewBuilder _ startWidget: @escaping (() -> Body)) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.startWidget = startWidget
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
}
|
246
Sources/Adwaita/View/Generated/CheckButton.swift
Normal file
246
Sources/Adwaita/View/Generated/CheckButton.swift
Normal file
@ -0,0 +1,246 @@
|
||||
//
|
||||
// CheckButton.swift
|
||||
// Adwaita
|
||||
//
|
||||
// Created by auto-generation on 22.01.24.
|
||||
//
|
||||
|
||||
import CAdw
|
||||
import LevenshteinTransformations
|
||||
|
||||
/// A `GtkCheckButton` places a label next to an indicator.
|
||||
///
|
||||
/// ![Example GtkCheckButtons](check-button.png)
|
||||
///
|
||||
/// A `GtkCheckButton` is created by calling either [ctor@Gtk.CheckButton.new]
|
||||
/// or [ctor@Gtk.CheckButton.new_with_label].
|
||||
///
|
||||
/// The state of a `GtkCheckButton` can be set specifically using
|
||||
/// [method@Gtk.CheckButton.set_active], and retrieved using
|
||||
/// [method@Gtk.CheckButton.get_active].
|
||||
///
|
||||
/// # Inconsistent state
|
||||
///
|
||||
/// In addition to "on" and "off", check buttons can be an
|
||||
/// "in between" state that is neither on nor off. This can be used
|
||||
/// e.g. when the user has selected a range of elements (such as some
|
||||
/// text or spreadsheet cells) that are affected by a check button,
|
||||
/// and the current values in that range are inconsistent.
|
||||
///
|
||||
/// To set a `GtkCheckButton` to inconsistent state, use
|
||||
/// [method@Gtk.CheckButton.set_inconsistent].
|
||||
///
|
||||
/// # Grouping
|
||||
///
|
||||
/// Check buttons can be grouped together, to form mutually exclusive
|
||||
/// groups - only one of the buttons can be toggled at a time, and toggling
|
||||
/// another one will switch the currently toggled one off.
|
||||
///
|
||||
/// Grouped check buttons use a different indicator, and are commonly referred
|
||||
/// to as *radio buttons*.
|
||||
///
|
||||
/// ![Example GtkCheckButtons](radio-button.png)
|
||||
///
|
||||
/// To add a `GtkCheckButton` to a group, use [method@Gtk.CheckButton.set_group].
|
||||
///
|
||||
/// When the code must keep track of the state of a group of radio buttons, it
|
||||
/// is recommended to keep track of such state through a stateful
|
||||
/// `GAction` with a target for each button. Using the `toggled` signals to keep
|
||||
/// track of the group changes and state is discouraged.
|
||||
///
|
||||
/// # CSS nodes
|
||||
///
|
||||
/// ```
|
||||
/// checkbutton[.text-button]
|
||||
/// ├── check
|
||||
/// ╰── [label]
|
||||
/// ```
|
||||
///
|
||||
/// A `GtkCheckButton` has a main node with name checkbutton. If the
|
||||
/// [property@Gtk.CheckButton:label] or [property@Gtk.CheckButton:child]
|
||||
/// properties are set, it contains a child widget. The indicator node
|
||||
/// is named check when no group is set, and radio if the checkbutton
|
||||
/// is grouped together with other checkbuttons.
|
||||
///
|
||||
/// # Accessibility
|
||||
///
|
||||
/// `GtkCheckButton` uses the %GTK_ACCESSIBLE_ROLE_CHECKBOX role.
|
||||
public struct CheckButton: Widget {
|
||||
|
||||
/// Additional update functions for type extensions.
|
||||
var updateFunctions: [(ViewStorage) -> Void] = []
|
||||
/// Additional appear functions for type extensions.
|
||||
var appearFunctions: [(ViewStorage) -> Void] = []
|
||||
|
||||
/// If the check button is active.
|
||||
///
|
||||
/// Setting `active` to %TRUE will add the `:checked:` state to both
|
||||
/// the check button and the indicator CSS node.
|
||||
var active: Binding<Bool>?
|
||||
/// The child widget.
|
||||
var child: (() -> Body)?
|
||||
/// If the check button is in an “in between” state.
|
||||
///
|
||||
/// The inconsistent state only affects visual appearance,
|
||||
/// not the semantics of the button.
|
||||
var inconsistent: Bool?
|
||||
/// Text of the label inside the check button, if it contains a label widget.
|
||||
var label: String?
|
||||
/// If set, an underline in the text indicates that the following
|
||||
/// character is to be used as mnemonic.
|
||||
var useUnderline: Bool?
|
||||
/// Emitted to when the check button is activated.
|
||||
///
|
||||
/// The `::activate` signal on `GtkCheckButton` is an action signal and
|
||||
/// emitting it causes the button to animate press then release.
|
||||
///
|
||||
/// Applications should never connect to this signal, but use the
|
||||
/// [signal@Gtk.CheckButton::toggled] signal.
|
||||
///
|
||||
/// The default bindings for this signal are all forms of the
|
||||
/// <kbd>␣</kbd> and <kbd>Enter</kbd> keys.
|
||||
var activate: (() -> Void)?
|
||||
/// Emitted when the buttons's [property@Gtk.CheckButton:active]
|
||||
/// property changes.
|
||||
var toggled: (() -> Void)?
|
||||
/// The application.
|
||||
var app: GTUIApp?
|
||||
/// The window.
|
||||
var window: GTUIApplicationWindow?
|
||||
|
||||
/// Initialize `CheckButton`.
|
||||
public init() {
|
||||
}
|
||||
|
||||
/// Get the widget's view storage.
|
||||
/// - Parameter modifiers: The view modifiers.
|
||||
/// - Returns: The view storage.
|
||||
public func container(modifiers: [(View) -> View]) -> ViewStorage {
|
||||
let storage = ViewStorage(gtk_check_button_new()?.opaque())
|
||||
update(storage, modifiers: modifiers)
|
||||
if let childStorage = child?().widget(modifiers: modifiers).storage(modifiers: modifiers) {
|
||||
storage.content["child"] = [childStorage]
|
||||
gtk_check_button_set_child(storage.pointer?.cast(), childStorage.pointer?.cast())
|
||||
}
|
||||
|
||||
|
||||
storage.notify(name: "active") {
|
||||
active?.wrappedValue = gtk_check_button_get_active(storage.pointer?.cast()) != 0
|
||||
}
|
||||
for function in appearFunctions {
|
||||
function(storage)
|
||||
}
|
||||
return storage
|
||||
}
|
||||
|
||||
/// Update the widget's view storage.
|
||||
/// - Parameters:
|
||||
/// - storage: The view storage.
|
||||
/// - modifiers: The view modifiers.
|
||||
public func update(_ storage: ViewStorage, modifiers: [(View) -> View]) {
|
||||
if let activate {
|
||||
storage.connectSignal(name: "activate") {
|
||||
activate()
|
||||
}
|
||||
}
|
||||
if let toggled {
|
||||
storage.connectSignal(name: "toggled") {
|
||||
toggled()
|
||||
}
|
||||
}
|
||||
storage.modify { widget in
|
||||
if let active {
|
||||
gtk_check_button_set_active(widget?.cast(), active.wrappedValue.cBool)
|
||||
}
|
||||
if let widget = storage.content["child"]?.first {
|
||||
child?().widget(modifiers: modifiers).update(widget, modifiers: modifiers)
|
||||
}
|
||||
if let inconsistent {
|
||||
gtk_check_button_set_inconsistent(widget?.cast(), inconsistent.cBool)
|
||||
}
|
||||
if let label, storage.content["child"] == nil {
|
||||
gtk_check_button_set_label(widget?.cast(), label)
|
||||
}
|
||||
if let useUnderline {
|
||||
gtk_check_button_set_use_underline(widget?.cast(), useUnderline.cBool)
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
for function in updateFunctions {
|
||||
function(storage)
|
||||
}
|
||||
}
|
||||
|
||||
/// If the check button is active.
|
||||
///
|
||||
/// Setting `active` to %TRUE will add the `:checked:` state to both
|
||||
/// the check button and the indicator CSS node.
|
||||
public func active(_ active: Binding<Bool>?) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.active = active
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// The child widget.
|
||||
public func child(@ViewBuilder _ child: @escaping (() -> Body)) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.child = child
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// If the check button is in an “in between” state.
|
||||
///
|
||||
/// The inconsistent state only affects visual appearance,
|
||||
/// not the semantics of the button.
|
||||
public func inconsistent(_ inconsistent: Bool? = true) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.inconsistent = inconsistent
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// Text of the label inside the check button, if it contains a label widget.
|
||||
public func label(_ label: String?) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.label = label
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// If set, an underline in the text indicates that the following
|
||||
/// character is to be used as mnemonic.
|
||||
public func useUnderline(_ useUnderline: Bool? = true) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.useUnderline = useUnderline
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// Emitted to when the check button is activated.
|
||||
///
|
||||
/// The `::activate` signal on `GtkCheckButton` is an action signal and
|
||||
/// emitting it causes the button to animate press then release.
|
||||
///
|
||||
/// Applications should never connect to this signal, but use the
|
||||
/// [signal@Gtk.CheckButton::toggled] signal.
|
||||
///
|
||||
/// The default bindings for this signal are all forms of the
|
||||
/// <kbd>␣</kbd> and <kbd>Enter</kbd> keys.
|
||||
public func activate(_ activate: @escaping () -> Void) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.activate = activate
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// Emitted when the buttons's [property@Gtk.CheckButton:active]
|
||||
/// property changes.
|
||||
public func toggled(_ toggled: @escaping () -> Void) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.toggled = toggled
|
||||
return newSelf
|
||||
}
|
||||
|
||||
}
|
146
Sources/Adwaita/View/Generated/Clamp.swift
Normal file
146
Sources/Adwaita/View/Generated/Clamp.swift
Normal file
@ -0,0 +1,146 @@
|
||||
//
|
||||
// Clamp.swift
|
||||
// Adwaita
|
||||
//
|
||||
// Created by auto-generation on 22.01.24.
|
||||
//
|
||||
|
||||
import CAdw
|
||||
import LevenshteinTransformations
|
||||
|
||||
/// A widget constraining its child to a given size.
|
||||
///
|
||||
/// <picture><source srcset="clamp-wide-dark.png" media="(prefers-color-scheme: dark)"><img src="clamp-wide.png" alt="clamp-wide"></picture><picture><source srcset="clamp-narrow-dark.png" media="(prefers-color-scheme: dark)"><img src="clamp-narrow.png" alt="clamp-narrow"></picture>
|
||||
///
|
||||
/// The `AdwClamp` widget constrains the size of the widget it contains to a
|
||||
/// given maximum size. It will constrain the width if it is horizontal, or the
|
||||
/// height if it is vertical. The expansion of the child from its minimum to its
|
||||
/// maximum size is eased out for a smooth transition.
|
||||
///
|
||||
/// If the child requires more than the requested maximum size, it will be
|
||||
/// allocated the minimum size it can fit in instead.
|
||||
///
|
||||
/// `AdwClamp` can scale with the text scale factor, use the
|
||||
/// [property@ClampLayout:unit] property to enable that behavior.
|
||||
///
|
||||
/// ## CSS nodes
|
||||
///
|
||||
/// `AdwClamp` has a single CSS node with name `clamp`.
|
||||
public struct Clamp: Widget {
|
||||
|
||||
/// Additional update functions for type extensions.
|
||||
var updateFunctions: [(ViewStorage) -> Void] = []
|
||||
/// Additional appear functions for type extensions.
|
||||
var appearFunctions: [(ViewStorage) -> Void] = []
|
||||
|
||||
/// The child widget of the `AdwClamp`.
|
||||
var child: (() -> Body)?
|
||||
/// The maximum size allocated to the child.
|
||||
///
|
||||
/// It is the width if the clamp is horizontal, or the height if it is vertical.
|
||||
var maximumSize: Int?
|
||||
/// The size above which the child is clamped.
|
||||
///
|
||||
/// Starting from this size, the clamp will tighten its grip on the child,
|
||||
/// slowly allocating less and less of the available size up to the maximum
|
||||
/// allocated size. Below that threshold and below the maximum size, the child
|
||||
/// will be allocated all the available size.
|
||||
///
|
||||
/// If the threshold is greater than the maximum size to allocate to the child,
|
||||
/// the child will be allocated all the size up to the maximum.
|
||||
/// If the threshold is lower than the minimum size to allocate to the child,
|
||||
/// that size will be used as the tightening threshold.
|
||||
///
|
||||
/// Effectively, tightening the grip on the child before it reaches its maximum
|
||||
/// size makes transitions to and from the maximum size smoother when resizing.
|
||||
var tighteningThreshold: Int?
|
||||
/// The application.
|
||||
var app: GTUIApp?
|
||||
/// The window.
|
||||
var window: GTUIApplicationWindow?
|
||||
|
||||
/// Initialize `Clamp`.
|
||||
public init() {
|
||||
}
|
||||
|
||||
/// Get the widget's view storage.
|
||||
/// - Parameter modifiers: The view modifiers.
|
||||
/// - Returns: The view storage.
|
||||
public func container(modifiers: [(View) -> View]) -> ViewStorage {
|
||||
let storage = ViewStorage(adw_clamp_new()?.opaque())
|
||||
update(storage, modifiers: modifiers)
|
||||
if let childStorage = child?().widget(modifiers: modifiers).storage(modifiers: modifiers) {
|
||||
storage.content["child"] = [childStorage]
|
||||
adw_clamp_set_child(storage.pointer, childStorage.pointer?.cast())
|
||||
}
|
||||
|
||||
|
||||
for function in appearFunctions {
|
||||
function(storage)
|
||||
}
|
||||
return storage
|
||||
}
|
||||
|
||||
/// Update the widget's view storage.
|
||||
/// - Parameters:
|
||||
/// - storage: The view storage.
|
||||
/// - modifiers: The view modifiers.
|
||||
public func update(_ storage: ViewStorage, modifiers: [(View) -> View]) {
|
||||
storage.modify { widget in
|
||||
if let widget = storage.content["child"]?.first {
|
||||
child?().widget(modifiers: modifiers).update(widget, modifiers: modifiers)
|
||||
}
|
||||
if let maximumSize {
|
||||
adw_clamp_set_maximum_size(widget, maximumSize.cInt)
|
||||
}
|
||||
if let tighteningThreshold {
|
||||
adw_clamp_set_tightening_threshold(widget, tighteningThreshold.cInt)
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
for function in updateFunctions {
|
||||
function(storage)
|
||||
}
|
||||
}
|
||||
|
||||
/// The child widget of the `AdwClamp`.
|
||||
public func child(@ViewBuilder _ child: @escaping (() -> Body)) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.child = child
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// The maximum size allocated to the child.
|
||||
///
|
||||
/// It is the width if the clamp is horizontal, or the height if it is vertical.
|
||||
public func maximumSize(_ maximumSize: Int?) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.maximumSize = maximumSize
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// The size above which the child is clamped.
|
||||
///
|
||||
/// Starting from this size, the clamp will tighten its grip on the child,
|
||||
/// slowly allocating less and less of the available size up to the maximum
|
||||
/// allocated size. Below that threshold and below the maximum size, the child
|
||||
/// will be allocated all the available size.
|
||||
///
|
||||
/// If the threshold is greater than the maximum size to allocate to the child,
|
||||
/// the child will be allocated all the size up to the maximum.
|
||||
/// If the threshold is lower than the minimum size to allocate to the child,
|
||||
/// that size will be used as the tightening threshold.
|
||||
///
|
||||
/// Effectively, tightening the grip on the child before it reaches its maximum
|
||||
/// size makes transitions to and from the maximum size smoother when resizing.
|
||||
public func tighteningThreshold(_ tighteningThreshold: Int?) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.tighteningThreshold = tighteningThreshold
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
}
|
380
Sources/Adwaita/View/Generated/ComboRow.swift
Normal file
380
Sources/Adwaita/View/Generated/ComboRow.swift
Normal file
@ -0,0 +1,380 @@
|
||||
//
|
||||
// ComboRow.swift
|
||||
// Adwaita
|
||||
//
|
||||
// Created by auto-generation on 22.01.24.
|
||||
//
|
||||
|
||||
import CAdw
|
||||
import LevenshteinTransformations
|
||||
|
||||
/// A [class@Gtk.ListBoxRow] used to choose from a list of items.
|
||||
///
|
||||
/// <picture><source srcset="combo-row-dark.png" media="(prefers-color-scheme: dark)"><img src="combo-row.png" alt="combo-row"></picture>
|
||||
///
|
||||
/// The `AdwComboRow` widget allows the user to choose from a list of valid
|
||||
/// choices. The row displays the selected choice. When activated, the row
|
||||
/// displays a popover which allows the user to make a new choice.
|
||||
///
|
||||
/// Example of an `AdwComboRow` UI definition:
|
||||
/// ```xml
|
||||
/// <object class="AdwComboRow"><property name="title" translatable="yes">Combo Row</property><property name="model"><object class="GtkStringList"><items><item translatable="yes">Foo</item><item translatable="yes">Bar</item><item translatable="yes">Baz</item></items></object></property></object>
|
||||
/// ```
|
||||
///
|
||||
/// The [property@ComboRow:selected] and [property@ComboRow:selected-item]
|
||||
/// properties can be used to keep track of the selected item and react to their
|
||||
/// changes.
|
||||
///
|
||||
/// `AdwComboRow` mirrors [class@Gtk.DropDown], see that widget for details.
|
||||
///
|
||||
/// `AdwComboRow` is [property@Gtk.ListBoxRow:activatable] if a model is set.
|
||||
///
|
||||
/// ## CSS nodes
|
||||
///
|
||||
/// `AdwComboRow` has a main CSS node with name `row` and the `.combo` style
|
||||
/// class.
|
||||
///
|
||||
/// Its popover has the node named `popover` with the `.menu` style class, it
|
||||
/// contains a [class@Gtk.ScrolledWindow], which in turn contains a
|
||||
/// [class@Gtk.ListView], both are accessible via their regular nodes.
|
||||
///
|
||||
/// ## Accessibility
|
||||
///
|
||||
/// `AdwComboRow` uses the `GTK_ACCESSIBLE_ROLE_COMBO_BOX` role.
|
||||
public struct ComboRow: Widget {
|
||||
|
||||
/// Additional update functions for type extensions.
|
||||
var updateFunctions: [(ViewStorage) -> Void] = []
|
||||
/// Additional appear functions for type extensions.
|
||||
var appearFunctions: [(ViewStorage) -> Void] = []
|
||||
|
||||
/// Whether to show a search entry in the popup.
|
||||
///
|
||||
/// If set to `TRUE`, a search entry will be shown in the popup that
|
||||
/// allows to search for items in the list.
|
||||
///
|
||||
/// Search requires [property@ComboRow:expression] to be set.
|
||||
var enableSearch: Bool?
|
||||
/// The position of the selected item.
|
||||
///
|
||||
/// If no item is selected, the property has the value
|
||||
/// [const@Gtk.INVALID_LIST_POSITION]
|
||||
var selected: Binding<UInt>?
|
||||
/// Whether to use the current value as the subtitle.
|
||||
///
|
||||
/// If you use a custom list item factory, you will need to give the row a
|
||||
/// name conversion expression with [property@ComboRow:expression].
|
||||
///
|
||||
/// If set to `TRUE`, you should not access [property@ActionRow:subtitle].
|
||||
///
|
||||
/// The subtitle is interpreted as Pango markup if
|
||||
/// [property@PreferencesRow:use-markup] is set to `TRUE`.
|
||||
var useSubtitle: Bool?
|
||||
/// The widget to activate when the row is activated.
|
||||
///
|
||||
/// The row can be activated either by clicking on it, calling
|
||||
/// [method@ActionRow.activate], or via mnemonics in the title.
|
||||
/// See the [property@PreferencesRow:use-underline] property to enable
|
||||
/// mnemonics.
|
||||
///
|
||||
/// The target widget will be activated by emitting the
|
||||
/// [signal@Gtk.Widget::mnemonic-activate] signal on it.
|
||||
var activatableWidget: (() -> Body)?
|
||||
/// The icon name for this row.
|
||||
var iconName: String?
|
||||
/// The subtitle for this row.
|
||||
///
|
||||
/// The subtitle is interpreted as Pango markup unless
|
||||
/// [property@PreferencesRow:use-markup] is set to `FALSE`.
|
||||
var subtitle: String?
|
||||
/// The number of lines at the end of which the subtitle label will be
|
||||
/// ellipsized.
|
||||
///
|
||||
/// If the value is 0, the number of lines won't be limited.
|
||||
var subtitleLines: Int?
|
||||
/// Whether the user can copy the subtitle from the label.
|
||||
///
|
||||
/// See also [property@Gtk.Label:selectable].
|
||||
var subtitleSelectable: Bool?
|
||||
/// The number of lines at the end of which the title label will be ellipsized.
|
||||
///
|
||||
/// If the value is 0, the number of lines won't be limited.
|
||||
var titleLines: Int?
|
||||
/// The title of the preference represented by this row.
|
||||
///
|
||||
/// The title is interpreted as Pango markup unless
|
||||
/// [property@PreferencesRow:use-markup] is set to `FALSE`.
|
||||
var title: String?
|
||||
/// Whether the user can copy the title from the label.
|
||||
///
|
||||
/// See also [property@Gtk.Label:selectable].
|
||||
var titleSelectable: Bool?
|
||||
/// Whether to use Pango markup for the title label.
|
||||
///
|
||||
/// Subclasses may also use it for other labels, such as subtitle.
|
||||
///
|
||||
/// See also [func@Pango.parse_markup].
|
||||
var useMarkup: Bool?
|
||||
/// Whether an embedded underline in the title indicates a mnemonic.
|
||||
var useUnderline: Bool?
|
||||
/// This signal is emitted after the row has been activated.
|
||||
var activated: (() -> Void)?
|
||||
/// The body for the widget "suffix".
|
||||
var suffix: () -> Body = { [] }
|
||||
/// The body for the widget "prefix".
|
||||
var prefix: () -> Body = { [] }
|
||||
/// The application.
|
||||
var app: GTUIApp?
|
||||
/// The window.
|
||||
var window: GTUIApplicationWindow?
|
||||
|
||||
/// Initialize `ComboRow`.
|
||||
public init() {
|
||||
}
|
||||
|
||||
/// Get the widget's view storage.
|
||||
/// - Parameter modifiers: The view modifiers.
|
||||
/// - Returns: The view storage.
|
||||
public func container(modifiers: [(View) -> View]) -> ViewStorage {
|
||||
let storage = ViewStorage(adw_combo_row_new()?.opaque())
|
||||
update(storage, modifiers: modifiers)
|
||||
if let activatableWidgetStorage = activatableWidget?().widget(modifiers: modifiers).storage(modifiers: modifiers) {
|
||||
storage.content["activatableWidget"] = [activatableWidgetStorage]
|
||||
adw_action_row_set_activatable_widget(storage.pointer?.cast(), activatableWidgetStorage.pointer?.cast())
|
||||
}
|
||||
|
||||
var suffixStorage: [ViewStorage] = []
|
||||
for view in suffix() {
|
||||
suffixStorage.append(view.storage(modifiers: modifiers))
|
||||
adw_action_row_add_suffix(storage.pointer?.cast(), suffixStorage.last?.pointer?.cast())
|
||||
}
|
||||
storage.content["suffix"] = suffixStorage
|
||||
var prefixStorage: [ViewStorage] = []
|
||||
for view in prefix() {
|
||||
prefixStorage.append(view.storage(modifiers: modifiers))
|
||||
adw_action_row_add_prefix(storage.pointer?.cast(), prefixStorage.last?.pointer?.cast())
|
||||
}
|
||||
storage.content["prefix"] = prefixStorage
|
||||
|
||||
storage.notify(name: "selected") {
|
||||
selected?.wrappedValue = .init(adw_combo_row_get_selected(storage.pointer?.cast()))
|
||||
}
|
||||
for function in appearFunctions {
|
||||
function(storage)
|
||||
}
|
||||
return storage
|
||||
}
|
||||
|
||||
/// Update the widget's view storage.
|
||||
/// - Parameters:
|
||||
/// - storage: The view storage.
|
||||
/// - modifiers: The view modifiers.
|
||||
public func update(_ storage: ViewStorage, modifiers: [(View) -> View]) {
|
||||
if let activated {
|
||||
storage.connectSignal(name: "activated") {
|
||||
activated()
|
||||
}
|
||||
}
|
||||
storage.modify { widget in
|
||||
if let enableSearch {
|
||||
adw_combo_row_set_enable_search(widget?.cast(), enableSearch.cBool)
|
||||
}
|
||||
if let selected {
|
||||
adw_combo_row_set_selected(widget?.cast(), selected.wrappedValue.cInt)
|
||||
}
|
||||
if let useSubtitle {
|
||||
adw_combo_row_set_use_subtitle(widget?.cast(), useSubtitle.cBool)
|
||||
}
|
||||
if let widget = storage.content["activatableWidget"]?.first {
|
||||
activatableWidget?().widget(modifiers: modifiers).update(widget, modifiers: modifiers)
|
||||
}
|
||||
if let iconName {
|
||||
adw_action_row_set_icon_name(widget?.cast(), iconName)
|
||||
}
|
||||
if let subtitle {
|
||||
adw_action_row_set_subtitle(widget?.cast(), subtitle)
|
||||
}
|
||||
if let subtitleLines {
|
||||
adw_action_row_set_subtitle_lines(widget?.cast(), subtitleLines.cInt)
|
||||
}
|
||||
if let subtitleSelectable {
|
||||
adw_action_row_set_subtitle_selectable(widget?.cast(), subtitleSelectable.cBool)
|
||||
}
|
||||
if let titleLines {
|
||||
adw_action_row_set_title_lines(widget?.cast(), titleLines.cInt)
|
||||
}
|
||||
if let title {
|
||||
adw_preferences_row_set_title(widget?.cast(), title)
|
||||
}
|
||||
if let titleSelectable {
|
||||
adw_preferences_row_set_title_selectable(widget?.cast(), titleSelectable.cBool)
|
||||
}
|
||||
if let useMarkup {
|
||||
adw_preferences_row_set_use_markup(widget?.cast(), useMarkup.cBool)
|
||||
}
|
||||
if let useUnderline {
|
||||
adw_preferences_row_set_use_underline(widget?.cast(), useUnderline.cBool)
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
for function in updateFunctions {
|
||||
function(storage)
|
||||
}
|
||||
}
|
||||
|
||||
/// Whether to show a search entry in the popup.
|
||||
///
|
||||
/// If set to `TRUE`, a search entry will be shown in the popup that
|
||||
/// allows to search for items in the list.
|
||||
///
|
||||
/// Search requires [property@ComboRow:expression] to be set.
|
||||
public func enableSearch(_ enableSearch: Bool? = true) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.enableSearch = enableSearch
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// The position of the selected item.
|
||||
///
|
||||
/// If no item is selected, the property has the value
|
||||
/// [const@Gtk.INVALID_LIST_POSITION]
|
||||
public func selected(_ selected: Binding<UInt>?) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.selected = selected
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// Whether to use the current value as the subtitle.
|
||||
///
|
||||
/// If you use a custom list item factory, you will need to give the row a
|
||||
/// name conversion expression with [property@ComboRow:expression].
|
||||
///
|
||||
/// If set to `TRUE`, you should not access [property@ActionRow:subtitle].
|
||||
///
|
||||
/// The subtitle is interpreted as Pango markup if
|
||||
/// [property@PreferencesRow:use-markup] is set to `TRUE`.
|
||||
public func useSubtitle(_ useSubtitle: Bool? = true) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.useSubtitle = useSubtitle
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// The widget to activate when the row is activated.
|
||||
///
|
||||
/// The row can be activated either by clicking on it, calling
|
||||
/// [method@ActionRow.activate], or via mnemonics in the title.
|
||||
/// See the [property@PreferencesRow:use-underline] property to enable
|
||||
/// mnemonics.
|
||||
///
|
||||
/// The target widget will be activated by emitting the
|
||||
/// [signal@Gtk.Widget::mnemonic-activate] signal on it.
|
||||
public func activatableWidget(@ViewBuilder _ activatableWidget: @escaping (() -> Body)) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.activatableWidget = activatableWidget
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// The icon name for this row.
|
||||
public func iconName(_ iconName: String?) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.iconName = iconName
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// The subtitle for this row.
|
||||
///
|
||||
/// The subtitle is interpreted as Pango markup unless
|
||||
/// [property@PreferencesRow:use-markup] is set to `FALSE`.
|
||||
public func subtitle(_ subtitle: String?) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.subtitle = subtitle
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// The number of lines at the end of which the subtitle label will be
|
||||
/// ellipsized.
|
||||
///
|
||||
/// If the value is 0, the number of lines won't be limited.
|
||||
public func subtitleLines(_ subtitleLines: Int?) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.subtitleLines = subtitleLines
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// Whether the user can copy the subtitle from the label.
|
||||
///
|
||||
/// See also [property@Gtk.Label:selectable].
|
||||
public func subtitleSelectable(_ subtitleSelectable: Bool? = true) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.subtitleSelectable = subtitleSelectable
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// The number of lines at the end of which the title label will be ellipsized.
|
||||
///
|
||||
/// If the value is 0, the number of lines won't be limited.
|
||||
public func titleLines(_ titleLines: Int?) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.titleLines = titleLines
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// The title of the preference represented by this row.
|
||||
///
|
||||
/// The title is interpreted as Pango markup unless
|
||||
/// [property@PreferencesRow:use-markup] is set to `FALSE`.
|
||||
public func title(_ title: String?) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.title = title
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// Whether the user can copy the title from the label.
|
||||
///
|
||||
/// See also [property@Gtk.Label:selectable].
|
||||
public func titleSelectable(_ titleSelectable: Bool? = true) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.titleSelectable = titleSelectable
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// Whether to use Pango markup for the title label.
|
||||
///
|
||||
/// Subclasses may also use it for other labels, such as subtitle.
|
||||
///
|
||||
/// See also [func@Pango.parse_markup].
|
||||
public func useMarkup(_ useMarkup: Bool? = true) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.useMarkup = useMarkup
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// Whether an embedded underline in the title indicates a mnemonic.
|
||||
public func useUnderline(_ useUnderline: Bool? = true) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.useUnderline = useUnderline
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// This signal is emitted after the row has been activated.
|
||||
public func activated(_ activated: @escaping () -> Void) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.activated = activated
|
||||
return newSelf
|
||||
}
|
||||
|
||||
}
|
293
Sources/Adwaita/View/Generated/EntryRow.swift
Normal file
293
Sources/Adwaita/View/Generated/EntryRow.swift
Normal file
@ -0,0 +1,293 @@
|
||||
//
|
||||
// EntryRow.swift
|
||||
// Adwaita
|
||||
//
|
||||
// Created by auto-generation on 22.01.24.
|
||||
//
|
||||
|
||||
import CAdw
|
||||
import LevenshteinTransformations
|
||||
|
||||
/// A [class@Gtk.ListBoxRow] with an embedded text entry.
|
||||
///
|
||||
/// <picture><source srcset="entry-row-dark.png" media="(prefers-color-scheme: dark)"><img src="entry-row.png" alt="entry-row"></picture>
|
||||
///
|
||||
/// `AdwEntryRow` has a title that doubles as placeholder text. It shows an icon
|
||||
/// indicating that it's editable and can receive additional widgets before or
|
||||
/// after the editable part.
|
||||
///
|
||||
/// If [property@EntryRow:show-apply-button] is set to `TRUE`, `AdwEntryRow` can
|
||||
/// show an apply button when editing its contents. This can be useful if
|
||||
/// changing its contents can result in an expensive operation, such as network
|
||||
/// activity.
|
||||
///
|
||||
/// `AdwEntryRow` provides only minimal API and should be used with the
|
||||
/// [iface@Gtk.Editable] API.
|
||||
///
|
||||
/// See also [class@PasswordEntryRow].
|
||||
///
|
||||
/// ## AdwEntryRow as GtkBuildable
|
||||
///
|
||||
/// The `AdwEntryRow` implementation of the [iface@Gtk.Buildable] interface
|
||||
/// supports adding a child at its end by specifying “suffix” or omitting the
|
||||
/// “type” attribute of a <child> element.
|
||||
///
|
||||
/// It also supports adding a child as a prefix widget by specifying “prefix” as
|
||||
/// the “type” attribute of a <child> element.
|
||||
///
|
||||
/// ## CSS nodes
|
||||
///
|
||||
/// `AdwEntryRow` has a single CSS node with name `row` and the `.entry` style
|
||||
/// class.
|
||||
public struct EntryRow: Widget {
|
||||
|
||||
/// Additional update functions for type extensions.
|
||||
var updateFunctions: [(ViewStorage) -> Void] = []
|
||||
/// Additional appear functions for type extensions.
|
||||
var appearFunctions: [(ViewStorage) -> Void] = []
|
||||
|
||||
/// Whether activating the embedded entry can activate the default widget.
|
||||
var activatesDefault: Bool?
|
||||
/// Whether to suggest emoji replacements on the entry row.
|
||||
///
|
||||
/// Emoji replacement is done with :-delimited names, like `:heart:`.
|
||||
var enableEmojiCompletion: Bool?
|
||||
/// Whether to show the apply button.
|
||||
///
|
||||
/// When set to `TRUE`, typing text in the entry will reveal an apply button.
|
||||
/// Clicking it or pressing the <kbd>Enter</kbd> key will hide the button and
|
||||
/// emit the [signal@EntryRow::apply] signal.
|
||||
///
|
||||
/// This is useful if changing the entry contents can trigger an expensive
|
||||
/// operation, e.g. network activity, to avoid triggering it after typing every
|
||||
/// character.
|
||||
var showApplyButton: Bool?
|
||||
/// The title of the preference represented by this row.
|
||||
///
|
||||
/// The title is interpreted as Pango markup unless
|
||||
/// [property@PreferencesRow:use-markup] is set to `FALSE`.
|
||||
var title: String?
|
||||
/// Whether the user can copy the title from the label.
|
||||
///
|
||||
/// See also [property@Gtk.Label:selectable].
|
||||
var titleSelectable: Bool?
|
||||
/// Whether to use Pango markup for the title label.
|
||||
///
|
||||
/// Subclasses may also use it for other labels, such as subtitle.
|
||||
///
|
||||
/// See also [func@Pango.parse_markup].
|
||||
var useMarkup: Bool?
|
||||
/// Whether an embedded underline in the title indicates a mnemonic.
|
||||
var useUnderline: Bool?
|
||||
/// Emitted when the apply button is pressed.
|
||||
///
|
||||
/// See [property@EntryRow:show-apply-button].
|
||||
var apply: (() -> Void)?
|
||||
/// Emitted when the embedded entry is activated.
|
||||
var entryActivated: (() -> Void)?
|
||||
/// The body for the widget "suffix".
|
||||
var suffix: () -> Body = { [] }
|
||||
/// The body for the widget "prefix".
|
||||
var prefix: () -> Body = { [] }
|
||||
/// The application.
|
||||
var app: GTUIApp?
|
||||
/// The window.
|
||||
var window: GTUIApplicationWindow?
|
||||
|
||||
/// Initialize `EntryRow`.
|
||||
public init() {
|
||||
}
|
||||
|
||||
/// Get the widget's view storage.
|
||||
/// - Parameter modifiers: The view modifiers.
|
||||
/// - Returns: The view storage.
|
||||
public func container(modifiers: [(View) -> View]) -> ViewStorage {
|
||||
let storage = ViewStorage(adw_entry_row_new()?.opaque())
|
||||
update(storage, modifiers: modifiers)
|
||||
|
||||
var suffixStorage: [ViewStorage] = []
|
||||
for view in suffix() {
|
||||
suffixStorage.append(view.storage(modifiers: modifiers))
|
||||
adw_entry_row_add_suffix(storage.pointer?.cast(), suffixStorage.last?.pointer?.cast())
|
||||
}
|
||||
storage.content["suffix"] = suffixStorage
|
||||
var prefixStorage: [ViewStorage] = []
|
||||
for view in prefix() {
|
||||
prefixStorage.append(view.storage(modifiers: modifiers))
|
||||
adw_entry_row_add_prefix(storage.pointer?.cast(), prefixStorage.last?.pointer?.cast())
|
||||
}
|
||||
storage.content["prefix"] = prefixStorage
|
||||
|
||||
for function in appearFunctions {
|
||||
function(storage)
|
||||
}
|
||||
return storage
|
||||
}
|
||||
|
||||
/// Update the widget's view storage.
|
||||
/// - Parameters:
|
||||
/// - storage: The view storage.
|
||||
/// - modifiers: The view modifiers.
|
||||
public func update(_ storage: ViewStorage, modifiers: [(View) -> View]) {
|
||||
if let apply {
|
||||
storage.connectSignal(name: "apply") {
|
||||
apply()
|
||||
}
|
||||
}
|
||||
if let entryActivated {
|
||||
storage.connectSignal(name: "entry-activated") {
|
||||
entryActivated()
|
||||
}
|
||||
}
|
||||
storage.modify { widget in
|
||||
if let activatesDefault {
|
||||
adw_entry_row_set_activates_default(widget?.cast(), activatesDefault.cBool)
|
||||
}
|
||||
if let enableEmojiCompletion {
|
||||
adw_entry_row_set_enable_emoji_completion(widget?.cast(), enableEmojiCompletion.cBool)
|
||||
}
|
||||
if let showApplyButton {
|
||||
adw_entry_row_set_show_apply_button(widget?.cast(), showApplyButton.cBool)
|
||||
}
|
||||
if let title {
|
||||
adw_preferences_row_set_title(widget?.cast(), title)
|
||||
}
|
||||
if let titleSelectable {
|
||||
adw_preferences_row_set_title_selectable(widget?.cast(), titleSelectable.cBool)
|
||||
}
|
||||
if let useMarkup {
|
||||
adw_preferences_row_set_use_markup(widget?.cast(), useMarkup.cBool)
|
||||
}
|
||||
if let useUnderline {
|
||||
adw_preferences_row_set_use_underline(widget?.cast(), useUnderline.cBool)
|
||||
}
|
||||
|
||||
if let suffixStorage = storage.content["suffix"] {
|
||||
for (index, view) in suffix().enumerated() {
|
||||
if let storage = suffixStorage[safe: index] {
|
||||
view.updateStorage(storage, modifiers: modifiers)
|
||||
}
|
||||
}
|
||||
}
|
||||
if let prefixStorage = storage.content["prefix"] {
|
||||
for (index, view) in prefix().enumerated() {
|
||||
if let storage = prefixStorage[safe: index] {
|
||||
view.updateStorage(storage, modifiers: modifiers)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
for function in updateFunctions {
|
||||
function(storage)
|
||||
}
|
||||
}
|
||||
|
||||
/// Whether activating the embedded entry can activate the default widget.
|
||||
public func activatesDefault(_ activatesDefault: Bool? = true) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.activatesDefault = activatesDefault
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// Whether to suggest emoji replacements on the entry row.
|
||||
///
|
||||
/// Emoji replacement is done with :-delimited names, like `:heart:`.
|
||||
public func enableEmojiCompletion(_ enableEmojiCompletion: Bool? = true) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.enableEmojiCompletion = enableEmojiCompletion
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// Whether to show the apply button.
|
||||
///
|
||||
/// When set to `TRUE`, typing text in the entry will reveal an apply button.
|
||||
/// Clicking it or pressing the <kbd>Enter</kbd> key will hide the button and
|
||||
/// emit the [signal@EntryRow::apply] signal.
|
||||
///
|
||||
/// This is useful if changing the entry contents can trigger an expensive
|
||||
/// operation, e.g. network activity, to avoid triggering it after typing every
|
||||
/// character.
|
||||
public func showApplyButton(_ showApplyButton: Bool? = true) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.showApplyButton = showApplyButton
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// The title of the preference represented by this row.
|
||||
///
|
||||
/// The title is interpreted as Pango markup unless
|
||||
/// [property@PreferencesRow:use-markup] is set to `FALSE`.
|
||||
public func title(_ title: String?) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.title = title
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// Whether the user can copy the title from the label.
|
||||
///
|
||||
/// See also [property@Gtk.Label:selectable].
|
||||
public func titleSelectable(_ titleSelectable: Bool? = true) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.titleSelectable = titleSelectable
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// Whether to use Pango markup for the title label.
|
||||
///
|
||||
/// Subclasses may also use it for other labels, such as subtitle.
|
||||
///
|
||||
/// See also [func@Pango.parse_markup].
|
||||
public func useMarkup(_ useMarkup: Bool? = true) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.useMarkup = useMarkup
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// Whether an embedded underline in the title indicates a mnemonic.
|
||||
public func useUnderline(_ useUnderline: Bool? = true) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.useUnderline = useUnderline
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// Emitted when the apply button is pressed.
|
||||
///
|
||||
/// See [property@EntryRow:show-apply-button].
|
||||
public func apply(_ apply: @escaping () -> Void) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.apply = apply
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// Emitted when the embedded entry is activated.
|
||||
public func entryActivated(_ entryActivated: @escaping () -> Void) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.entryActivated = entryActivated
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// Set the body for "suffix".
|
||||
/// - Parameter body: The body.
|
||||
/// - Returns: The widget.
|
||||
public func suffix(@ViewBuilder _ body: @escaping () -> Body) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.suffix = body
|
||||
return newSelf
|
||||
}
|
||||
/// Set the body for "prefix".
|
||||
/// - Parameter body: The body.
|
||||
/// - Returns: The widget.
|
||||
public func prefix(@ViewBuilder _ body: @escaping () -> Body) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.prefix = body
|
||||
return newSelf
|
||||
}
|
||||
}
|
332
Sources/Adwaita/View/Generated/ExpanderRow.swift
Normal file
332
Sources/Adwaita/View/Generated/ExpanderRow.swift
Normal file
@ -0,0 +1,332 @@
|
||||
//
|
||||
// ExpanderRow.swift
|
||||
// Adwaita
|
||||
//
|
||||
// Created by auto-generation on 22.01.24.
|
||||
//
|
||||
|
||||
import CAdw
|
||||
import LevenshteinTransformations
|
||||
|
||||
/// A [class@Gtk.ListBoxRow] used to reveal widgets.
|
||||
///
|
||||
/// <picture><source srcset="expander-row-dark.png" media="(prefers-color-scheme: dark)"><img src="expander-row.png" alt="expander-row"></picture>
|
||||
///
|
||||
/// The `AdwExpanderRow` widget allows the user to reveal or hide widgets below
|
||||
/// it. It also allows the user to enable the expansion of the row, allowing to
|
||||
/// disable all that the row contains.
|
||||
///
|
||||
/// ## AdwExpanderRow as GtkBuildable
|
||||
///
|
||||
/// The `AdwExpanderRow` implementation of the [iface@Gtk.Buildable] interface
|
||||
/// supports adding a child as an suffix widget by specifying “suffix” as the
|
||||
/// “type” attribute of a <child> element.
|
||||
///
|
||||
/// It also supports adding it as a prefix widget by specifying “prefix” as the
|
||||
/// “type” attribute of a <child> element.
|
||||
///
|
||||
/// ## CSS nodes
|
||||
///
|
||||
/// `AdwExpanderRow` has a main CSS node with name `row` and the `.expander`
|
||||
/// style class. It has the `.empty` style class when it contains no children.
|
||||
///
|
||||
/// It contains the subnodes `row.header` for its main embedded row,
|
||||
/// `list.nested` for the list it can expand, and `image.expander-row-arrow` for
|
||||
/// its arrow.
|
||||
public struct ExpanderRow: Widget {
|
||||
|
||||
/// Additional update functions for type extensions.
|
||||
var updateFunctions: [(ViewStorage) -> Void] = []
|
||||
/// Additional appear functions for type extensions.
|
||||
var appearFunctions: [(ViewStorage) -> Void] = []
|
||||
|
||||
/// Whether expansion is enabled.
|
||||
var enableExpansion: Binding<Bool>?
|
||||
/// Whether the row is expanded.
|
||||
var expanded: Binding<Bool>?
|
||||
/// The icon name for this row.
|
||||
var iconName: String?
|
||||
/// Whether the switch enabling the expansion is visible.
|
||||
var showEnableSwitch: Bool?
|
||||
/// The subtitle for this row.
|
||||
///
|
||||
/// The subtitle is interpreted as Pango markup unless
|
||||
/// [property@PreferencesRow:use-markup] is set to `FALSE`.
|
||||
var subtitle: String?
|
||||
/// The number of lines at the end of which the subtitle label will be
|
||||
/// ellipsized.
|
||||
///
|
||||
/// If the value is 0, the number of lines won't be limited.
|
||||
var subtitleLines: Int?
|
||||
/// The number of lines at the end of which the title label will be ellipsized.
|
||||
///
|
||||
/// If the value is 0, the number of lines won't be limited.
|
||||
var titleLines: Int?
|
||||
/// The title of the preference represented by this row.
|
||||
///
|
||||
/// The title is interpreted as Pango markup unless
|
||||
/// [property@PreferencesRow:use-markup] is set to `FALSE`.
|
||||
var title: String?
|
||||
/// Whether the user can copy the title from the label.
|
||||
///
|
||||
/// See also [property@Gtk.Label:selectable].
|
||||
var titleSelectable: Bool?
|
||||
/// Whether to use Pango markup for the title label.
|
||||
///
|
||||
/// Subclasses may also use it for other labels, such as subtitle.
|
||||
///
|
||||
/// See also [func@Pango.parse_markup].
|
||||
var useMarkup: Bool?
|
||||
/// Whether an embedded underline in the title indicates a mnemonic.
|
||||
var useUnderline: Bool?
|
||||
/// The body for the widget "rows".
|
||||
var rows: () -> Body = { [] }
|
||||
/// The body for the widget "suffix".
|
||||
var suffix: () -> Body = { [] }
|
||||
/// The body for the widget "prefix".
|
||||
var prefix: () -> Body = { [] }
|
||||
/// The application.
|
||||
var app: GTUIApp?
|
||||
/// The window.
|
||||
var window: GTUIApplicationWindow?
|
||||
|
||||
/// Initialize `ExpanderRow`.
|
||||
public init() {
|
||||
}
|
||||
|
||||
/// Get the widget's view storage.
|
||||
/// - Parameter modifiers: The view modifiers.
|
||||
/// - Returns: The view storage.
|
||||
public func container(modifiers: [(View) -> View]) -> ViewStorage {
|
||||
let storage = ViewStorage(adw_expander_row_new()?.opaque())
|
||||
update(storage, modifiers: modifiers)
|
||||
|
||||
var rowsStorage: [ViewStorage] = []
|
||||
for view in rows() {
|
||||
rowsStorage.append(view.storage(modifiers: modifiers))
|
||||
adw_expander_row_add_row(storage.pointer?.cast(), rowsStorage.last?.pointer?.cast())
|
||||
}
|
||||
storage.content["rows"] = rowsStorage
|
||||
var suffixStorage: [ViewStorage] = []
|
||||
for view in suffix() {
|
||||
suffixStorage.append(view.storage(modifiers: modifiers))
|
||||
adw_expander_row_add_suffix(storage.pointer?.cast(), suffixStorage.last?.pointer?.cast())
|
||||
}
|
||||
storage.content["suffix"] = suffixStorage
|
||||
var prefixStorage: [ViewStorage] = []
|
||||
for view in prefix() {
|
||||
prefixStorage.append(view.storage(modifiers: modifiers))
|
||||
adw_expander_row_add_prefix(storage.pointer?.cast(), prefixStorage.last?.pointer?.cast())
|
||||
}
|
||||
storage.content["prefix"] = prefixStorage
|
||||
|
||||
storage.notify(name: "enable-expansion") {
|
||||
enableExpansion?.wrappedValue = adw_expander_row_get_enable_expansion(storage.pointer?.cast()) != 0
|
||||
}
|
||||
storage.notify(name: "expanded") {
|
||||
expanded?.wrappedValue = adw_expander_row_get_expanded(storage.pointer?.cast()) != 0
|
||||
}
|
||||
for function in appearFunctions {
|
||||
function(storage)
|
||||
}
|
||||
return storage
|
||||
}
|
||||
|
||||
/// Update the widget's view storage.
|
||||
/// - Parameters:
|
||||
/// - storage: The view storage.
|
||||
/// - modifiers: The view modifiers.
|
||||
public func update(_ storage: ViewStorage, modifiers: [(View) -> View]) {
|
||||
storage.modify { widget in
|
||||
if let enableExpansion {
|
||||
adw_expander_row_set_enable_expansion(widget?.cast(), enableExpansion.wrappedValue.cBool)
|
||||
}
|
||||
if let expanded {
|
||||
adw_expander_row_set_expanded(widget?.cast(), expanded.wrappedValue.cBool)
|
||||
}
|
||||
if let iconName {
|
||||
adw_expander_row_set_icon_name(widget?.cast(), iconName)
|
||||
}
|
||||
if let showEnableSwitch {
|
||||
adw_expander_row_set_show_enable_switch(widget?.cast(), showEnableSwitch.cBool)
|
||||
}
|
||||
if let subtitle {
|
||||
adw_expander_row_set_subtitle(widget?.cast(), subtitle)
|
||||
}
|
||||
if let subtitleLines {
|
||||
adw_expander_row_set_subtitle_lines(widget?.cast(), subtitleLines.cInt)
|
||||
}
|
||||
if let titleLines {
|
||||
adw_expander_row_set_title_lines(widget?.cast(), titleLines.cInt)
|
||||
}
|
||||
if let title {
|
||||
adw_preferences_row_set_title(widget?.cast(), title)
|
||||
}
|
||||
if let titleSelectable {
|
||||
adw_preferences_row_set_title_selectable(widget?.cast(), titleSelectable.cBool)
|
||||
}
|
||||
if let useMarkup {
|
||||
adw_preferences_row_set_use_markup(widget?.cast(), useMarkup.cBool)
|
||||
}
|
||||
if let useUnderline {
|
||||
adw_preferences_row_set_use_underline(widget?.cast(), useUnderline.cBool)
|
||||
}
|
||||
|
||||
if let rowsStorage = storage.content["rows"] {
|
||||
for (index, view) in rows().enumerated() {
|
||||
if let storage = rowsStorage[safe: index] {
|
||||
view.updateStorage(storage, modifiers: modifiers)
|
||||
}
|
||||
}
|
||||
}
|
||||
if let suffixStorage = storage.content["suffix"] {
|
||||
for (index, view) in suffix().enumerated() {
|
||||
if let storage = suffixStorage[safe: index] {
|
||||
view.updateStorage(storage, modifiers: modifiers)
|
||||
}
|
||||
}
|
||||
}
|
||||
if let prefixStorage = storage.content["prefix"] {
|
||||
for (index, view) in prefix().enumerated() {
|
||||
if let storage = prefixStorage[safe: index] {
|
||||
view.updateStorage(storage, modifiers: modifiers)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
for function in updateFunctions {
|
||||
function(storage)
|
||||
}
|
||||
}
|
||||
|
||||
/// Whether expansion is enabled.
|
||||
public func enableExpansion(_ enableExpansion: Binding<Bool>?) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.enableExpansion = enableExpansion
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// Whether the row is expanded.
|
||||
public func expanded(_ expanded: Binding<Bool>?) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.expanded = expanded
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// The icon name for this row.
|
||||
public func iconName(_ iconName: String?) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.iconName = iconName
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// Whether the switch enabling the expansion is visible.
|
||||
public func showEnableSwitch(_ showEnableSwitch: Bool? = true) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.showEnableSwitch = showEnableSwitch
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// The subtitle for this row.
|
||||
///
|
||||
/// The subtitle is interpreted as Pango markup unless
|
||||
/// [property@PreferencesRow:use-markup] is set to `FALSE`.
|
||||
public func subtitle(_ subtitle: String?) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.subtitle = subtitle
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// The number of lines at the end of which the subtitle label will be
|
||||
/// ellipsized.
|
||||
///
|
||||
/// If the value is 0, the number of lines won't be limited.
|
||||
public func subtitleLines(_ subtitleLines: Int?) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.subtitleLines = subtitleLines
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// The number of lines at the end of which the title label will be ellipsized.
|
||||
///
|
||||
/// If the value is 0, the number of lines won't be limited.
|
||||
public func titleLines(_ titleLines: Int?) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.titleLines = titleLines
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// The title of the preference represented by this row.
|
||||
///
|
||||
/// The title is interpreted as Pango markup unless
|
||||
/// [property@PreferencesRow:use-markup] is set to `FALSE`.
|
||||
public func title(_ title: String?) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.title = title
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// Whether the user can copy the title from the label.
|
||||
///
|
||||
/// See also [property@Gtk.Label:selectable].
|
||||
public func titleSelectable(_ titleSelectable: Bool? = true) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.titleSelectable = titleSelectable
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// Whether to use Pango markup for the title label.
|
||||
///
|
||||
/// Subclasses may also use it for other labels, such as subtitle.
|
||||
///
|
||||
/// See also [func@Pango.parse_markup].
|
||||
public func useMarkup(_ useMarkup: Bool? = true) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.useMarkup = useMarkup
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// Whether an embedded underline in the title indicates a mnemonic.
|
||||
public func useUnderline(_ useUnderline: Bool? = true) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.useUnderline = useUnderline
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// Set the body for "rows".
|
||||
/// - Parameter body: The body.
|
||||
/// - Returns: The widget.
|
||||
public func rows(@ViewBuilder _ body: @escaping () -> Body) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.rows = body
|
||||
return newSelf
|
||||
}
|
||||
/// Set the body for "suffix".
|
||||
/// - Parameter body: The body.
|
||||
/// - Returns: The widget.
|
||||
public func suffix(@ViewBuilder _ body: @escaping () -> Body) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.suffix = body
|
||||
return newSelf
|
||||
}
|
||||
/// Set the body for "prefix".
|
||||
/// - Parameter body: The body.
|
||||
/// - Returns: The widget.
|
||||
public func prefix(@ViewBuilder _ body: @escaping () -> Body) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.prefix = body
|
||||
return newSelf
|
||||
}
|
||||
}
|
331
Sources/Adwaita/View/Generated/HeaderBar.swift
Normal file
331
Sources/Adwaita/View/Generated/HeaderBar.swift
Normal file
@ -0,0 +1,331 @@
|
||||
//
|
||||
// HeaderBar.swift
|
||||
// Adwaita
|
||||
//
|
||||
// Created by auto-generation on 22.01.24.
|
||||
//
|
||||
|
||||
import CAdw
|
||||
import LevenshteinTransformations
|
||||
|
||||
/// A title bar widget.
|
||||
///
|
||||
/// <picture><source srcset="header-bar-dark.png" media="(prefers-color-scheme: dark)"><img src="header-bar.png" alt="header-bar"></picture>
|
||||
///
|
||||
/// `AdwHeaderBar` is similar to [class@Gtk.HeaderBar], but provides additional
|
||||
/// features compared to it. Refer to `GtkHeaderBar` for details. It is typically
|
||||
/// used as a top bar within [class@ToolbarView].
|
||||
///
|
||||
/// ## Navigation View Integration
|
||||
///
|
||||
/// When placed inside an [class@NavigationPage], `AdwHeaderBar` will display the
|
||||
/// page title instead of window title.
|
||||
///
|
||||
/// When used together with [class@NavigationView] or [class@NavigationSplitView],
|
||||
/// it will also display a back button that can be used to go back to the previous
|
||||
/// page. The button also has a context menu, allowing to pop multiple pages at
|
||||
/// once, potentially across multiple navigation views. In rare scenarios, set
|
||||
/// [property@HeaderBar:show-back-button] to `FALSE` to disable the back button
|
||||
/// if it's unwanted (e.g. in an extra header bar on the same page).
|
||||
///
|
||||
/// ## Split View Integration
|
||||
///
|
||||
/// When placed inside `AdwNavigationSplitView` or `AdwOverlaySplitView`,
|
||||
/// `AdwHeaderBar` will automatically hide the title buttons other than at the
|
||||
/// edges of the window.
|
||||
///
|
||||
/// ## Centering Policy
|
||||
///
|
||||
/// [property@HeaderBar:centering-policy] allows to enforce strict centering of
|
||||
/// the title widget. This can be useful for entries inside [class@Clamp].
|
||||
///
|
||||
/// ## Title Buttons
|
||||
///
|
||||
/// Unlike `GtkHeaderBar`, `AdwHeaderBar` allows to toggle title button
|
||||
/// visibility for each side individually, using the
|
||||
/// [property@HeaderBar:show-start-title-buttons] and
|
||||
/// [property@HeaderBar:show-end-title-buttons] properties.
|
||||
///
|
||||
/// ## CSS nodes
|
||||
///
|
||||
/// ```
|
||||
/// headerbar
|
||||
/// ╰── windowhandle
|
||||
/// ╰── box
|
||||
/// ├── widget
|
||||
/// │ ╰── box.start
|
||||
/// │ ├── windowcontrols.start
|
||||
/// │ ├── widget
|
||||
/// │ │ ╰── [button.back]
|
||||
/// │ ╰── [other children]
|
||||
/// ├── widget
|
||||
/// │ ╰── [Title Widget]
|
||||
/// ╰── widget
|
||||
/// ╰── box.end
|
||||
/// ├── [other children]
|
||||
/// ╰── windowcontrols.end
|
||||
/// ```
|
||||
///
|
||||
/// `AdwHeaderBar`'s CSS node is called `headerbar`. It contains a `windowhandle`
|
||||
/// subnode, which contains a `box` subnode, which contains three `widget`
|
||||
/// subnodes at the start, center and end of the header bar. The start and end
|
||||
/// subnotes contain a `box` subnode with the `.start` and `.end` style classes
|
||||
/// respectively, and the center node contains a node that represents the title.
|
||||
///
|
||||
/// Each of the boxes contains a `windowcontrols` subnode, see
|
||||
/// [class@Gtk.WindowControls] for details, as well as other children.
|
||||
///
|
||||
/// When [property@HeaderBar:show-back-button] is `TRUE`, the start box also
|
||||
/// contains a node with the name `widget` that contains a node with the name
|
||||
/// `button` and `.back` style class.
|
||||
///
|
||||
/// ## Accessibility
|
||||
///
|
||||
/// `AdwHeaderBar` uses the `GTK_ACCESSIBLE_ROLE_GROUP` role.
|
||||
public struct HeaderBar: Widget {
|
||||
|
||||
/// Additional update functions for type extensions.
|
||||
var updateFunctions: [(ViewStorage) -> Void] = []
|
||||
/// Additional appear functions for type extensions.
|
||||
var appearFunctions: [(ViewStorage) -> Void] = []
|
||||
|
||||
/// The decoration layout for buttons.
|
||||
///
|
||||
/// If this property is not set, the
|
||||
/// [property@Gtk.Settings:gtk-decoration-layout] setting is used.
|
||||
///
|
||||
/// The format of the string is button names, separated by commas. A colon
|
||||
/// separates the buttons that should appear at the start from those at the
|
||||
/// end. Recognized button names are minimize, maximize, close and icon (the
|
||||
/// window icon).
|
||||
///
|
||||
/// For example, “icon:minimize,maximize,close” specifies an icon at the start,
|
||||
/// and minimize, maximize and close buttons at the end.
|
||||
var decorationLayout: String?
|
||||
/// Whether the header bar can show the back button.
|
||||
///
|
||||
/// The back button will never be shown unless the header bar is placed inside an
|
||||
/// [class@NavigationView]. Usually, there is no reason to set this to `FALSE`.
|
||||
var showBackButton: Bool?
|
||||
/// Whether to show title buttons at the end of the header bar.
|
||||
///
|
||||
/// See [property@HeaderBar:show-start-title-buttons] for the other side.
|
||||
///
|
||||
/// Which buttons are actually shown and where is determined by the
|
||||
/// [property@HeaderBar:decoration-layout] property, and by the state of the
|
||||
/// window (e.g. a close button will not be shown if the window can't be
|
||||
/// closed).
|
||||
var showEndTitleButtons: Bool?
|
||||
/// Whether to show title buttons at the start of the header bar.
|
||||
///
|
||||
/// See [property@HeaderBar:show-end-title-buttons] for the other side.
|
||||
///
|
||||
/// Which buttons are actually shown and where is determined by the
|
||||
/// [property@HeaderBar:decoration-layout] property, and by the state of the
|
||||
/// window (e.g. a close button will not be shown if the window can't be
|
||||
/// closed).
|
||||
var showStartTitleButtons: Bool?
|
||||
/// Whether the title widget should be shown.
|
||||
var showTitle: Bool?
|
||||
/// The title widget to display.
|
||||
///
|
||||
/// When set to `NULL`, the header bar will display the title of the window it
|
||||
/// is contained in.
|
||||
///
|
||||
/// To use a different title, use [class@WindowTitle]:
|
||||
///
|
||||
/// ```xml
|
||||
/// <object class="AdwHeaderBar"><property name="title-widget"><object class="AdwWindowTitle"><property name="title" translatable="yes">Title</property></object></property></object>
|
||||
/// ```
|
||||
var titleWidget: (() -> Body)?
|
||||
/// The body for the widget "start".
|
||||
var start: () -> Body = { [] }
|
||||
/// The body for the widget "end".
|
||||
var end: () -> Body = { [] }
|
||||
/// The application.
|
||||
var app: GTUIApp?
|
||||
/// The window.
|
||||
var window: GTUIApplicationWindow?
|
||||
|
||||
/// Initialize `HeaderBar`.
|
||||
public init() {
|
||||
}
|
||||
|
||||
/// Get the widget's view storage.
|
||||
/// - Parameter modifiers: The view modifiers.
|
||||
/// - Returns: The view storage.
|
||||
public func container(modifiers: [(View) -> View]) -> ViewStorage {
|
||||
let storage = ViewStorage(adw_header_bar_new()?.opaque())
|
||||
update(storage, modifiers: modifiers)
|
||||
if let titleWidgetStorage = titleWidget?().widget(modifiers: modifiers).storage(modifiers: modifiers) {
|
||||
storage.content["titleWidget"] = [titleWidgetStorage]
|
||||
adw_header_bar_set_title_widget(storage.pointer, titleWidgetStorage.pointer?.cast())
|
||||
}
|
||||
|
||||
var startStorage: [ViewStorage] = []
|
||||
for view in start() {
|
||||
startStorage.append(view.storage(modifiers: modifiers))
|
||||
adw_header_bar_pack_start(storage.pointer, startStorage.last?.pointer?.cast())
|
||||
}
|
||||
storage.content["start"] = startStorage
|
||||
var endStorage: [ViewStorage] = []
|
||||
for view in end() {
|
||||
endStorage.append(view.storage(modifiers: modifiers))
|
||||
adw_header_bar_pack_end(storage.pointer, endStorage.last?.pointer?.cast())
|
||||
}
|
||||
storage.content["end"] = endStorage
|
||||
|
||||
for function in appearFunctions {
|
||||
function(storage)
|
||||
}
|
||||
return storage
|
||||
}
|
||||
|
||||
/// Update the widget's view storage.
|
||||
/// - Parameters:
|
||||
/// - storage: The view storage.
|
||||
/// - modifiers: The view modifiers.
|
||||
public func update(_ storage: ViewStorage, modifiers: [(View) -> View]) {
|
||||
storage.modify { widget in
|
||||
if let decorationLayout {
|
||||
adw_header_bar_set_decoration_layout(widget, decorationLayout)
|
||||
}
|
||||
if let showBackButton {
|
||||
adw_header_bar_set_show_back_button(widget, showBackButton.cBool)
|
||||
}
|
||||
if let showEndTitleButtons {
|
||||
adw_header_bar_set_show_end_title_buttons(widget, showEndTitleButtons.cBool)
|
||||
}
|
||||
if let showStartTitleButtons {
|
||||
adw_header_bar_set_show_start_title_buttons(widget, showStartTitleButtons.cBool)
|
||||
}
|
||||
if let showTitle {
|
||||
adw_header_bar_set_show_title(widget, showTitle.cBool)
|
||||
}
|
||||
if let widget = storage.content["titleWidget"]?.first {
|
||||
titleWidget?().widget(modifiers: modifiers).update(widget, modifiers: modifiers)
|
||||
}
|
||||
|
||||
if let startStorage = storage.content["start"] {
|
||||
for (index, view) in start().enumerated() {
|
||||
if let storage = startStorage[safe: index] {
|
||||
view.updateStorage(storage, modifiers: modifiers)
|
||||
}
|
||||
}
|
||||
}
|
||||
if let endStorage = storage.content["end"] {
|
||||
for (index, view) in end().enumerated() {
|
||||
if let storage = endStorage[safe: index] {
|
||||
view.updateStorage(storage, modifiers: modifiers)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
for function in updateFunctions {
|
||||
function(storage)
|
||||
}
|
||||
}
|
||||
|
||||
/// The decoration layout for buttons.
|
||||
///
|
||||
/// If this property is not set, the
|
||||
/// [property@Gtk.Settings:gtk-decoration-layout] setting is used.
|
||||
///
|
||||
/// The format of the string is button names, separated by commas. A colon
|
||||
/// separates the buttons that should appear at the start from those at the
|
||||
/// end. Recognized button names are minimize, maximize, close and icon (the
|
||||
/// window icon).
|
||||
///
|
||||
/// For example, “icon:minimize,maximize,close” specifies an icon at the start,
|
||||
/// and minimize, maximize and close buttons at the end.
|
||||
public func decorationLayout(_ decorationLayout: String?) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.decorationLayout = decorationLayout
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// Whether the header bar can show the back button.
|
||||
///
|
||||
/// The back button will never be shown unless the header bar is placed inside an
|
||||
/// [class@NavigationView]. Usually, there is no reason to set this to `FALSE`.
|
||||
public func showBackButton(_ showBackButton: Bool? = true) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.showBackButton = showBackButton
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// Whether to show title buttons at the end of the header bar.
|
||||
///
|
||||
/// See [property@HeaderBar:show-start-title-buttons] for the other side.
|
||||
///
|
||||
/// Which buttons are actually shown and where is determined by the
|
||||
/// [property@HeaderBar:decoration-layout] property, and by the state of the
|
||||
/// window (e.g. a close button will not be shown if the window can't be
|
||||
/// closed).
|
||||
public func showEndTitleButtons(_ showEndTitleButtons: Bool? = true) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.showEndTitleButtons = showEndTitleButtons
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// Whether to show title buttons at the start of the header bar.
|
||||
///
|
||||
/// See [property@HeaderBar:show-end-title-buttons] for the other side.
|
||||
///
|
||||
/// Which buttons are actually shown and where is determined by the
|
||||
/// [property@HeaderBar:decoration-layout] property, and by the state of the
|
||||
/// window (e.g. a close button will not be shown if the window can't be
|
||||
/// closed).
|
||||
public func showStartTitleButtons(_ showStartTitleButtons: Bool? = true) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.showStartTitleButtons = showStartTitleButtons
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// Whether the title widget should be shown.
|
||||
public func showTitle(_ showTitle: Bool? = true) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.showTitle = showTitle
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// The title widget to display.
|
||||
///
|
||||
/// When set to `NULL`, the header bar will display the title of the window it
|
||||
/// is contained in.
|
||||
///
|
||||
/// To use a different title, use [class@WindowTitle]:
|
||||
///
|
||||
/// ```xml
|
||||
/// <object class="AdwHeaderBar"><property name="title-widget"><object class="AdwWindowTitle"><property name="title" translatable="yes">Title</property></object></property></object>
|
||||
/// ```
|
||||
public func titleWidget(@ViewBuilder _ titleWidget: @escaping (() -> Body)) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.titleWidget = titleWidget
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// Set the body for "start".
|
||||
/// - Parameter body: The body.
|
||||
/// - Returns: The widget.
|
||||
public func start(@ViewBuilder _ body: @escaping () -> Body) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.start = body
|
||||
return newSelf
|
||||
}
|
||||
/// Set the body for "end".
|
||||
/// - Parameter body: The body.
|
||||
/// - Returns: The widget.
|
||||
public func end(@ViewBuilder _ body: @escaping () -> Body) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.end = body
|
||||
return newSelf
|
||||
}
|
||||
}
|
502
Sources/Adwaita/View/Generated/Label.swift
Normal file
502
Sources/Adwaita/View/Generated/Label.swift
Normal file
@ -0,0 +1,502 @@
|
||||
//
|
||||
// Label.swift
|
||||
// Adwaita
|
||||
//
|
||||
// Created by auto-generation on 22.01.24.
|
||||
//
|
||||
|
||||
import CAdw
|
||||
import LevenshteinTransformations
|
||||
|
||||
/// The `GtkLabel` widget displays a small amount of text.
|
||||
///
|
||||
/// As the name implies, most labels are used to label another widget
|
||||
/// such as a [class@Button].
|
||||
///
|
||||
/// ![An example GtkLabel](label.png)
|
||||
///
|
||||
/// # CSS nodes
|
||||
///
|
||||
/// ```
|
||||
/// label
|
||||
/// ├── [selection]
|
||||
/// ├── [link]
|
||||
/// ┊
|
||||
/// ╰── [link]
|
||||
/// ```
|
||||
///
|
||||
/// `GtkLabel` has a single CSS node with the name label. A wide variety
|
||||
/// of style classes may be applied to labels, such as .title, .subtitle,
|
||||
/// .dim-label, etc. In the `GtkShortcutsWindow`, labels are used with the
|
||||
/// .keycap style class.
|
||||
///
|
||||
/// If the label has a selection, it gets a subnode with name selection.
|
||||
///
|
||||
/// If the label has links, there is one subnode per link. These subnodes
|
||||
/// carry the link or visited state depending on whether they have been
|
||||
/// visited. In this case, label node also gets a .link style class.
|
||||
///
|
||||
/// # GtkLabel as GtkBuildable
|
||||
///
|
||||
/// The GtkLabel implementation of the GtkBuildable interface supports a
|
||||
/// custom `<attributes>` element, which supports any number of `<attribute>`
|
||||
/// elements. The <attribute> element has attributes named “name“, “value“,
|
||||
/// “start“ and “end“ and allows you to specify [struct@Pango.Attribute]
|
||||
/// values for this label.
|
||||
///
|
||||
/// An example of a UI definition fragment specifying Pango attributes:
|
||||
/// ```xml
|
||||
/// <object class="GtkLabel"><attributes><attribute name="weight" value="PANGO_WEIGHT_BOLD"/><attribute name="background" value="red" start="5" end="10"/></attributes></object>
|
||||
/// ```
|
||||
///
|
||||
/// The start and end attributes specify the range of characters to which the
|
||||
/// Pango attribute applies. If start and end are not specified, the attribute is
|
||||
/// applied to the whole text. Note that specifying ranges does not make much
|
||||
/// sense with translatable attributes. Use markup embedded in the translatable
|
||||
/// content instead.
|
||||
///
|
||||
/// # Accessibility
|
||||
///
|
||||
/// `GtkLabel` uses the %GTK_ACCESSIBLE_ROLE_LABEL role.
|
||||
///
|
||||
/// # Mnemonics
|
||||
///
|
||||
/// Labels may contain “mnemonics”. Mnemonics are underlined characters in the
|
||||
/// label, used for keyboard navigation. Mnemonics are created by providing a
|
||||
/// string with an underscore before the mnemonic character, such as `"_File"`,
|
||||
/// to the functions [ctor@Gtk.Label.new_with_mnemonic] or
|
||||
/// [method@Gtk.Label.set_text_with_mnemonic].
|
||||
///
|
||||
/// Mnemonics automatically activate any activatable widget the label is
|
||||
/// inside, such as a [class@Gtk.Button]; if the label is not inside the
|
||||
/// mnemonic’s target widget, you have to tell the label about the target
|
||||
/// using [class@Gtk.Label.set_mnemonic_widget]. Here’s a simple example where
|
||||
/// the label is inside a button:
|
||||
///
|
||||
/// ```c
|
||||
/// // Pressing Alt+H will activate this button
|
||||
/// GtkWidget *button = gtk_button_new ();
|
||||
/// GtkWidget *label = gtk_label_new_with_mnemonic ("_Hello");
|
||||
/// gtk_button_set_child (GTK_BUTTON (button), label);
|
||||
/// ```
|
||||
///
|
||||
/// There’s a convenience function to create buttons with a mnemonic label
|
||||
/// already inside:
|
||||
///
|
||||
/// ```c
|
||||
/// // Pressing Alt+H will activate this button
|
||||
/// GtkWidget *button = gtk_button_new_with_mnemonic ("_Hello");
|
||||
/// ```
|
||||
///
|
||||
/// To create a mnemonic for a widget alongside the label, such as a
|
||||
/// [class@Gtk.Entry], you have to point the label at the entry with
|
||||
/// [method@Gtk.Label.set_mnemonic_widget]:
|
||||
///
|
||||
/// ```c
|
||||
/// // Pressing Alt+H will focus the entry
|
||||
/// GtkWidget *entry = gtk_entry_new ();
|
||||
/// GtkWidget *label = gtk_label_new_with_mnemonic ("_Hello");
|
||||
/// gtk_label_set_mnemonic_widget (GTK_LABEL (label), entry);
|
||||
/// ```
|
||||
///
|
||||
/// # Markup (styled text)
|
||||
///
|
||||
/// To make it easy to format text in a label (changing colors,
|
||||
/// fonts, etc.), label text can be provided in a simple
|
||||
/// markup format:
|
||||
///
|
||||
/// Here’s how to create a label with a small font:
|
||||
/// ```c
|
||||
/// GtkWidget *label = gtk_label_new (NULL);
|
||||
/// gtk_label_set_markup (GTK_LABEL (label), "<small>Small text</small>");
|
||||
/// ```
|
||||
///
|
||||
/// (See the Pango manual for complete documentation] of available
|
||||
/// tags, [func@Pango.parse_markup])
|
||||
///
|
||||
/// The markup passed to [method@Gtk.Label.set_markup] must be valid; for example,
|
||||
/// literal `<`, `>` and `&` characters must be escaped as `<`, `>`, and `&`.
|
||||
/// If you pass text obtained from the user, file, or a network to
|
||||
/// [method@Gtk.Label.set_markup], you’ll want to escape it with
|
||||
/// [func@GLib.markup_escape_text] or [func@GLib.markup_printf_escaped].
|
||||
///
|
||||
/// Markup strings are just a convenient way to set the [struct@Pango.AttrList]
|
||||
/// on a label; [method@Gtk.Label.set_attributes] may be a simpler way to set
|
||||
/// attributes in some cases. Be careful though; [struct@Pango.AttrList] tends
|
||||
/// to cause internationalization problems, unless you’re applying attributes
|
||||
/// to the entire string (i.e. unless you set the range of each attribute
|
||||
/// to [0, %G_MAXINT)). The reason is that specifying the start_index and
|
||||
/// end_index for a [struct@Pango.Attribute] requires knowledge of the exact
|
||||
/// string being displayed, so translations will cause problems.
|
||||
///
|
||||
/// # Selectable labels
|
||||
///
|
||||
/// Labels can be made selectable with [method@Gtk.Label.set_selectable].
|
||||
/// Selectable labels allow the user to copy the label contents to
|
||||
/// the clipboard. Only labels that contain useful-to-copy information
|
||||
/// — such as error messages — should be made selectable.
|
||||
///
|
||||
/// # Text layout
|
||||
///
|
||||
/// A label can contain any number of paragraphs, but will have
|
||||
/// performance problems if it contains more than a small number.
|
||||
/// Paragraphs are separated by newlines or other paragraph separators
|
||||
/// understood by Pango.
|
||||
///
|
||||
/// Labels can automatically wrap text if you call [method@Gtk.Label.set_wrap].
|
||||
///
|
||||
/// [method@Gtk.Label.set_justify] sets how the lines in a label align
|
||||
/// with one another. If you want to set how the label as a whole aligns
|
||||
/// in its available space, see the [property@Gtk.Widget:halign] and
|
||||
/// [property@Gtk.Widget:valign] properties.
|
||||
///
|
||||
/// The [property@Gtk.Label:width-chars] and [property@Gtk.Label:max-width-chars]
|
||||
/// properties can be used to control the size allocation of ellipsized or
|
||||
/// wrapped labels. For ellipsizing labels, if either is specified (and less
|
||||
/// than the actual text size), it is used as the minimum width, and the actual
|
||||
/// text size is used as the natural width of the label. For wrapping labels,
|
||||
/// width-chars is used as the minimum width, if specified, and max-width-chars
|
||||
/// is used as the natural width. Even if max-width-chars specified, wrapping
|
||||
/// labels will be rewrapped to use all of the available width.
|
||||
///
|
||||
/// # Links
|
||||
///
|
||||
/// GTK supports markup for clickable hyperlinks in addition to regular Pango
|
||||
/// markup. The markup for links is borrowed from HTML, using the `<a>` with
|
||||
/// “href“, “title“ and “class“ attributes. GTK renders links similar to the
|
||||
/// way they appear in web browsers, with colored, underlined text. The “title“
|
||||
/// attribute is displayed as a tooltip on the link. The “class“ attribute is
|
||||
/// used as style class on the CSS node for the link.
|
||||
///
|
||||
/// An example looks like this:
|
||||
///
|
||||
/// ```c
|
||||
/// const char *text =
|
||||
/// "Go to the "
|
||||
/// "<a href=\"https://www.gtk.org\" title=\"<i>Our</i> website\">"
|
||||
/// "GTK website</a> for more...";
|
||||
/// GtkWidget *label = gtk_label_new (NULL);
|
||||
/// gtk_label_set_markup (GTK_LABEL (label), text);
|
||||
/// ```
|
||||
///
|
||||
/// It is possible to implement custom handling for links and their tooltips
|
||||
/// with the [signal@Gtk.Label::activate-link] signal and the
|
||||
/// [method@Gtk.Label.get_current_uri] function.
|
||||
public struct Label: Widget {
|
||||
|
||||
/// Additional update functions for type extensions.
|
||||
var updateFunctions: [(ViewStorage) -> Void] = []
|
||||
/// Additional appear functions for type extensions.
|
||||
var appearFunctions: [(ViewStorage) -> Void] = []
|
||||
|
||||
/// The contents of the label.
|
||||
///
|
||||
/// If the string contains Pango markup (see [func@Pango.parse_markup]),
|
||||
/// you will have to set the [property@Gtk.Label:use-markup] property to
|
||||
/// %TRUE in order for the label to display the markup attributes. See also
|
||||
/// [method@Gtk.Label.set_markup] for a convenience function that sets both
|
||||
/// this property and the [property@Gtk.Label:use-markup] property at the
|
||||
/// same time.
|
||||
///
|
||||
/// If the string contains underlines acting as mnemonics, you will have to
|
||||
/// set the [property@Gtk.Label:use-underline] property to %TRUE in order
|
||||
/// for the label to display them.
|
||||
var label: String
|
||||
/// The number of lines to which an ellipsized, wrapping label
|
||||
/// should be limited.
|
||||
///
|
||||
/// This property has no effect if the label is not wrapping or ellipsized.
|
||||
/// Set this property to -1 if you don't want to limit the number of lines.
|
||||
var lines: Int?
|
||||
/// The desired maximum width of the label, in characters.
|
||||
///
|
||||
/// If this property is set to -1, the width will be calculated automatically.
|
||||
///
|
||||
/// See the section on [text layout](class.Label.html#text-layout) for details of how
|
||||
/// [property@Gtk.Label:width-chars] and [property@Gtk.Label:max-width-chars]
|
||||
/// determine the width of ellipsized and wrapped labels.
|
||||
var maxWidthChars: Int?
|
||||
/// The mnemonic accelerator key for the label.
|
||||
var mnemonicKeyval: UInt?
|
||||
/// The widget to be activated when the labels mnemonic key is pressed.
|
||||
var mnemonicWidget: (() -> Body)?
|
||||
/// Whether the label text can be selected with the mouse.
|
||||
var selectable: Bool?
|
||||
/// Whether the label is in single line mode.
|
||||
///
|
||||
/// In single line mode, the height of the label does not depend on the
|
||||
/// actual text, it is always set to ascent + descent of the font. This
|
||||
/// can be an advantage in situations where resizing the label because
|
||||
/// of text changes would be distracting, e.g. in a statusbar.
|
||||
var singleLineMode: Bool?
|
||||
/// %TRUE if the text of the label includes Pango markup.
|
||||
///
|
||||
/// See [func@Pango.parse_markup].
|
||||
var useMarkup: Bool?
|
||||
/// %TRUE if the text of the label indicates a mnemonic with an _
|
||||
/// before the mnemonic character.
|
||||
var useUnderline: Bool?
|
||||
/// The desired width of the label, in characters.
|
||||
///
|
||||
/// If this property is set to -1, the width will be calculated automatically.
|
||||
///
|
||||
/// See the section on [text layout](class.Label.html#text-layout) for details of how
|
||||
/// [property@Gtk.Label:width-chars] and [property@Gtk.Label:max-width-chars]
|
||||
/// determine the width of ellipsized and wrapped labels.
|
||||
var widthChars: Int?
|
||||
/// %TRUE if the label text will wrap if it gets too wide.
|
||||
var wrap: Bool?
|
||||
/// The horizontal alignment of the label text inside its size allocation.
|
||||
///
|
||||
/// Compare this to [property@Gtk.Widget:halign], which determines how the
|
||||
/// labels size allocation is positioned in the space available for the label.
|
||||
var xalign: Float?
|
||||
/// The vertical alignment of the label text inside its size allocation.
|
||||
///
|
||||
/// Compare this to [property@Gtk.Widget:valign], which determines how the
|
||||
/// labels size allocation is positioned in the space available for the label.
|
||||
var yalign: Float?
|
||||
/// Gets emitted to copy the selection to the clipboard.
|
||||
///
|
||||
/// The ::copy-clipboard signal is a [keybinding signal](class.SignalAction.html).
|
||||
///
|
||||
/// The default binding for this signal is <kbd>Ctrl</kbd>+<kbd>c</kbd>.
|
||||
var copyClipboard: (() -> Void)?
|
||||
/// The application.
|
||||
var app: GTUIApp?
|
||||
/// The window.
|
||||
var window: GTUIApplicationWindow?
|
||||
|
||||
/// Initialize `Label`.
|
||||
public init(label: String) {
|
||||
self.label = label
|
||||
}
|
||||
|
||||
/// Get the widget's view storage.
|
||||
/// - Parameter modifiers: The view modifiers.
|
||||
/// - Returns: The view storage.
|
||||
public func container(modifiers: [(View) -> View]) -> ViewStorage {
|
||||
let storage = ViewStorage(gtk_label_new(label)?.opaque())
|
||||
update(storage, modifiers: modifiers)
|
||||
if let mnemonicWidgetStorage = mnemonicWidget?().widget(modifiers: modifiers).storage(modifiers: modifiers) {
|
||||
storage.content["mnemonicWidget"] = [mnemonicWidgetStorage]
|
||||
gtk_label_set_mnemonic_widget(storage.pointer, mnemonicWidgetStorage.pointer?.cast())
|
||||
}
|
||||
|
||||
|
||||
for function in appearFunctions {
|
||||
function(storage)
|
||||
}
|
||||
return storage
|
||||
}
|
||||
|
||||
/// Update the widget's view storage.
|
||||
/// - Parameters:
|
||||
/// - storage: The view storage.
|
||||
/// - modifiers: The view modifiers.
|
||||
public func update(_ storage: ViewStorage, modifiers: [(View) -> View]) {
|
||||
if let copyClipboard {
|
||||
storage.connectSignal(name: "copy-clipboard") {
|
||||
copyClipboard()
|
||||
}
|
||||
}
|
||||
storage.modify { widget in
|
||||
gtk_label_set_label(widget, label)
|
||||
if let lines {
|
||||
gtk_label_set_lines(widget, lines.cInt)
|
||||
}
|
||||
if let maxWidthChars {
|
||||
gtk_label_set_max_width_chars(widget, maxWidthChars.cInt)
|
||||
}
|
||||
if let widget = storage.content["mnemonicWidget"]?.first {
|
||||
mnemonicWidget?().widget(modifiers: modifiers).update(widget, modifiers: modifiers)
|
||||
}
|
||||
if let selectable {
|
||||
gtk_label_set_selectable(widget, selectable.cBool)
|
||||
}
|
||||
if let singleLineMode {
|
||||
gtk_label_set_single_line_mode(widget, singleLineMode.cBool)
|
||||
}
|
||||
if let useMarkup {
|
||||
gtk_label_set_use_markup(widget, useMarkup.cBool)
|
||||
}
|
||||
if let useUnderline {
|
||||
gtk_label_set_use_underline(widget, useUnderline.cBool)
|
||||
}
|
||||
if let widthChars {
|
||||
gtk_label_set_width_chars(widget, widthChars.cInt)
|
||||
}
|
||||
if let wrap {
|
||||
gtk_label_set_wrap(widget, wrap.cBool)
|
||||
}
|
||||
if let xalign {
|
||||
gtk_label_set_xalign(widget, xalign)
|
||||
}
|
||||
if let yalign {
|
||||
gtk_label_set_yalign(widget, yalign)
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
for function in updateFunctions {
|
||||
function(storage)
|
||||
}
|
||||
}
|
||||
|
||||
/// The contents of the label.
|
||||
///
|
||||
/// If the string contains Pango markup (see [func@Pango.parse_markup]),
|
||||
/// you will have to set the [property@Gtk.Label:use-markup] property to
|
||||
/// %TRUE in order for the label to display the markup attributes. See also
|
||||
/// [method@Gtk.Label.set_markup] for a convenience function that sets both
|
||||
/// this property and the [property@Gtk.Label:use-markup] property at the
|
||||
/// same time.
|
||||
///
|
||||
/// If the string contains underlines acting as mnemonics, you will have to
|
||||
/// set the [property@Gtk.Label:use-underline] property to %TRUE in order
|
||||
/// for the label to display them.
|
||||
public func label(_ label: String) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.label = label
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// The number of lines to which an ellipsized, wrapping label
|
||||
/// should be limited.
|
||||
///
|
||||
/// This property has no effect if the label is not wrapping or ellipsized.
|
||||
/// Set this property to -1 if you don't want to limit the number of lines.
|
||||
public func lines(_ lines: Int?) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.lines = lines
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// The desired maximum width of the label, in characters.
|
||||
///
|
||||
/// If this property is set to -1, the width will be calculated automatically.
|
||||
///
|
||||
/// See the section on [text layout](class.Label.html#text-layout) for details of how
|
||||
/// [property@Gtk.Label:width-chars] and [property@Gtk.Label:max-width-chars]
|
||||
/// determine the width of ellipsized and wrapped labels.
|
||||
public func maxWidthChars(_ maxWidthChars: Int?) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.maxWidthChars = maxWidthChars
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// The mnemonic accelerator key for the label.
|
||||
public func mnemonicKeyval(_ mnemonicKeyval: UInt?) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.mnemonicKeyval = mnemonicKeyval
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// The widget to be activated when the labels mnemonic key is pressed.
|
||||
public func mnemonicWidget(@ViewBuilder _ mnemonicWidget: @escaping (() -> Body)) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.mnemonicWidget = mnemonicWidget
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// Whether the label text can be selected with the mouse.
|
||||
public func selectable(_ selectable: Bool? = true) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.selectable = selectable
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// Whether the label is in single line mode.
|
||||
///
|
||||
/// In single line mode, the height of the label does not depend on the
|
||||
/// actual text, it is always set to ascent + descent of the font. This
|
||||
/// can be an advantage in situations where resizing the label because
|
||||
/// of text changes would be distracting, e.g. in a statusbar.
|
||||
public func singleLineMode(_ singleLineMode: Bool? = true) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.singleLineMode = singleLineMode
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// %TRUE if the text of the label includes Pango markup.
|
||||
///
|
||||
/// See [func@Pango.parse_markup].
|
||||
public func useMarkup(_ useMarkup: Bool? = true) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.useMarkup = useMarkup
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// %TRUE if the text of the label indicates a mnemonic with an _
|
||||
/// before the mnemonic character.
|
||||
public func useUnderline(_ useUnderline: Bool? = true) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.useUnderline = useUnderline
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// The desired width of the label, in characters.
|
||||
///
|
||||
/// If this property is set to -1, the width will be calculated automatically.
|
||||
///
|
||||
/// See the section on [text layout](class.Label.html#text-layout) for details of how
|
||||
/// [property@Gtk.Label:width-chars] and [property@Gtk.Label:max-width-chars]
|
||||
/// determine the width of ellipsized and wrapped labels.
|
||||
public func widthChars(_ widthChars: Int?) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.widthChars = widthChars
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// %TRUE if the label text will wrap if it gets too wide.
|
||||
public func wrap(_ wrap: Bool? = true) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.wrap = wrap
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// The horizontal alignment of the label text inside its size allocation.
|
||||
///
|
||||
/// Compare this to [property@Gtk.Widget:halign], which determines how the
|
||||
/// labels size allocation is positioned in the space available for the label.
|
||||
public func xalign(_ xalign: Float?) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.xalign = xalign
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// The vertical alignment of the label text inside its size allocation.
|
||||
///
|
||||
/// Compare this to [property@Gtk.Widget:valign], which determines how the
|
||||
/// labels size allocation is positioned in the space available for the label.
|
||||
public func yalign(_ yalign: Float?) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.yalign = yalign
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// Gets emitted to copy the selection to the clipboard.
|
||||
///
|
||||
/// The ::copy-clipboard signal is a [keybinding signal](class.SignalAction.html).
|
||||
///
|
||||
/// The default binding for this signal is <kbd>Ctrl</kbd>+<kbd>c</kbd>.
|
||||
public func copyClipboard(_ copyClipboard: @escaping () -> Void) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.copyClipboard = copyClipboard
|
||||
return newSelf
|
||||
}
|
||||
|
||||
}
|
238
Sources/Adwaita/View/Generated/LevelBar.swift
Normal file
238
Sources/Adwaita/View/Generated/LevelBar.swift
Normal file
@ -0,0 +1,238 @@
|
||||
//
|
||||
// LevelBar.swift
|
||||
// Adwaita
|
||||
//
|
||||
// Created by auto-generation on 22.01.24.
|
||||
//
|
||||
|
||||
import CAdw
|
||||
import LevenshteinTransformations
|
||||
|
||||
/// `GtkLevelBar` is a widget that can be used as a level indicator.
|
||||
///
|
||||
/// Typical use cases are displaying the strength of a password, or
|
||||
/// showing the charge level of a battery.
|
||||
///
|
||||
/// ![An example GtkLevelBar](levelbar.png)
|
||||
///
|
||||
/// Use [method@Gtk.LevelBar.set_value] to set the current value, and
|
||||
/// [method@Gtk.LevelBar.add_offset_value] to set the value offsets at which
|
||||
/// the bar will be considered in a different state. GTK will add a few
|
||||
/// offsets by default on the level bar: %GTK_LEVEL_BAR_OFFSET_LOW,
|
||||
/// %GTK_LEVEL_BAR_OFFSET_HIGH and %GTK_LEVEL_BAR_OFFSET_FULL, with
|
||||
/// values 0.25, 0.75 and 1.0 respectively.
|
||||
///
|
||||
/// Note that it is your responsibility to update preexisting offsets
|
||||
/// when changing the minimum or maximum value. GTK will simply clamp
|
||||
/// them to the new range.
|
||||
///
|
||||
/// ## Adding a custom offset on the bar
|
||||
///
|
||||
/// ```c
|
||||
/// static GtkWidget *
|
||||
/// create_level_bar (void)
|
||||
/// {
|
||||
/// GtkWidget *widget;
|
||||
/// GtkLevelBar *bar;
|
||||
///
|
||||
/// widget = gtk_level_bar_new ();
|
||||
/// bar = GTK_LEVEL_BAR (widget);
|
||||
///
|
||||
/// // This changes the value of the default low offset
|
||||
///
|
||||
/// gtk_level_bar_add_offset_value (bar,
|
||||
/// GTK_LEVEL_BAR_OFFSET_LOW,
|
||||
/// 0.10);
|
||||
///
|
||||
/// // This adds a new offset to the bar; the application will
|
||||
/// // be able to change its color CSS like this:
|
||||
/// //
|
||||
/// // levelbar block.my-offset {
|
||||
/// // background-color: magenta;
|
||||
/// // border-style: solid;
|
||||
/// // border-color: black;
|
||||
/// // border-width: 1px;
|
||||
/// // }
|
||||
///
|
||||
/// gtk_level_bar_add_offset_value (bar, "my-offset", 0.60);
|
||||
///
|
||||
/// return widget;
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// The default interval of values is between zero and one, but it’s possible
|
||||
/// to modify the interval using [method@Gtk.LevelBar.set_min_value] and
|
||||
/// [method@Gtk.LevelBar.set_max_value]. The value will be always drawn in
|
||||
/// proportion to the admissible interval, i.e. a value of 15 with a specified
|
||||
/// interval between 10 and 20 is equivalent to a value of 0.5 with an interval
|
||||
/// between 0 and 1. When %GTK_LEVEL_BAR_MODE_DISCRETE is used, the bar level
|
||||
/// is rendered as a finite number of separated blocks instead of a single one.
|
||||
/// The number of blocks that will be rendered is equal to the number of units
|
||||
/// specified by the admissible interval.
|
||||
///
|
||||
/// For instance, to build a bar rendered with five blocks, it’s sufficient to
|
||||
/// set the minimum value to 0 and the maximum value to 5 after changing the
|
||||
/// indicator mode to discrete.
|
||||
///
|
||||
/// # GtkLevelBar as GtkBuildable
|
||||
///
|
||||
/// The `GtkLevelBar` implementation of the `GtkBuildable` interface supports a
|
||||
/// custom `<offsets>` element, which can contain any number of `<offset>` elements,
|
||||
/// each of which must have "name" and "value" attributes.
|
||||
///
|
||||
/// # CSS nodes
|
||||
///
|
||||
/// ```
|
||||
/// levelbar[.discrete]
|
||||
/// ╰── trough
|
||||
/// ├── block.filled.level-name
|
||||
/// ┊
|
||||
/// ├── block.empty
|
||||
/// ┊
|
||||
/// ```
|
||||
///
|
||||
/// `GtkLevelBar` has a main CSS node with name levelbar and one of the style
|
||||
/// classes .discrete or .continuous and a subnode with name trough. Below the
|
||||
/// trough node are a number of nodes with name block and style class .filled
|
||||
/// or .empty. In continuous mode, there is exactly one node of each, in discrete
|
||||
/// mode, the number of filled and unfilled nodes corresponds to blocks that are
|
||||
/// drawn. The block.filled nodes also get a style class .level-name corresponding
|
||||
/// to the level for the current value.
|
||||
///
|
||||
/// In horizontal orientation, the nodes are always arranged from left to right,
|
||||
/// regardless of text direction.
|
||||
///
|
||||
/// # Accessibility
|
||||
///
|
||||
/// `GtkLevelBar` uses the %GTK_ACCESSIBLE_ROLE_METER role.
|
||||
public struct LevelBar: Widget {
|
||||
|
||||
/// Additional update functions for type extensions.
|
||||
var updateFunctions: [(ViewStorage) -> Void] = []
|
||||
/// Additional appear functions for type extensions.
|
||||
var appearFunctions: [(ViewStorage) -> Void] = []
|
||||
|
||||
/// Whether the `GtkLeveBar` is inverted.
|
||||
///
|
||||
/// Level bars normally grow from top to bottom or left to right.
|
||||
/// Inverted level bars grow in the opposite direction.
|
||||
var inverted: Bool?
|
||||
/// Determines the maximum value of the interval that can be displayed by the bar.
|
||||
var maxValue: Double?
|
||||
/// Determines the minimum value of the interval that can be displayed by the bar.
|
||||
var minValue: Double?
|
||||
/// Determines the currently filled value of the level bar.
|
||||
var value: Double?
|
||||
/// Emitted when an offset specified on the bar changes value.
|
||||
///
|
||||
/// This typically is the result of a [method@Gtk.LevelBar.add_offset_value]
|
||||
/// call.
|
||||
///
|
||||
/// The signal supports detailed connections; you can connect to the
|
||||
/// detailed signal "changed::x" in order to only receive callbacks when
|
||||
/// the value of offset "x" changes.
|
||||
var offsetChanged: (() -> Void)?
|
||||
/// The application.
|
||||
var app: GTUIApp?
|
||||
/// The window.
|
||||
var window: GTUIApplicationWindow?
|
||||
|
||||
/// Initialize `LevelBar`.
|
||||
public init() {
|
||||
}
|
||||
|
||||
/// Get the widget's view storage.
|
||||
/// - Parameter modifiers: The view modifiers.
|
||||
/// - Returns: The view storage.
|
||||
public func container(modifiers: [(View) -> View]) -> ViewStorage {
|
||||
let storage = ViewStorage(gtk_level_bar_new()?.opaque())
|
||||
update(storage, modifiers: modifiers)
|
||||
|
||||
|
||||
for function in appearFunctions {
|
||||
function(storage)
|
||||
}
|
||||
return storage
|
||||
}
|
||||
|
||||
/// Update the widget's view storage.
|
||||
/// - Parameters:
|
||||
/// - storage: The view storage.
|
||||
/// - modifiers: The view modifiers.
|
||||
public func update(_ storage: ViewStorage, modifiers: [(View) -> View]) {
|
||||
if let offsetChanged {
|
||||
storage.connectSignal(name: "offset-changed") {
|
||||
offsetChanged()
|
||||
}
|
||||
}
|
||||
storage.modify { widget in
|
||||
if let inverted {
|
||||
gtk_level_bar_set_inverted(widget, inverted.cBool)
|
||||
}
|
||||
if let maxValue {
|
||||
gtk_level_bar_set_max_value(widget, maxValue)
|
||||
}
|
||||
if let minValue {
|
||||
gtk_level_bar_set_min_value(widget, minValue)
|
||||
}
|
||||
if let value {
|
||||
gtk_level_bar_set_value(widget, value)
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
for function in updateFunctions {
|
||||
function(storage)
|
||||
}
|
||||
}
|
||||
|
||||
/// Whether the `GtkLeveBar` is inverted.
|
||||
///
|
||||
/// Level bars normally grow from top to bottom or left to right.
|
||||
/// Inverted level bars grow in the opposite direction.
|
||||
public func inverted(_ inverted: Bool? = true) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.inverted = inverted
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// Determines the maximum value of the interval that can be displayed by the bar.
|
||||
public func maxValue(_ maxValue: Double?) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.maxValue = maxValue
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// Determines the minimum value of the interval that can be displayed by the bar.
|
||||
public func minValue(_ minValue: Double?) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.minValue = minValue
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// Determines the currently filled value of the level bar.
|
||||
public func value(_ value: Double?) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.value = value
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// Emitted when an offset specified on the bar changes value.
|
||||
///
|
||||
/// This typically is the result of a [method@Gtk.LevelBar.add_offset_value]
|
||||
/// call.
|
||||
///
|
||||
/// The signal supports detailed connections; you can connect to the
|
||||
/// detailed signal "changed::x" in order to only receive callbacks when
|
||||
/// the value of offset "x" changes.
|
||||
public func offsetChanged(_ offsetChanged: @escaping () -> Void) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.offsetChanged = offsetChanged
|
||||
return newSelf
|
||||
}
|
||||
|
||||
}
|
246
Sources/Adwaita/View/Generated/LinkButton.swift
Normal file
246
Sources/Adwaita/View/Generated/LinkButton.swift
Normal file
@ -0,0 +1,246 @@
|
||||
//
|
||||
// LinkButton.swift
|
||||
// Adwaita
|
||||
//
|
||||
// Created by auto-generation on 22.01.24.
|
||||
//
|
||||
|
||||
import CAdw
|
||||
import LevenshteinTransformations
|
||||
|
||||
/// A `GtkLinkButton` is a button with a hyperlink.
|
||||
///
|
||||
/// ![An example GtkLinkButton](link-button.png)
|
||||
///
|
||||
/// It is useful to show quick links to resources.
|
||||
///
|
||||
/// A link button is created by calling either [ctor@Gtk.LinkButton.new] or
|
||||
/// [ctor@Gtk.LinkButton.new_with_label]. If using the former, the URI you
|
||||
/// pass to the constructor is used as a label for the widget.
|
||||
///
|
||||
/// The URI bound to a `GtkLinkButton` can be set specifically using
|
||||
/// [method@Gtk.LinkButton.set_uri].
|
||||
///
|
||||
/// By default, `GtkLinkButton` calls [method@Gtk.FileLauncher.launch] when the button
|
||||
/// is clicked. This behaviour can be overridden by connecting to the
|
||||
/// [signal@Gtk.LinkButton::activate-link] signal and returning %TRUE from
|
||||
/// the signal handler.
|
||||
///
|
||||
/// # CSS nodes
|
||||
///
|
||||
/// `GtkLinkButton` has a single CSS node with name button. To differentiate
|
||||
/// it from a plain `GtkButton`, it gets the .link style class.
|
||||
///
|
||||
/// # Accessibility
|
||||
///
|
||||
/// `GtkLinkButton` uses the %GTK_ACCESSIBLE_ROLE_LINK role.
|
||||
public struct LinkButton: Widget {
|
||||
|
||||
/// Additional update functions for type extensions.
|
||||
var updateFunctions: [(ViewStorage) -> Void] = []
|
||||
/// Additional appear functions for type extensions.
|
||||
var appearFunctions: [(ViewStorage) -> Void] = []
|
||||
|
||||
/// The URI bound to this button.
|
||||
var uri: String
|
||||
/// The 'visited' state of this button.
|
||||
///
|
||||
/// A visited link is drawn in a different color.
|
||||
var visited: Bool?
|
||||
/// Whether the size of the button can be made smaller than the natural
|
||||
/// size of its contents.
|
||||
///
|
||||
/// For text buttons, setting this property will allow ellipsizing the label.
|
||||
///
|
||||
/// If the contents of a button are an icon or a custom widget, setting this
|
||||
/// property has no effect.
|
||||
var canShrink: Bool?
|
||||
/// The child widget.
|
||||
var child: (() -> Body)?
|
||||
/// Whether the button has a frame.
|
||||
var hasFrame: Bool?
|
||||
/// The name of the icon used to automatically populate the button.
|
||||
var iconName: String?
|
||||
/// Text of the label inside the button, if the button contains a label widget.
|
||||
var label: String?
|
||||
/// If set, an underline in the text indicates that the following character is
|
||||
/// to be used as mnemonic.
|
||||
var useUnderline: Bool?
|
||||
/// Emitted to animate press then release.
|
||||
///
|
||||
/// This is an action signal. Applications should never connect
|
||||
/// to this signal, but use the [signal@Gtk.Button::clicked] signal.
|
||||
///
|
||||
/// The default bindings for this signal are all forms of the
|
||||
/// <kbd>␣</kbd> and <kbd>Enter</kbd> keys.
|
||||
var activate: (() -> Void)?
|
||||
/// Emitted when the button has been activated (pressed and released).
|
||||
var clicked: (() -> Void)?
|
||||
/// The application.
|
||||
var app: GTUIApp?
|
||||
/// The window.
|
||||
var window: GTUIApplicationWindow?
|
||||
|
||||
/// Initialize `LinkButton`.
|
||||
public init(uri: String) {
|
||||
self.uri = uri
|
||||
}
|
||||
|
||||
/// Get the widget's view storage.
|
||||
/// - Parameter modifiers: The view modifiers.
|
||||
/// - Returns: The view storage.
|
||||
public func container(modifiers: [(View) -> View]) -> ViewStorage {
|
||||
let storage = ViewStorage(gtk_link_button_new(uri)?.opaque())
|
||||
update(storage, modifiers: modifiers)
|
||||
if let childStorage = child?().widget(modifiers: modifiers).storage(modifiers: modifiers) {
|
||||
storage.content["child"] = [childStorage]
|
||||
gtk_button_set_child(storage.pointer?.cast(), childStorage.pointer?.cast())
|
||||
}
|
||||
|
||||
|
||||
for function in appearFunctions {
|
||||
function(storage)
|
||||
}
|
||||
return storage
|
||||
}
|
||||
|
||||
/// Update the widget's view storage.
|
||||
/// - Parameters:
|
||||
/// - storage: The view storage.
|
||||
/// - modifiers: The view modifiers.
|
||||
public func update(_ storage: ViewStorage, modifiers: [(View) -> View]) {
|
||||
if let activate {
|
||||
storage.connectSignal(name: "activate") {
|
||||
activate()
|
||||
}
|
||||
}
|
||||
if let clicked {
|
||||
storage.connectSignal(name: "clicked") {
|
||||
clicked()
|
||||
}
|
||||
}
|
||||
storage.modify { widget in
|
||||
gtk_link_button_set_uri(widget, uri)
|
||||
if let visited {
|
||||
gtk_link_button_set_visited(widget, visited.cBool)
|
||||
}
|
||||
if let canShrink {
|
||||
gtk_button_set_can_shrink(widget?.cast(), canShrink.cBool)
|
||||
}
|
||||
if let widget = storage.content["child"]?.first {
|
||||
child?().widget(modifiers: modifiers).update(widget, modifiers: modifiers)
|
||||
}
|
||||
if let hasFrame {
|
||||
gtk_button_set_has_frame(widget?.cast(), hasFrame.cBool)
|
||||
}
|
||||
if let iconName {
|
||||
gtk_button_set_icon_name(widget?.cast(), iconName)
|
||||
}
|
||||
if let label, storage.content["child"] == nil {
|
||||
gtk_button_set_label(widget?.cast(), label)
|
||||
}
|
||||
if let useUnderline {
|
||||
gtk_button_set_use_underline(widget?.cast(), useUnderline.cBool)
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
for function in updateFunctions {
|
||||
function(storage)
|
||||
}
|
||||
}
|
||||
|
||||
/// The URI bound to this button.
|
||||
public func uri(_ uri: String) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.uri = uri
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// The 'visited' state of this button.
|
||||
///
|
||||
/// A visited link is drawn in a different color.
|
||||
public func visited(_ visited: Bool? = true) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.visited = visited
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// Whether the size of the button can be made smaller than the natural
|
||||
/// size of its contents.
|
||||
///
|
||||
/// For text buttons, setting this property will allow ellipsizing the label.
|
||||
///
|
||||
/// If the contents of a button are an icon or a custom widget, setting this
|
||||
/// property has no effect.
|
||||
public func canShrink(_ canShrink: Bool? = true) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.canShrink = canShrink
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// The child widget.
|
||||
public func child(@ViewBuilder _ child: @escaping (() -> Body)) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.child = child
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// Whether the button has a frame.
|
||||
public func hasFrame(_ hasFrame: Bool? = true) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.hasFrame = hasFrame
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// The name of the icon used to automatically populate the button.
|
||||
public func iconName(_ iconName: String?) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.iconName = iconName
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// Text of the label inside the button, if the button contains a label widget.
|
||||
public func label(_ label: String?) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.label = label
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// If set, an underline in the text indicates that the following character is
|
||||
/// to be used as mnemonic.
|
||||
public func useUnderline(_ useUnderline: Bool? = true) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.useUnderline = useUnderline
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// Emitted to animate press then release.
|
||||
///
|
||||
/// This is an action signal. Applications should never connect
|
||||
/// to this signal, but use the [signal@Gtk.Button::clicked] signal.
|
||||
///
|
||||
/// The default bindings for this signal are all forms of the
|
||||
/// <kbd>␣</kbd> and <kbd>Enter</kbd> keys.
|
||||
public func activate(_ activate: @escaping () -> Void) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.activate = activate
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// Emitted when the button has been activated (pressed and released).
|
||||
public func clicked(_ clicked: @escaping () -> Void) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.clicked = clicked
|
||||
return newSelf
|
||||
}
|
||||
|
||||
}
|
319
Sources/Adwaita/View/Generated/ListBox.swift
Normal file
319
Sources/Adwaita/View/Generated/ListBox.swift
Normal file
@ -0,0 +1,319 @@
|
||||
//
|
||||
// ListBox.swift
|
||||
// Adwaita
|
||||
//
|
||||
// Created by auto-generation on 22.01.24.
|
||||
//
|
||||
|
||||
import CAdw
|
||||
import LevenshteinTransformations
|
||||
|
||||
/// `GtkListBox` is a vertical list.
|
||||
///
|
||||
/// A `GtkListBox` only contains `GtkListBoxRow` children. These rows can
|
||||
/// by dynamically sorted and filtered, and headers can be added dynamically
|
||||
/// depending on the row content. It also allows keyboard and mouse navigation
|
||||
/// and selection like a typical list.
|
||||
///
|
||||
/// Using `GtkListBox` is often an alternative to `GtkTreeView`, especially
|
||||
/// when the list contents has a more complicated layout than what is allowed
|
||||
/// by a `GtkCellRenderer`, or when the contents is interactive (i.e. has a
|
||||
/// button in it).
|
||||
///
|
||||
/// Although a `GtkListBox` must have only `GtkListBoxRow` children, you can
|
||||
/// add any kind of widget to it via [method@Gtk.ListBox.prepend],
|
||||
/// [method@Gtk.ListBox.append] and [method@Gtk.ListBox.insert] and a
|
||||
/// `GtkListBoxRow` widget will automatically be inserted between the list
|
||||
/// and the widget.
|
||||
///
|
||||
/// `GtkListBoxRows` can be marked as activatable or selectable. If a row is
|
||||
/// activatable, [signal@Gtk.ListBox::row-activated] will be emitted for it when
|
||||
/// the user tries to activate it. If it is selectable, the row will be marked
|
||||
/// as selected when the user tries to select it.
|
||||
///
|
||||
/// # GtkListBox as GtkBuildable
|
||||
///
|
||||
/// The `GtkListBox` implementation of the `GtkBuildable` interface supports
|
||||
/// setting a child as the placeholder by specifying “placeholder” as the “type”
|
||||
/// attribute of a `<child>` element. See [method@Gtk.ListBox.set_placeholder]
|
||||
/// for info.
|
||||
///
|
||||
/// # CSS nodes
|
||||
///
|
||||
/// |[<!-- language="plain" -->
|
||||
/// list[.separators][.rich-list][.navigation-sidebar][.boxed-list]
|
||||
/// ╰── row[.activatable]
|
||||
/// ]|
|
||||
///
|
||||
/// `GtkListBox` uses a single CSS node named list. It may carry the .separators
|
||||
/// style class, when the [property@Gtk.ListBox:show-separators] property is set.
|
||||
/// Each `GtkListBoxRow` uses a single CSS node named row. The row nodes get the
|
||||
/// .activatable style class added when appropriate.
|
||||
///
|
||||
/// It may also carry the .boxed-list style class. In this case, the list will be
|
||||
/// automatically surrounded by a frame and have separators.
|
||||
///
|
||||
/// The main list node may also carry style classes to select
|
||||
/// the style of [list presentation](section-list-widget.html#list-styles):
|
||||
/// .rich-list, .navigation-sidebar or .data-table.
|
||||
///
|
||||
/// # Accessibility
|
||||
///
|
||||
/// `GtkListBox` uses the %GTK_ACCESSIBLE_ROLE_LIST role and `GtkListBoxRow` uses
|
||||
/// the %GTK_ACCESSIBLE_ROLE_LIST_ITEM role.
|
||||
public struct ListBox<Element>: Widget where Element: Identifiable {
|
||||
|
||||
/// Additional update functions for type extensions.
|
||||
var updateFunctions: [(ViewStorage) -> Void] = []
|
||||
/// Additional appear functions for type extensions.
|
||||
var appearFunctions: [(ViewStorage) -> Void] = []
|
||||
|
||||
/// Whether to accept unpaired release events.
|
||||
var acceptUnpairedRelease: Bool?
|
||||
/// Determines whether children can be activated with a single
|
||||
/// click, or require a double-click.
|
||||
var activateOnSingleClick: Bool?
|
||||
/// Whether to show separators between rows.
|
||||
var showSeparators: Bool?
|
||||
/// activateCursorRow
|
||||
var activateCursorRow: (() -> Void)?
|
||||
/// moveCursor
|
||||
var moveCursor: (() -> Void)?
|
||||
/// Emitted when a row has been activated by the user.
|
||||
var rowActivated: (() -> Void)?
|
||||
/// Emitted when a new row is selected, or (with a %NULL @row)
|
||||
/// when the selection is cleared.
|
||||
///
|
||||
/// When the @box is using %GTK_SELECTION_MULTIPLE, this signal will not
|
||||
/// give you the full picture of selection changes, and you should use
|
||||
/// the [signal@Gtk.ListBox::selected-rows-changed] signal instead.
|
||||
var rowSelected: (() -> Void)?
|
||||
/// Emitted to select all children of the box, if the selection
|
||||
/// mode permits it.
|
||||
///
|
||||
/// This is a [keybinding signal](class.SignalAction.html).
|
||||
///
|
||||
/// The default binding for this signal is <kbd>Ctrl</kbd>-<kbd>a</kbd>.
|
||||
var selectAll: (() -> Void)?
|
||||
/// Emitted when the set of selected rows changes.
|
||||
var selectedRowsChanged: (() -> Void)?
|
||||
/// toggleCursorRow
|
||||
var toggleCursorRow: (() -> Void)?
|
||||
/// Emitted to unselect all children of the box, if the selection
|
||||
/// mode permits it.
|
||||
///
|
||||
/// This is a [keybinding signal](class.SignalAction.html).
|
||||
///
|
||||
/// The default binding for this signal is
|
||||
/// <kbd>Ctrl</kbd>-<kbd>Shift</kbd>-<kbd>a</kbd>.
|
||||
var unselectAll: (() -> Void)?
|
||||
/// The dynamic widget elements.
|
||||
var elements: [Element]
|
||||
/// The dynamic widget content.
|
||||
var content: (Element) -> Body
|
||||
/// The application.
|
||||
var app: GTUIApp?
|
||||
/// The window.
|
||||
var window: GTUIApplicationWindow?
|
||||
|
||||
/// Initialize `ListBox`.
|
||||
public init(_ elements: [Element], @ViewBuilder content: @escaping (Element) -> Body) {
|
||||
self.elements = elements
|
||||
self.content = content
|
||||
}
|
||||
|
||||
/// Get the widget's view storage.
|
||||
/// - Parameter modifiers: The view modifiers.
|
||||
/// - Returns: The view storage.
|
||||
public func container(modifiers: [(View) -> View]) -> ViewStorage {
|
||||
let storage = ViewStorage(gtk_list_box_new()?.opaque())
|
||||
update(storage, modifiers: modifiers)
|
||||
|
||||
|
||||
for function in appearFunctions {
|
||||
function(storage)
|
||||
}
|
||||
return storage
|
||||
}
|
||||
|
||||
/// Update the widget's view storage.
|
||||
/// - Parameters:
|
||||
/// - storage: The view storage.
|
||||
/// - modifiers: The view modifiers.
|
||||
public func update(_ storage: ViewStorage, modifiers: [(View) -> View]) {
|
||||
if let activateCursorRow {
|
||||
storage.connectSignal(name: "activate-cursor-row") {
|
||||
activateCursorRow()
|
||||
}
|
||||
}
|
||||
if let moveCursor {
|
||||
storage.connectSignal(name: "move-cursor") {
|
||||
moveCursor()
|
||||
}
|
||||
}
|
||||
if let rowActivated {
|
||||
storage.connectSignal(name: "row-activated") {
|
||||
rowActivated()
|
||||
}
|
||||
}
|
||||
if let rowSelected {
|
||||
storage.connectSignal(name: "row-selected") {
|
||||
rowSelected()
|
||||
}
|
||||
}
|
||||
if let selectAll {
|
||||
storage.connectSignal(name: "select-all") {
|
||||
selectAll()
|
||||
}
|
||||
}
|
||||
if let selectedRowsChanged {
|
||||
storage.connectSignal(name: "selected-rows-changed") {
|
||||
selectedRowsChanged()
|
||||
}
|
||||
}
|
||||
if let toggleCursorRow {
|
||||
storage.connectSignal(name: "toggle-cursor-row") {
|
||||
toggleCursorRow()
|
||||
}
|
||||
}
|
||||
if let unselectAll {
|
||||
storage.connectSignal(name: "unselect-all") {
|
||||
unselectAll()
|
||||
}
|
||||
}
|
||||
storage.modify { widget in
|
||||
if let activateOnSingleClick {
|
||||
gtk_list_box_set_activate_on_single_click(widget, activateOnSingleClick.cBool)
|
||||
}
|
||||
if let showSeparators {
|
||||
gtk_list_box_set_show_separators(widget, showSeparators.cBool)
|
||||
}
|
||||
|
||||
var contentStorage: [ViewStorage] = storage.content[.mainContent] ?? []
|
||||
let old = storage.fields["element"] as? [Element] ?? []
|
||||
old.identifiableTransform(
|
||||
to: elements,
|
||||
functions: .init { index, element in
|
||||
let child = content(element).widget(modifiers: modifiers).container(modifiers: modifiers)
|
||||
gtk_list_box_remove(widget, gtk_list_box_get_row_at_index(widget, index.cInt)?.cast())
|
||||
gtk_list_box_insert(widget, child.pointer?.cast(), index.cInt)
|
||||
contentStorage.remove(at: index)
|
||||
contentStorage.insert(child, at: index)
|
||||
} delete: { index in
|
||||
gtk_list_box_remove(widget, gtk_list_box_get_row_at_index(widget, index.cInt)?.cast())
|
||||
contentStorage.remove(at: index)
|
||||
} insert: { index, element in
|
||||
let child = content(element).widget(modifiers: modifiers).container(modifiers: modifiers)
|
||||
gtk_list_box_insert(widget, child.pointer?.cast(), index.cInt)
|
||||
contentStorage.insert(child, at: index)
|
||||
}
|
||||
)
|
||||
storage.fields["element"] = elements
|
||||
storage.content[.mainContent] = contentStorage
|
||||
for (index, element) in elements.enumerated() {
|
||||
content(element).widget(modifiers: modifiers).update(contentStorage[index], modifiers: modifiers)
|
||||
}
|
||||
}
|
||||
for function in updateFunctions {
|
||||
function(storage)
|
||||
}
|
||||
}
|
||||
|
||||
/// Whether to accept unpaired release events.
|
||||
public func acceptUnpairedRelease(_ acceptUnpairedRelease: Bool? = true) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.acceptUnpairedRelease = acceptUnpairedRelease
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// Determines whether children can be activated with a single
|
||||
/// click, or require a double-click.
|
||||
public func activateOnSingleClick(_ activateOnSingleClick: Bool? = true) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.activateOnSingleClick = activateOnSingleClick
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// Whether to show separators between rows.
|
||||
public func showSeparators(_ showSeparators: Bool? = true) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.showSeparators = showSeparators
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// activateCursorRow
|
||||
public func activateCursorRow(_ activateCursorRow: @escaping () -> Void) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.activateCursorRow = activateCursorRow
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// moveCursor
|
||||
public func moveCursor(_ moveCursor: @escaping () -> Void) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.moveCursor = moveCursor
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// Emitted when a row has been activated by the user.
|
||||
public func rowActivated(_ rowActivated: @escaping () -> Void) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.rowActivated = rowActivated
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// Emitted when a new row is selected, or (with a %NULL @row)
|
||||
/// when the selection is cleared.
|
||||
///
|
||||
/// When the @box is using %GTK_SELECTION_MULTIPLE, this signal will not
|
||||
/// give you the full picture of selection changes, and you should use
|
||||
/// the [signal@Gtk.ListBox::selected-rows-changed] signal instead.
|
||||
public func rowSelected(_ rowSelected: @escaping () -> Void) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.rowSelected = rowSelected
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// Emitted to select all children of the box, if the selection
|
||||
/// mode permits it.
|
||||
///
|
||||
/// This is a [keybinding signal](class.SignalAction.html).
|
||||
///
|
||||
/// The default binding for this signal is <kbd>Ctrl</kbd>-<kbd>a</kbd>.
|
||||
public func selectAll(_ selectAll: @escaping () -> Void) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.selectAll = selectAll
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// Emitted when the set of selected rows changes.
|
||||
public func selectedRowsChanged(_ selectedRowsChanged: @escaping () -> Void) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.selectedRowsChanged = selectedRowsChanged
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// toggleCursorRow
|
||||
public func toggleCursorRow(_ toggleCursorRow: @escaping () -> Void) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.toggleCursorRow = toggleCursorRow
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// Emitted to unselect all children of the box, if the selection
|
||||
/// mode permits it.
|
||||
///
|
||||
/// This is a [keybinding signal](class.SignalAction.html).
|
||||
///
|
||||
/// The default binding for this signal is
|
||||
/// <kbd>Ctrl</kbd>-<kbd>Shift</kbd>-<kbd>a</kbd>.
|
||||
public func unselectAll(_ unselectAll: @escaping () -> Void) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.unselectAll = unselectAll
|
||||
return newSelf
|
||||
}
|
||||
|
||||
}
|
289
Sources/Adwaita/View/Generated/Menu.swift
Normal file
289
Sources/Adwaita/View/Generated/Menu.swift
Normal file
@ -0,0 +1,289 @@
|
||||
//
|
||||
// Menu.swift
|
||||
// Adwaita
|
||||
//
|
||||
// Created by auto-generation on 22.01.24.
|
||||
//
|
||||
|
||||
import CAdw
|
||||
import LevenshteinTransformations
|
||||
|
||||
/// The `GtkMenuButton` widget is used to display a popup when clicked.
|
||||
///
|
||||
/// ![An example GtkMenuButton](menu-button.png)
|
||||
///
|
||||
/// This popup can be provided either as a `GtkPopover` or as an abstract
|
||||
/// `GMenuModel`.
|
||||
///
|
||||
/// The `GtkMenuButton` widget can show either an icon (set with the
|
||||
/// [property@Gtk.MenuButton:icon-name] property) or a label (set with the
|
||||
/// [property@Gtk.MenuButton:label] property). If neither is explicitly set,
|
||||
/// a [class@Gtk.Image] is automatically created, using an arrow image oriented
|
||||
/// according to [property@Gtk.MenuButton:direction] or the generic
|
||||
/// “open-menu-symbolic” icon if the direction is not set.
|
||||
///
|
||||
/// The positioning of the popup is determined by the
|
||||
/// [property@Gtk.MenuButton:direction] property of the menu button.
|
||||
///
|
||||
/// For menus, the [property@Gtk.Widget:halign] and [property@Gtk.Widget:valign]
|
||||
/// properties of the menu are also taken into account. For example, when the
|
||||
/// direction is %GTK_ARROW_DOWN and the horizontal alignment is %GTK_ALIGN_START,
|
||||
/// the menu will be positioned below the button, with the starting edge
|
||||
/// (depending on the text direction) of the menu aligned with the starting
|
||||
/// edge of the button. If there is not enough space below the button, the
|
||||
/// menu is popped up above the button instead. If the alignment would move
|
||||
/// part of the menu offscreen, it is “pushed in”.
|
||||
///
|
||||
/// | | start | center | end |
|
||||
/// | - | --- | --- | --- |
|
||||
/// | **down** | ![](down-start.png) | ![](down-center.png) | ![](down-end.png) |
|
||||
/// | **up** | ![](up-start.png) | ![](up-center.png) | ![](up-end.png) |
|
||||
/// | **left** | ![](left-start.png) | ![](left-center.png) | ![](left-end.png) |
|
||||
/// | **right** | ![](right-start.png) | ![](right-center.png) | ![](right-end.png) |
|
||||
///
|
||||
/// # CSS nodes
|
||||
///
|
||||
/// ```
|
||||
/// menubutton
|
||||
/// ╰── button.toggle
|
||||
/// ╰── <content>╰── [arrow]
|
||||
/// ```
|
||||
///
|
||||
/// `GtkMenuButton` has a single CSS node with name `menubutton`
|
||||
/// which contains a `button` node with a `.toggle` style class.
|
||||
///
|
||||
/// If the button contains an icon, it will have the `.image-button` style class,
|
||||
/// if it contains text, it will have `.text-button` style class. If an arrow is
|
||||
/// visible in addition to an icon, text or a custom child, it will also have
|
||||
/// `.arrow-button` style class.
|
||||
///
|
||||
/// Inside the toggle button content, there is an `arrow` node for
|
||||
/// the indicator, which will carry one of the `.none`, `.up`, `.down`,
|
||||
/// `.left` or `.right` style classes to indicate the direction that
|
||||
/// the menu will appear in. The CSS is expected to provide a suitable
|
||||
/// image for each of these cases using the `-gtk-icon-source` property.
|
||||
///
|
||||
/// Optionally, the `menubutton` node can carry the `.circular` style class
|
||||
/// to request a round appearance.
|
||||
///
|
||||
/// # Accessibility
|
||||
///
|
||||
/// `GtkMenuButton` uses the %GTK_ACCESSIBLE_ROLE_BUTTON role.
|
||||
public struct Menu: Widget {
|
||||
|
||||
/// Additional update functions for type extensions.
|
||||
var updateFunctions: [(ViewStorage) -> Void] = []
|
||||
/// Additional appear functions for type extensions.
|
||||
var appearFunctions: [(ViewStorage) -> Void] = []
|
||||
|
||||
/// Whether the menu button is active.
|
||||
var active: Binding<Bool>?
|
||||
/// Whether to show a dropdown arrow even when using an icon or a custom child.
|
||||
var alwaysShowArrow: Bool?
|
||||
/// Whether the size of the button can be made smaller than the natural
|
||||
/// size of its contents.
|
||||
var canShrink: Bool?
|
||||
/// The child widget.
|
||||
var child: (() -> Body)?
|
||||
/// Whether the button has a frame.
|
||||
var hasFrame: Bool?
|
||||
/// The name of the icon used to automatically populate the button.
|
||||
var iconName: String?
|
||||
/// The label for the button.
|
||||
var label: String?
|
||||
/// The `GMenuModel` from which the popup will be created.
|
||||
///
|
||||
/// See [method@Gtk.MenuButton.set_menu_model] for the interaction
|
||||
/// with the [property@Gtk.MenuButton:popover] property.
|
||||
var menuModel: (() -> MenuContent)?
|
||||
/// Whether the menu button acts as a primary menu.
|
||||
///
|
||||
/// Primary menus can be opened using the <kbd>F10</kbd> key
|
||||
var primary: Bool?
|
||||
/// If set an underscore in the text indicates a mnemonic.
|
||||
var useUnderline: Bool?
|
||||
/// Emitted to when the menu button is activated.
|
||||
///
|
||||
/// The `::activate` signal on `GtkMenuButton` is an action signal and
|
||||
/// emitting it causes the button to pop up its menu.
|
||||
var activate: (() -> Void)?
|
||||
/// The application.
|
||||
var app: GTUIApp?
|
||||
/// The window.
|
||||
var window: GTUIApplicationWindow?
|
||||
|
||||
/// Initialize `Menu`.
|
||||
public init() {
|
||||
}
|
||||
|
||||
/// Get the widget's view storage.
|
||||
/// - Parameter modifiers: The view modifiers.
|
||||
/// - Returns: The view storage.
|
||||
public func container(modifiers: [(View) -> View]) -> ViewStorage {
|
||||
let storage = ViewStorage(gtk_menu_button_new()?.opaque())
|
||||
update(storage, modifiers: modifiers)
|
||||
if let childStorage = child?().widget(modifiers: modifiers).storage(modifiers: modifiers) {
|
||||
storage.content["child"] = [childStorage]
|
||||
gtk_menu_button_set_child(storage.pointer, childStorage.pointer?.cast())
|
||||
}
|
||||
if let declarative = menuModel?(), let app {
|
||||
let menu = g_menu_new()
|
||||
gtk_menu_button_set_menu_model(storage.pointer, menu?.cast())
|
||||
for item in declarative {
|
||||
item.addMenuItems(menu: menu, app: app, window: window)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
storage.notify(name: "active") {
|
||||
active?.wrappedValue = gtk_menu_button_get_active(storage.pointer) != 0
|
||||
}
|
||||
for function in appearFunctions {
|
||||
function(storage)
|
||||
}
|
||||
return storage
|
||||
}
|
||||
|
||||
/// Update the widget's view storage.
|
||||
/// - Parameters:
|
||||
/// - storage: The view storage.
|
||||
/// - modifiers: The view modifiers.
|
||||
public func update(_ storage: ViewStorage, modifiers: [(View) -> View]) {
|
||||
if let activate {
|
||||
storage.connectSignal(name: "activate") {
|
||||
activate()
|
||||
}
|
||||
}
|
||||
storage.modify { widget in
|
||||
if let active {
|
||||
gtk_menu_button_set_active(widget, active.wrappedValue.cBool)
|
||||
}
|
||||
if let alwaysShowArrow {
|
||||
gtk_menu_button_set_always_show_arrow(widget, alwaysShowArrow.cBool)
|
||||
}
|
||||
if let canShrink {
|
||||
gtk_menu_button_set_can_shrink(widget, canShrink.cBool)
|
||||
}
|
||||
if let widget = storage.content["child"]?.first {
|
||||
child?().widget(modifiers: modifiers).update(widget, modifiers: modifiers)
|
||||
}
|
||||
if let hasFrame {
|
||||
gtk_menu_button_set_has_frame(widget, hasFrame.cBool)
|
||||
}
|
||||
if let iconName {
|
||||
gtk_menu_button_set_icon_name(widget, iconName)
|
||||
}
|
||||
if let label, storage.content["child"] == nil {
|
||||
gtk_menu_button_set_label(widget, label)
|
||||
}
|
||||
if let primary {
|
||||
gtk_menu_button_set_primary(widget, primary.cBool)
|
||||
}
|
||||
if let useUnderline {
|
||||
gtk_menu_button_set_use_underline(widget, useUnderline.cBool)
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
for function in updateFunctions {
|
||||
function(storage)
|
||||
}
|
||||
}
|
||||
|
||||
/// Whether the menu button is active.
|
||||
public func active(_ active: Binding<Bool>?) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.active = active
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// Whether to show a dropdown arrow even when using an icon or a custom child.
|
||||
public func alwaysShowArrow(_ alwaysShowArrow: Bool? = true) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.alwaysShowArrow = alwaysShowArrow
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// Whether the size of the button can be made smaller than the natural
|
||||
/// size of its contents.
|
||||
public func canShrink(_ canShrink: Bool? = true) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.canShrink = canShrink
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// The child widget.
|
||||
public func child(@ViewBuilder _ child: @escaping (() -> Body)) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.child = child
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// Whether the button has a frame.
|
||||
public func hasFrame(_ hasFrame: Bool? = true) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.hasFrame = hasFrame
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// The name of the icon used to automatically populate the button.
|
||||
public func iconName(_ iconName: String?) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.iconName = iconName
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// The label for the button.
|
||||
public func label(_ label: String?) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.label = label
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// The `GMenuModel` from which the popup will be created.
|
||||
///
|
||||
/// See [method@Gtk.MenuButton.set_menu_model] for the interaction
|
||||
/// with the [property@Gtk.MenuButton:popover] property.
|
||||
public func menuModel(app: GTUIApp, window: GTUIApplicationWindow? = nil, @MenuBuilder _ menuModel: @escaping (() -> MenuContent)) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.menuModel = menuModel
|
||||
newSelf.app = app; newSelf.window = window
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// Whether the menu button acts as a primary menu.
|
||||
///
|
||||
/// Primary menus can be opened using the <kbd>F10</kbd> key
|
||||
public func primary(_ primary: Bool? = true) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.primary = primary
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// If set an underscore in the text indicates a mnemonic.
|
||||
public func useUnderline(_ useUnderline: Bool? = true) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.useUnderline = useUnderline
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// Emitted to when the menu button is activated.
|
||||
///
|
||||
/// The `::activate` signal on `GtkMenuButton` is an action signal and
|
||||
/// emitting it causes the button to pop up its menu.
|
||||
public func activate(_ activate: @escaping () -> Void) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.activate = activate
|
||||
return newSelf
|
||||
}
|
||||
|
||||
}
|
167
Sources/Adwaita/View/Generated/Overlay.swift
Normal file
167
Sources/Adwaita/View/Generated/Overlay.swift
Normal file
@ -0,0 +1,167 @@
|
||||
//
|
||||
// Overlay.swift
|
||||
// Adwaita
|
||||
//
|
||||
// Created by auto-generation on 22.01.24.
|
||||
//
|
||||
|
||||
import CAdw
|
||||
import LevenshteinTransformations
|
||||
|
||||
/// `GtkOverlay` is a container which contains a single main child, on top
|
||||
/// of which it can place “overlay” widgets.
|
||||
///
|
||||
/// ![An example GtkOverlay](overlay.png)
|
||||
///
|
||||
/// The position of each overlay widget is determined by its
|
||||
/// [property@Gtk.Widget:halign] and [property@Gtk.Widget:valign]
|
||||
/// properties. E.g. a widget with both alignments set to %GTK_ALIGN_START
|
||||
/// will be placed at the top left corner of the `GtkOverlay` container,
|
||||
/// whereas an overlay with halign set to %GTK_ALIGN_CENTER and valign set
|
||||
/// to %GTK_ALIGN_END will be placed a the bottom edge of the `GtkOverlay`,
|
||||
/// horizontally centered. The position can be adjusted by setting the margin
|
||||
/// properties of the child to non-zero values.
|
||||
///
|
||||
/// More complicated placement of overlays is possible by connecting
|
||||
/// to the [signal@Gtk.Overlay::get-child-position] signal.
|
||||
///
|
||||
/// An overlay’s minimum and natural sizes are those of its main child.
|
||||
/// The sizes of overlay children are not considered when measuring these
|
||||
/// preferred sizes.
|
||||
///
|
||||
/// # GtkOverlay as GtkBuildable
|
||||
///
|
||||
/// The `GtkOverlay` implementation of the `GtkBuildable` interface
|
||||
/// supports placing a child as an overlay by specifying “overlay” as
|
||||
/// the “type” attribute of a `<child>` element.
|
||||
///
|
||||
/// # CSS nodes
|
||||
///
|
||||
/// `GtkOverlay` has a single CSS node with the name “overlay”. Overlay children
|
||||
/// whose alignments cause them to be positioned at an edge get the style classes
|
||||
/// “.left”, “.right”, “.top”, and/or “.bottom” according to their position.
|
||||
public struct Overlay: Widget {
|
||||
|
||||
/// Additional update functions for type extensions.
|
||||
var updateFunctions: [(ViewStorage) -> Void] = []
|
||||
/// Additional appear functions for type extensions.
|
||||
var appearFunctions: [(ViewStorage) -> Void] = []
|
||||
|
||||
/// The main child widget.
|
||||
var child: (() -> Body)?
|
||||
/// Emitted to determine the position and size of any overlay
|
||||
/// child widgets.
|
||||
///
|
||||
/// A handler for this signal should fill @allocation with
|
||||
/// the desired position and size for @widget, relative to
|
||||
/// the 'main' child of @overlay.
|
||||
///
|
||||
/// The default handler for this signal uses the @widget's
|
||||
/// halign and valign properties to determine the position
|
||||
/// and gives the widget its natural size (except that an
|
||||
/// alignment of %GTK_ALIGN_FILL will cause the overlay to
|
||||
/// be full-width/height). If the main child is a
|
||||
/// `GtkScrolledWindow`, the overlays are placed relative
|
||||
/// to its contents.
|
||||
var getChildPosition: (() -> Void)?
|
||||
/// The body for the widget "overlay".
|
||||
var overlay: () -> Body = { [] }
|
||||
/// The application.
|
||||
var app: GTUIApp?
|
||||
/// The window.
|
||||
var window: GTUIApplicationWindow?
|
||||
|
||||
/// Initialize `Overlay`.
|
||||
public init() {
|
||||
}
|
||||
|
||||
/// Get the widget's view storage.
|
||||
/// - Parameter modifiers: The view modifiers.
|
||||
/// - Returns: The view storage.
|
||||
public func container(modifiers: [(View) -> View]) -> ViewStorage {
|
||||
let storage = ViewStorage(gtk_overlay_new()?.opaque())
|
||||
update(storage, modifiers: modifiers)
|
||||
if let childStorage = child?().widget(modifiers: modifiers).storage(modifiers: modifiers) {
|
||||
storage.content["child"] = [childStorage]
|
||||
gtk_overlay_set_child(storage.pointer, childStorage.pointer?.cast())
|
||||
}
|
||||
|
||||
var overlayStorage: [ViewStorage] = []
|
||||
for view in overlay() {
|
||||
overlayStorage.append(view.storage(modifiers: modifiers))
|
||||
gtk_overlay_add_overlay(storage.pointer, overlayStorage.last?.pointer?.cast())
|
||||
}
|
||||
storage.content["overlay"] = overlayStorage
|
||||
|
||||
for function in appearFunctions {
|
||||
function(storage)
|
||||
}
|
||||
return storage
|
||||
}
|
||||
|
||||
/// Update the widget's view storage.
|
||||
/// - Parameters:
|
||||
/// - storage: The view storage.
|
||||
/// - modifiers: The view modifiers.
|
||||
public func update(_ storage: ViewStorage, modifiers: [(View) -> View]) {
|
||||
if let getChildPosition {
|
||||
storage.connectSignal(name: "get-child-position") {
|
||||
getChildPosition()
|
||||
}
|
||||
}
|
||||
storage.modify { widget in
|
||||
if let widget = storage.content["child"]?.first {
|
||||
child?().widget(modifiers: modifiers).update(widget, modifiers: modifiers)
|
||||
}
|
||||
|
||||
if let overlayStorage = storage.content["overlay"] {
|
||||
for (index, view) in overlay().enumerated() {
|
||||
if let storage = overlayStorage[safe: index] {
|
||||
view.updateStorage(storage, modifiers: modifiers)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
for function in updateFunctions {
|
||||
function(storage)
|
||||
}
|
||||
}
|
||||
|
||||
/// The main child widget.
|
||||
public func child(@ViewBuilder _ child: @escaping (() -> Body)) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.child = child
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// Emitted to determine the position and size of any overlay
|
||||
/// child widgets.
|
||||
///
|
||||
/// A handler for this signal should fill @allocation with
|
||||
/// the desired position and size for @widget, relative to
|
||||
/// the 'main' child of @overlay.
|
||||
///
|
||||
/// The default handler for this signal uses the @widget's
|
||||
/// halign and valign properties to determine the position
|
||||
/// and gives the widget its natural size (except that an
|
||||
/// alignment of %GTK_ALIGN_FILL will cause the overlay to
|
||||
/// be full-width/height). If the main child is a
|
||||
/// `GtkScrolledWindow`, the overlays are placed relative
|
||||
/// to its contents.
|
||||
public func getChildPosition(_ getChildPosition: @escaping () -> Void) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.getChildPosition = getChildPosition
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// Set the body for "overlay".
|
||||
/// - Parameter body: The body.
|
||||
/// - Returns: The widget.
|
||||
public func overlay(@ViewBuilder _ body: @escaping () -> Body) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.overlay = body
|
||||
return newSelf
|
||||
}
|
||||
}
|
361
Sources/Adwaita/View/Generated/OverlaySplitView.swift
Normal file
361
Sources/Adwaita/View/Generated/OverlaySplitView.swift
Normal file
@ -0,0 +1,361 @@
|
||||
//
|
||||
// OverlaySplitView.swift
|
||||
// Adwaita
|
||||
//
|
||||
// Created by auto-generation on 22.01.24.
|
||||
//
|
||||
|
||||
import CAdw
|
||||
import LevenshteinTransformations
|
||||
|
||||
/// A widget presenting sidebar and content side by side or as an overlay.
|
||||
///
|
||||
/// <picture><source srcset="overlay-split-view-dark.png" media="(prefers-color-scheme: dark)"><img src="overlay-split-view.png" alt="overlay-split-view"></picture><picture><source srcset="overlay-split-view-collapsed-dark.png" media="(prefers-color-scheme: dark)"><img src="overlay-split-view-collapsed.png" alt="overlay-split-view-collapsed"></picture>
|
||||
///
|
||||
/// `AdwOverlaySplitView` has two children: sidebar and content, and displays
|
||||
/// them side by side.
|
||||
///
|
||||
/// When [property@OverlaySplitView:collapsed] is set to `TRUE`, the sidebar is
|
||||
/// instead shown as an overlay above the content widget.
|
||||
///
|
||||
/// The sidebar can be hidden or shown using the
|
||||
/// [property@OverlaySplitView:show-sidebar] property.
|
||||
///
|
||||
/// Sidebar can be displayed before or after the content, this can be controlled
|
||||
/// with the [property@OverlaySplitView:sidebar-position] property.
|
||||
///
|
||||
/// Collapsing the split view automatically hides the sidebar widget, and
|
||||
/// uncollapsing it shows the sidebar. If this behavior is not desired, the
|
||||
/// [property@OverlaySplitView:pin-sidebar] property can be used to override it.
|
||||
///
|
||||
/// `AdwOverlaySplitView` supports an edge swipe gesture for showing the sidebar,
|
||||
/// and a swipe from the sidebar for hiding it. Gestures are only supported on
|
||||
/// touchscreen, but not touchpad. Gestures can be controlled with the
|
||||
/// [property@OverlaySplitView:enable-show-gesture] and
|
||||
/// [property@OverlaySplitView:enable-hide-gesture] properties.
|
||||
///
|
||||
/// See also [class@NavigationSplitView].
|
||||
///
|
||||
/// `AdwOverlaySplitView` is typically used together with an [class@Breakpoint]
|
||||
/// setting the `collapsed` property to `TRUE` on small widths, as follows:
|
||||
///
|
||||
/// ```xml
|
||||
/// <object class="AdwWindow"><property name="width-request">360</property><property name="height-request">200</property><property name="default-width">800</property><property name="default-height">800</property><child><object class="AdwBreakpoint"><condition>max-width: 400sp</condition><setter object="split_view" property="collapsed">True</setter></object></child><property name="content"><object class="AdwOverlaySplitView" id="split_view"><property name="sidebar"><!-- ... --></property><property name="content"><!-- ... --></property></object></property></object>
|
||||
/// ```
|
||||
///
|
||||
/// `AdwOverlaySplitView` is often used for implementing the
|
||||
/// [utility pane](https://developer.gnome.org/hig/patterns/containers/utility-panes.html)
|
||||
/// pattern.
|
||||
///
|
||||
/// ## Sizing
|
||||
///
|
||||
/// When not collapsed, `AdwOverlaySplitView` changes the sidebar width
|
||||
/// depending on its own width.
|
||||
///
|
||||
/// If possible, it tries to allocate a fraction of the total width, controlled
|
||||
/// with the [property@OverlaySplitView:sidebar-width-fraction] property.
|
||||
///
|
||||
/// The sidebar also has minimum and maximum sizes, controlled with the
|
||||
/// [property@OverlaySplitView:min-sidebar-width] and
|
||||
/// [property@OverlaySplitView:max-sidebar-width] properties.
|
||||
///
|
||||
/// The minimum and maximum sizes are using the length unit specified with the
|
||||
/// [property@OverlaySplitView:sidebar-width-unit].
|
||||
///
|
||||
/// By default, sidebar is using 25% of the total width, with 180sp as the
|
||||
/// minimum size and 280sp as the maximum size.
|
||||
///
|
||||
/// When collapsed, the preferred width fraction is ignored and the sidebar uses
|
||||
/// [property@OverlaySplitView:max-sidebar-width] when possible.
|
||||
///
|
||||
/// ## Header Bar Integration
|
||||
///
|
||||
/// When used inside `AdwOverlaySplitView`, [class@HeaderBar] will automatically
|
||||
/// hide the window buttons in the middle.
|
||||
///
|
||||
/// ## `AdwOverlaySplitView` as `GtkBuildable`
|
||||
///
|
||||
/// The `AdwOverlaySplitView` implementation of the [iface@Gtk.Buildable]
|
||||
/// interface supports setting the sidebar widget by specifying “sidebar” as the
|
||||
/// “type” attribute of a `<child>` element, Specifying “content” child type or
|
||||
/// omitting it results in setting the content widget.
|
||||
///
|
||||
/// ## CSS nodes
|
||||
///
|
||||
/// `AdwOverlaySplitView` has a single CSS node with the name
|
||||
/// `overlay-split-view`.
|
||||
///
|
||||
/// It contains two nodes with the name `widget`, containing the sidebar and
|
||||
/// content children.
|
||||
///
|
||||
/// When not collapsed, they have the `.sidebar-view` and `.content-view` style
|
||||
/// classes respectively.
|
||||
///
|
||||
/// ```
|
||||
/// overlay-split-view
|
||||
/// ├── widget.sidebar-pane
|
||||
/// │ ╰── [sidebar child]
|
||||
/// ╰── widget.content-pane
|
||||
/// ╰── [content child]
|
||||
/// ```
|
||||
///
|
||||
/// When collapsed, the one containing the sidebar child has the `.background`
|
||||
/// style class and the other one has no style classes.
|
||||
///
|
||||
/// ```
|
||||
/// overlay-split-view
|
||||
/// ├── widget.background
|
||||
/// │ ╰── [sidebar child]
|
||||
/// ╰── widget
|
||||
/// ╰── [content child]
|
||||
/// ```
|
||||
///
|
||||
/// ## Accessibility
|
||||
///
|
||||
/// `AdwOverlaySplitView` uses the `GTK_ACCESSIBLE_ROLE_GROUP` role.
|
||||
public struct OverlaySplitView: Widget {
|
||||
|
||||
/// Additional update functions for type extensions.
|
||||
var updateFunctions: [(ViewStorage) -> Void] = []
|
||||
/// Additional appear functions for type extensions.
|
||||
var appearFunctions: [(ViewStorage) -> Void] = []
|
||||
|
||||
/// Whether the split view is collapsed.
|
||||
///
|
||||
/// When collapsed, the sidebar widget is presented as an overlay above the
|
||||
/// content widget, otherwise they are displayed side by side.
|
||||
var collapsed: Bool?
|
||||
/// The content widget.
|
||||
var content: (() -> Body)?
|
||||
/// Whether the sidebar can be closed with a swipe gesture.
|
||||
///
|
||||
/// Only touchscreen swipes are supported.
|
||||
var enableHideGesture: Bool?
|
||||
/// Whether the sidebar can be opened with an edge swipe gesture.
|
||||
///
|
||||
/// Only touchscreen swipes are supported.
|
||||
var enableShowGesture: Bool?
|
||||
/// The maximum sidebar width.
|
||||
///
|
||||
/// Maximum width is affected by
|
||||
/// [property@OverlaySplitView:sidebar-width-unit].
|
||||
///
|
||||
/// The sidebar widget can still be allocated with larger width if its own
|
||||
/// minimum width exceeds it.
|
||||
var maxSidebarWidth: Double?
|
||||
/// The minimum sidebar width.
|
||||
///
|
||||
/// Minimum width is affected by
|
||||
/// [property@OverlaySplitView:sidebar-width-unit].
|
||||
///
|
||||
/// The sidebar widget can still be allocated with larger width if its own
|
||||
/// minimum width exceeds it.
|
||||
var minSidebarWidth: Double?
|
||||
/// Whether the sidebar widget is pinned.
|
||||
///
|
||||
/// By default, collapsing @self automatically hides the sidebar widget, and
|
||||
/// uncollapsing it shows the sidebar. If set to `TRUE`, sidebar visibility
|
||||
/// never changes on its own.
|
||||
var pinSidebar: Bool?
|
||||
/// Whether the sidebar widget is shown.
|
||||
var showSidebar: Binding<Bool>?
|
||||
/// The sidebar widget.
|
||||
var sidebar: (() -> Body)?
|
||||
/// The preferred sidebar width as a fraction of the total width.
|
||||
///
|
||||
/// The preferred width is additionally limited by
|
||||
/// [property@OverlaySplitView:min-sidebar-width] and
|
||||
/// [property@OverlaySplitView:max-sidebar-width].
|
||||
///
|
||||
/// The sidebar widget can be allocated with larger width if its own minimum
|
||||
/// width exceeds the preferred width.
|
||||
var sidebarWidthFraction: Double?
|
||||
/// The application.
|
||||
var app: GTUIApp?
|
||||
/// The window.
|
||||
var window: GTUIApplicationWindow?
|
||||
|
||||
/// Initialize `OverlaySplitView`.
|
||||
public init() {
|
||||
}
|
||||
|
||||
/// Get the widget's view storage.
|
||||
/// - Parameter modifiers: The view modifiers.
|
||||
/// - Returns: The view storage.
|
||||
public func container(modifiers: [(View) -> View]) -> ViewStorage {
|
||||
let storage = ViewStorage(adw_overlay_split_view_new()?.opaque())
|
||||
update(storage, modifiers: modifiers)
|
||||
if let contentStorage = content?().widget(modifiers: modifiers).storage(modifiers: modifiers) {
|
||||
storage.content["content"] = [contentStorage]
|
||||
adw_overlay_split_view_set_content(storage.pointer, contentStorage.pointer?.cast())
|
||||
}
|
||||
if let sidebarStorage = sidebar?().widget(modifiers: modifiers).storage(modifiers: modifiers) {
|
||||
storage.content["sidebar"] = [sidebarStorage]
|
||||
adw_overlay_split_view_set_sidebar(storage.pointer, sidebarStorage.pointer?.cast())
|
||||
}
|
||||
|
||||
|
||||
storage.notify(name: "show-sidebar") {
|
||||
showSidebar?.wrappedValue = adw_overlay_split_view_get_show_sidebar(storage.pointer) != 0
|
||||
}
|
||||
for function in appearFunctions {
|
||||
function(storage)
|
||||
}
|
||||
return storage
|
||||
}
|
||||
|
||||
/// Update the widget's view storage.
|
||||
/// - Parameters:
|
||||
/// - storage: The view storage.
|
||||
/// - modifiers: The view modifiers.
|
||||
public func update(_ storage: ViewStorage, modifiers: [(View) -> View]) {
|
||||
storage.modify { widget in
|
||||
if let collapsed {
|
||||
adw_overlay_split_view_set_collapsed(widget, collapsed.cBool)
|
||||
}
|
||||
if let widget = storage.content["content"]?.first {
|
||||
content?().widget(modifiers: modifiers).update(widget, modifiers: modifiers)
|
||||
}
|
||||
if let enableHideGesture {
|
||||
adw_overlay_split_view_set_enable_hide_gesture(widget, enableHideGesture.cBool)
|
||||
}
|
||||
if let enableShowGesture {
|
||||
adw_overlay_split_view_set_enable_show_gesture(widget, enableShowGesture.cBool)
|
||||
}
|
||||
if let maxSidebarWidth {
|
||||
adw_overlay_split_view_set_max_sidebar_width(widget, maxSidebarWidth)
|
||||
}
|
||||
if let minSidebarWidth {
|
||||
adw_overlay_split_view_set_min_sidebar_width(widget, minSidebarWidth)
|
||||
}
|
||||
if let pinSidebar {
|
||||
adw_overlay_split_view_set_pin_sidebar(widget, pinSidebar.cBool)
|
||||
}
|
||||
if let showSidebar {
|
||||
adw_overlay_split_view_set_show_sidebar(widget, showSidebar.wrappedValue.cBool)
|
||||
}
|
||||
if let widget = storage.content["sidebar"]?.first {
|
||||
sidebar?().widget(modifiers: modifiers).update(widget, modifiers: modifiers)
|
||||
}
|
||||
if let sidebarWidthFraction {
|
||||
adw_overlay_split_view_set_sidebar_width_fraction(widget, sidebarWidthFraction)
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
for function in updateFunctions {
|
||||
function(storage)
|
||||
}
|
||||
}
|
||||
|
||||
/// Whether the split view is collapsed.
|
||||
///
|
||||
/// When collapsed, the sidebar widget is presented as an overlay above the
|
||||
/// content widget, otherwise they are displayed side by side.
|
||||
public func collapsed(_ collapsed: Bool? = true) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.collapsed = collapsed
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// The content widget.
|
||||
public func content(@ViewBuilder _ content: @escaping (() -> Body)) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.content = content
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// Whether the sidebar can be closed with a swipe gesture.
|
||||
///
|
||||
/// Only touchscreen swipes are supported.
|
||||
public func enableHideGesture(_ enableHideGesture: Bool? = true) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.enableHideGesture = enableHideGesture
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// Whether the sidebar can be opened with an edge swipe gesture.
|
||||
///
|
||||
/// Only touchscreen swipes are supported.
|
||||
public func enableShowGesture(_ enableShowGesture: Bool? = true) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.enableShowGesture = enableShowGesture
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// The maximum sidebar width.
|
||||
///
|
||||
/// Maximum width is affected by
|
||||
/// [property@OverlaySplitView:sidebar-width-unit].
|
||||
///
|
||||
/// The sidebar widget can still be allocated with larger width if its own
|
||||
/// minimum width exceeds it.
|
||||
public func maxSidebarWidth(_ maxSidebarWidth: Double?) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.maxSidebarWidth = maxSidebarWidth
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// The minimum sidebar width.
|
||||
///
|
||||
/// Minimum width is affected by
|
||||
/// [property@OverlaySplitView:sidebar-width-unit].
|
||||
///
|
||||
/// The sidebar widget can still be allocated with larger width if its own
|
||||
/// minimum width exceeds it.
|
||||
public func minSidebarWidth(_ minSidebarWidth: Double?) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.minSidebarWidth = minSidebarWidth
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// Whether the sidebar widget is pinned.
|
||||
///
|
||||
/// By default, collapsing @self automatically hides the sidebar widget, and
|
||||
/// uncollapsing it shows the sidebar. If set to `TRUE`, sidebar visibility
|
||||
/// never changes on its own.
|
||||
public func pinSidebar(_ pinSidebar: Bool? = true) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.pinSidebar = pinSidebar
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// Whether the sidebar widget is shown.
|
||||
public func showSidebar(_ showSidebar: Binding<Bool>?) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.showSidebar = showSidebar
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// The sidebar widget.
|
||||
public func sidebar(@ViewBuilder _ sidebar: @escaping (() -> Body)) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.sidebar = sidebar
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// The preferred sidebar width as a fraction of the total width.
|
||||
///
|
||||
/// The preferred width is additionally limited by
|
||||
/// [property@OverlaySplitView:min-sidebar-width] and
|
||||
/// [property@OverlaySplitView:max-sidebar-width].
|
||||
///
|
||||
/// The sidebar widget can be allocated with larger width if its own minimum
|
||||
/// width exceeds the preferred width.
|
||||
public func sidebarWidthFraction(_ sidebarWidthFraction: Double?) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.sidebarWidthFraction = sidebarWidthFraction
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
}
|
248
Sources/Adwaita/View/Generated/PasswordEntryRow.swift
Normal file
248
Sources/Adwaita/View/Generated/PasswordEntryRow.swift
Normal file
@ -0,0 +1,248 @@
|
||||
//
|
||||
// PasswordEntryRow.swift
|
||||
// Adwaita
|
||||
//
|
||||
// Created by auto-generation on 22.01.24.
|
||||
//
|
||||
|
||||
import CAdw
|
||||
import LevenshteinTransformations
|
||||
|
||||
/// A [class@EntryRow] tailored for entering secrets.
|
||||
///
|
||||
/// <picture><source srcset="password-entry-row-dark.png" media="(prefers-color-scheme: dark)"><img src="password-entry-row.png" alt="password-entry-row"></picture>
|
||||
///
|
||||
/// It does not show its contents in clear text, does not allow to copy it to the
|
||||
/// clipboard, and shows a warning when Caps Lock is engaged. If the underlying
|
||||
/// platform allows it, `AdwPasswordEntryRow` will also place the text in a
|
||||
/// non-pageable memory area, to avoid it being written out to disk by the
|
||||
/// operating system.
|
||||
///
|
||||
/// It offer a way to reveal the contents in clear text.
|
||||
///
|
||||
/// ## CSS Nodes
|
||||
///
|
||||
/// `AdwPasswordEntryRow` has a single CSS node with name `row` that carries
|
||||
/// `.entry` and `.password` style classes.
|
||||
public struct PasswordEntryRow: Widget {
|
||||
|
||||
/// Additional update functions for type extensions.
|
||||
var updateFunctions: [(ViewStorage) -> Void] = []
|
||||
/// Additional appear functions for type extensions.
|
||||
var appearFunctions: [(ViewStorage) -> Void] = []
|
||||
|
||||
/// Whether activating the embedded entry can activate the default widget.
|
||||
var activatesDefault: Bool?
|
||||
/// Whether to suggest emoji replacements on the entry row.
|
||||
///
|
||||
/// Emoji replacement is done with :-delimited names, like `:heart:`.
|
||||
var enableEmojiCompletion: Bool?
|
||||
/// Whether to show the apply button.
|
||||
///
|
||||
/// When set to `TRUE`, typing text in the entry will reveal an apply button.
|
||||
/// Clicking it or pressing the <kbd>Enter</kbd> key will hide the button and
|
||||
/// emit the [signal@EntryRow::apply] signal.
|
||||
///
|
||||
/// This is useful if changing the entry contents can trigger an expensive
|
||||
/// operation, e.g. network activity, to avoid triggering it after typing every
|
||||
/// character.
|
||||
var showApplyButton: Bool?
|
||||
/// The title of the preference represented by this row.
|
||||
///
|
||||
/// The title is interpreted as Pango markup unless
|
||||
/// [property@PreferencesRow:use-markup] is set to `FALSE`.
|
||||
var title: String?
|
||||
/// Whether the user can copy the title from the label.
|
||||
///
|
||||
/// See also [property@Gtk.Label:selectable].
|
||||
var titleSelectable: Bool?
|
||||
/// Whether to use Pango markup for the title label.
|
||||
///
|
||||
/// Subclasses may also use it for other labels, such as subtitle.
|
||||
///
|
||||
/// See also [func@Pango.parse_markup].
|
||||
var useMarkup: Bool?
|
||||
/// Whether an embedded underline in the title indicates a mnemonic.
|
||||
var useUnderline: Bool?
|
||||
/// Emitted when the apply button is pressed.
|
||||
///
|
||||
/// See [property@EntryRow:show-apply-button].
|
||||
var apply: (() -> Void)?
|
||||
/// Emitted when the embedded entry is activated.
|
||||
var entryActivated: (() -> Void)?
|
||||
/// The body for the widget "suffix".
|
||||
var suffix: () -> Body = { [] }
|
||||
/// The body for the widget "prefix".
|
||||
var prefix: () -> Body = { [] }
|
||||
/// The application.
|
||||
var app: GTUIApp?
|
||||
/// The window.
|
||||
var window: GTUIApplicationWindow?
|
||||
|
||||
/// Initialize `PasswordEntryRow`.
|
||||
public init() {
|
||||
}
|
||||
|
||||
/// Get the widget's view storage.
|
||||
/// - Parameter modifiers: The view modifiers.
|
||||
/// - Returns: The view storage.
|
||||
public func container(modifiers: [(View) -> View]) -> ViewStorage {
|
||||
let storage = ViewStorage(adw_password_entry_row_new()?.opaque())
|
||||
update(storage, modifiers: modifiers)
|
||||
|
||||
var suffixStorage: [ViewStorage] = []
|
||||
for view in suffix() {
|
||||
suffixStorage.append(view.storage(modifiers: modifiers))
|
||||
adw_entry_row_add_suffix(storage.pointer?.cast(), suffixStorage.last?.pointer?.cast())
|
||||
}
|
||||
storage.content["suffix"] = suffixStorage
|
||||
var prefixStorage: [ViewStorage] = []
|
||||
for view in prefix() {
|
||||
prefixStorage.append(view.storage(modifiers: modifiers))
|
||||
adw_entry_row_add_prefix(storage.pointer?.cast(), prefixStorage.last?.pointer?.cast())
|
||||
}
|
||||
storage.content["prefix"] = prefixStorage
|
||||
|
||||
for function in appearFunctions {
|
||||
function(storage)
|
||||
}
|
||||
return storage
|
||||
}
|
||||
|
||||
/// Update the widget's view storage.
|
||||
/// - Parameters:
|
||||
/// - storage: The view storage.
|
||||
/// - modifiers: The view modifiers.
|
||||
public func update(_ storage: ViewStorage, modifiers: [(View) -> View]) {
|
||||
if let apply {
|
||||
storage.connectSignal(name: "apply") {
|
||||
apply()
|
||||
}
|
||||
}
|
||||
if let entryActivated {
|
||||
storage.connectSignal(name: "entry-activated") {
|
||||
entryActivated()
|
||||
}
|
||||
}
|
||||
storage.modify { widget in
|
||||
if let activatesDefault {
|
||||
adw_entry_row_set_activates_default(widget?.cast(), activatesDefault.cBool)
|
||||
}
|
||||
if let enableEmojiCompletion {
|
||||
adw_entry_row_set_enable_emoji_completion(widget?.cast(), enableEmojiCompletion.cBool)
|
||||
}
|
||||
if let showApplyButton {
|
||||
adw_entry_row_set_show_apply_button(widget?.cast(), showApplyButton.cBool)
|
||||
}
|
||||
if let title {
|
||||
adw_preferences_row_set_title(widget?.cast(), title)
|
||||
}
|
||||
if let titleSelectable {
|
||||
adw_preferences_row_set_title_selectable(widget?.cast(), titleSelectable.cBool)
|
||||
}
|
||||
if let useMarkup {
|
||||
adw_preferences_row_set_use_markup(widget?.cast(), useMarkup.cBool)
|
||||
}
|
||||
if let useUnderline {
|
||||
adw_preferences_row_set_use_underline(widget?.cast(), useUnderline.cBool)
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
for function in updateFunctions {
|
||||
function(storage)
|
||||
}
|
||||
}
|
||||
|
||||
/// Whether activating the embedded entry can activate the default widget.
|
||||
public func activatesDefault(_ activatesDefault: Bool? = true) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.activatesDefault = activatesDefault
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// Whether to suggest emoji replacements on the entry row.
|
||||
///
|
||||
/// Emoji replacement is done with :-delimited names, like `:heart:`.
|
||||
public func enableEmojiCompletion(_ enableEmojiCompletion: Bool? = true) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.enableEmojiCompletion = enableEmojiCompletion
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// Whether to show the apply button.
|
||||
///
|
||||
/// When set to `TRUE`, typing text in the entry will reveal an apply button.
|
||||
/// Clicking it or pressing the <kbd>Enter</kbd> key will hide the button and
|
||||
/// emit the [signal@EntryRow::apply] signal.
|
||||
///
|
||||
/// This is useful if changing the entry contents can trigger an expensive
|
||||
/// operation, e.g. network activity, to avoid triggering it after typing every
|
||||
/// character.
|
||||
public func showApplyButton(_ showApplyButton: Bool? = true) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.showApplyButton = showApplyButton
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// The title of the preference represented by this row.
|
||||
///
|
||||
/// The title is interpreted as Pango markup unless
|
||||
/// [property@PreferencesRow:use-markup] is set to `FALSE`.
|
||||
public func title(_ title: String?) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.title = title
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// Whether the user can copy the title from the label.
|
||||
///
|
||||
/// See also [property@Gtk.Label:selectable].
|
||||
public func titleSelectable(_ titleSelectable: Bool? = true) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.titleSelectable = titleSelectable
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// Whether to use Pango markup for the title label.
|
||||
///
|
||||
/// Subclasses may also use it for other labels, such as subtitle.
|
||||
///
|
||||
/// See also [func@Pango.parse_markup].
|
||||
public func useMarkup(_ useMarkup: Bool? = true) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.useMarkup = useMarkup
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// Whether an embedded underline in the title indicates a mnemonic.
|
||||
public func useUnderline(_ useUnderline: Bool? = true) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.useUnderline = useUnderline
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// Emitted when the apply button is pressed.
|
||||
///
|
||||
/// See [property@EntryRow:show-apply-button].
|
||||
public func apply(_ apply: @escaping () -> Void) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.apply = apply
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// Emitted when the embedded entry is activated.
|
||||
public func entryActivated(_ entryActivated: @escaping () -> Void) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.entryActivated = entryActivated
|
||||
return newSelf
|
||||
}
|
||||
|
||||
}
|
159
Sources/Adwaita/View/Generated/PreferencesGroup.swift
Normal file
159
Sources/Adwaita/View/Generated/PreferencesGroup.swift
Normal file
@ -0,0 +1,159 @@
|
||||
//
|
||||
// PreferencesGroup.swift
|
||||
// Adwaita
|
||||
//
|
||||
// Created by auto-generation on 22.01.24.
|
||||
//
|
||||
|
||||
import CAdw
|
||||
import LevenshteinTransformations
|
||||
|
||||
/// A group of preference rows.
|
||||
///
|
||||
/// <picture><source srcset="preferences-group-dark.png" media="(prefers-color-scheme: dark)"><img src="preferences-group.png" alt="preferences-group"></picture>
|
||||
///
|
||||
/// An `AdwPreferencesGroup` represents a group or tightly related preferences,
|
||||
/// which in turn are represented by [class@PreferencesRow].
|
||||
///
|
||||
/// To summarize the role of the preferences it gathers, a group can have both a
|
||||
/// title and a description. The title will be used by [class@PreferencesWindow]
|
||||
/// to let the user look for a preference.
|
||||
///
|
||||
/// ## AdwPreferencesGroup as GtkBuildable
|
||||
///
|
||||
/// The `AdwPreferencesGroup` implementation of the [iface@Gtk.Buildable] interface
|
||||
/// supports adding [class@PreferencesRow]s to the list by omitting "type". If "type"
|
||||
/// is omitted and the widget isn't a [class@PreferencesRow] the child is added to
|
||||
/// a box below the list.
|
||||
///
|
||||
/// When the "type" attribute of a child is `header-suffix`, the child
|
||||
/// is set as the suffix on the end of the title and description.
|
||||
///
|
||||
/// ## CSS nodes
|
||||
///
|
||||
/// `AdwPreferencesGroup` has a single CSS node with name `preferencesgroup`.
|
||||
///
|
||||
/// ## Accessibility
|
||||
///
|
||||
/// `AdwPreferencesGroup` uses the `GTK_ACCESSIBLE_ROLE_GROUP` role.
|
||||
public struct PreferencesGroup: Widget {
|
||||
|
||||
/// Additional update functions for type extensions.
|
||||
var updateFunctions: [(ViewStorage) -> Void] = []
|
||||
/// Additional appear functions for type extensions.
|
||||
var appearFunctions: [(ViewStorage) -> Void] = []
|
||||
|
||||
/// The description for this group of preferences.
|
||||
var description: String?
|
||||
/// The header suffix widget.
|
||||
///
|
||||
/// Displayed above the list, next to the title and description.
|
||||
///
|
||||
/// Suffixes are commonly used to show a button or a spinner for the whole
|
||||
/// group.
|
||||
var headerSuffix: (() -> Body)?
|
||||
/// The title for this group of preferences.
|
||||
var title: String?
|
||||
/// The body for the widget "child".
|
||||
var child: () -> Body = { [] }
|
||||
/// The application.
|
||||
var app: GTUIApp?
|
||||
/// The window.
|
||||
var window: GTUIApplicationWindow?
|
||||
|
||||
/// Initialize `PreferencesGroup`.
|
||||
public init() {
|
||||
}
|
||||
|
||||
/// Get the widget's view storage.
|
||||
/// - Parameter modifiers: The view modifiers.
|
||||
/// - Returns: The view storage.
|
||||
public func container(modifiers: [(View) -> View]) -> ViewStorage {
|
||||
let storage = ViewStorage(adw_preferences_group_new()?.opaque())
|
||||
update(storage, modifiers: modifiers)
|
||||
if let headerSuffixStorage = headerSuffix?().widget(modifiers: modifiers).storage(modifiers: modifiers) {
|
||||
storage.content["headerSuffix"] = [headerSuffixStorage]
|
||||
adw_preferences_group_set_header_suffix(storage.pointer?.cast(), headerSuffixStorage.pointer?.cast())
|
||||
}
|
||||
|
||||
var childStorage: [ViewStorage] = []
|
||||
for view in child() {
|
||||
childStorage.append(view.storage(modifiers: modifiers))
|
||||
adw_preferences_group_add(storage.pointer?.cast(), childStorage.last?.pointer?.cast())
|
||||
}
|
||||
storage.content["child"] = childStorage
|
||||
|
||||
for function in appearFunctions {
|
||||
function(storage)
|
||||
}
|
||||
return storage
|
||||
}
|
||||
|
||||
/// Update the widget's view storage.
|
||||
/// - Parameters:
|
||||
/// - storage: The view storage.
|
||||
/// - modifiers: The view modifiers.
|
||||
public func update(_ storage: ViewStorage, modifiers: [(View) -> View]) {
|
||||
storage.modify { widget in
|
||||
if let description {
|
||||
adw_preferences_group_set_description(widget?.cast(), description)
|
||||
}
|
||||
if let widget = storage.content["headerSuffix"]?.first {
|
||||
headerSuffix?().widget(modifiers: modifiers).update(widget, modifiers: modifiers)
|
||||
}
|
||||
if let title {
|
||||
adw_preferences_group_set_title(widget?.cast(), title)
|
||||
}
|
||||
|
||||
if let childStorage = storage.content["child"] {
|
||||
for (index, view) in child().enumerated() {
|
||||
if let storage = childStorage[safe: index] {
|
||||
view.updateStorage(storage, modifiers: modifiers)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
for function in updateFunctions {
|
||||
function(storage)
|
||||
}
|
||||
}
|
||||
|
||||
/// The description for this group of preferences.
|
||||
public func description(_ description: String?) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.description = description
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// The header suffix widget.
|
||||
///
|
||||
/// Displayed above the list, next to the title and description.
|
||||
///
|
||||
/// Suffixes are commonly used to show a button or a spinner for the whole
|
||||
/// group.
|
||||
public func headerSuffix(@ViewBuilder _ headerSuffix: @escaping (() -> Body)) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.headerSuffix = headerSuffix
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// The title for this group of preferences.
|
||||
public func title(_ title: String?) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.title = title
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// Set the body for "child".
|
||||
/// - Parameter body: The body.
|
||||
/// - Returns: The widget.
|
||||
public func child(@ViewBuilder _ body: @escaping () -> Body) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.child = body
|
||||
return newSelf
|
||||
}
|
||||
}
|
157
Sources/Adwaita/View/Generated/PreferencesPage.swift
Normal file
157
Sources/Adwaita/View/Generated/PreferencesPage.swift
Normal file
@ -0,0 +1,157 @@
|
||||
//
|
||||
// PreferencesPage.swift
|
||||
// Adwaita
|
||||
//
|
||||
// Created by auto-generation on 22.01.24.
|
||||
//
|
||||
|
||||
import CAdw
|
||||
import LevenshteinTransformations
|
||||
|
||||
/// A page from [class@PreferencesWindow].
|
||||
///
|
||||
/// <picture><source srcset="preferences-page-dark.png" media="(prefers-color-scheme: dark)"><img src="preferences-page.png" alt="preferences-page"></picture>
|
||||
///
|
||||
/// The `AdwPreferencesPage` widget gathers preferences groups into a single page
|
||||
/// of a preferences window.
|
||||
///
|
||||
/// ## CSS nodes
|
||||
///
|
||||
/// `AdwPreferencesPage` has a single CSS node with name `preferencespage`.
|
||||
///
|
||||
/// ## Accessibility
|
||||
///
|
||||
/// `AdwPreferencesPage` uses the `GTK_ACCESSIBLE_ROLE_GROUP` role.
|
||||
public struct PreferencesPage: Widget {
|
||||
|
||||
/// Additional update functions for type extensions.
|
||||
var updateFunctions: [(ViewStorage) -> Void] = []
|
||||
/// Additional appear functions for type extensions.
|
||||
var appearFunctions: [(ViewStorage) -> Void] = []
|
||||
|
||||
/// The description to be displayed at the top of the page.
|
||||
var description: String?
|
||||
/// The icon name for this page.
|
||||
var iconName: String?
|
||||
/// The name of this page.
|
||||
var name: String?
|
||||
/// The title for this page.
|
||||
var title: String?
|
||||
/// Whether an embedded underline in the title indicates a mnemonic.
|
||||
var useUnderline: Bool?
|
||||
/// The body for the widget "child".
|
||||
var child: () -> Body = { [] }
|
||||
/// The application.
|
||||
var app: GTUIApp?
|
||||
/// The window.
|
||||
var window: GTUIApplicationWindow?
|
||||
|
||||
/// Initialize `PreferencesPage`.
|
||||
public init() {
|
||||
}
|
||||
|
||||
/// Get the widget's view storage.
|
||||
/// - Parameter modifiers: The view modifiers.
|
||||
/// - Returns: The view storage.
|
||||
public func container(modifiers: [(View) -> View]) -> ViewStorage {
|
||||
let storage = ViewStorage(adw_preferences_page_new()?.opaque())
|
||||
update(storage, modifiers: modifiers)
|
||||
|
||||
var childStorage: [ViewStorage] = []
|
||||
for view in child() {
|
||||
childStorage.append(view.storage(modifiers: modifiers))
|
||||
adw_preferences_group_add(storage.pointer?.cast(), childStorage.last?.pointer?.cast())
|
||||
}
|
||||
storage.content["child"] = childStorage
|
||||
|
||||
for function in appearFunctions {
|
||||
function(storage)
|
||||
}
|
||||
return storage
|
||||
}
|
||||
|
||||
/// Update the widget's view storage.
|
||||
/// - Parameters:
|
||||
/// - storage: The view storage.
|
||||
/// - modifiers: The view modifiers.
|
||||
public func update(_ storage: ViewStorage, modifiers: [(View) -> View]) {
|
||||
storage.modify { widget in
|
||||
if let description {
|
||||
adw_preferences_page_set_description(widget?.cast(), description)
|
||||
}
|
||||
if let iconName {
|
||||
adw_preferences_page_set_icon_name(widget?.cast(), iconName)
|
||||
}
|
||||
if let name {
|
||||
adw_preferences_page_set_name(widget?.cast(), name)
|
||||
}
|
||||
if let title {
|
||||
adw_preferences_page_set_title(widget?.cast(), title)
|
||||
}
|
||||
if let useUnderline {
|
||||
adw_preferences_page_set_use_underline(widget?.cast(), useUnderline.cBool)
|
||||
}
|
||||
|
||||
if let childStorage = storage.content["child"] {
|
||||
for (index, view) in child().enumerated() {
|
||||
if let storage = childStorage[safe: index] {
|
||||
view.updateStorage(storage, modifiers: modifiers)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
for function in updateFunctions {
|
||||
function(storage)
|
||||
}
|
||||
}
|
||||
|
||||
/// The description to be displayed at the top of the page.
|
||||
public func description(_ description: String?) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.description = description
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// The icon name for this page.
|
||||
public func iconName(_ iconName: String?) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.iconName = iconName
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// The name of this page.
|
||||
public func name(_ name: String?) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.name = name
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// The title for this page.
|
||||
public func title(_ title: String?) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.title = title
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// Whether an embedded underline in the title indicates a mnemonic.
|
||||
public func useUnderline(_ useUnderline: Bool? = true) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.useUnderline = useUnderline
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// Set the body for "child".
|
||||
/// - Parameter body: The body.
|
||||
/// - Returns: The widget.
|
||||
public func child(@ViewBuilder _ body: @escaping () -> Body) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.child = body
|
||||
return newSelf
|
||||
}
|
||||
}
|
134
Sources/Adwaita/View/Generated/PreferencesRow.swift
Normal file
134
Sources/Adwaita/View/Generated/PreferencesRow.swift
Normal file
@ -0,0 +1,134 @@
|
||||
//
|
||||
// PreferencesRow.swift
|
||||
// Adwaita
|
||||
//
|
||||
// Created by auto-generation on 22.01.24.
|
||||
//
|
||||
|
||||
import CAdw
|
||||
import LevenshteinTransformations
|
||||
|
||||
/// A [class@Gtk.ListBoxRow] used to present preferences.
|
||||
///
|
||||
/// The `AdwPreferencesRow` widget has a title that [class@PreferencesWindow]
|
||||
/// will use to let the user look for a preference. It doesn't present the title
|
||||
/// in any way and lets you present the preference as you please.
|
||||
///
|
||||
/// [class@ActionRow] and its derivatives are convenient to use as preference
|
||||
/// rows as they take care of presenting the preference's title while letting you
|
||||
/// compose the inputs of the preference around it.
|
||||
public struct PreferencesRow: Widget {
|
||||
|
||||
/// Additional update functions for type extensions.
|
||||
var updateFunctions: [(ViewStorage) -> Void] = []
|
||||
/// Additional appear functions for type extensions.
|
||||
var appearFunctions: [(ViewStorage) -> Void] = []
|
||||
|
||||
/// The title of the preference represented by this row.
|
||||
///
|
||||
/// The title is interpreted as Pango markup unless
|
||||
/// [property@PreferencesRow:use-markup] is set to `FALSE`.
|
||||
var title: String?
|
||||
/// Whether the user can copy the title from the label.
|
||||
///
|
||||
/// See also [property@Gtk.Label:selectable].
|
||||
var titleSelectable: Bool?
|
||||
/// Whether to use Pango markup for the title label.
|
||||
///
|
||||
/// Subclasses may also use it for other labels, such as subtitle.
|
||||
///
|
||||
/// See also [func@Pango.parse_markup].
|
||||
var useMarkup: Bool?
|
||||
/// Whether an embedded underline in the title indicates a mnemonic.
|
||||
var useUnderline: Bool?
|
||||
/// The application.
|
||||
var app: GTUIApp?
|
||||
/// The window.
|
||||
var window: GTUIApplicationWindow?
|
||||
|
||||
/// Initialize `PreferencesRow`.
|
||||
public init() {
|
||||
}
|
||||
|
||||
/// Get the widget's view storage.
|
||||
/// - Parameter modifiers: The view modifiers.
|
||||
/// - Returns: The view storage.
|
||||
public func container(modifiers: [(View) -> View]) -> ViewStorage {
|
||||
let storage = ViewStorage(adw_preferences_row_new()?.opaque())
|
||||
update(storage, modifiers: modifiers)
|
||||
|
||||
|
||||
for function in appearFunctions {
|
||||
function(storage)
|
||||
}
|
||||
return storage
|
||||
}
|
||||
|
||||
/// Update the widget's view storage.
|
||||
/// - Parameters:
|
||||
/// - storage: The view storage.
|
||||
/// - modifiers: The view modifiers.
|
||||
public func update(_ storage: ViewStorage, modifiers: [(View) -> View]) {
|
||||
storage.modify { widget in
|
||||
if let title {
|
||||
adw_preferences_row_set_title(widget?.cast(), title)
|
||||
}
|
||||
if let titleSelectable {
|
||||
adw_preferences_row_set_title_selectable(widget?.cast(), titleSelectable.cBool)
|
||||
}
|
||||
if let useMarkup {
|
||||
adw_preferences_row_set_use_markup(widget?.cast(), useMarkup.cBool)
|
||||
}
|
||||
if let useUnderline {
|
||||
adw_preferences_row_set_use_underline(widget?.cast(), useUnderline.cBool)
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
for function in updateFunctions {
|
||||
function(storage)
|
||||
}
|
||||
}
|
||||
|
||||
/// The title of the preference represented by this row.
|
||||
///
|
||||
/// The title is interpreted as Pango markup unless
|
||||
/// [property@PreferencesRow:use-markup] is set to `FALSE`.
|
||||
public func title(_ title: String?) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.title = title
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// Whether the user can copy the title from the label.
|
||||
///
|
||||
/// See also [property@Gtk.Label:selectable].
|
||||
public func titleSelectable(_ titleSelectable: Bool? = true) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.titleSelectable = titleSelectable
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// Whether to use Pango markup for the title label.
|
||||
///
|
||||
/// Subclasses may also use it for other labels, such as subtitle.
|
||||
///
|
||||
/// See also [func@Pango.parse_markup].
|
||||
public func useMarkup(_ useMarkup: Bool? = true) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.useMarkup = useMarkup
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// Whether an embedded underline in the title indicates a mnemonic.
|
||||
public func useUnderline(_ useUnderline: Bool? = true) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.useUnderline = useUnderline
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
}
|
184
Sources/Adwaita/View/Generated/ProgressBar.swift
Normal file
184
Sources/Adwaita/View/Generated/ProgressBar.swift
Normal file
@ -0,0 +1,184 @@
|
||||
//
|
||||
// ProgressBar.swift
|
||||
// Adwaita
|
||||
//
|
||||
// Created by auto-generation on 22.01.24.
|
||||
//
|
||||
|
||||
import CAdw
|
||||
import LevenshteinTransformations
|
||||
|
||||
/// `GtkProgressBar` is typically used to display the progress of a long
|
||||
/// running operation.
|
||||
///
|
||||
/// It provides a visual clue that processing is underway. `GtkProgressBar`
|
||||
/// can be used in two different modes: percentage mode and activity mode.
|
||||
///
|
||||
/// ![An example GtkProgressBar](progressbar.png)
|
||||
///
|
||||
/// When an application can determine how much work needs to take place
|
||||
/// (e.g. read a fixed number of bytes from a file) and can monitor its
|
||||
/// progress, it can use the `GtkProgressBar` in percentage mode and the
|
||||
/// user sees a growing bar indicating the percentage of the work that
|
||||
/// has been completed. In this mode, the application is required to call
|
||||
/// [method@Gtk.ProgressBar.set_fraction] periodically to update the progress bar.
|
||||
///
|
||||
/// When an application has no accurate way of knowing the amount of work
|
||||
/// to do, it can use the `GtkProgressBar` in activity mode, which shows
|
||||
/// activity by a block moving back and forth within the progress area. In
|
||||
/// this mode, the application is required to call [method@Gtk.ProgressBar.pulse]
|
||||
/// periodically to update the progress bar.
|
||||
///
|
||||
/// There is quite a bit of flexibility provided to control the appearance
|
||||
/// of the `GtkProgressBar`. Functions are provided to control the orientation
|
||||
/// of the bar, optional text can be displayed along with the bar, and the
|
||||
/// step size used in activity mode can be set.
|
||||
///
|
||||
/// # CSS nodes
|
||||
///
|
||||
/// ```
|
||||
/// progressbar[.osd]
|
||||
/// ├── [text]
|
||||
/// ╰── trough[.empty][.full]
|
||||
/// ╰── progress[.pulse]
|
||||
/// ```
|
||||
///
|
||||
/// `GtkProgressBar` has a main CSS node with name progressbar and subnodes with
|
||||
/// names text and trough, of which the latter has a subnode named progress. The
|
||||
/// text subnode is only present if text is shown. The progress subnode has the
|
||||
/// style class .pulse when in activity mode. It gets the style classes .left,
|
||||
/// .right, .top or .bottom added when the progress 'touches' the corresponding
|
||||
/// end of the GtkProgressBar. The .osd class on the progressbar node is for use
|
||||
/// in overlays like the one Epiphany has for page loading progress.
|
||||
///
|
||||
/// # Accessibility
|
||||
///
|
||||
/// `GtkProgressBar` uses the %GTK_ACCESSIBLE_ROLE_PROGRESS_BAR role.
|
||||
public struct ProgressBar: Widget {
|
||||
|
||||
/// Additional update functions for type extensions.
|
||||
var updateFunctions: [(ViewStorage) -> Void] = []
|
||||
/// Additional appear functions for type extensions.
|
||||
var appearFunctions: [(ViewStorage) -> Void] = []
|
||||
|
||||
/// The fraction of total work that has been completed.
|
||||
var fraction: Double?
|
||||
/// Invert the direction in which the progress bar grows.
|
||||
var inverted: Bool?
|
||||
/// The fraction of total progress to move the bounding block when pulsed.
|
||||
var pulseStep: Double?
|
||||
/// Sets whether the progress bar will show a text in addition
|
||||
/// to the bar itself.
|
||||
///
|
||||
/// The shown text is either the value of the [property@Gtk.ProgressBar:text]
|
||||
/// property or, if that is %NULL, the [property@Gtk.ProgressBar:fraction]
|
||||
/// value, as a percentage.
|
||||
///
|
||||
/// To make a progress bar that is styled and sized suitably for showing text
|
||||
/// (even if the actual text is blank), set [property@Gtk.ProgressBar:show-text]
|
||||
/// to %TRUE and [property@Gtk.ProgressBar:text] to the empty string (not %NULL).
|
||||
var showText: Bool?
|
||||
/// Text to be displayed in the progress bar.
|
||||
var text: String?
|
||||
/// The application.
|
||||
var app: GTUIApp?
|
||||
/// The window.
|
||||
var window: GTUIApplicationWindow?
|
||||
|
||||
/// Initialize `ProgressBar`.
|
||||
public init() {
|
||||
}
|
||||
|
||||
/// Get the widget's view storage.
|
||||
/// - Parameter modifiers: The view modifiers.
|
||||
/// - Returns: The view storage.
|
||||
public func container(modifiers: [(View) -> View]) -> ViewStorage {
|
||||
let storage = ViewStorage(gtk_progress_bar_new()?.opaque())
|
||||
update(storage, modifiers: modifiers)
|
||||
|
||||
|
||||
for function in appearFunctions {
|
||||
function(storage)
|
||||
}
|
||||
return storage
|
||||
}
|
||||
|
||||
/// Update the widget's view storage.
|
||||
/// - Parameters:
|
||||
/// - storage: The view storage.
|
||||
/// - modifiers: The view modifiers.
|
||||
public func update(_ storage: ViewStorage, modifiers: [(View) -> View]) {
|
||||
storage.modify { widget in
|
||||
if let fraction {
|
||||
gtk_progress_bar_set_fraction(widget, fraction)
|
||||
}
|
||||
if let inverted {
|
||||
gtk_progress_bar_set_inverted(widget, inverted.cBool)
|
||||
}
|
||||
if let pulseStep {
|
||||
gtk_progress_bar_set_pulse_step(widget, pulseStep)
|
||||
}
|
||||
if let showText {
|
||||
gtk_progress_bar_set_show_text(widget, showText.cBool)
|
||||
}
|
||||
if let text {
|
||||
gtk_progress_bar_set_text(widget, text)
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
for function in updateFunctions {
|
||||
function(storage)
|
||||
}
|
||||
}
|
||||
|
||||
/// The fraction of total work that has been completed.
|
||||
public func fraction(_ fraction: Double?) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.fraction = fraction
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// Invert the direction in which the progress bar grows.
|
||||
public func inverted(_ inverted: Bool? = true) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.inverted = inverted
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// The fraction of total progress to move the bounding block when pulsed.
|
||||
public func pulseStep(_ pulseStep: Double?) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.pulseStep = pulseStep
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// Sets whether the progress bar will show a text in addition
|
||||
/// to the bar itself.
|
||||
///
|
||||
/// The shown text is either the value of the [property@Gtk.ProgressBar:text]
|
||||
/// property or, if that is %NULL, the [property@Gtk.ProgressBar:fraction]
|
||||
/// value, as a percentage.
|
||||
///
|
||||
/// To make a progress bar that is styled and sized suitably for showing text
|
||||
/// (even if the actual text is blank), set [property@Gtk.ProgressBar:show-text]
|
||||
/// to %TRUE and [property@Gtk.ProgressBar:text] to the empty string (not %NULL).
|
||||
public func showText(_ showText: Bool? = true) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.showText = showText
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// Text to be displayed in the progress bar.
|
||||
public func text(_ text: String?) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.text = text
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
}
|
403
Sources/Adwaita/View/Generated/ScrolledWindow.swift
Normal file
403
Sources/Adwaita/View/Generated/ScrolledWindow.swift
Normal file
@ -0,0 +1,403 @@
|
||||
//
|
||||
// ScrolledWindow.swift
|
||||
// Adwaita
|
||||
//
|
||||
// Created by auto-generation on 22.01.24.
|
||||
//
|
||||
|
||||
import CAdw
|
||||
import LevenshteinTransformations
|
||||
|
||||
/// `GtkScrolledWindow` is a container that makes its child scrollable.
|
||||
///
|
||||
/// It does so using either internally added scrollbars or externally
|
||||
/// associated adjustments, and optionally draws a frame around the child.
|
||||
///
|
||||
/// Widgets with native scrolling support, i.e. those whose classes implement
|
||||
/// the [iface@Gtk.Scrollable] interface, are added directly. For other types
|
||||
/// of widget, the class [class@Gtk.Viewport] acts as an adaptor, giving
|
||||
/// scrollability to other widgets. [method@Gtk.ScrolledWindow.set_child]
|
||||
/// intelligently accounts for whether or not the added child is a `GtkScrollable`.
|
||||
/// If it isn’t, then it wraps the child in a `GtkViewport`. Therefore, you can
|
||||
/// just add any child widget and not worry about the details.
|
||||
///
|
||||
/// If [method@Gtk.ScrolledWindow.set_child] has added a `GtkViewport` for you,
|
||||
/// it will be automatically removed when you unset the child.
|
||||
/// Unless [property@Gtk.ScrolledWindow:hscrollbar-policy] and
|
||||
/// [property@Gtk.ScrolledWindow:vscrollbar-policy] are %GTK_POLICY_NEVER or
|
||||
/// %GTK_POLICY_EXTERNAL, `GtkScrolledWindow` adds internal `GtkScrollbar` widgets
|
||||
/// around its child. The scroll position of the child, and if applicable the
|
||||
/// scrollbars, is controlled by the [property@Gtk.ScrolledWindow:hadjustment]
|
||||
/// and [property@Gtk.ScrolledWindow:vadjustment] that are associated with the
|
||||
/// `GtkScrolledWindow`. See the docs on [class@Gtk.Scrollbar] for the details,
|
||||
/// but note that the “step_increment” and “page_increment” fields are only
|
||||
/// effective if the policy causes scrollbars to be present.
|
||||
///
|
||||
/// If a `GtkScrolledWindow` doesn’t behave quite as you would like, or
|
||||
/// doesn’t have exactly the right layout, it’s very possible to set up
|
||||
/// your own scrolling with `GtkScrollbar` and for example a `GtkGrid`.
|
||||
///
|
||||
/// # Touch support
|
||||
///
|
||||
/// `GtkScrolledWindow` has built-in support for touch devices. When a
|
||||
/// touchscreen is used, swiping will move the scrolled window, and will
|
||||
/// expose 'kinetic' behavior. This can be turned off with the
|
||||
/// [property@Gtk.ScrolledWindow:kinetic-scrolling] property if it is undesired.
|
||||
///
|
||||
/// `GtkScrolledWindow` also displays visual 'overshoot' indication when
|
||||
/// the content is pulled beyond the end, and this situation can be
|
||||
/// captured with the [signal@Gtk.ScrolledWindow::edge-overshot] signal.
|
||||
///
|
||||
/// If no mouse device is present, the scrollbars will overlaid as
|
||||
/// narrow, auto-hiding indicators over the content. If traditional
|
||||
/// scrollbars are desired although no mouse is present, this behaviour
|
||||
/// can be turned off with the [property@Gtk.ScrolledWindow:overlay-scrolling]
|
||||
/// property.
|
||||
///
|
||||
/// # CSS nodes
|
||||
///
|
||||
/// `GtkScrolledWindow` has a main CSS node with name scrolledwindow.
|
||||
/// It gets a .frame style class added when [property@Gtk.ScrolledWindow:has-frame]
|
||||
/// is %TRUE.
|
||||
///
|
||||
/// It uses subnodes with names overshoot and undershoot to draw the overflow
|
||||
/// and underflow indications. These nodes get the .left, .right, .top or .bottom
|
||||
/// style class added depending on where the indication is drawn.
|
||||
///
|
||||
/// `GtkScrolledWindow` also sets the positional style classes (.left, .right,
|
||||
/// .top, .bottom) and style classes related to overlay scrolling
|
||||
/// (.overlay-indicator, .dragging, .hovering) on its scrollbars.
|
||||
///
|
||||
/// If both scrollbars are visible, the area where they meet is drawn
|
||||
/// with a subnode named junction.
|
||||
///
|
||||
/// # Accessibility
|
||||
///
|
||||
/// Until GTK 4.10, `GtkScrolledWindow` used the `GTK_ACCESSIBLE_ROLE_GROUP` role.
|
||||
///
|
||||
/// Starting from GTK 4.12, `GtkScrolledWindow` uses the `GTK_ACCESSIBLE_ROLE_GENERIC` role.
|
||||
public struct ScrolledWindow: Widget {
|
||||
|
||||
/// Additional update functions for type extensions.
|
||||
var updateFunctions: [(ViewStorage) -> Void] = []
|
||||
/// Additional appear functions for type extensions.
|
||||
var appearFunctions: [(ViewStorage) -> Void] = []
|
||||
|
||||
/// The child widget.
|
||||
var child: (() -> Body)?
|
||||
/// Whether to draw a frame around the contents.
|
||||
var hasFrame: Bool?
|
||||
/// Whether kinetic scrolling is enabled or not.
|
||||
///
|
||||
/// Kinetic scrolling only applies to devices with source %GDK_SOURCE_TOUCHSCREEN.
|
||||
var kineticScrolling: Bool?
|
||||
/// The maximum content height of @scrolled_window.
|
||||
var maxContentHeight: Int?
|
||||
/// The maximum content width of @scrolled_window.
|
||||
var maxContentWidth: Int?
|
||||
/// The minimum content height of @scrolled_window.
|
||||
var minContentHeight: Int?
|
||||
/// The minimum content width of @scrolled_window.
|
||||
var minContentWidth: Int?
|
||||
/// Whether overlay scrolling is enabled or not.
|
||||
///
|
||||
/// If it is, the scrollbars are only added as traditional widgets
|
||||
/// when a mouse is present. Otherwise, they are overlaid on top of
|
||||
/// the content, as narrow indicators.
|
||||
///
|
||||
/// Note that overlay scrolling can also be globally disabled, with
|
||||
/// the [property@Gtk.Settings:gtk-overlay-scrolling] setting.
|
||||
var overlayScrolling: Bool?
|
||||
/// Whether the natural height of the child should be calculated and propagated
|
||||
/// through the scrolled window’s requested natural height.
|
||||
///
|
||||
/// This is useful in cases where an attempt should be made to allocate exactly
|
||||
/// enough space for the natural size of the child.
|
||||
var propagateNaturalHeight: Bool?
|
||||
/// Whether the natural width of the child should be calculated and propagated
|
||||
/// through the scrolled window’s requested natural width.
|
||||
///
|
||||
/// This is useful in cases where an attempt should be made to allocate exactly
|
||||
/// enough space for the natural size of the child.
|
||||
var propagateNaturalWidth: Bool?
|
||||
/// Emitted whenever user initiated scrolling makes the scrolled
|
||||
/// window firmly surpass the limits defined by the adjustment
|
||||
/// in that orientation.
|
||||
///
|
||||
/// A similar behavior without edge resistance is provided by the
|
||||
/// [signal@Gtk.ScrolledWindow::edge-reached] signal.
|
||||
///
|
||||
/// Note: The @pos argument is LTR/RTL aware, so callers should be
|
||||
/// aware too if intending to provide behavior on horizontal edges.
|
||||
var edgeOvershot: (() -> Void)?
|
||||
/// Emitted whenever user-initiated scrolling makes the scrolled
|
||||
/// window exactly reach the lower or upper limits defined by the
|
||||
/// adjustment in that orientation.
|
||||
///
|
||||
/// A similar behavior with edge resistance is provided by the
|
||||
/// [signal@Gtk.ScrolledWindow::edge-overshot] signal.
|
||||
///
|
||||
/// Note: The @pos argument is LTR/RTL aware, so callers should be
|
||||
/// aware too if intending to provide behavior on horizontal edges.
|
||||
var edgeReached: (() -> Void)?
|
||||
/// Emitted when focus is moved away from the scrolled window by a
|
||||
/// keybinding.
|
||||
///
|
||||
/// This is a [keybinding signal](class.SignalAction.html).
|
||||
///
|
||||
/// The default bindings for this signal are
|
||||
/// `Ctrl + Tab` to move forward and `Ctrl + Shift + Tab` to
|
||||
/// move backward.
|
||||
var moveFocusOut: (() -> Void)?
|
||||
/// Emitted when a keybinding that scrolls is pressed.
|
||||
///
|
||||
/// This is a [keybinding signal](class.SignalAction.html).
|
||||
///
|
||||
/// The horizontal or vertical adjustment is updated which triggers a
|
||||
/// signal that the scrolled window’s child may listen to and scroll itself.
|
||||
var scrollChild: (() -> Void)?
|
||||
/// The application.
|
||||
var app: GTUIApp?
|
||||
/// The window.
|
||||
var window: GTUIApplicationWindow?
|
||||
|
||||
/// Initialize `ScrolledWindow`.
|
||||
public init() {
|
||||
}
|
||||
|
||||
/// Get the widget's view storage.
|
||||
/// - Parameter modifiers: The view modifiers.
|
||||
/// - Returns: The view storage.
|
||||
public func container(modifiers: [(View) -> View]) -> ViewStorage {
|
||||
let storage = ViewStorage(gtk_scrolled_window_new()?.opaque())
|
||||
update(storage, modifiers: modifiers)
|
||||
if let childStorage = child?().widget(modifiers: modifiers).storage(modifiers: modifiers) {
|
||||
storage.content["child"] = [childStorage]
|
||||
gtk_scrolled_window_set_child(storage.pointer, childStorage.pointer?.cast())
|
||||
}
|
||||
|
||||
|
||||
for function in appearFunctions {
|
||||
function(storage)
|
||||
}
|
||||
return storage
|
||||
}
|
||||
|
||||
/// Update the widget's view storage.
|
||||
/// - Parameters:
|
||||
/// - storage: The view storage.
|
||||
/// - modifiers: The view modifiers.
|
||||
public func update(_ storage: ViewStorage, modifiers: [(View) -> View]) {
|
||||
if let edgeOvershot {
|
||||
storage.connectSignal(name: "edge-overshot") {
|
||||
edgeOvershot()
|
||||
}
|
||||
}
|
||||
if let edgeReached {
|
||||
storage.connectSignal(name: "edge-reached") {
|
||||
edgeReached()
|
||||
}
|
||||
}
|
||||
if let moveFocusOut {
|
||||
storage.connectSignal(name: "move-focus-out") {
|
||||
moveFocusOut()
|
||||
}
|
||||
}
|
||||
if let scrollChild {
|
||||
storage.connectSignal(name: "scroll-child") {
|
||||
scrollChild()
|
||||
}
|
||||
}
|
||||
storage.modify { widget in
|
||||
if let widget = storage.content["child"]?.first {
|
||||
child?().widget(modifiers: modifiers).update(widget, modifiers: modifiers)
|
||||
}
|
||||
if let hasFrame {
|
||||
gtk_scrolled_window_set_has_frame(widget, hasFrame.cBool)
|
||||
}
|
||||
if let kineticScrolling {
|
||||
gtk_scrolled_window_set_kinetic_scrolling(widget, kineticScrolling.cBool)
|
||||
}
|
||||
if let maxContentHeight {
|
||||
gtk_scrolled_window_set_max_content_height(widget, maxContentHeight.cInt)
|
||||
}
|
||||
if let maxContentWidth {
|
||||
gtk_scrolled_window_set_max_content_width(widget, maxContentWidth.cInt)
|
||||
}
|
||||
if let minContentHeight {
|
||||
gtk_scrolled_window_set_min_content_height(widget, minContentHeight.cInt)
|
||||
}
|
||||
if let minContentWidth {
|
||||
gtk_scrolled_window_set_min_content_width(widget, minContentWidth.cInt)
|
||||
}
|
||||
if let overlayScrolling {
|
||||
gtk_scrolled_window_set_overlay_scrolling(widget, overlayScrolling.cBool)
|
||||
}
|
||||
if let propagateNaturalHeight {
|
||||
gtk_scrolled_window_set_propagate_natural_height(widget, propagateNaturalHeight.cBool)
|
||||
}
|
||||
if let propagateNaturalWidth {
|
||||
gtk_scrolled_window_set_propagate_natural_width(widget, propagateNaturalWidth.cBool)
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
for function in updateFunctions {
|
||||
function(storage)
|
||||
}
|
||||
}
|
||||
|
||||
/// The child widget.
|
||||
public func child(@ViewBuilder _ child: @escaping (() -> Body)) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.child = child
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// Whether to draw a frame around the contents.
|
||||
public func hasFrame(_ hasFrame: Bool? = true) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.hasFrame = hasFrame
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// Whether kinetic scrolling is enabled or not.
|
||||
///
|
||||
/// Kinetic scrolling only applies to devices with source %GDK_SOURCE_TOUCHSCREEN.
|
||||
public func kineticScrolling(_ kineticScrolling: Bool? = true) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.kineticScrolling = kineticScrolling
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// The maximum content height of @scrolled_window.
|
||||
public func maxContentHeight(_ maxContentHeight: Int?) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.maxContentHeight = maxContentHeight
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// The maximum content width of @scrolled_window.
|
||||
public func maxContentWidth(_ maxContentWidth: Int?) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.maxContentWidth = maxContentWidth
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// The minimum content height of @scrolled_window.
|
||||
public func minContentHeight(_ minContentHeight: Int?) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.minContentHeight = minContentHeight
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// The minimum content width of @scrolled_window.
|
||||
public func minContentWidth(_ minContentWidth: Int?) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.minContentWidth = minContentWidth
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// Whether overlay scrolling is enabled or not.
|
||||
///
|
||||
/// If it is, the scrollbars are only added as traditional widgets
|
||||
/// when a mouse is present. Otherwise, they are overlaid on top of
|
||||
/// the content, as narrow indicators.
|
||||
///
|
||||
/// Note that overlay scrolling can also be globally disabled, with
|
||||
/// the [property@Gtk.Settings:gtk-overlay-scrolling] setting.
|
||||
public func overlayScrolling(_ overlayScrolling: Bool? = true) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.overlayScrolling = overlayScrolling
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// Whether the natural height of the child should be calculated and propagated
|
||||
/// through the scrolled window’s requested natural height.
|
||||
///
|
||||
/// This is useful in cases where an attempt should be made to allocate exactly
|
||||
/// enough space for the natural size of the child.
|
||||
public func propagateNaturalHeight(_ propagateNaturalHeight: Bool? = true) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.propagateNaturalHeight = propagateNaturalHeight
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// Whether the natural width of the child should be calculated and propagated
|
||||
/// through the scrolled window’s requested natural width.
|
||||
///
|
||||
/// This is useful in cases where an attempt should be made to allocate exactly
|
||||
/// enough space for the natural size of the child.
|
||||
public func propagateNaturalWidth(_ propagateNaturalWidth: Bool? = true) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.propagateNaturalWidth = propagateNaturalWidth
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// Emitted whenever user initiated scrolling makes the scrolled
|
||||
/// window firmly surpass the limits defined by the adjustment
|
||||
/// in that orientation.
|
||||
///
|
||||
/// A similar behavior without edge resistance is provided by the
|
||||
/// [signal@Gtk.ScrolledWindow::edge-reached] signal.
|
||||
///
|
||||
/// Note: The @pos argument is LTR/RTL aware, so callers should be
|
||||
/// aware too if intending to provide behavior on horizontal edges.
|
||||
public func edgeOvershot(_ edgeOvershot: @escaping () -> Void) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.edgeOvershot = edgeOvershot
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// Emitted whenever user-initiated scrolling makes the scrolled
|
||||
/// window exactly reach the lower or upper limits defined by the
|
||||
/// adjustment in that orientation.
|
||||
///
|
||||
/// A similar behavior with edge resistance is provided by the
|
||||
/// [signal@Gtk.ScrolledWindow::edge-overshot] signal.
|
||||
///
|
||||
/// Note: The @pos argument is LTR/RTL aware, so callers should be
|
||||
/// aware too if intending to provide behavior on horizontal edges.
|
||||
public func edgeReached(_ edgeReached: @escaping () -> Void) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.edgeReached = edgeReached
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// Emitted when focus is moved away from the scrolled window by a
|
||||
/// keybinding.
|
||||
///
|
||||
/// This is a [keybinding signal](class.SignalAction.html).
|
||||
///
|
||||
/// The default bindings for this signal are
|
||||
/// `Ctrl + Tab` to move forward and `Ctrl + Shift + Tab` to
|
||||
/// move backward.
|
||||
public func moveFocusOut(_ moveFocusOut: @escaping () -> Void) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.moveFocusOut = moveFocusOut
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// Emitted when a keybinding that scrolls is pressed.
|
||||
///
|
||||
/// This is a [keybinding signal](class.SignalAction.html).
|
||||
///
|
||||
/// The horizontal or vertical adjustment is updated which triggers a
|
||||
/// signal that the scrolled window’s child may listen to and scroll itself.
|
||||
public func scrollChild(_ scrollChild: @escaping () -> Void) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.scrollChild = scrollChild
|
||||
return newSelf
|
||||
}
|
||||
|
||||
}
|
432
Sources/Adwaita/View/Generated/SpinRow.swift
Normal file
432
Sources/Adwaita/View/Generated/SpinRow.swift
Normal file
@ -0,0 +1,432 @@
|
||||
//
|
||||
// SpinRow.swift
|
||||
// Adwaita
|
||||
//
|
||||
// Created by auto-generation on 22.01.24.
|
||||
//
|
||||
|
||||
import CAdw
|
||||
import LevenshteinTransformations
|
||||
|
||||
/// An [class@ActionRow] with an embedded spin button.
|
||||
///
|
||||
/// <picture><source srcset="spin-row-dark.png" media="(prefers-color-scheme: dark)"><img src="spin-row.png" alt="spin-row"></picture>
|
||||
///
|
||||
/// Example of an `AdwSpinRow` UI definition:
|
||||
///
|
||||
/// ```xml
|
||||
/// <object class="AdwSpinRow"><property name="title" translatable="yes">Spin Row</property><property name="adjustment"><object class="GtkAdjustment"><property name="lower">0</property><property name="upper">100</property><property name="value">50</property><property name="page-increment">10</property><property name="step-increment">1</property></object></property></object>
|
||||
/// ```
|
||||
///
|
||||
/// See [class@Gtk.SpinButton] for details.
|
||||
///
|
||||
/// ## CSS nodes
|
||||
///
|
||||
/// `AdwSpinRow` has the same structure as [class@ActionRow], as well as the
|
||||
/// `.spin` style class on the main node.
|
||||
public struct SpinRow: Widget {
|
||||
|
||||
/// Additional update functions for type extensions.
|
||||
var updateFunctions: [(ViewStorage) -> Void] = []
|
||||
/// Additional appear functions for type extensions.
|
||||
var appearFunctions: [(ViewStorage) -> Void] = []
|
||||
|
||||
/// The acceleration rate when you hold down a button or key.
|
||||
var climbRate: Double
|
||||
/// The number of decimal places to display.
|
||||
var digits: UInt
|
||||
/// Whether non-numeric characters should be ignored.
|
||||
var numeric: Bool?
|
||||
/// Whether invalid values are snapped to the nearest step increment.
|
||||
var snapToTicks: Bool?
|
||||
/// The current value.
|
||||
var value: Binding<Double>?
|
||||
/// Whether the spin row should wrap upon reaching its limits.
|
||||
var wrap: Bool?
|
||||
/// The widget to activate when the row is activated.
|
||||
///
|
||||
/// The row can be activated either by clicking on it, calling
|
||||
/// [method@ActionRow.activate], or via mnemonics in the title.
|
||||
/// See the [property@PreferencesRow:use-underline] property to enable
|
||||
/// mnemonics.
|
||||
///
|
||||
/// The target widget will be activated by emitting the
|
||||
/// [signal@Gtk.Widget::mnemonic-activate] signal on it.
|
||||
var activatableWidget: (() -> Body)?
|
||||
/// The icon name for this row.
|
||||
var iconName: String?
|
||||
/// The subtitle for this row.
|
||||
///
|
||||
/// The subtitle is interpreted as Pango markup unless
|
||||
/// [property@PreferencesRow:use-markup] is set to `FALSE`.
|
||||
var subtitle: String?
|
||||
/// The number of lines at the end of which the subtitle label will be
|
||||
/// ellipsized.
|
||||
///
|
||||
/// If the value is 0, the number of lines won't be limited.
|
||||
var subtitleLines: Int?
|
||||
/// Whether the user can copy the subtitle from the label.
|
||||
///
|
||||
/// See also [property@Gtk.Label:selectable].
|
||||
var subtitleSelectable: Bool?
|
||||
/// The number of lines at the end of which the title label will be ellipsized.
|
||||
///
|
||||
/// If the value is 0, the number of lines won't be limited.
|
||||
var titleLines: Int?
|
||||
/// The title of the preference represented by this row.
|
||||
///
|
||||
/// The title is interpreted as Pango markup unless
|
||||
/// [property@PreferencesRow:use-markup] is set to `FALSE`.
|
||||
var title: String?
|
||||
/// Whether the user can copy the title from the label.
|
||||
///
|
||||
/// See also [property@Gtk.Label:selectable].
|
||||
var titleSelectable: Bool?
|
||||
/// Whether to use Pango markup for the title label.
|
||||
///
|
||||
/// Subclasses may also use it for other labels, such as subtitle.
|
||||
///
|
||||
/// See also [func@Pango.parse_markup].
|
||||
var useMarkup: Bool?
|
||||
/// Whether an embedded underline in the title indicates a mnemonic.
|
||||
var useUnderline: Bool?
|
||||
/// Emitted to convert the user's input into a double value.
|
||||
///
|
||||
/// The signal handler is expected to use [method@Gtk.Editable.get_text] to
|
||||
/// retrieve the text of the spinbutton and set new_value to the new value.
|
||||
///
|
||||
/// The default conversion uses [func@GLib.strtod].
|
||||
///
|
||||
/// See [signal@Gtk.SpinButton::input].
|
||||
var input: (() -> Void)?
|
||||
/// Emitted to tweak the formatting of the value for display.
|
||||
///
|
||||
/// See [signal@Gtk.SpinButton::output].
|
||||
var output: (() -> Void)?
|
||||
/// Emitted right after the spinbutton wraps.
|
||||
///
|
||||
/// See [signal@Gtk.SpinButton::wrapped].
|
||||
var wrapped: (() -> Void)?
|
||||
/// This signal is emitted after the row has been activated.
|
||||
var activated: (() -> Void)?
|
||||
/// The body for the widget "suffix".
|
||||
var suffix: () -> Body = { [] }
|
||||
/// The body for the widget "prefix".
|
||||
var prefix: () -> Body = { [] }
|
||||
/// The application.
|
||||
var app: GTUIApp?
|
||||
/// The window.
|
||||
var window: GTUIApplicationWindow?
|
||||
|
||||
/// Initialize `SpinRow`.
|
||||
public init(climbRate: Double, digits: UInt) {
|
||||
self.climbRate = climbRate
|
||||
self.digits = digits
|
||||
}
|
||||
|
||||
/// Get the widget's view storage.
|
||||
/// - Parameter modifiers: The view modifiers.
|
||||
/// - Returns: The view storage.
|
||||
public func container(modifiers: [(View) -> View]) -> ViewStorage {
|
||||
let storage = ViewStorage(adw_spin_row_new(nil, climbRate, digits.cInt)?.opaque())
|
||||
update(storage, modifiers: modifiers)
|
||||
if let activatableWidgetStorage = activatableWidget?().widget(modifiers: modifiers).storage(modifiers: modifiers) {
|
||||
storage.content["activatableWidget"] = [activatableWidgetStorage]
|
||||
adw_action_row_set_activatable_widget(storage.pointer?.cast(), activatableWidgetStorage.pointer?.cast())
|
||||
}
|
||||
|
||||
var suffixStorage: [ViewStorage] = []
|
||||
for view in suffix() {
|
||||
suffixStorage.append(view.storage(modifiers: modifiers))
|
||||
adw_action_row_add_suffix(storage.pointer?.cast(), suffixStorage.last?.pointer?.cast())
|
||||
}
|
||||
storage.content["suffix"] = suffixStorage
|
||||
var prefixStorage: [ViewStorage] = []
|
||||
for view in prefix() {
|
||||
prefixStorage.append(view.storage(modifiers: modifiers))
|
||||
adw_action_row_add_prefix(storage.pointer?.cast(), prefixStorage.last?.pointer?.cast())
|
||||
}
|
||||
storage.content["prefix"] = prefixStorage
|
||||
|
||||
storage.notify(name: "value") {
|
||||
value?.wrappedValue = adw_spin_row_get_value(storage.pointer)
|
||||
}
|
||||
for function in appearFunctions {
|
||||
function(storage)
|
||||
}
|
||||
return storage
|
||||
}
|
||||
|
||||
/// Update the widget's view storage.
|
||||
/// - Parameters:
|
||||
/// - storage: The view storage.
|
||||
/// - modifiers: The view modifiers.
|
||||
public func update(_ storage: ViewStorage, modifiers: [(View) -> View]) {
|
||||
if let input {
|
||||
storage.connectSignal(name: "input") {
|
||||
input()
|
||||
}
|
||||
}
|
||||
if let output {
|
||||
storage.connectSignal(name: "output") {
|
||||
output()
|
||||
}
|
||||
}
|
||||
if let wrapped {
|
||||
storage.connectSignal(name: "wrapped") {
|
||||
wrapped()
|
||||
}
|
||||
}
|
||||
if let activated {
|
||||
storage.connectSignal(name: "activated") {
|
||||
activated()
|
||||
}
|
||||
}
|
||||
storage.modify { widget in
|
||||
adw_spin_row_set_climb_rate(widget, climbRate)
|
||||
adw_spin_row_set_digits(widget, digits.cInt)
|
||||
if let numeric {
|
||||
adw_spin_row_set_numeric(widget, numeric.cBool)
|
||||
}
|
||||
if let snapToTicks {
|
||||
adw_spin_row_set_snap_to_ticks(widget, snapToTicks.cBool)
|
||||
}
|
||||
if let value {
|
||||
adw_spin_row_set_value(widget, value.wrappedValue)
|
||||
}
|
||||
if let wrap {
|
||||
adw_spin_row_set_wrap(widget, wrap.cBool)
|
||||
}
|
||||
if let widget = storage.content["activatableWidget"]?.first {
|
||||
activatableWidget?().widget(modifiers: modifiers).update(widget, modifiers: modifiers)
|
||||
}
|
||||
if let iconName {
|
||||
adw_action_row_set_icon_name(widget?.cast(), iconName)
|
||||
}
|
||||
if let subtitle {
|
||||
adw_action_row_set_subtitle(widget?.cast(), subtitle)
|
||||
}
|
||||
if let subtitleLines {
|
||||
adw_action_row_set_subtitle_lines(widget?.cast(), subtitleLines.cInt)
|
||||
}
|
||||
if let subtitleSelectable {
|
||||
adw_action_row_set_subtitle_selectable(widget?.cast(), subtitleSelectable.cBool)
|
||||
}
|
||||
if let titleLines {
|
||||
adw_action_row_set_title_lines(widget?.cast(), titleLines.cInt)
|
||||
}
|
||||
if let title {
|
||||
adw_preferences_row_set_title(widget?.cast(), title)
|
||||
}
|
||||
if let titleSelectable {
|
||||
adw_preferences_row_set_title_selectable(widget?.cast(), titleSelectable.cBool)
|
||||
}
|
||||
if let useMarkup {
|
||||
adw_preferences_row_set_use_markup(widget?.cast(), useMarkup.cBool)
|
||||
}
|
||||
if let useUnderline {
|
||||
adw_preferences_row_set_use_underline(widget?.cast(), useUnderline.cBool)
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
for function in updateFunctions {
|
||||
function(storage)
|
||||
}
|
||||
}
|
||||
|
||||
/// The acceleration rate when you hold down a button or key.
|
||||
public func climbRate(_ climbRate: Double) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.climbRate = climbRate
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// The number of decimal places to display.
|
||||
public func digits(_ digits: UInt) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.digits = digits
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// Whether non-numeric characters should be ignored.
|
||||
public func numeric(_ numeric: Bool? = true) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.numeric = numeric
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// Whether invalid values are snapped to the nearest step increment.
|
||||
public func snapToTicks(_ snapToTicks: Bool? = true) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.snapToTicks = snapToTicks
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// The current value.
|
||||
public func value(_ value: Binding<Double>?) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.value = value
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// Whether the spin row should wrap upon reaching its limits.
|
||||
public func wrap(_ wrap: Bool? = true) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.wrap = wrap
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// The widget to activate when the row is activated.
|
||||
///
|
||||
/// The row can be activated either by clicking on it, calling
|
||||
/// [method@ActionRow.activate], or via mnemonics in the title.
|
||||
/// See the [property@PreferencesRow:use-underline] property to enable
|
||||
/// mnemonics.
|
||||
///
|
||||
/// The target widget will be activated by emitting the
|
||||
/// [signal@Gtk.Widget::mnemonic-activate] signal on it.
|
||||
public func activatableWidget(@ViewBuilder _ activatableWidget: @escaping (() -> Body)) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.activatableWidget = activatableWidget
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// The icon name for this row.
|
||||
public func iconName(_ iconName: String?) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.iconName = iconName
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// The subtitle for this row.
|
||||
///
|
||||
/// The subtitle is interpreted as Pango markup unless
|
||||
/// [property@PreferencesRow:use-markup] is set to `FALSE`.
|
||||
public func subtitle(_ subtitle: String?) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.subtitle = subtitle
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// The number of lines at the end of which the subtitle label will be
|
||||
/// ellipsized.
|
||||
///
|
||||
/// If the value is 0, the number of lines won't be limited.
|
||||
public func subtitleLines(_ subtitleLines: Int?) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.subtitleLines = subtitleLines
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// Whether the user can copy the subtitle from the label.
|
||||
///
|
||||
/// See also [property@Gtk.Label:selectable].
|
||||
public func subtitleSelectable(_ subtitleSelectable: Bool? = true) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.subtitleSelectable = subtitleSelectable
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// The number of lines at the end of which the title label will be ellipsized.
|
||||
///
|
||||
/// If the value is 0, the number of lines won't be limited.
|
||||
public func titleLines(_ titleLines: Int?) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.titleLines = titleLines
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// The title of the preference represented by this row.
|
||||
///
|
||||
/// The title is interpreted as Pango markup unless
|
||||
/// [property@PreferencesRow:use-markup] is set to `FALSE`.
|
||||
public func title(_ title: String?) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.title = title
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// Whether the user can copy the title from the label.
|
||||
///
|
||||
/// See also [property@Gtk.Label:selectable].
|
||||
public func titleSelectable(_ titleSelectable: Bool? = true) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.titleSelectable = titleSelectable
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// Whether to use Pango markup for the title label.
|
||||
///
|
||||
/// Subclasses may also use it for other labels, such as subtitle.
|
||||
///
|
||||
/// See also [func@Pango.parse_markup].
|
||||
public func useMarkup(_ useMarkup: Bool? = true) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.useMarkup = useMarkup
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// Whether an embedded underline in the title indicates a mnemonic.
|
||||
public func useUnderline(_ useUnderline: Bool? = true) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.useUnderline = useUnderline
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// Emitted to convert the user's input into a double value.
|
||||
///
|
||||
/// The signal handler is expected to use [method@Gtk.Editable.get_text] to
|
||||
/// retrieve the text of the spinbutton and set new_value to the new value.
|
||||
///
|
||||
/// The default conversion uses [func@GLib.strtod].
|
||||
///
|
||||
/// See [signal@Gtk.SpinButton::input].
|
||||
public func input(_ input: @escaping () -> Void) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.input = input
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// Emitted to tweak the formatting of the value for display.
|
||||
///
|
||||
/// See [signal@Gtk.SpinButton::output].
|
||||
public func output(_ output: @escaping () -> Void) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.output = output
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// Emitted right after the spinbutton wraps.
|
||||
///
|
||||
/// See [signal@Gtk.SpinButton::wrapped].
|
||||
public func wrapped(_ wrapped: @escaping () -> Void) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.wrapped = wrapped
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// This signal is emitted after the row has been activated.
|
||||
public func activated(_ activated: @escaping () -> Void) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.activated = activated
|
||||
return newSelf
|
||||
}
|
||||
|
||||
}
|
83
Sources/Adwaita/View/Generated/Spinner.swift
Normal file
83
Sources/Adwaita/View/Generated/Spinner.swift
Normal file
@ -0,0 +1,83 @@
|
||||
//
|
||||
// Spinner.swift
|
||||
// Adwaita
|
||||
//
|
||||
// Created by auto-generation on 22.01.24.
|
||||
//
|
||||
|
||||
import CAdw
|
||||
import LevenshteinTransformations
|
||||
|
||||
/// A `GtkSpinner` widget displays an icon-size spinning animation.
|
||||
///
|
||||
/// It is often used as an alternative to a [class@Gtk.ProgressBar]
|
||||
/// for displaying indefinite activity, instead of actual progress.
|
||||
///
|
||||
/// ![An example GtkSpinner](spinner.png)
|
||||
///
|
||||
/// To start the animation, use [method@Gtk.Spinner.start], to stop it
|
||||
/// use [method@Gtk.Spinner.stop].
|
||||
///
|
||||
/// # CSS nodes
|
||||
///
|
||||
/// `GtkSpinner` has a single CSS node with the name spinner.
|
||||
/// When the animation is active, the :checked pseudoclass is
|
||||
/// added to this node.
|
||||
public struct Spinner: Widget {
|
||||
|
||||
/// Additional update functions for type extensions.
|
||||
var updateFunctions: [(ViewStorage) -> Void] = []
|
||||
/// Additional appear functions for type extensions.
|
||||
var appearFunctions: [(ViewStorage) -> Void] = []
|
||||
|
||||
/// Whether the spinner is spinning
|
||||
var spinning: Bool?
|
||||
/// The application.
|
||||
var app: GTUIApp?
|
||||
/// The window.
|
||||
var window: GTUIApplicationWindow?
|
||||
|
||||
/// Initialize `Spinner`.
|
||||
public init() {
|
||||
}
|
||||
|
||||
/// Get the widget's view storage.
|
||||
/// - Parameter modifiers: The view modifiers.
|
||||
/// - Returns: The view storage.
|
||||
public func container(modifiers: [(View) -> View]) -> ViewStorage {
|
||||
let storage = ViewStorage(gtk_spinner_new()?.opaque())
|
||||
update(storage, modifiers: modifiers)
|
||||
|
||||
|
||||
for function in appearFunctions {
|
||||
function(storage)
|
||||
}
|
||||
return storage
|
||||
}
|
||||
|
||||
/// Update the widget's view storage.
|
||||
/// - Parameters:
|
||||
/// - storage: The view storage.
|
||||
/// - modifiers: The view modifiers.
|
||||
public func update(_ storage: ViewStorage, modifiers: [(View) -> View]) {
|
||||
storage.modify { widget in
|
||||
if let spinning {
|
||||
gtk_spinner_set_spinning(widget, spinning.cBool)
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
for function in updateFunctions {
|
||||
function(storage)
|
||||
}
|
||||
}
|
||||
|
||||
/// Whether the spinner is spinning
|
||||
public func spinning(_ spinning: Bool? = true) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.spinning = spinning
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
}
|
274
Sources/Adwaita/View/Generated/SplitButton.swift
Normal file
274
Sources/Adwaita/View/Generated/SplitButton.swift
Normal file
@ -0,0 +1,274 @@
|
||||
//
|
||||
// SplitButton.swift
|
||||
// Adwaita
|
||||
//
|
||||
// Created by auto-generation on 22.01.24.
|
||||
//
|
||||
|
||||
import CAdw
|
||||
import LevenshteinTransformations
|
||||
|
||||
/// A combined button and dropdown widget.
|
||||
///
|
||||
/// <picture><source srcset="split-button-dark.png" media="(prefers-color-scheme: dark)"><img src="split-button.png" alt="split-button"></picture>
|
||||
///
|
||||
/// `AdwSplitButton` is typically used to present a set of actions in a menu,
|
||||
/// but allow access to one of them with a single click.
|
||||
///
|
||||
/// The API is very similar to [class@Gtk.Button] and [class@Gtk.MenuButton], see
|
||||
/// their documentation for details.
|
||||
///
|
||||
/// ## CSS nodes
|
||||
///
|
||||
/// ```
|
||||
/// splitbutton[.image-button][.text-button]
|
||||
/// ├── button
|
||||
/// │ ╰── <content>├── separator
|
||||
/// ╰── menubutton
|
||||
/// ╰── button.toggle
|
||||
/// ╰── arrow
|
||||
/// ```
|
||||
///
|
||||
/// `AdwSplitButton`'s CSS node is called `splitbutton`. It contains the css
|
||||
/// nodes: `button`, `separator`, `menubutton`. See [class@Gtk.MenuButton]
|
||||
/// documentation for the `menubutton` contents.
|
||||
///
|
||||
/// The main CSS node will contain the `.image-button` or `.text-button` style
|
||||
/// classes matching the button contents. The nested button nodes will never
|
||||
/// contain them.
|
||||
///
|
||||
/// ## Accessibility
|
||||
///
|
||||
/// `AdwSplitButton` uses the `GTK_ACCESSIBLE_ROLE_GROUP` role.
|
||||
public struct SplitButton: Widget {
|
||||
|
||||
/// Additional update functions for type extensions.
|
||||
var updateFunctions: [(ViewStorage) -> Void] = []
|
||||
/// Additional appear functions for type extensions.
|
||||
var appearFunctions: [(ViewStorage) -> Void] = []
|
||||
|
||||
/// Whether the button can be smaller than the natural size of its contents.
|
||||
///
|
||||
/// If set to `TRUE`, the label will ellipsize.
|
||||
///
|
||||
/// See [property@Gtk.Button:can-shrink] and
|
||||
/// [property@Gtk.MenuButton:can-shrink].
|
||||
var canShrink: Bool?
|
||||
/// The child widget.
|
||||
///
|
||||
/// Setting the child widget will set [property@SplitButton:label] and
|
||||
/// [property@SplitButton:icon-name] to `NULL`.
|
||||
var child: (() -> Body)?
|
||||
/// The tooltip of the dropdown button.
|
||||
///
|
||||
/// The tooltip can be marked up with the Pango text markup language.
|
||||
var dropdownTooltip: String?
|
||||
/// The name of the icon used to automatically populate the button.
|
||||
///
|
||||
/// Setting the icon name will set [property@SplitButton:label] and
|
||||
/// [property@SplitButton:child] to `NULL`.
|
||||
var iconName: String?
|
||||
/// The label for the button.
|
||||
///
|
||||
/// Setting the label will set [property@SplitButton:icon-name] and
|
||||
/// [property@SplitButton:child] to `NULL`.
|
||||
var label: String?
|
||||
/// The `GMenuModel` from which the popup will be created.
|
||||
///
|
||||
/// If the menu model is `NULL`, the dropdown is disabled.
|
||||
///
|
||||
/// A [class@Gtk.Popover] will be created from the menu model with
|
||||
/// [ctor@Gtk.PopoverMenu.new_from_model]. Actions will be connected as
|
||||
/// documented for this function.
|
||||
///
|
||||
/// If [property@SplitButton:popover] is already set, it will be dissociated
|
||||
/// from the button, and the property is set to `NULL`.
|
||||
var menuModel: (() -> MenuContent)?
|
||||
/// Whether an underline in the text indicates a mnemonic.
|
||||
///
|
||||
/// See [property@SplitButton:label].
|
||||
var useUnderline: Bool?
|
||||
/// Emitted to animate press then release.
|
||||
///
|
||||
/// This is an action signal. Applications should never connect to this signal,
|
||||
/// but use the [signal@SplitButton::clicked] signal.
|
||||
var activate: (() -> Void)?
|
||||
/// Emitted when the button has been activated (pressed and released).
|
||||
var clicked: (() -> Void)?
|
||||
/// The application.
|
||||
var app: GTUIApp?
|
||||
/// The window.
|
||||
var window: GTUIApplicationWindow?
|
||||
|
||||
/// Initialize `SplitButton`.
|
||||
public init() {
|
||||
}
|
||||
|
||||
/// Get the widget's view storage.
|
||||
/// - Parameter modifiers: The view modifiers.
|
||||
/// - Returns: The view storage.
|
||||
public func container(modifiers: [(View) -> View]) -> ViewStorage {
|
||||
let storage = ViewStorage(adw_split_button_new()?.opaque())
|
||||
update(storage, modifiers: modifiers)
|
||||
if let childStorage = child?().widget(modifiers: modifiers).storage(modifiers: modifiers) {
|
||||
storage.content["child"] = [childStorage]
|
||||
adw_split_button_set_child(storage.pointer, childStorage.pointer?.cast())
|
||||
}
|
||||
if let declarative = menuModel?(), let app {
|
||||
let menu = g_menu_new()
|
||||
adw_split_button_set_menu_model(storage.pointer, menu?.cast())
|
||||
for item in declarative {
|
||||
item.addMenuItems(menu: menu, app: app, window: window)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
for function in appearFunctions {
|
||||
function(storage)
|
||||
}
|
||||
return storage
|
||||
}
|
||||
|
||||
/// Update the widget's view storage.
|
||||
/// - Parameters:
|
||||
/// - storage: The view storage.
|
||||
/// - modifiers: The view modifiers.
|
||||
public func update(_ storage: ViewStorage, modifiers: [(View) -> View]) {
|
||||
if let activate {
|
||||
storage.connectSignal(name: "activate") {
|
||||
activate()
|
||||
}
|
||||
}
|
||||
if let clicked {
|
||||
storage.connectSignal(name: "clicked") {
|
||||
clicked()
|
||||
}
|
||||
}
|
||||
storage.modify { widget in
|
||||
if let canShrink {
|
||||
adw_split_button_set_can_shrink(widget, canShrink.cBool)
|
||||
}
|
||||
if let widget = storage.content["child"]?.first {
|
||||
child?().widget(modifiers: modifiers).update(widget, modifiers: modifiers)
|
||||
}
|
||||
if let dropdownTooltip {
|
||||
adw_split_button_set_dropdown_tooltip(widget, dropdownTooltip)
|
||||
}
|
||||
if let iconName {
|
||||
adw_split_button_set_icon_name(widget, iconName)
|
||||
}
|
||||
if let label, storage.content["child"] == nil {
|
||||
adw_split_button_set_label(widget, label)
|
||||
}
|
||||
if let useUnderline {
|
||||
adw_split_button_set_use_underline(widget, useUnderline.cBool)
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
for function in updateFunctions {
|
||||
function(storage)
|
||||
}
|
||||
}
|
||||
|
||||
/// Whether the button can be smaller than the natural size of its contents.
|
||||
///
|
||||
/// If set to `TRUE`, the label will ellipsize.
|
||||
///
|
||||
/// See [property@Gtk.Button:can-shrink] and
|
||||
/// [property@Gtk.MenuButton:can-shrink].
|
||||
public func canShrink(_ canShrink: Bool? = true) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.canShrink = canShrink
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// The child widget.
|
||||
///
|
||||
/// Setting the child widget will set [property@SplitButton:label] and
|
||||
/// [property@SplitButton:icon-name] to `NULL`.
|
||||
public func child(@ViewBuilder _ child: @escaping (() -> Body)) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.child = child
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// The tooltip of the dropdown button.
|
||||
///
|
||||
/// The tooltip can be marked up with the Pango text markup language.
|
||||
public func dropdownTooltip(_ dropdownTooltip: String?) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.dropdownTooltip = dropdownTooltip
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// The name of the icon used to automatically populate the button.
|
||||
///
|
||||
/// Setting the icon name will set [property@SplitButton:label] and
|
||||
/// [property@SplitButton:child] to `NULL`.
|
||||
public func iconName(_ iconName: String?) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.iconName = iconName
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// The label for the button.
|
||||
///
|
||||
/// Setting the label will set [property@SplitButton:icon-name] and
|
||||
/// [property@SplitButton:child] to `NULL`.
|
||||
public func label(_ label: String?) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.label = label
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// The `GMenuModel` from which the popup will be created.
|
||||
///
|
||||
/// If the menu model is `NULL`, the dropdown is disabled.
|
||||
///
|
||||
/// A [class@Gtk.Popover] will be created from the menu model with
|
||||
/// [ctor@Gtk.PopoverMenu.new_from_model]. Actions will be connected as
|
||||
/// documented for this function.
|
||||
///
|
||||
/// If [property@SplitButton:popover] is already set, it will be dissociated
|
||||
/// from the button, and the property is set to `NULL`.
|
||||
public func menuModel(app: GTUIApp, window: GTUIApplicationWindow? = nil, @MenuBuilder _ menuModel: @escaping (() -> MenuContent)) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.menuModel = menuModel
|
||||
newSelf.app = app; newSelf.window = window
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// Whether an underline in the text indicates a mnemonic.
|
||||
///
|
||||
/// See [property@SplitButton:label].
|
||||
public func useUnderline(_ useUnderline: Bool? = true) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.useUnderline = useUnderline
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// Emitted to animate press then release.
|
||||
///
|
||||
/// This is an action signal. Applications should never connect to this signal,
|
||||
/// but use the [signal@SplitButton::clicked] signal.
|
||||
public func activate(_ activate: @escaping () -> Void) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.activate = activate
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// Emitted when the button has been activated (pressed and released).
|
||||
public func clicked(_ clicked: @escaping () -> Void) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.clicked = clicked
|
||||
return newSelf
|
||||
}
|
||||
|
||||
}
|
133
Sources/Adwaita/View/Generated/StatusPage.swift
Normal file
133
Sources/Adwaita/View/Generated/StatusPage.swift
Normal file
@ -0,0 +1,133 @@
|
||||
//
|
||||
// StatusPage.swift
|
||||
// Adwaita
|
||||
//
|
||||
// Created by auto-generation on 22.01.24.
|
||||
//
|
||||
|
||||
import CAdw
|
||||
import LevenshteinTransformations
|
||||
|
||||
/// A page used for empty/error states and similar use-cases.
|
||||
///
|
||||
/// <picture><source srcset="status-page-dark.png" media="(prefers-color-scheme: dark)"><img src="status-page.png" alt="status-page"></picture>
|
||||
///
|
||||
/// The `AdwStatusPage` widget can have an icon, a title, a description and a
|
||||
/// custom widget which is displayed below them.
|
||||
///
|
||||
/// ## CSS nodes
|
||||
///
|
||||
/// `AdwStatusPage` has a main CSS node with name `statuspage`.
|
||||
///
|
||||
/// `AdwStatusPage` can use the
|
||||
/// [`.compact`](style-classes.html#compact-status-page) style class for when it
|
||||
/// needs to fit into a small space such a sidebar or a popover.
|
||||
public struct StatusPage: Widget {
|
||||
|
||||
/// Additional update functions for type extensions.
|
||||
var updateFunctions: [(ViewStorage) -> Void] = []
|
||||
/// Additional appear functions for type extensions.
|
||||
var appearFunctions: [(ViewStorage) -> Void] = []
|
||||
|
||||
/// The child widget.
|
||||
var child: (() -> Body)?
|
||||
/// The description markup to be displayed below the title.
|
||||
var description: String?
|
||||
/// The name of the icon to be used.
|
||||
///
|
||||
/// Changing this will set [property@StatusPage:paintable] to `NULL`.
|
||||
var iconName: String?
|
||||
/// The title to be displayed below the icon.
|
||||
///
|
||||
/// It is not parsed as Pango markup.
|
||||
var title: String?
|
||||
/// The application.
|
||||
var app: GTUIApp?
|
||||
/// The window.
|
||||
var window: GTUIApplicationWindow?
|
||||
|
||||
/// Initialize `StatusPage`.
|
||||
public init() {
|
||||
}
|
||||
|
||||
/// Get the widget's view storage.
|
||||
/// - Parameter modifiers: The view modifiers.
|
||||
/// - Returns: The view storage.
|
||||
public func container(modifiers: [(View) -> View]) -> ViewStorage {
|
||||
let storage = ViewStorage(adw_status_page_new()?.opaque())
|
||||
update(storage, modifiers: modifiers)
|
||||
if let childStorage = child?().widget(modifiers: modifiers).storage(modifiers: modifiers) {
|
||||
storage.content["child"] = [childStorage]
|
||||
adw_status_page_set_child(storage.pointer, childStorage.pointer?.cast())
|
||||
}
|
||||
|
||||
|
||||
for function in appearFunctions {
|
||||
function(storage)
|
||||
}
|
||||
return storage
|
||||
}
|
||||
|
||||
/// Update the widget's view storage.
|
||||
/// - Parameters:
|
||||
/// - storage: The view storage.
|
||||
/// - modifiers: The view modifiers.
|
||||
public func update(_ storage: ViewStorage, modifiers: [(View) -> View]) {
|
||||
storage.modify { widget in
|
||||
if let widget = storage.content["child"]?.first {
|
||||
child?().widget(modifiers: modifiers).update(widget, modifiers: modifiers)
|
||||
}
|
||||
if let description {
|
||||
adw_status_page_set_description(widget, description)
|
||||
}
|
||||
if let iconName {
|
||||
adw_status_page_set_icon_name(widget, iconName)
|
||||
}
|
||||
if let title {
|
||||
adw_status_page_set_title(widget, title)
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
for function in updateFunctions {
|
||||
function(storage)
|
||||
}
|
||||
}
|
||||
|
||||
/// The child widget.
|
||||
public func child(@ViewBuilder _ child: @escaping (() -> Body)) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.child = child
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// The description markup to be displayed below the title.
|
||||
public func description(_ description: String?) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.description = description
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// The name of the icon to be used.
|
||||
///
|
||||
/// Changing this will set [property@StatusPage:paintable] to `NULL`.
|
||||
public func iconName(_ iconName: String?) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.iconName = iconName
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// The title to be displayed below the icon.
|
||||
///
|
||||
/// It is not parsed as Pango markup.
|
||||
public func title(_ title: String?) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.title = title
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
}
|
309
Sources/Adwaita/View/Generated/SwitchRow.swift
Normal file
309
Sources/Adwaita/View/Generated/SwitchRow.swift
Normal file
@ -0,0 +1,309 @@
|
||||
//
|
||||
// SwitchRow.swift
|
||||
// Adwaita
|
||||
//
|
||||
// Created by auto-generation on 22.01.24.
|
||||
//
|
||||
|
||||
import CAdw
|
||||
import LevenshteinTransformations
|
||||
|
||||
/// A [class@Gtk.ListBoxRow] used to represent two states.
|
||||
///
|
||||
/// <picture><source srcset="switch-row-dark.png" media="(prefers-color-scheme: dark)"><img src="switch-row.png" alt="switch-row"></picture>
|
||||
///
|
||||
/// The `AdwSwitchRow` widget contains a [class@Gtk.Switch] that allows the user
|
||||
/// to select between two states: "on" or "off". When activated, the row will
|
||||
/// invert its active state.
|
||||
///
|
||||
/// The user can control the switch by activating the row or by dragging on the
|
||||
/// switch handle.
|
||||
///
|
||||
/// See [class@Gtk.Switch] for details.
|
||||
///
|
||||
/// Example of an `AdwSwitchRow` UI definition:
|
||||
/// ```xml
|
||||
/// <object class="AdwSwitchRow"><property name="title" translatable="yes">Switch Row</property><signal name="notify::active" handler="switch_row_notify_active_cb"/></object>
|
||||
/// ```
|
||||
///
|
||||
/// The [property@SwitchRow:active] property should be connected to in order to
|
||||
/// monitor changes to the active state.
|
||||
public struct SwitchRow: Widget {
|
||||
|
||||
/// Additional update functions for type extensions.
|
||||
var updateFunctions: [(ViewStorage) -> Void] = []
|
||||
/// Additional appear functions for type extensions.
|
||||
var appearFunctions: [(ViewStorage) -> Void] = []
|
||||
|
||||
/// Whether the switch row is in the "on" or "off" position.
|
||||
var active: Binding<Bool>?
|
||||
/// The widget to activate when the row is activated.
|
||||
///
|
||||
/// The row can be activated either by clicking on it, calling
|
||||
/// [method@ActionRow.activate], or via mnemonics in the title.
|
||||
/// See the [property@PreferencesRow:use-underline] property to enable
|
||||
/// mnemonics.
|
||||
///
|
||||
/// The target widget will be activated by emitting the
|
||||
/// [signal@Gtk.Widget::mnemonic-activate] signal on it.
|
||||
var activatableWidget: (() -> Body)?
|
||||
/// The icon name for this row.
|
||||
var iconName: String?
|
||||
/// The subtitle for this row.
|
||||
///
|
||||
/// The subtitle is interpreted as Pango markup unless
|
||||
/// [property@PreferencesRow:use-markup] is set to `FALSE`.
|
||||
var subtitle: String?
|
||||
/// The number of lines at the end of which the subtitle label will be
|
||||
/// ellipsized.
|
||||
///
|
||||
/// If the value is 0, the number of lines won't be limited.
|
||||
var subtitleLines: Int?
|
||||
/// Whether the user can copy the subtitle from the label.
|
||||
///
|
||||
/// See also [property@Gtk.Label:selectable].
|
||||
var subtitleSelectable: Bool?
|
||||
/// The number of lines at the end of which the title label will be ellipsized.
|
||||
///
|
||||
/// If the value is 0, the number of lines won't be limited.
|
||||
var titleLines: Int?
|
||||
/// The title of the preference represented by this row.
|
||||
///
|
||||
/// The title is interpreted as Pango markup unless
|
||||
/// [property@PreferencesRow:use-markup] is set to `FALSE`.
|
||||
var title: String?
|
||||
/// Whether the user can copy the title from the label.
|
||||
///
|
||||
/// See also [property@Gtk.Label:selectable].
|
||||
var titleSelectable: Bool?
|
||||
/// Whether to use Pango markup for the title label.
|
||||
///
|
||||
/// Subclasses may also use it for other labels, such as subtitle.
|
||||
///
|
||||
/// See also [func@Pango.parse_markup].
|
||||
var useMarkup: Bool?
|
||||
/// Whether an embedded underline in the title indicates a mnemonic.
|
||||
var useUnderline: Bool?
|
||||
/// This signal is emitted after the row has been activated.
|
||||
var activated: (() -> Void)?
|
||||
/// The body for the widget "suffix".
|
||||
var suffix: () -> Body = { [] }
|
||||
/// The body for the widget "prefix".
|
||||
var prefix: () -> Body = { [] }
|
||||
/// The application.
|
||||
var app: GTUIApp?
|
||||
/// The window.
|
||||
var window: GTUIApplicationWindow?
|
||||
|
||||
/// Initialize `SwitchRow`.
|
||||
public init() {
|
||||
}
|
||||
|
||||
/// Get the widget's view storage.
|
||||
/// - Parameter modifiers: The view modifiers.
|
||||
/// - Returns: The view storage.
|
||||
public func container(modifiers: [(View) -> View]) -> ViewStorage {
|
||||
let storage = ViewStorage(adw_switch_row_new()?.opaque())
|
||||
update(storage, modifiers: modifiers)
|
||||
if let activatableWidgetStorage = activatableWidget?().widget(modifiers: modifiers).storage(modifiers: modifiers) {
|
||||
storage.content["activatableWidget"] = [activatableWidgetStorage]
|
||||
adw_action_row_set_activatable_widget(storage.pointer?.cast(), activatableWidgetStorage.pointer?.cast())
|
||||
}
|
||||
|
||||
var suffixStorage: [ViewStorage] = []
|
||||
for view in suffix() {
|
||||
suffixStorage.append(view.storage(modifiers: modifiers))
|
||||
adw_action_row_add_suffix(storage.pointer?.cast(), suffixStorage.last?.pointer?.cast())
|
||||
}
|
||||
storage.content["suffix"] = suffixStorage
|
||||
var prefixStorage: [ViewStorage] = []
|
||||
for view in prefix() {
|
||||
prefixStorage.append(view.storage(modifiers: modifiers))
|
||||
adw_action_row_add_prefix(storage.pointer?.cast(), prefixStorage.last?.pointer?.cast())
|
||||
}
|
||||
storage.content["prefix"] = prefixStorage
|
||||
|
||||
storage.notify(name: "active") {
|
||||
active?.wrappedValue = adw_switch_row_get_active(storage.pointer) != 0
|
||||
}
|
||||
for function in appearFunctions {
|
||||
function(storage)
|
||||
}
|
||||
return storage
|
||||
}
|
||||
|
||||
/// Update the widget's view storage.
|
||||
/// - Parameters:
|
||||
/// - storage: The view storage.
|
||||
/// - modifiers: The view modifiers.
|
||||
public func update(_ storage: ViewStorage, modifiers: [(View) -> View]) {
|
||||
if let activated {
|
||||
storage.connectSignal(name: "activated") {
|
||||
activated()
|
||||
}
|
||||
}
|
||||
storage.modify { widget in
|
||||
if let active {
|
||||
adw_switch_row_set_active(widget, active.wrappedValue.cBool)
|
||||
}
|
||||
if let widget = storage.content["activatableWidget"]?.first {
|
||||
activatableWidget?().widget(modifiers: modifiers).update(widget, modifiers: modifiers)
|
||||
}
|
||||
if let iconName {
|
||||
adw_action_row_set_icon_name(widget?.cast(), iconName)
|
||||
}
|
||||
if let subtitle {
|
||||
adw_action_row_set_subtitle(widget?.cast(), subtitle)
|
||||
}
|
||||
if let subtitleLines {
|
||||
adw_action_row_set_subtitle_lines(widget?.cast(), subtitleLines.cInt)
|
||||
}
|
||||
if let subtitleSelectable {
|
||||
adw_action_row_set_subtitle_selectable(widget?.cast(), subtitleSelectable.cBool)
|
||||
}
|
||||
if let titleLines {
|
||||
adw_action_row_set_title_lines(widget?.cast(), titleLines.cInt)
|
||||
}
|
||||
if let title {
|
||||
adw_preferences_row_set_title(widget?.cast(), title)
|
||||
}
|
||||
if let titleSelectable {
|
||||
adw_preferences_row_set_title_selectable(widget?.cast(), titleSelectable.cBool)
|
||||
}
|
||||
if let useMarkup {
|
||||
adw_preferences_row_set_use_markup(widget?.cast(), useMarkup.cBool)
|
||||
}
|
||||
if let useUnderline {
|
||||
adw_preferences_row_set_use_underline(widget?.cast(), useUnderline.cBool)
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
for function in updateFunctions {
|
||||
function(storage)
|
||||
}
|
||||
}
|
||||
|
||||
/// Whether the switch row is in the "on" or "off" position.
|
||||
public func active(_ active: Binding<Bool>?) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.active = active
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// The widget to activate when the row is activated.
|
||||
///
|
||||
/// The row can be activated either by clicking on it, calling
|
||||
/// [method@ActionRow.activate], or via mnemonics in the title.
|
||||
/// See the [property@PreferencesRow:use-underline] property to enable
|
||||
/// mnemonics.
|
||||
///
|
||||
/// The target widget will be activated by emitting the
|
||||
/// [signal@Gtk.Widget::mnemonic-activate] signal on it.
|
||||
public func activatableWidget(@ViewBuilder _ activatableWidget: @escaping (() -> Body)) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.activatableWidget = activatableWidget
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// The icon name for this row.
|
||||
public func iconName(_ iconName: String?) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.iconName = iconName
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// The subtitle for this row.
|
||||
///
|
||||
/// The subtitle is interpreted as Pango markup unless
|
||||
/// [property@PreferencesRow:use-markup] is set to `FALSE`.
|
||||
public func subtitle(_ subtitle: String?) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.subtitle = subtitle
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// The number of lines at the end of which the subtitle label will be
|
||||
/// ellipsized.
|
||||
///
|
||||
/// If the value is 0, the number of lines won't be limited.
|
||||
public func subtitleLines(_ subtitleLines: Int?) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.subtitleLines = subtitleLines
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// Whether the user can copy the subtitle from the label.
|
||||
///
|
||||
/// See also [property@Gtk.Label:selectable].
|
||||
public func subtitleSelectable(_ subtitleSelectable: Bool? = true) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.subtitleSelectable = subtitleSelectable
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// The number of lines at the end of which the title label will be ellipsized.
|
||||
///
|
||||
/// If the value is 0, the number of lines won't be limited.
|
||||
public func titleLines(_ titleLines: Int?) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.titleLines = titleLines
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// The title of the preference represented by this row.
|
||||
///
|
||||
/// The title is interpreted as Pango markup unless
|
||||
/// [property@PreferencesRow:use-markup] is set to `FALSE`.
|
||||
public func title(_ title: String?) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.title = title
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// Whether the user can copy the title from the label.
|
||||
///
|
||||
/// See also [property@Gtk.Label:selectable].
|
||||
public func titleSelectable(_ titleSelectable: Bool? = true) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.titleSelectable = titleSelectable
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// Whether to use Pango markup for the title label.
|
||||
///
|
||||
/// Subclasses may also use it for other labels, such as subtitle.
|
||||
///
|
||||
/// See also [func@Pango.parse_markup].
|
||||
public func useMarkup(_ useMarkup: Bool? = true) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.useMarkup = useMarkup
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// Whether an embedded underline in the title indicates a mnemonic.
|
||||
public func useUnderline(_ useUnderline: Bool? = true) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.useUnderline = useUnderline
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// This signal is emitted after the row has been activated.
|
||||
public func activated(_ activated: @escaping () -> Void) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.activated = activated
|
||||
return newSelf
|
||||
}
|
||||
|
||||
}
|
108
Sources/Adwaita/View/Generated/ToastOverlay.swift
Normal file
108
Sources/Adwaita/View/Generated/ToastOverlay.swift
Normal file
@ -0,0 +1,108 @@
|
||||
//
|
||||
// ToastOverlay.swift
|
||||
// Adwaita
|
||||
//
|
||||
// Created by auto-generation on 22.01.24.
|
||||
//
|
||||
|
||||
import CAdw
|
||||
import LevenshteinTransformations
|
||||
|
||||
/// A widget showing toasts above its content.
|
||||
///
|
||||
/// <picture><source srcset="toast-overlay-dark.png" media="(prefers-color-scheme: dark)"><img src="toast-overlay.png" alt="toast-overlay"></picture>
|
||||
///
|
||||
/// Much like [class@Gtk.Overlay], `AdwToastOverlay` is a container with a single
|
||||
/// main child, on top of which it can display a [class@Toast], overlaid.
|
||||
/// Toasts can be shown with [method@ToastOverlay.add_toast].
|
||||
///
|
||||
/// See [class@Toast] for details.
|
||||
///
|
||||
/// ## CSS nodes
|
||||
///
|
||||
/// ```
|
||||
/// toastoverlay
|
||||
/// ├── [child]
|
||||
/// ├── toast
|
||||
/// ┊ ├── widget
|
||||
/// ┊ │ ├── [label.heading]
|
||||
/// │ ╰── [custom title]
|
||||
/// ├── [button]
|
||||
/// ╰── button.circular.flat
|
||||
/// ```
|
||||
///
|
||||
/// `AdwToastOverlay`'s CSS node is called `toastoverlay`. It contains the child,
|
||||
/// as well as zero or more `toast` subnodes.
|
||||
///
|
||||
/// Each of the `toast` nodes contains a `widget` subnode, optionally a `button`
|
||||
/// subnode, and another `button` subnode with `.circular` and `.flat` style
|
||||
/// classes.
|
||||
///
|
||||
/// The `widget` subnode contains a `label` subnode with the `.heading` style
|
||||
/// class, or a custom widget provided by the application.
|
||||
///
|
||||
/// ## Accessibility
|
||||
///
|
||||
/// `AdwToastOverlay` uses the `GTK_ACCESSIBLE_ROLE_TAB_GROUP` role.
|
||||
public struct ToastOverlay: Widget {
|
||||
|
||||
/// Additional update functions for type extensions.
|
||||
var updateFunctions: [(ViewStorage) -> Void] = []
|
||||
/// Additional appear functions for type extensions.
|
||||
var appearFunctions: [(ViewStorage) -> Void] = []
|
||||
|
||||
/// The child widget.
|
||||
var child: (() -> Body)?
|
||||
/// The application.
|
||||
var app: GTUIApp?
|
||||
/// The window.
|
||||
var window: GTUIApplicationWindow?
|
||||
|
||||
/// Initialize `ToastOverlay`.
|
||||
public init() {
|
||||
}
|
||||
|
||||
/// Get the widget's view storage.
|
||||
/// - Parameter modifiers: The view modifiers.
|
||||
/// - Returns: The view storage.
|
||||
public func container(modifiers: [(View) -> View]) -> ViewStorage {
|
||||
let storage = ViewStorage(adw_toast_overlay_new()?.opaque())
|
||||
update(storage, modifiers: modifiers)
|
||||
if let childStorage = child?().widget(modifiers: modifiers).storage(modifiers: modifiers) {
|
||||
storage.content["child"] = [childStorage]
|
||||
adw_toast_overlay_set_child(storage.pointer, childStorage.pointer?.cast())
|
||||
}
|
||||
|
||||
|
||||
for function in appearFunctions {
|
||||
function(storage)
|
||||
}
|
||||
return storage
|
||||
}
|
||||
|
||||
/// Update the widget's view storage.
|
||||
/// - Parameters:
|
||||
/// - storage: The view storage.
|
||||
/// - modifiers: The view modifiers.
|
||||
public func update(_ storage: ViewStorage, modifiers: [(View) -> View]) {
|
||||
storage.modify { widget in
|
||||
if let widget = storage.content["child"]?.first {
|
||||
child?().widget(modifiers: modifiers).update(widget, modifiers: modifiers)
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
for function in updateFunctions {
|
||||
function(storage)
|
||||
}
|
||||
}
|
||||
|
||||
/// The child widget.
|
||||
public func child(@ViewBuilder _ child: @escaping (() -> Body)) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.child = child
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
}
|
296
Sources/Adwaita/View/Generated/ToggleButton.swift
Normal file
296
Sources/Adwaita/View/Generated/ToggleButton.swift
Normal file
@ -0,0 +1,296 @@
|
||||
//
|
||||
// ToggleButton.swift
|
||||
// Adwaita
|
||||
//
|
||||
// Created by auto-generation on 22.01.24.
|
||||
//
|
||||
|
||||
import CAdw
|
||||
import LevenshteinTransformations
|
||||
|
||||
/// A `GtkToggleButton` is a button which remains “pressed-in” when
|
||||
/// clicked.
|
||||
///
|
||||
/// Clicking again will cause the toggle button to return to its normal state.
|
||||
///
|
||||
/// A toggle button is created by calling either [ctor@Gtk.ToggleButton.new] or
|
||||
/// [ctor@Gtk.ToggleButton.new_with_label]. If using the former, it is advisable
|
||||
/// to pack a widget, (such as a `GtkLabel` and/or a `GtkImage`), into the toggle
|
||||
/// button’s container. (See [class@Gtk.Button] for more information).
|
||||
///
|
||||
/// The state of a `GtkToggleButton` can be set specifically using
|
||||
/// [method@Gtk.ToggleButton.set_active], and retrieved using
|
||||
/// [method@Gtk.ToggleButton.get_active].
|
||||
///
|
||||
/// To simply switch the state of a toggle button, use
|
||||
/// [method@Gtk.ToggleButton.toggled].
|
||||
///
|
||||
/// ## Grouping
|
||||
///
|
||||
/// Toggle buttons can be grouped together, to form mutually exclusive
|
||||
/// groups - only one of the buttons can be toggled at a time, and toggling
|
||||
/// another one will switch the currently toggled one off.
|
||||
///
|
||||
/// To add a `GtkToggleButton` to a group, use [method@Gtk.ToggleButton.set_group].
|
||||
///
|
||||
/// ## CSS nodes
|
||||
///
|
||||
/// `GtkToggleButton` has a single CSS node with name button. To differentiate
|
||||
/// it from a plain `GtkButton`, it gets the `.toggle` style class.
|
||||
///
|
||||
/// ## Accessibility
|
||||
///
|
||||
/// `GtkToggleButton` uses the %GTK_ACCESSIBLE_ROLE_TOGGLE_BUTTON role.
|
||||
///
|
||||
/// ## Creating two `GtkToggleButton` widgets.
|
||||
///
|
||||
/// ```c
|
||||
/// static void
|
||||
/// output_state (GtkToggleButton *source,
|
||||
/// gpointer user_data)
|
||||
/// {
|
||||
/// g_print ("Toggle button "%s" is active: %s",
|
||||
/// gtk_button_get_label (GTK_BUTTON (source)),
|
||||
/// gtk_toggle_button_get_active (source) ? "Yes" : "No");
|
||||
/// }
|
||||
///
|
||||
/// static void
|
||||
/// make_toggles (void)
|
||||
/// {
|
||||
/// GtkWidget *window, *toggle1, *toggle2;
|
||||
/// GtkWidget *box;
|
||||
/// const char *text;
|
||||
///
|
||||
/// window = gtk_window_new ();
|
||||
/// box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 12);
|
||||
///
|
||||
/// text = "Hi, I’m toggle button one";
|
||||
/// toggle1 = gtk_toggle_button_new_with_label (text);
|
||||
///
|
||||
/// g_signal_connect (toggle1, "toggled",
|
||||
/// G_CALLBACK (output_state),
|
||||
/// NULL);
|
||||
/// gtk_box_append (GTK_BOX (box), toggle1);
|
||||
///
|
||||
/// text = "Hi, I’m toggle button two";
|
||||
/// toggle2 = gtk_toggle_button_new_with_label (text);
|
||||
/// g_signal_connect (toggle2, "toggled",
|
||||
/// G_CALLBACK (output_state),
|
||||
/// NULL);
|
||||
/// gtk_box_append (GTK_BOX (box), toggle2);
|
||||
///
|
||||
/// gtk_window_set_child (GTK_WINDOW (window), box);
|
||||
/// gtk_window_present (GTK_WINDOW (window));
|
||||
/// }
|
||||
/// ```
|
||||
public struct ToggleButton: Widget {
|
||||
|
||||
/// Additional update functions for type extensions.
|
||||
var updateFunctions: [(ViewStorage) -> Void] = []
|
||||
/// Additional appear functions for type extensions.
|
||||
var appearFunctions: [(ViewStorage) -> Void] = []
|
||||
|
||||
/// If the toggle button should be pressed in.
|
||||
var active: Binding<Bool>?
|
||||
/// Whether the size of the button can be made smaller than the natural
|
||||
/// size of its contents.
|
||||
///
|
||||
/// For text buttons, setting this property will allow ellipsizing the label.
|
||||
///
|
||||
/// If the contents of a button are an icon or a custom widget, setting this
|
||||
/// property has no effect.
|
||||
var canShrink: Bool?
|
||||
/// The child widget.
|
||||
var child: (() -> Body)?
|
||||
/// Whether the button has a frame.
|
||||
var hasFrame: Bool?
|
||||
/// The name of the icon used to automatically populate the button.
|
||||
var iconName: String?
|
||||
/// Text of the label inside the button, if the button contains a label widget.
|
||||
var label: String?
|
||||
/// If set, an underline in the text indicates that the following character is
|
||||
/// to be used as mnemonic.
|
||||
var useUnderline: Bool?
|
||||
/// Emitted whenever the `GtkToggleButton`'s state is changed.
|
||||
var toggled: (() -> Void)?
|
||||
/// Emitted to animate press then release.
|
||||
///
|
||||
/// This is an action signal. Applications should never connect
|
||||
/// to this signal, but use the [signal@Gtk.Button::clicked] signal.
|
||||
///
|
||||
/// The default bindings for this signal are all forms of the
|
||||
/// <kbd>␣</kbd> and <kbd>Enter</kbd> keys.
|
||||
var activate: (() -> Void)?
|
||||
/// Emitted when the button has been activated (pressed and released).
|
||||
var clicked: (() -> Void)?
|
||||
/// The application.
|
||||
var app: GTUIApp?
|
||||
/// The window.
|
||||
var window: GTUIApplicationWindow?
|
||||
|
||||
/// Initialize `ToggleButton`.
|
||||
public init() {
|
||||
}
|
||||
|
||||
/// Get the widget's view storage.
|
||||
/// - Parameter modifiers: The view modifiers.
|
||||
/// - Returns: The view storage.
|
||||
public func container(modifiers: [(View) -> View]) -> ViewStorage {
|
||||
let storage = ViewStorage(gtk_toggle_button_new()?.opaque())
|
||||
update(storage, modifiers: modifiers)
|
||||
if let childStorage = child?().widget(modifiers: modifiers).storage(modifiers: modifiers) {
|
||||
storage.content["child"] = [childStorage]
|
||||
gtk_button_set_child(storage.pointer?.cast(), childStorage.pointer?.cast())
|
||||
}
|
||||
|
||||
|
||||
storage.notify(name: "active") {
|
||||
active?.wrappedValue = gtk_toggle_button_get_active(storage.pointer?.cast()) != 0
|
||||
}
|
||||
for function in appearFunctions {
|
||||
function(storage)
|
||||
}
|
||||
return storage
|
||||
}
|
||||
|
||||
/// Update the widget's view storage.
|
||||
/// - Parameters:
|
||||
/// - storage: The view storage.
|
||||
/// - modifiers: The view modifiers.
|
||||
public func update(_ storage: ViewStorage, modifiers: [(View) -> View]) {
|
||||
if let toggled {
|
||||
storage.connectSignal(name: "toggled") {
|
||||
toggled()
|
||||
}
|
||||
}
|
||||
if let activate {
|
||||
storage.connectSignal(name: "activate") {
|
||||
activate()
|
||||
}
|
||||
}
|
||||
if let clicked {
|
||||
storage.connectSignal(name: "clicked") {
|
||||
clicked()
|
||||
}
|
||||
}
|
||||
storage.modify { widget in
|
||||
if let active {
|
||||
gtk_toggle_button_set_active(widget?.cast(), active.wrappedValue.cBool)
|
||||
}
|
||||
if let canShrink {
|
||||
gtk_button_set_can_shrink(widget?.cast(), canShrink.cBool)
|
||||
}
|
||||
if let widget = storage.content["child"]?.first {
|
||||
child?().widget(modifiers: modifiers).update(widget, modifiers: modifiers)
|
||||
}
|
||||
if let hasFrame {
|
||||
gtk_button_set_has_frame(widget?.cast(), hasFrame.cBool)
|
||||
}
|
||||
if let iconName {
|
||||
gtk_button_set_icon_name(widget?.cast(), iconName)
|
||||
}
|
||||
if let label, storage.content["child"] == nil {
|
||||
gtk_button_set_label(widget?.cast(), label)
|
||||
}
|
||||
if let useUnderline {
|
||||
gtk_button_set_use_underline(widget?.cast(), useUnderline.cBool)
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
for function in updateFunctions {
|
||||
function(storage)
|
||||
}
|
||||
}
|
||||
|
||||
/// If the toggle button should be pressed in.
|
||||
public func active(_ active: Binding<Bool>?) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.active = active
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// Whether the size of the button can be made smaller than the natural
|
||||
/// size of its contents.
|
||||
///
|
||||
/// For text buttons, setting this property will allow ellipsizing the label.
|
||||
///
|
||||
/// If the contents of a button are an icon or a custom widget, setting this
|
||||
/// property has no effect.
|
||||
public func canShrink(_ canShrink: Bool? = true) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.canShrink = canShrink
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// The child widget.
|
||||
public func child(@ViewBuilder _ child: @escaping (() -> Body)) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.child = child
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// Whether the button has a frame.
|
||||
public func hasFrame(_ hasFrame: Bool? = true) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.hasFrame = hasFrame
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// The name of the icon used to automatically populate the button.
|
||||
public func iconName(_ iconName: String?) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.iconName = iconName
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// Text of the label inside the button, if the button contains a label widget.
|
||||
public func label(_ label: String?) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.label = label
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// If set, an underline in the text indicates that the following character is
|
||||
/// to be used as mnemonic.
|
||||
public func useUnderline(_ useUnderline: Bool? = true) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.useUnderline = useUnderline
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// Emitted whenever the `GtkToggleButton`'s state is changed.
|
||||
public func toggled(_ toggled: @escaping () -> Void) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.toggled = toggled
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// Emitted to animate press then release.
|
||||
///
|
||||
/// This is an action signal. Applications should never connect
|
||||
/// to this signal, but use the [signal@Gtk.Button::clicked] signal.
|
||||
///
|
||||
/// The default bindings for this signal are all forms of the
|
||||
/// <kbd>␣</kbd> and <kbd>Enter</kbd> keys.
|
||||
public func activate(_ activate: @escaping () -> Void) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.activate = activate
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// Emitted when the button has been activated (pressed and released).
|
||||
public func clicked(_ clicked: @escaping () -> Void) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.clicked = clicked
|
||||
return newSelf
|
||||
}
|
||||
|
||||
}
|
332
Sources/Adwaita/View/Generated/ToolbarView.swift
Normal file
332
Sources/Adwaita/View/Generated/ToolbarView.swift
Normal file
@ -0,0 +1,332 @@
|
||||
//
|
||||
// ToolbarView.swift
|
||||
// Adwaita
|
||||
//
|
||||
// Created by auto-generation on 22.01.24.
|
||||
//
|
||||
|
||||
import CAdw
|
||||
import LevenshteinTransformations
|
||||
|
||||
/// A widget containing a page, as well as top and/or bottom bars.
|
||||
///
|
||||
/// <picture><source srcset="toolbar-view-dark.png" media="(prefers-color-scheme: dark)"><img src="toolbar-view.png" alt="toolbar-view"></picture>
|
||||
///
|
||||
/// `AdwToolbarView` has a single content widget and one or multiple top and
|
||||
/// bottom bars, shown at the top and bottom sides respectively.
|
||||
///
|
||||
/// Example of an `AdwToolbarView` UI definition:
|
||||
/// ```xml
|
||||
/// <object class="AdwToolbarView"><child type="top"><object class="AdwHeaderBar"/></child><property name="content"><object class="AdwPreferencesPage"><!-- ... --></object></property></object>
|
||||
/// ```
|
||||
///
|
||||
/// The following kinds of top and bottom bars are supported:
|
||||
///
|
||||
/// - [class@HeaderBar]
|
||||
/// - [class@TabBar]
|
||||
/// - [class@ViewSwitcherBar]
|
||||
/// - [class@Gtk.ActionBar]
|
||||
/// - [class@Gtk.HeaderBar]
|
||||
/// - [class@Gtk.PopoverMenuBar]
|
||||
/// - [class@Gtk.SearchBar]
|
||||
/// - Any [class@Gtk.Box] or a similar widget with the
|
||||
/// [`.toolbar`](style-classes.html#toolbars) style class
|
||||
///
|
||||
/// By default, top and bottom bars are flat and scrolling content has a subtle
|
||||
/// undershoot shadow, same as when using the
|
||||
/// [`.undershoot-top`](style-classes.html#undershot-indicators) and
|
||||
/// [`.undershoot-bottom`](style-classes.html#undershot-indicators) style
|
||||
/// classes. This works well in most cases, e.g. with [class@StatusPage] or
|
||||
/// [class@PreferencesPage], where the background at the top and bottom parts of
|
||||
/// the page is uniform. Additionally, windows with sidebars should always use
|
||||
/// this style.
|
||||
///
|
||||
/// [property@ToolbarView:top-bar-style] and
|
||||
/// [property@ToolbarView:bottom-bar-style] properties can be used add an opaque
|
||||
/// background and a persistent shadow to top and bottom bars, this can be useful
|
||||
/// for content such as [utility panes](https://developer.gnome.org/hig/patterns/containers/utility-panes.html),
|
||||
/// where some elements are adjacent to the top/bottom bars, or [class@TabView],
|
||||
/// where each page can have a different background.
|
||||
///
|
||||
/// <picture style="min-width: 33%; display: inline-block;"><source srcset="toolbar-view-flat-1-dark.png" media="(prefers-color-scheme: dark)"><img src="toolbar-view-flat-1.png" alt="toolbar-view-flat-1"></picture><picture style="min-width: 33%; display: inline-block;"><source srcset="toolbar-view-flat-2-dark.png" media="(prefers-color-scheme: dark)"><img src="toolbar-view-flat-2.png" alt="toolbar-view-flat-2"></picture><picture style="min-width: 33%; display: inline-block;"><source srcset="toolbar-view-raised-dark.png" media="(prefers-color-scheme: dark)"><img src="toolbar-view-raised.png" alt="toolbar-view-raised"></picture>
|
||||
///
|
||||
/// `AdwToolbarView` ensures the top and bottom bars have consistent backdrop
|
||||
/// styles and vertical spacing. For comparison:
|
||||
///
|
||||
/// <picture style="min-width: 40%; display: inline-block;"><source srcset="toolbar-view-spacing-dark.png" media="(prefers-color-scheme: dark)"><img src="toolbar-view-spacing.png" alt="toolbar-view-spacing"></picture><picture style="min-width: 40%; display: inline-block;"><source srcset="toolbar-view-spacing-box-dark.png" media="(prefers-color-scheme: dark)"><img src="toolbar-view-spacing-box.png" alt="toolbar-view-spacing-box"></picture>
|
||||
///
|
||||
/// Any top and bottom bars can also be dragged to move the window, equivalent
|
||||
/// to putting them into a [class@Gtk.WindowHandle].
|
||||
///
|
||||
/// Content is typically place between top and bottom bars, but can also extend
|
||||
/// behind them. This is controlled with the
|
||||
/// [property@ToolbarView:extend-content-to-top-edge] and
|
||||
/// [property@ToolbarView:extend-content-to-bottom-edge] properties.
|
||||
///
|
||||
/// Top and bottom bars can be hidden and revealed with an animation using the
|
||||
/// [property@ToolbarView:reveal-top-bars] and
|
||||
/// [property@ToolbarView:reveal-bottom-bars] properties.
|
||||
///
|
||||
/// ## `AdwToolbarView` as `GtkBuildable`
|
||||
///
|
||||
/// The `AdwToolbarView` implementation of the [iface@Gtk.Buildable] interface
|
||||
/// supports adding a top bar by specifying “top” as the “type” attribute of a
|
||||
/// `<child>` element, or adding a bottom bar by specifying “bottom”.
|
||||
///
|
||||
/// ## Accessibility
|
||||
///
|
||||
/// `AdwToolbarView` uses the `GTK_ACCESSIBLE_ROLE_GROUP` role.
|
||||
public struct ToolbarView: Widget {
|
||||
|
||||
/// Additional update functions for type extensions.
|
||||
var updateFunctions: [(ViewStorage) -> Void] = []
|
||||
/// Additional appear functions for type extensions.
|
||||
var appearFunctions: [(ViewStorage) -> Void] = []
|
||||
|
||||
/// The current bottom bar height.
|
||||
///
|
||||
/// Bottom bar height does change depending on
|
||||
/// [property@ToolbarView:reveal-bottom-bars], including during the transition.
|
||||
///
|
||||
/// See [property@ToolbarView:top-bar-height].
|
||||
var bottomBarHeight: Int?
|
||||
/// The content widget.
|
||||
var content: (() -> Body)?
|
||||
/// Whether the content widget can extend behind bottom bars.
|
||||
///
|
||||
/// This can be used in combination with
|
||||
/// [property@ToolbarView:reveal-bottom-bars] to show and hide toolbars in
|
||||
/// fullscreen.
|
||||
///
|
||||
/// See [property@ToolbarView:extend-content-to-top-edge].
|
||||
var extendContentToBottomEdge: Bool?
|
||||
/// Whether the content widget can extend behind top bars.
|
||||
///
|
||||
/// This can be used in combination with [property@ToolbarView:reveal-top-bars]
|
||||
/// to show and hide toolbars in fullscreen.
|
||||
///
|
||||
/// See [property@ToolbarView:extend-content-to-bottom-edge].
|
||||
var extendContentToTopEdge: Bool?
|
||||
/// Whether bottom bars are visible.
|
||||
///
|
||||
/// The transition will be animated.
|
||||
///
|
||||
/// This can be used in combination with
|
||||
/// [property@ToolbarView:extend-content-to-bottom-edge] to show and hide
|
||||
/// toolbars in fullscreen.
|
||||
///
|
||||
/// See [property@ToolbarView:reveal-top-bars].
|
||||
var revealBottomBars: Bool?
|
||||
/// Whether top bars are revealed.
|
||||
///
|
||||
/// The transition will be animated.
|
||||
///
|
||||
/// This can be used in combination with
|
||||
/// [property@ToolbarView:extend-content-to-top-edge] to show and hide toolbars
|
||||
/// in fullscreen.
|
||||
///
|
||||
/// See [property@ToolbarView:reveal-bottom-bars].
|
||||
var revealTopBars: Bool?
|
||||
/// The current top bar height.
|
||||
///
|
||||
/// Top bar height does change depending [property@ToolbarView:reveal-top-bars],
|
||||
/// including during the transition.
|
||||
///
|
||||
/// See [property@ToolbarView:bottom-bar-height].
|
||||
var topBarHeight: Int?
|
||||
/// The body for the widget "bottom".
|
||||
var bottom: () -> Body = { [] }
|
||||
/// The body for the widget "top".
|
||||
var top: () -> Body = { [] }
|
||||
/// The application.
|
||||
var app: GTUIApp?
|
||||
/// The window.
|
||||
var window: GTUIApplicationWindow?
|
||||
|
||||
/// Initialize `ToolbarView`.
|
||||
public init() {
|
||||
}
|
||||
|
||||
/// Get the widget's view storage.
|
||||
/// - Parameter modifiers: The view modifiers.
|
||||
/// - Returns: The view storage.
|
||||
public func container(modifiers: [(View) -> View]) -> ViewStorage {
|
||||
let storage = ViewStorage(adw_toolbar_view_new()?.opaque())
|
||||
update(storage, modifiers: modifiers)
|
||||
if let contentStorage = content?().widget(modifiers: modifiers).storage(modifiers: modifiers) {
|
||||
storage.content["content"] = [contentStorage]
|
||||
adw_toolbar_view_set_content(storage.pointer, contentStorage.pointer?.cast())
|
||||
}
|
||||
|
||||
var bottomStorage: [ViewStorage] = []
|
||||
for view in bottom() {
|
||||
bottomStorage.append(view.storage(modifiers: modifiers))
|
||||
adw_toolbar_view_add_bottom_bar(storage.pointer, bottomStorage.last?.pointer?.cast())
|
||||
}
|
||||
storage.content["bottom"] = bottomStorage
|
||||
var topStorage: [ViewStorage] = []
|
||||
for view in top() {
|
||||
topStorage.append(view.storage(modifiers: modifiers))
|
||||
adw_toolbar_view_add_top_bar(storage.pointer, topStorage.last?.pointer?.cast())
|
||||
}
|
||||
storage.content["top"] = topStorage
|
||||
|
||||
for function in appearFunctions {
|
||||
function(storage)
|
||||
}
|
||||
return storage
|
||||
}
|
||||
|
||||
/// Update the widget's view storage.
|
||||
/// - Parameters:
|
||||
/// - storage: The view storage.
|
||||
/// - modifiers: The view modifiers.
|
||||
public func update(_ storage: ViewStorage, modifiers: [(View) -> View]) {
|
||||
storage.modify { widget in
|
||||
if let widget = storage.content["content"]?.first {
|
||||
content?().widget(modifiers: modifiers).update(widget, modifiers: modifiers)
|
||||
}
|
||||
if let extendContentToBottomEdge {
|
||||
adw_toolbar_view_set_extend_content_to_bottom_edge(widget, extendContentToBottomEdge.cBool)
|
||||
}
|
||||
if let extendContentToTopEdge {
|
||||
adw_toolbar_view_set_extend_content_to_top_edge(widget, extendContentToTopEdge.cBool)
|
||||
}
|
||||
if let revealBottomBars {
|
||||
adw_toolbar_view_set_reveal_bottom_bars(widget, revealBottomBars.cBool)
|
||||
}
|
||||
if let revealTopBars {
|
||||
adw_toolbar_view_set_reveal_top_bars(widget, revealTopBars.cBool)
|
||||
}
|
||||
|
||||
if let bottomStorage = storage.content["bottom"] {
|
||||
for (index, view) in bottom().enumerated() {
|
||||
if let storage = bottomStorage[safe: index] {
|
||||
view.updateStorage(storage, modifiers: modifiers)
|
||||
}
|
||||
}
|
||||
}
|
||||
if let topStorage = storage.content["top"] {
|
||||
for (index, view) in top().enumerated() {
|
||||
if let storage = topStorage[safe: index] {
|
||||
view.updateStorage(storage, modifiers: modifiers)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
for function in updateFunctions {
|
||||
function(storage)
|
||||
}
|
||||
}
|
||||
|
||||
/// The current bottom bar height.
|
||||
///
|
||||
/// Bottom bar height does change depending on
|
||||
/// [property@ToolbarView:reveal-bottom-bars], including during the transition.
|
||||
///
|
||||
/// See [property@ToolbarView:top-bar-height].
|
||||
public func bottomBarHeight(_ bottomBarHeight: Int?) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.bottomBarHeight = bottomBarHeight
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// The content widget.
|
||||
public func content(@ViewBuilder _ content: @escaping (() -> Body)) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.content = content
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// Whether the content widget can extend behind bottom bars.
|
||||
///
|
||||
/// This can be used in combination with
|
||||
/// [property@ToolbarView:reveal-bottom-bars] to show and hide toolbars in
|
||||
/// fullscreen.
|
||||
///
|
||||
/// See [property@ToolbarView:extend-content-to-top-edge].
|
||||
public func extendContentToBottomEdge(_ extendContentToBottomEdge: Bool? = true) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.extendContentToBottomEdge = extendContentToBottomEdge
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// Whether the content widget can extend behind top bars.
|
||||
///
|
||||
/// This can be used in combination with [property@ToolbarView:reveal-top-bars]
|
||||
/// to show and hide toolbars in fullscreen.
|
||||
///
|
||||
/// See [property@ToolbarView:extend-content-to-bottom-edge].
|
||||
public func extendContentToTopEdge(_ extendContentToTopEdge: Bool? = true) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.extendContentToTopEdge = extendContentToTopEdge
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// Whether bottom bars are visible.
|
||||
///
|
||||
/// The transition will be animated.
|
||||
///
|
||||
/// This can be used in combination with
|
||||
/// [property@ToolbarView:extend-content-to-bottom-edge] to show and hide
|
||||
/// toolbars in fullscreen.
|
||||
///
|
||||
/// See [property@ToolbarView:reveal-top-bars].
|
||||
public func revealBottomBars(_ revealBottomBars: Bool? = true) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.revealBottomBars = revealBottomBars
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// Whether top bars are revealed.
|
||||
///
|
||||
/// The transition will be animated.
|
||||
///
|
||||
/// This can be used in combination with
|
||||
/// [property@ToolbarView:extend-content-to-top-edge] to show and hide toolbars
|
||||
/// in fullscreen.
|
||||
///
|
||||
/// See [property@ToolbarView:reveal-bottom-bars].
|
||||
public func revealTopBars(_ revealTopBars: Bool? = true) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.revealTopBars = revealTopBars
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// The current top bar height.
|
||||
///
|
||||
/// Top bar height does change depending [property@ToolbarView:reveal-top-bars],
|
||||
/// including during the transition.
|
||||
///
|
||||
/// See [property@ToolbarView:bottom-bar-height].
|
||||
public func topBarHeight(_ topBarHeight: Int?) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.topBarHeight = topBarHeight
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// Set the body for "bottom".
|
||||
/// - Parameter body: The body.
|
||||
/// - Returns: The widget.
|
||||
public func bottom(@ViewBuilder _ body: @escaping () -> Body) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.bottom = body
|
||||
return newSelf
|
||||
}
|
||||
/// Set the body for "top".
|
||||
/// - Parameter body: The body.
|
||||
/// - Returns: The widget.
|
||||
public func top(@ViewBuilder _ body: @escaping () -> Body) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.top = body
|
||||
return newSelf
|
||||
}
|
||||
}
|
99
Sources/Adwaita/View/Generated/WindowTitle.swift
Normal file
99
Sources/Adwaita/View/Generated/WindowTitle.swift
Normal file
@ -0,0 +1,99 @@
|
||||
//
|
||||
// WindowTitle.swift
|
||||
// Adwaita
|
||||
//
|
||||
// Created by auto-generation on 22.01.24.
|
||||
//
|
||||
|
||||
import CAdw
|
||||
import LevenshteinTransformations
|
||||
|
||||
/// A helper widget for setting a window's title and subtitle.
|
||||
///
|
||||
/// <picture><source srcset="window-title-dark.png" media="(prefers-color-scheme: dark)"><img src="window-title.png" alt="window-title"></picture>
|
||||
///
|
||||
/// `AdwWindowTitle` shows a title and subtitle. It's intended to be used as the
|
||||
/// title child of [class@Gtk.HeaderBar] or [class@HeaderBar].
|
||||
///
|
||||
/// ## CSS nodes
|
||||
///
|
||||
/// `AdwWindowTitle` has a single CSS node with name `windowtitle`.
|
||||
public struct WindowTitle: Widget {
|
||||
|
||||
/// Additional update functions for type extensions.
|
||||
var updateFunctions: [(ViewStorage) -> Void] = []
|
||||
/// Additional appear functions for type extensions.
|
||||
var appearFunctions: [(ViewStorage) -> Void] = []
|
||||
|
||||
/// The subtitle to display.
|
||||
///
|
||||
/// The subtitle should give the user additional details.
|
||||
var subtitle: String
|
||||
/// The title to display.
|
||||
///
|
||||
/// The title typically identifies the current view or content item, and
|
||||
/// generally does not use the application name.
|
||||
var title: String
|
||||
/// The application.
|
||||
var app: GTUIApp?
|
||||
/// The window.
|
||||
var window: GTUIApplicationWindow?
|
||||
|
||||
/// Initialize `WindowTitle`.
|
||||
public init(subtitle: String, title: String) {
|
||||
self.subtitle = subtitle
|
||||
self.title = title
|
||||
}
|
||||
|
||||
/// Get the widget's view storage.
|
||||
/// - Parameter modifiers: The view modifiers.
|
||||
/// - Returns: The view storage.
|
||||
public func container(modifiers: [(View) -> View]) -> ViewStorage {
|
||||
let storage = ViewStorage(adw_window_title_new(title, subtitle)?.opaque())
|
||||
update(storage, modifiers: modifiers)
|
||||
|
||||
|
||||
for function in appearFunctions {
|
||||
function(storage)
|
||||
}
|
||||
return storage
|
||||
}
|
||||
|
||||
/// Update the widget's view storage.
|
||||
/// - Parameters:
|
||||
/// - storage: The view storage.
|
||||
/// - modifiers: The view modifiers.
|
||||
public func update(_ storage: ViewStorage, modifiers: [(View) -> View]) {
|
||||
storage.modify { widget in
|
||||
adw_window_title_set_subtitle(widget, subtitle)
|
||||
adw_window_title_set_title(widget, title)
|
||||
|
||||
|
||||
}
|
||||
for function in updateFunctions {
|
||||
function(storage)
|
||||
}
|
||||
}
|
||||
|
||||
/// The subtitle to display.
|
||||
///
|
||||
/// The subtitle should give the user additional details.
|
||||
public func subtitle(_ subtitle: String) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.subtitle = subtitle
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// The title to display.
|
||||
///
|
||||
/// The title typically identifies the current view or content item, and
|
||||
/// generally does not use the application name.
|
||||
public func title(_ title: String) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.title = title
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
}
|
@ -5,40 +5,21 @@
|
||||
// Created by david-swift on 26.09.23.
|
||||
//
|
||||
|
||||
import Libadwaita
|
||||
|
||||
/// A horizontal GtkBox equivalent.
|
||||
public struct HStack: Widget {
|
||||
public struct HStack: View {
|
||||
|
||||
/// The content.
|
||||
var content: () -> Body
|
||||
|
||||
/// The view's body.
|
||||
public var view: Body {
|
||||
VStack(horizontal: true, content: content)
|
||||
}
|
||||
|
||||
/// Initialize a `HStack`.
|
||||
/// - Parameter content: The view content.
|
||||
public init(@ViewBuilder content: @escaping () -> Body) {
|
||||
self.content = content
|
||||
}
|
||||
|
||||
/// Update a view storage.
|
||||
/// - Parameters:
|
||||
/// - storage: The view storage.
|
||||
/// - modifiers: Modify views before being updated.
|
||||
public func update(_ storage: ViewStorage, modifiers: [(View) -> View]) {
|
||||
content().update(storage.content[.mainContent] ?? [], modifiers: modifiers)
|
||||
}
|
||||
|
||||
/// Get a view storage.
|
||||
/// - Parameter modifiers: Modify views before being updated.
|
||||
/// - Returns: The view storage.
|
||||
public func container(modifiers: [(View) -> View]) -> ViewStorage {
|
||||
let box: Box = .init(horizontal: true)
|
||||
var content: [ViewStorage] = []
|
||||
for element in self.content() {
|
||||
let widget = element.storage(modifiers: modifiers)
|
||||
_ = box.append(widget.view)
|
||||
content.append(widget)
|
||||
}
|
||||
return .init(box, content: [.mainContent: content])
|
||||
}
|
||||
|
||||
}
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user