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:
|
validations:
|
||||||
required: false
|
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
|
- type: textarea
|
||||||
attributes:
|
attributes:
|
||||||
label: Describe your idea for the implementation.
|
label: Describe your idea for the implementation.
|
||||||
|
|||||||
@ -160,3 +160,6 @@ type_contents_order:
|
|||||||
- view_life_cycle_method
|
- view_life_cycle_method
|
||||||
- ib_action
|
- ib_action
|
||||||
- other_method
|
- 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.
|
- `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.
|
- `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.
|
- `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`.
|
- `Tests` contains an example application for testing `Adwaita`.
|
||||||
|
|
||||||
### 4. Edit the Code
|
### 4. Edit the Code
|
||||||
|
|||||||
696
LICENSE.md
696
LICENSE.md
@ -1,675 +1,21 @@
|
|||||||
GNU GENERAL PUBLIC LICENSE
|
MIT License
|
||||||
Version 3, 29 June 2007
|
|
||||||
|
Copyright (c) 2024 david-swift
|
||||||
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
|
|
||||||
Everyone is permitted to copy and distribute verbatim copies
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
of this license document, but changing it is not allowed.
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
Preamble
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
The GNU General Public License is a free, copyleft license for
|
furnished to do so, subject to the following conditions:
|
||||||
software and other kinds of works.
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
The licenses for most software and other practical works are designed
|
copies or substantial portions of the Software.
|
||||||
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
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
share and change all versions of a program--to make sure it remains free
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
software for all its users. We, the Free Software Foundation, use the
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
GNU General Public License for most of our software; it applies also to
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
any other work released this way by its authors. You can apply it to
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
your programs, too.
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
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>.
|
|
||||||
|
|
||||||
|
|||||||
@ -15,25 +15,39 @@ let package = Package(
|
|||||||
.library(
|
.library(
|
||||||
name: "Adwaita",
|
name: "Adwaita",
|
||||||
targets: ["Adwaita"]
|
targets: ["Adwaita"]
|
||||||
|
),
|
||||||
|
.library(
|
||||||
|
name: "CAdw",
|
||||||
|
targets: ["CAdw"]
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
dependencies: [
|
dependencies: [
|
||||||
.package(url: "https://github.com/AparokshaUI/Libadwaita", from: "0.1.6"),
|
|
||||||
.package(
|
.package(
|
||||||
url: "https://github.com/david-swift/LevenshteinTransformations",
|
url: "https://github.com/david-swift/LevenshteinTransformations",
|
||||||
from: "0.1.1"
|
from: "0.1.1"
|
||||||
)
|
),
|
||||||
|
.package(url: "https://github.com/CoreOffice/XMLCoder", from: "0.17.1")
|
||||||
],
|
],
|
||||||
targets: [
|
targets: [
|
||||||
|
.systemLibrary(
|
||||||
|
name: "CAdw",
|
||||||
|
pkgConfig: "libadwaita-1"
|
||||||
|
),
|
||||||
.target(
|
.target(
|
||||||
name: "Adwaita",
|
name: "Adwaita",
|
||||||
dependencies: [
|
dependencies: [
|
||||||
.product(name: "Libadwaita", package: "Libadwaita"),
|
"CAdw",
|
||||||
.product(name: "LevenshteinTransformations", package: "LevenshteinTransformations")
|
.product(name: "LevenshteinTransformations", package: "LevenshteinTransformations")
|
||||||
]
|
]
|
||||||
),
|
),
|
||||||
.executableTarget(
|
.executableTarget(
|
||||||
name: "Swift Adwaita Demo",
|
name: "Generation",
|
||||||
|
dependencies: [
|
||||||
|
.product(name: "XMLCoder", package: "XMLCoder")
|
||||||
|
]
|
||||||
|
),
|
||||||
|
.executableTarget(
|
||||||
|
name: "Demo",
|
||||||
dependencies: ["Adwaita"],
|
dependencies: ["Adwaita"],
|
||||||
path: "Tests"
|
path: "Tests"
|
||||||
)
|
)
|
||||||
|
|||||||
10
README.md
10
README.md
@ -1,6 +1,6 @@
|
|||||||
<p align="center">
|
<p align="center">
|
||||||
<img width="256" alt="Adwaita Icon" src="Icons/AdwaitaIcon.png">
|
<img width="256" alt="Adwaita Icon" src="Icons/AdwaitaIcon.png">
|
||||||
<h1 align="center">Adwaita</h1>
|
<h1 align="center">Adwaita for Swift</h1>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p align="center">
|
<p align="center">
|
||||||
@ -110,15 +110,17 @@ I recommend using the [template repository](https://github.com/AparokshaUI/Adwai
|
|||||||
### Information
|
### Information
|
||||||
|
|
||||||
* [Widgets](user-manual/Information/Widgets.md)
|
* [Widgets](user-manual/Information/Widgets.md)
|
||||||
|
* [Auto-Generated Widgets](user-manual/Information/AutoGeneratedWidgets.md)
|
||||||
|
|
||||||
## Thanks
|
## Thanks
|
||||||
|
|
||||||
### Dependencies
|
### 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)
|
- [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
|
### Other Thanks
|
||||||
- The [contributors][20]
|
- 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
|
- [SwiftLint][21] for checking whether code style conventions are violated
|
||||||
- The programming language [Swift][22]
|
- The programming language [Swift][22]
|
||||||
- [SourceDocs][23] used for generating the [docs][24]
|
- [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
|
[15]: user-manual/Basics/Windows.md
|
||||||
[16]: user-manual/Basics/KeyboardShortcuts.md
|
[16]: user-manual/Basics/KeyboardShortcuts.md
|
||||||
[17]: user-manual/Advanced/CreatingWidgets.md
|
[17]: user-manual/Advanced/CreatingWidgets.md
|
||||||
[18]: https://github.com/AparokshaUI/Libadwaita
|
[18]: https://github.com/CoreOffice/XMLCoder
|
||||||
[19]: https://github.com/AparokshaUI/Libadwaita/blob/main/LICENSE.md
|
[19]: https://github.com/CoreOffice/XMLCoder/blob/main/LICENSE
|
||||||
[20]: Contributors.md
|
[20]: Contributors.md
|
||||||
[21]: https://github.com/realm/SwiftLint
|
[21]: https://github.com/realm/SwiftLint
|
||||||
[22]: https://github.com/apple/swift
|
[22]: https://github.com/apple/swift
|
||||||
|
|||||||
@ -17,6 +17,7 @@
|
|||||||
## Information
|
## Information
|
||||||
|
|
||||||
* [Widgets](user-manual/Information/Widgets.md)
|
* [Widgets](user-manual/Information/Widgets.md)
|
||||||
|
* [Auto-Generated Widgets](user-manual/Information/AutoGeneratedWidgets.md)
|
||||||
|
|
||||||
[1]: README.md
|
[1]: README.md
|
||||||
[2]: user-manual/GettingStarted.md
|
[2]: user-manual/GettingStarted.md
|
||||||
|
|||||||
@ -5,7 +5,7 @@
|
|||||||
// Created by david-swift on 22.10.23.
|
// Created by david-swift on 22.10.23.
|
||||||
//
|
//
|
||||||
|
|
||||||
import Libadwaita
|
import CAdw
|
||||||
|
|
||||||
/// A button widget for menus.
|
/// A button widget for menus.
|
||||||
public struct MenuButton: MenuItem {
|
public struct MenuButton: MenuItem {
|
||||||
@ -19,6 +19,9 @@ public struct MenuButton: MenuItem {
|
|||||||
/// Whether to prefer adding the action to the application window.
|
/// Whether to prefer adding the action to the application window.
|
||||||
var preferApplicationWindow: Bool
|
var preferApplicationWindow: Bool
|
||||||
|
|
||||||
|
/// The action label.
|
||||||
|
var filteredLabel: String { label.filter { $0.isLetter || $0.isNumber || $0 == "-" || $0 == "." } }
|
||||||
|
|
||||||
/// Initialize a menu button.
|
/// Initialize a menu button.
|
||||||
/// - Parameters:
|
/// - Parameters:
|
||||||
/// - label: The buttons label.
|
/// - label: The buttons label.
|
||||||
@ -35,11 +38,13 @@ public struct MenuButton: MenuItem {
|
|||||||
/// - menu: The menu.
|
/// - menu: The menu.
|
||||||
/// - app: The application containing the menu.
|
/// - app: The application containing the menu.
|
||||||
/// - window: The application window 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 {
|
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 {
|
} 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.
|
// Created by david-swift on 22.10.23.
|
||||||
//
|
//
|
||||||
|
|
||||||
import Libadwaita
|
import CAdw
|
||||||
|
|
||||||
/// A section for menus.
|
/// A section for menus.
|
||||||
public struct MenuSection: MenuItem {
|
public struct MenuSection: MenuItem {
|
||||||
@ -24,9 +24,9 @@ public struct MenuSection: MenuItem {
|
|||||||
/// - menu: The menu.
|
/// - menu: The menu.
|
||||||
/// - app: The application containing the menu.
|
/// - app: The application containing the menu.
|
||||||
/// - window: The application window 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?) {
|
||||||
let section = Libadwaita.Menu()
|
let section = g_menu_new()
|
||||||
_ = menu.append("", section: section)
|
g_menu_append_section(menu, nil, section?.cast())
|
||||||
for element in sectionContent {
|
for element in sectionContent {
|
||||||
element.addMenuItems(menu: section, app: app, window: window)
|
element.addMenuItems(menu: section, app: app, window: window)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -5,7 +5,7 @@
|
|||||||
// Created by david-swift on 22.10.23.
|
// Created by david-swift on 22.10.23.
|
||||||
//
|
//
|
||||||
|
|
||||||
import Libadwaita
|
import CAdw
|
||||||
|
|
||||||
/// A submenu widget.
|
/// A submenu widget.
|
||||||
public struct Submenu: MenuItem {
|
public struct Submenu: MenuItem {
|
||||||
@ -29,9 +29,9 @@ public struct Submenu: MenuItem {
|
|||||||
/// - menu: The menu.
|
/// - menu: The menu.
|
||||||
/// - app: The application containing the menu.
|
/// - app: The application containing the menu.
|
||||||
/// - window: The application window 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?) {
|
||||||
let submenu = Libadwaita.Menu()
|
let submenu = g_menu_new()
|
||||||
_ = menu.append(label, submenu: submenu)
|
g_menu_append_submenu(menu, label, submenu?.cast())
|
||||||
for element in submenuContent {
|
for element in submenuContent {
|
||||||
element.addMenuItems(menu: submenu, app: app, window: window)
|
element.addMenuItems(menu: submenu, app: app, window: window)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -9,8 +9,6 @@
|
|||||||
// https://gist.github.com/JadenGeller/c375fc15ad5900a0ddac4ed8ba8307a9
|
// https://gist.github.com/JadenGeller/c375fc15ad5900a0ddac4ed8ba8307a9
|
||||||
//
|
//
|
||||||
|
|
||||||
import Foundation
|
|
||||||
|
|
||||||
/// The ``ArrayBuilder`` is a simple result builder that outputs an array of any type.
|
/// The ``ArrayBuilder`` is a simple result builder that outputs an array of any type.
|
||||||
///
|
///
|
||||||
/// You can define any array using Swift's DSL:
|
/// You can define any array using Swift's DSL:
|
||||||
|
|||||||
@ -5,8 +5,8 @@
|
|||||||
// Created by david-swift on 06.08.23.
|
// Created by david-swift on 06.08.23.
|
||||||
//
|
//
|
||||||
|
|
||||||
|
import CAdw
|
||||||
import Foundation
|
import Foundation
|
||||||
import Libadwaita
|
|
||||||
|
|
||||||
/// A property wrapper for properties in a view that should be stored throughout view updates.
|
/// A property wrapper for properties in a view that should be stored throughout view updates.
|
||||||
@propertyWrapper
|
@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.
|
/// Get the settings directory path.
|
||||||
/// - Returns: The path.
|
/// - Returns: The path.
|
||||||
private func dirPath() -> URL {
|
private func dirPath() -> URL {
|
||||||
NativePeer
|
Self.userDataDir()
|
||||||
.getUserDataDirectory()
|
|
||||||
.appendingPathComponent(content.storage.folder ?? GTUIApp.appID, isDirectory: true)
|
.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.
|
// Created by david-swift on 06.08.23.
|
||||||
//
|
//
|
||||||
|
|
||||||
import Libadwaita
|
import Foundation
|
||||||
|
|
||||||
extension Array: View where Element == View {
|
extension Array: View where Element == View {
|
||||||
|
|
||||||
@ -22,7 +22,7 @@ extension Array: View where Element == View {
|
|||||||
var modified = self
|
var modified = self
|
||||||
for (index, view) in modified.enumerated() {
|
for (index, view) in modified.enumerated() {
|
||||||
for modifier in modifiers {
|
for modifier in modifiers {
|
||||||
modified[index] = modifier(view)
|
modified[safe: index] = modifier(view)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return VStack { modified }
|
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 {
|
extension Array {
|
||||||
|
|
||||||
/// Accesses the element at the specified position safely.
|
/// 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.
|
/// A label for the navigation label in a GTUI widget's fields.
|
||||||
static var navigationLabel: Self { "navigation-label" }
|
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.
|
// Created by david-swift on 05.08.23.
|
||||||
//
|
//
|
||||||
|
|
||||||
import Libadwaita
|
|
||||||
|
|
||||||
/// A structure conforming to `App` is the entry point of your app.
|
/// A structure conforming to `App` is the entry point of your app.
|
||||||
///
|
///
|
||||||
/// ```swift
|
/// ```swift
|
||||||
|
|||||||
@ -5,16 +5,21 @@
|
|||||||
// Created by david-swift on 05.08.23.
|
// Created by david-swift on 05.08.23.
|
||||||
//
|
//
|
||||||
|
|
||||||
import Libadwaita
|
import CAdw
|
||||||
|
|
||||||
/// The GTUI application.
|
/// The GTUI application.
|
||||||
public class GTUIApp: Application {
|
public class GTUIApp {
|
||||||
|
|
||||||
/// The handlers which are called when a state changes.
|
/// The handlers which are called when a state changes.
|
||||||
static var updateHandlers: [() -> Void] = []
|
static var updateHandlers: [() -> Void] = []
|
||||||
/// The app's id for the file name for storing the data.
|
/// The app's id for the file name for storing the data.
|
||||||
static var appID = "temporary"
|
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.
|
/// The app's content.
|
||||||
var body: () -> App
|
var body: () -> App
|
||||||
/// The scenes that are displayed.
|
/// The scenes that are displayed.
|
||||||
@ -28,11 +33,11 @@ public class GTUIApp: Application {
|
|||||||
/// - body: The application's content.
|
/// - body: The application's content.
|
||||||
init(_ id: String, body: @escaping () -> App) {
|
init(_ id: String, body: @escaping () -> App) {
|
||||||
self.body = body
|
self.body = body
|
||||||
super.init(name: id)
|
self.pointer = adw_application_new(id, G_APPLICATION_DEFAULT_FLAGS)?.cast()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The entry point of the application.
|
/// The entry point of the application.
|
||||||
override public func onActivate() {
|
public func onActivate() {
|
||||||
let body = body()
|
let body = body()
|
||||||
for windowScene in body.scene.windows() {
|
for windowScene in body.scene.windows() {
|
||||||
for _ in 0..<windowScene.open {
|
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.
|
/// Focus the window with a certain id. Create the window if it doesn't already exist.
|
||||||
/// - Parameters:
|
/// - Parameters:
|
||||||
/// - id: The window's id.
|
/// - 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.
|
// Created by david-swift on 22.10.23.
|
||||||
//
|
//
|
||||||
|
|
||||||
import Libadwaita
|
import CAdw
|
||||||
|
|
||||||
/// A structure representing the content for a certain menu item type.
|
/// A structure representing the content for a certain menu item type.
|
||||||
public protocol MenuItem: MenuItemGroup {
|
public protocol MenuItem: MenuItemGroup {
|
||||||
@ -15,7 +15,7 @@ public protocol MenuItem: MenuItemGroup {
|
|||||||
/// - menu: The menu.
|
/// - menu: The menu.
|
||||||
/// - app: The application containing the menu.
|
/// - app: The application containing the menu.
|
||||||
/// - window: The application window 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.
|
// 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.
|
/// A structure conforming to `MenuItemGroup` can be added to the content accepting a menu.
|
||||||
public protocol MenuItemGroup {
|
public protocol MenuItemGroup {
|
||||||
@ -19,7 +19,7 @@ extension MenuItemGroup {
|
|||||||
|
|
||||||
/// Add the menu items described by the group to a menu.
|
/// Add the menu items described by the group to a menu.
|
||||||
/// - Parameter menu: The 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 {
|
for element in content {
|
||||||
if let item = element as? MenuItem {
|
if let item = element as? MenuItem {
|
||||||
item.addMenuItem(menu: menu, app: app, window: window)
|
item.addMenuItem(menu: menu, app: app, window: window)
|
||||||
|
|||||||
@ -5,8 +5,6 @@
|
|||||||
// Created by david-swift on 05.08.23.
|
// Created by david-swift on 05.08.23.
|
||||||
//
|
//
|
||||||
|
|
||||||
import Libadwaita
|
|
||||||
|
|
||||||
/// A structure conforming to `View` is referred to as a view.
|
/// A structure conforming to `View` is referred to as a view.
|
||||||
/// It can be part of a body.
|
/// It can be part of a body.
|
||||||
///
|
///
|
||||||
@ -37,13 +35,7 @@ extension View {
|
|||||||
if let peer = modified as? Widget {
|
if let peer = modified as? Widget {
|
||||||
return peer
|
return peer
|
||||||
} else {
|
} else {
|
||||||
var state: [String: StateProtocol] = [:]
|
return StateWrapper(content: { view }, state: getState())
|
||||||
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)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -56,10 +48,20 @@ extension View {
|
|||||||
if let widget = modified as? Widget {
|
if let widget = modified as? Widget {
|
||||||
widget.update(storage, modifiers: modifiers)
|
widget.update(storage, modifiers: modifiers)
|
||||||
} else {
|
} 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.
|
/// Get a storage.
|
||||||
/// - Parameter modifiers: Modify views before being updated.
|
/// - Parameter modifiers: Modify views before being updated.
|
||||||
/// - Returns: The storage.
|
/// - Returns: The storage.
|
||||||
|
|||||||
@ -5,31 +5,194 @@
|
|||||||
// Created by david-swift on 31.08.23.
|
// Created by david-swift on 31.08.23.
|
||||||
//
|
//
|
||||||
|
|
||||||
import Libadwaita
|
import CAdw
|
||||||
|
|
||||||
/// Store a rendered view in a view storage.
|
/// Store a rendered view in a view storage.
|
||||||
public class ViewStorage {
|
public class ViewStorage {
|
||||||
|
|
||||||
/// The GTUI widget.
|
/// The pointer.
|
||||||
public var view: NativeWidgetPeer
|
public var pointer: OpaquePointer?
|
||||||
/// The view's content.
|
/// The view's content.
|
||||||
public var content: [String: [ViewStorage]]
|
public var content: [String: [ViewStorage]]
|
||||||
/// The view's state (used in `StateWrapper`).
|
/// The view's state (used in `StateWrapper`).
|
||||||
public var state: [String: StateProtocol]
|
public var state: [String: StateProtocol]
|
||||||
|
/// The signal handlers.
|
||||||
|
public var handlers: [String: SignalData] = [:]
|
||||||
|
/// Other properties.
|
||||||
|
public var fields: [String: Any] = [:]
|
||||||
|
|
||||||
/// Initialize a view storage.
|
/// Initialize a view storage.
|
||||||
/// - Parameters:
|
/// - Parameters:
|
||||||
/// - view: The GTUI widget.
|
/// - pointer: The pointer to the Gtk widget.
|
||||||
/// - content: The view's content.
|
/// - content: The view's content.
|
||||||
/// - state: The view's state.
|
/// - state: The view's state.
|
||||||
public init(
|
public init(
|
||||||
_ view: NativeWidgetPeer,
|
_ pointer: OpaquePointer?,
|
||||||
content: [String: [ViewStorage]] = [:],
|
content: [String: [ViewStorage]] = [:],
|
||||||
state: [String: StateProtocol] = [:]
|
state: [String: StateProtocol] = [:]
|
||||||
) {
|
) {
|
||||||
self.view = view
|
self.pointer = pointer
|
||||||
self.content = content
|
self.content = content
|
||||||
self.state = state
|
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.
|
// Created by david-swift on 16.08.23.
|
||||||
//
|
//
|
||||||
|
|
||||||
import Libadwaita
|
|
||||||
|
|
||||||
/// A widget is a view that know about its GTUI widget.
|
/// A widget is a view that know about its GTUI widget.
|
||||||
public protocol Widget: View {
|
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.
|
// Created by david-swift on 19.10.23.
|
||||||
//
|
//
|
||||||
|
|
||||||
import Libadwaita
|
import CAdw
|
||||||
|
|
||||||
/// A GTUI application window.
|
/// 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.
|
// Created by david-swift on 12.10.23.
|
||||||
//
|
//
|
||||||
|
|
||||||
import Libadwaita
|
import CAdw
|
||||||
|
|
||||||
/// A GTUI window.
|
/// 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.
|
/// Set the window's parent window.
|
||||||
/// - Parameter parent: The parent window.
|
/// - Parameter parent: The parent window.
|
||||||
public func setParentWindow(_ parent: WindowType) {
|
public func setParentWindow(_ parent: WindowType) {
|
||||||
|
// swiftlint:disable prefer_self_in_static_references
|
||||||
if let window = parent as? GTUIWindow {
|
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.
|
// Created by david-swift on 05.08.23.
|
||||||
//
|
//
|
||||||
|
|
||||||
import Libadwaita
|
|
||||||
|
|
||||||
/// A structure representing the content for a certain window type.
|
/// A structure representing the content for a certain window type.
|
||||||
public protocol WindowScene: WindowSceneGroup {
|
public protocol WindowScene: WindowSceneGroup {
|
||||||
|
|
||||||
|
|||||||
@ -5,8 +5,6 @@
|
|||||||
// Created by david-swift on 31.08.23.
|
// Created by david-swift on 31.08.23.
|
||||||
//
|
//
|
||||||
|
|
||||||
import Libadwaita
|
|
||||||
|
|
||||||
/// A storage for an app's window.
|
/// A storage for an app's window.
|
||||||
public class WindowStorage {
|
public class WindowStorage {
|
||||||
|
|
||||||
|
|||||||
@ -5,8 +5,6 @@
|
|||||||
// Created by david-swift on 09.12.23.
|
// Created by david-swift on 09.12.23.
|
||||||
//
|
//
|
||||||
|
|
||||||
import Libadwaita
|
|
||||||
|
|
||||||
/// A window type.
|
/// A window type.
|
||||||
public protocol WindowType {
|
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.
|
// Created by david-swift on 03.01.24.
|
||||||
//
|
//
|
||||||
|
|
||||||
import Libadwaita
|
import CAdw
|
||||||
|
|
||||||
/// A list with no dynamic content styled as a boxed list.
|
/// A list with no dynamic content styled as a boxed list.
|
||||||
public struct Form: Widget {
|
public struct Form: View {
|
||||||
|
|
||||||
/// The content.
|
/// 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`.
|
/// Initialize a `Form`.
|
||||||
/// - Parameter content: The view content, usually different kind of rows.
|
/// - Parameter content: The view content, usually different kind of rows.
|
||||||
public init(@ViewBuilder content: @escaping () -> Body) {
|
public init(@ViewBuilder content: @escaping () -> Body) {
|
||||||
self.content = content
|
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])
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
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.
|
||||||
|
///
|
||||||
|
/// 
|
||||||
|
///
|
||||||
|
/// 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.
|
||||||
|
///
|
||||||
|
/// 
|
||||||
|
///
|
||||||
|
/// 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.
|
||||||
|
///
|
||||||
|
/// 
|
||||||
|
///
|
||||||
|
/// 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.
|
||||||
|
///
|
||||||
|
/// 
|
||||||
|
///
|
||||||
|
/// 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*.
|
||||||
|
///
|
||||||
|
/// 
|
||||||
|
///
|
||||||
|
/// 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].
|
||||||
|
///
|
||||||
|
/// 
|
||||||
|
///
|
||||||
|
/// # 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.
|
||||||
|
///
|
||||||
|
/// 
|
||||||
|
///
|
||||||
|
/// 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.
|
||||||
|
///
|
||||||
|
/// 
|
||||||
|
///
|
||||||
|
/// 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.
|
||||||
|
///
|
||||||
|
/// 
|
||||||
|
///
|
||||||
|
/// 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** |  |  |  |
|
||||||
|
/// | **up** |  |  |  |
|
||||||
|
/// | **left** |  |  |  |
|
||||||
|
/// | **right** |  |  |  |
|
||||||
|
///
|
||||||
|
/// # 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.
|
||||||
|
///
|
||||||
|
/// 
|
||||||
|
///
|
||||||
|
/// 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.
|
||||||
|
///
|
||||||
|
/// 
|
||||||
|
///
|
||||||
|
/// 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.
|
||||||
|
///
|
||||||
|
/// 
|
||||||
|
///
|
||||||
|
/// 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.
|
// Created by david-swift on 26.09.23.
|
||||||
//
|
//
|
||||||
|
|
||||||
import Libadwaita
|
|
||||||
|
|
||||||
/// A horizontal GtkBox equivalent.
|
/// A horizontal GtkBox equivalent.
|
||||||
public struct HStack: Widget {
|
public struct HStack: View {
|
||||||
|
|
||||||
/// The content.
|
/// The content.
|
||||||
var content: () -> Body
|
var content: () -> Body
|
||||||
|
|
||||||
|
/// The view's body.
|
||||||
|
public var view: Body {
|
||||||
|
VStack(horizontal: true, content: content)
|
||||||
|
}
|
||||||
|
|
||||||
/// Initialize a `HStack`.
|
/// Initialize a `HStack`.
|
||||||
/// - Parameter content: The view content.
|
/// - Parameter content: The view content.
|
||||||
public init(@ViewBuilder content: @escaping () -> Body) {
|
public init(@ViewBuilder content: @escaping () -> Body) {
|
||||||
self.content = content
|
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…
x
Reference in New Issue
Block a user