mirror of
https://github.com/Mauler125/r5sdk.git
synced 2025-02-09 19:15:03 +01:00
Add 'cppkore' library to project
This commit is contained in:
parent
62f3108909
commit
f11f3fe95d
674
r5dev/thirdparty/cppnet/LICENSE.md
vendored
Normal file
674
r5dev/thirdparty/cppnet/LICENSE.md
vendored
Normal file
@ -0,0 +1,674 @@
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 3, 29 June 2007
|
||||
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The GNU General Public License is a free, copyleft license for
|
||||
software and other kinds of works.
|
||||
|
||||
The licenses for most software and other practical works are designed
|
||||
to take away your freedom to share and change the works. By contrast,
|
||||
the GNU General Public License is intended to guarantee your freedom to
|
||||
share and change all versions of a program--to make sure it remains free
|
||||
software for all its users. We, the Free Software Foundation, use the
|
||||
GNU General Public License for most of our software; it applies also to
|
||||
any other work released this way by its authors. You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
them if you wish), that you receive source code or can get it if you
|
||||
want it, that you can change the software or use pieces of it in new
|
||||
free programs, and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to prevent others from denying you
|
||||
these rights or asking you to surrender the rights. Therefore, you have
|
||||
certain responsibilities if you distribute copies of the software, or if
|
||||
you modify it: responsibilities to respect the freedom of others.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must pass on to the recipients the same
|
||||
freedoms that you received. You must make sure that they, too, receive
|
||||
or can get the source code. And you must show them these terms so they
|
||||
know their rights.
|
||||
|
||||
Developers that use the GNU GPL protect your rights with two steps:
|
||||
(1) assert copyright on the software, and (2) offer you this License
|
||||
giving you legal permission to copy, distribute and/or modify it.
|
||||
|
||||
For the developers' and authors' protection, the GPL clearly explains
|
||||
that there is no warranty for this free software. For both users' and
|
||||
authors' sake, the GPL requires that modified versions be marked as
|
||||
changed, so that their problems will not be attributed erroneously to
|
||||
authors of previous versions.
|
||||
|
||||
Some devices are designed to deny users access to install or run
|
||||
modified versions of the software inside them, although the manufacturer
|
||||
can do so. This is fundamentally incompatible with the aim of
|
||||
protecting users' freedom to change the software. The systematic
|
||||
pattern of such abuse occurs in the area of products for individuals to
|
||||
use, which is precisely where it is most unacceptable. Therefore, we
|
||||
have designed this version of the GPL to prohibit the practice for those
|
||||
products. If such problems arise substantially in other domains, we
|
||||
stand ready to extend this provision to those domains in future versions
|
||||
of the GPL, as needed to protect the freedom of users.
|
||||
|
||||
Finally, every program is threatened constantly by software patents.
|
||||
States should not allow patents to restrict development and use of
|
||||
software on general-purpose computers, but in those that do, we wish to
|
||||
avoid the special danger that patents applied to a free program could
|
||||
make it effectively proprietary. To prevent this, the GPL assures that
|
||||
patents cannot be used to render the program non-free.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
TERMS AND CONDITIONS
|
||||
|
||||
0. Definitions.
|
||||
|
||||
"This License" refers to version 3 of the GNU General Public License.
|
||||
|
||||
"Copyright" also means copyright-like laws that apply to other kinds of
|
||||
works, such as semiconductor masks.
|
||||
|
||||
"The Program" refers to any copyrightable work licensed under this
|
||||
License. Each licensee is addressed as "you". "Licensees" and
|
||||
"recipients" may be individuals or organizations.
|
||||
|
||||
To "modify" a work means to copy from or adapt all or part of the work
|
||||
in a fashion requiring copyright permission, other than the making of an
|
||||
exact copy. The resulting work is called a "modified version" of the
|
||||
earlier work or a work "based on" the earlier work.
|
||||
|
||||
A "covered work" means either the unmodified Program or a work based
|
||||
on the Program.
|
||||
|
||||
To "propagate" a work means to do anything with it that, without
|
||||
permission, would make you directly or secondarily liable for
|
||||
infringement under applicable copyright law, except executing it on a
|
||||
computer or modifying a private copy. Propagation includes copying,
|
||||
distribution (with or without modification), making available to the
|
||||
public, and in some countries other activities as well.
|
||||
|
||||
To "convey" a work means any kind of propagation that enables other
|
||||
parties to make or receive copies. Mere interaction with a user through
|
||||
a computer network, with no transfer of a copy, is not conveying.
|
||||
|
||||
An interactive user interface displays "Appropriate Legal Notices"
|
||||
to the extent that it includes a convenient and prominently visible
|
||||
feature that (1) displays an appropriate copyright notice, and (2)
|
||||
tells the user that there is no warranty for the work (except to the
|
||||
extent that warranties are provided), that licensees may convey the
|
||||
work under this License, and how to view a copy of this License. If
|
||||
the interface presents a list of user commands or options, such as a
|
||||
menu, a prominent item in the list meets this criterion.
|
||||
|
||||
1. Source Code.
|
||||
|
||||
The "source code" for a work means the preferred form of the work
|
||||
for making modifications to it. "Object code" means any non-source
|
||||
form of a work.
|
||||
|
||||
A "Standard Interface" means an interface that either is an official
|
||||
standard defined by a recognized standards body, or, in the case of
|
||||
interfaces specified for a particular programming language, one that
|
||||
is widely used among developers working in that language.
|
||||
|
||||
The "System Libraries" of an executable work include anything, other
|
||||
than the work as a whole, that (a) is included in the normal form of
|
||||
packaging a Major Component, but which is not part of that Major
|
||||
Component, and (b) serves only to enable use of the work with that
|
||||
Major Component, or to implement a Standard Interface for which an
|
||||
implementation is available to the public in source code form. A
|
||||
"Major Component", in this context, means a major essential component
|
||||
(kernel, window system, and so on) of the specific operating system
|
||||
(if any) on which the executable work runs, or a compiler used to
|
||||
produce the work, or an object code interpreter used to run it.
|
||||
|
||||
The "Corresponding Source" for a work in object code form means all
|
||||
the source code needed to generate, install, and (for an executable
|
||||
work) run the object code and to modify the work, including scripts to
|
||||
control those activities. However, it does not include the work's
|
||||
System Libraries, or general-purpose tools or generally available free
|
||||
programs which are used unmodified in performing those activities but
|
||||
which are not part of the work. For example, Corresponding Source
|
||||
includes interface definition files associated with source files for
|
||||
the work, and the source code for shared libraries and dynamically
|
||||
linked subprograms that the work is specifically designed to require,
|
||||
such as by intimate data communication or control flow between those
|
||||
subprograms and other parts of the work.
|
||||
|
||||
The Corresponding Source need not include anything that users
|
||||
can regenerate automatically from other parts of the Corresponding
|
||||
Source.
|
||||
|
||||
The Corresponding Source for a work in source code form is that
|
||||
same work.
|
||||
|
||||
2. Basic Permissions.
|
||||
|
||||
All rights granted under this License are granted for the term of
|
||||
copyright on the Program, and are irrevocable provided the stated
|
||||
conditions are met. This License explicitly affirms your unlimited
|
||||
permission to run the unmodified Program. The output from running a
|
||||
covered work is covered by this License only if the output, given its
|
||||
content, constitutes a covered work. This License acknowledges your
|
||||
rights of fair use or other equivalent, as provided by copyright law.
|
||||
|
||||
You may make, run and propagate covered works that you do not
|
||||
convey, without conditions so long as your license otherwise remains
|
||||
in force. You may convey covered works to others for the sole purpose
|
||||
of having them make modifications exclusively for you, or provide you
|
||||
with facilities for running those works, provided that you comply with
|
||||
the terms of this License in conveying all material for which you do
|
||||
not control copyright. Those thus making or running the covered works
|
||||
for you must do so exclusively on your behalf, under your direction
|
||||
and control, on terms that prohibit them from making any copies of
|
||||
your copyrighted material outside their relationship with you.
|
||||
|
||||
Conveying under any other circumstances is permitted solely under
|
||||
the conditions stated below. Sublicensing is not allowed; section 10
|
||||
makes it unnecessary.
|
||||
|
||||
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
|
||||
|
||||
No covered work shall be deemed part of an effective technological
|
||||
measure under any applicable law fulfilling obligations under article
|
||||
11 of the WIPO copyright treaty adopted on 20 December 1996, or
|
||||
similar laws prohibiting or restricting circumvention of such
|
||||
measures.
|
||||
|
||||
When you convey a covered work, you waive any legal power to forbid
|
||||
circumvention of technological measures to the extent such circumvention
|
||||
is effected by exercising rights under this License with respect to
|
||||
the covered work, and you disclaim any intention to limit operation or
|
||||
modification of the work as a means of enforcing, against the work's
|
||||
users, your or third parties' legal rights to forbid circumvention of
|
||||
technological measures.
|
||||
|
||||
4. Conveying Verbatim Copies.
|
||||
|
||||
You may convey verbatim copies of the Program's source code as you
|
||||
receive it, in any medium, provided that you conspicuously and
|
||||
appropriately publish on each copy an appropriate copyright notice;
|
||||
keep intact all notices stating that this License and any
|
||||
non-permissive terms added in accord with section 7 apply to the code;
|
||||
keep intact all notices of the absence of any warranty; and give all
|
||||
recipients a copy of this License along with the Program.
|
||||
|
||||
You may charge any price or no price for each copy that you convey,
|
||||
and you may offer support or warranty protection for a fee.
|
||||
|
||||
5. Conveying Modified Source Versions.
|
||||
|
||||
You may convey a work based on the Program, or the modifications to
|
||||
produce it from the Program, in the form of source code under the
|
||||
terms of section 4, provided that you also meet all of these conditions:
|
||||
|
||||
a) The work must carry prominent notices stating that you modified
|
||||
it, and giving a relevant date.
|
||||
|
||||
b) The work must carry prominent notices stating that it is
|
||||
released under this License and any conditions added under section
|
||||
7. This requirement modifies the requirement in section 4 to
|
||||
"keep intact all notices".
|
||||
|
||||
c) You must license the entire work, as a whole, under this
|
||||
License to anyone who comes into possession of a copy. This
|
||||
License will therefore apply, along with any applicable section 7
|
||||
additional terms, to the whole of the work, and all its parts,
|
||||
regardless of how they are packaged. This License gives no
|
||||
permission to license the work in any other way, but it does not
|
||||
invalidate such permission if you have separately received it.
|
||||
|
||||
d) If the work has interactive user interfaces, each must display
|
||||
Appropriate Legal Notices; however, if the Program has interactive
|
||||
interfaces that do not display Appropriate Legal Notices, your
|
||||
work need not make them do so.
|
||||
|
||||
A compilation of a covered work with other separate and independent
|
||||
works, which are not by their nature extensions of the covered work,
|
||||
and which are not combined with it such as to form a larger program,
|
||||
in or on a volume of a storage or distribution medium, is called an
|
||||
"aggregate" if the compilation and its resulting copyright are not
|
||||
used to limit the access or legal rights of the compilation's users
|
||||
beyond what the individual works permit. Inclusion of a covered work
|
||||
in an aggregate does not cause this License to apply to the other
|
||||
parts of the aggregate.
|
||||
|
||||
6. Conveying Non-Source Forms.
|
||||
|
||||
You may convey a covered work in object code form under the terms
|
||||
of sections 4 and 5, provided that you also convey the
|
||||
machine-readable Corresponding Source under the terms of this License,
|
||||
in one of these ways:
|
||||
|
||||
a) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by the
|
||||
Corresponding Source fixed on a durable physical medium
|
||||
customarily used for software interchange.
|
||||
|
||||
b) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by a
|
||||
written offer, valid for at least three years and valid for as
|
||||
long as you offer spare parts or customer support for that product
|
||||
model, to give anyone who possesses the object code either (1) a
|
||||
copy of the Corresponding Source for all the software in the
|
||||
product that is covered by this License, on a durable physical
|
||||
medium customarily used for software interchange, for a price no
|
||||
more than your reasonable cost of physically performing this
|
||||
conveying of source, or (2) access to copy the
|
||||
Corresponding Source from a network server at no charge.
|
||||
|
||||
c) Convey individual copies of the object code with a copy of the
|
||||
written offer to provide the Corresponding Source. This
|
||||
alternative is allowed only occasionally and noncommercially, and
|
||||
only if you received the object code with such an offer, in accord
|
||||
with subsection 6b.
|
||||
|
||||
d) Convey the object code by offering access from a designated
|
||||
place (gratis or for a charge), and offer equivalent access to the
|
||||
Corresponding Source in the same way through the same place at no
|
||||
further charge. You need not require recipients to copy the
|
||||
Corresponding Source along with the object code. If the place to
|
||||
copy the object code is a network server, the Corresponding Source
|
||||
may be on a different server (operated by you or a third party)
|
||||
that supports equivalent copying facilities, provided you maintain
|
||||
clear directions next to the object code saying where to find the
|
||||
Corresponding Source. Regardless of what server hosts the
|
||||
Corresponding Source, you remain obligated to ensure that it is
|
||||
available for as long as needed to satisfy these requirements.
|
||||
|
||||
e) Convey the object code using peer-to-peer transmission, provided
|
||||
you inform other peers where the object code and Corresponding
|
||||
Source of the work are being offered to the general public at no
|
||||
charge under subsection 6d.
|
||||
|
||||
A separable portion of the object code, whose source code is excluded
|
||||
from the Corresponding Source as a System Library, need not be
|
||||
included in conveying the object code work.
|
||||
|
||||
A "User Product" is either (1) a "consumer product", which means any
|
||||
tangible personal property which is normally used for personal, family,
|
||||
or household purposes, or (2) anything designed or sold for incorporation
|
||||
into a dwelling. In determining whether a product is a consumer product,
|
||||
doubtful cases shall be resolved in favor of coverage. For a particular
|
||||
product received by a particular user, "normally used" refers to a
|
||||
typical or common use of that class of product, regardless of the status
|
||||
of the particular user or of the way in which the particular user
|
||||
actually uses, or expects or is expected to use, the product. A product
|
||||
is a consumer product regardless of whether the product has substantial
|
||||
commercial, industrial or non-consumer uses, unless such uses represent
|
||||
the only significant mode of use of the product.
|
||||
|
||||
"Installation Information" for a User Product means any methods,
|
||||
procedures, authorization keys, or other information required to install
|
||||
and execute modified versions of a covered work in that User Product from
|
||||
a modified version of its Corresponding Source. The information must
|
||||
suffice to ensure that the continued functioning of the modified object
|
||||
code is in no case prevented or interfered with solely because
|
||||
modification has been made.
|
||||
|
||||
If you convey an object code work under this section in, or with, or
|
||||
specifically for use in, a User Product, and the conveying occurs as
|
||||
part of a transaction in which the right of possession and use of the
|
||||
User Product is transferred to the recipient in perpetuity or for a
|
||||
fixed term (regardless of how the transaction is characterized), the
|
||||
Corresponding Source conveyed under this section must be accompanied
|
||||
by the Installation Information. But this requirement does not apply
|
||||
if neither you nor any third party retains the ability to install
|
||||
modified object code on the User Product (for example, the work has
|
||||
been installed in ROM).
|
||||
|
||||
The requirement to provide Installation Information does not include a
|
||||
requirement to continue to provide support service, warranty, or updates
|
||||
for a work that has been modified or installed by the recipient, or for
|
||||
the User Product in which it has been modified or installed. Access to a
|
||||
network may be denied when the modification itself materially and
|
||||
adversely affects the operation of the network or violates the rules and
|
||||
protocols for communication across the network.
|
||||
|
||||
Corresponding Source conveyed, and Installation Information provided,
|
||||
in accord with this section must be in a format that is publicly
|
||||
documented (and with an implementation available to the public in
|
||||
source code form), and must require no special password or key for
|
||||
unpacking, reading or copying.
|
||||
|
||||
7. Additional Terms.
|
||||
|
||||
"Additional permissions" are terms that supplement the terms of this
|
||||
License by making exceptions from one or more of its conditions.
|
||||
Additional permissions that are applicable to the entire Program shall
|
||||
be treated as though they were included in this License, to the extent
|
||||
that they are valid under applicable law. If additional permissions
|
||||
apply only to part of the Program, that part may be used separately
|
||||
under those permissions, but the entire Program remains governed by
|
||||
this License without regard to the additional permissions.
|
||||
|
||||
When you convey a copy of a covered work, you may at your option
|
||||
remove any additional permissions from that copy, or from any part of
|
||||
it. (Additional permissions may be written to require their own
|
||||
removal in certain cases when you modify the work.) You may place
|
||||
additional permissions on material, added by you to a covered work,
|
||||
for which you have or can give appropriate copyright permission.
|
||||
|
||||
Notwithstanding any other provision of this License, for material you
|
||||
add to a covered work, you may (if authorized by the copyright holders of
|
||||
that material) supplement the terms of this License with terms:
|
||||
|
||||
a) Disclaiming warranty or limiting liability differently from the
|
||||
terms of sections 15 and 16 of this License; or
|
||||
|
||||
b) Requiring preservation of specified reasonable legal notices or
|
||||
author attributions in that material or in the Appropriate Legal
|
||||
Notices displayed by works containing it; or
|
||||
|
||||
c) Prohibiting misrepresentation of the origin of that material, or
|
||||
requiring that modified versions of such material be marked in
|
||||
reasonable ways as different from the original version; or
|
||||
|
||||
d) Limiting the use for publicity purposes of names of licensors or
|
||||
authors of the material; or
|
||||
|
||||
e) Declining to grant rights under trademark law for use of some
|
||||
trade names, trademarks, or service marks; or
|
||||
|
||||
f) Requiring indemnification of licensors and authors of that
|
||||
material by anyone who conveys the material (or modified versions of
|
||||
it) with contractual assumptions of liability to the recipient, for
|
||||
any liability that these contractual assumptions directly impose on
|
||||
those licensors and authors.
|
||||
|
||||
All other non-permissive additional terms are considered "further
|
||||
restrictions" within the meaning of section 10. If the Program as you
|
||||
received it, or any part of it, contains a notice stating that it is
|
||||
governed by this License along with a term that is a further
|
||||
restriction, you may remove that term. If a license document contains
|
||||
a further restriction but permits relicensing or conveying under this
|
||||
License, you may add to a covered work material governed by the terms
|
||||
of that license document, provided that the further restriction does
|
||||
not survive such relicensing or conveying.
|
||||
|
||||
If you add terms to a covered work in accord with this section, you
|
||||
must place, in the relevant source files, a statement of the
|
||||
additional terms that apply to those files, or a notice indicating
|
||||
where to find the applicable terms.
|
||||
|
||||
Additional terms, permissive or non-permissive, may be stated in the
|
||||
form of a separately written license, or stated as exceptions;
|
||||
the above requirements apply either way.
|
||||
|
||||
8. Termination.
|
||||
|
||||
You may not propagate or modify a covered work except as expressly
|
||||
provided under this License. Any attempt otherwise to propagate or
|
||||
modify it is void, and will automatically terminate your rights under
|
||||
this License (including any patent licenses granted under the third
|
||||
paragraph of section 11).
|
||||
|
||||
However, if you cease all violation of this License, then your
|
||||
license from a particular copyright holder is reinstated (a)
|
||||
provisionally, unless and until the copyright holder explicitly and
|
||||
finally terminates your license, and (b) permanently, if the copyright
|
||||
holder fails to notify you of the violation by some reasonable means
|
||||
prior to 60 days after the cessation.
|
||||
|
||||
Moreover, your license from a particular copyright holder is
|
||||
reinstated permanently if the copyright holder notifies you of the
|
||||
violation by some reasonable means, this is the first time you have
|
||||
received notice of violation of this License (for any work) from that
|
||||
copyright holder, and you cure the violation prior to 30 days after
|
||||
your receipt of the notice.
|
||||
|
||||
Termination of your rights under this section does not terminate the
|
||||
licenses of parties who have received copies or rights from you under
|
||||
this License. If your rights have been terminated and not permanently
|
||||
reinstated, you do not qualify to receive new licenses for the same
|
||||
material under section 10.
|
||||
|
||||
9. Acceptance Not Required for Having Copies.
|
||||
|
||||
You are not required to accept this License in order to receive or
|
||||
run a copy of the Program. Ancillary propagation of a covered work
|
||||
occurring solely as a consequence of using peer-to-peer transmission
|
||||
to receive a copy likewise does not require acceptance. However,
|
||||
nothing other than this License grants you permission to propagate or
|
||||
modify any covered work. These actions infringe copyright if you do
|
||||
not accept this License. Therefore, by modifying or propagating a
|
||||
covered work, you indicate your acceptance of this License to do so.
|
||||
|
||||
10. Automatic Licensing of Downstream Recipients.
|
||||
|
||||
Each time you convey a covered work, the recipient automatically
|
||||
receives a license from the original licensors, to run, modify and
|
||||
propagate that work, subject to this License. You are not responsible
|
||||
for enforcing compliance by third parties with this License.
|
||||
|
||||
An "entity transaction" is a transaction transferring control of an
|
||||
organization, or substantially all assets of one, or subdividing an
|
||||
organization, or merging organizations. If propagation of a covered
|
||||
work results from an entity transaction, each party to that
|
||||
transaction who receives a copy of the work also receives whatever
|
||||
licenses to the work the party's predecessor in interest had or could
|
||||
give under the previous paragraph, plus a right to possession of the
|
||||
Corresponding Source of the work from the predecessor in interest, if
|
||||
the predecessor has it or can get it with reasonable efforts.
|
||||
|
||||
You may not impose any further restrictions on the exercise of the
|
||||
rights granted or affirmed under this License. For example, you may
|
||||
not impose a license fee, royalty, or other charge for exercise of
|
||||
rights granted under this License, and you may not initiate litigation
|
||||
(including a cross-claim or counterclaim in a lawsuit) alleging that
|
||||
any patent claim is infringed by making, using, selling, offering for
|
||||
sale, or importing the Program or any portion of it.
|
||||
|
||||
11. Patents.
|
||||
|
||||
A "contributor" is a copyright holder who authorizes use under this
|
||||
License of the Program or a work on which the Program is based. The
|
||||
work thus licensed is called the contributor's "contributor version".
|
||||
|
||||
A contributor's "essential patent claims" are all patent claims
|
||||
owned or controlled by the contributor, whether already acquired or
|
||||
hereafter acquired, that would be infringed by some manner, permitted
|
||||
by this License, of making, using, or selling its contributor version,
|
||||
but do not include claims that would be infringed only as a
|
||||
consequence of further modification of the contributor version. For
|
||||
purposes of this definition, "control" includes the right to grant
|
||||
patent sublicenses in a manner consistent with the requirements of
|
||||
this License.
|
||||
|
||||
Each contributor grants you a non-exclusive, worldwide, royalty-free
|
||||
patent license under the contributor's essential patent claims, to
|
||||
make, use, sell, offer for sale, import and otherwise run, modify and
|
||||
propagate the contents of its contributor version.
|
||||
|
||||
In the following three paragraphs, a "patent license" is any express
|
||||
agreement or commitment, however denominated, not to enforce a patent
|
||||
(such as an express permission to practice a patent or covenant not to
|
||||
sue for patent infringement). To "grant" such a patent license to a
|
||||
party means to make such an agreement or commitment not to enforce a
|
||||
patent against the party.
|
||||
|
||||
If you convey a covered work, knowingly relying on a patent license,
|
||||
and the Corresponding Source of the work is not available for anyone
|
||||
to copy, free of charge and under the terms of this License, through a
|
||||
publicly available network server or other readily accessible means,
|
||||
then you must either (1) cause the Corresponding Source to be so
|
||||
available, or (2) arrange to deprive yourself of the benefit of the
|
||||
patent license for this particular work, or (3) arrange, in a manner
|
||||
consistent with the requirements of this License, to extend the patent
|
||||
license to downstream recipients. "Knowingly relying" means you have
|
||||
actual knowledge that, but for the patent license, your conveying the
|
||||
covered work in a country, or your recipient's use of the covered work
|
||||
in a country, would infringe one or more identifiable patents in that
|
||||
country that you have reason to believe are valid.
|
||||
|
||||
If, pursuant to or in connection with a single transaction or
|
||||
arrangement, you convey, or propagate by procuring conveyance of, a
|
||||
covered work, and grant a patent license to some of the parties
|
||||
receiving the covered work authorizing them to use, propagate, modify
|
||||
or convey a specific copy of the covered work, then the patent license
|
||||
you grant is automatically extended to all recipients of the covered
|
||||
work and works based on it.
|
||||
|
||||
A patent license is "discriminatory" if it does not include within
|
||||
the scope of its coverage, prohibits the exercise of, or is
|
||||
conditioned on the non-exercise of one or more of the rights that are
|
||||
specifically granted under this License. You may not convey a covered
|
||||
work if you are a party to an arrangement with a third party that is
|
||||
in the business of distributing software, under which you make payment
|
||||
to the third party based on the extent of your activity of conveying
|
||||
the work, and under which the third party grants, to any of the
|
||||
parties who would receive the covered work from you, a discriminatory
|
||||
patent license (a) in connection with copies of the covered work
|
||||
conveyed by you (or copies made from those copies), or (b) primarily
|
||||
for and in connection with specific products or compilations that
|
||||
contain the covered work, unless you entered into that arrangement,
|
||||
or that patent license was granted, prior to 28 March 2007.
|
||||
|
||||
Nothing in this License shall be construed as excluding or limiting
|
||||
any implied license or other defenses to infringement that may
|
||||
otherwise be available to you under applicable patent law.
|
||||
|
||||
12. No Surrender of Others' Freedom.
|
||||
|
||||
If conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot convey a
|
||||
covered work so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you may
|
||||
not convey it at all. For example, if you agree to terms that obligate you
|
||||
to collect a royalty for further conveying from those to whom you convey
|
||||
the Program, the only way you could satisfy both those terms and this
|
||||
License would be to refrain entirely from conveying the Program.
|
||||
|
||||
13. Use with the GNU Affero General Public License.
|
||||
|
||||
Notwithstanding any other provision of this License, you have
|
||||
permission to link or combine any covered work with a work licensed
|
||||
under version 3 of the GNU Affero General Public License into a single
|
||||
combined work, and to convey the resulting work. The terms of this
|
||||
License will continue to apply to the part which is the covered work,
|
||||
but the special requirements of the GNU Affero General Public License,
|
||||
section 13, concerning interaction through a network will apply to the
|
||||
combination as such.
|
||||
|
||||
14. Revised Versions of this License.
|
||||
|
||||
The Free Software Foundation may publish revised and/or new versions of
|
||||
the GNU General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the
|
||||
Program specifies that a certain numbered version of the GNU General
|
||||
Public License "or any later version" applies to it, you have the
|
||||
option of following the terms and conditions either of that numbered
|
||||
version or of any later version published by the Free Software
|
||||
Foundation. If the Program does not specify a version number of the
|
||||
GNU General Public License, you may choose any version ever published
|
||||
by the Free Software Foundation.
|
||||
|
||||
If the Program specifies that a proxy can decide which future
|
||||
versions of the GNU General Public License can be used, that proxy's
|
||||
public statement of acceptance of a version permanently authorizes you
|
||||
to choose that version for the Program.
|
||||
|
||||
Later license versions may give you additional or different
|
||||
permissions. However, no additional obligations are imposed on any
|
||||
author or copyright holder as a result of your choosing to follow a
|
||||
later version.
|
||||
|
||||
15. Disclaimer of Warranty.
|
||||
|
||||
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
|
||||
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
|
||||
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
|
||||
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
|
||||
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
|
||||
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
|
||||
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
16. Limitation of Liability.
|
||||
|
||||
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
|
||||
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
|
||||
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
|
||||
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
|
||||
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
|
||||
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
|
||||
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
|
||||
SUCH DAMAGES.
|
||||
|
||||
17. Interpretation of Sections 15 and 16.
|
||||
|
||||
If the disclaimer of warranty and limitation of liability provided
|
||||
above cannot be given local legal effect according to their terms,
|
||||
reviewing courts shall apply local law that most closely approximates
|
||||
an absolute waiver of all civil liability in connection with the
|
||||
Program, unless a warranty or assumption of liability accompanies a
|
||||
copy of the Program in return for a fee.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
state the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://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
|
||||
<https://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
|
||||
<https://www.gnu.org/licenses/why-not-lgpl.html>.
|
2
r5dev/thirdparty/cppnet/README.md
vendored
Normal file
2
r5dev/thirdparty/cppnet/README.md
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
# cppnet
|
||||
It's .NET for C++17
|
3
r5dev/thirdparty/cppnet/cppkore/Action.h
vendored
Normal file
3
r5dev/thirdparty/cppnet/cppkore/Action.h
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
#pragma once
|
||||
|
||||
typedef void(*Action)();
|
45
r5dev/thirdparty/cppnet/cppkore/Adler32.cpp
vendored
Normal file
45
r5dev/thirdparty/cppnet/cppkore/Adler32.cpp
vendored
Normal file
@ -0,0 +1,45 @@
|
||||
#include "stdafx.h"
|
||||
#include "Adler32.h"
|
||||
|
||||
uint32_t Hashing::Adler32::ComputeHash(uint32_t adler, const void* ptr, size_t buflen)
|
||||
{
|
||||
if (!ptr)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const uint8_t* buffer = static_cast<const uint8_t*>(ptr);
|
||||
|
||||
const unsigned long ADLER_MOD = 65521;
|
||||
unsigned long s1 = adler & 0xffff, s2 = adler >> 16;
|
||||
size_t blocklen;
|
||||
unsigned long i;
|
||||
|
||||
blocklen = buflen % 5552;
|
||||
while (buflen)
|
||||
{
|
||||
for (i = 0; i + 7 < blocklen; i += 8)
|
||||
{
|
||||
s1 += buffer[0], s2 += s1;
|
||||
s1 += buffer[1], s2 += s1;
|
||||
s1 += buffer[2], s2 += s1;
|
||||
s1 += buffer[3], s2 += s1;
|
||||
s1 += buffer[4], s2 += s1;
|
||||
s1 += buffer[5], s2 += s1;
|
||||
s1 += buffer[6], s2 += s1;
|
||||
s1 += buffer[7], s2 += s1;
|
||||
|
||||
buffer += 8;
|
||||
}
|
||||
|
||||
for (; i < blocklen; ++i)
|
||||
{
|
||||
s1 += *buffer++, s2 += s1;
|
||||
}
|
||||
|
||||
s1 %= ADLER_MOD, s2 %= ADLER_MOD;
|
||||
buflen -= blocklen;
|
||||
blocklen = 5552;
|
||||
}
|
||||
return (s2 << 16) + s1;
|
||||
}
|
12
r5dev/thirdparty/cppnet/cppkore/Adler32.h
vendored
Normal file
12
r5dev/thirdparty/cppnet/cppkore/Adler32.h
vendored
Normal file
@ -0,0 +1,12 @@
|
||||
#pragma once
|
||||
|
||||
namespace Hashing
|
||||
{
|
||||
// Mark Adler's compact Adler32 hashing algorithm
|
||||
// Originally from the public domain stb.h header.
|
||||
class Adler32
|
||||
{
|
||||
public:
|
||||
static uint32_t ComputeHash(uint32_t adler, const void* ptr, size_t buflen);
|
||||
};
|
||||
}
|
30
r5dev/thirdparty/cppnet/cppkore/AnchorStyles.h
vendored
Normal file
30
r5dev/thirdparty/cppnet/cppkore/AnchorStyles.h
vendored
Normal file
@ -0,0 +1,30 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <type_traits>
|
||||
|
||||
namespace Forms
|
||||
{
|
||||
// Specifies how a control anchors to the edges of its container.
|
||||
enum class AnchorStyles
|
||||
{
|
||||
// The control is anchored to the top edge of its container.
|
||||
Top = 0x1,
|
||||
// The control is anchored to the bottom edge of its container.
|
||||
Bottom = 0x2,
|
||||
// The control is anchored to the left edge of its container.
|
||||
Left = 0x4,
|
||||
// The control is anchored to the right edge of its container.
|
||||
Right = 0x8,
|
||||
// The control is not anchored to any edges of its container.
|
||||
None = 0x0
|
||||
};
|
||||
|
||||
//
|
||||
// Allow bitwise operations on this enumeration
|
||||
//
|
||||
constexpr AnchorStyles operator|(AnchorStyles Lhs, AnchorStyles Rhs)
|
||||
{
|
||||
return static_cast<AnchorStyles>(static_cast<std::underlying_type<AnchorStyles>::type>(Lhs) | static_cast<std::underlying_type<AnchorStyles>::type>(Rhs));
|
||||
};
|
||||
}
|
128
r5dev/thirdparty/cppnet/cppkore/Animation.cpp
vendored
Normal file
128
r5dev/thirdparty/cppnet/cppkore/Animation.cpp
vendored
Normal file
@ -0,0 +1,128 @@
|
||||
#include "stdafx.h"
|
||||
#include "Animation.h"
|
||||
|
||||
namespace Assets
|
||||
{
|
||||
Animation::Animation()
|
||||
: Animation(0)
|
||||
{
|
||||
}
|
||||
|
||||
Animation::Animation(uint32_t BoneCount)
|
||||
: Animation(BoneCount, 30.0f)
|
||||
{
|
||||
}
|
||||
|
||||
Animation::Animation(uint32_t BoneCount, float FrameRate)
|
||||
: Bones(BoneCount), Looping(false), FrameRate(FrameRate), Name("error"), TransformSpace(AnimationTransformSpace::Local), RotationInterpolation(AnimationRotationInterpolation::Quaternion)
|
||||
{
|
||||
}
|
||||
|
||||
List<Curve>& Animation::GetNodeCurves(const string& NodeName)
|
||||
{
|
||||
if (Curves.ContainsKey(NodeName))
|
||||
return Curves[NodeName];
|
||||
|
||||
Curves.Add(NodeName, List<Curve>());
|
||||
return Curves[NodeName];
|
||||
}
|
||||
|
||||
void Animation::AddNotification(const string& Name, uint32_t Frame)
|
||||
{
|
||||
if (Notificiations.ContainsKey(Name))
|
||||
Notificiations[Name].EmplaceBack(Frame);
|
||||
|
||||
Notificiations.Add(Name, List<uint32_t>());
|
||||
Notificiations[Name].EmplaceBack(Frame);
|
||||
}
|
||||
|
||||
const uint32_t Animation::FrameCount(bool Legacy) const
|
||||
{
|
||||
uint32_t Result = 0;
|
||||
|
||||
for (auto& Kvp : Curves)
|
||||
{
|
||||
for (auto& Curve : Kvp.Value())
|
||||
{
|
||||
if (Legacy)
|
||||
{
|
||||
// Used for animation types which do not support non-bone like curves
|
||||
// So we only have quaternion rotation, translations, and scales
|
||||
if (Curve.Property == CurveProperty::RotateQuaternion || (Curve.Property >= CurveProperty::TranslateX && Curve.Property <= CurveProperty::TranslateZ) || (Curve.Property >= CurveProperty::ScaleX && Curve.Property <= CurveProperty::ScaleZ))
|
||||
{
|
||||
for (auto& Keyframe : Curve.Keyframes)
|
||||
Result = max(Result, Keyframe.Frame.Integer32);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Support all curves
|
||||
for (auto& Keyframe : Curve.Keyframes)
|
||||
Result = max(Result, Keyframe.Frame.Integer32);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (auto& NoteTrack : Notificiations)
|
||||
for (auto& Note : NoteTrack.Value())
|
||||
Result = max(Result, Note);
|
||||
|
||||
// Frame count is the length of the animation in frames
|
||||
// Frames start at index 0, so we add one to get the count
|
||||
return Result + 1;
|
||||
}
|
||||
|
||||
const uint32_t Animation::NotificationCount() const
|
||||
{
|
||||
uint32_t Result = 0;
|
||||
|
||||
for (auto& NoteTrack : Notificiations)
|
||||
Result += NoteTrack.Value().Count();
|
||||
|
||||
return Result;
|
||||
}
|
||||
|
||||
void Animation::Scale(float Factor)
|
||||
{
|
||||
for (auto& Kvp : Curves)
|
||||
{
|
||||
for (auto& Curve : Kvp.Value())
|
||||
{
|
||||
// Translation keyframes are scaled here...
|
||||
if (Curve.Property >= CurveProperty::TranslateX && Curve.Property <= CurveProperty::TranslateZ)
|
||||
{
|
||||
for (auto& Keyframe : Curve.Keyframes)
|
||||
{
|
||||
Keyframe.Value.Float *= Factor;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (auto& Bone : Bones)
|
||||
{
|
||||
if (Bone.GetFlag(BoneFlags::HasLocalSpaceMatrices))
|
||||
{
|
||||
Bone.SetLocalPosition(Bone.LocalPosition() * Factor);
|
||||
}
|
||||
if (Bone.GetFlag(BoneFlags::HasGlobalSpaceMatrices))
|
||||
{
|
||||
Bone.SetGlobalPosition(Bone.GlobalPosition() * Factor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Animation::RemoveEmptyNodes()
|
||||
{
|
||||
for (auto& Kvp : Curves)
|
||||
{
|
||||
for (int32_t i = ((int32_t)Kvp.Value().Count() - 1); i >= 0; i--)
|
||||
{
|
||||
if (Kvp.Value()[i].Keyframes.Count() == 0)
|
||||
{
|
||||
Kvp.Value().RemoveAt(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
62
r5dev/thirdparty/cppnet/cppkore/Animation.h
vendored
Normal file
62
r5dev/thirdparty/cppnet/cppkore/Animation.h
vendored
Normal file
@ -0,0 +1,62 @@
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include <cstdint>
|
||||
#include "ListBase.h"
|
||||
#include "DictionaryBase.h"
|
||||
|
||||
// The separate anim parts
|
||||
#include "Bone.h"
|
||||
#include "Vector3.h"
|
||||
#include "Quaternion.h"
|
||||
#include "AnimationTypes.h"
|
||||
#include "Curve.h"
|
||||
|
||||
namespace Assets
|
||||
{
|
||||
// A container class that holds 3D animation data.
|
||||
class Animation
|
||||
{
|
||||
public:
|
||||
// Initialize a blank 3D animation without any known counts.
|
||||
Animation();
|
||||
// Initialize a 3D animation with the given count for bones.
|
||||
Animation(uint32_t BoneCount);
|
||||
// Initialize a 3D animation with the given bone count and framerate.
|
||||
Animation(uint32_t BoneCount, float FrameRate);
|
||||
|
||||
// The name of the animation
|
||||
string Name;
|
||||
|
||||
// A collection of 3D bones for this animation. (May or may not represent the actual skeleton)
|
||||
List<Bone> Bones;
|
||||
// The collection of curves that make up this animation.
|
||||
Dictionary<string, List<Curve>> Curves;
|
||||
// A collection of notifications that may occur.
|
||||
Dictionary<string, List<uint32_t>> Notificiations;
|
||||
|
||||
// Gets a reference to a list of node curves.
|
||||
List<Curve>& GetNodeCurves(const string& NodeName);
|
||||
// Adds a notification to the animation.
|
||||
void AddNotification(const string& Name, uint32_t Frame);
|
||||
|
||||
// Gets the count of frames in the animation.
|
||||
const uint32_t FrameCount(bool Legacy = false) const;
|
||||
// Gets the count of notifications in the animation.
|
||||
const uint32_t NotificationCount() const;
|
||||
|
||||
// Specifies if this animation should loop.
|
||||
bool Looping;
|
||||
// The framerate of this animation.
|
||||
float FrameRate;
|
||||
// The transformation space of this animation.
|
||||
AnimationTransformSpace TransformSpace;
|
||||
// The rotation interpolation mode.
|
||||
AnimationRotationInterpolation RotationInterpolation;
|
||||
|
||||
// Scales the animation with the given factor.
|
||||
void Scale(float Factor);
|
||||
// Removes nodes without keyframes.
|
||||
void RemoveEmptyNodes();
|
||||
};
|
||||
}
|
33
r5dev/thirdparty/cppnet/cppkore/AnimationTypes.h
vendored
Normal file
33
r5dev/thirdparty/cppnet/cppkore/AnimationTypes.h
vendored
Normal file
@ -0,0 +1,33 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
namespace Assets
|
||||
{
|
||||
// This enumeration represents the possible animation types
|
||||
enum class AnimationCurveMode
|
||||
{
|
||||
// Animation translations are set to this exact value each frame.
|
||||
Absolute = 0,
|
||||
// Animation values are added on to the scene values.
|
||||
Additive = 1,
|
||||
// Animation values are relative to rest position in the model.
|
||||
Relative = 2
|
||||
};
|
||||
|
||||
// This enumeration represents the possible transform spaces
|
||||
enum class AnimationTransformSpace
|
||||
{
|
||||
// All of the curve nodes are in local object space
|
||||
Local = 0,
|
||||
// All of the curve nodes are in world space
|
||||
World = 1,
|
||||
};
|
||||
|
||||
// This enumeration represents the interpolation options
|
||||
enum class AnimationRotationInterpolation
|
||||
{
|
||||
Quaternion = 0,
|
||||
Euler = 1,
|
||||
};
|
||||
}
|
15
r5dev/thirdparty/cppnet/cppkore/Appearence.h
vendored
Normal file
15
r5dev/thirdparty/cppnet/cppkore/Appearence.h
vendored
Normal file
@ -0,0 +1,15 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
namespace Forms
|
||||
{
|
||||
// Specifies the appearance of a control.
|
||||
enum class Appearence
|
||||
{
|
||||
// The default appearance defined by the control.
|
||||
Normal = 0,
|
||||
// The appearance of a Windows button.
|
||||
Button = 1
|
||||
};
|
||||
}
|
116
r5dev/thirdparty/cppnet/cppkore/Application.cpp
vendored
Normal file
116
r5dev/thirdparty/cppnet/cppkore/Application.cpp
vendored
Normal file
@ -0,0 +1,116 @@
|
||||
#include "stdafx.h"
|
||||
#include "Application.h"
|
||||
|
||||
// We're an application, so, we require GDI+, ComCtl32
|
||||
#pragma comment(lib, "Gdiplus.lib")
|
||||
#pragma comment(lib, "Comctl32.lib")
|
||||
|
||||
namespace Forms
|
||||
{
|
||||
// We haven't initialized it yet...
|
||||
std::atomic<bool> Application::IsGdipInitialized = false;
|
||||
ULONG_PTR Application::GdipToken = NULL;
|
||||
|
||||
void Application::Run(Form* MainWindow)
|
||||
{
|
||||
if (MainWindow == nullptr)
|
||||
return;
|
||||
|
||||
// Initialize COM
|
||||
OleInitialize(NULL);
|
||||
|
||||
#if _DEBUG
|
||||
if (!IsGdipInitialized)
|
||||
printf("-- Warning: GDI+ has not been initialized before Application::Run() --\n");
|
||||
#endif
|
||||
|
||||
// Execute on the main loop
|
||||
Application::RunMainLoop(MainWindow);
|
||||
|
||||
if (MainWindow)
|
||||
delete MainWindow;
|
||||
|
||||
// Shutdown COM
|
||||
OleUninitialize();
|
||||
}
|
||||
|
||||
void Application::RunDialog(Form* MainDialog)
|
||||
{
|
||||
// We must disable the owner dialog so that we can properly be the focus
|
||||
auto HwndOwner = GetWindowLongPtr(MainDialog->GetHandle(), GWLP_HWNDPARENT);
|
||||
if (HwndOwner != NULL)
|
||||
{
|
||||
if (IsWindowEnabled((HWND)HwndOwner))
|
||||
EnableWindow((HWND)HwndOwner, false);
|
||||
}
|
||||
|
||||
RunMainLoop(MainDialog);
|
||||
|
||||
// We must re-enable the owner window
|
||||
if (HwndOwner != NULL)
|
||||
EnableWindow((HWND)HwndOwner, true);
|
||||
}
|
||||
|
||||
void Application::EnableVisualStyles()
|
||||
{
|
||||
SetProcessDPIAware();
|
||||
if (!IsGdipInitialized)
|
||||
InitializeGdip();
|
||||
}
|
||||
|
||||
void Application::RunMainLoop(Form* MainWindow)
|
||||
{
|
||||
bool ContinueLoop = true;
|
||||
|
||||
//
|
||||
// Initialize the main window before starting the message pump...
|
||||
//
|
||||
|
||||
MainWindow->Show();
|
||||
|
||||
//
|
||||
// Loop until any of the conditions are met...
|
||||
//
|
||||
|
||||
MSG nMSG;
|
||||
while (ContinueLoop)
|
||||
{
|
||||
auto Peeked = PeekMessage(&nMSG, NULL, 0, 0, PM_NOREMOVE);
|
||||
|
||||
if (Peeked)
|
||||
{
|
||||
if (!GetMessage(&nMSG, NULL, 0, 0))
|
||||
continue;
|
||||
|
||||
TranslateMessage(&nMSG);
|
||||
DispatchMessage(&nMSG);
|
||||
|
||||
if (MainWindow)
|
||||
ContinueLoop = !MainWindow->CheckCloseDialog(false);
|
||||
}
|
||||
else if (MainWindow == nullptr || MainWindow->GetState(ControlStates::StateDisposed))
|
||||
{
|
||||
break;
|
||||
}
|
||||
else if (!PeekMessage(&nMSG, NULL, 0, 0, PM_NOREMOVE))
|
||||
{
|
||||
WaitMessage();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Application::InitializeGdip()
|
||||
{
|
||||
IsGdipInitialized = true;
|
||||
|
||||
Gdiplus::GdiplusStartupInput gdipStartup;
|
||||
Gdiplus::GdiplusStartup(&GdipToken, &gdipStartup, NULL);
|
||||
}
|
||||
|
||||
void Application::ShutdownGdip()
|
||||
{
|
||||
IsGdipInitialized = false;
|
||||
|
||||
Gdiplus::GdiplusShutdown(GdipToken);
|
||||
}
|
||||
}
|
37
r5dev/thirdparty/cppnet/cppkore/Application.h
vendored
Normal file
37
r5dev/thirdparty/cppnet/cppkore/Application.h
vendored
Normal file
@ -0,0 +1,37 @@
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include <atomic>
|
||||
#include "Form.h"
|
||||
|
||||
namespace Forms
|
||||
{
|
||||
// Provides static methods and properties to manage an application.
|
||||
class Application
|
||||
{
|
||||
public:
|
||||
// Begins running a standard application message loop on the current
|
||||
// thread, and makes the specified form visible.
|
||||
static void Run(Form* MainWindow);
|
||||
|
||||
// Begins running a dialog application loop on the
|
||||
// current thread, you MUST clean up the dialog after use.
|
||||
static void RunDialog(Form* MainDialog);
|
||||
|
||||
// Enables the use of visual style components and initializes GDI+.
|
||||
static void EnableVisualStyles();
|
||||
|
||||
private:
|
||||
// Runs the main window loop.
|
||||
static void RunMainLoop(Form* MainWindow);
|
||||
|
||||
// Whether or not GDI+ has been initialized
|
||||
static std::atomic<bool> IsGdipInitialized;
|
||||
// The token for GDI+
|
||||
static ULONG_PTR GdipToken;
|
||||
|
||||
// Internal cleanup routines
|
||||
static void InitializeGdip();
|
||||
static void ShutdownGdip();
|
||||
};
|
||||
}
|
720
r5dev/thirdparty/cppnet/cppkore/AssetRenderer.cpp
vendored
Normal file
720
r5dev/thirdparty/cppnet/cppkore/AssetRenderer.cpp
vendored
Normal file
@ -0,0 +1,720 @@
|
||||
#include "stdafx.h"
|
||||
#include <thread>
|
||||
#include "AssetRenderer.h"
|
||||
#include "Path.h"
|
||||
#include "Thread.h"
|
||||
|
||||
// Include the internal font, and shaders
|
||||
#include "FontArial.h"
|
||||
#include "ModelFragmentShader.h"
|
||||
#include "ModelVertexShader.h"
|
||||
|
||||
// We need to include the OpenGL classes
|
||||
#include "Mangler.h"
|
||||
|
||||
namespace Assets
|
||||
{
|
||||
AssetRenderer::AssetRenderer()
|
||||
: OpenGLViewport(), _Camera(0.5f* (float)MathHelper::PI, 0.45f* (float)MathHelper::PI, 100.f), _UseWireframe(false), _ShowBones(true), _ShowMaterials(true), _DrawingMode(DrawMode::Model), _DrawInformation{}, _BonePointBuffer(0), _BonePointCount(0), _DrawTexture(0)
|
||||
{
|
||||
}
|
||||
|
||||
AssetRenderer::~AssetRenderer()
|
||||
{
|
||||
ClearViewModel();
|
||||
ClearViewTexture();
|
||||
}
|
||||
|
||||
void AssetRenderer::SetViewModel(const Model& Model)
|
||||
{
|
||||
this->_DrawingMode = DrawMode::Model;
|
||||
ClearViewModel();
|
||||
ClearViewTexture();
|
||||
|
||||
for (auto& Submesh : Model.Meshes)
|
||||
{
|
||||
auto Draw = DrawObject();
|
||||
|
||||
glGenVertexArrays(1, &Draw.VertexArrayObject);
|
||||
glBindVertexArray(Draw.VertexArrayObject);
|
||||
|
||||
// We'll take the POSITION, NORMAL, COLOR, and first UV pair...
|
||||
const uint32_t Stride = sizeof(Vector3) + sizeof(Vector3) + sizeof(VertexColor) + sizeof(Vector2);
|
||||
auto VertexBuffer = std::make_unique<uint8_t[]>((uint64_t)Submesh.Vertices.Count() * Stride);
|
||||
|
||||
uint64_t Offset = 0;
|
||||
for (auto& Vertex : Submesh.Vertices)
|
||||
{
|
||||
std::memcpy(&VertexBuffer.get()[Offset], &Vertex.Position(), Stride);
|
||||
Offset += Stride;
|
||||
}
|
||||
|
||||
glGenBuffers(1, &Draw.VertexBuffer);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, Draw.VertexBuffer);
|
||||
glBufferData(GL_ARRAY_BUFFER, (Stride * (uint64_t)Submesh.Vertices.Count()), VertexBuffer.get(), GL_STATIC_DRAW);
|
||||
|
||||
glGenBuffers(1, &Draw.FaceBuffer);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, Draw.FaceBuffer);
|
||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, (uint64_t)Submesh.Faces.Count() * 3 * sizeof(uint32_t), &Submesh.Faces[0], GL_STATIC_DRAW);
|
||||
|
||||
wglSwapIntervalEXT(1);
|
||||
|
||||
Draw.FaceCount = Submesh.Faces.Count();
|
||||
Draw.VertexCount = Submesh.Vertices.Count();
|
||||
|
||||
if (Submesh.MaterialIndices.Count() > 0 && this->_MaterialStreamer != nullptr && Model.Materials.Count() != 0)
|
||||
{
|
||||
Assets::Material& Material = Model.Materials[Submesh.MaterialIndices[0]];
|
||||
|
||||
if (Material.Slots.ContainsKey(MaterialSlotType::Albedo))
|
||||
{
|
||||
auto MaterialDiffuseMap = this->_MaterialStreamer("", Material.Slots[MaterialSlotType::Albedo].second);
|
||||
if (MaterialDiffuseMap != nullptr)
|
||||
{
|
||||
glGenTextures(1, &Draw.Material.AlbedoMap);
|
||||
this->LoadDXTextureOGL(*MaterialDiffuseMap.get(), Draw.Material.AlbedoMap);
|
||||
}
|
||||
}
|
||||
|
||||
if (Material.Slots.ContainsKey(MaterialSlotType::Normal))
|
||||
{
|
||||
auto MaterialNormalMap = this->_MaterialStreamer("", Material.Slots[MaterialSlotType::Normal].second);
|
||||
if (MaterialNormalMap != nullptr)
|
||||
{
|
||||
glGenTextures(1, &Draw.Material.NormalMap);
|
||||
this->LoadDXTextureOGL(*MaterialNormalMap.get(), Draw.Material.NormalMap);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if (Material.Slots.ContainsKey(MaterialSlotType::Gloss))
|
||||
{
|
||||
auto MaterialGlossMap = this->_MaterialStreamer("", Material.Slots[MaterialSlotType::Gloss].second);
|
||||
if (MaterialGlossMap != nullptr)
|
||||
{
|
||||
glGenTextures(1, &Draw.Material.RoughnessMap);
|
||||
this->LoadDXTextureOGL(*MaterialGlossMap.get(), Draw.Material.RoughnessMap);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if (Material.Slots.ContainsKey(MaterialSlotType::Specular))
|
||||
{
|
||||
auto MaterialSpecMap = this->_MaterialStreamer("", Material.Slots[MaterialSlotType::Specular].second);
|
||||
if (MaterialSpecMap != nullptr)
|
||||
{
|
||||
glGenTextures(1, &Draw.Material.MetallicMap);
|
||||
this->LoadDXTextureOGL(*MaterialSpecMap.get(), Draw.Material.MetallicMap);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
Draw.LoadedMaterial = true;
|
||||
}
|
||||
|
||||
this->_DrawObjects.Emplace(Draw);
|
||||
this->_DrawInformation.VertexCount += Submesh.Vertices.Count();
|
||||
this->_DrawInformation.TriangleCount += Submesh.Faces.Count();
|
||||
}
|
||||
|
||||
glGenBuffers(1, &this->_BonePointBuffer);
|
||||
List<Math::Vector3> Positions;
|
||||
|
||||
for (int32_t i = (int32_t)Model.Bones.Count() - 1; i >= 0; i--)
|
||||
{
|
||||
auto& CurrentBone = Model.Bones[i];
|
||||
|
||||
Positions.EmplaceBack(Math::Matrix::TransformVector(CurrentBone.GlobalPosition(), this->_Camera.GetModelMatrix()));
|
||||
|
||||
if (CurrentBone.Parent() > -1)
|
||||
Positions.EmplaceBack(Math::Matrix::TransformVector(Model.Bones[CurrentBone.Parent()].GlobalPosition(), this->_Camera.GetModelMatrix()));
|
||||
else
|
||||
Positions.EmplaceBack(0.f, 0.f, 0.f);
|
||||
}
|
||||
|
||||
this->_BonePointCount = Positions.Count();
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, this->_BonePointBuffer);
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(Math::Vector3) * Positions.Count(), &Positions[0], GL_STATIC_DRAW);
|
||||
|
||||
this->_DrawInformation.BoneCount = Model.Bones.Count();
|
||||
this->_DrawInformation.MeshCount = Model.Meshes.Count();
|
||||
|
||||
// Trigger a resize, then redraw, first redraw needs invalidation...
|
||||
this->OnResize();
|
||||
this->Invalidate();
|
||||
}
|
||||
|
||||
void AssetRenderer::SetAssetName(const string& Name)
|
||||
{
|
||||
this->_DrawInformation.AssetName = Name;
|
||||
this->Redraw();
|
||||
}
|
||||
|
||||
void AssetRenderer::ClearViewModel()
|
||||
{
|
||||
for (auto& Draw : _DrawObjects)
|
||||
{
|
||||
glDeleteVertexArrays(1, &Draw.VertexArrayObject);
|
||||
glDeleteBuffers(1, &Draw.VertexBuffer);
|
||||
glDeleteBuffers(1, &Draw.FaceBuffer);
|
||||
|
||||
if (Draw.LoadedMaterial)
|
||||
{
|
||||
glDeleteTextures(1, &Draw.Material.AlbedoMap);
|
||||
glDeleteTextures(1, &Draw.Material.AmbientOccluionMap);
|
||||
glDeleteTextures(1, &Draw.Material.MetallicMap);
|
||||
glDeleteTextures(1, &Draw.Material.NormalMap);
|
||||
glDeleteTextures(1, &Draw.Material.RoughnessMap);
|
||||
}
|
||||
}
|
||||
|
||||
glDeleteBuffers(1, &this->_BonePointBuffer);
|
||||
this->_BonePointBuffer = 0;
|
||||
this->_BonePointCount = 0;
|
||||
|
||||
_DrawObjects.Clear();
|
||||
_DrawInformation = {};
|
||||
}
|
||||
|
||||
void AssetRenderer::SetMaterialStreamer(MaterialStreamCallback Callback)
|
||||
{
|
||||
this->_MaterialStreamer = std::move(Callback);
|
||||
}
|
||||
|
||||
void AssetRenderer::SetViewTexture(const Texture& Texture)
|
||||
{
|
||||
this->_DrawingMode = DrawMode::Texture;
|
||||
ClearViewTexture();
|
||||
ClearViewModel();
|
||||
|
||||
glGenTextures(1, &this->_DrawTexture);
|
||||
|
||||
// Load into the draw texture slot
|
||||
this->LoadDXTextureOGL((Assets::Texture&)Texture, this->_DrawTexture);
|
||||
|
||||
this->_DrawInformation.Width = Texture.Width();
|
||||
this->_DrawInformation.Height = Texture.Height();
|
||||
|
||||
// Determine best fit scale to fit the image
|
||||
float Scale = min((float)this->_ClientWidth / (float)Texture.Width(), (float)this->_ClientHeight / (float)Texture.Height());
|
||||
this->_DrawInformation.Scale = min(100, (int)(Scale * 100));
|
||||
}
|
||||
|
||||
void AssetRenderer::ClearViewTexture()
|
||||
{
|
||||
glDeleteTextures(1, &this->_DrawTexture);
|
||||
_DrawInformation = {};
|
||||
}
|
||||
|
||||
void AssetRenderer::SetUseWireframe(bool Value)
|
||||
{
|
||||
if (Value != this->_UseWireframe)
|
||||
{
|
||||
this->_UseWireframe = Value;
|
||||
this->Redraw();
|
||||
}
|
||||
}
|
||||
|
||||
void AssetRenderer::SetShowBones(bool Value)
|
||||
{
|
||||
if (Value != this->_ShowBones)
|
||||
{
|
||||
this->_ShowBones = Value;
|
||||
this->Redraw();
|
||||
}
|
||||
}
|
||||
|
||||
void AssetRenderer::SetShowMaterials(bool Value)
|
||||
{
|
||||
if (Value != this->_ShowMaterials)
|
||||
{
|
||||
this->_ShowMaterials = Value;
|
||||
this->Redraw();
|
||||
}
|
||||
}
|
||||
|
||||
void AssetRenderer::SetZUpAxis(bool ZUp)
|
||||
{
|
||||
if (ZUp)
|
||||
this->_Camera.SetUpAxis(RenderViewCameraUpAxis::Z);
|
||||
else
|
||||
this->_Camera.SetUpAxis(RenderViewCameraUpAxis::Y);
|
||||
|
||||
if (this->GetState(Forms::ControlStates::StateCreated))
|
||||
this->Redraw();
|
||||
}
|
||||
|
||||
void AssetRenderer::ResetView()
|
||||
{
|
||||
this->_Camera.Reset(0.5f * (float)MathHelper::PI, 0.45f * (float)MathHelper::PI, 100.f);
|
||||
this->Redraw();
|
||||
}
|
||||
|
||||
void AssetRenderer::ZoomModelToView()
|
||||
{
|
||||
// Using the bounding box, we need to
|
||||
// TODO: Implement this zoom code
|
||||
}
|
||||
|
||||
void AssetRenderer::OnRender()
|
||||
{
|
||||
// Clear the frame
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
this->RenderBackground();
|
||||
|
||||
switch (this->_DrawingMode)
|
||||
{
|
||||
case DrawMode::Model:
|
||||
this->RenderGrid();
|
||||
this->RenderModel();
|
||||
break;
|
||||
case DrawMode::Texture:
|
||||
this->RenderTexture();
|
||||
break;
|
||||
}
|
||||
|
||||
this->RenderHUD();
|
||||
|
||||
// Render the frame
|
||||
SwapBuffers(this->_DCHandle);
|
||||
}
|
||||
|
||||
void AssetRenderer::OnResize()
|
||||
{
|
||||
glViewport(0, 0, this->_ClientWidth, this->_ClientHeight);
|
||||
|
||||
// Update the projection matrix
|
||||
this->_Camera.UpdateProjectionMatrix(45.f, (float)this->_ClientWidth, (float)this->_ClientHeight, .1f, 10000.f);
|
||||
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadMatrixf(this->_Camera.GetProjectionMatrix().GetMatrix());
|
||||
|
||||
// Switch back to the modelview matrix
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glLoadIdentity();
|
||||
|
||||
// Ask the control to do the resize event
|
||||
OpenGLViewport::OnResize();
|
||||
}
|
||||
|
||||
void AssetRenderer::OnHandleCreated()
|
||||
{
|
||||
OpenGLViewport::OnHandleCreated();
|
||||
|
||||
// Now, the opengl context is completely valid, we can initialize our font / shaders
|
||||
this->_RenderFont.LoadFont(FontArial_PTRF, sizeof(FontArial_PTRF));
|
||||
|
||||
#if _DEBUG
|
||||
// Grab the root path of the libraries...
|
||||
auto CppNetPath = IO::Path::GetDirectoryName(IO::Path::GetDirectoryName(__FILE__));
|
||||
auto Vert = IO::Path::Combine(CppNetPath, "cppkore_shaders\\preview.vert");
|
||||
auto Frag = IO::Path::Combine(CppNetPath, "cppkore_shaders\\preview.frag");
|
||||
printf("-- NOTICE: Using debug shaders from disk --\n");
|
||||
printf("Vertex: %s\nFrag: %s\n", Vert.ToCString(), Frag.ToCString());
|
||||
this->_ModelShader.LoadShader(Vert, Frag);
|
||||
#else
|
||||
this->_ModelShader.LoadShader(ModelVertexShader_Src, ModelFragmentShader_Src);
|
||||
#endif
|
||||
}
|
||||
|
||||
void AssetRenderer::OnKeyUp(const std::unique_ptr<Forms::KeyEventArgs>& EventArgs)
|
||||
{
|
||||
if (EventArgs->KeyCode() == Forms::Keys::W)
|
||||
{
|
||||
this->SetUseWireframe(!this->_UseWireframe);
|
||||
}
|
||||
else if (EventArgs->KeyCode() == Forms::Keys::B)
|
||||
{
|
||||
this->SetShowBones(!this->_ShowBones);
|
||||
}
|
||||
else if (EventArgs->KeyCode() == Forms::Keys::T)
|
||||
{
|
||||
this->SetShowMaterials(!this->_ShowMaterials);
|
||||
}
|
||||
|
||||
OpenGLViewport::OnKeyUp(EventArgs);
|
||||
}
|
||||
|
||||
void AssetRenderer::OnMouseDown(const std::unique_ptr<Forms::MouseEventArgs>& EventArgs)
|
||||
{
|
||||
this->_TargetMousePosition = Vector2((float)EventArgs->X, (float)EventArgs->Y);
|
||||
OpenGLViewport::OnMouseDown(EventArgs);
|
||||
}
|
||||
|
||||
void AssetRenderer::OnMouseMove(const std::unique_ptr<Forms::MouseEventArgs>& EventArgs)
|
||||
{
|
||||
auto IsAltKey = (GetKeyState(VK_MENU) & 0x8000);
|
||||
|
||||
if (EventArgs->Button == Forms::MouseButtons::Left && IsAltKey)
|
||||
{
|
||||
float dPhi = ((float)(this->_TargetMousePosition.Y - EventArgs->Y) / 200.f);
|
||||
float dTheta = ((float)(this->_TargetMousePosition.X - EventArgs->X) / 200.f);
|
||||
|
||||
this->_Camera.Rotate(dTheta, dPhi);
|
||||
this->Redraw();
|
||||
}
|
||||
else if (EventArgs->Button == Forms::MouseButtons::Middle && IsAltKey)
|
||||
{
|
||||
float dx = ((float)(this->_TargetMousePosition.X - EventArgs->X));
|
||||
float dy = ((float)(this->_TargetMousePosition.Y - EventArgs->Y));
|
||||
|
||||
this->_Camera.Pan(dx * .1f, dy * .1f);
|
||||
this->Redraw();
|
||||
}
|
||||
else if (EventArgs->Button == Forms::MouseButtons::Right && IsAltKey)
|
||||
{
|
||||
float dx = ((float)(this->_TargetMousePosition.X - EventArgs->X) / 2.f);
|
||||
|
||||
this->_Camera.Zoom(-dx);
|
||||
this->Redraw();
|
||||
}
|
||||
|
||||
this->_TargetMousePosition = Vector2((float)EventArgs->X, (float)EventArgs->Y);
|
||||
|
||||
OpenGLViewport::OnMouseMove(EventArgs);
|
||||
}
|
||||
|
||||
void AssetRenderer::OnMouseWheel(const std::unique_ptr<Forms::HandledMouseEventArgs>& EventArgs)
|
||||
{
|
||||
if (this->_DrawingMode == DrawMode::Texture)
|
||||
{
|
||||
if (EventArgs->Delta > 0)
|
||||
this->_DrawInformation.Scale += 3;
|
||||
else
|
||||
this->_DrawInformation.Scale -= 3;
|
||||
this->_DrawInformation.Scale = max(min(200, this->_DrawInformation.Scale), 0);
|
||||
}
|
||||
else if (this->_DrawingMode == DrawMode::Model)
|
||||
{
|
||||
this->_Camera.Zoom((float)EventArgs->Delta * .04f);
|
||||
}
|
||||
|
||||
this->Redraw();
|
||||
|
||||
OpenGLViewport::OnMouseWheel(EventArgs);
|
||||
}
|
||||
|
||||
void AssetRenderer::RenderBackground()
|
||||
{
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
glDisable(GL_LIGHTING);
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
|
||||
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
|
||||
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadIdentity();
|
||||
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glLoadIdentity();
|
||||
|
||||
glBegin(GL_QUADS);
|
||||
|
||||
glColor3f(this->_BackColor.GetR() / 255.f, this->_BackColor.GetG() / 255.f, this->_BackColor.GetB() / 255.f);
|
||||
|
||||
glVertex2f(-1.0, -1.0);
|
||||
glVertex2f(1.0, -1.0);
|
||||
glVertex2f(1.0, 1.0);
|
||||
glVertex2f(-1.0, 1.0);
|
||||
|
||||
glEnd();
|
||||
}
|
||||
|
||||
void AssetRenderer::RenderGrid()
|
||||
{
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadMatrixf(this->_Camera.GetProjectionMatrix().GetMatrix());
|
||||
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glLoadMatrixf(this->_Camera.GetViewMatrix().GetMatrix());
|
||||
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glDepthFunc(GL_LESS);
|
||||
|
||||
glBegin(GL_LINES);
|
||||
glLineWidth(1.f);
|
||||
|
||||
auto Size = 5.0f;
|
||||
auto MinSize = -Size;
|
||||
auto Step = 0.5f;
|
||||
|
||||
for (GLfloat i = MinSize; i <= Size; i += Step)
|
||||
{
|
||||
if (i == 0)
|
||||
{
|
||||
glColor3f(0, 0, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
glColor3f(.70f, .70f, .70f);
|
||||
}
|
||||
|
||||
glVertex3f(i, 0, Size); glVertex3f(i, 0, MinSize);
|
||||
glVertex3f(Size, 0, i); glVertex3f(MinSize, 0, i);
|
||||
}
|
||||
|
||||
glEnd();
|
||||
}
|
||||
|
||||
void AssetRenderer::RenderModel()
|
||||
{
|
||||
this->_ModelShader.Use();
|
||||
|
||||
if (_UseWireframe)
|
||||
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
|
||||
else
|
||||
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
|
||||
|
||||
// Calculate and load the matrix
|
||||
auto Model = this->_Camera.GetModelMatrix();
|
||||
auto View = this->_Camera.GetViewMatrix();
|
||||
auto Proj = this->_Camera.GetProjectionMatrix();
|
||||
|
||||
const uint32_t Stride = sizeof(Vector3) + sizeof(Vector3) + sizeof(VertexColor) + sizeof(Vector2);
|
||||
|
||||
glUniformMatrix4fv(this->_ModelShader.GetUniformLocation("model"), 1, GL_FALSE, Model.GetMatrix());
|
||||
glUniformMatrix4fv(this->_ModelShader.GetUniformLocation("view"), 1, GL_FALSE, View.GetMatrix());
|
||||
glUniformMatrix4fv(this->_ModelShader.GetUniformLocation("projection"), 1, GL_FALSE, Proj.GetMatrix());
|
||||
|
||||
glEnableVertexAttribArray(0);
|
||||
glEnableVertexAttribArray(1);
|
||||
glEnableVertexAttribArray(2);
|
||||
glEnableVertexAttribArray(3);
|
||||
|
||||
for (auto& Draw : this->_DrawObjects)
|
||||
{
|
||||
|
||||
if (Draw.LoadedMaterial && this->_ShowMaterials)
|
||||
{
|
||||
const GLint DiffuseLoaded = 1;
|
||||
glUniform1iv(this->_ModelShader.GetUniformLocation("diffuseLoaded"), 1, &DiffuseLoaded);
|
||||
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
const GLint DiffuseLoaded = 0;
|
||||
glUniform1iv(this->_ModelShader.GetUniformLocation("diffuseLoaded"), 1, &DiffuseLoaded);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_2D, Draw.Material.AlbedoMap);
|
||||
|
||||
const GLint DiffuseSlot = 0;
|
||||
glUniform1iv(this->_ModelShader.GetUniformLocation("diffuseTexture"), 1, &DiffuseSlot);
|
||||
|
||||
|
||||
glActiveTexture(GL_TEXTURE1);
|
||||
glBindTexture(GL_TEXTURE_2D, Draw.Material.NormalMap);
|
||||
|
||||
|
||||
const GLint NormalSlot = 1;
|
||||
glUniform1iv(this->_ModelShader.GetUniformLocation("normalTexture"), 1, &NormalSlot);
|
||||
|
||||
|
||||
|
||||
glActiveTexture(GL_TEXTURE2);
|
||||
glBindTexture(GL_TEXTURE_2D, Draw.Material.RoughnessMap);
|
||||
|
||||
|
||||
const GLint GlossSlot = 2;
|
||||
glUniform1iv(this->_ModelShader.GetUniformLocation("glossTexture"), 1, &GlossSlot);
|
||||
|
||||
|
||||
|
||||
glActiveTexture(GL_TEXTURE3);
|
||||
glBindTexture(GL_TEXTURE_2D, Draw.Material.MetallicMap);
|
||||
|
||||
|
||||
const GLint SpecularSlot = 3;
|
||||
glUniform1iv(this->_ModelShader.GetUniformLocation("specularTexture"), 1, &SpecularSlot);
|
||||
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, Draw.VertexBuffer);
|
||||
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, Stride, (void*)0);
|
||||
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, Stride, (void*)12);
|
||||
glVertexAttribPointer(2, 4, GL_UNSIGNED_BYTE, GL_TRUE, Stride, (void*)24);
|
||||
glVertexAttribPointer(3, 2, GL_FLOAT, GL_FALSE, Stride, (void*)28);
|
||||
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, Draw.FaceBuffer);
|
||||
glDrawElements(GL_TRIANGLES, Draw.FaceCount * 3, GL_UNSIGNED_INT, (void*)0);
|
||||
}
|
||||
|
||||
glDisableVertexAttribArray(0);
|
||||
glDisableVertexAttribArray(1);
|
||||
glDisableVertexAttribArray(2);
|
||||
glDisableVertexAttribArray(3);
|
||||
|
||||
this->_ModelShader.Detatch();
|
||||
|
||||
if (this->_ShowBones)
|
||||
{
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
|
||||
glColor3f(18 / 255.f, 0, 54 / 255.f);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, this->_BonePointBuffer);
|
||||
|
||||
glEnableVertexAttribArray(0);
|
||||
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
|
||||
|
||||
glDrawArrays(GL_LINES, 0, this->_BonePointCount);
|
||||
}
|
||||
|
||||
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
|
||||
}
|
||||
|
||||
void AssetRenderer::RenderTexture()
|
||||
{
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadMatrixf(Matrix::CreateOrthographic(0, (float)this->_ClientWidth, (float)this->_ClientHeight, 0, -1, 1).GetMatrix());
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glLoadIdentity();
|
||||
|
||||
glColor3f(1.0f, 1.0f, 1.0f);
|
||||
glDisable(GL_BLEND);
|
||||
|
||||
float Scale = (float)this->_DrawInformation.Scale / 100.f;
|
||||
|
||||
float ImageWidth = this->_DrawInformation.Width * Scale;
|
||||
float ImageHeight = this->_DrawInformation.Height * Scale;
|
||||
|
||||
float Width = (ImageWidth);
|
||||
float Height = (ImageHeight);
|
||||
float X = (this->_ClientWidth - (float)Width) / 2.0f;
|
||||
float Y = (this->_ClientHeight - (float)Height) / 2.0f;
|
||||
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
glBindTexture(GL_TEXTURE_2D, this->_DrawTexture);
|
||||
glBegin(GL_QUADS);
|
||||
glTexCoord2i(0, 0); glVertex2f(X, Y);
|
||||
glTexCoord2i(0, 1); glVertex2f(X, Y + Height);
|
||||
glTexCoord2i(1, 1); glVertex2f(X + Width, Y + Height);
|
||||
glTexCoord2i(1, 0); glVertex2f(X + Width, Y);
|
||||
glEnd();
|
||||
}
|
||||
|
||||
void AssetRenderer::RenderHUD()
|
||||
{
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadMatrixf(Matrix::CreateOrthographic(0, (float)this->_ClientWidth, (float)this->_ClientHeight, 0, -1, 1).GetMatrix());
|
||||
|
||||
// Scale the font size for dpi aware controls
|
||||
auto Screen = GetDC(nullptr);
|
||||
auto Ratio = GetDeviceCaps(Screen, LOGPIXELSX);
|
||||
ReleaseDC(nullptr, Screen);
|
||||
|
||||
// We based layout on stock 96 dpi, which is 100% scaling on windows
|
||||
// so scale linearly based on that
|
||||
const auto Scale = (1.0f - (96.f / (float)Ratio)) + 1.0f;
|
||||
const auto FontScale = 0.7f * Scale;
|
||||
|
||||
switch (this->_DrawingMode)
|
||||
{
|
||||
case DrawMode::Model:
|
||||
glColor4f(3 / 255.f, 169 / 255.f, 244 / 255.f, 1);
|
||||
|
||||
_RenderFont.RenderString("Model", 22, 22, FontScale); _RenderFont.RenderString(":", 80, 22, FontScale);
|
||||
_RenderFont.RenderString("Meshes", 22, 38, FontScale); _RenderFont.RenderString(":", 80, 38, FontScale);
|
||||
_RenderFont.RenderString("Verts", 22, 54, FontScale); _RenderFont.RenderString(":", 80, 54, FontScale);
|
||||
_RenderFont.RenderString("Tris", 22, 70, FontScale); _RenderFont.RenderString(":", 80, 70, FontScale);
|
||||
_RenderFont.RenderString("Bones", 22, 86, FontScale); _RenderFont.RenderString(":", 80, 86, FontScale);
|
||||
|
||||
glColor4f(35 / 255.f, 206 / 255.f, 107 / 255.f, 1);
|
||||
|
||||
_RenderFont.RenderString(string((this->_ShowBones) ? "Hide Bones (b), " : "Draw Bones (b), ") + string((this->_ShowMaterials) ? "Shaded View (t), " : "Material View (t), ") + string((this->_UseWireframe) ? "Hide Wireframe (w)" : "Draw Wireframe (w)"), 22, this->_Height - 44.f, FontScale);
|
||||
|
||||
glColor4f(0.9f, 0.9f, 0.9f, 1);
|
||||
|
||||
_RenderFont.RenderString((this->_DrawInformation.AssetName == "") ? string("N/A") : this->_DrawInformation.AssetName, 96, 22, FontScale);
|
||||
_RenderFont.RenderString(string::Format("%d", this->_DrawInformation.MeshCount), 96, 38, FontScale);
|
||||
_RenderFont.RenderString(string::Format("%d", this->_DrawInformation.VertexCount), 96, 54, FontScale);
|
||||
_RenderFont.RenderString(string::Format("%d", this->_DrawInformation.TriangleCount), 96, 70, FontScale);
|
||||
_RenderFont.RenderString(string::Format("%d", this->_DrawInformation.BoneCount), 96, 86, FontScale);
|
||||
break;
|
||||
case DrawMode::Texture:
|
||||
glColor4f(3 / 255.f, 169 / 255.f, 244 / 255.f, 1);
|
||||
|
||||
_RenderFont.RenderString("Image", 22, 22, FontScale); _RenderFont.RenderString(":", 80, 22, FontScale);
|
||||
_RenderFont.RenderString("Width", 22, 38, FontScale); _RenderFont.RenderString(":", 80, 38, FontScale);
|
||||
_RenderFont.RenderString("Height", 22, 54, FontScale); _RenderFont.RenderString(":", 80, 54, FontScale);
|
||||
_RenderFont.RenderString("Scale", 22, 70, FontScale); _RenderFont.RenderString(":", 80, 70, FontScale);
|
||||
|
||||
glColor4f(0.9f, 0.9f, 0.9f, 1);
|
||||
|
||||
_RenderFont.RenderString((this->_DrawInformation.AssetName == "") ? string("N/A") : this->_DrawInformation.AssetName, 96, 22, FontScale);
|
||||
_RenderFont.RenderString(string::Format("%d", this->_DrawInformation.Width), 96, 38, FontScale);
|
||||
_RenderFont.RenderString(string::Format("%d", this->_DrawInformation.Height), 96, 54, FontScale);
|
||||
_RenderFont.RenderString(string::Format("%d%%", this->_DrawInformation.Scale), 96, 70, FontScale);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void AssetRenderer::LoadDXTextureOGL(Texture& Texture, const uint32_t TextureSlot)
|
||||
{
|
||||
glBindTexture(GL_TEXTURE_2D, TextureSlot);
|
||||
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
||||
|
||||
switch (Texture.Format())
|
||||
{
|
||||
case DXGI_FORMAT::DXGI_FORMAT_BC6H_UF16:
|
||||
Texture.ConvertToFormat(DXGI_FORMAT_BC1_UNORM);
|
||||
case DXGI_FORMAT::DXGI_FORMAT_BC1_UNORM:
|
||||
case DXGI_FORMAT::DXGI_FORMAT_BC1_UNORM_SRGB:
|
||||
glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, Texture.Width(), Texture.Height(), 0, Texture.BlockSize(), Texture.GetPixels());
|
||||
break;
|
||||
case DXGI_FORMAT::DXGI_FORMAT_BC2_UNORM:
|
||||
case DXGI_FORMAT::DXGI_FORMAT_BC2_UNORM_SRGB:
|
||||
glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, Texture.Width(), Texture.Height(), 0, Texture.BlockSize(), Texture.GetPixels());
|
||||
break;
|
||||
case DXGI_FORMAT::DXGI_FORMAT_BC3_UNORM:
|
||||
case DXGI_FORMAT::DXGI_FORMAT_BC3_UNORM_SRGB:
|
||||
glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, Texture.Width(), Texture.Height(), 0, Texture.BlockSize(), Texture.GetPixels());
|
||||
break;
|
||||
case DXGI_FORMAT::DXGI_FORMAT_BC4_UNORM:
|
||||
case DXGI_FORMAT::DXGI_FORMAT_BC4_SNORM:
|
||||
glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RED_RGTC1, Texture.Width(), Texture.Height(), 0, Texture.BlockSize(), Texture.GetPixels());
|
||||
break;
|
||||
case DXGI_FORMAT::DXGI_FORMAT_BC5_UNORM:
|
||||
case DXGI_FORMAT::DXGI_FORMAT_BC5_SNORM:
|
||||
glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RG_RGTC2, Texture.Width(), Texture.Height(), 0, Texture.BlockSize(), Texture.GetPixels());
|
||||
break;
|
||||
case DXGI_FORMAT::DXGI_FORMAT_BC7_UNORM_SRGB:
|
||||
case DXGI_FORMAT::DXGI_FORMAT_BC7_UNORM:
|
||||
glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGBA_BPTC_UNORM, Texture.Width(), Texture.Height(), 0, Texture.BlockSize(), Texture.GetPixels());
|
||||
break;
|
||||
case DXGI_FORMAT::DXGI_FORMAT_R8_UNORM:
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, Texture.Width(), Texture.Height(), 0, GL_RED, GL_UNSIGNED_BYTE, Texture.GetPixels());
|
||||
break;
|
||||
case DXGI_FORMAT::DXGI_FORMAT_R8G8_UNORM:
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE_ALPHA, Texture.Width(), Texture.Height(), 0, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, Texture.GetPixels());
|
||||
break;
|
||||
case DXGI_FORMAT::DXGI_FORMAT_R8G8B8A8_UNORM:
|
||||
case DXGI_FORMAT::DXGI_FORMAT_R8G8B8A8_UNORM_SRGB:
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, Texture.Width(), Texture.Height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, Texture.GetPixels());
|
||||
break;
|
||||
default:
|
||||
#if _DEBUG
|
||||
printf("Unsupported DXGI->OGL mapping\n");
|
||||
__debugbreak();
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
DrawObject::DrawObject()
|
||||
: VertexArrayObject(0), VertexBuffer(0), FaceBuffer(0), LoadedMaterial(false), FaceCount(0), VertexCount(0), Material{(uint32_t)-1, (uint32_t)-1, (uint32_t)-1, (uint32_t)-1, (uint32_t)-1}
|
||||
{
|
||||
}
|
||||
}
|
165
r5dev/thirdparty/cppnet/cppkore/AssetRenderer.h
vendored
Normal file
165
r5dev/thirdparty/cppnet/cppkore/AssetRenderer.h
vendored
Normal file
@ -0,0 +1,165 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <memory>
|
||||
#include <atomic>
|
||||
#include <functional>
|
||||
#include "Model.h"
|
||||
#include "Animation.h"
|
||||
#include "Texture.h"
|
||||
#include "ListBase.h"
|
||||
#include "OpenGLViewport.h"
|
||||
#include "RenderViewCamera.h"
|
||||
#include "RenderShader.h"
|
||||
#include "RenderFont.h"
|
||||
|
||||
namespace Assets
|
||||
{
|
||||
// A 3D uniform buffer object
|
||||
struct DrawObjectMaterial
|
||||
{
|
||||
uint32_t AlbedoMap;
|
||||
uint32_t NormalMap;
|
||||
uint32_t MetallicMap;
|
||||
uint32_t RoughnessMap;
|
||||
uint32_t AmbientOccluionMap;
|
||||
};
|
||||
|
||||
// A 3D buffer object that is being drawn.
|
||||
struct DrawObject
|
||||
{
|
||||
uint32_t VertexArrayObject;
|
||||
uint32_t VertexBuffer;
|
||||
uint32_t FaceBuffer;
|
||||
|
||||
bool LoadedMaterial;
|
||||
DrawObjectMaterial Material;
|
||||
|
||||
uint32_t FaceCount;
|
||||
uint32_t VertexCount;
|
||||
|
||||
DrawObject();
|
||||
};
|
||||
|
||||
enum class DrawMode
|
||||
{
|
||||
Model,
|
||||
Animation,
|
||||
Texture
|
||||
};
|
||||
|
||||
// A 3D asset renderer control.
|
||||
class AssetRenderer : public Forms::OpenGLViewport
|
||||
{
|
||||
public:
|
||||
AssetRenderer();
|
||||
virtual ~AssetRenderer();
|
||||
|
||||
// Special function to stream in a material image
|
||||
using MaterialStreamCallback = std::function<std::unique_ptr<Texture>(const string, const uint64_t)>;
|
||||
|
||||
// Clears the current model, if any, and assigns the new one
|
||||
void SetViewModel(const Model& Model);
|
||||
// Clears the current model
|
||||
void ClearViewModel();
|
||||
|
||||
// Applies a custom material streamer routine
|
||||
void SetMaterialStreamer(MaterialStreamCallback Callback);
|
||||
|
||||
// Clears the current texture, if any, and assigns the new one
|
||||
void SetViewTexture(const Texture& Texture);
|
||||
// Clears the current texture
|
||||
void ClearViewTexture();
|
||||
|
||||
// Sets the name of the model
|
||||
void SetAssetName(const string& Name);
|
||||
|
||||
// Enable or disable wireframe rendering
|
||||
void SetUseWireframe(bool Value);
|
||||
// Enable or disable bone rendering
|
||||
void SetShowBones(bool Value);
|
||||
// Enable or disable material rendering
|
||||
void SetShowMaterials(bool Value);
|
||||
|
||||
// Changes the up axis
|
||||
void SetZUpAxis(bool ZUp);
|
||||
|
||||
// Resets the current view to the default view
|
||||
void ResetView();
|
||||
// Brings the current model into view
|
||||
void ZoomModelToView();
|
||||
|
||||
// We must define base events here
|
||||
virtual void OnRender();
|
||||
virtual void OnResize();
|
||||
virtual void OnHandleCreated();
|
||||
virtual void OnKeyUp(const std::unique_ptr<Forms::KeyEventArgs>& EventArgs);
|
||||
virtual void OnMouseDown(const std::unique_ptr<Forms::MouseEventArgs>& EventArgs);
|
||||
virtual void OnMouseMove(const std::unique_ptr<Forms::MouseEventArgs>& EventArgs);
|
||||
virtual void OnMouseWheel(const std::unique_ptr<Forms::HandledMouseEventArgs>& EventArgs);
|
||||
|
||||
private:
|
||||
// Internal buffers
|
||||
List<DrawObject> _DrawObjects;
|
||||
|
||||
// Internal buffer for texture mode
|
||||
uint32_t _DrawTexture;
|
||||
|
||||
// Internal bone point buffer
|
||||
uint32_t _BonePointBuffer;
|
||||
// Internal bone point count
|
||||
uint32_t _BonePointCount;
|
||||
|
||||
struct
|
||||
{
|
||||
uint32_t VertexCount;
|
||||
uint32_t TriangleCount;
|
||||
uint32_t MeshCount;
|
||||
|
||||
uint32_t Width;
|
||||
uint32_t Height;
|
||||
|
||||
int32_t Scale;
|
||||
|
||||
string AssetName;
|
||||
|
||||
uint32_t BoneCount;
|
||||
} _DrawInformation;
|
||||
|
||||
DrawMode _DrawingMode;
|
||||
|
||||
// The target mouse position
|
||||
Vector2 _TargetMousePosition;
|
||||
|
||||
// Function to handle streaming in material images
|
||||
MaterialStreamCallback _MaterialStreamer;
|
||||
|
||||
// The view camera instance
|
||||
RenderViewCamera _Camera;
|
||||
// The shader for the model
|
||||
RenderShader _ModelShader;
|
||||
// The render font instance
|
||||
RenderFont _RenderFont;
|
||||
|
||||
// Whether or not to use wireframe mode
|
||||
bool _UseWireframe;
|
||||
// Whether or not to show bones
|
||||
bool _ShowBones;
|
||||
// Whether or not to render with materials
|
||||
bool _ShowMaterials;
|
||||
|
||||
// Internal routine to render the gradient background
|
||||
void RenderBackground();
|
||||
// Internal routine to render the grid
|
||||
void RenderGrid();
|
||||
// Internal routine to render the model
|
||||
void RenderModel();
|
||||
// Internal routine to render the texture
|
||||
void RenderTexture();
|
||||
// Internal routine to render the hud
|
||||
void RenderHUD();
|
||||
|
||||
// Internal routine to load a texture to an index
|
||||
void LoadDXTextureOGL(Texture& Texture, const uint32_t TextureSlot);
|
||||
};
|
||||
}
|
75
r5dev/thirdparty/cppnet/cppkore/AtomicListBase.h
vendored
Normal file
75
r5dev/thirdparty/cppnet/cppkore/AtomicListBase.h
vendored
Normal file
@ -0,0 +1,75 @@
|
||||
#pragma once
|
||||
|
||||
#include <atomic>
|
||||
#include <thread>
|
||||
#include <mutex>
|
||||
#include "ListBase.h"
|
||||
|
||||
template<typename T>
|
||||
class AtomicListBase
|
||||
{
|
||||
public:
|
||||
AtomicListBase();
|
||||
~AtomicListBase() = default;
|
||||
|
||||
void Enqueue(T& Item);
|
||||
bool Dequeue(T& Item);
|
||||
|
||||
bool IsEmpty() const;
|
||||
uint32_t Count() const;
|
||||
|
||||
private:
|
||||
List<T> _List;
|
||||
|
||||
std::atomic<uint32_t> _SyncCount;
|
||||
std::mutex _SyncContext;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
inline AtomicListBase<T>::AtomicListBase()
|
||||
: _SyncCount(0)
|
||||
{
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline void AtomicListBase<T>::Enqueue(T& Item)
|
||||
{
|
||||
{
|
||||
std::lock_guard lock(this->_SyncContext);
|
||||
this->_List.EmplaceBack(Item);
|
||||
}
|
||||
|
||||
this->_SyncCount++;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline bool AtomicListBase<T>::Dequeue(T& Item)
|
||||
{
|
||||
{
|
||||
std::lock_guard lock(this->_SyncContext);
|
||||
const auto Length = this->_List.Count();
|
||||
|
||||
if (Length > 0)
|
||||
{
|
||||
Item = this->_List[Length - 1];
|
||||
this->_List.RemoveAt(Length - 1);
|
||||
|
||||
this->_SyncCount--;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline bool AtomicListBase<T>::IsEmpty() const
|
||||
{
|
||||
return (this->_SyncCount == 0);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline uint32_t AtomicListBase<T>::Count() const
|
||||
{
|
||||
return this->_SyncCount;
|
||||
}
|
132
r5dev/thirdparty/cppnet/cppkore/AtomicQueueBase.h
vendored
Normal file
132
r5dev/thirdparty/cppnet/cppkore/AtomicQueueBase.h
vendored
Normal file
@ -0,0 +1,132 @@
|
||||
#pragma once
|
||||
|
||||
#include <atomic>
|
||||
#include <mutex>
|
||||
#include "ListBase.h"
|
||||
|
||||
struct AtomicSyncContext
|
||||
{
|
||||
std::atomic<uint32_t> _declspec(align(std::hardware_constructive_interference_size)) Head;
|
||||
std::atomic<uint32_t> _declspec(align(std::hardware_constructive_interference_size)) Tail;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
class AtomicQueueBase
|
||||
{
|
||||
public:
|
||||
AtomicQueueBase();
|
||||
~AtomicQueueBase() = default;
|
||||
|
||||
bool Enqueue(T& Item, uint32_t Count = 1);
|
||||
bool Dequeue(T& Item, uint32_t Count = 1);
|
||||
|
||||
bool IsEmpty() const;
|
||||
uint32_t Count() const;
|
||||
|
||||
private:
|
||||
AtomicSyncContext _Writer;
|
||||
AtomicSyncContext _Reader;
|
||||
|
||||
constexpr static uint32_t BufferSize = (2 << 10);
|
||||
constexpr static uint32_t Mask = BufferSize - 1;
|
||||
|
||||
std::atomic_flag _SpinLock;
|
||||
T alignas(std::hardware_constructive_interference_size) _Buffer[BufferSize];
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
inline AtomicQueueBase<T>::AtomicQueueBase()
|
||||
: _Writer{ 0, 0 }, _Reader{ 0, 0 }, _Buffer{}, _SpinLock()
|
||||
{
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline bool AtomicQueueBase<T>::Enqueue(T& Item, uint32_t Count)
|
||||
{
|
||||
uint32_t NextHead, EndTail, NewHead;
|
||||
|
||||
// The queue can fail to insert if it's already full, so you must check the result..
|
||||
bool Success = false;
|
||||
do {
|
||||
NextHead = _Writer.Head.load(std::memory_order_acquire);
|
||||
EndTail = _Reader.Tail.load(std::memory_order_acquire);
|
||||
|
||||
// Check if queue is full, yield time slice to other threads
|
||||
if ((NextHead - EndTail + 1) > Mask)
|
||||
return false;
|
||||
|
||||
NewHead = NextHead + Count;
|
||||
Success = _Writer.Head.compare_exchange_weak(NextHead, NewHead, std::memory_order_release);
|
||||
} while (!Success);
|
||||
|
||||
_Buffer[NextHead & Mask] = Item;
|
||||
|
||||
std::atomic_thread_fence(std::memory_order_release);
|
||||
while (_Writer.Tail.load(std::memory_order_acquire) != NextHead)
|
||||
{
|
||||
// Spin lock wait
|
||||
while (_SpinLock.test_and_set(std::memory_order_acquire));
|
||||
}
|
||||
|
||||
// Set the value and unlock the spin
|
||||
_Writer.Tail.store(NewHead, std::memory_order_release);
|
||||
_SpinLock.clear(std::memory_order_release);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline bool AtomicQueueBase<T>::Dequeue(T& Item, uint32_t Count)
|
||||
{
|
||||
uint32_t Head, Tail, Next;
|
||||
|
||||
bool Success = false;
|
||||
do {
|
||||
Tail = _Reader.Head.load(std::memory_order_acquire);
|
||||
Head = _Writer.Tail.load(std::memory_order_acquire);
|
||||
|
||||
// Check if the queue is empty, in that case, no result
|
||||
if (Head == Tail)
|
||||
return false;
|
||||
|
||||
Next = Tail + Count;
|
||||
Success = _Reader.Head.compare_exchange_weak(Tail, Next, std::memory_order_release);
|
||||
} while (!Success);
|
||||
|
||||
Item = _Buffer[Tail & Mask];
|
||||
|
||||
std::atomic_thread_fence(std::memory_order_acquire);
|
||||
while (_Reader.Tail.load(std::memory_order_acquire) != Tail)
|
||||
{
|
||||
// Spin lock wait
|
||||
while (_SpinLock.test_and_set(std::memory_order_acquire));
|
||||
}
|
||||
|
||||
_Reader.Tail.store(Next, std::memory_order_release);
|
||||
_SpinLock.clear(std::memory_order_release);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline bool AtomicQueueBase<T>::IsEmpty() const
|
||||
{
|
||||
uint32_t Tail = _Reader.Head.load(std::memory_order_acquire);
|
||||
uint32_t Head = _Writer.Tail.load(std::memory_order_acquire);
|
||||
|
||||
// Check if the queue is empty, in that case, no result
|
||||
if (Head == Tail)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline uint32_t AtomicQueueBase<T>::Count() const
|
||||
{
|
||||
// We need to subtract where we are writing to
|
||||
uint32_t Tail = _Reader.Head.load(std::memory_order_acquire);
|
||||
uint32_t Head = _Writer.Tail.load(std::memory_order_acquire);
|
||||
|
||||
return (Head - Tail);
|
||||
}
|
13
r5dev/thirdparty/cppnet/cppkore/AutoScaleMode.h
vendored
Normal file
13
r5dev/thirdparty/cppnet/cppkore/AutoScaleMode.h
vendored
Normal file
@ -0,0 +1,13 @@
|
||||
#pragma once
|
||||
|
||||
namespace Forms
|
||||
{
|
||||
// Specifies the auto scaling mode used by a container control.
|
||||
enum class AutoScaleMode
|
||||
{
|
||||
None,
|
||||
Font,
|
||||
Dpi,
|
||||
Inherit
|
||||
};
|
||||
}
|
517
r5dev/thirdparty/cppnet/cppkore/AutodeskMaya.cpp
vendored
Normal file
517
r5dev/thirdparty/cppnet/cppkore/AutodeskMaya.cpp
vendored
Normal file
@ -0,0 +1,517 @@
|
||||
#include "stdafx.h"
|
||||
#include "AutodeskMaya.h"
|
||||
|
||||
#include "File.h"
|
||||
#include "Path.h"
|
||||
#include "CRC32.h"
|
||||
#include "StreamWriter.h"
|
||||
#include "DictionaryBase.h"
|
||||
|
||||
namespace Assets::Exporters
|
||||
{
|
||||
bool AutodeskMaya::ExportAnimation(const Animation& Animation, const string& Path)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool AutodeskMaya::ExportModel(const Model& Model, const string& Path)
|
||||
{
|
||||
auto Writer = IO::StreamWriter(IO::File::Create(Path));
|
||||
auto FileName = IO::Path::GetFileNameWithoutExtension(Path);
|
||||
auto Hash = Hashing::CRC32::HashString(FileName);
|
||||
|
||||
Writer.WriteLine(
|
||||
"//Maya ASCII 8.5 scene\n\n"
|
||||
"requires maya \"8.5\";\ncurrentUnit -l centimeter -a degree -t film;\nfileInfo \"application\" \"maya\";\nfileInfo \"product\" \"Maya Unlimited 8.5\";\nfileInfo \"version\" \"8.5\";\nfileInfo \"cutIdentifier\" \"200612162224-692032\";"
|
||||
"createNode transform -s -n \"persp\";\n\tsetAttr \".v\" no;\n\tsetAttr \".t\" -type \"double3\" 48.186233840145825 37.816674066853686 41.0540421364379 ;\n\tsetAttr \".r\" -type \"double3\" -29.738352729603015 49.400000000000432 0 ;\ncreateNode camera -s -n \"perspShape\" -p \"persp\";\n\tsetAttr -k off \".v\" no;\n\tsetAttr \".fl\" 34.999999999999993;\n\tsetAttr \".fcp\" 10000;\n\tsetAttr \".coi\" 73.724849603665149;\n\tsetAttr \".imn\" -type \"string\" \"persp\";\n\tsetAttr \".den\" -type \"string\" \"persp_depth\";\n\tsetAttr \".man\" -type \"string\" \"persp_mask\";\n\tsetAttr \".hc\" -type \"string\" \"viewSet -p %camera\";\ncreateNode transform -s -n \"top\";\n\tsetAttr \".v\" no;\n\tsetAttr \".t\" -type \"double3\" 0 100.1 0 ;\n\tsetAttr \".r\" -type \"double3\" -89.999999999999986 0 0 ;\ncreateNode camera -s -n \"topShape\" -p \"top\";\n\tsetAttr -k off \".v\" no;\n\tsetAttr \".rnd\" no;\n\tsetAttr \".coi\" 100.1;\n\tsetAttr \".ow\" 30;\n\tsetAttr \".imn\" -type \"string\" \"top\";\n\tsetAttr \".den\" -type \"string\" \"top_depth\";\n\tsetAttr \".man\" -type \"string\" \"top_mask\";\n\tsetAttr \".hc\" -type \"string\" \"viewSet -t %camera\";\n\tsetAttr \".o\" yes;\ncreateNode transform -s -n \"front\";\n\tsetAttr \".v\" no;\n\tsetAttr \".t\" -type \"double3\" 0 0 100.1 ;\ncreateNode camera -s -n \"frontShape\" -p \"front\";\n\tsetAttr -k off \".v\" no;\n\tsetAttr \".rnd\" no;\n\tsetAttr \".coi\" 100.1;\n\tsetAttr \".ow\" 30;\n\tsetAttr \".imn\" -type \"string\" \"front\";\n\tsetAttr \".den\" -type \"string\" \"front_depth\";\n\tsetAttr \".man\" -type \"string\" \"front_mask\";\n\tsetAttr \".hc\" -type \"string\" \"viewSet -f %camera\";\n\tsetAttr \".o\" yes;\ncreateNode transform -s -n \"side\";\n\tsetAttr \".v\" no;\n\tsetAttr \".t\" -type \"double3\" 100.1 0 0 ;\n\tsetAttr \".r\" -type \"double3\" 0 89.999999999999986 0 ;\ncreateNode camera -s -n \"sideShape\" -p \"side\";\n\tsetAttr -k off \".v\" no;\n\tsetAttr \".rnd\" no;\n\tsetAttr \".coi\" 100.1;\n\tsetAttr \".ow\" 30;\n\tsetAttr \".imn\" -type \"string\" \"side\";\n\tsetAttr \".den\" -type \"string\" \"side_depth\";\n\tsetAttr \".man\" -type \"string\" \"side_mask\";\n\tsetAttr \".hc\" -type \"string\" \"viewSet -s %camera\";\n\tsetAttr \".o\" yes;\ncreateNode lightLinker -n \"lightLinker1\";\n\tsetAttr -s 9 \".lnk\";\n\tsetAttr -s 9 \".slnk\";\ncreateNode displayLayerManager -n \"layerManager\";\ncreateNode displayLayer -n \"defaultLayer\";\ncreateNode renderLayerManager -n \"renderLayerManager\";\ncreateNode renderLayer -n \"defaultRenderLayer\";\n\tsetAttr \".g\" yes;\ncreateNode script -n \"sceneConfigurationScriptNode\";\n\tsetAttr \".b\" -type \"string\" \"playbackOptions -min 1 -max 24 -ast 1 -aet 48 \";\n\tsetAttr \".st\" 6;\nselect -ne :time1;\n\tsetAttr \".o\" 1;\nselect -ne :renderPartition;\n\tsetAttr -s 2 \".st\";\nselect -ne :renderGlobalsList1;\nselect -ne :defaultShaderList1;\n\tsetAttr -s 2 \".s\";\nselect -ne :postProcessList1;\n\tsetAttr -s 2 \".p\";\nselect -ne :lightList1;\nselect -ne :initialShadingGroup;\n\tsetAttr \".ro\" yes;\nselect -ne :initialParticleSE;\n\tsetAttr \".ro\" yes;\nselect -ne :hardwareRenderGlobals;\n\tsetAttr \".ctrs\" 256;\n\tsetAttr \".btrs\" 512;\nselect -ne :defaultHardwareRenderGlobals;\n\tsetAttr \".fn\" -type \"string\" \"im\";\n\tsetAttr \".res\" -type \"string\" \"ntsc_4d 646 485 1.333\";\nselect -ne :ikSystem;\n\tsetAttr -s 4 \".sol\";\nconnectAttr \":defaultLightSet.msg\" \"lightLinker1.lnk[0].llnk\";\nconnectAttr \":initialShadingGroup.msg\" \"lightLinker1.lnk[0].olnk\";\nconnectAttr \":defaultLightSet.msg\" \"lightLinker1.lnk[1].llnk\";\nconnectAttr \":initialParticleSE.msg\" \"lightLinker1.lnk[1].olnk\";\nconnectAttr \":defaultLightSet.msg\" \"lightLinker1.slnk[0].sllk\";\nconnectAttr \":initialShadingGroup.msg\" \"lightLinker1.slnk[0].solk\";\nconnectAttr \":defaultLightSet.msg\" \"lightLinker1.slnk[1].sllk\";\nconnectAttr \":initialParticleSE.msg\" \"lightLinker1.slnk[1].solk\";\nconnectAttr \"layerManager.dli[0]\" \"defaultLayer.id\";\nconnectAttr \"renderLayerManager.rlmi[0]\" \"defaultRenderLayer.rlid\";\nconnectAttr \"lightLinker1.msg\" \":lightList1.ln\" -na;"
|
||||
);
|
||||
|
||||
Writer.WriteLineFmt(
|
||||
"createNode transform -n \"%s\";\n"
|
||||
"setAttr \".ove\" yes;",
|
||||
(char*)FileName
|
||||
);
|
||||
|
||||
uint32_t SubmeshIndex = 0;
|
||||
|
||||
for (auto& Submesh : Model.Meshes)
|
||||
{
|
||||
Writer.WriteLineFmt(
|
||||
"createNode transform -n \"KoreMesh_%08x_%02d\" -p \"%s\";\n"
|
||||
"setAttr \".rp\" -type \"double3\" 0.000000 0.000000 0.000000 ;\nsetAttr \".sp\" -type \"double3\" 0.000000 0.000000 0.000000 ;\n"
|
||||
"createNode mesh -n \"MeshShape_%d\" -p \"KoreMesh_%08x_%02d\";\n"
|
||||
"setAttr -k off \".v\";\nsetAttr \".vir\" yes;\nsetAttr \".vif\" yes;\n"
|
||||
"setAttr -s %d \".uvst\";",
|
||||
Hash, SubmeshIndex, (char*)FileName,
|
||||
SubmeshIndex, Hash, SubmeshIndex,
|
||||
Submesh.Vertices.UVLayerCount()
|
||||
);
|
||||
|
||||
for (uint8_t i = 1; i < Submesh.Vertices.UVLayerCount() + 1; i++)
|
||||
{
|
||||
if (Submesh.Vertices.Count() == 1)
|
||||
{
|
||||
Writer.WriteFmt(
|
||||
"setAttr \".uvst[%d].uvsn\" -type \"string\" \"map%d\";\n"
|
||||
"setAttr -s 1 \".uvst[0].uvsp[0]\" -type \"float2\"",
|
||||
(i - 1), i
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
Writer.WriteFmt(
|
||||
"setAttr \".uvst[%d].uvsn\" -type \"string\" \"map%d\";\n"
|
||||
"setAttr -s %d \".uvst[0].uvsp[0:%d]\" -type \"float2\"",
|
||||
(i - 1), i,
|
||||
Submesh.Vertices.Count(), (Submesh.Vertices.Count() - 1)
|
||||
);
|
||||
}
|
||||
|
||||
for (auto& Vertex : Submesh.Vertices)
|
||||
{
|
||||
auto& Layer = Vertex.UVLayers(i - 1);
|
||||
Writer.WriteFmt(" %f %f", Layer.U, (1 - Layer.V));
|
||||
}
|
||||
|
||||
Writer.Write(";\n");
|
||||
}
|
||||
|
||||
Writer.WriteFmt(
|
||||
"setAttr \".cuvs\" -type \"string\" \"map1\";\nsetAttr \".dcol\" yes;\nsetAttr \".dcc\" -type \"string\" \"Ambient+Diffuse\";\nsetAttr \".ccls\" -type \"string\" \"colorSet1\";\nsetAttr \".clst[0].clsn\" -type \"string\" \"colorSet1\";\n"
|
||||
"setAttr -s %d \".clst[0].clsp\";\n"
|
||||
"setAttr \".clst[0].clsp[0:%d]\"",
|
||||
(Submesh.Faces.Count() * 3),
|
||||
(Submesh.Faces.Count() * 3) - 1
|
||||
);
|
||||
|
||||
for (auto& Face : Submesh.Faces)
|
||||
{
|
||||
auto& Vertex1 = Submesh.Vertices[Face[2]].Color();
|
||||
auto& Vertex2 = Submesh.Vertices[Face[1]].Color();
|
||||
auto& Vertex3 = Submesh.Vertices[Face[0]].Color();
|
||||
|
||||
Writer.WriteFmt(
|
||||
" %f %f %f %f"
|
||||
" %f %f %f %f"
|
||||
" %f %f %f %f",
|
||||
Vertex1[0] / 255.f, Vertex1[1] / 255.f, Vertex1[2] / 255.f, Vertex1[3] / 255.f,
|
||||
Vertex2[0] / 255.f, Vertex2[1] / 255.f, Vertex2[2] / 255.f, Vertex2[3] / 255.f,
|
||||
Vertex3[0] / 255.f, Vertex3[1] / 255.f, Vertex3[2] / 255.f, Vertex3[3] / 255.f
|
||||
);
|
||||
}
|
||||
|
||||
Writer.WriteLineFmt(
|
||||
";\n"
|
||||
"setAttr \".covm[0]\" 0 1 1;\nsetAttr \".cdvm[0]\" 0 1 1;\nsetAttr -s %d \".vt\";",
|
||||
Submesh.Vertices.Count()
|
||||
);
|
||||
|
||||
if (Submesh.Vertices.Count() == 1)
|
||||
Writer.Write("setAttr \".vt[0]\"");
|
||||
else
|
||||
Writer.WriteFmt("setAttr \".vt[0:%d]\"", Submesh.Vertices.Count() - 1);
|
||||
|
||||
for (auto& Vertex : Submesh.Vertices)
|
||||
{
|
||||
auto& Position = Vertex.Position();
|
||||
Writer.WriteFmt(" %f %f %f", Position.X, Position.Y, Position.Z);
|
||||
}
|
||||
|
||||
Writer.WriteFmt(
|
||||
";\n"
|
||||
"setAttr -s %d \".ed\";\n"
|
||||
"setAttr \".ed[0:%d]\"",
|
||||
(Submesh.Faces.Count() * 3),
|
||||
(Submesh.Faces.Count() * 3) - 1
|
||||
);
|
||||
|
||||
for (auto& Face : Submesh.Faces)
|
||||
Writer.WriteFmt(" %d %d 0 %d %d 0 %d %d 0", Face[2], Face[1], Face[1], Face[0], Face[0], Face[2]);
|
||||
|
||||
Writer.WriteFmt(
|
||||
";\n"
|
||||
"setAttr -s %d \".n\";\n"
|
||||
"setAttr \".n[0:%d]\" -type \"float3\"",
|
||||
(Submesh.Faces.Count() * 3),
|
||||
(Submesh.Faces.Count() * 3) - 1
|
||||
);
|
||||
|
||||
for (auto& Face : Submesh.Faces)
|
||||
{
|
||||
auto& Vertex1 = Submesh.Vertices[Face[2]].Normal();
|
||||
auto& Vertex2 = Submesh.Vertices[Face[1]].Normal();
|
||||
auto& Vertex3 = Submesh.Vertices[Face[0]].Normal();
|
||||
|
||||
Writer.WriteFmt(
|
||||
" %f %f %f"
|
||||
" %f %f %f"
|
||||
" %f %f %f",
|
||||
Vertex1.X, Vertex1.Y, Vertex1.Z,
|
||||
Vertex2.X, Vertex2.Y, Vertex2.Z,
|
||||
Vertex3.X, Vertex3.Y, Vertex3.Z
|
||||
);
|
||||
}
|
||||
|
||||
Writer.WriteLine(";");
|
||||
|
||||
if (Submesh.Faces.Count() == 1)
|
||||
Writer.WriteFmt("setAttr -s %d \".fc[0]\" -type \"polyFaces\"", Submesh.Faces.Count());
|
||||
else
|
||||
Writer.WriteFmt("setAttr -s %d \".fc[0:%d]\" -type \"polyFaces\"", Submesh.Faces.Count(), Submesh.Faces.Count() - 1);
|
||||
|
||||
uint32_t FaceIndex = 0;
|
||||
|
||||
for (auto& Face : Submesh.Faces)
|
||||
{
|
||||
Writer.WriteFmt(" f 3 %d %d %d", FaceIndex, (FaceIndex + 1), (FaceIndex + 2));
|
||||
|
||||
for (uint8_t i = 0; i < Submesh.Vertices.UVLayerCount(); i++)
|
||||
Writer.WriteFmt(" mu %d 3 %d %d %d", i, Face[2], Face[1], Face[0]);
|
||||
|
||||
Writer.WriteFmt(" mc 0 3 %d %d %d", FaceIndex, (FaceIndex + 1), (FaceIndex + 2));
|
||||
|
||||
FaceIndex += 3;
|
||||
}
|
||||
|
||||
Writer.WriteLine(
|
||||
";\n"
|
||||
"setAttr \".cd\" -type \"dataPolyComponent\" Index_Data Edge 0 ;\nsetAttr \".cvd\" -type \"dataPolyComponent\" Index_Data Vertex 0 ;\nsetAttr \".hfd\" -type \"dataPolyComponent\" Index_Data Face 0 ;"
|
||||
);
|
||||
|
||||
SubmeshIndex++;
|
||||
}
|
||||
|
||||
Writer.Write("\n");
|
||||
|
||||
for (auto& Material : Model.Materials)
|
||||
{
|
||||
auto MaterialName = (char*)Material.Name;
|
||||
|
||||
Writer.WriteLineFmt(
|
||||
"createNode shadingEngine -n \"%sSG\";\n"
|
||||
"setAttr \".ihi\" 0;\n"
|
||||
"setAttr \".ro\" yes;\n"
|
||||
"createNode materialInfo -n \"%sMI\";\r\ncreateNode lambert -n \"%s\";\n"
|
||||
"createNode place2dTexture -n \"%sP2DT\";",
|
||||
MaterialName,
|
||||
MaterialName, MaterialName,
|
||||
MaterialName
|
||||
);
|
||||
|
||||
auto DiffuseTexture = (Material.Slots.ContainsKey(MaterialSlotType::Albedo))
|
||||
? MaterialSlotType::Albedo : (Material.Slots.ContainsKey(MaterialSlotType::Diffuse) ? MaterialSlotType::Diffuse : MaterialSlotType::Invalid);
|
||||
|
||||
if (DiffuseTexture != MaterialSlotType::Invalid)
|
||||
{
|
||||
Writer.WriteLineFmt(
|
||||
"createNode file -n \"%sFILE\";\n"
|
||||
"setAttr \".ftn\" -type \"string\" \"%s\";",
|
||||
MaterialName,
|
||||
(char*)string(Material.Slots[DiffuseTexture].first).Replace("\\", "\\\\")
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t LightConnectionIndex = 2;
|
||||
|
||||
for (auto& Material : Model.Materials)
|
||||
{
|
||||
auto MaterialName = (char*)Material.Name;
|
||||
|
||||
Writer.WriteLineFmt(
|
||||
"connectAttr \":defaultLightSet.msg\" \"lightLinker1.lnk[%d].llnk\";\n"
|
||||
"connectAttr \"%sSG.msg\" \"lightLinker1.lnk[%d].olnk\";\n"
|
||||
"connectAttr \":defaultLightSet.msg\" \"lightLinker1.slnk[%d].sllk\";\n"
|
||||
"connectAttr \"%sSG.msg\" \"lightLinker1.slnk[%d].solk\";\n"
|
||||
"connectAttr \"%s.oc\" \"%sSG.ss\";\n"
|
||||
"connectAttr \"%sSG.msg\" \"%sMI.sg\";\n"
|
||||
"connectAttr \"%s.msg\" \"%sMI.m\";",
|
||||
LightConnectionIndex,
|
||||
MaterialName, LightConnectionIndex,
|
||||
LightConnectionIndex,
|
||||
MaterialName, LightConnectionIndex,
|
||||
MaterialName, MaterialName,
|
||||
MaterialName, MaterialName,
|
||||
MaterialName, MaterialName
|
||||
);
|
||||
|
||||
auto DiffuseTexture = (Material.Slots.ContainsKey(MaterialSlotType::Albedo))
|
||||
? MaterialSlotType::Albedo : (Material.Slots.ContainsKey(MaterialSlotType::Diffuse) ? MaterialSlotType::Diffuse : MaterialSlotType::Invalid);
|
||||
|
||||
if (DiffuseTexture != MaterialSlotType::Invalid)
|
||||
{
|
||||
Writer.WriteLineFmt(
|
||||
"connectAttr \"%sFILE.msg\" \"%sMI.t\" -na;\n"
|
||||
"connectAttr \"%sFILE.oc\" \"%s.c\";\n"
|
||||
"connectAttr \"%sP2DT.c\" \"%sFILE.c\";\n"
|
||||
"connectAttr \"%sP2DT.tf\" \"%sFILE.tf\";\n"
|
||||
"connectAttr \"%sP2DT.rf\" \"%sFILE.rf\";\n"
|
||||
"connectAttr \"%sP2DT.mu\" \"%sFILE.mu\";\n"
|
||||
"connectAttr \"%sP2DT.mv\" \"%sFILE.mv\";\n"
|
||||
"connectAttr \"%sP2DT.s\" \"%sFILE.s\";\n"
|
||||
"connectAttr \"%sP2DT.wu\" \"%sFILE.wu\";\n"
|
||||
"connectAttr \"%sP2DT.wv\" \"%sFILE.wv\";\n"
|
||||
"connectAttr \"%sP2DT.re\" \"%sFILE.re\";\n"
|
||||
"connectAttr \"%sP2DT.of\" \"%sFILE.of\";\n"
|
||||
"connectAttr \"%sP2DT.r\" \"%sFILE.ro\";\n"
|
||||
"connectAttr \"%sP2DT.n\" \"%sFILE.n\";\n"
|
||||
"connectAttr \"%sP2DT.vt1\" \"%sFILE.vt1\";\n"
|
||||
"connectAttr \"%sP2DT.vt2\" \"%sFILE.vt2\";\n"
|
||||
"connectAttr \"%sP2DT.vt3\" \"%sFILE.vt3\";\n"
|
||||
"connectAttr \"%sP2DT.vc1\" \"%sFILE.vc1\";\n"
|
||||
"connectAttr \"%sP2DT.o\" \"%sFILE.uv\";\n"
|
||||
"connectAttr \"%sP2DT.ofs\" \"%sFILE.fs\";\n",
|
||||
MaterialName, MaterialName,
|
||||
MaterialName, MaterialName,
|
||||
MaterialName, MaterialName,
|
||||
MaterialName, MaterialName,
|
||||
MaterialName, MaterialName,
|
||||
MaterialName, MaterialName,
|
||||
MaterialName, MaterialName,
|
||||
MaterialName, MaterialName,
|
||||
MaterialName, MaterialName,
|
||||
MaterialName, MaterialName,
|
||||
MaterialName, MaterialName,
|
||||
MaterialName, MaterialName,
|
||||
MaterialName, MaterialName,
|
||||
MaterialName, MaterialName,
|
||||
MaterialName, MaterialName,
|
||||
MaterialName, MaterialName,
|
||||
MaterialName, MaterialName,
|
||||
MaterialName, MaterialName,
|
||||
MaterialName, MaterialName,
|
||||
MaterialName, MaterialName
|
||||
);
|
||||
}
|
||||
|
||||
Writer.WriteLineFmt(
|
||||
"connectAttr \"%sSG.pa\" \":renderPartition.st\" -na;\n"
|
||||
"connectAttr \"%s.msg\" \":defaultShaderList1.s\" -na;\n"
|
||||
"connectAttr \"%sP2DT.msg\" \":defaultRenderUtilityList1.u\" -na;\n"
|
||||
"connectAttr \"%sFILE.msg\" \":defaultTextureList1.tx\" -na;\n",
|
||||
MaterialName,
|
||||
MaterialName,
|
||||
MaterialName,
|
||||
MaterialName
|
||||
);
|
||||
|
||||
LightConnectionIndex++;
|
||||
}
|
||||
|
||||
SubmeshIndex = 0;
|
||||
|
||||
for (auto& Submesh : Model.Meshes)
|
||||
{
|
||||
Writer.WriteLineFmt(
|
||||
"setAttr -s %d \"MeshShape_%d.iog\";",
|
||||
Submesh.Vertices.UVLayerCount(), SubmeshIndex
|
||||
);
|
||||
|
||||
for (uint8_t i = 0; i < Submesh.Vertices.UVLayerCount(); i++)
|
||||
{
|
||||
if (Submesh.MaterialIndices[i] < 0)
|
||||
continue;
|
||||
|
||||
Writer.WriteLineFmt(
|
||||
"connectAttr \"MeshShape_%d.iog[%d]\" \"%sSG.dsm\" -na;",
|
||||
SubmeshIndex, i, (char*)Model.Materials[Submesh.MaterialIndices[i]].Name
|
||||
);
|
||||
}
|
||||
|
||||
SubmeshIndex++;
|
||||
}
|
||||
|
||||
Writer.WriteLine(
|
||||
"createNode transform -n \"Joints\";\nsetAttr \".ove\" yes;\n"
|
||||
);
|
||||
|
||||
for (auto& Bone : Model.Bones)
|
||||
{
|
||||
if (Bone.Parent() == -1)
|
||||
Writer.WriteLineFmt("createNode joint -n \"%s\" -p \"Joints\";", (char*)Bone.Name());
|
||||
else
|
||||
Writer.WriteLineFmt("createNode joint -n \"%s\" -p \"%s\";", (char*)Bone.Name(), (char*)Model.Bones[Bone.Parent()].Name());
|
||||
|
||||
if (Bone.GetFlag(BoneFlags::HasLocalSpaceMatrices))
|
||||
{
|
||||
auto Rotation = Bone.LocalRotation().ToEulerAngles();
|
||||
|
||||
auto& Position = Bone.LocalPosition();
|
||||
auto& Scale = Bone.Scale();
|
||||
|
||||
Writer.WriteLineFmt(
|
||||
"addAttr -ci true -sn \"liw\" -ln \"lockInfluenceWeights\" -bt \"lock\" -min 0 -max 1 -at \"bool\";\n"
|
||||
"setAttr \".uoc\" yes;\n"
|
||||
"setAttr \".ove\" yes;\n"
|
||||
"setAttr \".t\" -type \"double3\" %f %f %f ;\n"
|
||||
"setAttr \".mnrl\" -type \"double3\" -360 -360 -360 ;\n"
|
||||
"setAttr \".mxrl\" -type \"double3\" 360 360 360 ;\n"
|
||||
"setAttr \".radi\" 0.50;\n"
|
||||
"setAttr \".jo\" -type \"double3\" %f %f %f;\n"
|
||||
"setAttr \".scale\" -type \"double3\" %f %f %f;\n",
|
||||
Position.X, Position.Y, Position.Z,
|
||||
Rotation.X, Rotation.Y, Rotation.Z,
|
||||
Scale.X, Scale.Y, Scale.Z
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
auto Rotation = Bone.GlobalRotation().ToEulerAngles();
|
||||
|
||||
auto& Position = Bone.GlobalPosition();
|
||||
auto& Scale = Bone.Scale();
|
||||
|
||||
Writer.WriteLineFmt(
|
||||
"addAttr -ci true -sn \"liw\" -ln \"lockInfluenceWeights\" -bt \"lock\" -min 0 -max 1 -at \"bool\";\n"
|
||||
"setAttr \".uoc\" yes;\n"
|
||||
"setAttr \".ove\" yes;\n"
|
||||
"setAttr \".it\" no;\n"
|
||||
"setAttr \".t\" -type \"double3\" %f %f %f ;\n"
|
||||
"setAttr \".mnrl\" -type \"double3\" -360 -360 -360 ;\n"
|
||||
"setAttr \".mxrl\" -type \"double3\" 360 360 360 ;\n"
|
||||
"setAttr \".radi\" 0.50;\n"
|
||||
"setAttr \".jo\" -type \"double3\" %f %f %f;\n"
|
||||
"setAttr \".scale\" -type \"double3\" %f %f %f;\n",
|
||||
Position.X, Position.Y, Position.Z,
|
||||
Rotation.X, Rotation.Y, Rotation.Z,
|
||||
Scale.X, Scale.Y, Scale.Z
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
auto Binder = IO::StreamWriter(IO::File::Create(IO::Path::Combine(IO::Path::GetDirectoryName(Path), FileName + "_BIND.mel")));
|
||||
|
||||
Binder.WriteLine(
|
||||
"/*\n* Autodesk Maya Bind Script\n*/\n"
|
||||
);
|
||||
|
||||
SubmeshIndex = 0;
|
||||
|
||||
for (auto& Submesh : Model.Meshes)
|
||||
{
|
||||
Binder.WriteLineFmt(
|
||||
"global proc KoreMesh_%08x_%02d_BindFunc()\n{\n"
|
||||
" select -r KoreMesh_%08x_%02d;",
|
||||
Hash, SubmeshIndex,
|
||||
Hash, SubmeshIndex
|
||||
);
|
||||
|
||||
auto MaximumInfluence = Submesh.Vertices.WeightCount();
|
||||
|
||||
uint32_t BoneMapIndex = 0;
|
||||
Dictionary<uint32_t, uint8_t> BoneMap;
|
||||
Dictionary<uint32_t, uint32_t> ReverseBoneMap;
|
||||
List<string> BoneNames;
|
||||
|
||||
for (auto& Vertex : Submesh.Vertices)
|
||||
{
|
||||
for (uint8_t i = 0; i < Vertex.WeightCount(); i++)
|
||||
{
|
||||
auto& Weight = Vertex.Weights(i);
|
||||
|
||||
if (BoneMap.Add(Weight.Bone, 0))
|
||||
{
|
||||
BoneNames.Add(Model.Bones[Weight.Bone].Name());
|
||||
ReverseBoneMap.Add(BoneMapIndex, Weight.Bone);
|
||||
BoneMapIndex++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (auto& BoneName : BoneNames)
|
||||
Binder.WriteLineFmt(" select -add %s;", (char*)BoneName);
|
||||
|
||||
Binder.WriteLineFmt(
|
||||
" newSkinCluster \"-toSelectedBones -mi %d -omi true -dr 5.0 -rui false\";\n"
|
||||
" string $clu = findRelatedSkinCluster(\"KoreMesh_%08x_%02d\");",
|
||||
MaximumInfluence,
|
||||
Hash, SubmeshIndex
|
||||
);
|
||||
|
||||
// If we are a complex skin, we need a weight matrix
|
||||
if (BoneNames.Count() > 1)
|
||||
{
|
||||
Binder.WriteFmt(" int $NV = %d;\n matrix $WM[%d][%d] = <<", Submesh.Vertices.Count(), Submesh.Vertices.Count(), BoneNames.Count());
|
||||
|
||||
for (uint32_t i = 0; i < Submesh.Vertices.Count(); i++)
|
||||
{
|
||||
auto Vertex = Submesh.Vertices[i];
|
||||
|
||||
if (i != 0)
|
||||
Binder.Write(";");
|
||||
|
||||
for (uint32_t b = 0; b < BoneNames.Count(); b++)
|
||||
{
|
||||
if (b != 0)
|
||||
Binder.Write(",");
|
||||
|
||||
float WeightValue = 0.0f;
|
||||
|
||||
for (uint8_t w = 0; w < Vertex.WeightCount(); w++)
|
||||
{
|
||||
if (Vertex.Weights(w).Bone == ReverseBoneMap[b])
|
||||
{
|
||||
WeightValue = Vertex.Weights(w).Value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (WeightValue == 0.0f || WeightValue == 1.0f)
|
||||
Binder.WriteFmt("%d", (uint32_t)WeightValue);
|
||||
else
|
||||
Binder.WriteFmt("%f", WeightValue);
|
||||
}
|
||||
}
|
||||
|
||||
Binder.WriteLine(">>;");
|
||||
Binder.Write(" for ($i = 0; $i < $NV; $i++) {");
|
||||
|
||||
Binder.WriteFmt(" setAttr($clu + \".weightList[\" + $i + \"].weights[0:%d]\")", BoneNames.Count() - 1);
|
||||
|
||||
for (uint32_t i = 0; i < BoneNames.Count(); i++)
|
||||
Binder.WriteFmt(" $WM[$i][%d]", i);
|
||||
|
||||
Binder.WriteLine("; }");
|
||||
}
|
||||
|
||||
Binder.WriteLine("}\n");
|
||||
SubmeshIndex++;
|
||||
}
|
||||
|
||||
Binder.WriteLine("global proc RunAdvancedScript()\n{");
|
||||
|
||||
SubmeshIndex = 0;
|
||||
|
||||
for (auto& Submesh : Model.Meshes)
|
||||
Binder.WriteLineFmt(" catch(KoreMesh_%08x_%02d_BindFunc());", Hash, SubmeshIndex++);
|
||||
|
||||
Binder.WriteLine("}\n\nglobal proc NamespacePurge()\n{\n string $allNodes[] = `ls`;\n for($node in $allNodes) {\n string $buffer[];\n tokenize $node \":\" $buffer;\n string $newName = $buffer[size($buffer)-1];\n catchQuiet(`rename $node $newName`);\n }\n}\n\nprint(\"Currently binding the current model, please wait...\\n\");\nNamespacePurge();\nRunAdvancedScript();\nprint(\"The model has been binded.\\n\");\n");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
imstring AutodeskMaya::ModelExtension()
|
||||
{
|
||||
return ".ma";
|
||||
}
|
||||
|
||||
imstring AutodeskMaya::AnimationExtension()
|
||||
{
|
||||
return ".anim";
|
||||
}
|
||||
|
||||
ExporterScale AutodeskMaya::ExportScale()
|
||||
{
|
||||
return ExporterScale::CM;
|
||||
}
|
||||
|
||||
bool AutodeskMaya::SupportsAnimations()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool AutodeskMaya::SupportsModels()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
33
r5dev/thirdparty/cppnet/cppkore/AutodeskMaya.h
vendored
Normal file
33
r5dev/thirdparty/cppnet/cppkore/AutodeskMaya.h
vendored
Normal file
@ -0,0 +1,33 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include "Exporter.h"
|
||||
|
||||
namespace Assets::Exporters
|
||||
{
|
||||
// The Autodesk Maya exporter
|
||||
class AutodeskMaya : public Exporter
|
||||
{
|
||||
public:
|
||||
AutodeskMaya() = default;
|
||||
~AutodeskMaya() = default;
|
||||
|
||||
// Exports the given animation to the provided path.
|
||||
virtual bool ExportAnimation(const Animation& Animation, const string& Path);
|
||||
// Exports the given model to the provided path.
|
||||
virtual bool ExportModel(const Model& Model, const string& Path);
|
||||
|
||||
// Gets the file extension for this exporters model format.
|
||||
virtual imstring ModelExtension();
|
||||
// Gets the file extension for this exporters animation format.
|
||||
virtual imstring AnimationExtension();
|
||||
|
||||
// Gets the required scaling constant for this exporter.
|
||||
virtual ExporterScale ExportScale();
|
||||
|
||||
// Gets whether or not the exporter supports animation exporting.
|
||||
virtual bool SupportsAnimations();
|
||||
// Gets whether or not the exporter supports model exporting.
|
||||
virtual bool SupportsModels();
|
||||
};
|
||||
}
|
251
r5dev/thirdparty/cppnet/cppkore/BinaryReader.cpp
vendored
Normal file
251
r5dev/thirdparty/cppnet/cppkore/BinaryReader.cpp
vendored
Normal file
@ -0,0 +1,251 @@
|
||||
#include "stdafx.h"
|
||||
#include "BinaryReader.h"
|
||||
#include "Pattern.h"
|
||||
|
||||
namespace IO
|
||||
{
|
||||
BinaryReader::BinaryReader()
|
||||
: BinaryReader(nullptr, false)
|
||||
{
|
||||
}
|
||||
|
||||
BinaryReader::BinaryReader(std::unique_ptr<Stream> Stream)
|
||||
: BinaryReader(std::move(Stream), false)
|
||||
{
|
||||
}
|
||||
|
||||
BinaryReader::BinaryReader(std::unique_ptr<Stream> Stream, bool LeaveOpen)
|
||||
{
|
||||
this->BaseStream = std::move(Stream);
|
||||
this->_LeaveOpen = LeaveOpen;
|
||||
}
|
||||
|
||||
BinaryReader::BinaryReader(Stream* Stream)
|
||||
: BinaryReader(Stream, false)
|
||||
{
|
||||
}
|
||||
|
||||
BinaryReader::BinaryReader(Stream* Stream, bool LeaveOpen)
|
||||
{
|
||||
this->BaseStream.reset(Stream);
|
||||
this->_LeaveOpen = LeaveOpen;
|
||||
}
|
||||
|
||||
BinaryReader::~BinaryReader()
|
||||
{
|
||||
this->Close();
|
||||
}
|
||||
|
||||
std::unique_ptr<uint8_t[]> BinaryReader::Read(uint64_t Count, uint64_t& Result)
|
||||
{
|
||||
auto Buffer = std::make_unique<uint8_t[]>(Count);
|
||||
|
||||
Result = Read(Buffer.get(), 0, Count);
|
||||
|
||||
return Buffer;
|
||||
}
|
||||
|
||||
uint64_t BinaryReader::Read(uint8_t* Buffer, uint64_t Index, uint64_t Count)
|
||||
{
|
||||
if (!this->BaseStream)
|
||||
IOError::StreamBaseStream();
|
||||
|
||||
return this->BaseStream->Read(Buffer, Index, Count);
|
||||
}
|
||||
|
||||
uint64_t BinaryReader::Read(void* Buffer, uint64_t Index, uint64_t Count)
|
||||
{
|
||||
if (!this->BaseStream)
|
||||
IOError::StreamBaseStream();
|
||||
|
||||
return this->BaseStream->Read((uint8_t*)Buffer, Index, Count);
|
||||
}
|
||||
|
||||
string BinaryReader::ReadCString()
|
||||
{
|
||||
if (!this->BaseStream)
|
||||
IOError::StreamBaseStream();
|
||||
|
||||
string Buffer = "";
|
||||
|
||||
char Cur = this->Read<char>();
|
||||
while ((uint8_t)Cur > 0)
|
||||
{
|
||||
Buffer += Cur;
|
||||
Cur = this->Read<char>();
|
||||
}
|
||||
|
||||
return std::move(Buffer);
|
||||
}
|
||||
|
||||
wstring BinaryReader::ReadWCString()
|
||||
{
|
||||
if (!this->BaseStream)
|
||||
IOError::StreamBaseStream();
|
||||
|
||||
wstring Buffer = L"";
|
||||
|
||||
wchar_t Cur = this->Read<wchar_t>();
|
||||
while (Cur != (wchar_t)'\0')
|
||||
{
|
||||
Buffer += Cur;
|
||||
Cur = this->Read<wchar_t>();
|
||||
}
|
||||
|
||||
return std::move(Buffer);
|
||||
}
|
||||
|
||||
string BinaryReader::ReadSizeString(uint64_t Size)
|
||||
{
|
||||
if (!this->BaseStream)
|
||||
IOError::StreamBaseStream();
|
||||
|
||||
auto Buffer = string((uint32_t)Size, '\0');
|
||||
this->BaseStream->Read((uint8_t*)&Buffer[0], 0, Size);
|
||||
|
||||
return std::move(Buffer);
|
||||
}
|
||||
|
||||
string BinaryReader::ReadNetString()
|
||||
{
|
||||
if (!this->BaseStream)
|
||||
IOError::StreamBaseStream();
|
||||
|
||||
auto Buffer = string(this->ReadVarInt(), '\0');
|
||||
this->BaseStream->Read((uint8_t*)&Buffer[0], 0, (uint64_t)Buffer.Length());
|
||||
|
||||
return std::move(Buffer);
|
||||
}
|
||||
|
||||
uint32_t BinaryReader::ReadVarInt()
|
||||
{
|
||||
uint32_t Count = 0, Shift = 0;
|
||||
uint8_t Byte;
|
||||
|
||||
do
|
||||
{
|
||||
if (Shift == 5 * 7)
|
||||
return 0;
|
||||
|
||||
Byte = this->Read<uint8_t>();
|
||||
Count |= (Byte & 0x7F) << Shift;
|
||||
Shift += 7;
|
||||
} while ((Byte & 0x80) != 0);
|
||||
|
||||
return Count;
|
||||
}
|
||||
|
||||
int64_t BinaryReader::SignatureScan(const string& Signature)
|
||||
{
|
||||
if (!this->BaseStream)
|
||||
IOError::StreamBaseStream();
|
||||
|
||||
auto Sig = Data::Pattern(Signature);
|
||||
auto Position = this->BaseStream->GetPosition();
|
||||
auto Length = this->BaseStream->GetLength();
|
||||
auto ChunkSize = (0x5F5E100 + (0x5F5E100 % Sig.DataSize()));
|
||||
|
||||
uint64_t SearchResult = -1, ReadResult = 0, DataRead = 0;
|
||||
|
||||
while (true)
|
||||
{
|
||||
auto StartPosition = this->BaseStream->GetPosition();
|
||||
auto Buffer = this->Read(ChunkSize, ReadResult);
|
||||
|
||||
auto ChunkResult = Sig.Search(Buffer.get(), 0, ReadResult);
|
||||
if (ChunkResult > -1)
|
||||
{
|
||||
return (DataRead + ChunkResult + StartPosition);
|
||||
}
|
||||
DataRead += ReadResult;
|
||||
|
||||
if (ReadResult < ChunkSize)
|
||||
break;
|
||||
}
|
||||
|
||||
return SearchResult;
|
||||
}
|
||||
|
||||
int64_t BinaryReader::SignatureScan(const string& Signature, uint64_t Offset, uint64_t Count)
|
||||
{
|
||||
if (!this->BaseStream)
|
||||
IOError::StreamBaseStream();
|
||||
|
||||
uint64_t ReadResult = 0;
|
||||
auto Sig = Data::Pattern(Signature);
|
||||
this->BaseStream->SetPosition(Offset);
|
||||
auto Buffer = this->Read(Count, ReadResult);
|
||||
|
||||
auto SearchResult = Sig.Search(Buffer.get(), 0, ReadResult);
|
||||
|
||||
if (SearchResult > -1)
|
||||
return (SearchResult + Offset);
|
||||
|
||||
return SearchResult;
|
||||
}
|
||||
|
||||
List<int64_t> BinaryReader::SignatureScanAll(const string & Signature)
|
||||
{
|
||||
if (!this->BaseStream)
|
||||
IOError::StreamBaseStream();
|
||||
|
||||
auto ResultList = List<int64_t>();
|
||||
|
||||
auto Sig = Data::Pattern(Signature);
|
||||
auto Position = this->BaseStream->GetPosition();
|
||||
auto Length = this->BaseStream->GetLength();
|
||||
auto ChunkSize = (0x5F5E100 + (0x5F5E100 % Sig.DataSize()));
|
||||
|
||||
uint64_t SearchResult = -1, ReadResult = 0, DataRead = 0;
|
||||
|
||||
while (true)
|
||||
{
|
||||
auto StartPosition = this->BaseStream->GetPosition();
|
||||
auto Buffer = this->Read(ChunkSize, ReadResult);
|
||||
|
||||
auto ChunkResult = Sig.SearchAll(Buffer.get(), 0, ReadResult);
|
||||
|
||||
for (auto& Result : ChunkResult)
|
||||
ResultList.EmplaceBack(Result + DataRead + StartPosition);
|
||||
|
||||
DataRead += ReadResult;
|
||||
|
||||
if (ReadResult < ChunkSize)
|
||||
break;
|
||||
}
|
||||
|
||||
return ResultList;
|
||||
}
|
||||
|
||||
List<int64_t> BinaryReader::SignatureScanAll(const string & Signature, uint64_t Offset, uint64_t Count)
|
||||
{
|
||||
if (!this->BaseStream)
|
||||
IOError::StreamBaseStream();
|
||||
|
||||
uint64_t ReadResult = 0;
|
||||
auto Sig = Data::Pattern(Signature);
|
||||
this->BaseStream->SetPosition(Offset);
|
||||
auto Buffer = this->Read(Count, ReadResult);
|
||||
|
||||
auto ResultList = Sig.SearchAll(Buffer.get(), 0, ReadResult);
|
||||
|
||||
for (auto& Result : ResultList)
|
||||
Result += Offset;
|
||||
|
||||
return ResultList;
|
||||
}
|
||||
|
||||
Stream* BinaryReader::GetBaseStream() const
|
||||
{
|
||||
return this->BaseStream.get();
|
||||
}
|
||||
|
||||
void BinaryReader::Close()
|
||||
{
|
||||
// Forcefully reset the stream
|
||||
if (this->_LeaveOpen)
|
||||
this->BaseStream.release();
|
||||
else
|
||||
this->BaseStream.reset();
|
||||
}
|
||||
}
|
72
r5dev/thirdparty/cppnet/cppkore/BinaryReader.h
vendored
Normal file
72
r5dev/thirdparty/cppnet/cppkore/BinaryReader.h
vendored
Normal file
@ -0,0 +1,72 @@
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include "Stream.h"
|
||||
#include "ListBase.h"
|
||||
#include "StringBase.h"
|
||||
|
||||
namespace IO
|
||||
{
|
||||
// BinaryReader supports reading binary data streams
|
||||
class BinaryReader
|
||||
{
|
||||
public:
|
||||
BinaryReader();
|
||||
BinaryReader(std::unique_ptr<Stream> Stream);
|
||||
BinaryReader(std::unique_ptr<Stream> Stream, bool LeaveOpen);
|
||||
BinaryReader(Stream* Stream);
|
||||
BinaryReader(Stream* Stream, bool LeaveOpen);
|
||||
~BinaryReader();
|
||||
|
||||
template <class T>
|
||||
// Reads data of type T from the stream
|
||||
T Read() const
|
||||
{
|
||||
if (!this->BaseStream)
|
||||
IOError::StreamBaseStream();
|
||||
|
||||
T ResultValue{};
|
||||
this->BaseStream->Read((uint8_t*)&ResultValue, 0, sizeof(T));
|
||||
|
||||
return ResultValue;
|
||||
}
|
||||
|
||||
// Reads data from the stream
|
||||
std::unique_ptr<uint8_t[]> Read(uint64_t Count, uint64_t& Result);
|
||||
// Reads data from the stream to the specified buffer
|
||||
uint64_t Read(uint8_t* Buffer, uint64_t Index, uint64_t Count);
|
||||
// Reads data from the stream to the specified buffer
|
||||
uint64_t Read(void* Buffer, uint64_t Index, uint64_t Count);
|
||||
|
||||
// Reads a null-terminated string from the stream
|
||||
string ReadCString();
|
||||
// Reads a wide null-terminated string from the stream
|
||||
wstring ReadWCString();
|
||||
// Reads a size-string from the stream
|
||||
string ReadSizeString(uint64_t Size);
|
||||
// Reads a .NET string from the stream
|
||||
string ReadNetString();
|
||||
|
||||
// Reads an integer encoded into 7 bits, top bit = read more
|
||||
uint32_t ReadVarInt();
|
||||
|
||||
// Scan the stream for a given signature
|
||||
int64_t SignatureScan(const string& Signature);
|
||||
// Scan the stream for a given signature
|
||||
int64_t SignatureScan(const string& Signature, uint64_t Offset, uint64_t Count);
|
||||
|
||||
// Scan the process for a given signature (All occurences)
|
||||
List<int64_t> SignatureScanAll(const string& Signature);
|
||||
// Scan the process for a given signature (All occurences)
|
||||
List<int64_t> SignatureScanAll(const string& Signature, uint64_t Offset, uint64_t Count);
|
||||
|
||||
// Get the underlying stream
|
||||
Stream* GetBaseStream() const;
|
||||
// Close the BinaryReader and underlying stream
|
||||
void Close();
|
||||
|
||||
private:
|
||||
std::unique_ptr<Stream> BaseStream;
|
||||
bool _LeaveOpen;
|
||||
};
|
||||
}
|
145
r5dev/thirdparty/cppnet/cppkore/BinaryWriter.cpp
vendored
Normal file
145
r5dev/thirdparty/cppnet/cppkore/BinaryWriter.cpp
vendored
Normal file
@ -0,0 +1,145 @@
|
||||
#include "stdafx.h"
|
||||
#include "BinaryWriter.h"
|
||||
|
||||
namespace IO
|
||||
{
|
||||
BinaryWriter::BinaryWriter()
|
||||
: BinaryWriter(nullptr, false)
|
||||
{
|
||||
}
|
||||
|
||||
BinaryWriter::BinaryWriter(std::unique_ptr<Stream> Stream)
|
||||
: BinaryWriter(std::move(Stream), false)
|
||||
{
|
||||
}
|
||||
|
||||
BinaryWriter::BinaryWriter(std::unique_ptr<Stream> Stream, bool LeaveOpen)
|
||||
{
|
||||
this->BaseStream = std::move(Stream);
|
||||
this->_LeaveOpen = LeaveOpen;
|
||||
}
|
||||
|
||||
BinaryWriter::BinaryWriter(Stream* Stream)
|
||||
: BinaryWriter(Stream, false)
|
||||
{
|
||||
}
|
||||
|
||||
BinaryWriter::BinaryWriter(Stream * Stream, bool LeaveOpen)
|
||||
{
|
||||
this->BaseStream.reset(Stream);
|
||||
this->_LeaveOpen = LeaveOpen;
|
||||
}
|
||||
|
||||
BinaryWriter::~BinaryWriter()
|
||||
{
|
||||
this->Close();
|
||||
}
|
||||
|
||||
void BinaryWriter::Write(std::unique_ptr<uint8_t[]>& Buffer, uint64_t Count)
|
||||
{
|
||||
this->Write(Buffer.get(), 0, Count);
|
||||
}
|
||||
|
||||
void BinaryWriter::Write(uint8_t* Buffer, uint64_t Index, uint64_t Count)
|
||||
{
|
||||
if (!this->BaseStream)
|
||||
IOError::StreamBaseStream();
|
||||
|
||||
this->BaseStream->Write(Buffer, Index, Count);
|
||||
}
|
||||
|
||||
void BinaryWriter::Write(void* Buffer, uint64_t Index, uint64_t Count)
|
||||
{
|
||||
if (!this->BaseStream)
|
||||
IOError::StreamBaseStream();
|
||||
|
||||
this->BaseStream->Write((uint8_t*)Buffer, Index, Count);
|
||||
}
|
||||
|
||||
void BinaryWriter::WriteCString(const string& Value)
|
||||
{
|
||||
if (!this->BaseStream)
|
||||
IOError::StreamBaseStream();
|
||||
|
||||
uint8_t NullBuffer = 0x0;
|
||||
auto ValueLength = Value.Length();
|
||||
|
||||
this->BaseStream->Write((uint8_t*)Value.begin(), 0, ValueLength);
|
||||
|
||||
if (ValueLength == 0 || Value[ValueLength - 1] != '\0')
|
||||
this->BaseStream->Write(&NullBuffer, 0, 1);
|
||||
}
|
||||
|
||||
void BinaryWriter::WriteWCString(const wstring& Value)
|
||||
{
|
||||
if (!this->BaseStream)
|
||||
IOError::StreamBaseStream();
|
||||
|
||||
uint16_t NullBuffer = 0x0;
|
||||
auto ValueLength = Value.Length();
|
||||
|
||||
this->BaseStream->Write((uint8_t*)Value.begin(), 0, ValueLength * sizeof(wchar_t));
|
||||
|
||||
if (ValueLength == 0 || Value[ValueLength - 1] != (wchar_t)'\0')
|
||||
this->BaseStream->Write((uint8_t*)&NullBuffer, 0, sizeof(uint16_t));
|
||||
}
|
||||
|
||||
void BinaryWriter::WriteSizeString(const string& Value)
|
||||
{
|
||||
if (!this->BaseStream)
|
||||
IOError::StreamBaseStream();
|
||||
|
||||
this->BaseStream->Write((uint8_t*)Value.begin(), 0, Value.Length());
|
||||
}
|
||||
|
||||
void BinaryWriter::WriteNetString(const string& Value)
|
||||
{
|
||||
if (!this->BaseStream)
|
||||
IOError::StreamBaseStream();
|
||||
|
||||
auto ValueSize = (uint32_t)Value.Length();
|
||||
this->WriteVarInt(ValueSize);
|
||||
|
||||
this->BaseStream->Write((uint8_t*)Value.begin(), 0, ValueSize);
|
||||
}
|
||||
|
||||
void BinaryWriter::WriteVarInt(uint32_t Value)
|
||||
{
|
||||
// Write out 7 bits per byte, highest bit = keep reading
|
||||
while (Value >= 0x80)
|
||||
{
|
||||
this->Write<uint8_t>((uint8_t)(Value | 0x80));
|
||||
Value >>= 7;
|
||||
}
|
||||
|
||||
this->Write<uint8_t>((uint8_t)Value);
|
||||
}
|
||||
|
||||
void BinaryWriter::Pad(uint64_t Count)
|
||||
{
|
||||
char Padding[0x1000]{};
|
||||
|
||||
while (Count > 0)
|
||||
{
|
||||
auto Want = (Count > 0x1000) ? 0x1000 : Count;
|
||||
|
||||
Write(Padding, 0, Want);
|
||||
|
||||
Count -= Want;
|
||||
}
|
||||
}
|
||||
|
||||
Stream* BinaryWriter::GetBaseStream() const
|
||||
{
|
||||
return this->BaseStream.get();
|
||||
}
|
||||
|
||||
void BinaryWriter::Close()
|
||||
{
|
||||
// Forcefully reset the stream
|
||||
if (this->_LeaveOpen)
|
||||
this->BaseStream.release();
|
||||
else
|
||||
this->BaseStream.reset();
|
||||
}
|
||||
}
|
61
r5dev/thirdparty/cppnet/cppkore/BinaryWriter.h
vendored
Normal file
61
r5dev/thirdparty/cppnet/cppkore/BinaryWriter.h
vendored
Normal file
@ -0,0 +1,61 @@
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include "Stream.h"
|
||||
#include "StringBase.h"
|
||||
|
||||
namespace IO
|
||||
{
|
||||
// BinaryWriter supports writing to binary data streams
|
||||
class BinaryWriter
|
||||
{
|
||||
public:
|
||||
BinaryWriter();
|
||||
BinaryWriter(std::unique_ptr<Stream> Stream);
|
||||
BinaryWriter(std::unique_ptr<Stream> Stream, bool LeaveOpen);
|
||||
BinaryWriter(Stream* Stream);
|
||||
BinaryWriter(Stream* Stream, bool LeaveOpen);
|
||||
~BinaryWriter();
|
||||
|
||||
template<class T>
|
||||
// Writes data of type T to the stream
|
||||
void Write(T Value)
|
||||
{
|
||||
if (!this->BaseStream)
|
||||
IOError::StreamBaseStream();
|
||||
|
||||
this->BaseStream->Write((uint8_t*)&Value, 0, sizeof(T));
|
||||
}
|
||||
|
||||
// Writes data to the stream
|
||||
void Write(std::unique_ptr<uint8_t[]>& Buffer, uint64_t Count);
|
||||
// Writes data to the stream to the specified buffer
|
||||
void Write(uint8_t* Buffer, uint64_t Index, uint64_t Count);
|
||||
// Writes data to the stream to the specified buffer
|
||||
void Write(void* Buffer, uint64_t Index, uint64_t Count);
|
||||
|
||||
// Writes a null-terminated string to the stream
|
||||
void WriteCString(const string& Value);
|
||||
// Writes a wide null-terminated string to the stream
|
||||
void WriteWCString(const wstring& Value);
|
||||
// Writes a already predetermined size string to the stream
|
||||
void WriteSizeString(const string& Value);
|
||||
// Writes a .NET string to the stream
|
||||
void WriteNetString(const string& Value);
|
||||
|
||||
// Writes an integer encoded into 7 bits, top bit = read more
|
||||
void WriteVarInt(uint32_t Value);
|
||||
|
||||
// Writes padding bytes (0x0) to the stream
|
||||
void Pad(uint64_t Count);
|
||||
|
||||
// Get the underlying stream
|
||||
Stream* GetBaseStream() const;
|
||||
// Close the BinaryWriter and underlying stream
|
||||
void Close();
|
||||
|
||||
private:
|
||||
std::unique_ptr<Stream> BaseStream;
|
||||
bool _LeaveOpen;
|
||||
};
|
||||
}
|
140
r5dev/thirdparty/cppnet/cppkore/Bone.cpp
vendored
Normal file
140
r5dev/thirdparty/cppnet/cppkore/Bone.cpp
vendored
Normal file
@ -0,0 +1,140 @@
|
||||
#include "stdafx.h"
|
||||
#include "Bone.h"
|
||||
|
||||
namespace Assets
|
||||
{
|
||||
Bone::Bone()
|
||||
: _Parent(-1), _Flags(BoneFlags::HasLocalSpaceMatrices), _LocalSpacePosition(0, 0, 0), _LocalSpaceRotation(0, 0, 0, 1), _GlobalSpacePosition(0, 0, 0), _GlobalSpaceRotation(0, 0, 0, 1), _Scale(1, 1, 1)
|
||||
{
|
||||
}
|
||||
|
||||
Bone::Bone(const string& Name)
|
||||
: Bone(Name, -1, { 0, 0, 0 }, { 0, 0, 0, 1 }, { 0, 0, 0 }, { 0, 0, 0, 1 }, { 1, 1, 1 }, BoneFlags::HasLocalSpaceMatrices)
|
||||
{
|
||||
}
|
||||
|
||||
Bone::Bone(const string& Name, int32_t ParentIndex)
|
||||
: Bone(Name, ParentIndex, { 0, 0, 0 }, { 0, 0, 0, 1 }, { 0, 0, 0 }, { 0, 0, 0, 1 }, { 1, 1, 1 }, BoneFlags::HasLocalSpaceMatrices)
|
||||
{
|
||||
}
|
||||
|
||||
Bone::Bone(const string& Name, int32_t ParentIndex, Vector3 Position, Quaternion Rotation, BoneFlags Flags)
|
||||
: Bone(Name, ParentIndex)
|
||||
{
|
||||
if (((int)Flags & (int)BoneFlags::HasLocalSpaceMatrices) == (int)BoneFlags::HasLocalSpaceMatrices)
|
||||
{
|
||||
this->_LocalSpacePosition = Position;
|
||||
this->_LocalSpaceRotation = Rotation;
|
||||
}
|
||||
else
|
||||
{
|
||||
this->_GlobalSpacePosition = Position;
|
||||
this->_GlobalSpaceRotation = Rotation;
|
||||
}
|
||||
|
||||
this->_Flags = Flags;
|
||||
}
|
||||
|
||||
Bone::Bone(const string & Name, int32_t ParentIndex, Vector3 Position, Quaternion Rotation, Vector3 Scale, BoneFlags Flags)
|
||||
: Bone(Name, ParentIndex)
|
||||
{
|
||||
if (((int)Flags & (int)BoneFlags::HasLocalSpaceMatrices) == (int)BoneFlags::HasLocalSpaceMatrices)
|
||||
{
|
||||
this->_LocalSpacePosition = Position;
|
||||
this->_LocalSpaceRotation = Rotation;
|
||||
}
|
||||
else
|
||||
{
|
||||
this->_GlobalSpacePosition = Position;
|
||||
this->_GlobalSpaceRotation = Rotation;
|
||||
}
|
||||
|
||||
this->_Scale = Scale;
|
||||
this->_Flags = Flags;
|
||||
}
|
||||
|
||||
Bone::Bone(const string& Name, int32_t ParentIndex, Vector3 LocalPosition, Quaternion LocalRotation, Vector3 GlobalPosition, Quaternion GlobalRotation, Vector3 Scale, BoneFlags Flags)
|
||||
: _Name(Name), _Parent(ParentIndex), _LocalSpacePosition(LocalPosition), _LocalSpaceRotation(LocalRotation), _GlobalSpacePosition(GlobalPosition), _GlobalSpaceRotation(GlobalRotation), _Scale(Scale), _Flags(Flags)
|
||||
{
|
||||
}
|
||||
|
||||
bool Bone::GetFlag(BoneFlags Flag)
|
||||
{
|
||||
return ((int)this->_Flags & (int)Flag) == (int)Flag;
|
||||
}
|
||||
|
||||
void Bone::SetFlag(BoneFlags Flags, bool Value)
|
||||
{
|
||||
this->_Flags = Value ? (BoneFlags)((int)this->_Flags | (int)Flags) : (BoneFlags)((int)this->_Flags & ~(int)Flags);
|
||||
}
|
||||
|
||||
const string& Bone::Name() const
|
||||
{
|
||||
return this->_Name;
|
||||
}
|
||||
|
||||
void Bone::SetName(const string& Value)
|
||||
{
|
||||
this->_Name = Value;
|
||||
}
|
||||
|
||||
const int32_t& Bone::Parent() const
|
||||
{
|
||||
return this->_Parent;
|
||||
}
|
||||
|
||||
void Bone::SetParent(int32_t Value)
|
||||
{
|
||||
this->_Parent = Value;
|
||||
}
|
||||
|
||||
const Vector3& Bone::LocalPosition() const
|
||||
{
|
||||
return this->_LocalSpacePosition;
|
||||
}
|
||||
|
||||
void Bone::SetLocalPosition(Vector3 Value)
|
||||
{
|
||||
this->_LocalSpacePosition = Value;
|
||||
}
|
||||
|
||||
const Quaternion& Bone::LocalRotation() const
|
||||
{
|
||||
return this->_LocalSpaceRotation;
|
||||
}
|
||||
|
||||
void Bone::SetLocalRotation(Quaternion Value)
|
||||
{
|
||||
this->_LocalSpaceRotation = Value;
|
||||
}
|
||||
|
||||
const Vector3& Bone::GlobalPosition() const
|
||||
{
|
||||
return this->_GlobalSpacePosition;
|
||||
}
|
||||
|
||||
void Bone::SetGlobalPosition(Vector3 Value)
|
||||
{
|
||||
this->_GlobalSpacePosition = Value;
|
||||
}
|
||||
|
||||
const Quaternion& Bone::GlobalRotation() const
|
||||
{
|
||||
return this->_GlobalSpaceRotation;
|
||||
}
|
||||
|
||||
void Bone::SetGlobalRotation(Quaternion Value)
|
||||
{
|
||||
this->_GlobalSpaceRotation = Value;
|
||||
}
|
||||
|
||||
const Vector3& Bone::Scale() const
|
||||
{
|
||||
return this->_Scale;
|
||||
}
|
||||
|
||||
void Bone::SetScale(Vector3 Value)
|
||||
{
|
||||
this->_Scale = Value;
|
||||
}
|
||||
}
|
93
r5dev/thirdparty/cppnet/cppkore/Bone.h
vendored
Normal file
93
r5dev/thirdparty/cppnet/cppkore/Bone.h
vendored
Normal file
@ -0,0 +1,93 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include "StringBase.h"
|
||||
#include "MathHelper.h"
|
||||
#include "Vector3.h"
|
||||
#include "Quaternion.h"
|
||||
#include "BoneFlags.h"
|
||||
|
||||
namespace Assets
|
||||
{
|
||||
using namespace Math; // All of the matrices classes are in Math::*
|
||||
|
||||
// A container class that holds 3D bone data.
|
||||
class Bone
|
||||
{
|
||||
public:
|
||||
// Initialize a blank 3D bone.
|
||||
Bone();
|
||||
// Initialize a 3D bone with it's tag name.
|
||||
Bone(const string& Name);
|
||||
// Initialize a 3D bone with it's tag name, and parent index.
|
||||
Bone(const string& Name, int32_t ParentIndex);
|
||||
// Initialize a 3D bone with it's tag name, parent index, and transposition matrix.
|
||||
Bone(const string& Name, int32_t ParentIndex, Vector3 Position, Quaternion Rotation, BoneFlags Flags = BoneFlags::HasLocalSpaceMatrices);
|
||||
// Initialize a 3D bone with it's tag name, parent index, transposition matrix, and scale transform.
|
||||
Bone(const string& Name, int32_t ParentIndex, Vector3 Position, Quaternion Rotation, Vector3 Scale, BoneFlags Flags = (BoneFlags::HasLocalSpaceMatrices | BoneFlags::HasScale));
|
||||
// Initialize a 3D bone with it's tag name, parent index, local and global transposition matrix, and scale transform.
|
||||
Bone(const string& Name, int32_t ParentIndex, Vector3 LocalPosition, Quaternion LocalRotation, Vector3 GlobalPosition, Quaternion GlobalRotation, Vector3 Scale, BoneFlags Flags = (BoneFlags::HasGlobalSpaceMatrices | BoneFlags::HasLocalSpaceMatrices | BoneFlags::HasScale));
|
||||
// Destroy all 3D bone resources.
|
||||
~Bone() = default;
|
||||
|
||||
// Ensure that our bone is not copied or assigned to for performance reasons.
|
||||
Bone(const Bone&) = delete;
|
||||
|
||||
// Gets bone specific flags.
|
||||
bool GetFlag(BoneFlags Flag);
|
||||
// Sets bone specific flags.
|
||||
void SetFlag(BoneFlags Flags, bool Value);
|
||||
|
||||
// Gets the tag name assigned to the bone.
|
||||
const string& Name() const;
|
||||
// Sets the tag name assigned to the bone.
|
||||
void SetName(const string& Value);
|
||||
|
||||
// Gets the parent bone index.
|
||||
const int32_t& Parent() const;
|
||||
// Sets the parent bone index.
|
||||
void SetParent(int32_t Value);
|
||||
|
||||
// Gets the local space position.
|
||||
const Vector3& LocalPosition() const;
|
||||
// Sets the local space position.
|
||||
void SetLocalPosition(Vector3 Value);
|
||||
|
||||
// Gets the local space rotation.
|
||||
const Quaternion& LocalRotation() const;
|
||||
// Sets the local space rotation.
|
||||
void SetLocalRotation(Quaternion Value);
|
||||
|
||||
// Gets the global space position.
|
||||
const Vector3& GlobalPosition() const;
|
||||
// Sets the global space position.
|
||||
void SetGlobalPosition(Vector3 Value);
|
||||
|
||||
// Gets the global space rotation.
|
||||
const Quaternion& GlobalRotation() const;
|
||||
// Sets the global space rotation.
|
||||
void SetGlobalRotation(Quaternion Value);
|
||||
|
||||
// Gets the scale transform.
|
||||
const Vector3& Scale() const;
|
||||
// Sets the scale transform.
|
||||
void SetScale(Vector3 Value);
|
||||
|
||||
private:
|
||||
// Internal tag name
|
||||
string _Name;
|
||||
|
||||
// Internal parent index
|
||||
int32_t _Parent;
|
||||
|
||||
// Internal flags for this bone
|
||||
BoneFlags _Flags;
|
||||
|
||||
// Internal 3D matrix information for this bone
|
||||
Vector3 _LocalSpacePosition;
|
||||
Vector3 _GlobalSpacePosition;
|
||||
Quaternion _LocalSpaceRotation;
|
||||
Quaternion _GlobalSpaceRotation;
|
||||
Vector3 _Scale;
|
||||
};
|
||||
}
|
26
r5dev/thirdparty/cppnet/cppkore/BoneFlags.h
vendored
Normal file
26
r5dev/thirdparty/cppnet/cppkore/BoneFlags.h
vendored
Normal file
@ -0,0 +1,26 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <type_traits>
|
||||
|
||||
namespace Assets
|
||||
{
|
||||
// This enumeration represents the possible bone flags.
|
||||
enum class BoneFlags : uint8_t
|
||||
{
|
||||
// Whether or not the bone has local space transforms
|
||||
HasLocalSpaceMatrices = 0x1,
|
||||
// Whether or not the bone has global space transforms
|
||||
HasGlobalSpaceMatrices = 0x2,
|
||||
// Whether or not the bone has a scale transform
|
||||
HasScale = 0x4
|
||||
};
|
||||
|
||||
//
|
||||
// Allow bitwise operations on this enumeration
|
||||
//
|
||||
constexpr BoneFlags operator|(BoneFlags Lhs, BoneFlags Rhs)
|
||||
{
|
||||
return static_cast<BoneFlags>(static_cast<std::underlying_type<BoneFlags>::type>(Lhs) | static_cast<std::underlying_type<BoneFlags>::type>(Rhs));
|
||||
};
|
||||
}
|
17
r5dev/thirdparty/cppnet/cppkore/BorderStyle.h
vendored
Normal file
17
r5dev/thirdparty/cppnet/cppkore/BorderStyle.h
vendored
Normal file
@ -0,0 +1,17 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
namespace Forms
|
||||
{
|
||||
// Specifies the border style for a control or form.
|
||||
enum class BorderStyle
|
||||
{
|
||||
// No border.
|
||||
None = 0,
|
||||
// A single-line border.
|
||||
FixedSingle = 1,
|
||||
// A three-dimensional border.
|
||||
Fixed3D = 2
|
||||
};
|
||||
}
|
21
r5dev/thirdparty/cppnet/cppkore/BoundsSpecified.h
vendored
Normal file
21
r5dev/thirdparty/cppnet/cppkore/BoundsSpecified.h
vendored
Normal file
@ -0,0 +1,21 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <type_traits>
|
||||
|
||||
namespace Forms
|
||||
{
|
||||
// Specifies the bounds of the control to
|
||||
// use when defining a control's size and position.
|
||||
enum class BoundsSpecified : uint32_t
|
||||
{
|
||||
X = 0x1,
|
||||
Y = 0x2,
|
||||
Width = 0x4,
|
||||
Height = 0x8,
|
||||
Location = X | Y,
|
||||
Size = Width | Height,
|
||||
All = Location | Size,
|
||||
None = 0,
|
||||
};
|
||||
}
|
27
r5dev/thirdparty/cppnet/cppkore/BufferedGraphics.cpp
vendored
Normal file
27
r5dev/thirdparty/cppnet/cppkore/BufferedGraphics.cpp
vendored
Normal file
@ -0,0 +1,27 @@
|
||||
#include "stdafx.h"
|
||||
#include "BufferedGraphics.h"
|
||||
|
||||
namespace Drawing
|
||||
{
|
||||
BufferedGraphics::BufferedGraphics(HDC TargetDC, Drawing::Rectangle TargetRectangle)
|
||||
: _TargetDC(TargetDC), Rectangle(TargetRectangle)
|
||||
{
|
||||
this->Buffer = std::make_unique<Drawing::Bitmap>(TargetRectangle.Width, TargetRectangle.Height);
|
||||
this->Graphics = std::make_unique<Drawing::Graphics>(this->Buffer.get());
|
||||
}
|
||||
|
||||
void BufferedGraphics::Render()
|
||||
{
|
||||
// Render the buffer to the target
|
||||
auto Gfx = Gdiplus::Graphics::FromHDC(this->_TargetDC);
|
||||
Gfx->DrawImage(this->Buffer.get(), this->Rectangle);
|
||||
|
||||
// Clean up the graphics object
|
||||
delete Gfx;
|
||||
}
|
||||
|
||||
Drawing::Rectangle BufferedGraphics::Region()
|
||||
{
|
||||
return Drawing::Rectangle(0, 0, this->Rectangle.Width, this->Rectangle.Height);
|
||||
}
|
||||
}
|
32
r5dev/thirdparty/cppnet/cppkore/BufferedGraphics.h
vendored
Normal file
32
r5dev/thirdparty/cppnet/cppkore/BufferedGraphics.h
vendored
Normal file
@ -0,0 +1,32 @@
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include "DrawingBase.h"
|
||||
|
||||
namespace Drawing
|
||||
{
|
||||
class BufferedGraphics
|
||||
{
|
||||
public:
|
||||
BufferedGraphics(HDC TargetDC, Drawing::Rectangle TargetRectangle);
|
||||
~BufferedGraphics() = default;
|
||||
|
||||
// Renders the buffered graphics to the target surface
|
||||
void Render();
|
||||
|
||||
// Gets the size of the region
|
||||
Drawing::Rectangle Region();
|
||||
|
||||
// The graphics instance for this instance
|
||||
std::unique_ptr<Drawing::Graphics> Graphics;
|
||||
|
||||
private:
|
||||
// Internal buffer to draw to
|
||||
std::unique_ptr<Drawing::Bitmap> Buffer;
|
||||
// Internal target handle
|
||||
HDC _TargetDC;
|
||||
|
||||
// Internal size of the buffer region
|
||||
Drawing::Rectangle Rectangle;
|
||||
};
|
||||
}
|
104
r5dev/thirdparty/cppnet/cppkore/Button.cpp
vendored
Normal file
104
r5dev/thirdparty/cppnet/cppkore/Button.cpp
vendored
Normal file
@ -0,0 +1,104 @@
|
||||
#include "stdafx.h"
|
||||
#include "Button.h"
|
||||
#include "Form.h"
|
||||
|
||||
namespace Forms
|
||||
{
|
||||
Button::Button()
|
||||
: ButtonBase(), _DialogResult(DialogResult::None)
|
||||
{
|
||||
SetStyle(ControlStyles::StandardClick | ControlStyles::StandardDoubleClick, false);
|
||||
|
||||
// We are a button control
|
||||
this->_RTTI = ControlTypes::Button;
|
||||
}
|
||||
|
||||
DialogResult Button::GetDialogResult()
|
||||
{
|
||||
return this->_DialogResult;
|
||||
}
|
||||
|
||||
void Button::SetDialogResult(DialogResult Value)
|
||||
{
|
||||
this->_DialogResult = Value;
|
||||
}
|
||||
|
||||
void Button::PerformClick()
|
||||
{
|
||||
if (CanSelect())
|
||||
{
|
||||
ResetFlagsAndPaint();
|
||||
OnClick();
|
||||
}
|
||||
}
|
||||
|
||||
void Button::NotifyDefault(bool Value)
|
||||
{
|
||||
if (IsDefault() != Value)
|
||||
SetIsDefault(Value);
|
||||
}
|
||||
|
||||
void Button::OnClick()
|
||||
{
|
||||
auto Form = this->FindForm();
|
||||
|
||||
if (Form != nullptr)
|
||||
((Forms::Form*)Form)->SetDialogResult(this->_DialogResult);
|
||||
|
||||
// Call base event last
|
||||
ButtonBase::OnClick();
|
||||
}
|
||||
|
||||
void Button::OnMouseUp(const std::unique_ptr<MouseEventArgs>& EventArgs)
|
||||
{
|
||||
if (EventArgs->Button == MouseButtons::Left && GetFlag(ButtonFlags::FlagMousePressed))
|
||||
{
|
||||
auto isMouseDown = GetFlag(ButtonFlags::FlagMouseDown);
|
||||
|
||||
if (GetStyle(ControlStyles::UserPaint))
|
||||
{
|
||||
this->ResetFlagsAndPaint();
|
||||
}
|
||||
|
||||
if (isMouseDown)
|
||||
{
|
||||
auto Pt = PointToScreen({ (INT)EventArgs->X, (INT)EventArgs->Y });
|
||||
|
||||
POINT nPt;
|
||||
nPt.x = Pt.X;
|
||||
nPt.y = Pt.Y;
|
||||
|
||||
if (WindowFromPoint(nPt) == this->_Handle)
|
||||
{
|
||||
if (GetStyle(ControlStyles::UserPaint))
|
||||
OnClick();
|
||||
|
||||
OnMouseClick(EventArgs);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Call base event last
|
||||
ButtonBase::OnMouseUp(EventArgs);
|
||||
}
|
||||
|
||||
CreateParams Button::GetCreateParams()
|
||||
{
|
||||
auto Cp = ButtonBase::GetCreateParams();
|
||||
|
||||
Cp.ClassName = "BUTTON";
|
||||
|
||||
if (GetStyle(ControlStyles::UserPaint))
|
||||
Cp.Style |= BS_OWNERDRAW;
|
||||
else
|
||||
{
|
||||
Cp.Style |= BS_MULTILINE;
|
||||
Cp.Style |= BS_PUSHBUTTON;
|
||||
|
||||
if (this->IsDefault())
|
||||
Cp.Style |= BS_DEFPUSHBUTTON;
|
||||
}
|
||||
|
||||
return Cp;
|
||||
}
|
||||
}
|
42
r5dev/thirdparty/cppnet/cppkore/Button.h
vendored
Normal file
42
r5dev/thirdparty/cppnet/cppkore/Button.h
vendored
Normal file
@ -0,0 +1,42 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include "Control.h"
|
||||
#include "ButtonBase.h"
|
||||
#include "DialogResult.h"
|
||||
|
||||
namespace Forms
|
||||
{
|
||||
// Represents a Windows button.
|
||||
class Button : public ButtonBase
|
||||
{
|
||||
public:
|
||||
Button();
|
||||
virtual ~Button() = default;
|
||||
|
||||
// Gets a value that is returned to the
|
||||
// parent form when the button is clicked.
|
||||
DialogResult GetDialogResult();
|
||||
// Sets a value that is returned to the
|
||||
// parent form when the button is clicked.
|
||||
void SetDialogResult(DialogResult Value);
|
||||
|
||||
// Generates a click event for a button.
|
||||
void PerformClick();
|
||||
|
||||
// Changes the default action status.
|
||||
void NotifyDefault(bool Value);
|
||||
|
||||
// We must define base events here
|
||||
virtual void OnClick();
|
||||
virtual void OnMouseUp(const std::unique_ptr<MouseEventArgs>& EventArgs);
|
||||
|
||||
protected:
|
||||
// Get custom control creation parameters for this instance.
|
||||
virtual CreateParams GetCreateParams();
|
||||
|
||||
private:
|
||||
// Internal cached dialog result that this button represents
|
||||
DialogResult _DialogResult;
|
||||
};
|
||||
}
|
330
r5dev/thirdparty/cppnet/cppkore/ButtonBase.cpp
vendored
Normal file
330
r5dev/thirdparty/cppnet/cppkore/ButtonBase.cpp
vendored
Normal file
@ -0,0 +1,330 @@
|
||||
#include "stdafx.h"
|
||||
#include "ButtonBase.h"
|
||||
|
||||
namespace Forms
|
||||
{
|
||||
ButtonBase::ButtonBase()
|
||||
: Control(), _OwnerDraw(false), _Flags((ButtonFlags)0), _FlatStyle(FlatStyle::Standard), _TextAlign(Drawing::ContentAlignment::MiddleCenter)
|
||||
{
|
||||
SetStyle(ControlStyles::SupportsTransparentBackColor |
|
||||
ControlStyles::Opaque |
|
||||
ControlStyles::ResizeRedraw |
|
||||
ControlStyles::OptimizedDoubleBuffer |
|
||||
ControlStyles::CacheText |
|
||||
ControlStyles::StandardClick, true);
|
||||
|
||||
SetStyle(ControlStyles::UserMouse |
|
||||
ControlStyles::UserPaint, this->_OwnerDraw);
|
||||
}
|
||||
|
||||
bool ButtonBase::OwnerDraw()
|
||||
{
|
||||
return this->_OwnerDraw;
|
||||
}
|
||||
|
||||
void ButtonBase::SetOwnerDraw(bool Value)
|
||||
{
|
||||
this->_OwnerDraw = Value;
|
||||
|
||||
SetStyle(ControlStyles::UserMouse | ControlStyles::UserPaint, Value);
|
||||
|
||||
UpdateStyles();
|
||||
Invalidate();
|
||||
}
|
||||
|
||||
Drawing::ContentAlignment ButtonBase::TextAlign()
|
||||
{
|
||||
return this->_TextAlign;
|
||||
}
|
||||
|
||||
void ButtonBase::SetTextAlign(Drawing::ContentAlignment Value)
|
||||
{
|
||||
this->_TextAlign = Value;
|
||||
|
||||
if (this->_OwnerDraw)
|
||||
Invalidate();
|
||||
else
|
||||
UpdateStyles();
|
||||
}
|
||||
|
||||
FlatStyle ButtonBase::GetFlatStyle()
|
||||
{
|
||||
return this->_FlatStyle;
|
||||
}
|
||||
|
||||
void ButtonBase::SetFlatStyle(FlatStyle Value)
|
||||
{
|
||||
this->_FlatStyle = Value;
|
||||
|
||||
Invalidate();
|
||||
|
||||
// Force update styles...
|
||||
SetStyle(ControlStyles::UserMouse | ControlStyles::UserPaint, this->_OwnerDraw);
|
||||
UpdateStyles();
|
||||
}
|
||||
|
||||
bool ButtonBase::IsDefault()
|
||||
{
|
||||
return GetFlag(ButtonFlags::FlagIsDefault);
|
||||
}
|
||||
|
||||
void ButtonBase::SetIsDefault(bool Value)
|
||||
{
|
||||
if (IsDefault() != Value)
|
||||
{
|
||||
SetFlag(ButtonFlags::FlagIsDefault, Value);
|
||||
|
||||
if (this->_OwnerDraw)
|
||||
Invalidate();
|
||||
else
|
||||
UpdateStyles();
|
||||
}
|
||||
}
|
||||
|
||||
bool ButtonBase::GetFlag(ButtonFlags Flag)
|
||||
{
|
||||
return ((int)this->_Flags & (int)Flag) == (int)Flag;
|
||||
}
|
||||
|
||||
void ButtonBase::SetFlag(ButtonFlags Flags, bool Value)
|
||||
{
|
||||
this->_Flags = Value ? (ButtonFlags)((int)this->_Flags | (int)Flags) : (ButtonFlags)((int)this->_Flags & ~(int)Flags);
|
||||
}
|
||||
|
||||
void ButtonBase::OnLostFocus()
|
||||
{
|
||||
Control::OnLostFocus();
|
||||
|
||||
// Hitting tab while holding down the space key
|
||||
SetFlag(ButtonFlags::FlagMouseDown, false);
|
||||
SetCapture(false);
|
||||
|
||||
Invalidate();
|
||||
}
|
||||
|
||||
void ButtonBase::OnGotFocus()
|
||||
{
|
||||
Control::OnGotFocus();
|
||||
Invalidate();
|
||||
}
|
||||
|
||||
void ButtonBase::OnMouseEnter()
|
||||
{
|
||||
SetFlag(ButtonFlags::FlagMouseOver, true);
|
||||
Invalidate();
|
||||
|
||||
// Call base event last
|
||||
Control::OnMouseEnter();
|
||||
}
|
||||
|
||||
void ButtonBase::OnMouseLeave()
|
||||
{
|
||||
SetFlag(ButtonFlags::FlagMouseOver, false);
|
||||
Invalidate();
|
||||
|
||||
// Call base event last
|
||||
Control::OnMouseLeave();
|
||||
}
|
||||
|
||||
void ButtonBase::OnEnabledChanged()
|
||||
{
|
||||
Control::OnEnabledChanged();
|
||||
|
||||
if (!Enabled())
|
||||
{
|
||||
SetFlag(ButtonFlags::FlagMouseDown | ButtonFlags::FlagMouseOver, false);
|
||||
Invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
void ButtonBase::OnTextChanged()
|
||||
{
|
||||
Control::OnTextChanged();
|
||||
Invalidate();
|
||||
}
|
||||
|
||||
void ButtonBase::OnMouseMove(const std::unique_ptr<MouseEventArgs>& EventArgs)
|
||||
{
|
||||
if (EventArgs->Button != MouseButtons::None && GetFlag(ButtonFlags::FlagMousePressed))
|
||||
{
|
||||
auto CRect = this->ClientRectangle();
|
||||
|
||||
if (!CRect.Contains(EventArgs->X, EventArgs->Y))
|
||||
{
|
||||
if (GetFlag(ButtonFlags::FlagMouseDown))
|
||||
{
|
||||
SetFlag(ButtonFlags::FlagMouseDown, false);
|
||||
Invalidate();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!GetFlag(ButtonFlags::FlagMouseDown))
|
||||
{
|
||||
SetFlag(ButtonFlags::FlagMouseDown, true);
|
||||
Invalidate();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Call base event last
|
||||
Control::OnMouseMove(EventArgs);
|
||||
}
|
||||
|
||||
void ButtonBase::OnMouseDown(const std::unique_ptr<MouseEventArgs>& EventArgs)
|
||||
{
|
||||
if (EventArgs->Button == MouseButtons::Left)
|
||||
{
|
||||
SetFlag(ButtonFlags::FlagMouseDown | ButtonFlags::FlagMousePressed, true);
|
||||
Invalidate();
|
||||
}
|
||||
|
||||
// Call base event last
|
||||
Control::OnMouseDown(EventArgs);
|
||||
}
|
||||
|
||||
void ButtonBase::OnMouseUp(const std::unique_ptr<MouseEventArgs>& EventArgs)
|
||||
{
|
||||
// Call base event last
|
||||
Control::OnMouseUp(EventArgs);
|
||||
}
|
||||
|
||||
void ButtonBase::OnKeyUp(const std::unique_ptr<KeyEventArgs>& EventArgs)
|
||||
{
|
||||
if (GetFlag(ButtonFlags::FlagMouseDown))
|
||||
{
|
||||
if (this->_OwnerDraw)
|
||||
ResetFlagsAndPaint();
|
||||
else
|
||||
{
|
||||
SetFlag(ButtonFlags::FlagMousePressed | ButtonFlags::FlagMouseDown, false);
|
||||
SendMessageA(this->_Handle, BM_SETSTATE, 0, 0);
|
||||
}
|
||||
|
||||
if (EventArgs->KeyCode() == Keys::Enter || EventArgs->KeyCode() == Keys::Space)
|
||||
OnClick();
|
||||
|
||||
EventArgs->SetHandled(true);
|
||||
}
|
||||
|
||||
// Call base event last
|
||||
Control::OnKeyUp(EventArgs);
|
||||
}
|
||||
|
||||
void ButtonBase::OnKeyDown(const std::unique_ptr<KeyEventArgs>& EventArgs)
|
||||
{
|
||||
if (EventArgs->KeyData() == Keys::Space)
|
||||
{
|
||||
if (!GetFlag(ButtonFlags::FlagMouseDown))
|
||||
{
|
||||
SetFlag(ButtonFlags::FlagMouseDown, true);
|
||||
|
||||
if (!this->_OwnerDraw)
|
||||
SendMessageA(this->_Handle, BM_SETSTATE, 1, 0);
|
||||
|
||||
Invalidate();
|
||||
}
|
||||
|
||||
EventArgs->SetHandled(true);
|
||||
}
|
||||
|
||||
// Call base event last
|
||||
Control::OnKeyDown(EventArgs);
|
||||
}
|
||||
|
||||
void ButtonBase::WndProc(Message& Msg)
|
||||
{
|
||||
switch (Msg.Msg)
|
||||
{
|
||||
case BM_CLICK:
|
||||
OnClick();
|
||||
return;
|
||||
}
|
||||
|
||||
if (this->_OwnerDraw)
|
||||
{
|
||||
switch (Msg.Msg)
|
||||
{
|
||||
case BM_SETSTATE:
|
||||
break;
|
||||
|
||||
case WM_KILLFOCUS:
|
||||
case WM_CANCELMODE:
|
||||
case WM_CAPTURECHANGED:
|
||||
|
||||
if (!GetFlag(ButtonFlags::FlagInButtonUp) && GetFlag(ButtonFlags::FlagMousePressed))
|
||||
{
|
||||
SetFlag(ButtonFlags::FlagMousePressed, false);
|
||||
|
||||
if (GetFlag(ButtonFlags::FlagMouseDown))
|
||||
{
|
||||
SetFlag(ButtonFlags::FlagMouseDown, false);
|
||||
Invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
Control::WndProc(Msg);
|
||||
break;
|
||||
|
||||
case WM_LBUTTONUP:
|
||||
case WM_MBUTTONUP:
|
||||
case WM_RBUTTONUP:
|
||||
|
||||
SetFlag(ButtonFlags::FlagInButtonUp, true);
|
||||
Control::WndProc(Msg);
|
||||
SetFlag(ButtonFlags::FlagInButtonUp, false);
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
Control::WndProc(Msg);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Msg.Msg == (WM_REFLECT + WM_COMMAND) && HIWORD(Msg.WParam) == BN_CLICKED)
|
||||
OnClick();
|
||||
else
|
||||
Control::WndProc(Msg);
|
||||
}
|
||||
}
|
||||
|
||||
CreateParams ButtonBase::GetCreateParams()
|
||||
{
|
||||
auto Cp = Control::GetCreateParams();
|
||||
|
||||
if (!this->_OwnerDraw)
|
||||
{
|
||||
Cp.ExStyle &= ~WS_EX_RIGHT; // Messes up the BM_ Alignment flags
|
||||
|
||||
Cp.Style |= BS_MULTILINE;
|
||||
|
||||
if (IsDefault())
|
||||
Cp.Style |= BS_DEFPUSHBUTTON;
|
||||
|
||||
if (((int)this->_TextAlign & (int)Drawing::AnyLeftAlign) != 0)
|
||||
Cp.Style |= BS_LEFT;
|
||||
else if (((int)this->_TextAlign & (int)Drawing::AnyRightAlign) != 0)
|
||||
Cp.Style |= BS_RIGHT;
|
||||
else
|
||||
Cp.Style |= BS_CENTER;
|
||||
|
||||
if (((int)this->_TextAlign & (int)Drawing::AnyTopAlign) != 0)
|
||||
Cp.Style |= BS_TOP;
|
||||
else if (((int)this->_TextAlign & (int)Drawing::AnyBottomAlign) != 0)
|
||||
Cp.Style |= BS_BOTTOM;
|
||||
else
|
||||
Cp.Style |= BS_VCENTER;
|
||||
}
|
||||
|
||||
return Cp;
|
||||
}
|
||||
|
||||
void ButtonBase::ResetFlagsAndPaint()
|
||||
{
|
||||
SetFlag(ButtonFlags::FlagMousePressed | ButtonFlags::FlagMouseDown, false);
|
||||
Invalidate();
|
||||
Update();
|
||||
}
|
||||
}
|
76
r5dev/thirdparty/cppnet/cppkore/ButtonBase.h
vendored
Normal file
76
r5dev/thirdparty/cppnet/cppkore/ButtonBase.h
vendored
Normal file
@ -0,0 +1,76 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include "Control.h"
|
||||
#include "FlatStyle.h"
|
||||
#include "ButtonFlags.h"
|
||||
#include "ContentAlignment.h"
|
||||
|
||||
namespace Forms
|
||||
{
|
||||
// Implements the basic functionality required by a button control.
|
||||
class ButtonBase : public Control
|
||||
{
|
||||
public:
|
||||
virtual ~ButtonBase() = default;
|
||||
|
||||
// Gets the drawing mode of the button control.
|
||||
bool OwnerDraw();
|
||||
// Sets the drawing mode of the button control.
|
||||
void SetOwnerDraw(bool Value);
|
||||
|
||||
// Gets the alignment of the text on the button control.
|
||||
Drawing::ContentAlignment TextAlign();
|
||||
// Sets the alignment of the text on the button control.
|
||||
void SetTextAlign(Drawing::ContentAlignment Value);
|
||||
|
||||
// Gets the flat style appearance of the button control.
|
||||
FlatStyle GetFlatStyle();
|
||||
// Sets the flat style appearance of the button control.
|
||||
void SetFlatStyle(FlatStyle Value);
|
||||
|
||||
// Get whether or not this control is the default response.
|
||||
bool IsDefault();
|
||||
// Sets whether or not this control is the default response.
|
||||
void SetIsDefault(bool Value);
|
||||
|
||||
// We must define base events here
|
||||
virtual void OnLostFocus();
|
||||
virtual void OnGotFocus();
|
||||
virtual void OnMouseEnter();
|
||||
virtual void OnMouseLeave();
|
||||
virtual void OnEnabledChanged();
|
||||
virtual void OnTextChanged();
|
||||
virtual void OnMouseMove(const std::unique_ptr<MouseEventArgs>& EventArgs);
|
||||
virtual void OnMouseDown(const std::unique_ptr<MouseEventArgs>& EventArgs);
|
||||
virtual void OnMouseUp(const std::unique_ptr<MouseEventArgs>& EventArgs);
|
||||
virtual void OnKeyUp(const std::unique_ptr<KeyEventArgs>& EventArgs);
|
||||
virtual void OnKeyDown(const std::unique_ptr<KeyEventArgs>& EventArgs);
|
||||
|
||||
// Override WndProc for specific button messages.
|
||||
virtual void WndProc(Message& Msg);
|
||||
|
||||
protected:
|
||||
ButtonBase();
|
||||
|
||||
// Get custom control creation parameters for this instance.
|
||||
virtual CreateParams GetCreateParams();
|
||||
|
||||
// Used for quick re-painting of the button after the pressed state.
|
||||
void ResetFlagsAndPaint();
|
||||
|
||||
// Gets button specific flags
|
||||
bool GetFlag(ButtonFlags Flag);
|
||||
// Sets button specific flags
|
||||
void SetFlag(ButtonFlags Flags, bool Value);
|
||||
|
||||
// Whether or not the control will draw itself
|
||||
bool _OwnerDraw;
|
||||
// Control specific flags
|
||||
ButtonFlags _Flags;
|
||||
// Controls the style of the control
|
||||
FlatStyle _FlatStyle;
|
||||
// Controls the alignment of text on the control
|
||||
Drawing::ContentAlignment _TextAlign;
|
||||
};
|
||||
}
|
29
r5dev/thirdparty/cppnet/cppkore/ButtonFlags.h
vendored
Normal file
29
r5dev/thirdparty/cppnet/cppkore/ButtonFlags.h
vendored
Normal file
@ -0,0 +1,29 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <type_traits>
|
||||
|
||||
namespace Forms
|
||||
{
|
||||
// This enumeration represents the ButtonBase flags...
|
||||
enum class ButtonFlags
|
||||
{
|
||||
FlagMouseOver = 0x0001,
|
||||
FlagMouseDown = 0x0002,
|
||||
FlagMousePressed = 0x0004,
|
||||
FlagInButtonUp = 0x0008,
|
||||
FlagCurrentlyAnimating = 0x0010,
|
||||
FlagAutoEllipsis = 0x0020,
|
||||
FlagIsDefault = 0x0040,
|
||||
FlagUseMnemonic = 0x0080,
|
||||
FlagShowToolTip = 0x0100,
|
||||
};
|
||||
|
||||
//
|
||||
// Allow bitwise operations on this enumeration
|
||||
//
|
||||
constexpr ButtonFlags operator|(ButtonFlags Lhs, ButtonFlags Rhs)
|
||||
{
|
||||
return static_cast<ButtonFlags>(static_cast<std::underlying_type<ButtonFlags>::type>(Lhs) | static_cast<std::underlying_type<ButtonFlags>::type>(Rhs));
|
||||
};
|
||||
}
|
69
r5dev/thirdparty/cppnet/cppkore/CRC32.cpp
vendored
Normal file
69
r5dev/thirdparty/cppnet/cppkore/CRC32.cpp
vendored
Normal file
@ -0,0 +1,69 @@
|
||||
#include "stdafx.h"
|
||||
#include "CRC32.h"
|
||||
|
||||
namespace Hashing
|
||||
{
|
||||
// The table of precalculated CRC32 primes.
|
||||
static constexpr uint32_t CRC32LookupTable[] =
|
||||
{
|
||||
0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f,
|
||||
0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
|
||||
0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2,
|
||||
0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
|
||||
0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
|
||||
0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
|
||||
0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c,
|
||||
0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
|
||||
0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423,
|
||||
0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
|
||||
0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106,
|
||||
0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
|
||||
0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d,
|
||||
0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
|
||||
0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
|
||||
0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
|
||||
0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7,
|
||||
0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
|
||||
0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa,
|
||||
0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
|
||||
0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81,
|
||||
0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
|
||||
0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84,
|
||||
0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
|
||||
0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
|
||||
0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
|
||||
0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e,
|
||||
0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
|
||||
0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55,
|
||||
0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
|
||||
0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28,
|
||||
0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
|
||||
0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f,
|
||||
0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
|
||||
0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
|
||||
0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
|
||||
0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69,
|
||||
0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
|
||||
0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc,
|
||||
0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
|
||||
0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693,
|
||||
0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
|
||||
0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
|
||||
};
|
||||
|
||||
uint32_t CRC32::HashString(const string& Input, uint32_t Seed)
|
||||
{
|
||||
return ComputeHash((uint8_t*)(char*)Input, 0, Input.Length(), Seed);
|
||||
}
|
||||
|
||||
uint32_t CRC32::ComputeHash(uint8_t* Input, uint64_t InputOffset, uint64_t InputLength, uint32_t Seed)
|
||||
{
|
||||
auto pCur = (uint8_t*)(Input + InputOffset);
|
||||
|
||||
uint32_t _crc = ~Seed;
|
||||
for (; InputLength--; ++pCur)
|
||||
_crc = (_crc >> 8) ^ CRC32LookupTable[(_crc ^ *pCur) & 0xFF];
|
||||
|
||||
return (~_crc);
|
||||
}
|
||||
}
|
26
r5dev/thirdparty/cppnet/cppkore/CRC32.h
vendored
Normal file
26
r5dev/thirdparty/cppnet/cppkore/CRC32.h
vendored
Normal file
@ -0,0 +1,26 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include "StringBase.h"
|
||||
|
||||
namespace Hashing
|
||||
{
|
||||
// A hashing algo that implements CRC32.
|
||||
class CRC32
|
||||
{
|
||||
public:
|
||||
|
||||
// Computes the hash code of the integral value using CRC32 algo.
|
||||
template<class Tinput>
|
||||
static uint32_t HashValue(Tinput Input, uint32_t Seed = 0)
|
||||
{
|
||||
return ComputeHash((uint8_t*)&Input, 0, sizeof(Tinput), Seed);
|
||||
}
|
||||
|
||||
// Computes the hash code of the input string using CRC32 algo.
|
||||
static uint32_t HashString(const string& Input, uint32_t Seed = 0);
|
||||
|
||||
// Computes the hash code using the CRC32 algo.
|
||||
static uint32_t ComputeHash(uint8_t* Input, uint64_t InputOffset, uint64_t InputLength, uint32_t Seed = 0);
|
||||
};
|
||||
}
|
10
r5dev/thirdparty/cppnet/cppkore/CacheVirtualItemsEventArgs.cpp
vendored
Normal file
10
r5dev/thirdparty/cppnet/cppkore/CacheVirtualItemsEventArgs.cpp
vendored
Normal file
@ -0,0 +1,10 @@
|
||||
#include "stdafx.h"
|
||||
#include "CacheVirtualItemsEventArgs.h"
|
||||
|
||||
namespace Forms
|
||||
{
|
||||
CacheVirtualItemsEventArgs::CacheVirtualItemsEventArgs(int32_t Start, int32_t End)
|
||||
: StartIndex(Start), EndIndex(End)
|
||||
{
|
||||
}
|
||||
}
|
19
r5dev/thirdparty/cppnet/cppkore/CacheVirtualItemsEventArgs.h
vendored
Normal file
19
r5dev/thirdparty/cppnet/cppkore/CacheVirtualItemsEventArgs.h
vendored
Normal file
@ -0,0 +1,19 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
namespace Forms
|
||||
{
|
||||
// Provides data for the CacheVirtualItems event.
|
||||
class CacheVirtualItemsEventArgs
|
||||
{
|
||||
public:
|
||||
CacheVirtualItemsEventArgs(int32_t Start, int32_t End);
|
||||
~CacheVirtualItemsEventArgs() = default;
|
||||
|
||||
// The start of the cache index.
|
||||
int32_t StartIndex;
|
||||
// The end of the cache index.
|
||||
int32_t EndIndex;
|
||||
};
|
||||
}
|
15
r5dev/thirdparty/cppnet/cppkore/CancelEventArgs.cpp
vendored
Normal file
15
r5dev/thirdparty/cppnet/cppkore/CancelEventArgs.cpp
vendored
Normal file
@ -0,0 +1,15 @@
|
||||
#include "stdafx.h"
|
||||
#include "CancelEventArgs.h"
|
||||
|
||||
namespace Forms
|
||||
{
|
||||
CancelEventArgs::CancelEventArgs()
|
||||
: CancelEventArgs(false)
|
||||
{
|
||||
}
|
||||
|
||||
CancelEventArgs::CancelEventArgs(bool Cancel)
|
||||
: Cancel(Cancel)
|
||||
{
|
||||
}
|
||||
}
|
18
r5dev/thirdparty/cppnet/cppkore/CancelEventArgs.h
vendored
Normal file
18
r5dev/thirdparty/cppnet/cppkore/CancelEventArgs.h
vendored
Normal file
@ -0,0 +1,18 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
namespace Forms
|
||||
{
|
||||
// Provides data for the cancel event.
|
||||
class CancelEventArgs
|
||||
{
|
||||
public:
|
||||
CancelEventArgs();
|
||||
CancelEventArgs(bool Cancel);
|
||||
~CancelEventArgs() = default;
|
||||
|
||||
// Gets or sets a value indicating whether the operation should be cancelled.
|
||||
bool Cancel;
|
||||
};
|
||||
}
|
402
r5dev/thirdparty/cppnet/cppkore/CastAsset.cpp
vendored
Normal file
402
r5dev/thirdparty/cppnet/cppkore/CastAsset.cpp
vendored
Normal file
@ -0,0 +1,402 @@
|
||||
#include "stdafx.h"
|
||||
#include "CastAsset.h"
|
||||
#include "CastNode.h"
|
||||
#include "File.h"
|
||||
#include "XXHash.h"
|
||||
#include "BinaryWriter.h"
|
||||
|
||||
namespace Assets::Exporters
|
||||
{
|
||||
struct CastHeader
|
||||
{
|
||||
uint32_t Magic; // char[4] cast (0x74736163)
|
||||
uint32_t Version; // 0x1
|
||||
uint32_t RootNodes; // Number of root nodes, which contain various sub nodes if necessary
|
||||
uint32_t Flags; // Reserved for flags, or padding, whichever is needed
|
||||
};
|
||||
|
||||
static_assert(sizeof(CastHeader) == 0x10, "Cast header size mismatch");
|
||||
|
||||
|
||||
bool CastAsset::ExportAnimation(const Animation& Animation, const string& Path)
|
||||
{
|
||||
auto Writer = IO::BinaryWriter(IO::File::Create(Path));
|
||||
|
||||
// Magic, version 1, one root node, no flags.
|
||||
Writer.Write<CastHeader>({ 0x74736163, 0x1, 0x1, 0x0 });
|
||||
|
||||
// This is the base of the virtual scene
|
||||
auto Root = CastNode(CastId::Root);
|
||||
auto& AnimNode = Root.Children.Emplace(CastId::Animation, Hashing::XXHash::HashString("animation"));
|
||||
auto& SkeletonNode = AnimNode.Children.Emplace(CastId::Skeleton, Hashing::XXHash::HashString("skeleton"));
|
||||
|
||||
AnimNode.Properties.Emplace(CastPropertyId::Float, "fr").AddFloat(Animation.FrameRate);
|
||||
AnimNode.Properties.Emplace(CastPropertyId::Byte, "lo").AddByte((uint8_t)Animation.Looping);
|
||||
|
||||
for (auto& Bone : Animation.Bones)
|
||||
{
|
||||
auto& BoneNode = SkeletonNode.Children.Emplace(CastId::Bone);
|
||||
|
||||
BoneNode.Properties.Emplace(CastPropertyId::String, "n").SetString(Bone.Name());
|
||||
BoneNode.Properties.Emplace(CastPropertyId::Integer32, "p").AddInteger32(Bone.Parent());
|
||||
|
||||
if (Bone.GetFlag(Assets::BoneFlags::HasLocalSpaceMatrices))
|
||||
{
|
||||
BoneNode.Properties.Emplace(CastPropertyId::Vector3, "lp").AddVector3(Bone.LocalPosition());
|
||||
BoneNode.Properties.Emplace(CastPropertyId::Vector4, "lr").AddVector4(Bone.LocalRotation());
|
||||
}
|
||||
if (Bone.GetFlag(Assets::BoneFlags::HasGlobalSpaceMatrices))
|
||||
{
|
||||
BoneNode.Properties.Emplace(CastPropertyId::Vector3, "wp").AddVector3(Bone.GlobalPosition());
|
||||
BoneNode.Properties.Emplace(CastPropertyId::Vector4, "wr").AddVector4(Bone.GlobalRotation());
|
||||
}
|
||||
if (Bone.GetFlag(Assets::BoneFlags::HasScale))
|
||||
{
|
||||
BoneNode.Properties.Emplace(CastPropertyId::Vector3, "s").AddVector3(Bone.Scale());
|
||||
}
|
||||
}
|
||||
|
||||
for (auto& Kvp : Animation.Curves)
|
||||
{
|
||||
for (auto& Curve : Kvp.Value())
|
||||
{
|
||||
auto& CurveNode = AnimNode.Children.Emplace(CastId::Curve, 0);
|
||||
|
||||
CurveNode.Properties.Emplace(CastPropertyId::String, "nn").SetString(Curve.Name);
|
||||
|
||||
constexpr const char* PropertyNameMap[] = {
|
||||
"ex",
|
||||
"rq",
|
||||
"rx",
|
||||
"ry",
|
||||
"rz",
|
||||
"tx",
|
||||
"ty",
|
||||
"tz",
|
||||
"sx",
|
||||
"sy",
|
||||
"sz",
|
||||
"vb"
|
||||
};
|
||||
|
||||
constexpr const char* ModeNameMap[] = {
|
||||
"absolute",
|
||||
"additive",
|
||||
"relative"
|
||||
};
|
||||
|
||||
CurveNode.Properties.Emplace(CastPropertyId::String, "kp").SetString(PropertyNameMap[(uint32_t)Curve.Property]);
|
||||
CurveNode.Properties.Emplace(CastPropertyId::String, "m").SetString(ModeNameMap[(uint32_t)Curve.Mode]);
|
||||
|
||||
auto KeyframeValueProperty = CastPropertyId::Float;
|
||||
|
||||
switch (Curve.Property)
|
||||
{
|
||||
case CurveProperty::RotateQuaternion:
|
||||
KeyframeValueProperty = CastPropertyId::Vector4;
|
||||
break;
|
||||
|
||||
case CurveProperty::RotateX:
|
||||
case CurveProperty::RotateY:
|
||||
case CurveProperty::RotateZ:
|
||||
case CurveProperty::TranslateX:
|
||||
case CurveProperty::TranslateY:
|
||||
case CurveProperty::TranslateZ:
|
||||
case CurveProperty::ScaleX:
|
||||
case CurveProperty::ScaleY:
|
||||
case CurveProperty::ScaleZ:
|
||||
KeyframeValueProperty = CastPropertyId::Float;
|
||||
break;
|
||||
|
||||
case CurveProperty::Visibility:
|
||||
KeyframeValueProperty = CastPropertyId::Byte;
|
||||
break;
|
||||
}
|
||||
|
||||
auto KeyframeFrameProperty = CastPropertyId::Float;
|
||||
|
||||
if (Curve.IsFrameIntegral())
|
||||
{
|
||||
uint32_t LargestFrameIndex = 0;
|
||||
for (auto& KeyFrame : Curve.Keyframes)
|
||||
LargestFrameIndex = max(LargestFrameIndex, KeyFrame.Frame.Integer32);
|
||||
|
||||
if (LargestFrameIndex <= 0xFF)
|
||||
KeyframeFrameProperty = CastPropertyId::Byte;
|
||||
else if (LargestFrameIndex <= 0xFFFF)
|
||||
KeyframeFrameProperty = CastPropertyId::Short;
|
||||
else
|
||||
KeyframeFrameProperty = CastPropertyId::Integer32;
|
||||
}
|
||||
|
||||
auto& KeyFrameBuffer = CurveNode.Properties.Emplace(KeyframeFrameProperty, "kb");
|
||||
auto& KeyValueBuffer = CurveNode.Properties.Emplace(KeyframeValueProperty, "kv");
|
||||
|
||||
for (auto& KeyFrame : Curve.Keyframes)
|
||||
{
|
||||
switch (KeyframeFrameProperty)
|
||||
{
|
||||
case CastPropertyId::Float:
|
||||
KeyFrameBuffer.AddFloat(KeyFrame.Frame.Float);
|
||||
break;
|
||||
case CastPropertyId::Byte:
|
||||
KeyFrameBuffer.AddByte((uint8_t)KeyFrame.Frame.Integer32);
|
||||
break;
|
||||
case CastPropertyId::Short:
|
||||
KeyFrameBuffer.AddShort((uint16_t)KeyFrame.Frame.Integer32);
|
||||
break;
|
||||
case CastPropertyId::Integer32:
|
||||
KeyFrameBuffer.AddInteger32(KeyFrame.Frame.Integer32);
|
||||
break;
|
||||
}
|
||||
|
||||
switch (Curve.Property)
|
||||
{
|
||||
case CurveProperty::RotateQuaternion:
|
||||
KeyValueBuffer.AddVector4(KeyFrame.Value.Vector4);
|
||||
break;
|
||||
|
||||
case CurveProperty::RotateX:
|
||||
case CurveProperty::RotateY:
|
||||
case CurveProperty::RotateZ:
|
||||
case CurveProperty::TranslateX:
|
||||
case CurveProperty::TranslateY:
|
||||
case CurveProperty::TranslateZ:
|
||||
case CurveProperty::ScaleX:
|
||||
case CurveProperty::ScaleY:
|
||||
case CurveProperty::ScaleZ:
|
||||
KeyValueBuffer.AddFloat(KeyFrame.Value.Float);
|
||||
break;
|
||||
|
||||
case CurveProperty::Visibility:
|
||||
KeyValueBuffer.AddByte(KeyFrame.Value.Byte);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (auto& Notetrack : Animation.Notificiations)
|
||||
{
|
||||
auto& TrackNode = AnimNode.Children.Emplace(CastId::NotificationTrack, Hashing::XXHash::HashString(Notetrack.Key()));
|
||||
|
||||
TrackNode.Properties.Emplace(CastPropertyId::String, "n").SetString(Notetrack.Key());
|
||||
|
||||
auto& KeyBuffer = TrackNode.Properties.Emplace(CastPropertyId::Integer32, "kb");
|
||||
|
||||
for (auto& Key : Notetrack.Value())
|
||||
KeyBuffer.AddInteger32(Key);
|
||||
}
|
||||
|
||||
// Finally, serialize the node to the disk
|
||||
Root.Write(Writer);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CastAsset::ExportModel(const Model& Model, const string& Path)
|
||||
{
|
||||
auto Writer = IO::BinaryWriter(IO::File::Create(Path));
|
||||
|
||||
// Magic, version 1, one root node, no flags.
|
||||
Writer.Write<CastHeader>({ 0x74736163, 0x1, 0x1, 0x0 });
|
||||
|
||||
// This is the base of the virtual scene
|
||||
auto Root = CastNode(CastId::Root);
|
||||
auto& ModelNode = Root.Children.Emplace(CastId::Model, Hashing::XXHash::HashString("model"));
|
||||
auto& SkeletonNode = ModelNode.Children.Emplace(CastId::Skeleton, Hashing::XXHash::HashString("skeleton"));
|
||||
|
||||
auto BoneCount = Model.Bones.Count();
|
||||
|
||||
for (auto& Bone : Model.Bones)
|
||||
{
|
||||
auto& BoneNode = SkeletonNode.Children.Emplace(CastId::Bone);
|
||||
|
||||
BoneNode.Properties.Emplace(CastPropertyId::String, "n").SetString(Bone.Name());
|
||||
BoneNode.Properties.Emplace(CastPropertyId::Integer32, "p").AddInteger32(Bone.Parent());
|
||||
|
||||
if (Bone.GetFlag(Assets::BoneFlags::HasLocalSpaceMatrices))
|
||||
{
|
||||
BoneNode.Properties.Emplace(CastPropertyId::Vector3, "lp").AddVector3(Bone.LocalPosition());
|
||||
BoneNode.Properties.Emplace(CastPropertyId::Vector4, "lr").AddVector4(Bone.LocalRotation());
|
||||
}
|
||||
if (Bone.GetFlag(Assets::BoneFlags::HasGlobalSpaceMatrices))
|
||||
{
|
||||
BoneNode.Properties.Emplace(CastPropertyId::Vector3, "wp").AddVector3(Bone.GlobalPosition());
|
||||
BoneNode.Properties.Emplace(CastPropertyId::Vector4, "wr").AddVector4(Bone.GlobalRotation());
|
||||
}
|
||||
if (Bone.GetFlag(Assets::BoneFlags::HasScale))
|
||||
{
|
||||
BoneNode.Properties.Emplace(CastPropertyId::Vector3, "s").AddVector3(Bone.Scale());
|
||||
}
|
||||
}
|
||||
|
||||
Dictionary<uint32_t, uint64_t> MaterialHashMap;
|
||||
uint32_t MaterialIndex = 0;
|
||||
|
||||
for (auto& Mat : Model.Materials)
|
||||
{
|
||||
auto& MatNode = ModelNode.Children.Emplace(CastId::Material, Hashing::XXHash::HashString(Mat.Name));
|
||||
|
||||
MatNode.Properties.Emplace(CastPropertyId::String, "n").SetString(Mat.Name);
|
||||
MatNode.Properties.Emplace(CastPropertyId::String, "t").SetString("pbr");
|
||||
|
||||
for (auto& Kvp : Mat.Slots)
|
||||
{
|
||||
auto FileHash = Hashing::XXHash::HashString(Kvp.second.first);
|
||||
MatNode.Children.Emplace(CastId::File, FileHash).Properties.Emplace(CastPropertyId::String, "p").SetString(Kvp.second.first);
|
||||
|
||||
// Cast material property mapping
|
||||
constexpr const char* MaterialSlotNames[] =
|
||||
{
|
||||
"extra", // Invalid
|
||||
"albedo",
|
||||
"diffuse",
|
||||
"normal",
|
||||
"specular",
|
||||
"emissive",
|
||||
"gloss",
|
||||
"roughness",
|
||||
"ao",
|
||||
"cavity"
|
||||
};
|
||||
|
||||
MatNode.Properties.Emplace(CastPropertyId::Integer64, MaterialSlotNames[(uint32_t)Kvp.first]).AddInteger64(FileHash);
|
||||
}
|
||||
|
||||
MaterialHashMap.Add(MaterialIndex++, MatNode.Hash);
|
||||
}
|
||||
|
||||
uint32_t MeshIndex = 0;
|
||||
|
||||
for (auto& Mesh : Model.Meshes)
|
||||
{
|
||||
auto& MeshNode = ModelNode.Children.Emplace(CastId::Mesh, Hashing::XXHash::HashString(string::Format("mesh%02d", MeshIndex++)));
|
||||
|
||||
MeshNode.Properties.EmplaceBack(CastPropertyId::Vector3, "vp");
|
||||
MeshNode.Properties.EmplaceBack(CastPropertyId::Vector3, "vn");
|
||||
MeshNode.Properties.EmplaceBack(CastPropertyId::Integer32, "vc");
|
||||
|
||||
auto VertexCount = Mesh.Vertices.Count();
|
||||
|
||||
if (VertexCount <= 0xFF)
|
||||
MeshNode.Properties.EmplaceBack(CastPropertyId::Byte, "f");
|
||||
else if (VertexCount <= 0xFFFF)
|
||||
MeshNode.Properties.EmplaceBack(CastPropertyId::Short, "f");
|
||||
else
|
||||
MeshNode.Properties.EmplaceBack(CastPropertyId::Integer32, "f");
|
||||
|
||||
// Configure the uv layer count, and maximum influence
|
||||
MeshNode.Properties.Emplace(CastPropertyId::Byte, "ul").AddByte((uint8_t)Mesh.Vertices.UVLayerCount());
|
||||
MeshNode.Properties.Emplace(CastPropertyId::Byte, "mi").AddByte((uint8_t)Mesh.Vertices.WeightCount());
|
||||
|
||||
if (BoneCount <= 0xFF)
|
||||
MeshNode.Properties.Emplace(CastPropertyId::Byte, "wb");
|
||||
else if (BoneCount <= 0xFFFF)
|
||||
MeshNode.Properties.Emplace(CastPropertyId::Short, "wb");
|
||||
else
|
||||
MeshNode.Properties.Emplace(CastPropertyId::Integer32, "wb");
|
||||
|
||||
MeshNode.Properties.Emplace(CastPropertyId::Float, "wv");
|
||||
|
||||
List<CastProperty*> UVLayers;
|
||||
|
||||
for (uint8_t i = 0; i < Mesh.Vertices.UVLayerCount(); i++)
|
||||
MeshNode.Properties.EmplaceBack(CastPropertyId::Vector2, string::Format("u%d", i));
|
||||
|
||||
auto& VertexPositions = MeshNode.Properties[0];
|
||||
auto& VertexNormals = MeshNode.Properties[1];
|
||||
auto& VertexColors = MeshNode.Properties[2];
|
||||
auto& FaceIndices = MeshNode.Properties[3];
|
||||
auto& VertexWeightBones = MeshNode.Properties[6];
|
||||
auto& VertexWeightValues = MeshNode.Properties[7];
|
||||
|
||||
for (auto& Layer : MeshNode.Properties)
|
||||
{
|
||||
if (Layer.Name != "ul" && Layer.Name.StartsWith("u"))
|
||||
UVLayers.Add(&Layer);
|
||||
}
|
||||
|
||||
for (auto& Vertex : Mesh.Vertices)
|
||||
{
|
||||
VertexPositions.AddVector3(Vertex.Position());
|
||||
VertexNormals.AddVector3(Vertex.Normal());
|
||||
VertexColors.AddInteger32(*(uint32_t*)&Vertex.Color());
|
||||
|
||||
for (uint8_t i = 0; i < Mesh.Vertices.WeightCount(); i++)
|
||||
{
|
||||
if (BoneCount <= 0xFF)
|
||||
VertexWeightBones.AddByte((uint8_t)Vertex.Weights(i).Bone);
|
||||
else if (BoneCount <= 0xFFFF)
|
||||
VertexWeightBones.AddShort((uint16_t)Vertex.Weights(i).Bone);
|
||||
else
|
||||
VertexWeightBones.AddInteger32(Vertex.Weights(i).Bone);
|
||||
|
||||
VertexWeightValues.AddFloat(Vertex.Weights(i).Value);
|
||||
}
|
||||
|
||||
for (uint8_t i = 0; i < Mesh.Vertices.UVLayerCount(); i++)
|
||||
{
|
||||
UVLayers[i]->AddVector2(Vertex.UVLayers(i));
|
||||
}
|
||||
}
|
||||
|
||||
for (auto& Face : Mesh.Faces)
|
||||
{
|
||||
if (VertexCount <= 0xFF)
|
||||
{
|
||||
FaceIndices.AddByte((uint8_t)Face[2]);
|
||||
FaceIndices.AddByte((uint8_t)Face[1]);
|
||||
FaceIndices.AddByte((uint8_t)Face[0]);
|
||||
}
|
||||
else if (VertexCount <= 0xFFFF)
|
||||
{
|
||||
FaceIndices.AddShort((uint16_t)Face[2]);
|
||||
FaceIndices.AddShort((uint16_t)Face[1]);
|
||||
FaceIndices.AddShort((uint16_t)Face[0]);
|
||||
}
|
||||
else
|
||||
{
|
||||
FaceIndices.AddInteger32(Face[2]);
|
||||
FaceIndices.AddInteger32(Face[1]);
|
||||
FaceIndices.AddInteger32(Face[0]);
|
||||
}
|
||||
}
|
||||
|
||||
if (Mesh.MaterialIndices.Count() > 0 && Mesh.MaterialIndices[0] > -1)
|
||||
{
|
||||
MeshNode.Properties.Emplace(CastPropertyId::Integer64, "m").AddInteger64(MaterialHashMap[Mesh.MaterialIndices[0]]);
|
||||
}
|
||||
}
|
||||
|
||||
// Finally, serialize the node to the disk
|
||||
Root.Write(Writer);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
imstring CastAsset::ModelExtension()
|
||||
{
|
||||
return ".cast";
|
||||
}
|
||||
|
||||
imstring CastAsset::AnimationExtension()
|
||||
{
|
||||
return ".cast";
|
||||
}
|
||||
|
||||
ExporterScale CastAsset::ExportScale()
|
||||
{
|
||||
return ExporterScale::Default;
|
||||
}
|
||||
|
||||
bool CastAsset::SupportsAnimations()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CastAsset::SupportsModels()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
32
r5dev/thirdparty/cppnet/cppkore/CastAsset.h
vendored
Normal file
32
r5dev/thirdparty/cppnet/cppkore/CastAsset.h
vendored
Normal file
@ -0,0 +1,32 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include "Exporter.h"
|
||||
|
||||
namespace Assets::Exporters
|
||||
{
|
||||
class CastAsset : public Exporter
|
||||
{
|
||||
public:
|
||||
CastAsset() = default;
|
||||
~CastAsset() = default;
|
||||
|
||||
// Exports the given animation to the provided path.
|
||||
virtual bool ExportAnimation(const Animation& Animation, const string& Path);
|
||||
// Exports the given model to the provided path.
|
||||
virtual bool ExportModel(const Model& Model, const string& Path);
|
||||
|
||||
// Gets the file extension for this exporters model format.
|
||||
virtual imstring ModelExtension();
|
||||
// Gets the file extension for this exporters animation format.
|
||||
virtual imstring AnimationExtension();
|
||||
|
||||
// Gets the required scaling constant for this exporter.
|
||||
virtual ExporterScale ExportScale();
|
||||
|
||||
// Gets whether or not the exporter supports animation exporting.
|
||||
virtual bool SupportsAnimations();
|
||||
// Gets whether or not the exporter supports model exporting.
|
||||
virtual bool SupportsModels();
|
||||
};
|
||||
}
|
222
r5dev/thirdparty/cppnet/cppkore/CastNode.cpp
vendored
Normal file
222
r5dev/thirdparty/cppnet/cppkore/CastNode.cpp
vendored
Normal file
@ -0,0 +1,222 @@
|
||||
#include "stdafx.h"
|
||||
#include "CastNode.h"
|
||||
|
||||
namespace Assets::Exporters
|
||||
{
|
||||
CastProperty::CastProperty()
|
||||
: Identifier(CastPropertyId::Byte)
|
||||
{
|
||||
}
|
||||
|
||||
CastProperty::CastProperty(CastPropertyId Id, const char* Name)
|
||||
: Identifier(Id), Name(Name)
|
||||
{
|
||||
// All property names are lower-case
|
||||
this->Name = this->Name.ToLower();
|
||||
}
|
||||
|
||||
const uint32_t CastProperty::Length() const
|
||||
{
|
||||
switch (this->Identifier)
|
||||
{
|
||||
case CastPropertyId::Byte: return sizeof(CastPropertyHeader) + this->Name.Length() + (sizeof(uint8_t) * this->IntegralValues.Count());
|
||||
case CastPropertyId::Short: return sizeof(CastPropertyHeader) + this->Name.Length() + (sizeof(uint16_t) * this->IntegralValues.Count());
|
||||
case CastPropertyId::Integer32: return sizeof(CastPropertyHeader) + this->Name.Length() + (sizeof(uint32_t) * this->IntegralValues.Count());
|
||||
case CastPropertyId::Integer64: return sizeof(CastPropertyHeader) + this->Name.Length() + (sizeof(uint64_t) * this->IntegralValues.Count());
|
||||
case CastPropertyId::Float: return sizeof(CastPropertyHeader) + this->Name.Length() + (sizeof(float) * this->IntegralValues.Count());
|
||||
case CastPropertyId::Double: return sizeof(CastPropertyHeader) + this->Name.Length() + (sizeof(double) * this->IntegralValues.Count());
|
||||
case CastPropertyId::Vector2 : return sizeof(CastPropertyHeader) + this->Name.Length() + (sizeof(Math::Vector2) * this->IntegralValues.Count());
|
||||
case CastPropertyId::Vector3: return sizeof(CastPropertyHeader) + this->Name.Length() + (sizeof(Math::Vector3) * this->IntegralValues.Count());
|
||||
case CastPropertyId::Vector4: return sizeof(CastPropertyHeader) + this->Name.Length() + (sizeof(Math::Quaternion) * this->IntegralValues.Count());
|
||||
case CastPropertyId::String: return sizeof(CastPropertyHeader) + this->Name.Length() + (StringValue.Length() + sizeof(uint8_t));
|
||||
default: return 0;
|
||||
}
|
||||
}
|
||||
|
||||
void CastProperty::Write(IO::BinaryWriter& Writer) const
|
||||
{
|
||||
auto Size = (this->Identifier == CastPropertyId::String) ? 1 : this->IntegralValues.Count();
|
||||
Writer.Write<CastPropertyHeader>({this->Identifier, (uint16_t)this->Name.Length(), Size});
|
||||
Writer.Write(&this->Name[0], 0, this->Name.Length());
|
||||
|
||||
switch (this->Identifier)
|
||||
{
|
||||
case CastPropertyId::Byte:
|
||||
for (auto& Value : this->IntegralValues)
|
||||
Writer.Write<uint8_t>(Value.Byte);
|
||||
break;
|
||||
case CastPropertyId::Short:
|
||||
for (auto& Value : this->IntegralValues)
|
||||
Writer.Write<uint16_t>(Value.Short);
|
||||
break;
|
||||
case CastPropertyId::Integer32:
|
||||
for (auto& Value : this->IntegralValues)
|
||||
Writer.Write<uint32_t>(Value.Integer32);
|
||||
break;
|
||||
case CastPropertyId::Integer64:
|
||||
for (auto& Value : this->IntegralValues)
|
||||
Writer.Write<uint64_t>(Value.Integer64);
|
||||
break;
|
||||
case CastPropertyId::Float:
|
||||
for (auto& Value : this->IntegralValues)
|
||||
Writer.Write<float>(Value.Float);
|
||||
break;
|
||||
case CastPropertyId::Double:
|
||||
for (auto& Value : this->IntegralValues)
|
||||
Writer.Write<double>(Value.Double);
|
||||
break;
|
||||
case CastPropertyId::Vector2:
|
||||
for (auto& Value : this->IntegralValues)
|
||||
Writer.Write<Math::Vector2>(Value.Vector2);
|
||||
break;
|
||||
case CastPropertyId::Vector3:
|
||||
for (auto& Value : this->IntegralValues)
|
||||
Writer.Write<Math::Vector3>(Value.Vector3);
|
||||
break;
|
||||
case CastPropertyId::Vector4:
|
||||
for (auto& Value : this->IntegralValues)
|
||||
Writer.Write<Math::Quaternion>(Value.Vector4);
|
||||
break;
|
||||
case CastPropertyId::String:
|
||||
Writer.WriteCString(this->StringValue);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void CastProperty::AddByte(uint8_t Value)
|
||||
{
|
||||
this->IntegralValues.EmplaceBack(Value);
|
||||
}
|
||||
|
||||
void CastProperty::AddShort(uint16_t Value)
|
||||
{
|
||||
this->IntegralValues.EmplaceBack(Value);
|
||||
}
|
||||
|
||||
void CastProperty::AddInteger32(uint32_t Value)
|
||||
{
|
||||
this->IntegralValues.EmplaceBack(Value);
|
||||
}
|
||||
|
||||
void CastProperty::AddInteger64(uint64_t Value)
|
||||
{
|
||||
this->IntegralValues.EmplaceBack(Value);
|
||||
}
|
||||
|
||||
void CastProperty::AddFloat(float Value)
|
||||
{
|
||||
this->IntegralValues.EmplaceBack(Value);
|
||||
}
|
||||
|
||||
void CastProperty::AddDouble(double Value)
|
||||
{
|
||||
this->IntegralValues.EmplaceBack(Value);
|
||||
}
|
||||
|
||||
void CastProperty::AddVector2(Math::Vector2 Value)
|
||||
{
|
||||
this->IntegralValues.EmplaceBack(Value);
|
||||
}
|
||||
|
||||
void CastProperty::AddVector3(Math::Vector3 Value)
|
||||
{
|
||||
this->IntegralValues.EmplaceBack(Value);
|
||||
}
|
||||
|
||||
void CastProperty::AddVector4(Math::Quaternion Value)
|
||||
{
|
||||
this->IntegralValues.EmplaceBack(Value);
|
||||
}
|
||||
|
||||
void CastProperty::SetString(const string& Value)
|
||||
{
|
||||
this->StringValue = Value;
|
||||
}
|
||||
|
||||
CastNode::CastNode()
|
||||
: Identifier(CastId::Root), Hash(0)
|
||||
{
|
||||
}
|
||||
|
||||
CastNode::CastNode(CastId Id)
|
||||
: Identifier(Id), Hash(0)
|
||||
{
|
||||
}
|
||||
|
||||
CastNode::CastNode(CastId Id, uint64_t Hash)
|
||||
: Identifier(Id), Hash(Hash)
|
||||
{
|
||||
}
|
||||
|
||||
const uint32_t CastNode::Length() const
|
||||
{
|
||||
uint32_t Result = sizeof(CastNodeHeader);
|
||||
|
||||
for (auto& Child : this->Children)
|
||||
Result += Child.Length();
|
||||
for (auto& Property : this->Properties)
|
||||
Result += Property.Length();
|
||||
|
||||
return Result;
|
||||
}
|
||||
|
||||
void CastNode::Write(IO::BinaryWriter& Writer) const
|
||||
{
|
||||
Writer.Write<CastNodeHeader>({this->Identifier, this->Length(), this->Hash, this->Properties.Count(), this->Children.Count()});
|
||||
|
||||
for (auto& Prop : Properties)
|
||||
Prop.Write(Writer);
|
||||
for (auto& Child : Children)
|
||||
Child.Write(Writer);
|
||||
}
|
||||
|
||||
CastPropertyUnion::CastPropertyUnion()
|
||||
: Vector4(0,0,0,0)
|
||||
{
|
||||
}
|
||||
|
||||
CastPropertyUnion::CastPropertyUnion(uint8_t Value)
|
||||
: Byte(Value)
|
||||
{
|
||||
}
|
||||
|
||||
CastPropertyUnion::CastPropertyUnion(uint16_t Value)
|
||||
: Short(Value)
|
||||
{
|
||||
}
|
||||
|
||||
CastPropertyUnion::CastPropertyUnion(uint32_t Value)
|
||||
: Integer32(Value)
|
||||
{
|
||||
}
|
||||
|
||||
CastPropertyUnion::CastPropertyUnion(uint64_t Value)
|
||||
: Integer64(Value)
|
||||
{
|
||||
}
|
||||
|
||||
CastPropertyUnion::CastPropertyUnion(float Value)
|
||||
: Float(Value)
|
||||
{
|
||||
}
|
||||
|
||||
CastPropertyUnion::CastPropertyUnion(double Value)
|
||||
: Double(Value)
|
||||
{
|
||||
}
|
||||
|
||||
CastPropertyUnion::CastPropertyUnion(Math::Vector2 Value)
|
||||
: Vector2(Value)
|
||||
{
|
||||
}
|
||||
|
||||
CastPropertyUnion::CastPropertyUnion(Math::Vector3 Value)
|
||||
: Vector3(Value)
|
||||
{
|
||||
}
|
||||
|
||||
CastPropertyUnion::CastPropertyUnion(Math::Quaternion Value)
|
||||
: Vector4(Value)
|
||||
{
|
||||
}
|
||||
}
|
146
r5dev/thirdparty/cppnet/cppkore/CastNode.h
vendored
Normal file
146
r5dev/thirdparty/cppnet/cppkore/CastNode.h
vendored
Normal file
@ -0,0 +1,146 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include "Vector2.h"
|
||||
#include "Vector3.h"
|
||||
#include "Quaternion.h"
|
||||
#include "StringBase.h"
|
||||
#include "ListBase.h"
|
||||
#include "BinaryWriter.h"
|
||||
|
||||
namespace Assets::Exporters
|
||||
{
|
||||
enum class CastId : uint32_t
|
||||
{
|
||||
Root = 0x746F6F72,
|
||||
Model = 0x6C646F6D,
|
||||
Mesh = 0x6873656D,
|
||||
Skeleton = 0x6C656B73,
|
||||
Bone = 0x656E6F62,
|
||||
Animation = 0x6D696E61,
|
||||
Curve = 0x76727563,
|
||||
NotificationTrack = 0x6669746E,
|
||||
Material = 0x6C74616D,
|
||||
File = 0x656C6966,
|
||||
};
|
||||
|
||||
enum class CastPropertyId : uint16_t
|
||||
{
|
||||
Byte = 'b', // <uint8_t>
|
||||
Short = 'h', // <uint16_t>
|
||||
Integer32 = 'i', // <uint32_t>
|
||||
Integer64 = 'l', // <uint64_t>
|
||||
|
||||
Float = 'f', // <float>
|
||||
Double = 'd', // <double>
|
||||
|
||||
String = 's', // Null terminated UTF-8 string
|
||||
|
||||
Vector2 = 'v2', // Float precision vector XY
|
||||
Vector3 = 'v3', // Float precision vector XYZ
|
||||
Vector4 = 'v4' // Float precision vector XYZW
|
||||
};
|
||||
|
||||
struct CastNodeHeader
|
||||
{
|
||||
CastId Identifier; // Used to signify which class this node uses
|
||||
uint32_t NodeSize; // Size of all data and sub data following the node
|
||||
uint64_t NodeHash; // Unique hash, like an id, used to link nodes together
|
||||
uint32_t PropertyCount; // The count of properties
|
||||
uint32_t ChildCount; // The count of direct children nodes
|
||||
|
||||
// We must read until the node size hits, and that means we are done.
|
||||
// The nodes are in a stack layout, so it's easy to load, FILO order.
|
||||
};
|
||||
|
||||
struct CastPropertyHeader
|
||||
{
|
||||
CastPropertyId Identifier; // The element type of this property
|
||||
uint16_t NameSize; // The size of the name of this property
|
||||
uint32_t ArrayLength; // The number of elements this property contains (1 for single)
|
||||
|
||||
// Following is UTF-8 string lowercase, size of namesize, NOT null terminated
|
||||
// cast_property[ArrayLength] array of data
|
||||
};
|
||||
|
||||
union CastPropertyUnion
|
||||
{
|
||||
uint8_t Byte;
|
||||
uint16_t Short;
|
||||
uint32_t Integer32;
|
||||
uint64_t Integer64;
|
||||
|
||||
float Float;
|
||||
double Double;
|
||||
|
||||
Math::Vector2 Vector2;
|
||||
Math::Vector3 Vector3;
|
||||
Math::Quaternion Vector4;
|
||||
|
||||
CastPropertyUnion();
|
||||
|
||||
explicit CastPropertyUnion(uint8_t Value);
|
||||
explicit CastPropertyUnion(uint16_t Value);
|
||||
explicit CastPropertyUnion(uint32_t Value);
|
||||
explicit CastPropertyUnion(uint64_t Value);
|
||||
explicit CastPropertyUnion(float Value);
|
||||
explicit CastPropertyUnion(double Value);
|
||||
explicit CastPropertyUnion(Math::Vector2 Value);
|
||||
explicit CastPropertyUnion(Math::Vector3 Value);
|
||||
explicit CastPropertyUnion(Math::Quaternion Value);
|
||||
};
|
||||
|
||||
static_assert(sizeof(CastNodeHeader) == 0x18, "CastNode header size mismatch");
|
||||
static_assert(sizeof(CastPropertyHeader) == 0x8, "CastProperty header size mismatch");
|
||||
static_assert(sizeof(CastPropertyUnion) == 0x10, "CastProperty union size mismatch");
|
||||
|
||||
class CastProperty
|
||||
{
|
||||
public:
|
||||
CastProperty();
|
||||
explicit CastProperty(CastPropertyId Id, const char* Name);
|
||||
|
||||
const uint32_t Length() const;
|
||||
|
||||
void Write(IO::BinaryWriter& Writer) const;
|
||||
|
||||
void AddByte(uint8_t Value);
|
||||
void AddShort(uint16_t Value);
|
||||
void AddInteger32(uint32_t Value);
|
||||
void AddInteger64(uint64_t Value);
|
||||
|
||||
void AddFloat(float Value);
|
||||
void AddDouble(double Value);
|
||||
|
||||
void AddVector2(Math::Vector2 Value);
|
||||
void AddVector3(Math::Vector3 Value);
|
||||
void AddVector4(Math::Quaternion Value);
|
||||
|
||||
void SetString(const string& Value);
|
||||
|
||||
CastPropertyId Identifier;
|
||||
string Name;
|
||||
|
||||
private:
|
||||
List<CastPropertyUnion> IntegralValues;
|
||||
string StringValue;
|
||||
};
|
||||
|
||||
class CastNode
|
||||
{
|
||||
public:
|
||||
CastNode();
|
||||
CastNode(CastId Id);
|
||||
CastNode(CastId Id, uint64_t Hash);
|
||||
|
||||
const uint32_t Length() const;
|
||||
|
||||
void Write(IO::BinaryWriter& Writer) const;
|
||||
|
||||
CastId Identifier;
|
||||
uint64_t Hash;
|
||||
|
||||
List<CastProperty> Properties;
|
||||
List<CastNode> Children;
|
||||
};
|
||||
}
|
17
r5dev/thirdparty/cppnet/cppkore/CharacterCasing.h
vendored
Normal file
17
r5dev/thirdparty/cppnet/cppkore/CharacterCasing.h
vendored
Normal file
@ -0,0 +1,17 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
namespace Forms
|
||||
{
|
||||
// Specifies the case of characters in a Textbox control.
|
||||
enum class CharacterCasing
|
||||
{
|
||||
// The case of characters is left unchanged.
|
||||
Normal = 0,
|
||||
// Converts all characters to uppercase.
|
||||
Upper = 1,
|
||||
// Converts all characters to lowercase.
|
||||
Lower = 2,
|
||||
};
|
||||
}
|
188
r5dev/thirdparty/cppnet/cppkore/CheckBox.cpp
vendored
Normal file
188
r5dev/thirdparty/cppnet/cppkore/CheckBox.cpp
vendored
Normal file
@ -0,0 +1,188 @@
|
||||
#include "stdafx.h"
|
||||
#include "CheckBox.h"
|
||||
|
||||
namespace Forms
|
||||
{
|
||||
CheckBox::CheckBox()
|
||||
: ButtonBase(), _AutoCheck(true), _ThreeState(false), _Appearence(Appearence::Normal), _CheckState(CheckState::Unchecked)
|
||||
{
|
||||
SetStyle(ControlStyles::StandardClick | ControlStyles::StandardDoubleClick, false);
|
||||
this->SetTextAlign(Drawing::ContentAlignment::MiddleLeft);
|
||||
|
||||
// We are a checkbox control
|
||||
this->_RTTI = ControlTypes::CheckBox;
|
||||
}
|
||||
|
||||
Appearence CheckBox::GetAppearence()
|
||||
{
|
||||
return this->_Appearence;
|
||||
}
|
||||
|
||||
void CheckBox::SetAppearence(Appearence Value)
|
||||
{
|
||||
if (this->_Appearence != Value)
|
||||
{
|
||||
this->_Appearence = Value;
|
||||
|
||||
if (this->_OwnerDraw)
|
||||
Refresh();
|
||||
else
|
||||
UpdateStyles();
|
||||
|
||||
OnAppearenceChanged();
|
||||
}
|
||||
}
|
||||
|
||||
bool CheckBox::AutoCheck()
|
||||
{
|
||||
return this->_AutoCheck;
|
||||
}
|
||||
|
||||
void CheckBox::SetAutoCheck(bool Value)
|
||||
{
|
||||
this->_AutoCheck = Value;
|
||||
}
|
||||
|
||||
bool CheckBox::Checked()
|
||||
{
|
||||
return _CheckState != CheckState::Unchecked;
|
||||
}
|
||||
|
||||
void CheckBox::SetChecked(bool Value)
|
||||
{
|
||||
this->SetCheckState((Value) ? CheckState::Checked : CheckState::Unchecked);
|
||||
}
|
||||
|
||||
CheckState CheckBox::GetCheckState()
|
||||
{
|
||||
return _CheckState;
|
||||
}
|
||||
|
||||
void CheckBox::SetCheckState(CheckState Value)
|
||||
{
|
||||
if (_CheckState != Value)
|
||||
{
|
||||
bool oChecked = Checked();
|
||||
|
||||
_CheckState = Value;
|
||||
|
||||
if (GetState(ControlStates::StateCreated))
|
||||
SendMessageA(this->_Handle, BM_SETCHECK, (int)_CheckState, 0);
|
||||
|
||||
if (oChecked != Checked())
|
||||
{
|
||||
OnCheckedChanged();
|
||||
}
|
||||
|
||||
OnCheckStateChanged();
|
||||
}
|
||||
}
|
||||
|
||||
bool CheckBox::ThreeState()
|
||||
{
|
||||
return _ThreeState;
|
||||
}
|
||||
|
||||
void CheckBox::SetThreeState(bool Value)
|
||||
{
|
||||
_ThreeState = Value;
|
||||
}
|
||||
|
||||
void CheckBox::OnClick()
|
||||
{
|
||||
if (_AutoCheck)
|
||||
{
|
||||
switch (_CheckState)
|
||||
{
|
||||
case CheckState::Unchecked:
|
||||
SetCheckState(CheckState::Checked);
|
||||
break;
|
||||
case CheckState::Checked:
|
||||
if (_ThreeState)
|
||||
SetCheckState(CheckState::Indeterminate);
|
||||
else
|
||||
SetCheckState(CheckState::Unchecked);
|
||||
break;
|
||||
default:
|
||||
SetCheckState(CheckState::Unchecked);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Call base event last
|
||||
ButtonBase::OnClick();
|
||||
}
|
||||
|
||||
void CheckBox::OnAppearenceChanged()
|
||||
{
|
||||
AppearenceChanged.RaiseEvent(this);
|
||||
}
|
||||
|
||||
void CheckBox::OnCheckedChanged()
|
||||
{
|
||||
CheckedChanged.RaiseEvent(this);
|
||||
}
|
||||
|
||||
void CheckBox::OnCheckStateChanged()
|
||||
{
|
||||
if (this->_OwnerDraw)
|
||||
Refresh();
|
||||
|
||||
CheckStateChanged.RaiseEvent(this);
|
||||
}
|
||||
|
||||
void CheckBox::OnHandleCreated()
|
||||
{
|
||||
SendMessageA(this->_Handle, BM_SETCHECK, (int)_CheckState, NULL);
|
||||
|
||||
// We must call base event last
|
||||
Control::OnHandleCreated();
|
||||
}
|
||||
|
||||
void CheckBox::OnMouseUp(const std::unique_ptr<MouseEventArgs>& EventArgs)
|
||||
{
|
||||
if (EventArgs->Button == MouseButtons::Left && GetFlag(ButtonFlags::FlagMousePressed))
|
||||
{
|
||||
if (GetFlag(ButtonFlags::FlagMouseDown))
|
||||
{
|
||||
auto Pt = PointToScreen({ (INT)EventArgs->X, (INT)EventArgs->Y });
|
||||
|
||||
POINT nPt;
|
||||
nPt.x = Pt.X;
|
||||
nPt.y = Pt.Y;
|
||||
|
||||
if (WindowFromPoint(nPt) == this->_Handle)
|
||||
{
|
||||
ResetFlagsAndPaint();
|
||||
|
||||
if (this->Capture())
|
||||
OnClick();
|
||||
|
||||
OnMouseClick(EventArgs);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Call base event last
|
||||
ButtonBase::OnMouseUp(EventArgs);
|
||||
}
|
||||
|
||||
CreateParams CheckBox::GetCreateParams()
|
||||
{
|
||||
auto Cp = ButtonBase::GetCreateParams();
|
||||
|
||||
Cp.ClassName = "BUTTON";
|
||||
|
||||
if (GetStyle(ControlStyles::UserPaint))
|
||||
Cp.Style |= BS_OWNERDRAW;
|
||||
else
|
||||
{
|
||||
Cp.Style |= BS_3STATE;
|
||||
|
||||
if (this->_Appearence == Appearence::Button)
|
||||
Cp.Style |= BS_PUSHLIKE;
|
||||
}
|
||||
|
||||
return Cp;
|
||||
}
|
||||
}
|
72
r5dev/thirdparty/cppnet/cppkore/CheckBox.h
vendored
Normal file
72
r5dev/thirdparty/cppnet/cppkore/CheckBox.h
vendored
Normal file
@ -0,0 +1,72 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include "Control.h"
|
||||
#include "Appearence.h"
|
||||
#include "ButtonBase.h"
|
||||
#include "CheckState.h"
|
||||
#include "ContentAlignment.h"
|
||||
|
||||
namespace Forms
|
||||
{
|
||||
// Represents a Windows check box.
|
||||
class CheckBox : public ButtonBase
|
||||
{
|
||||
public:
|
||||
CheckBox();
|
||||
virtual ~CheckBox() = default;
|
||||
|
||||
// Gets the value that determines the appearance of a check box control.
|
||||
Appearence GetAppearence();
|
||||
// Sets the value that determines the appearance of a check box control.
|
||||
void SetAppearence(Appearence Value);
|
||||
|
||||
// Gets a value indicating whether the check box automatically checks itself.
|
||||
bool AutoCheck();
|
||||
// Sets a value indicating whether the check box automatically checks itself.
|
||||
void SetAutoCheck(bool Value);
|
||||
|
||||
// Gets a value indicating whether the check box is checked.
|
||||
bool Checked();
|
||||
// Sets a value indicating whether the check box is checked.
|
||||
void SetChecked(bool Value);
|
||||
|
||||
// Gets a value indicating whether the check box is checked.
|
||||
CheckState GetCheckState();
|
||||
// Sets a value indicating whether the check box is checked.
|
||||
void SetCheckState(CheckState Value);
|
||||
|
||||
// Gets a value indicating whether the check box will allow three check states rather than two.
|
||||
bool ThreeState();
|
||||
// Sets a value indicating whether the check box will allow three check states rather than two.
|
||||
void SetThreeState(bool Value);
|
||||
|
||||
// We must define base events here
|
||||
virtual void OnClick();
|
||||
virtual void OnAppearenceChanged();
|
||||
virtual void OnCheckedChanged();
|
||||
virtual void OnCheckStateChanged();
|
||||
virtual void OnHandleCreated();
|
||||
virtual void OnMouseUp(const std::unique_ptr<MouseEventArgs>& EventArgs);
|
||||
|
||||
// We must define event handlers here
|
||||
EventBase<void(*)(Control*)> AppearenceChanged;
|
||||
EventBase<void(*)(Control*)> CheckedChanged;
|
||||
EventBase<void(*)(Control*)> CheckStateChanged;
|
||||
|
||||
protected:
|
||||
// Get custom control creation parameters for this instance.
|
||||
virtual CreateParams GetCreateParams();
|
||||
|
||||
private:
|
||||
// Whether or not the control handles checking itself.
|
||||
bool _AutoCheck;
|
||||
// Whether or not the control handles three checked states.
|
||||
bool _ThreeState;
|
||||
|
||||
// The appearence of the control.
|
||||
Appearence _Appearence;
|
||||
// The checked state of the control.
|
||||
CheckState _CheckState;
|
||||
};
|
||||
}
|
92
r5dev/thirdparty/cppnet/cppkore/CheckBoxImage.h
vendored
Normal file
92
r5dev/thirdparty/cppnet/cppkore/CheckBoxImage.h
vendored
Normal file
@ -0,0 +1,92 @@
|
||||
#pragma once
|
||||
|
||||
constexpr const unsigned char CheckBoxImage_Src[] =
|
||||
{
|
||||
0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x10, 0x00, 0x10, 0x00, 0x20, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x0E, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x59, 0xFF, 0xFF,
|
||||
0xFF, 0xFD, 0xFF, 0xFF, 0xFF, 0x6C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x49, 0xFF, 0xFF,
|
||||
0xFF, 0xFA, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF,
|
||||
0xFF, 0x63, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x3B, 0xFF, 0xFF,
|
||||
0xFF, 0xF6, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0xFF, 0xFF, 0xFF, 0x5B, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x2F, 0xFF, 0xFF,
|
||||
0xFF, 0xEF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF9, 0xFF, 0xFF,
|
||||
0xFF, 0x7E, 0xFF, 0xFF, 0xFF, 0xEF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFC, 0xFF, 0xFF, 0xFF, 0x53, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x24, 0xFF, 0xFF,
|
||||
0xFF, 0xE8, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0xFF, 0xFF,
|
||||
0xFF, 0x56, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x37, 0xFF, 0xFF,
|
||||
0xFF, 0xF2, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFA, 0xFF, 0xFF,
|
||||
0xFF, 0x4B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF,
|
||||
0xFF, 0xD4, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x3E, 0xFF, 0xFF, 0xFF, 0xF5, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0xFF, 0xFF, 0xFF, 0x44, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x8B, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF,
|
||||
0xFF, 0x44, 0xFF, 0xFF, 0xFF, 0xF8, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xF5, 0xFF, 0xFF, 0xFF, 0x3D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF,
|
||||
0xFF, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x4B, 0xFF, 0xFF,
|
||||
0xFF, 0xFA, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF2, 0xFF, 0xFF,
|
||||
0xFF, 0x37, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x53, 0xFF, 0xFF, 0xFF, 0xFC, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xEF, 0xFF, 0xFF, 0xFF, 0x31, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF,
|
||||
0xFF, 0x5B, 0xFF, 0xFF, 0xFF, 0xFD, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xEB, 0xFF, 0xFF, 0xFF, 0x2B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x63, 0xFF, 0xFF,
|
||||
0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC8, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x6C, 0xFF, 0xFF, 0xFF, 0xF7, 0xFF, 0xFF,
|
||||
0xFF, 0x6B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
};
|
19
r5dev/thirdparty/cppnet/cppkore/CheckState.h
vendored
Normal file
19
r5dev/thirdparty/cppnet/cppkore/CheckState.h
vendored
Normal file
@ -0,0 +1,19 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
namespace Forms
|
||||
{
|
||||
// Specifies the state of a control,
|
||||
// such as a check box, that can be checked, unchecked, or
|
||||
// set to an indeterminate state.
|
||||
enum class CheckState
|
||||
{
|
||||
// The control is unchecked.
|
||||
Unchecked = 0,
|
||||
// The control is checked.
|
||||
Checked = 1,
|
||||
// The control is indeterminate. An indeterminate control generally has a shaded appearance.
|
||||
Indeterminate = 2
|
||||
};
|
||||
}
|
25
r5dev/thirdparty/cppnet/cppkore/CloseReason.h
vendored
Normal file
25
r5dev/thirdparty/cppnet/cppkore/CloseReason.h
vendored
Normal file
@ -0,0 +1,25 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
namespace Forms
|
||||
{
|
||||
// Specifies the reason for the Form Closing.
|
||||
enum class CloseReason
|
||||
{
|
||||
// No reason for closure of the Form.
|
||||
None = 0,
|
||||
// In the process of shutting down, Windows has closed the application.
|
||||
WindowsShutDown = 1,
|
||||
// The parent form of this MDI form is closing.
|
||||
MdiFormClosing = 2,
|
||||
// The user has clicked the close button on the form window, selected Close from the window's control menu or hit Alt + F4
|
||||
UserClosing = 3,
|
||||
// The Microsoft Windows Task Manager is closing the application.
|
||||
TaskManagerClosing = 4,
|
||||
// A form is closing because its owner is closing.
|
||||
FormOwnerClosing = 5,
|
||||
// A form is closing because Application.Exit() was called.
|
||||
ApplicationExitCall = 6
|
||||
};
|
||||
}
|
251
r5dev/thirdparty/cppnet/cppkore/CoDXAssetExport.cpp
vendored
Normal file
251
r5dev/thirdparty/cppnet/cppkore/CoDXAssetExport.cpp
vendored
Normal file
@ -0,0 +1,251 @@
|
||||
#include "stdafx.h"
|
||||
#include "CoDXAssetExport.h"
|
||||
|
||||
#include "File.h"
|
||||
#include "Path.h"
|
||||
#include "Matrix.h"
|
||||
#include "StreamWriter.h"
|
||||
|
||||
namespace Assets::Exporters
|
||||
{
|
||||
bool CoDXAssetExport::ExportAnimation(const Animation& Animation, const string& Path)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CoDXAssetExport::ExportModel(const Model& Model, const string& Path)
|
||||
{
|
||||
auto Writer = IO::StreamWriter(IO::File::Create(Path));
|
||||
|
||||
Writer.WriteLine(
|
||||
"MODEL\nVERSION 6\n"
|
||||
);
|
||||
|
||||
Writer.WriteLineFmt("NUMBONES %d", Model.Bones.Count());
|
||||
|
||||
uint32_t BoneIndex = 0;
|
||||
|
||||
for (auto& Bone : Model.Bones)
|
||||
{
|
||||
Writer.WriteLineFmt("BONE %d %d \"%s\"", BoneIndex, Bone.Parent(), (char*)Bone.Name());
|
||||
BoneIndex++;
|
||||
}
|
||||
|
||||
Writer.Write("\n");
|
||||
BoneIndex = 0;
|
||||
|
||||
for (auto& Bone : Model.Bones)
|
||||
{
|
||||
auto Rotation = ::Math::Matrix::CreateFromQuaternion(Bone.GlobalRotation());
|
||||
|
||||
auto& Position = Bone.GlobalPosition();
|
||||
auto& Scale = Bone.Scale();
|
||||
|
||||
Writer.WriteLineFmt(
|
||||
"BONE %d\n"
|
||||
"OFFSET %f, %f, %f\n"
|
||||
"SCALE %f, %f, %f\n"
|
||||
"X %f, %f, %f\n"
|
||||
"Y %f, %f, %f\n"
|
||||
"Z %f, %f, %f\n",
|
||||
BoneIndex,
|
||||
Position.X, Position.Y, Position.Z,
|
||||
Scale.X, Scale.Y, Scale.Z,
|
||||
MathHelper::Clamp(Rotation.Mat(0, 0), -1.f, 1.f), MathHelper::Clamp(Rotation.Mat(0, 1), -1.f, 1.f), MathHelper::Clamp(Rotation.Mat(0, 2), -1.f, 1.f),
|
||||
MathHelper::Clamp(Rotation.Mat(1, 0), -1.f, 1.f), MathHelper::Clamp(Rotation.Mat(1, 1), -1.f, 1.f), MathHelper::Clamp(Rotation.Mat(1, 2), -1.f, 1.f),
|
||||
MathHelper::Clamp(Rotation.Mat(2, 0), -1.f, 1.f), MathHelper::Clamp(Rotation.Mat(2, 1), -1.f, 1.f), MathHelper::Clamp(Rotation.Mat(2, 2), -1.f, 1.f)
|
||||
);
|
||||
|
||||
BoneIndex++;
|
||||
}
|
||||
|
||||
auto TotalVertexCount = Model.VertexCount();
|
||||
auto TotalFaceCount = Model.FaceCount();
|
||||
|
||||
if (TotalVertexCount > UINT16_MAX)
|
||||
Writer.WriteLineFmt("NUMVERTS32 %d", TotalVertexCount);
|
||||
else
|
||||
Writer.WriteLineFmt("NUMVERTS %d", TotalVertexCount);
|
||||
|
||||
uint32_t VertexIndex = 0;
|
||||
|
||||
for (auto& Submesh : Model.Meshes)
|
||||
{
|
||||
for (auto& Vertex : Submesh.Vertices)
|
||||
{
|
||||
auto& Position = Vertex.Position();
|
||||
|
||||
if (TotalVertexCount > UINT16_MAX)
|
||||
Writer.WriteLineFmt(
|
||||
"VERT32 %d\n"
|
||||
"OFFSET %f, %f, %f",
|
||||
VertexIndex,
|
||||
Position.X, Position.Y, Position.Z
|
||||
);
|
||||
else
|
||||
Writer.WriteLineFmt(
|
||||
"VERT %d\n"
|
||||
"OFFSET %f, %f, %f",
|
||||
VertexIndex,
|
||||
Position.X, Position.Y, Position.Z
|
||||
);
|
||||
|
||||
if (Vertex.WeightCount() == 1)
|
||||
Writer.WriteLineFmt(
|
||||
"BONES 1\n"
|
||||
"BONE %d 1.0\n",
|
||||
Vertex.Weights(0).Bone
|
||||
);
|
||||
else
|
||||
{
|
||||
Writer.WriteLineFmt("BONES %d", Vertex.WeightCount());
|
||||
|
||||
for (uint8_t i = 0; i < Vertex.WeightCount(); i++)
|
||||
Writer.WriteLineFmt("BONE %d %f", Vertex.Weights(i).Bone, Vertex.Weights(i).Value);
|
||||
|
||||
Writer.Write("\n");
|
||||
}
|
||||
|
||||
VertexIndex++;
|
||||
}
|
||||
}
|
||||
|
||||
Writer.WriteLineFmt("NUMFACES %d", TotalFaceCount);
|
||||
|
||||
uint32_t SubmeshIndex = 0;
|
||||
VertexIndex = 0;
|
||||
|
||||
for (auto& Submesh : Model.Meshes)
|
||||
{
|
||||
for (auto& Face : Submesh.Faces)
|
||||
{
|
||||
if (SubmeshIndex > UINT8_MAX || Submesh.MaterialIndices[0] > UINT8_MAX)
|
||||
Writer.WriteLineFmt("TRI16 %d %d 0 0", SubmeshIndex, Submesh.MaterialIndices[0]);
|
||||
else
|
||||
Writer.WriteLineFmt("TRI %d %d 0 0", SubmeshIndex, Submesh.MaterialIndices[0]);
|
||||
|
||||
//
|
||||
// Face vertex [2]
|
||||
//
|
||||
|
||||
Writer.WriteLineFmt((TotalVertexCount > UINT16_MAX) ? "VERT32 %d" : "VERT %d", (Face[2] + VertexIndex));
|
||||
|
||||
auto& Face1Normal = Submesh.Vertices[Face[2]].Normal();
|
||||
auto& Face1Color = Submesh.Vertices[Face[2]].Color();
|
||||
|
||||
Writer.WriteFmt(
|
||||
"NORMAL %f %f %f\n"
|
||||
"COLOR %f %f %f %f\n"
|
||||
"UV %d",
|
||||
Face1Normal.X, Face1Normal.Y, Face1Normal.Z,
|
||||
Face1Color[0], Face1Color[1], Face1Color[2], Face1Color[3],
|
||||
Submesh.Vertices.UVLayerCount()
|
||||
);
|
||||
|
||||
for (uint8_t i = 0; i < Submesh.Vertices.UVLayerCount(); i++)
|
||||
Writer.WriteFmt(" %f %f", Submesh.Vertices[Face[2]].UVLayers(i).U, Submesh.Vertices[Face[2]].UVLayers(i).V);
|
||||
Writer.Write("\n");
|
||||
|
||||
//
|
||||
// Face vertex [0]
|
||||
//
|
||||
|
||||
Writer.WriteLineFmt((TotalVertexCount > UINT16_MAX) ? "VERT32 %d" : "VERT %d", (Face[0] + VertexIndex));
|
||||
|
||||
auto& Face2Normal = Submesh.Vertices[Face[0]].Normal();
|
||||
auto& Face2Color = Submesh.Vertices[Face[0]].Color();
|
||||
|
||||
Writer.WriteFmt(
|
||||
"NORMAL %f %f %f\n"
|
||||
"COLOR %f %f %f %f\n"
|
||||
"UV %d",
|
||||
Face2Normal.X, Face2Normal.Y, Face2Normal.Z,
|
||||
Face2Color[0], Face2Color[1], Face2Color[2], Face2Color[3],
|
||||
Submesh.Vertices.UVLayerCount()
|
||||
);
|
||||
|
||||
for (uint8_t i = 0; i < Submesh.Vertices.UVLayerCount(); i++)
|
||||
Writer.WriteFmt(" %f %f", Submesh.Vertices[Face[0]].UVLayers(i).U, Submesh.Vertices[Face[0]].UVLayers(i).V);
|
||||
Writer.Write("\n");
|
||||
|
||||
//
|
||||
// Face vertex [1]
|
||||
//
|
||||
|
||||
Writer.WriteLineFmt((TotalVertexCount > UINT16_MAX) ? "VERT32 %d" : "VERT %d", (Face[1] + VertexIndex));
|
||||
|
||||
auto& Face3Normal = Submesh.Vertices[Face[1]].Normal();
|
||||
auto& Face3Color = Submesh.Vertices[Face[1]].Color();
|
||||
|
||||
Writer.WriteFmt(
|
||||
"NORMAL %f %f %f\n"
|
||||
"COLOR %f %f %f %f\n"
|
||||
"UV %d",
|
||||
Face3Normal.X, Face3Normal.Y, Face3Normal.Z,
|
||||
Face3Color[0], Face3Color[1], Face3Color[2], Face3Color[3],
|
||||
Submesh.Vertices.UVLayerCount()
|
||||
);
|
||||
|
||||
for (uint8_t i = 0; i < Submesh.Vertices.UVLayerCount(); i++)
|
||||
Writer.WriteFmt(" %f %f", Submesh.Vertices[Face[1]].UVLayers(i).U, Submesh.Vertices[Face[1]].UVLayers(i).V);
|
||||
Writer.Write("\n");
|
||||
}
|
||||
|
||||
VertexIndex += Submesh.Vertices.Count();
|
||||
SubmeshIndex++;
|
||||
}
|
||||
|
||||
Writer.WriteLineFmt("\nNUMOBJECTS %d", Model.Meshes.Count());
|
||||
SubmeshIndex = 0;
|
||||
|
||||
for (auto& Submesh : Model.Meshes)
|
||||
Writer.WriteLineFmt("OBJECT %d \"KoreMesh_%d\"", SubmeshIndex, SubmeshIndex++);
|
||||
Writer.Write("\n");
|
||||
|
||||
Writer.WriteLineFmt("NUMMATERIALS %d", Model.Materials.Count());
|
||||
|
||||
uint32_t MaterialIndex = 0;
|
||||
|
||||
for (auto& Material : Model.Materials)
|
||||
{
|
||||
Writer.WriteFmt("MATERIAL %d \"%s\" \"Phong\" \"", MaterialIndex, (char*)Material.Name);
|
||||
|
||||
if (Material.Slots.ContainsKey(MaterialSlotType::Albedo))
|
||||
Writer.WriteFmt("color:%s", (char*)Material.Slots[MaterialSlotType::Albedo].first);
|
||||
else if (Material.Slots.ContainsKey(MaterialSlotType::Diffuse))
|
||||
Writer.WriteFmt("color:%s", (char*)Material.Slots[MaterialSlotType::Diffuse].first);
|
||||
|
||||
Writer.WriteLine("\"\nCOLOR 0.000000 0.000000 0.000000 1.000000\nTRANSPARENCY 0.000000 0.000000 0.000000 1.000000\nAMBIENTCOLOR 1.000000 1.000000 1.000000 1.000000\nINCANDESCENCE 0.000000 0.000000 0.000000 1.000000\nCOEFFS 0.800000 0.000000\nGLOW 0.000000 0\nREFRACTIVE 6 1.000000\nSPECULARCOLOR 0.500000 0.500000 0.500000 1.000000\nREFLECTIVECOLOR 0.000000 0.000000 0.000000 1.000000\nREFLECTIVE 1 0.500000\nBLINN -1.000000 -1.000000\nPHONG 20.000000");
|
||||
|
||||
MaterialIndex++;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
imstring CoDXAssetExport::ModelExtension()
|
||||
{
|
||||
return ".xmodel_export";
|
||||
}
|
||||
|
||||
imstring CoDXAssetExport::AnimationExtension()
|
||||
{
|
||||
return ".xanim_export";
|
||||
}
|
||||
|
||||
ExporterScale CoDXAssetExport::ExportScale()
|
||||
{
|
||||
// Call of Duty uses inches as the primary scale constant.
|
||||
return ExporterScale::Inch;
|
||||
}
|
||||
|
||||
bool CoDXAssetExport::SupportsAnimations()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CoDXAssetExport::SupportsModels()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
33
r5dev/thirdparty/cppnet/cppkore/CoDXAssetExport.h
vendored
Normal file
33
r5dev/thirdparty/cppnet/cppkore/CoDXAssetExport.h
vendored
Normal file
@ -0,0 +1,33 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include "Exporter.h"
|
||||
|
||||
namespace Assets::Exporters
|
||||
{
|
||||
// The Call of Duty XAsset Export exporter
|
||||
class CoDXAssetExport : public Exporter
|
||||
{
|
||||
public:
|
||||
CoDXAssetExport() = default;
|
||||
~CoDXAssetExport() = default;
|
||||
|
||||
// Exports the given animation to the provided path.
|
||||
virtual bool ExportAnimation(const Animation& Animation, const string& Path);
|
||||
// Exports the given model to the provided path.
|
||||
virtual bool ExportModel(const Model& Model, const string& Path);
|
||||
|
||||
// Gets the file extension for this exporters model format.
|
||||
virtual imstring ModelExtension();
|
||||
// Gets the file extension for this exporters animation format.
|
||||
virtual imstring AnimationExtension();
|
||||
|
||||
// Gets the required scaling constant for this exporter.
|
||||
virtual ExporterScale ExportScale();
|
||||
|
||||
// Gets whether or not the exporter supports animation exporting.
|
||||
virtual bool SupportsAnimations();
|
||||
// Gets whether or not the exporter supports model exporting.
|
||||
virtual bool SupportsModels();
|
||||
};
|
||||
}
|
10
r5dev/thirdparty/cppnet/cppkore/ColumnClickEventArgs.cpp
vendored
Normal file
10
r5dev/thirdparty/cppnet/cppkore/ColumnClickEventArgs.cpp
vendored
Normal file
@ -0,0 +1,10 @@
|
||||
#include "stdafx.h"
|
||||
#include "ColumnClickEventArgs.h"
|
||||
|
||||
namespace Forms
|
||||
{
|
||||
ColumnClickEventArgs::ColumnClickEventArgs(int32_t Column)
|
||||
: Column(Column)
|
||||
{
|
||||
}
|
||||
}
|
17
r5dev/thirdparty/cppnet/cppkore/ColumnClickEventArgs.h
vendored
Normal file
17
r5dev/thirdparty/cppnet/cppkore/ColumnClickEventArgs.h
vendored
Normal file
@ -0,0 +1,17 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
namespace Forms
|
||||
{
|
||||
// Provides data for the OnColumnClick event.
|
||||
class ColumnClickEventArgs
|
||||
{
|
||||
public:
|
||||
ColumnClickEventArgs(int32_t Column);
|
||||
~ColumnClickEventArgs() = default;
|
||||
|
||||
// The index of the column that was clicked.
|
||||
const int32_t Column;
|
||||
};
|
||||
}
|
158
r5dev/thirdparty/cppnet/cppkore/ColumnHeader.cpp
vendored
Normal file
158
r5dev/thirdparty/cppnet/cppkore/ColumnHeader.cpp
vendored
Normal file
@ -0,0 +1,158 @@
|
||||
#include "stdafx.h"
|
||||
#include "ColumnHeader.h"
|
||||
#include "ListView.h"
|
||||
|
||||
namespace Forms
|
||||
{
|
||||
ColumnHeader::ColumnHeader()
|
||||
: ColumnHeader("")
|
||||
{
|
||||
}
|
||||
|
||||
ColumnHeader::ColumnHeader(const string& Text)
|
||||
: ColumnHeader(Text, 60)
|
||||
{
|
||||
}
|
||||
|
||||
ColumnHeader::ColumnHeader(const string& Text, int32_t Width)
|
||||
: ColumnHeader(Text, Width, HorizontalAlignment::Left)
|
||||
{
|
||||
}
|
||||
|
||||
ColumnHeader::ColumnHeader(const string& Text, int32_t Width, HorizontalAlignment Alignment)
|
||||
: _Text(Text), _Width(Width), _TextAlign(Alignment), _OwnerListView(nullptr), _IndexInternal(-1)
|
||||
{
|
||||
}
|
||||
|
||||
int32_t ColumnHeader::Index() const
|
||||
{
|
||||
if (_OwnerListView != nullptr)
|
||||
return _OwnerListView->Columns.IndexOf(*this);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
int32_t ColumnHeader::DisplayIndex()
|
||||
{
|
||||
return this->_IndexInternal;
|
||||
}
|
||||
|
||||
void ColumnHeader::SetDisplayIndex(int32_t Value)
|
||||
{
|
||||
if (this->_OwnerListView == nullptr)
|
||||
{
|
||||
this->_IndexInternal = Value;
|
||||
return;
|
||||
}
|
||||
|
||||
auto LowDI = min(this->_IndexInternal, Value);
|
||||
auto HiDI = max(this->_IndexInternal, Value);
|
||||
auto ColsOrder = std::make_unique<int32_t[]>(_OwnerListView->Columns.Count());
|
||||
|
||||
bool HdrMovedForward = Value > this->_IndexInternal;
|
||||
ColumnHeader* MovedHdr = nullptr;
|
||||
|
||||
for (uint32_t i = 0; i < _OwnerListView->Columns.Count(); i++)
|
||||
{
|
||||
auto& Hdr = _OwnerListView->Columns[i];
|
||||
if (Hdr.DisplayIndex() == _IndexInternal)
|
||||
MovedHdr = &Hdr;
|
||||
else if (Hdr.DisplayIndex() >= LowDI && Hdr.DisplayIndex() <= HiDI)
|
||||
Hdr._IndexInternal -= HdrMovedForward ? 1 : -1;
|
||||
|
||||
if (i != this->Index())
|
||||
ColsOrder[Hdr._IndexInternal] = i;
|
||||
}
|
||||
|
||||
if (MovedHdr != nullptr)
|
||||
{
|
||||
MovedHdr->_IndexInternal = Value;
|
||||
ColsOrder[MovedHdr->_IndexInternal] = MovedHdr->Index();
|
||||
}
|
||||
|
||||
SetDisplayIndices(ColsOrder, _OwnerListView->Columns.Count());
|
||||
}
|
||||
|
||||
void ColumnHeader::SetDisplayIndexInternal(int32_t Value)
|
||||
{
|
||||
this->_IndexInternal = Value;
|
||||
}
|
||||
|
||||
const string& ColumnHeader::Text() const
|
||||
{
|
||||
return this->_Text;
|
||||
}
|
||||
|
||||
void ColumnHeader::SetText(const string& Value)
|
||||
{
|
||||
_Text = Value;
|
||||
|
||||
if (_OwnerListView)
|
||||
_OwnerListView->SetColumnInfo(LVCF_TEXT, *this);
|
||||
}
|
||||
|
||||
int32_t ColumnHeader::Width() const
|
||||
{
|
||||
if (_OwnerListView != nullptr && _OwnerListView->GetState(Forms::ControlStates::StateCreated) && _OwnerListView->GetState(ControlStates::StateCreated))
|
||||
{
|
||||
auto HwndHdr = (HWND)SendMessageA(_OwnerListView->GetHandle(), LVM_GETHEADER, NULL, NULL);
|
||||
if (HwndHdr != NULL)
|
||||
{
|
||||
auto NativeItemCount = (int32_t)SendMessageA(HwndHdr, HDM_GETITEMCOUNT, NULL, NULL);
|
||||
auto Idx = Index();
|
||||
if (Idx < NativeItemCount)
|
||||
return (int32_t)SendMessageA(_OwnerListView->GetHandle(), LVM_GETCOLUMNWIDTH, (WPARAM)Idx, 0);
|
||||
}
|
||||
}
|
||||
|
||||
return this->_Width;
|
||||
}
|
||||
|
||||
void ColumnHeader::SetWidth(int32_t Value)
|
||||
{
|
||||
_Width = Value;
|
||||
|
||||
if (_OwnerListView)
|
||||
_OwnerListView->SetColumnWidth(this->Index(), _Width);
|
||||
}
|
||||
|
||||
HorizontalAlignment ColumnHeader::TextAlign() const
|
||||
{
|
||||
return this->_TextAlign;
|
||||
}
|
||||
|
||||
void ColumnHeader::SetTextAlign(HorizontalAlignment Value)
|
||||
{
|
||||
if (_TextAlign != Value)
|
||||
{
|
||||
_TextAlign = Value;
|
||||
|
||||
if (_OwnerListView)
|
||||
{
|
||||
_OwnerListView->SetColumnInfo(LVCF_FMT, *this);
|
||||
_OwnerListView->Invalidate();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ListView* ColumnHeader::GetListView()
|
||||
{
|
||||
return this->_OwnerListView;
|
||||
}
|
||||
|
||||
void ColumnHeader::SetListView(ListView* Owner)
|
||||
{
|
||||
this->_OwnerListView = Owner;
|
||||
}
|
||||
|
||||
bool ColumnHeader::operator==(const ColumnHeader& Rhs)
|
||||
{
|
||||
return (this->_IndexInternal == Rhs._IndexInternal && this->_Text == Rhs._Text && this->_TextAlign == Rhs._TextAlign);
|
||||
}
|
||||
|
||||
void ColumnHeader::SetDisplayIndices(const std::unique_ptr<int32_t[]>& Cols, int32_t Count)
|
||||
{
|
||||
if (this->_OwnerListView != nullptr && this->_OwnerListView->GetState(ControlStates::StateCreated))
|
||||
SendMessageA(this->_OwnerListView->GetHandle(), LVM_SETCOLUMNORDERARRAY, (WPARAM)Count, (LPARAM)Cols.get());
|
||||
}
|
||||
}
|
71
r5dev/thirdparty/cppnet/cppkore/ColumnHeader.h
vendored
Normal file
71
r5dev/thirdparty/cppnet/cppkore/ColumnHeader.h
vendored
Normal file
@ -0,0 +1,71 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include "StringBase.h"
|
||||
#include "HorizontalAlignment.h"
|
||||
|
||||
namespace Forms
|
||||
{
|
||||
// Externally defined so we don't conflict
|
||||
class ListView;
|
||||
|
||||
// Displays a single column header in a ListView control.
|
||||
class ColumnHeader
|
||||
{
|
||||
public:
|
||||
ColumnHeader();
|
||||
ColumnHeader(const string& Text);
|
||||
ColumnHeader(const string& Text, int32_t Width);
|
||||
ColumnHeader(const string& Text, int32_t Width, HorizontalAlignment Alignment);
|
||||
~ColumnHeader() = default;
|
||||
|
||||
// The index of this column.
|
||||
int32_t Index() const;
|
||||
|
||||
// The index of this column as it is displayed.
|
||||
int32_t DisplayIndex();
|
||||
// The index of this column as it is displayed.
|
||||
void SetDisplayIndex(int32_t Value);
|
||||
|
||||
// Sets the display index without reflowing others.
|
||||
void SetDisplayIndexInternal(int32_t Value);
|
||||
|
||||
// The text displayed in the column header.
|
||||
const string& Text() const;
|
||||
// The text displayed in the column header.
|
||||
void SetText(const string& Value);
|
||||
|
||||
// The width of the column in pixels.
|
||||
int32_t Width() const;
|
||||
// The width of the column in pixels.
|
||||
void SetWidth(int32_t Value);
|
||||
|
||||
// The horizontal alignment of the text contained in this column.
|
||||
HorizontalAlignment TextAlign() const;
|
||||
// The horizontal alignment of the text contained in this column.
|
||||
void SetTextAlign(HorizontalAlignment Value);
|
||||
|
||||
// Returns the ListView control that this column is displayed in. May be null.
|
||||
ListView* GetListView();
|
||||
// Sets the ListView control that this column is displayed in.
|
||||
void SetListView(ListView* Owner);
|
||||
|
||||
// Custom equality operator
|
||||
bool operator==(const ColumnHeader& Rhs);
|
||||
|
||||
private:
|
||||
// Internal cached properties
|
||||
ListView* _OwnerListView;
|
||||
|
||||
// Width and index
|
||||
int32_t _Width;
|
||||
int32_t _IndexInternal;
|
||||
|
||||
// Text to display
|
||||
string _Text;
|
||||
HorizontalAlignment _TextAlign;
|
||||
|
||||
// Set the display indices of the ListView columns.
|
||||
void SetDisplayIndices(const std::unique_ptr<int32_t[]>& Cols, int32_t Count);
|
||||
};
|
||||
}
|
17
r5dev/thirdparty/cppnet/cppkore/ColumnHeaderStyle.h
vendored
Normal file
17
r5dev/thirdparty/cppnet/cppkore/ColumnHeaderStyle.h
vendored
Normal file
@ -0,0 +1,17 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
namespace Forms
|
||||
{
|
||||
// Specifies how ListView column headers behave.
|
||||
enum class ColumnHeaderStyle
|
||||
{
|
||||
// No visible column header.
|
||||
None = 0,
|
||||
// Visible column header that does not respond to clicking.
|
||||
NonClickable = 1,
|
||||
// Visible column header that responds to clicking.
|
||||
Clickable = 2
|
||||
};
|
||||
}
|
496
r5dev/thirdparty/cppnet/cppkore/ComboBox.cpp
vendored
Normal file
496
r5dev/thirdparty/cppnet/cppkore/ComboBox.cpp
vendored
Normal file
@ -0,0 +1,496 @@
|
||||
#include "stdafx.h"
|
||||
#include "ComboBox.h"
|
||||
|
||||
namespace Forms
|
||||
{
|
||||
ComboBox::ComboBox()
|
||||
: Control(), Items(this), _DrawMode(DrawMode::Normal), _FlatStyle(FlatStyle::Standard), _DropDownStyle(ComboBoxStyle::DropDown), _IntegralHeight(true), _DropDownWidth(-1), _DropDownHeight(-1), _MaxDropDownItems(8), _MaximumLength(SHRT_MAX), _SelectedIndex(-1), _ChildEdit(nullptr), _ChildListBox(nullptr)
|
||||
{
|
||||
SetStyle(ControlStyles::UserPaint |
|
||||
ControlStyles::UseTextForAccessibility |
|
||||
ControlStyles::StandardClick, false);
|
||||
|
||||
// Default back color is different...
|
||||
this->_BackColor = Drawing::GetSystemColor(Drawing::SystemColors::Window);
|
||||
// We are a ComboBox control.
|
||||
this->_RTTI = ControlTypes::ComboBox;
|
||||
}
|
||||
|
||||
DrawMode ComboBox::GetDrawMode()
|
||||
{
|
||||
return this->_DrawMode;
|
||||
}
|
||||
|
||||
void ComboBox::SetDrawMode(DrawMode Value)
|
||||
{
|
||||
if (_DrawMode != Value)
|
||||
{
|
||||
_DrawMode = Value;
|
||||
UpdateStyles();
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t ComboBox::DropDownWidth()
|
||||
{
|
||||
if (_DropDownWidth > -1)
|
||||
return _DropDownWidth;
|
||||
|
||||
return _Width;
|
||||
}
|
||||
|
||||
void ComboBox::SetDropDownWidth(uint32_t Value)
|
||||
{
|
||||
_DropDownWidth = (int32_t)Value;
|
||||
|
||||
if (GetState(ControlStates::StateCreated))
|
||||
SendMessageA(this->_Handle, CB_SETDROPPEDWIDTH, (WPARAM)Value, NULL);
|
||||
}
|
||||
|
||||
uint32_t ComboBox::DropDownHeight()
|
||||
{
|
||||
if (_DropDownHeight > -1)
|
||||
return _DropDownHeight;
|
||||
|
||||
return 106; // Default drop down height...
|
||||
}
|
||||
|
||||
void ComboBox::SetDropDownHeight(uint32_t Value)
|
||||
{
|
||||
_DropDownHeight = (int32_t)Value;
|
||||
SetIntegralHeight(false);
|
||||
}
|
||||
|
||||
bool ComboBox::DroppedDown()
|
||||
{
|
||||
if (GetState(ControlStates::StateCreated))
|
||||
return (SendMessageA(this->_Handle, CB_GETDROPPEDSTATE, NULL, NULL) != 0);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void ComboBox::SetDroppedDown(bool Value)
|
||||
{
|
||||
if (GetState(ControlStates::StateCreated))
|
||||
SendMessageA(this->_Handle, CB_SHOWDROPDOWN, Value ? -1 : 0, NULL);
|
||||
}
|
||||
|
||||
FlatStyle ComboBox::GetFlatStyle()
|
||||
{
|
||||
return this->_FlatStyle;
|
||||
}
|
||||
|
||||
void ComboBox::SetFlatStyle(FlatStyle Value)
|
||||
{
|
||||
if (_FlatStyle != Value)
|
||||
{
|
||||
_FlatStyle = Value;
|
||||
UpdateStyles();
|
||||
}
|
||||
}
|
||||
|
||||
bool ComboBox::IntegralHeight()
|
||||
{
|
||||
return this->_IntegralHeight;
|
||||
}
|
||||
|
||||
void ComboBox::SetIntegralHeight(bool Value)
|
||||
{
|
||||
if (_IntegralHeight != Value)
|
||||
{
|
||||
_IntegralHeight = Value;
|
||||
UpdateStyles();
|
||||
}
|
||||
}
|
||||
|
||||
int32_t ComboBox::ItemHeight()
|
||||
{
|
||||
return (int32_t)SendMessageA(this->_Handle, CB_GETITEMHEIGHT, NULL, NULL);
|
||||
}
|
||||
|
||||
void ComboBox::SetItemHeight(int32_t Value)
|
||||
{
|
||||
if (_DrawMode == DrawMode::OwnerDrawFixed)
|
||||
{
|
||||
SendMessageA(this->_Handle, CB_SETITEMHEIGHT, (WPARAM)-1, (LPARAM)Value);
|
||||
SendMessageA(this->_Handle, CB_SETITEMHEIGHT, (WPARAM)0, (LPARAM)Value);
|
||||
}
|
||||
else if (_DrawMode == DrawMode::OwnerDrawVariable)
|
||||
{
|
||||
SendMessageA(this->_Handle, CB_SETITEMHEIGHT, (WPARAM)-1, (LPARAM)Value);
|
||||
|
||||
for (uint32_t i = 0; i < Items.Count(); i++)
|
||||
SendMessageA(this->_Handle, CB_SETITEMHEIGHT, (WPARAM)i, (LPARAM)Value);
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t ComboBox::MaxDropDownItems()
|
||||
{
|
||||
return this->_MaxDropDownItems;
|
||||
}
|
||||
|
||||
void ComboBox::SetMaxDropDownItems(uint8_t Value)
|
||||
{
|
||||
this->_MaxDropDownItems = Value;
|
||||
}
|
||||
|
||||
uint32_t ComboBox::MaxLength()
|
||||
{
|
||||
return this->_MaximumLength;
|
||||
}
|
||||
|
||||
void ComboBox::SetMaxLength(uint32_t Value)
|
||||
{
|
||||
if (_MaximumLength != Value)
|
||||
{
|
||||
_MaximumLength = Value;
|
||||
|
||||
if (GetState(ControlStates::StateCreated))
|
||||
SendMessageA(this->_Handle, CB_LIMITTEXT, (WPARAM)Value, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
int32_t ComboBox::SelectedIndex()
|
||||
{
|
||||
if (GetState(ControlStates::StateCreated))
|
||||
return (int32_t)SendMessageA(this->_Handle, CB_GETCURSEL, NULL, NULL);
|
||||
|
||||
return this->_SelectedIndex;
|
||||
}
|
||||
|
||||
void ComboBox::SetSelectedIndex(int32_t Value)
|
||||
{
|
||||
if (GetState(ControlStates::StateCreated))
|
||||
SendMessageA(this->_Handle, CB_SETCURSEL, (WPARAM)Value, NULL);
|
||||
else
|
||||
_SelectedIndex = Value;
|
||||
|
||||
OnTextChanged();
|
||||
|
||||
OnSelectedIndexChanged();
|
||||
OnSelectedItemChanged();
|
||||
}
|
||||
|
||||
string ComboBox::SelectedText()
|
||||
{
|
||||
if (_DropDownStyle == ComboBoxStyle::DropDownList)
|
||||
return "";
|
||||
|
||||
return Text().Substring(SelectionStart(), SelectionLength());
|
||||
}
|
||||
|
||||
void ComboBox::SetSelectedText(const string& Value)
|
||||
{
|
||||
if (_DropDownStyle != ComboBoxStyle::DropDownList)
|
||||
{
|
||||
if (GetState(ControlStates::StateCreated))
|
||||
SendMessageA(this->_ChildEdit, EM_REPLACESEL, (WPARAM)-1, (LPARAM)(const char*)Value);
|
||||
}
|
||||
}
|
||||
|
||||
int32_t ComboBox::SelectionLength()
|
||||
{
|
||||
int32_t End = 0;
|
||||
int32_t Start = 0;
|
||||
SendMessageA(this->_Handle, CB_GETEDITSEL, (WPARAM)&Start, (WPARAM)&End);
|
||||
|
||||
return End - Start;
|
||||
}
|
||||
|
||||
void ComboBox::SetSelectionLength(int32_t Value)
|
||||
{
|
||||
Select(SelectionStart(), Value);
|
||||
}
|
||||
|
||||
int32_t ComboBox::SelectionStart()
|
||||
{
|
||||
int32_t Value = 0;
|
||||
SendMessageA(this->_Handle, CB_GETEDITSEL, (WPARAM)&Value, NULL);
|
||||
|
||||
return Value;
|
||||
}
|
||||
|
||||
void ComboBox::SetSelectionStart(int32_t Value)
|
||||
{
|
||||
Select(Value, SelectionLength());
|
||||
}
|
||||
|
||||
ComboBoxStyle ComboBox::DropDownStyle()
|
||||
{
|
||||
return this->_DropDownStyle;
|
||||
}
|
||||
|
||||
void ComboBox::SetDropDownStyle(ComboBoxStyle Value)
|
||||
{
|
||||
if (_DropDownStyle != Value)
|
||||
{
|
||||
_DropDownStyle = Value;
|
||||
|
||||
if (GetState(ControlStates::StateCreated))
|
||||
UpdateStyles();
|
||||
}
|
||||
}
|
||||
|
||||
void ComboBox::Select(int32_t Start, int32_t Length)
|
||||
{
|
||||
int32_t End = Start + Length;
|
||||
SendMessageA(this->_Handle, CB_SETEDITSEL, NULL, MAKELPARAM(Start, End));
|
||||
}
|
||||
|
||||
void ComboBox::OnHandleCreated()
|
||||
{
|
||||
if (_MaximumLength > 0)
|
||||
SendMessageA(this->_Handle, CB_LIMITTEXT, (WPARAM)_MaximumLength, NULL);
|
||||
|
||||
if (_DropDownStyle != ComboBoxStyle::DropDownList)
|
||||
{
|
||||
auto Hwnd = GetWindow(this->_Handle, GW_CHILD);
|
||||
if (Hwnd != NULL)
|
||||
{
|
||||
if (_DropDownStyle == ComboBoxStyle::Simple)
|
||||
{
|
||||
_ChildListBox = Hwnd;
|
||||
Hwnd = GetWindow(Hwnd, GW_HWNDNEXT);
|
||||
}
|
||||
|
||||
_ChildEdit = Hwnd;
|
||||
}
|
||||
}
|
||||
|
||||
if (_DropDownWidth > -1)
|
||||
SendMessageA(this->_Handle, CB_SETDROPPEDWIDTH, (WPARAM)_DropDownWidth, NULL);
|
||||
|
||||
// If we have items, add them now
|
||||
for (auto& Item : Items)
|
||||
this->NativeAdd((const char*)Item);
|
||||
|
||||
if (_SelectedIndex > -1)
|
||||
{
|
||||
SendMessageA(this->_Handle, CB_SETCURSEL, (WPARAM)_SelectedIndex, NULL);
|
||||
_SelectedIndex = -1;
|
||||
}
|
||||
|
||||
// We must call the base event last
|
||||
Control::OnHandleCreated();
|
||||
}
|
||||
|
||||
void ComboBox::OnSelectedItemChanged()
|
||||
{
|
||||
SelectedItemChanged.RaiseEvent(this);
|
||||
}
|
||||
|
||||
void ComboBox::OnSelectedIndexChanged()
|
||||
{
|
||||
SelectedIndexChanged.RaiseEvent(this);
|
||||
}
|
||||
|
||||
void ComboBox::OnDropDownClosed()
|
||||
{
|
||||
DropDownClosed.RaiseEvent(this);
|
||||
}
|
||||
|
||||
void ComboBox::WndProc(Message& Msg)
|
||||
{
|
||||
switch (Msg.Msg)
|
||||
{
|
||||
case WM_CTLCOLOREDIT:
|
||||
case WM_CTLCOLORLISTBOX:
|
||||
Msg.Result = InitializeDCForWmCtlColor((HDC)Msg.WParam, Msg.Msg);
|
||||
break;
|
||||
case WM_REFLECT + WM_COMMAND:
|
||||
WmReflectCommand(Msg);
|
||||
break;
|
||||
default:
|
||||
Control::WndProc(Msg);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
CreateParams ComboBox::GetCreateParams()
|
||||
{
|
||||
auto Cp = Control::GetCreateParams();
|
||||
|
||||
Cp.ClassName = "COMBOBOX";
|
||||
Cp.Style |= WS_VSCROLL | CBS_HASSTRINGS | CBS_AUTOHSCROLL;
|
||||
|
||||
if (!_IntegralHeight)
|
||||
Cp.Style |= CBS_NOINTEGRALHEIGHT;
|
||||
|
||||
switch (_FlatStyle)
|
||||
{
|
||||
case FlatStyle::Popup:
|
||||
case FlatStyle::Flat:
|
||||
Cp.ExStyle |= WS_EX_STATICEDGE;
|
||||
default:
|
||||
Cp.ExStyle |= WS_EX_CLIENTEDGE;
|
||||
break;
|
||||
}
|
||||
|
||||
switch (_DropDownStyle)
|
||||
{
|
||||
case ComboBoxStyle::Simple:
|
||||
Cp.Style |= CBS_SIMPLE;
|
||||
break;
|
||||
case ComboBoxStyle::DropDown:
|
||||
Cp.Style |= CBS_DROPDOWN;
|
||||
break;
|
||||
case ComboBoxStyle::DropDownList:
|
||||
Cp.Style |= CBS_DROPDOWNLIST;
|
||||
break;
|
||||
}
|
||||
|
||||
switch (_DrawMode)
|
||||
{
|
||||
case DrawMode::OwnerDrawFixed:
|
||||
Cp.Style |= CBS_OWNERDRAWFIXED;
|
||||
break;
|
||||
case DrawMode::OwnerDrawVariable:
|
||||
Cp.Style |= CBS_OWNERDRAWVARIABLE;
|
||||
break;
|
||||
}
|
||||
|
||||
return Cp;
|
||||
}
|
||||
|
||||
uintptr_t ComboBox::InitializeDCForWmCtlColor(HDC Dc, int32_t Message)
|
||||
{
|
||||
if ((Message == WM_CTLCOLORSTATIC))
|
||||
{
|
||||
return (uintptr_t)0;
|
||||
}
|
||||
else if ((Message == WM_CTLCOLORLISTBOX) && GetStyle(ControlStyles::UserPaint))
|
||||
{
|
||||
SetTextColor(Dc, this->ForeColor().ToCOLORREF());
|
||||
SetBkColor(Dc, this->BackColor().ToCOLORREF());
|
||||
|
||||
return BackColorBrush();
|
||||
}
|
||||
else
|
||||
{
|
||||
return Control::InitializeDCForWmCtlColor(Dc, Message);
|
||||
}
|
||||
}
|
||||
|
||||
int32_t ComboBox::NativeAdd(const char* Value)
|
||||
{
|
||||
return (int32_t)SendMessageA(this->_Handle, CB_ADDSTRING, NULL, (LPARAM)Value);
|
||||
}
|
||||
|
||||
void ComboBox::NativeClear()
|
||||
{
|
||||
string Saved;
|
||||
|
||||
if (_DropDownStyle != ComboBoxStyle::DropDownList)
|
||||
Saved = this->WindowText();
|
||||
|
||||
SendMessageA(this->_Handle, CB_RESETCONTENT, NULL, NULL);
|
||||
|
||||
if (!string::IsNullOrEmpty(Saved))
|
||||
this->SetWindowText(Saved);
|
||||
}
|
||||
|
||||
int32_t ComboBox::NativeInsert(int32_t Index, const char* Value)
|
||||
{
|
||||
return (int32_t)SendMessageA(this->_Handle, CB_INSERTSTRING, (WPARAM)Index, (LPARAM)Value);
|
||||
}
|
||||
|
||||
void ComboBox::NativeRemoveAt(int32_t Index)
|
||||
{
|
||||
if (_DropDownStyle == ComboBoxStyle::DropDownList && SelectedIndex() == Index)
|
||||
Invalidate();
|
||||
|
||||
SendMessageA(this->_Handle, CB_DELETESTRING, (WPARAM)Index, NULL);
|
||||
}
|
||||
|
||||
void ComboBox::WmReflectCommand(Message& Msg)
|
||||
{
|
||||
switch ((int16_t)HIWORD(Msg.WParam))
|
||||
{
|
||||
case CBN_EDITCHANGE:
|
||||
OnTextChanged();
|
||||
break;
|
||||
case CBN_SELCHANGE:
|
||||
OnSelectedIndexChanged();
|
||||
OnSelectedItemChanged();
|
||||
break;
|
||||
case CBN_CLOSEUP:
|
||||
OnDropDownClosed();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ComboBox::ComboBoxItemCollection::ComboBoxItemCollection(ComboBox* Owner)
|
||||
: _Owner(Owner), _Items()
|
||||
{
|
||||
}
|
||||
|
||||
void ComboBox::ComboBoxItemCollection::Add(const imstring& Value)
|
||||
{
|
||||
_Items.EmplaceBack(Value);
|
||||
|
||||
if (_Owner->GetState(ControlStates::StateCreated))
|
||||
_Owner->NativeAdd(Value);
|
||||
}
|
||||
|
||||
void ComboBox::ComboBoxItemCollection::Insert(int32_t Index, const imstring& Value)
|
||||
{
|
||||
_Items.Insert(Index, Value);
|
||||
|
||||
if (_Owner->GetState(ControlStates::StateCreated))
|
||||
_Owner->NativeInsert(Index, Value);
|
||||
}
|
||||
|
||||
void ComboBox::ComboBoxItemCollection::Clear()
|
||||
{
|
||||
_Items.Clear();
|
||||
|
||||
if (_Owner->GetState(ControlStates::StateCreated))
|
||||
_Owner->NativeClear();
|
||||
}
|
||||
|
||||
bool ComboBox::ComboBoxItemCollection::Contains(const imstring & Value)
|
||||
{
|
||||
return (IndexOf(Value) > -1);
|
||||
}
|
||||
|
||||
int32_t ComboBox::ComboBoxItemCollection::IndexOf(const imstring& Value)
|
||||
{
|
||||
auto Str = string(Value);
|
||||
auto Res = _Items.IndexOf(Str);
|
||||
|
||||
if (Res == List<string>::InvalidPosition)
|
||||
return -1;
|
||||
|
||||
return Res;
|
||||
}
|
||||
|
||||
void ComboBox::ComboBoxItemCollection::RemoveAt(int32_t Index)
|
||||
{
|
||||
if (_Owner->GetState(ControlStates::StateCreated))
|
||||
_Owner->NativeRemoveAt(Index);
|
||||
|
||||
_Items.RemoveAt(Index);
|
||||
}
|
||||
|
||||
void ComboBox::ComboBoxItemCollection::Remove(const imstring& Value)
|
||||
{
|
||||
auto Index = IndexOf(Value);
|
||||
|
||||
if (Index > -1)
|
||||
RemoveAt(Index);
|
||||
}
|
||||
|
||||
uint32_t ComboBox::ComboBoxItemCollection::Count()
|
||||
{
|
||||
return _Items.Count();
|
||||
}
|
||||
|
||||
string* ComboBox::ComboBoxItemCollection::begin() const
|
||||
{
|
||||
return _Items.begin();
|
||||
}
|
||||
|
||||
string* ComboBox::ComboBoxItemCollection::end() const
|
||||
{
|
||||
return _Items.end();
|
||||
}
|
||||
}
|
190
r5dev/thirdparty/cppnet/cppkore/ComboBox.h
vendored
Normal file
190
r5dev/thirdparty/cppnet/cppkore/ComboBox.h
vendored
Normal file
@ -0,0 +1,190 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include "Control.h"
|
||||
#include "StringBase.h"
|
||||
#include "ListBase.h"
|
||||
#include "ImmutableStringBase.h"
|
||||
#include "DrawMode.h"
|
||||
#include "FlatStyle.h"
|
||||
#include "ComboBoxStyle.h"
|
||||
|
||||
namespace Forms
|
||||
{
|
||||
// Displays an editing field and a list control.
|
||||
class ComboBox : public Control
|
||||
{
|
||||
public:
|
||||
ComboBox();
|
||||
virtual ~ComboBox() = default;
|
||||
|
||||
// Gets whether the control is drawn by Windows or by the user.
|
||||
DrawMode GetDrawMode();
|
||||
// Sets whether the control is drawn by Windows or by the user.
|
||||
void SetDrawMode(DrawMode Value);
|
||||
|
||||
// Gets the width of the drop down box in a combo box.
|
||||
uint32_t DropDownWidth();
|
||||
// Sets the width of the drop down box in a combo box.
|
||||
void SetDropDownWidth(uint32_t Value);
|
||||
|
||||
// Gets the Height of the drop down box in a combo box.
|
||||
uint32_t DropDownHeight();
|
||||
// Sets the Height of the drop down box in a combo box.
|
||||
void SetDropDownHeight(uint32_t Value);
|
||||
|
||||
// Indicates whether the DropDown of the combo is currently dropped down.
|
||||
bool DroppedDown();
|
||||
// Sets whether the DropDown of the combo is currently dropped down.
|
||||
void SetDroppedDown(bool Value);
|
||||
|
||||
// Gets the flat style appearance of the button control.
|
||||
FlatStyle GetFlatStyle();
|
||||
// Sets the flat style appearance of the button control.
|
||||
void SetFlatStyle(FlatStyle Value);
|
||||
|
||||
// Gets if the combo should avoid showing partial Items.
|
||||
bool IntegralHeight();
|
||||
// Sets if the combo should avoid showing partial Items.
|
||||
void SetIntegralHeight(bool Value);
|
||||
|
||||
// Gets the height of an item in the combo box.
|
||||
int32_t ItemHeight();
|
||||
// Sets the height of an item in the combo box.
|
||||
void SetItemHeight(int32_t Value);
|
||||
|
||||
// Gets the maximum number of items to be shown in the dropdown portion
|
||||
// of the ComboBox. This number can be between 1 and 100.
|
||||
uint8_t MaxDropDownItems();
|
||||
// Sets the maximum number of items to be shown in the dropdown portion
|
||||
// of the ComboBox. This number can be between 1 and 100.
|
||||
void SetMaxDropDownItems(uint8_t Value);
|
||||
|
||||
// Gets the maximum length of the text the user may type into the edit control of a combo box.
|
||||
uint32_t MaxLength();
|
||||
// Sets the maximum length of the text the user may type into the edit control of a combo box.
|
||||
void SetMaxLength(uint32_t Value);
|
||||
|
||||
// Gets the [zero based] index of the currently selected item in the combos list.
|
||||
// Note If the value of index is -1, then the ComboBox is
|
||||
// set to have no selection.
|
||||
int32_t SelectedIndex();
|
||||
// Sets the [zero based] index of the currently selected item in the combos list.
|
||||
// Note If the value of index is -1, then the ComboBox is
|
||||
// set to have no selection.
|
||||
void SetSelectedIndex(int32_t Value);
|
||||
|
||||
// Gets the selected text in the edit component of the ComboBox.
|
||||
string SelectedText();
|
||||
// Sets the selected text in the edit component of the ComboBox.
|
||||
void SetSelectedText(const string& Value);
|
||||
|
||||
// Gets length, in characters, of the selection in the editbox.
|
||||
int32_t SelectionLength();
|
||||
// Sets length, in characters, of the selection in the editbox.
|
||||
void SetSelectionLength(int32_t Value);
|
||||
|
||||
// Gets the [zero-based] index of the first character in the current text selection.
|
||||
int32_t SelectionStart();
|
||||
// Sets the [zero-based] index of the first character in the current text selection.
|
||||
void SetSelectionStart(int32_t Value);
|
||||
|
||||
// Gets the type of combo that we are right now.
|
||||
ComboBoxStyle DropDownStyle();
|
||||
// Sets the type of combo that we are right now.
|
||||
void SetDropDownStyle(ComboBoxStyle Value);
|
||||
|
||||
// Selects the text in the editable portion of the ComboBox at the
|
||||
void Select(int32_t Start, int32_t Length);
|
||||
|
||||
// The items contained in the combo box.
|
||||
struct ComboBoxItemCollection
|
||||
{
|
||||
ComboBoxItemCollection(ComboBox* Owner);
|
||||
~ComboBoxItemCollection() = default;
|
||||
|
||||
// Adds an item to the combo box.
|
||||
void Add(const imstring& Value);
|
||||
// Inserts an item to the combo box.
|
||||
void Insert(int32_t Index, const imstring& Value);
|
||||
// Removes all items from the combo box.
|
||||
void Clear();
|
||||
// Checks if the combo box contains the value.
|
||||
bool Contains(const imstring& Value);
|
||||
// Gets the index of the item, if any.
|
||||
int32_t IndexOf(const imstring& Value);
|
||||
// Removes an item at the specified index.
|
||||
void RemoveAt(int32_t Index);
|
||||
// Removes an item from the combo box.
|
||||
void Remove(const imstring& Value);
|
||||
// Gets the count of items in the combo box.
|
||||
uint32_t Count();
|
||||
|
||||
// Iterater classes
|
||||
string* begin() const;
|
||||
string* end() const;
|
||||
|
||||
protected:
|
||||
// Internal references
|
||||
ComboBox* _Owner;
|
||||
List<string> _Items;
|
||||
} Items;
|
||||
|
||||
// We must define control event bases here
|
||||
virtual void OnHandleCreated();
|
||||
virtual void OnSelectedItemChanged();
|
||||
virtual void OnSelectedIndexChanged();
|
||||
virtual void OnDropDownClosed();
|
||||
|
||||
// We must define event handlers here
|
||||
EventBase<void(*)(Control*)> SelectedItemChanged;
|
||||
EventBase<void(*)(Control*)> SelectedIndexChanged;
|
||||
EventBase<void(*)(Control*)> DropDownClosed;
|
||||
|
||||
// Override WndProc for specific combo box messages.
|
||||
virtual void WndProc(Message& Msg);
|
||||
|
||||
protected:
|
||||
// Get custom control creation parameters for this instance.
|
||||
virtual CreateParams GetCreateParams();
|
||||
|
||||
// Sets the text and background colors of the DC, and returns the background HBRUSH.
|
||||
virtual uintptr_t InitializeDCForWmCtlColor(HDC Dc, int32_t Message);
|
||||
|
||||
// Internal routine to add an item.
|
||||
int32_t NativeAdd(const char* Value);
|
||||
// Internal routine to clear the items.
|
||||
void NativeClear();
|
||||
// Internal routine to insert an item.
|
||||
int32_t NativeInsert(int32_t Index, const char* Value);
|
||||
// Internal routine to remove an item.
|
||||
void NativeRemoveAt(int32_t Index);
|
||||
|
||||
private:
|
||||
// Internal cached flags
|
||||
FlatStyle _FlatStyle;
|
||||
DrawMode _DrawMode;
|
||||
ComboBoxStyle _DropDownStyle;
|
||||
|
||||
// Internal show partial items
|
||||
bool _IntegralHeight;
|
||||
|
||||
// Internal size of dropdown
|
||||
int32_t _DropDownWidth;
|
||||
int32_t _DropDownHeight;
|
||||
int32_t _SelectedIndex;
|
||||
|
||||
// Internal children
|
||||
HWND _ChildEdit;
|
||||
HWND _ChildListBox;
|
||||
|
||||
// Internal maximum items
|
||||
uint8_t _MaxDropDownItems;
|
||||
|
||||
// Internal maximun length
|
||||
uint32_t _MaximumLength;
|
||||
|
||||
// We must define each window message handler here...
|
||||
void WmReflectCommand(Message& Msg);
|
||||
};
|
||||
}
|
17
r5dev/thirdparty/cppnet/cppkore/ComboBoxStyle.h
vendored
Normal file
17
r5dev/thirdparty/cppnet/cppkore/ComboBoxStyle.h
vendored
Normal file
@ -0,0 +1,17 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
namespace Forms
|
||||
{
|
||||
// Specifies the ComboBox style.
|
||||
enum class ComboBoxStyle
|
||||
{
|
||||
// The text portion is editable. The list portion is always visible.
|
||||
Simple = 0,
|
||||
// The text portion is editable. The user must click the arrow button to display the list portion.
|
||||
DropDown = 1,
|
||||
// The user cannot directly edit the text portion. The user must click the arrow button to display the list portion.
|
||||
DropDownList = 2
|
||||
};
|
||||
}
|
13
r5dev/thirdparty/cppnet/cppkore/CompressionMode.h
vendored
Normal file
13
r5dev/thirdparty/cppnet/cppkore/CompressionMode.h
vendored
Normal file
@ -0,0 +1,13 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
namespace Compression
|
||||
{
|
||||
// Which mode of operation we are performing
|
||||
enum class CompressionMode
|
||||
{
|
||||
Compress,
|
||||
Decompress
|
||||
};
|
||||
}
|
563
r5dev/thirdparty/cppnet/cppkore/Console.cpp
vendored
Normal file
563
r5dev/thirdparty/cppnet/cppkore/Console.cpp
vendored
Normal file
@ -0,0 +1,563 @@
|
||||
#include "stdafx.h"
|
||||
#include "Console.h"
|
||||
#include "ConsoleStream.h"
|
||||
|
||||
namespace System
|
||||
{
|
||||
// This holds the global std handle for the input stream
|
||||
__ConsoleInit Console::ConsoleInstance = __ConsoleInit();
|
||||
|
||||
enum class ControlKeyState
|
||||
{
|
||||
RightAltPressed = 0x0001,
|
||||
LeftAltPressed = 0x0002,
|
||||
RightCtrlPressed = 0x0004,
|
||||
LeftCtrlPressed = 0x0008,
|
||||
ShiftPressed = 0x0010,
|
||||
NumLockOn = 0x0020,
|
||||
ScrollLockOn = 0x0040,
|
||||
CapsLockOn = 0x0080,
|
||||
EnhancedKey = 0x0100
|
||||
};
|
||||
|
||||
void Console::Beep()
|
||||
{
|
||||
::Beep(800, 200);
|
||||
}
|
||||
|
||||
void Console::Beep(uint32_t Frequency, uint32_t Duration)
|
||||
{
|
||||
::Beep(Frequency, Duration);
|
||||
}
|
||||
|
||||
void Console::Clear()
|
||||
{
|
||||
auto hStdOut = ((IO::ConsoleStream*)ConsoleInstance.Out.GetBaseStream())->GetStreamHandle();
|
||||
|
||||
CONSOLE_SCREEN_BUFFER_INFO cSBI{};
|
||||
GetConsoleScreenBufferInfo(hStdOut, &cSBI);
|
||||
|
||||
COORD cScreen{};
|
||||
int conSize = (cSBI.dwSize.X * cSBI.dwSize.Y);
|
||||
|
||||
DWORD nCellsWritten = 0;
|
||||
FillConsoleOutputCharacterA(hStdOut, ' ', conSize, cScreen, &nCellsWritten);
|
||||
|
||||
nCellsWritten = 0;
|
||||
FillConsoleOutputAttribute(hStdOut, FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED, conSize, cScreen, &nCellsWritten);
|
||||
|
||||
SetConsoleCursorPosition(hStdOut, cScreen);
|
||||
}
|
||||
|
||||
void Console::ClearLine()
|
||||
{
|
||||
auto hStdOut = ((IO::ConsoleStream*)ConsoleInstance.Out.GetBaseStream())->GetStreamHandle();
|
||||
|
||||
CONSOLE_SCREEN_BUFFER_INFO cSBI{};
|
||||
GetConsoleScreenBufferInfo(hStdOut, &cSBI);
|
||||
|
||||
cSBI.dwCursorPosition.X = 0;
|
||||
|
||||
DWORD nCellsWritten = 0;
|
||||
FillConsoleOutputCharacterA(hStdOut, ' ', cSBI.dwSize.X, cSBI.dwCursorPosition, &nCellsWritten);
|
||||
|
||||
SetConsoleCursorPosition(hStdOut, cSBI.dwCursorPosition);
|
||||
}
|
||||
|
||||
void Console::ResetColor()
|
||||
{
|
||||
Console::SetColors(ConsoleColor::Gray, ConsoleColor::Black);
|
||||
}
|
||||
|
||||
void Console::SetForegroundColor(ConsoleColor Color)
|
||||
{
|
||||
auto hStdOut = ((IO::ConsoleStream*)ConsoleInstance.Out.GetBaseStream())->GetStreamHandle();
|
||||
|
||||
CONSOLE_SCREEN_BUFFER_INFO cSBI{};
|
||||
GetConsoleScreenBufferInfo(hStdOut, &cSBI);
|
||||
|
||||
auto nColor = Console::ConsoleColorToColorAttribute(Color, false);
|
||||
|
||||
int16_t Attrs = cSBI.wAttributes;
|
||||
|
||||
Attrs &= ~((int16_t)Console::ForegroundMask);
|
||||
Attrs = (int16_t)(((uint32_t)(uint16_t)Attrs) | ((uint32_t)(uint16_t)nColor));
|
||||
|
||||
SetConsoleTextAttribute(hStdOut, Attrs);
|
||||
}
|
||||
|
||||
void Console::SetBackgroundColor(ConsoleColor Color)
|
||||
{
|
||||
auto hStdOut = ((IO::ConsoleStream*)ConsoleInstance.Out.GetBaseStream())->GetStreamHandle();
|
||||
|
||||
CONSOLE_SCREEN_BUFFER_INFO cSBI{};
|
||||
GetConsoleScreenBufferInfo(hStdOut, &cSBI);
|
||||
|
||||
auto nColor = Console::ConsoleColorToColorAttribute(Color, true);
|
||||
|
||||
int16_t Attrs = cSBI.wAttributes;
|
||||
|
||||
Attrs &= ~((int16_t)Console::BackgroundMask);
|
||||
Attrs = (int16_t)(((uint32_t)(uint16_t)Attrs) | ((uint32_t)(uint16_t)nColor));
|
||||
|
||||
SetConsoleTextAttribute(hStdOut, Attrs);
|
||||
}
|
||||
|
||||
void Console::SetColors(ConsoleColor Foreground, ConsoleColor Background)
|
||||
{
|
||||
auto hStdOut = ((IO::ConsoleStream*)ConsoleInstance.Out.GetBaseStream())->GetStreamHandle();
|
||||
|
||||
CONSOLE_SCREEN_BUFFER_INFO cSBI{};
|
||||
GetConsoleScreenBufferInfo(hStdOut, &cSBI);
|
||||
|
||||
auto nColor = Console::ConsoleColorToColorAttribute(Foreground, false);
|
||||
auto nColor2 = Console::ConsoleColorToColorAttribute(Background, true);
|
||||
|
||||
int16_t Attrs = cSBI.wAttributes;
|
||||
|
||||
Attrs &= ~((int16_t)Console::ForegroundMask);
|
||||
Attrs = (int16_t)(((uint32_t)(uint16_t)Attrs) | ((uint32_t)(uint16_t)nColor));
|
||||
|
||||
Attrs &= ~((int16_t)Console::BackgroundMask);
|
||||
Attrs = (int16_t)(((uint32_t)(uint16_t)Attrs) | ((uint32_t)(uint16_t)nColor2));
|
||||
|
||||
SetConsoleTextAttribute(hStdOut, Attrs);
|
||||
}
|
||||
|
||||
void Console::SetBufferSize(uint32_t Width, uint32_t Height)
|
||||
{
|
||||
COORD cScreen;
|
||||
cScreen.X = (SHORT)Width;
|
||||
cScreen.Y = (SHORT)Height;
|
||||
|
||||
SetConsoleScreenBufferSize(((IO::ConsoleStream*)ConsoleInstance.Out.GetBaseStream())->GetStreamHandle(), cScreen);
|
||||
}
|
||||
|
||||
void Console::SetCursorPosition(uint32_t Left, uint32_t Right)
|
||||
{
|
||||
auto hStdOut = ((IO::ConsoleStream*)ConsoleInstance.Out.GetBaseStream())->GetStreamHandle();
|
||||
|
||||
COORD cScreen;
|
||||
cScreen.X = (SHORT)Left;
|
||||
cScreen.Y = (SHORT)Right;
|
||||
|
||||
SetConsoleCursorPosition(hStdOut, cScreen);
|
||||
}
|
||||
|
||||
void Console::SetWindowSize(uint32_t Width, uint32_t Height)
|
||||
{
|
||||
auto hStdOut = ((IO::ConsoleStream*)ConsoleInstance.Out.GetBaseStream())->GetStreamHandle();
|
||||
|
||||
CONSOLE_SCREEN_BUFFER_INFO cSBI{};
|
||||
GetConsoleScreenBufferInfo(hStdOut, &cSBI);
|
||||
|
||||
COORD cScreen;
|
||||
cScreen.X = cSBI.dwSize.X;
|
||||
cScreen.Y = cSBI.dwSize.Y;
|
||||
|
||||
bool nBufferResize = false;
|
||||
if (cSBI.dwSize.X < (SHORT)(cSBI.srWindow.Left + Width))
|
||||
{
|
||||
cScreen.X = (SHORT)(cSBI.srWindow.Left + Width);
|
||||
nBufferResize = true;
|
||||
}
|
||||
if (cSBI.dwSize.Y < (SHORT)(cSBI.srWindow.Top + Height))
|
||||
{
|
||||
cScreen.Y = (SHORT)(cSBI.srWindow.Top + Height);
|
||||
nBufferResize = true;
|
||||
}
|
||||
|
||||
if (nBufferResize)
|
||||
SetConsoleScreenBufferSize(hStdOut, cScreen);
|
||||
|
||||
SMALL_RECT srWindow = cSBI.srWindow;
|
||||
srWindow.Bottom = (SHORT)(srWindow.Top + Height - 1);
|
||||
srWindow.Right = (SHORT)(srWindow.Left + Width - 1);
|
||||
|
||||
auto hResult = SetConsoleWindowInfo(hStdOut, true, &srWindow);
|
||||
if (!hResult)
|
||||
SetConsoleScreenBufferSize(hStdOut, cSBI.dwSize);
|
||||
}
|
||||
|
||||
void Console::SetWindowPosition(uint32_t Left, uint32_t Top)
|
||||
{
|
||||
auto hStdOut = ((IO::ConsoleStream*)ConsoleInstance.Out.GetBaseStream())->GetStreamHandle();
|
||||
|
||||
CONSOLE_SCREEN_BUFFER_INFO cSBI{};
|
||||
GetConsoleScreenBufferInfo(hStdOut, &cSBI);
|
||||
|
||||
SMALL_RECT srWindow = cSBI.srWindow;
|
||||
|
||||
srWindow.Bottom -= (SHORT)(srWindow.Top - Top);
|
||||
srWindow.Right -= (SHORT)(srWindow.Left - Left);
|
||||
srWindow.Left = (SHORT)Left;
|
||||
srWindow.Top = (SHORT)Top;
|
||||
|
||||
SetConsoleWindowInfo(hStdOut, TRUE, &srWindow);
|
||||
}
|
||||
|
||||
void Console::SetFontSize(uint32_t Width, uint32_t Height, uint32_t Weight)
|
||||
{
|
||||
auto hStdOut = ((IO::ConsoleStream*)ConsoleInstance.Out.GetBaseStream())->GetStreamHandle();
|
||||
|
||||
CONSOLE_FONT_INFOEX cFont;
|
||||
cFont.cbSize = sizeof(cFont);
|
||||
|
||||
GetCurrentConsoleFontEx(hStdOut, false, &cFont);
|
||||
|
||||
cFont.dwFontSize.X = Width;
|
||||
cFont.dwFontSize.Y = Height;
|
||||
cFont.FontWeight = Weight;
|
||||
|
||||
SetCurrentConsoleFontEx(hStdOut, false, &cFont);
|
||||
}
|
||||
|
||||
void Console::SetTitle(const string& Value)
|
||||
{
|
||||
SetConsoleTitleA((const char*)Value);
|
||||
}
|
||||
|
||||
void Console::SetTitle(const char* Value)
|
||||
{
|
||||
SetConsoleTitleA(Value);
|
||||
}
|
||||
|
||||
void Console::SetCursorVisible(bool Visible)
|
||||
{
|
||||
auto hStdOut = ((IO::ConsoleStream*)ConsoleInstance.Out.GetBaseStream())->GetStreamHandle();
|
||||
|
||||
CONSOLE_CURSOR_INFO cCI{};
|
||||
GetConsoleCursorInfo(hStdOut, &cCI);
|
||||
|
||||
cCI.bVisible = Visible;
|
||||
|
||||
SetConsoleCursorInfo(hStdOut, &cCI);
|
||||
}
|
||||
|
||||
void Console::MoveBufferArea(uint32_t SourceLeft, uint32_t SourceTop, uint32_t SourceWidth, uint32_t SourceHeight, uint32_t TargetLeft, uint32_t TargetTop, char SourceChar, ConsoleColor SourceForeColor, ConsoleColor SourceBackColor)
|
||||
{
|
||||
auto hStdOut = ((IO::ConsoleStream*)ConsoleInstance.Out.GetBaseStream())->GetStreamHandle();
|
||||
|
||||
CONSOLE_SCREEN_BUFFER_INFO cSBI{};
|
||||
GetConsoleScreenBufferInfo(hStdOut, &cSBI);
|
||||
|
||||
COORD BufferSize = cSBI.dwSize;
|
||||
COORD BufferCoord{};
|
||||
SMALL_RECT ReadRegion{};
|
||||
|
||||
if (SourceWidth == 0 || SourceHeight == 0)
|
||||
return;
|
||||
|
||||
auto CharBuffer = std::make_unique<CHAR_INFO[]>(SourceWidth * SourceHeight);
|
||||
|
||||
BufferSize.X = (SHORT)SourceWidth;
|
||||
BufferSize.Y = (SHORT)SourceHeight;
|
||||
ReadRegion.Left = (SHORT)SourceLeft;
|
||||
ReadRegion.Right = (SHORT)(SourceLeft + SourceWidth - 1);
|
||||
ReadRegion.Top = (SHORT)SourceTop;
|
||||
ReadRegion.Bottom = (SHORT)(SourceTop + SourceHeight - 1);
|
||||
|
||||
ReadConsoleOutput(hStdOut, CharBuffer.get(), BufferSize, BufferCoord, &ReadRegion);
|
||||
|
||||
COLORREF NativeColor = (Console::ConsoleColorToColorAttribute(SourceBackColor, true) | Console::ConsoleColorToColorAttribute(SourceForeColor, false));
|
||||
DWORD nWrite = 0;
|
||||
|
||||
COORD WriteCoord{};
|
||||
WriteCoord.X = (SHORT)SourceLeft;
|
||||
|
||||
SHORT Attr = (SHORT)NativeColor;
|
||||
for (uint32_t i = SourceTop; i < (SourceTop + SourceHeight); i++)
|
||||
{
|
||||
WriteCoord.Y = (SHORT)i;
|
||||
|
||||
FillConsoleOutputCharacterA(hStdOut, SourceChar, SourceWidth, WriteCoord, &nWrite);
|
||||
FillConsoleOutputAttribute(hStdOut, Attr, SourceWidth, WriteCoord, &nWrite);
|
||||
}
|
||||
|
||||
SMALL_RECT WriteRegion{};
|
||||
WriteRegion.Left = (SHORT)TargetLeft;
|
||||
WriteRegion.Right = (SHORT)(TargetLeft + SourceWidth);
|
||||
WriteRegion.Top = (SHORT)TargetTop;
|
||||
WriteRegion.Bottom = (SHORT)(TargetTop + SourceHeight);
|
||||
|
||||
WriteConsoleOutput(hStdOut, CharBuffer.get(), BufferSize, BufferCoord, &WriteRegion);
|
||||
}
|
||||
|
||||
void Console::SetMaximizeBoxVisible(bool Visible)
|
||||
{
|
||||
auto hConsole = GetConsoleWindow();
|
||||
auto Style = GetWindowLong(hConsole, GWL_STYLE);
|
||||
|
||||
if (Visible)
|
||||
Style |= WS_MAXIMIZEBOX;
|
||||
else
|
||||
Style &= ~WS_MAXIMIZEBOX;
|
||||
|
||||
SetWindowLong(hConsole, GWL_STYLE, Style);
|
||||
}
|
||||
|
||||
void Console::SetMinimizeBoxVisible(bool Visible)
|
||||
{
|
||||
auto hConsole = GetConsoleWindow();
|
||||
auto Style = GetWindowLong(hConsole, GWL_STYLE);
|
||||
|
||||
if (Visible)
|
||||
Style |= WS_MINIMIZEBOX;
|
||||
else
|
||||
Style &= ~WS_MINIMIZEBOX;
|
||||
|
||||
SetWindowLong(hConsole, GWL_STYLE, Style);
|
||||
}
|
||||
|
||||
void Console::SetWindowResizable(bool Resizable)
|
||||
{
|
||||
auto hConsole = GetConsoleWindow();
|
||||
auto Style = GetWindowLong(hConsole, GWL_STYLE);
|
||||
|
||||
if (Resizable)
|
||||
Style |= WS_SIZEBOX;
|
||||
else
|
||||
Style &= ~WS_SIZEBOX;
|
||||
|
||||
SetWindowLong(hConsole, GWL_STYLE, Style);
|
||||
}
|
||||
|
||||
void Console::CenterWindow()
|
||||
{
|
||||
auto hConsole = GetConsoleWindow();
|
||||
auto hMonitor = MonitorFromWindow(hConsole, MONITOR_DEFAULTTONEAREST);
|
||||
|
||||
if (hMonitor)
|
||||
{
|
||||
MONITORINFO Info;
|
||||
Info.cbSize = sizeof(Info);
|
||||
|
||||
if (GetMonitorInfo(hMonitor, &Info))
|
||||
{
|
||||
RECT cRect{};
|
||||
GetWindowRect(hConsole, &cRect);
|
||||
|
||||
auto Width = (cRect.right - cRect.left);
|
||||
auto Height = (cRect.bottom - cRect.top);
|
||||
|
||||
auto X = (Info.rcWork.left + Info.rcWork.right) / 2 - Width / 2;
|
||||
auto Y = (Info.rcWork.top + Info.rcWork.bottom) / 2 - Height / 2;
|
||||
|
||||
SetWindowPos(hConsole, NULL, X, Y, 0, 0, SWP_NOZORDER | SWP_NOOWNERZORDER | SWP_NOSIZE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Console::RemapConsoleColor(ConsoleColor Source, uint8_t R, uint8_t G, uint8_t B)
|
||||
{
|
||||
auto hStdOut = ((IO::ConsoleStream*)ConsoleInstance.Out.GetBaseStream())->GetStreamHandle();
|
||||
|
||||
CONSOLE_SCREEN_BUFFER_INFOEX cBuffer;
|
||||
cBuffer.cbSize = sizeof(cBuffer);
|
||||
GetConsoleScreenBufferInfoEx(hStdOut, &cBuffer);
|
||||
|
||||
// GetConsoleScreenBufferInfoEx returns one short here, so we keep resizing each time...
|
||||
cBuffer.srWindow.Bottom++;
|
||||
cBuffer.srWindow.Right++;
|
||||
|
||||
cBuffer.ColorTable[(int8_t)Source] = RGB(R, G, B);
|
||||
|
||||
SetConsoleScreenBufferInfoEx(hStdOut, &cBuffer);
|
||||
}
|
||||
|
||||
void Console::RemapAllConsoleColors(std::initializer_list<System::ConsoleColor> Colors)
|
||||
{
|
||||
static_assert(sizeof(Colors) == 16, "You must specify all 16 colors");
|
||||
|
||||
auto hStdOut = ((IO::ConsoleStream*)ConsoleInstance.Out.GetBaseStream())->GetStreamHandle();
|
||||
|
||||
CONSOLE_SCREEN_BUFFER_INFOEX cBuffer;
|
||||
cBuffer.cbSize = sizeof(cBuffer);
|
||||
GetConsoleScreenBufferInfoEx(hStdOut, &cBuffer);
|
||||
|
||||
// GetConsoleScreenBufferInfoEx returns one short here, so we keep resizing each time...
|
||||
cBuffer.srWindow.Bottom++;
|
||||
cBuffer.srWindow.Right++;
|
||||
|
||||
std::memcpy(cBuffer.ColorTable, Colors.begin(), sizeof(uint32_t) * 16);
|
||||
|
||||
SetConsoleScreenBufferInfoEx(hStdOut, &cBuffer);
|
||||
}
|
||||
|
||||
string Console::GetTitle()
|
||||
{
|
||||
char Buffer[2048]{};
|
||||
GetConsoleTitleA(Buffer, 2048); // Honestly it would be too big at 256...
|
||||
|
||||
return string(Buffer);
|
||||
}
|
||||
|
||||
bool Console::GetCursorVisible()
|
||||
{
|
||||
auto hStdOut = ((IO::ConsoleStream*)ConsoleInstance.Out.GetBaseStream())->GetStreamHandle();
|
||||
|
||||
CONSOLE_CURSOR_INFO cCI{};
|
||||
GetConsoleCursorInfo(hStdOut, &cCI);
|
||||
|
||||
return cCI.bVisible;
|
||||
}
|
||||
|
||||
ConsoleColor Console::GetForegroundColor()
|
||||
{
|
||||
auto hStdOut = ((IO::ConsoleStream*)ConsoleInstance.Out.GetBaseStream())->GetStreamHandle();
|
||||
|
||||
CONSOLE_SCREEN_BUFFER_INFO cSBI{};
|
||||
GetConsoleScreenBufferInfo(hStdOut, &cSBI);
|
||||
|
||||
return Console::ColorAttributeToConsoleColor((int16_t)(cSBI.wAttributes & Console::ForegroundMask));
|
||||
}
|
||||
|
||||
ConsoleColor Console::GetBackgroundColor()
|
||||
{
|
||||
auto hStdOut = ((IO::ConsoleStream*)ConsoleInstance.Out.GetBaseStream())->GetStreamHandle();
|
||||
|
||||
CONSOLE_SCREEN_BUFFER_INFO cSBI{};
|
||||
GetConsoleScreenBufferInfo(hStdOut, &cSBI);
|
||||
|
||||
return Console::ColorAttributeToConsoleColor((int16_t)(cSBI.wAttributes & Console::BackgroundMask));
|
||||
}
|
||||
|
||||
void Console::Header(const char* Heading, ConsoleColor Color)
|
||||
{
|
||||
Console::SetColors(Color, ConsoleColor::DarkGray);
|
||||
|
||||
auto sLen = strlen(Heading);
|
||||
|
||||
char HeaderBuffer[21];
|
||||
std::memset(HeaderBuffer + 1, ' ', 19);
|
||||
|
||||
HeaderBuffer[0] = '[';
|
||||
HeaderBuffer[20] = (char)0;
|
||||
HeaderBuffer[sLen + 1] = ']';
|
||||
|
||||
std::memcpy(HeaderBuffer + 1, Heading, sLen);
|
||||
|
||||
ConsoleInstance.Out.Write((const char*)HeaderBuffer);
|
||||
|
||||
Console::ResetColor();
|
||||
|
||||
ConsoleInstance.Out.Write(": ");
|
||||
}
|
||||
|
||||
void Console::Progress(const char* Heading, ConsoleColor Color, uint32_t Width, uint32_t Progress)
|
||||
{
|
||||
Progress = min(Progress, 100);
|
||||
|
||||
ConsoleInstance.Out.Write("\r");
|
||||
Console::Header(Heading, Color);
|
||||
|
||||
string Buffer(Width + 2, '\0', false);
|
||||
Buffer.Append("[");
|
||||
|
||||
uint32_t Blocks = min((uint32_t)((Progress / 100.f) * Width), Width);
|
||||
for (uint32_t i = 0; i < Width; i++)
|
||||
{
|
||||
if (i < Blocks)
|
||||
Buffer.Append("=");
|
||||
else if (i == Blocks)
|
||||
Buffer.Append(">");
|
||||
else
|
||||
Buffer.Append(" ");
|
||||
}
|
||||
|
||||
Buffer.Append("]");
|
||||
|
||||
ConsoleInstance.Out.Write(Buffer);
|
||||
}
|
||||
|
||||
int32_t Console::Read()
|
||||
{
|
||||
return ConsoleInstance.In.Read();
|
||||
}
|
||||
|
||||
ConsoleKeyInfo Console::ReadKey(bool Intercept)
|
||||
{
|
||||
INPUT_RECORD iRecord{};
|
||||
DWORD rRead = 0;
|
||||
|
||||
auto hStdIn = ((IO::ConsoleStream*)ConsoleInstance.In.GetBaseStream())->GetStreamHandle();
|
||||
|
||||
while (true)
|
||||
{
|
||||
ReadConsoleInputA(hStdIn, &iRecord, 1, &rRead);
|
||||
|
||||
int16_t kCode = iRecord.Event.KeyEvent.wVirtualKeyCode;
|
||||
|
||||
if (!IsKeyDownEvent(iRecord))
|
||||
if (kCode != AltVKCode)
|
||||
continue;
|
||||
|
||||
char Ch = (char)iRecord.Event.KeyEvent.uChar.AsciiChar;
|
||||
|
||||
if (Ch == 0)
|
||||
if (IsModKey(iRecord))
|
||||
continue;
|
||||
|
||||
ConsoleKey key = (ConsoleKey)kCode;
|
||||
if (IsAltKeyDown(iRecord) && ((key >= ConsoleKey::NumPad0 && key <= ConsoleKey::NumPad9) || (key == ConsoleKey::Clear) || (key == ConsoleKey::Insert) || (key >= ConsoleKey::PageUp && key <= ConsoleKey::DownArrow)))
|
||||
continue;
|
||||
|
||||
// We passed all checks
|
||||
break;
|
||||
}
|
||||
|
||||
// Calculate key status
|
||||
auto State = iRecord.Event.KeyEvent.dwControlKeyState;
|
||||
bool Shift = (State & (uint32_t)ControlKeyState::ShiftPressed) != 0;
|
||||
bool Alt = (State & ((uint32_t)ControlKeyState::LeftAltPressed | (uint32_t)ControlKeyState::RightAltPressed)) != 0;
|
||||
bool Control = (State & ((uint32_t)ControlKeyState::LeftCtrlPressed | (uint32_t)ControlKeyState::RightCtrlPressed)) != 0;
|
||||
|
||||
if (!Intercept)
|
||||
{
|
||||
char iBuffer[] = { iRecord.Event.KeyEvent.uChar.AsciiChar, 0 };
|
||||
Console::Write(iBuffer);
|
||||
}
|
||||
|
||||
return ConsoleKeyInfo((char)iRecord.Event.KeyEvent.uChar.AsciiChar, (ConsoleKey)iRecord.Event.KeyEvent.wVirtualKeyCode, Shift, Alt, Control);
|
||||
}
|
||||
|
||||
string Console::ReadLine()
|
||||
{
|
||||
return ConsoleInstance.In.ReadLine();
|
||||
}
|
||||
|
||||
bool Console::IsKeyDownEvent(INPUT_RECORD iRecord)
|
||||
{
|
||||
return (iRecord.EventType == KEY_EVENT && iRecord.Event.KeyEvent.bKeyDown);
|
||||
}
|
||||
|
||||
bool Console::IsModKey(INPUT_RECORD iRecord)
|
||||
{
|
||||
int16_t keyCode = iRecord.Event.KeyEvent.wVirtualKeyCode;
|
||||
|
||||
return ((keyCode >= 0x10 && keyCode <= 0x12) || keyCode == 0x14 || keyCode == 0x90 || keyCode == 0x91);
|
||||
}
|
||||
|
||||
bool Console::IsAltKeyDown(INPUT_RECORD iRecord)
|
||||
{
|
||||
return ((iRecord.Event.KeyEvent.dwControlKeyState) & ((uint32_t)ControlKeyState::LeftAltPressed | (uint32_t)ControlKeyState::RightAltPressed)) != 0;
|
||||
}
|
||||
|
||||
ConsoleColor Console::ColorAttributeToConsoleColor(int16_t Attribute)
|
||||
{
|
||||
if ((Attribute & Console::BackgroundMask) != 0)
|
||||
Attribute = (int32_t)(((int32_t)Attribute) >> 4);
|
||||
|
||||
return ConsoleColor(Attribute);
|
||||
}
|
||||
|
||||
int16_t Console::ConsoleColorToColorAttribute(ConsoleColor Color, bool isBackground)
|
||||
{
|
||||
auto Result = (int16_t)Color;
|
||||
|
||||
if (isBackground)
|
||||
Result = (int16_t)((int32_t)Result << 4);
|
||||
|
||||
return Result;
|
||||
}
|
||||
}
|
133
r5dev/thirdparty/cppnet/cppkore/Console.h
vendored
Normal file
133
r5dev/thirdparty/cppnet/cppkore/Console.h
vendored
Normal file
@ -0,0 +1,133 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <cstdio>
|
||||
#include "StringBase.h"
|
||||
#include "ConsoleKey.h"
|
||||
#include "ConsoleColor.h"
|
||||
#include "__ConsoleInit.h"
|
||||
#include "ConsoleKeyInfo.h"
|
||||
|
||||
namespace System
|
||||
{
|
||||
class Console
|
||||
{
|
||||
public:
|
||||
// Trigger a standard console beep sound
|
||||
static void Beep();
|
||||
// Trigger a custom console beep sound
|
||||
static void Beep(uint32_t Frequency, uint32_t Duration);
|
||||
// Clears the console window
|
||||
static void Clear();
|
||||
// Clears the current console line
|
||||
static void ClearLine();
|
||||
// Resets the colors
|
||||
static void ResetColor();
|
||||
|
||||
// Sets the foreground color
|
||||
static void SetForegroundColor(ConsoleColor Color);
|
||||
// Sets the background color
|
||||
static void SetBackgroundColor(ConsoleColor Color);
|
||||
// Sets both colors
|
||||
static void SetColors(ConsoleColor Foreground, ConsoleColor Background);
|
||||
|
||||
// Sets the console buffer size
|
||||
static void SetBufferSize(uint32_t Width, uint32_t Height);
|
||||
// Moves the cursor to the specified position
|
||||
static void SetCursorPosition(uint32_t Left, uint32_t Right);
|
||||
// Changes the size of the console window
|
||||
static void SetWindowSize(uint32_t Width, uint32_t Height);
|
||||
// Changes the position of the console window
|
||||
static void SetWindowPosition(uint32_t Left, uint32_t Top);
|
||||
// Changes the font of the console window
|
||||
static void SetFontSize(uint32_t Width, uint32_t Height, uint32_t Weight);
|
||||
// Sets the window title
|
||||
static void SetTitle(const string& Value);
|
||||
// Sets the window title
|
||||
static void SetTitle(const char* Value);
|
||||
// Sets whether or not the cursor is visible
|
||||
static void SetCursorVisible(bool Visible);
|
||||
|
||||
// Moves the specified area in the buffer to another location
|
||||
static void MoveBufferArea(uint32_t SourceLeft, uint32_t SourceTop, uint32_t SourceWidth, uint32_t SourceHeight, uint32_t TargetLeft, uint32_t TargetTop, char SourceChar, ConsoleColor SourceForeColor = ConsoleColor::Gray, ConsoleColor SourceBackColor = ConsoleColor::Black);
|
||||
|
||||
// Sets whether or not the maximize box is visible
|
||||
static void SetMaximizeBoxVisible(bool Visible);
|
||||
// Sets whether or not the minimize box is visible
|
||||
static void SetMinimizeBoxVisible(bool Visible);
|
||||
// Make the window resizable
|
||||
static void SetWindowResizable(bool Resizable);
|
||||
|
||||
// Centers the console window on the current screen
|
||||
static void CenterWindow();
|
||||
|
||||
// Reassign an existing console color
|
||||
static void RemapConsoleColor(ConsoleColor Source, uint8_t R, uint8_t G, uint8_t B);
|
||||
// Reassign all existing console colors
|
||||
static void RemapAllConsoleColors(std::initializer_list<System::ConsoleColor> Colors);
|
||||
|
||||
// Gets the window title
|
||||
static string GetTitle();
|
||||
// Gets whether or not the cursor is visible
|
||||
static bool GetCursorVisible();
|
||||
// Gets the current foreground color
|
||||
static ConsoleColor GetForegroundColor();
|
||||
// Gets the current background color
|
||||
static ConsoleColor GetBackgroundColor();
|
||||
|
||||
// Writes text to the console
|
||||
template<class... TArgs>
|
||||
static void Write(const char* Format, TArgs&&... Args);
|
||||
// Writes a line to the console
|
||||
template<class... TArgs>
|
||||
static void WriteLine(const char* Format = nullptr, TArgs&&... Args);
|
||||
|
||||
// Writes a heading to the console
|
||||
static void Header(const char* Heading, ConsoleColor Color);
|
||||
// Generates a progress bar in the console
|
||||
static void Progress(const char* Heading, ConsoleColor Color, uint32_t Width, uint32_t Progress);
|
||||
|
||||
// Read a character
|
||||
static int32_t Read();
|
||||
// Reads a key
|
||||
static ConsoleKeyInfo ReadKey(bool Intercept = false);
|
||||
// Reads a line from the console
|
||||
static string ReadLine();
|
||||
|
||||
private:
|
||||
|
||||
// Internal routine for IsKeyDown event
|
||||
static bool IsKeyDownEvent(INPUT_RECORD iRecord);
|
||||
// Internal routine for IsModKey event
|
||||
static bool IsModKey(INPUT_RECORD iRecord);
|
||||
// Internal routine for IsAltKeyDown event
|
||||
static bool IsAltKeyDown(INPUT_RECORD iRecord);
|
||||
|
||||
// Internal routine to convert an internal console color to a ConsoleColor
|
||||
static ConsoleColor ColorAttributeToConsoleColor(int16_t Attribute);
|
||||
// Internal routine to convert a ConsoleColor to an internal console color
|
||||
static int16_t ConsoleColorToColorAttribute(ConsoleColor Color, bool isBackground);
|
||||
|
||||
// Internal console handle
|
||||
static __ConsoleInit ConsoleInstance;
|
||||
|
||||
// The alternate virtual key code
|
||||
static constexpr int16_t AltVKCode = 0x12;
|
||||
|
||||
// Masks for internal data
|
||||
static constexpr int16_t ForegroundMask = 0xf;
|
||||
static constexpr int16_t BackgroundMask = 0xf0;
|
||||
};
|
||||
|
||||
template<class... TArgs>
|
||||
inline void Console::Write(const char* Format, TArgs&&... Args)
|
||||
{
|
||||
ConsoleInstance.Out.WriteFmt(Format, std::forward<TArgs>(Args)...);
|
||||
}
|
||||
|
||||
template<class... TArgs>
|
||||
inline void Console::WriteLine(const char* Format, TArgs&&... Args)
|
||||
{
|
||||
ConsoleInstance.Out.WriteLineFmt(Format, std::forward<TArgs>(Args)...);
|
||||
}
|
||||
}
|
23
r5dev/thirdparty/cppnet/cppkore/ConsoleColor.cpp
vendored
Normal file
23
r5dev/thirdparty/cppnet/cppkore/ConsoleColor.cpp
vendored
Normal file
@ -0,0 +1,23 @@
|
||||
#include "stdafx.h"
|
||||
#include "ConsoleColor.h"
|
||||
|
||||
namespace System
|
||||
{
|
||||
// Predefine the existing colors
|
||||
ConsoleColor ConsoleColor::Black = ConsoleColor(0);
|
||||
ConsoleColor ConsoleColor::DarkBlue = ConsoleColor(1);
|
||||
ConsoleColor ConsoleColor::DarkGreen = ConsoleColor(2);
|
||||
ConsoleColor ConsoleColor::DarkCyan = ConsoleColor(3);
|
||||
ConsoleColor ConsoleColor::DarkRed = ConsoleColor(4);
|
||||
ConsoleColor ConsoleColor::DarkMagenta = ConsoleColor(5);
|
||||
ConsoleColor ConsoleColor::DarkYellow = ConsoleColor(6);
|
||||
ConsoleColor ConsoleColor::Gray = ConsoleColor(7);
|
||||
ConsoleColor ConsoleColor::DarkGray = ConsoleColor(8);
|
||||
ConsoleColor ConsoleColor::Blue = ConsoleColor(9);
|
||||
ConsoleColor ConsoleColor::Green = ConsoleColor(10);
|
||||
ConsoleColor ConsoleColor::Cyan = ConsoleColor(11);
|
||||
ConsoleColor ConsoleColor::Red = ConsoleColor(12);
|
||||
ConsoleColor ConsoleColor::Magenta = ConsoleColor(13);
|
||||
ConsoleColor ConsoleColor::Yellow = ConsoleColor(14);
|
||||
ConsoleColor ConsoleColor::White = ConsoleColor(15);
|
||||
}
|
69
r5dev/thirdparty/cppnet/cppkore/ConsoleColor.h
vendored
Normal file
69
r5dev/thirdparty/cppnet/cppkore/ConsoleColor.h
vendored
Normal file
@ -0,0 +1,69 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
namespace System
|
||||
{
|
||||
// This represents the colors that can be used for console text foreground and background colors.
|
||||
struct ConsoleColor
|
||||
{
|
||||
union
|
||||
{
|
||||
uint32_t NativeIndex;
|
||||
uint32_t Color;
|
||||
};
|
||||
|
||||
constexpr ConsoleColor()
|
||||
: NativeIndex(0)
|
||||
{
|
||||
}
|
||||
|
||||
// Construct a ConsoleColor from the built-in index
|
||||
constexpr ConsoleColor(uint32_t Index)
|
||||
: NativeIndex(Index)
|
||||
{
|
||||
}
|
||||
|
||||
// Construct a new ConsoleColor from the given RGB
|
||||
constexpr ConsoleColor(uint8_t R, uint8_t G, uint8_t B)
|
||||
: Color(((uint32_t)(((uint8_t)(R) | ((uint16_t)((uint8_t)(G)) << 8)) | (((uint32_t)(uint8_t)(B)) << 16))))
|
||||
{
|
||||
}
|
||||
|
||||
constexpr operator const uint32_t(void) const
|
||||
{
|
||||
return (uint32_t)NativeIndex;
|
||||
}
|
||||
constexpr operator const int32_t(void) const
|
||||
{
|
||||
return (int32_t)NativeIndex;
|
||||
}
|
||||
constexpr operator const int8_t(void) const
|
||||
{
|
||||
return (int8_t)NativeIndex;
|
||||
}
|
||||
constexpr operator const int16_t(void) const
|
||||
{
|
||||
return (int16_t)NativeIndex;
|
||||
}
|
||||
|
||||
static ConsoleColor Black;
|
||||
static ConsoleColor DarkBlue;
|
||||
static ConsoleColor DarkGreen;
|
||||
static ConsoleColor DarkCyan;
|
||||
static ConsoleColor DarkRed;
|
||||
static ConsoleColor DarkMagenta;
|
||||
static ConsoleColor DarkYellow;
|
||||
static ConsoleColor Gray;
|
||||
static ConsoleColor DarkGray;
|
||||
static ConsoleColor Blue;
|
||||
static ConsoleColor Green;
|
||||
static ConsoleColor Cyan;
|
||||
static ConsoleColor Red;
|
||||
static ConsoleColor Magenta;
|
||||
static ConsoleColor Yellow;
|
||||
static ConsoleColor White;
|
||||
};
|
||||
|
||||
static_assert(sizeof(ConsoleColor) == 4, "System::ConsoleColor size mismatch, expected 4!");
|
||||
}
|
196
r5dev/thirdparty/cppnet/cppkore/ConsoleKey.h
vendored
Normal file
196
r5dev/thirdparty/cppnet/cppkore/ConsoleKey.h
vendored
Normal file
@ -0,0 +1,196 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
namespace System
|
||||
{
|
||||
// This enumeration represents characters returned from a keyboard.
|
||||
enum class ConsoleKey : int16_t
|
||||
{
|
||||
Backspace = 0x8,
|
||||
Tab = 0x9,
|
||||
// 0xA, // Reserved
|
||||
// 0xB, // Reserved
|
||||
Clear = 0xC,
|
||||
Enter = 0xD,
|
||||
// 0E-0F, // Undefined
|
||||
// SHIFT = 0x10,
|
||||
// CONTROL = 0x11,
|
||||
// Alt = 0x12,
|
||||
Pause = 0x13,
|
||||
// CAPSLOCK = 0x14,
|
||||
// Kana = 0x15, // Ime Mode
|
||||
// Hangul = 0x15, // Ime Mode
|
||||
// 0x16, // Undefined
|
||||
// Junja = 0x17, // Ime Mode
|
||||
// Final = 0x18, // Ime Mode
|
||||
// Hanja = 0x19, // Ime Mode
|
||||
// Kanji = 0x19, // Ime Mode
|
||||
// 0x1A, // Undefined
|
||||
Escape = 0x1B,
|
||||
// Convert = 0x1C, // Ime Mode
|
||||
// NonConvert = 0x1D, // Ime Mode
|
||||
// Accept = 0x1E, // Ime Mode
|
||||
// ModeChange = 0x1F, // Ime Mode
|
||||
Spacebar = 0x20,
|
||||
PageUp = 0x21,
|
||||
PageDown = 0x22,
|
||||
End = 0x23,
|
||||
Home = 0x24,
|
||||
LeftArrow = 0x25,
|
||||
UpArrow = 0x26,
|
||||
RightArrow = 0x27,
|
||||
DownArrow = 0x28,
|
||||
Select = 0x29,
|
||||
Print = 0x2A,
|
||||
Execute = 0x2B,
|
||||
PrintScreen = 0x2C,
|
||||
Insert = 0x2D,
|
||||
Delete = 0x2E,
|
||||
Help = 0x2F,
|
||||
D0 = 0x30, // 0 through 9
|
||||
D1 = 0x31,
|
||||
D2 = 0x32,
|
||||
D3 = 0x33,
|
||||
D4 = 0x34,
|
||||
D5 = 0x35,
|
||||
D6 = 0x36,
|
||||
D7 = 0x37,
|
||||
D8 = 0x38,
|
||||
D9 = 0x39,
|
||||
// 3A-40 , // Undefined
|
||||
A = 0x41,
|
||||
B = 0x42,
|
||||
C = 0x43,
|
||||
D = 0x44,
|
||||
E = 0x45,
|
||||
F = 0x46,
|
||||
G = 0x47,
|
||||
H = 0x48,
|
||||
I = 0x49,
|
||||
J = 0x4A,
|
||||
K = 0x4B,
|
||||
L = 0x4C,
|
||||
M = 0x4D,
|
||||
N = 0x4E,
|
||||
O = 0x4F,
|
||||
P = 0x50,
|
||||
Q = 0x51,
|
||||
R = 0x52,
|
||||
S = 0x53,
|
||||
T = 0x54,
|
||||
U = 0x55,
|
||||
V = 0x56,
|
||||
W = 0x57,
|
||||
X = 0x58,
|
||||
Y = 0x59,
|
||||
Z = 0x5A,
|
||||
LeftWindows = 0x5B, // Microsoft Natural keyboard
|
||||
RightWindows = 0x5C, // Microsoft Natural keyboard
|
||||
Applications = 0x5D, // Microsoft Natural keyboard
|
||||
// 5E , // Reserved
|
||||
Sleep = 0x5F, // Computer Sleep Key
|
||||
NumPad0 = 0x60,
|
||||
NumPad1 = 0x61,
|
||||
NumPad2 = 0x62,
|
||||
NumPad3 = 0x63,
|
||||
NumPad4 = 0x64,
|
||||
NumPad5 = 0x65,
|
||||
NumPad6 = 0x66,
|
||||
NumPad7 = 0x67,
|
||||
NumPad8 = 0x68,
|
||||
NumPad9 = 0x69,
|
||||
Multiply = 0x6A,
|
||||
Add = 0x6B,
|
||||
Separator = 0x6C,
|
||||
Subtract = 0x6D,
|
||||
Decimal = 0x6E,
|
||||
Divide = 0x6F,
|
||||
F1 = 0x70,
|
||||
F2 = 0x71,
|
||||
F3 = 0x72,
|
||||
F4 = 0x73,
|
||||
F5 = 0x74,
|
||||
F6 = 0x75,
|
||||
F7 = 0x76,
|
||||
F8 = 0x77,
|
||||
F9 = 0x78,
|
||||
F10 = 0x79,
|
||||
F11 = 0x7A,
|
||||
F12 = 0x7B,
|
||||
F13 = 0x7C,
|
||||
F14 = 0x7D,
|
||||
F15 = 0x7E,
|
||||
F16 = 0x7F,
|
||||
F17 = 0x80,
|
||||
F18 = 0x81,
|
||||
F19 = 0x82,
|
||||
F20 = 0x83,
|
||||
F21 = 0x84,
|
||||
F22 = 0x85,
|
||||
F23 = 0x86,
|
||||
F24 = 0x87,
|
||||
// 88-8F, // Undefined
|
||||
// NumberLock = 0x90,
|
||||
// ScrollLock = 0x91,
|
||||
// 0x92, // OEM Specific
|
||||
// 97-9F , // Undefined
|
||||
// LeftShift = 0xA0,
|
||||
// RightShift = 0xA1,
|
||||
// LeftControl = 0xA2,
|
||||
// RightControl = 0xA3,
|
||||
// LeftAlt = 0xA4,
|
||||
// RightAlt = 0xA5,
|
||||
BrowserBack = 0xA6, // Windows 2000/XP
|
||||
BrowserForward = 0xA7, // Windows 2000/XP
|
||||
BrowserRefresh = 0xA8, // Windows 2000/XP
|
||||
BrowserStop = 0xA9, // Windows 2000/XP
|
||||
BrowserSearch = 0xAA, // Windows 2000/XP
|
||||
BrowserFavorites = 0xAB, // Windows 2000/XP
|
||||
BrowserHome = 0xAC, // Windows 2000/XP
|
||||
VolumeMute = 0xAD, // Windows 2000/XP
|
||||
VolumeDown = 0xAE, // Windows 2000/XP
|
||||
VolumeUp = 0xAF, // Windows 2000/XP
|
||||
MediaNext = 0xB0, // Windows 2000/XP
|
||||
MediaPrevious = 0xB1, // Windows 2000/XP
|
||||
MediaStop = 0xB2, // Windows 2000/XP
|
||||
MediaPlay = 0xB3, // Windows 2000/XP
|
||||
LaunchMail = 0xB4, // Windows 2000/XP
|
||||
LaunchMediaSelect = 0xB5, // Windows 2000/XP
|
||||
LaunchApp1 = 0xB6, // Windows 2000/XP
|
||||
LaunchApp2 = 0xB7, // Windows 2000/XP
|
||||
// B8-B9, // Reserved
|
||||
Oem1 = 0xBA, // Misc characters, varies by keyboard. For US standard, ;:
|
||||
OemPlus = 0xBB, // Misc characters, varies by keyboard. For US standard, +
|
||||
OemComma = 0xBC, // Misc characters, varies by keyboard. For US standard, ,
|
||||
OemMinus = 0xBD, // Misc characters, varies by keyboard. For US standard, -
|
||||
OemPeriod = 0xBE, // Misc characters, varies by keyboard. For US standard, .
|
||||
Oem2 = 0xBF, // Misc characters, varies by keyboard. For US standard, /?
|
||||
Oem3 = 0xC0, // Misc characters, varies by keyboard. For US standard, `~
|
||||
// 0xC1, // Reserved
|
||||
// D8-DA, // Unassigned
|
||||
Oem4 = 0xDB, // Misc characters, varies by keyboard. For US standard, [{
|
||||
Oem5 = 0xDC, // Misc characters, varies by keyboard. For US standard, \|
|
||||
Oem6 = 0xDD, // Misc characters, varies by keyboard. For US standard, ]}
|
||||
Oem7 = 0xDE, // Misc characters, varies by keyboard. For US standard,
|
||||
Oem8 = 0xDF, // Used for miscellaneous characters; it can vary by keyboard
|
||||
// 0xE0, // Reserved
|
||||
// 0xE1, // OEM specific
|
||||
Oem102 = 0xE2, // Win2K/XP: Either angle or backslash on RT 102-key keyboard
|
||||
// 0xE3, // OEM specific
|
||||
Process = 0xE5, // Windows: IME Process Key
|
||||
// 0xE6, // OEM specific
|
||||
Packet = 0xE7, // Win2K/XP: Used to pass Unicode chars as if keystrokes
|
||||
// 0xE8, // Unassigned
|
||||
// 0xE9, // OEM specific
|
||||
Attention = 0xF6,
|
||||
CrSel = 0xF7,
|
||||
ExSel = 0xF8,
|
||||
EraseEndOfFile = 0xF9,
|
||||
Play = 0xFA,
|
||||
Zoom = 0xFB,
|
||||
NoName = 0xFC, // Reserved
|
||||
Pa1 = 0xFD,
|
||||
OemClear = 0xFE,
|
||||
};
|
||||
}
|
35
r5dev/thirdparty/cppnet/cppkore/ConsoleKeyInfo.h
vendored
Normal file
35
r5dev/thirdparty/cppnet/cppkore/ConsoleKeyInfo.h
vendored
Normal file
@ -0,0 +1,35 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include "ConsoleKey.h"
|
||||
|
||||
namespace System
|
||||
{
|
||||
// Control key modifiers
|
||||
enum class ConsoleModifiers : uint8_t
|
||||
{
|
||||
None = 0,
|
||||
Alt = 1,
|
||||
Shift = 2,
|
||||
Control = 4
|
||||
};
|
||||
|
||||
// Information about the current keystroke
|
||||
struct ConsoleKeyInfo
|
||||
{
|
||||
char KeyChar;
|
||||
ConsoleKey Key;
|
||||
ConsoleModifiers Modifiers;
|
||||
|
||||
ConsoleKeyInfo(char kChar, ConsoleKey Key, bool Shift, bool Alt, bool Control)
|
||||
: KeyChar(kChar), Key(Key), Modifiers(ConsoleModifiers::None)
|
||||
{
|
||||
if (Shift)
|
||||
*(uint8_t*)&Modifiers |= (uint8_t)ConsoleModifiers::Shift;
|
||||
if (Alt)
|
||||
*(uint8_t*)&Modifiers |= (uint8_t)ConsoleModifiers::Alt;
|
||||
if (Control)
|
||||
*(uint8_t*)&Modifiers |= (uint8_t)ConsoleModifiers::Control;
|
||||
}
|
||||
};
|
||||
}
|
131
r5dev/thirdparty/cppnet/cppkore/ConsoleStream.cpp
vendored
Normal file
131
r5dev/thirdparty/cppnet/cppkore/ConsoleStream.cpp
vendored
Normal file
@ -0,0 +1,131 @@
|
||||
#include "stdafx.h"
|
||||
#include "ConsoleStream.h"
|
||||
|
||||
namespace IO
|
||||
{
|
||||
ConsoleStream::ConsoleStream(HANDLE StreamHandle, FileAccess Access)
|
||||
: _Handle(StreamHandle)
|
||||
{
|
||||
this->_CanRead = (((uint8_t)Access & (uint8_t)FileAccess::Read) == (uint8_t)FileAccess::Read);
|
||||
this->_CanRead = (((uint8_t)Access & (uint8_t)FileAccess::Write) == (uint8_t)FileAccess::Write);
|
||||
this->_IsPipe = (GetFileType(StreamHandle) == FILE_TYPE_PIPE);
|
||||
}
|
||||
|
||||
ConsoleStream::~ConsoleStream()
|
||||
{
|
||||
this->Close();
|
||||
}
|
||||
|
||||
void ConsoleStream::Seek(uint64_t Offset, SeekOrigin Origin)
|
||||
{
|
||||
IOError::StreamNoSeekSupport();
|
||||
}
|
||||
|
||||
uint64_t ConsoleStream::Read(uint8_t* Buffer, uint64_t Offset, uint64_t Count)
|
||||
{
|
||||
// Wait for available input...
|
||||
ConsoleStream::WaitForAvailableConsoleInput(this->_Handle, this->_IsPipe);
|
||||
|
||||
DWORD bRead = 0;
|
||||
ReadFile(this->_Handle, Buffer + Offset, (DWORD)Count, &bRead, NULL);
|
||||
|
||||
return bRead;
|
||||
}
|
||||
|
||||
uint64_t ConsoleStream::Read(uint8_t * Buffer, uint64_t Offset, uint64_t Count, uint64_t Position)
|
||||
{
|
||||
IOError::StreamNoSeekSupport();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ConsoleStream::Write(uint8_t* Buffer, uint64_t Offset, uint64_t Count)
|
||||
{
|
||||
DWORD bWrite = 0;
|
||||
WriteFile(this->_Handle, Buffer + Offset, (DWORD)Count, &bWrite, NULL);
|
||||
}
|
||||
|
||||
void ConsoleStream::Write(uint8_t * Buffer, uint64_t Offset, uint64_t Count, uint64_t Position)
|
||||
{
|
||||
IOError::StreamNoSeekSupport();
|
||||
}
|
||||
|
||||
HANDLE ConsoleStream::GetStreamHandle() const
|
||||
{
|
||||
return this->_Handle;
|
||||
}
|
||||
|
||||
void ConsoleStream::Close()
|
||||
{
|
||||
this->_Handle = nullptr;
|
||||
this->_CanRead = false;
|
||||
this->_CanWrite = false;
|
||||
}
|
||||
|
||||
void ConsoleStream::Flush()
|
||||
{
|
||||
}
|
||||
|
||||
bool ConsoleStream::CanRead()
|
||||
{
|
||||
return this->_CanRead;
|
||||
}
|
||||
|
||||
bool ConsoleStream::CanWrite()
|
||||
{
|
||||
return this->_CanWrite;
|
||||
}
|
||||
|
||||
bool ConsoleStream::CanSeek()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ConsoleStream::GetIsEndOfFile()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
uint64_t ConsoleStream::GetLength()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
uint64_t ConsoleStream::GetPosition()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ConsoleStream::SetLength(uint64_t Length)
|
||||
{
|
||||
IOError::StreamNoSeekSupport();
|
||||
}
|
||||
|
||||
void ConsoleStream::SetPosition(uint64_t Position)
|
||||
{
|
||||
IOError::StreamNoSeekSupport();
|
||||
}
|
||||
|
||||
void ConsoleStream::WaitForAvailableConsoleInput(HANDLE hHandle, bool IsPipe)
|
||||
{
|
||||
bool sWait = false;
|
||||
|
||||
if (IsPipe)
|
||||
{
|
||||
|
||||
DWORD cBytesRead, cTotalBytesAvailable, cBytesLeftThisMessage;
|
||||
auto Result = PeekNamedPipe(hHandle, NULL, 0, &cBytesRead, &cTotalBytesAvailable, &cBytesLeftThisMessage);
|
||||
if (Result != 0)
|
||||
{
|
||||
sWait = (cTotalBytesAvailable > 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
auto eCode = GetLastError();
|
||||
sWait = eCode == ERROR_BROKEN_PIPE || eCode == ERROR_NO_DATA || eCode == ERROR_PIPE_NOT_CONNECTED;
|
||||
}
|
||||
}
|
||||
|
||||
if (!sWait)
|
||||
WaitForSingleObjectEx(hHandle, INFINITE, TRUE);
|
||||
}
|
||||
}
|
52
r5dev/thirdparty/cppnet/cppkore/ConsoleStream.h
vendored
Normal file
52
r5dev/thirdparty/cppnet/cppkore/ConsoleStream.h
vendored
Normal file
@ -0,0 +1,52 @@
|
||||
#pragma once
|
||||
|
||||
#include "Stream.h"
|
||||
#include "FileMode.h"
|
||||
#include "FileAccess.h"
|
||||
#include "FileShare.h"
|
||||
#include <Windows.h>
|
||||
|
||||
namespace IO
|
||||
{
|
||||
// ConsoleStream supports reading and writing from stdin/out
|
||||
class ConsoleStream : public Stream
|
||||
{
|
||||
public:
|
||||
ConsoleStream(HANDLE StreamHandle, FileAccess Access);
|
||||
virtual ~ConsoleStream();
|
||||
|
||||
// Implement Getters and Setters
|
||||
virtual bool CanRead();
|
||||
virtual bool CanWrite();
|
||||
virtual bool CanSeek();
|
||||
virtual bool GetIsEndOfFile();
|
||||
virtual uint64_t GetLength();
|
||||
virtual uint64_t GetPosition();
|
||||
virtual void SetLength(uint64_t Length);
|
||||
virtual void SetPosition(uint64_t Position);
|
||||
|
||||
// Implement functions
|
||||
virtual void Close();
|
||||
virtual void Flush();
|
||||
virtual void Seek(uint64_t Offset, SeekOrigin Origin);
|
||||
virtual uint64_t Read(uint8_t* Buffer, uint64_t Offset, uint64_t Count);
|
||||
virtual uint64_t Read(uint8_t* Buffer, uint64_t Offset, uint64_t Count, uint64_t Position);
|
||||
virtual void Write(uint8_t* Buffer, uint64_t Offset, uint64_t Count);
|
||||
virtual void Write(uint8_t* Buffer, uint64_t Offset, uint64_t Count, uint64_t Position);
|
||||
|
||||
// Retreive the internal stream handle
|
||||
virtual HANDLE GetStreamHandle() const;
|
||||
|
||||
private:
|
||||
// FileMode flags cached
|
||||
bool _CanRead;
|
||||
bool _CanWrite;
|
||||
bool _IsPipe;
|
||||
|
||||
// Internal routine to wait for input
|
||||
static void WaitForAvailableConsoleInput(HANDLE hHandle, bool IsPipe);
|
||||
|
||||
// The handle
|
||||
HANDLE _Handle;
|
||||
};
|
||||
}
|
452
r5dev/thirdparty/cppnet/cppkore/ContainerControl.cpp
vendored
Normal file
452
r5dev/thirdparty/cppnet/cppkore/ContainerControl.cpp
vendored
Normal file
@ -0,0 +1,452 @@
|
||||
#include "stdafx.h"
|
||||
#include "ContainerControl.h"
|
||||
#include "Form.h"
|
||||
|
||||
namespace Forms
|
||||
{
|
||||
ContainerControl::ContainerControl()
|
||||
: Control(), _ActiveControl(nullptr), _FocusedControl(nullptr), _AutoScaleDimensions{}, _CurrentAutoScaleDimensions{}, _AutoScaleMode(AutoScaleMode::Inherit), _ScalingNeededOnLayout(false)
|
||||
{
|
||||
SetStyle(ControlStyles::AllPaintingInWmPaint, false);
|
||||
}
|
||||
|
||||
Control* ContainerControl::ActiveControl()
|
||||
{
|
||||
return this->_ActiveControl;
|
||||
}
|
||||
|
||||
void ContainerControl::SetActiveControl(Control* Value)
|
||||
{
|
||||
SetActiveControlInternal(Value);
|
||||
}
|
||||
|
||||
bool ContainerControl::ActivateControl(Control* Value)
|
||||
{
|
||||
return ActivateControlInternal(Value, true);
|
||||
}
|
||||
|
||||
Drawing::SizeF ContainerControl::AutoScaleDimensions()
|
||||
{
|
||||
return this->_AutoScaleDimensions;
|
||||
}
|
||||
|
||||
void ContainerControl::SetAutoScaleDimensions(Drawing::SizeF Size)
|
||||
{
|
||||
this->_AutoScaleDimensions = Size;
|
||||
if (!this->_AutoScaleDimensions.Empty())
|
||||
{
|
||||
this->LayoutScalingNeeded();
|
||||
}
|
||||
}
|
||||
|
||||
Drawing::SizeF ContainerControl::CurrentAutoScaleDimensions()
|
||||
{
|
||||
if (this->_CurrentAutoScaleDimensions.Empty())
|
||||
{
|
||||
switch (this->_AutoScaleMode)
|
||||
{
|
||||
case AutoScaleMode::Font:
|
||||
this->_CurrentAutoScaleDimensions = this->GetFontAutoScaleDimensions();
|
||||
break;
|
||||
case AutoScaleMode::Dpi:
|
||||
// TODO: Handle dpi related scaling values...
|
||||
break;
|
||||
|
||||
default:
|
||||
this->_CurrentAutoScaleDimensions = this->AutoScaleDimensions();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return this->_CurrentAutoScaleDimensions;
|
||||
}
|
||||
|
||||
AutoScaleMode ContainerControl::AutoScaleMode()
|
||||
{
|
||||
return this->_AutoScaleMode;
|
||||
}
|
||||
|
||||
void ContainerControl::SetAutoScaleMode(Forms::AutoScaleMode Mode)
|
||||
{
|
||||
bool ScalingRequired = false;
|
||||
|
||||
if (Mode != this->_AutoScaleMode)
|
||||
{
|
||||
if (_AutoScaleMode != Forms::AutoScaleMode::Inherit)
|
||||
{
|
||||
this->_AutoScaleDimensions = Drawing::SizeF{};
|
||||
}
|
||||
|
||||
this->_AutoScaleMode = Mode;
|
||||
ScalingRequired = true;
|
||||
}
|
||||
|
||||
// TODO: OnAutoScaleModeChanged();
|
||||
|
||||
if (ScalingRequired)
|
||||
this->LayoutScalingNeeded();
|
||||
}
|
||||
|
||||
void ContainerControl::WndProc(Message& Msg)
|
||||
{
|
||||
switch (Msg.Msg)
|
||||
{
|
||||
case WM_SETFOCUS:
|
||||
WmSetFocus(Msg);
|
||||
break;
|
||||
default:
|
||||
Control::WndProc(Msg);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
CreateParams ContainerControl::GetCreateParams()
|
||||
{
|
||||
auto Cp = Control::GetCreateParams();
|
||||
Cp.ExStyle |= WS_EX_CONTROLPARENT;
|
||||
|
||||
return Cp;
|
||||
}
|
||||
|
||||
bool ContainerControl::IsContainerControl()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
void ContainerControl::WmSetFocus(Message& Msg)
|
||||
{
|
||||
if (_ActiveControl != nullptr)
|
||||
{
|
||||
if (!_ActiveControl->Visible())
|
||||
this->OnGotFocus();
|
||||
|
||||
FocusActiveControlInternal();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_Parent != nullptr)
|
||||
{
|
||||
ContainerControl* C = (ContainerControl*)_Parent->GetContainerControl();
|
||||
if (C != nullptr)
|
||||
{
|
||||
if (!C->ActivateControlInternal(this, true))
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
Control::WndProc(Msg);
|
||||
}
|
||||
}
|
||||
|
||||
void ContainerControl::LayoutScalingNeeded()
|
||||
{
|
||||
this->EnableRequiredScaling(this, true);
|
||||
this->_ScalingNeededOnLayout = true;
|
||||
}
|
||||
|
||||
void ContainerControl::EnableRequiredScaling(Control *Ctrl, bool Enable)
|
||||
{
|
||||
Ctrl->SetRequiredScalingEnabled(Enable);
|
||||
|
||||
if (!Ctrl->GetStyle(ControlStyles::ContainerControl) || Ctrl->Controls() == nullptr)
|
||||
return;
|
||||
|
||||
uint32_t ControlCount = Ctrl->Controls()->Count();
|
||||
auto& ControlList = *Ctrl->Controls().get();
|
||||
|
||||
for (uint32_t i = 0; i < ControlCount; i++)
|
||||
{
|
||||
EnableRequiredScaling(ControlList[i], Enable);
|
||||
}
|
||||
}
|
||||
|
||||
void ContainerControl::PerformNeededAutoScaleOnLayout()
|
||||
{
|
||||
if (this->_ScalingNeededOnLayout)
|
||||
{
|
||||
this->PerformAutoScale(this->_ScalingNeededOnLayout, false);
|
||||
}
|
||||
}
|
||||
|
||||
void ContainerControl::PerformAutoScale(bool IncludeBounds, bool ExcludeBounds)
|
||||
{
|
||||
bool Suspended = false;
|
||||
|
||||
if (this->_AutoScaleMode != AutoScaleMode::None && this->_AutoScaleMode != AutoScaleMode::Inherit)
|
||||
{
|
||||
// TODO: SuspendAllLayout(this)
|
||||
Suspended = true;
|
||||
|
||||
Drawing::SizeF Included{};
|
||||
Drawing::SizeF Excluded{};
|
||||
|
||||
if (IncludeBounds)
|
||||
Included = this->AutoScaleFactor();
|
||||
if (ExcludeBounds)
|
||||
Excluded = this->AutoScaleFactor();
|
||||
|
||||
this->Scale(Included, Excluded, this);
|
||||
this->_AutoScaleDimensions = this->CurrentAutoScaleDimensions();
|
||||
}
|
||||
|
||||
if (IncludeBounds)
|
||||
{
|
||||
this->_ScalingNeededOnLayout = false;
|
||||
this->EnableRequiredScaling(this, false);
|
||||
}
|
||||
|
||||
if (Suspended)
|
||||
{
|
||||
// TODO: ResumeAllLayout(this, false);
|
||||
}
|
||||
}
|
||||
|
||||
Drawing::SizeF ContainerControl::GetFontAutoScaleDimensions()
|
||||
{
|
||||
Drawing::SizeF Result{};
|
||||
|
||||
auto hDC = CreateCompatibleDC(nullptr);
|
||||
auto CurrentFont = this->GetFont();
|
||||
auto OldFont = SelectObject(hDC, CurrentFont->GetFontHandle());
|
||||
|
||||
TEXTMETRICA Tm{};
|
||||
GetTextMetricsA(hDC, &Tm);
|
||||
|
||||
Result.Height = (float)Tm.tmHeight;
|
||||
|
||||
if ((Tm.tmPitchAndFamily & TMPF_FIXED_PITCH) != 0)
|
||||
{
|
||||
constexpr const char* FontMeasureString = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
||||
const uint32_t FontMeasureSize = (uint32_t)strlen(FontMeasureString);
|
||||
|
||||
SIZE Sz{};
|
||||
GetTextExtentPoint32A(hDC, FontMeasureString, FontMeasureSize, &Sz);
|
||||
Result.Width = (float)(int)std::roundf(((float)Sz.cx) / ((float)FontMeasureSize));
|
||||
}
|
||||
else
|
||||
{
|
||||
Result.Width = (float)Tm.tmAveCharWidth;
|
||||
}
|
||||
|
||||
SelectObject(hDC, OldFont);
|
||||
DeleteDC(hDC);
|
||||
|
||||
return Result;
|
||||
}
|
||||
|
||||
bool ContainerControl::ActivateControlInternal(Control* Ctrl, bool Originator)
|
||||
{
|
||||
bool Result = true;
|
||||
bool UpdateContainerActiveControl = false;
|
||||
|
||||
ContainerControl* Cc = nullptr;
|
||||
Control* Parent = this->_Parent;
|
||||
|
||||
if (Parent != nullptr)
|
||||
{
|
||||
Cc = (ContainerControl*)Parent->GetContainerControl();
|
||||
|
||||
if (Cc != nullptr)
|
||||
{
|
||||
UpdateContainerActiveControl = (Cc->ActiveControl() != this);
|
||||
}
|
||||
}
|
||||
|
||||
if (Ctrl != _ActiveControl || UpdateContainerActiveControl)
|
||||
{
|
||||
if (UpdateContainerActiveControl)
|
||||
{
|
||||
if (!Cc->ActivateControlInternal(this, false))
|
||||
return false;
|
||||
}
|
||||
|
||||
Result = AssignActiveControlInternal((Ctrl == this) ? nullptr : Ctrl);
|
||||
}
|
||||
|
||||
if (Originator)
|
||||
{
|
||||
// TODO: ScrollActiveControlIntoView();
|
||||
}
|
||||
|
||||
return Result;
|
||||
}
|
||||
|
||||
bool ContainerControl::AssignActiveControlInternal(Control* Ctrl)
|
||||
{
|
||||
if (_ActiveControl != Ctrl)
|
||||
{
|
||||
_ActiveControl = Ctrl;
|
||||
// TODO: UpdateFocusedControl();
|
||||
|
||||
if (_ActiveControl == Ctrl)
|
||||
{
|
||||
auto FormCtrl = (Form*)FindForm();
|
||||
if (FormCtrl != nullptr)
|
||||
FormCtrl->UpdateDefaultButton();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_FocusedControl = _ActiveControl;
|
||||
}
|
||||
|
||||
return (_ActiveControl == Ctrl);
|
||||
}
|
||||
|
||||
void ContainerControl::Select(bool Directed, bool Forward)
|
||||
{
|
||||
bool CorrectParentActiveControl = true;
|
||||
if (this->_Parent != nullptr)
|
||||
{
|
||||
auto C = (ContainerControl*)this->_Parent->GetContainerControl();
|
||||
if (C != nullptr)
|
||||
{
|
||||
C->SetActiveControl(this);
|
||||
CorrectParentActiveControl = (C->ActiveControl() == this);
|
||||
}
|
||||
}
|
||||
|
||||
if (Directed && CorrectParentActiveControl)
|
||||
SelectNextControl(nullptr, Forward, true, true, false);
|
||||
}
|
||||
|
||||
void ContainerControl::Scale(Drawing::SizeF IncludedFactor, Drawing::SizeF ExcludedFactor, Control* Ctrl)
|
||||
{
|
||||
if (this->_AutoScaleMode == AutoScaleMode::Inherit)
|
||||
{
|
||||
Control::Scale(IncludedFactor, ExcludedFactor, Ctrl);
|
||||
}
|
||||
else
|
||||
{
|
||||
Drawing::SizeF OurExcludedFactor = ExcludedFactor;
|
||||
Drawing::SizeF ChildIncludedFactor = IncludedFactor;
|
||||
|
||||
if (!OurExcludedFactor.Empty())
|
||||
OurExcludedFactor = this->AutoScaleFactor();
|
||||
|
||||
// If we're not supposed to be scaling, don't scale the internal ones either.
|
||||
if (this->AutoScaleMode() == AutoScaleMode::None)
|
||||
ChildIncludedFactor = this->AutoScaleFactor();
|
||||
|
||||
Drawing::SizeF OurExternalContainerFactor = OurExcludedFactor;
|
||||
|
||||
if (!ExcludedFactor.Empty() && this->_Parent != nullptr)
|
||||
{
|
||||
OurExternalContainerFactor = Drawing::SizeF{};
|
||||
|
||||
if ((Ctrl != this))
|
||||
{
|
||||
OurExternalContainerFactor = ExcludedFactor;
|
||||
}
|
||||
}
|
||||
|
||||
ScaleControl(IncludedFactor, OurExternalContainerFactor, Ctrl);
|
||||
ScaleChildControls(ChildIncludedFactor, OurExcludedFactor, Ctrl);
|
||||
}
|
||||
}
|
||||
|
||||
void ContainerControl::OnLayoutResuming(bool PerformLayout)
|
||||
{
|
||||
this->PerformNeededAutoScaleOnLayout();
|
||||
Control::OnLayoutResuming(PerformLayout);
|
||||
}
|
||||
|
||||
void ContainerControl::OnChildLayoutResuming(Control* Child, bool PerformLayout)
|
||||
{
|
||||
Control::OnChildLayoutResuming(Child, PerformLayout);
|
||||
|
||||
// Do not scale children if AutoScaleMode is set to Dpi
|
||||
if (/*DpiHelper.EnableSinglePassScalingOfDpiForms &&*/ (this->_AutoScaleMode == AutoScaleMode::Dpi))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Perform scaling of the child control
|
||||
if (!PerformLayout && this->_AutoScaleMode != AutoScaleMode::None && this->_AutoScaleMode != AutoScaleMode::Inherit && this->_ScalingNeededOnLayout)
|
||||
{
|
||||
Child->Scale(this->AutoScaleFactor(), Drawing::SizeF{}, this);
|
||||
}
|
||||
}
|
||||
|
||||
void ContainerControl::FocusActiveControlInternal()
|
||||
{
|
||||
if (_ActiveControl != nullptr && _ActiveControl->Visible())
|
||||
{
|
||||
auto FocusHandle = GetFocus();
|
||||
if (FocusHandle == NULL || FocusHandle != _ActiveControl->GetHandle())
|
||||
SetFocus(_ActiveControl->GetHandle());
|
||||
}
|
||||
else
|
||||
{
|
||||
ContainerControl* Cc = this;
|
||||
while (Cc != nullptr && !Cc->Visible())
|
||||
{
|
||||
auto Parent = Cc->Parent();
|
||||
if (Parent != nullptr)
|
||||
Cc = (ContainerControl*)Parent->GetContainerControl();
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
if (Cc != nullptr && Cc->Visible())
|
||||
SetFocus(Cc->GetHandle());
|
||||
}
|
||||
}
|
||||
|
||||
void ContainerControl::SetActiveControlInternal(Control* Value)
|
||||
{
|
||||
if (_ActiveControl != Value || (Value != nullptr && !Value->Focused()))
|
||||
{
|
||||
bool Result = false;
|
||||
ContainerControl* Cc = nullptr;
|
||||
|
||||
if (Value != nullptr && Value->Parent() != nullptr)
|
||||
{
|
||||
Cc = (ContainerControl*)Value->Parent()->GetContainerControl();
|
||||
}
|
||||
|
||||
if (Cc != nullptr)
|
||||
{
|
||||
Result = ActivateControlInternal(Value, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
Result = AssignActiveControlInternal(Value);
|
||||
}
|
||||
|
||||
if (Cc != nullptr && Result)
|
||||
{
|
||||
ContainerControl* CcAncestor = this;
|
||||
while (CcAncestor->_Parent != nullptr && CcAncestor->_Parent->GetContainerControl() != nullptr)
|
||||
CcAncestor = (ContainerControl*)CcAncestor->_Parent->GetContainerControl();
|
||||
|
||||
if (CcAncestor->ContainsFocus() /*&& Value is NOT USERCONTROL!!*/)
|
||||
Cc->FocusActiveControlInternal();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Control* ContainerControl::ParentFormInternal()
|
||||
{
|
||||
if (this->_Parent != nullptr)
|
||||
return this->_Parent->FindForm();
|
||||
|
||||
if (this->_RTTI == ControlTypes::Form)
|
||||
return nullptr;
|
||||
|
||||
return FindForm();
|
||||
}
|
||||
|
||||
Drawing::SizeF ContainerControl::AutoScaleFactor()
|
||||
{
|
||||
auto Current = this->CurrentAutoScaleDimensions();
|
||||
auto Saved = this->AutoScaleDimensions();
|
||||
|
||||
if (Saved.Empty())
|
||||
{
|
||||
return Drawing::SizeF(1.f, 1.f);
|
||||
}
|
||||
|
||||
return Drawing::SizeF(Current.Width / Saved.Width, Current.Height / Saved.Height);
|
||||
}
|
||||
}
|
100
r5dev/thirdparty/cppnet/cppkore/ContainerControl.h
vendored
Normal file
100
r5dev/thirdparty/cppnet/cppkore/ContainerControl.h
vendored
Normal file
@ -0,0 +1,100 @@
|
||||
#pragma once
|
||||
|
||||
#include "Control.h"
|
||||
#include "AutoScaleMode.h"
|
||||
|
||||
namespace Forms
|
||||
{
|
||||
// TODO: Process [*] Key functions, virtual...
|
||||
|
||||
class ContainerControl : public Control
|
||||
{
|
||||
public:
|
||||
ContainerControl();
|
||||
virtual ~ContainerControl() = default;
|
||||
|
||||
// Indicates the current active control on the container control.
|
||||
Control* ActiveControl();
|
||||
// Indicates the current active control on the container control.
|
||||
void SetActiveControl(Control* Value);
|
||||
|
||||
// Activates a control
|
||||
bool ActivateControl(Control* Value);
|
||||
|
||||
// Represents the DPI or Font setting that the control has been scaled to or designed at.
|
||||
Drawing::SizeF AutoScaleDimensions();
|
||||
// Represents the DPI or Font setting that the control has been scaled to or designed at.
|
||||
void SetAutoScaleDimensions(Drawing::SizeF Size);
|
||||
|
||||
// Gets the current auto scale ratio.
|
||||
Drawing::SizeF CurrentAutoScaleDimensions();
|
||||
|
||||
// Determines the scaling mode of this control.
|
||||
AutoScaleMode AutoScaleMode();
|
||||
// Determines the scaling mode of this control.
|
||||
void SetAutoScaleMode(Forms::AutoScaleMode Mode);
|
||||
|
||||
// Override WndProc for specific form messages.
|
||||
virtual void WndProc(Message& Msg);
|
||||
|
||||
protected:
|
||||
// Get custom control creation parameters for this instance.
|
||||
virtual CreateParams GetCreateParams();
|
||||
// Make sure we set this so we know if we are a container.
|
||||
virtual bool IsContainerControl();
|
||||
|
||||
// Internal routine to active a control.
|
||||
bool ActivateControlInternal(Control* Ctrl, bool Originator);
|
||||
// Internal routine to set active control.
|
||||
bool AssignActiveControlInternal(Control* Ctrl);
|
||||
|
||||
// Internal selection routine
|
||||
virtual void Select(bool Directed, bool Forward);
|
||||
// Internal routine to scale a control
|
||||
virtual void Scale(Drawing::SizeF IncludedFactor, Drawing::SizeF ExcludedFactor, Control* Ctrl);
|
||||
// Internal layout resuming routine
|
||||
virtual void OnLayoutResuming(bool PerformLayout);
|
||||
// Internal child layout resuming routine
|
||||
virtual void OnChildLayoutResuming(Control* Child, bool PerformLayout);
|
||||
|
||||
// Sets focus to the active control.
|
||||
void FocusActiveControlInternal();
|
||||
|
||||
// Internal routine to set a control as active.
|
||||
void SetActiveControlInternal(Control* Value);
|
||||
|
||||
// Gets the parent form, if any.
|
||||
Control* ParentFormInternal();
|
||||
|
||||
// Fetches the auto scale ratio for the given settings.
|
||||
Drawing::SizeF AutoScaleFactor();
|
||||
|
||||
private:
|
||||
// Internal cached flags
|
||||
Control* _ActiveControl;
|
||||
Control* _FocusedControl;
|
||||
|
||||
Drawing::SizeF _AutoScaleDimensions;
|
||||
Drawing::SizeF _CurrentAutoScaleDimensions;
|
||||
|
||||
Forms::AutoScaleMode _AutoScaleMode;
|
||||
bool _ScalingNeededOnLayout;
|
||||
|
||||
// We must define each window message handler here...
|
||||
void WmSetFocus(Message& Msg);
|
||||
|
||||
// Internal routine to enable scaling on child controls.
|
||||
void LayoutScalingNeeded();
|
||||
// Internal routine to set scaling flag.
|
||||
void EnableRequiredScaling(Control* Ctrl, bool Enable);
|
||||
|
||||
// Internal routine to determinalistically perform scaling.
|
||||
void PerformNeededAutoScaleOnLayout();
|
||||
|
||||
// Performs scaling of this control. Scaling works by scaling all children of this control.
|
||||
void PerformAutoScale(bool IncludeBounds, bool ExcludeBounds);
|
||||
|
||||
// Internal routine to calculate the font scale ratio.
|
||||
Drawing::SizeF GetFontAutoScaleDimensions();
|
||||
};
|
||||
}
|
56
r5dev/thirdparty/cppnet/cppkore/ContentAlignment.h
vendored
Normal file
56
r5dev/thirdparty/cppnet/cppkore/ContentAlignment.h
vendored
Normal file
@ -0,0 +1,56 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
namespace Drawing
|
||||
{
|
||||
// Specifies alignment of content on the drawing surface.
|
||||
enum class ContentAlignment
|
||||
{
|
||||
// Content is vertically aligned at the top, and horizontally
|
||||
// aligned on the left.
|
||||
TopLeft = 0x001,
|
||||
// Content is vertically aligned at the top, and
|
||||
// horizontally aligned at the center.
|
||||
TopCenter = 0x002,
|
||||
// Content is vertically aligned at the top, and
|
||||
// horizontally aligned on the right.
|
||||
TopRight = 0x004,
|
||||
// Content is vertically aligned in the middle, and
|
||||
// horizontally aligned on the left.
|
||||
MiddleLeft = 0x010,
|
||||
// Content is vertically aligned in the middle, and
|
||||
// horizontally aligned at the center.
|
||||
MiddleCenter = 0x020,
|
||||
// Content is vertically aligned in the middle, and horizontally aligned on the
|
||||
// right.
|
||||
MiddleRight = 0x040,
|
||||
// Content is vertically aligned at the bottom, and horizontally aligned on the
|
||||
// left.
|
||||
BottomLeft = 0x100,
|
||||
// Content is vertically aligned at the bottom, and horizontally aligned at the
|
||||
// center.
|
||||
BottomCenter = 0x200,
|
||||
// Content is vertically aligned at the bottom, and horizontally aligned on the right.
|
||||
BottomRight = 0x400,
|
||||
};
|
||||
|
||||
//
|
||||
// Allow bitwise operations on this enumeration
|
||||
//
|
||||
constexpr ContentAlignment operator|(ContentAlignment Lhs, ContentAlignment Rhs)
|
||||
{
|
||||
return static_cast<ContentAlignment>(static_cast<std::underlying_type<ContentAlignment>::type>(Lhs) | static_cast<std::underlying_type<ContentAlignment>::type>(Rhs));
|
||||
};
|
||||
|
||||
//
|
||||
// Content alignment masks
|
||||
//
|
||||
|
||||
constexpr static ContentAlignment AnyRightAlign = ContentAlignment::TopRight | ContentAlignment::MiddleRight | ContentAlignment::BottomRight;
|
||||
constexpr static ContentAlignment AnyLeftAlign = ContentAlignment::TopLeft | ContentAlignment::MiddleLeft | ContentAlignment::BottomLeft;
|
||||
constexpr static ContentAlignment AnyTopAlign = ContentAlignment::TopLeft | ContentAlignment::TopCenter | ContentAlignment::TopRight;
|
||||
constexpr static ContentAlignment AnyBottomAlign = ContentAlignment::BottomLeft | ContentAlignment::BottomCenter | ContentAlignment::BottomRight;
|
||||
constexpr static ContentAlignment AnyMiddleAlign = ContentAlignment::MiddleLeft | ContentAlignment::MiddleCenter | ContentAlignment::MiddleRight;
|
||||
constexpr static ContentAlignment AnyCenterAlign = ContentAlignment::TopCenter | ContentAlignment::MiddleCenter | ContentAlignment::BottomCenter;
|
||||
}
|
2744
r5dev/thirdparty/cppnet/cppkore/Control.cpp
vendored
Normal file
2744
r5dev/thirdparty/cppnet/cppkore/Control.cpp
vendored
Normal file
File diff suppressed because it is too large
Load Diff
574
r5dev/thirdparty/cppnet/cppkore/Control.h
vendored
Normal file
574
r5dev/thirdparty/cppnet/cppkore/Control.h
vendored
Normal file
@ -0,0 +1,574 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <memory>
|
||||
#include <Windows.h>
|
||||
#include <CommCtrl.h>
|
||||
#include "Keys.h"
|
||||
#include "Font.h"
|
||||
#include "Action.h"
|
||||
#include "Message.h"
|
||||
#include "DropTarget.h"
|
||||
#include "EventBase.h"
|
||||
#include "StringBase.h"
|
||||
#include "ControlTypes.h"
|
||||
#include "AnchorStyles.h"
|
||||
#include "CreateParams.h"
|
||||
#include "MouseButtons.h"
|
||||
#include "ControlStyles.h"
|
||||
#include "ControlStates.h"
|
||||
#include "KeyEventArgs.h"
|
||||
#include "PaintEventArgs.h"
|
||||
#include "MouseEventArgs.h"
|
||||
#include "ControlCollection.h"
|
||||
#include "BoundsSpecified.h"
|
||||
#include "InvalidateEventArgs.h"
|
||||
#include "DragEventArgs.h"
|
||||
#include "KeyPressEventArgs.h"
|
||||
#include "HandledMouseEventArgs.h"
|
||||
|
||||
// Used for reflection messages
|
||||
#define WM_REFLECT (WM_USER + 0x1C00)
|
||||
|
||||
// Undocumented flags
|
||||
#define DCX_USESTYLE 0x00010000
|
||||
#define DCX_NODELETERGN 0x00040000
|
||||
|
||||
// Remove built-in macros
|
||||
#undef SetWindowText
|
||||
#undef DrawText
|
||||
|
||||
namespace Forms
|
||||
{
|
||||
// Defines the base class for controls, which are components
|
||||
// with visual representation.
|
||||
class Control
|
||||
{
|
||||
public:
|
||||
Control();
|
||||
virtual ~Control();
|
||||
|
||||
// Makes the control display by setting the visible property to true.
|
||||
virtual void Show();
|
||||
// Hides the control by setting the visible property to false.
|
||||
virtual void Hide();
|
||||
|
||||
// Creates a new instance of the specified control with the given parent.
|
||||
virtual void CreateControl(Control* Parent = nullptr);
|
||||
|
||||
// Attempts to set focus to this control.
|
||||
bool Focus();
|
||||
// Indicates whether the control has focus.
|
||||
bool Focused();
|
||||
// Indicates whether the control can receive focus.
|
||||
bool CanFocus();
|
||||
// Indicates whether the control can be selected.
|
||||
bool CanSelect();
|
||||
|
||||
// Indicates whether the control or one of it's children currently has focus.
|
||||
bool ContainsFocus();
|
||||
|
||||
// Suspends the control layout functionality.
|
||||
void SuspendLayout();
|
||||
// Resumes layout functionality.
|
||||
void ResumeLayout(bool PerformLayout = true);
|
||||
|
||||
// Indicates whether the control is currently enabled.
|
||||
bool Enabled();
|
||||
// Indicates whether the control is currently enabled.
|
||||
void SetEnabled(bool Value);
|
||||
|
||||
// The AllowDrop property. If AllowDrop is set to true then
|
||||
// this control will allow drag and drop operations and events to be used.
|
||||
bool AllowDrop();
|
||||
// The AllowDrop property. If AllowDrop is set to true then
|
||||
// this control will allow drag and drop operations and events to be used.
|
||||
void SetAllowDrop(bool Value);
|
||||
|
||||
// Indicates whether the control is visible.
|
||||
bool Visible();
|
||||
// Indicates whether the control is visible.
|
||||
void SetVisible(bool Value);
|
||||
|
||||
// This will enable or disable double buffering.
|
||||
bool DoubleBuffered();
|
||||
// This will enable or disable double buffering.
|
||||
void SetDoubleBuffered(bool Value);
|
||||
|
||||
// Indicates whether the control has captured the mouse.
|
||||
bool Capture();
|
||||
// Indicates whether the control has captured the mouse.
|
||||
void SetCapture(bool Value);
|
||||
|
||||
// The current value of the anchor property. The anchor property
|
||||
// determines which edges of the control are anchored to the container's
|
||||
// edges.
|
||||
AnchorStyles Anchor();
|
||||
// The current value of the anchor property. The anchor property
|
||||
// determines which edges of the control are anchored to the container's
|
||||
// edges.
|
||||
void SetAnchor(AnchorStyles Value);
|
||||
|
||||
// The tab index of this control.
|
||||
uint32_t TabIndex();
|
||||
// The tab index of this control.
|
||||
void SetTabIndex(uint32_t Value);
|
||||
|
||||
// The location of this control.
|
||||
Drawing::Point Location();
|
||||
// The location of this control.
|
||||
void SetLocation(Drawing::Point Value);
|
||||
|
||||
// The size of the control.
|
||||
Drawing::Size Size();
|
||||
// The size of the control.
|
||||
void SetSize(Drawing::Size Value);
|
||||
|
||||
// The maximum size of the control.
|
||||
Drawing::Size MaximumSize();
|
||||
// The maximum size of the control.
|
||||
void SetMaximumSize(Drawing::Size Value);
|
||||
|
||||
// The minimum size of the control.
|
||||
Drawing::Size MinimumSize();
|
||||
// The minimum size of the control.
|
||||
void SetMinimumSize(Drawing::Size Value);
|
||||
|
||||
// The background color of this control.
|
||||
Drawing::Color BackColor();
|
||||
// The background color of this control.
|
||||
void SetBackColor(Drawing::Color Color);
|
||||
|
||||
// The foreground color of the control.
|
||||
Drawing::Color ForeColor();
|
||||
// The foreground color of the control.
|
||||
void SetForeColor(Drawing::Color Color);
|
||||
|
||||
// Retrieves the current font for this control.
|
||||
Drawing::Font* GetFont();
|
||||
// Retrieves the current font for this control.
|
||||
void SetFont(Drawing::Font* Font);
|
||||
|
||||
// The parent of this control.
|
||||
Control* Parent();
|
||||
// The parent of this control.
|
||||
void SetParent(Control* Value);
|
||||
|
||||
// The client rect of the control.
|
||||
Drawing::Rectangle ClientRectangle();
|
||||
|
||||
// The size of the clientRect.
|
||||
Drawing::Size ClientSize();
|
||||
// The size of the clientRect.
|
||||
void SetClientSize(Drawing::Size Value);
|
||||
|
||||
// Computes the location of the client point in screen coords.
|
||||
Drawing::Point PointToScreen(const Drawing::Point& Point);
|
||||
// Computes the location of the screen point in client coords.
|
||||
Drawing::Point PointToClient(const Drawing::Point& Point);
|
||||
|
||||
// Computes the location of the client rectangle in screen coords.
|
||||
Drawing::Rectangle RectangleToScreen(const Drawing::Rectangle& Rect);
|
||||
// Computes the location of the screen rectangle in client coords.
|
||||
Drawing::Rectangle RectangleToClient(const Drawing::Rectangle& Rect);
|
||||
|
||||
// Gets the current text associated with this control.
|
||||
virtual string Text();
|
||||
// Sets the current text associated with this control.
|
||||
virtual void SetText(const string& Value);
|
||||
|
||||
// Brings this control to the front of the z-order.
|
||||
void BringToFront();
|
||||
// Sends this control to the back of the z-order.
|
||||
void SendToBack();
|
||||
|
||||
// Style flags attached to this control.
|
||||
bool GetStyle(ControlStyles Flag);
|
||||
// Style flags attached to this control.
|
||||
void SetStyle(ControlStyles Flags, bool Value);
|
||||
|
||||
// State flags attached to this control.
|
||||
bool GetState(ControlStates Flag);
|
||||
// State flags attached to this control.
|
||||
void SetState(ControlStates Flags, bool Value);
|
||||
|
||||
// Invalidates the control and causes a paint message to be sent to the control.
|
||||
void Invalidate(bool InvalidateChildren = false);
|
||||
|
||||
// Executes a delegate on the thread that owns the control's underlying window handle.
|
||||
void Invoke(Action Method);
|
||||
// Gets whether or not an invoke is required.
|
||||
bool InvokeRequired();
|
||||
|
||||
// Forces the control to paint any currently invalid areas.
|
||||
void Update();
|
||||
// Forces the control to invalidate and immediately repaint itself and children.
|
||||
void Refresh();
|
||||
|
||||
// Returns the native handle of this control
|
||||
HWND GetHandle();
|
||||
// Returns the type of this control
|
||||
ControlTypes GetType();
|
||||
|
||||
// Retrieves the form that the control is on.
|
||||
Control* FindForm();
|
||||
// Retrieves the container control that we have, if any.
|
||||
Control* GetContainerControl();
|
||||
// Retrieves the next control in the tab order of child controls.
|
||||
Control* GetNextControl(Control* Ctrl, bool Forward);
|
||||
|
||||
// Verifies if a control is a child of this control.
|
||||
bool Contains(Control* Ctrl);
|
||||
|
||||
// Returns a reference to this controls child collection, if available
|
||||
const std::unique_ptr<ControlCollection>& Controls();
|
||||
|
||||
// Activates this control.
|
||||
void Select();
|
||||
// Selects the next control following Ctrl.
|
||||
bool SelectNextControl(Control* Ctrl, bool Forward, bool TabStopOnly, bool Nested, bool Wrap);
|
||||
|
||||
// Updates this control in it's parent's z-order.
|
||||
void UpdateZOrder();
|
||||
|
||||
// Invokes the default window procedure associated with this Window. It is
|
||||
// an error to call this method when the Handle property is zero.
|
||||
void DefWndProc(Message& Msg);
|
||||
|
||||
// We must define control event bases here
|
||||
virtual void OnPaint(const std::unique_ptr<PaintEventArgs>& EventArgs);
|
||||
virtual void OnPaintBackground(const std::unique_ptr<PaintEventArgs>& EventArgs);
|
||||
virtual void OnMouseClick(const std::unique_ptr<MouseEventArgs>& EventArgs);
|
||||
virtual void OnMouseDoubleClick(const std::unique_ptr<MouseEventArgs>& EventArgs);
|
||||
virtual void OnMouseUp(const std::unique_ptr<MouseEventArgs>& EventArgs);
|
||||
virtual void OnMouseDown(const std::unique_ptr<MouseEventArgs>& EventArgs);
|
||||
virtual void OnMouseMove(const std::unique_ptr<MouseEventArgs>& EventArgs);
|
||||
virtual void OnInvalidated(const std::unique_ptr<InvalidateEventArgs>& EventArgs);
|
||||
virtual void OnMouseWheel(const std::unique_ptr<HandledMouseEventArgs>& EventArgs);
|
||||
virtual void OnKeyPress(const std::unique_ptr<KeyPressEventArgs>& EventArgs);
|
||||
virtual void OnKeyUp(const std::unique_ptr<KeyEventArgs>& EventArgs);
|
||||
virtual void OnKeyDown(const std::unique_ptr<KeyEventArgs>& EventArgs);
|
||||
virtual void OnDragEnter(const std::unique_ptr<DragEventArgs>& EventArgs);
|
||||
virtual void OnDragOver(const std::unique_ptr<DragEventArgs>& EventArgs);
|
||||
virtual void OnDragDrop(const std::unique_ptr<DragEventArgs>& EventArgs);
|
||||
virtual void OnDragLeave();
|
||||
virtual void OnFontChanged();
|
||||
virtual void OnVisibleChanged();
|
||||
virtual void OnHandleCreated();
|
||||
virtual void OnHandleDestroyed();
|
||||
virtual void OnTextChanged();
|
||||
virtual void OnMouseEnter();
|
||||
virtual void OnMouseLeave();
|
||||
virtual void OnMouseHover();
|
||||
virtual void OnLostFocus();
|
||||
virtual void OnGotFocus();
|
||||
virtual void OnStyleChanged();
|
||||
virtual void OnLocationChanged();
|
||||
virtual void OnSizeChanged();
|
||||
virtual void OnResize();
|
||||
virtual void OnClientSizeChanged();
|
||||
virtual void OnMouseCaptureChanged();
|
||||
virtual void OnBackColorChanged();
|
||||
virtual void OnForeColorChanged();
|
||||
virtual void OnClick();
|
||||
virtual void OnDoubleClick();
|
||||
virtual void OnEnabledChanged();
|
||||
|
||||
// We must define event handlers here
|
||||
EventBase<void(*)(Control*)> Click;
|
||||
EventBase<void(*)(Control*)> DoubleClick;
|
||||
EventBase<void(*)(Control*)> MouseEnter;
|
||||
EventBase<void(*)(Control*)> MouseLeave;
|
||||
EventBase<void(*)(Control*)> MouseHover;
|
||||
EventBase<void(*)(Control*)> SizeChanged;
|
||||
EventBase<void(*)(Control*)> Resize;
|
||||
EventBase<void(*)(Control*)> LostFocus;
|
||||
EventBase<void(*)(Control*)> GotFocus;
|
||||
EventBase<void(*)(Control*)> TextChanged;
|
||||
EventBase<void(*)(Control*)> FontChanged;
|
||||
EventBase<void(*)(Control*)> HandleCreated;
|
||||
EventBase<void(*)(Control*)> HandleDestroyed;
|
||||
EventBase<void(*)(Control*)> EnabledChanged;
|
||||
EventBase<void(*)(Control*)> VisibleChanged;
|
||||
EventBase<void(*)(Control*)> LocationChanged;
|
||||
EventBase<void(*)(Control*)> BackColorChanged;
|
||||
EventBase<void(*)(Control*)> ForeColorChanged;
|
||||
EventBase<void(*)(Control*)> StyleChanged;
|
||||
EventBase<void(*)(Control*)> ClientSizeChanged;
|
||||
EventBase<void(*)(Control*)> MouseCaptureChanged;
|
||||
EventBase<void(*)(Control*)> DragLeave;
|
||||
EventBase<void(*)(const std::unique_ptr<DragEventArgs>&, Control*)> DragEnter;
|
||||
EventBase<void(*)(const std::unique_ptr<DragEventArgs>&, Control*)> DragDrop;
|
||||
EventBase<void(*)(const std::unique_ptr<DragEventArgs>&, Control*)> DragOver;
|
||||
EventBase<void(*)(const std::unique_ptr<KeyEventArgs>&, Control*)> KeyUp;
|
||||
EventBase<void(*)(const std::unique_ptr<KeyEventArgs>&, Control*)> KeyDown;
|
||||
EventBase<void(*)(const std::unique_ptr<KeyPressEventArgs>&, Control*)> KeyPress;
|
||||
EventBase<void(*)(const std::unique_ptr<PaintEventArgs>&, Control*)> Paint;
|
||||
EventBase<void(*)(const std::unique_ptr<MouseEventArgs>&, Control*)> MouseUp;
|
||||
EventBase<void(*)(const std::unique_ptr<MouseEventArgs>&, Control*)> MouseDown;
|
||||
EventBase<void(*)(const std::unique_ptr<MouseEventArgs>&, Control*)> MouseMove;
|
||||
EventBase<void(*)(const std::unique_ptr<MouseEventArgs>&, Control*)> MouseClick;
|
||||
EventBase<void(*)(const std::unique_ptr<MouseEventArgs>&, Control*)> MouseDoubleClick;
|
||||
EventBase<void(*)(const std::unique_ptr<InvalidateEventArgs>&, Control*)> Invalidated;
|
||||
EventBase<void(*)(const std::unique_ptr<HandledMouseEventArgs>&, Control*)> MouseWheel;
|
||||
|
||||
// The standard windows message pump for this control.
|
||||
virtual void WndProc(Message& Msg);
|
||||
|
||||
// Routine to get the default GDI+ palette for a control.
|
||||
static HPALETTE SetUpPalette(HDC Dc, bool Force, bool RealizePalette);
|
||||
// Gets the current state of the mouse buttons.
|
||||
static MouseButtons GetMouseButtons();
|
||||
// Gets the current position of the mouse in screen coordinates.
|
||||
static Drawing::Point GetMousePosition();
|
||||
// Retrieves the current state of the modifier keys.
|
||||
static Keys GetModifierKeys();
|
||||
|
||||
// Determines if the required scaling property is enabled
|
||||
bool RequiredScalingEnabled();
|
||||
// Determines if the required scaling property is enabled
|
||||
void SetRequiredScalingEnabled(bool Value);
|
||||
|
||||
// Routine to scale a control
|
||||
virtual void Scale(Drawing::SizeF IncludedFactor, Drawing::SizeF ExcludedFactor, Control* Ctrl);
|
||||
|
||||
protected:
|
||||
// The control handle
|
||||
HWND _Handle;
|
||||
// The control base windows proc
|
||||
LONG_PTR _WndProcBase;
|
||||
|
||||
// The RTTI type of this control
|
||||
ControlTypes _RTTI;
|
||||
|
||||
// The parent control if any
|
||||
Control* _Parent;
|
||||
|
||||
// A collection of children controls, if we are a container control
|
||||
std::unique_ptr<ControlCollection> _Controls;
|
||||
|
||||
// Internal size caching
|
||||
uint32_t _X;
|
||||
uint32_t _Y;
|
||||
uint32_t _Width;
|
||||
uint32_t _Height;
|
||||
uint32_t _ClientWidth;
|
||||
uint32_t _ClientHeight;
|
||||
|
||||
// Internal tab index caching
|
||||
uint32_t _TabIndex;
|
||||
|
||||
// Internal min/max size caching
|
||||
uint32_t _MaximumWidth;
|
||||
uint32_t _MaximumHeight;
|
||||
uint32_t _MinimumWidth;
|
||||
uint32_t _MinimumHeight;
|
||||
|
||||
// Internal text caching
|
||||
string _Text;
|
||||
|
||||
// Contains the anchor information...
|
||||
struct AnchorDeltasCache
|
||||
{
|
||||
float XMoveFrac;
|
||||
float YMoveFrac;
|
||||
float XSizeFrac;
|
||||
float YSizeFrac;
|
||||
RECT InitialRect;
|
||||
bool InitialRectSet;
|
||||
} _AnchorDeltas;
|
||||
|
||||
// Internal layout anchor
|
||||
AnchorStyles _Anchor;
|
||||
|
||||
// Control base colors
|
||||
Drawing::Color _BackColor;
|
||||
Drawing::Color _ForeColor;
|
||||
|
||||
// Control brush, if any
|
||||
uintptr_t _BackColorBrush;
|
||||
|
||||
// Control base font
|
||||
std::unique_ptr<Drawing::Font> _Font;
|
||||
|
||||
// Updates the bounds of the control based on the handle the control is bound to.
|
||||
void UpdateBounds();
|
||||
// Updates the bounds of the control based on the bounds passed in.
|
||||
void UpdateBounds(uint32_t X, uint32_t Y, uint32_t Width, uint32_t Height, uint32_t ClientWidth, uint32_t ClientHeight);
|
||||
// Updates the bounds of the control based on the bounds passed in.
|
||||
void UpdateBounds(uint32_t X, uint32_t Y, uint32_t Width, uint32_t Height);
|
||||
// Sets the bounds of the control.
|
||||
void SetBounds(uint32_t X, uint32_t Y, uint32_t Width, uint32_t Height);
|
||||
// Updates the deltas of the control based on the anchor
|
||||
void UpdateDeltas();
|
||||
// Updates the initial position based on anchor
|
||||
void UpdateInitialPos();
|
||||
|
||||
// Internal selection routine
|
||||
virtual void Select(bool Directed, bool Forward);
|
||||
// Internal layout resuming routine
|
||||
virtual void OnLayoutResuming(bool PerformLayout);
|
||||
// Internal child layout resuming routine
|
||||
virtual void OnChildLayoutResuming(Control* Child, bool PerformLayout);
|
||||
|
||||
// Gets the current control window style
|
||||
uint32_t WindowStyle();
|
||||
// Sets the current controls window style
|
||||
void SetWindowStyle(uint32_t Value);
|
||||
// Gets the current control extended style
|
||||
uint32_t WindowExStyle();
|
||||
// Sets the current controls extended style
|
||||
void SetWindowExStyle(uint32_t Value);
|
||||
|
||||
// Internal routine to calculate client size into size
|
||||
Drawing::Size SizeFromClientSize(int32_t Width, int32_t Height);
|
||||
|
||||
// Internal routine to scale a size, based on control limitations
|
||||
Drawing::Size ScaleSize(Drawing::Size Start, float X, float Y);
|
||||
// Internal routine to scale a control, calculating bounds
|
||||
void ScaleControl(Drawing::SizeF IncludedFactor, Drawing::SizeF ExcludedFactor, Control* Ctrl);
|
||||
// Internal routine to scale child controls, calculating bounds
|
||||
void ScaleChildControls(Drawing::SizeF IncludedFactor, Drawing::SizeF ExcludedFactor, Control* Ctrl);
|
||||
|
||||
// Internal routine to scale a control by factor
|
||||
virtual void ScaleControl(Drawing::SizeF Factor, BoundsSpecified Specified);
|
||||
// Internal routine to scale a bounds by a factor
|
||||
virtual Drawing::Rectangle GetScaledBounds(Drawing::Rectangle Bounds, Drawing::SizeF Factor, BoundsSpecified Specified);
|
||||
|
||||
// The GDI brush for our background color.
|
||||
uintptr_t BackColorBrush();
|
||||
|
||||
// Gets the current text of the Window
|
||||
virtual string WindowText();
|
||||
// Sets the current text of the Window
|
||||
virtual void SetWindowText(const string& Value);
|
||||
|
||||
// Updates the control styles...
|
||||
void UpdateStyles();
|
||||
|
||||
// Registers the control drop target.
|
||||
void SetAcceptDrops(bool Accept);
|
||||
|
||||
// Resets the mouse leave listeners.
|
||||
void ResetMouseEventArgs();
|
||||
|
||||
// Destroys the window handle
|
||||
void DestroyHandle();
|
||||
|
||||
// Performs layout of child controls based on their anchors.
|
||||
virtual void PerformLayout();
|
||||
// Processes a key message.
|
||||
virtual bool ProcessKeyMessage(Message& Msg);
|
||||
// Previews a key message.
|
||||
virtual bool ProcessKeyPreview(Message& Msg);
|
||||
// Processes a key message and properly generates key events.
|
||||
virtual bool ProcessKeyEventArgs(Message& Msg);
|
||||
|
||||
// Internal routine to get control visibility.
|
||||
virtual bool GetVisibleCore();
|
||||
// Internal routine to change control visibility.
|
||||
virtual void SetVisibleCore(bool Value);
|
||||
|
||||
// Gets the CreateParams for this control instance.
|
||||
virtual CreateParams GetCreateParams();
|
||||
|
||||
// An internal routine that is the root window message processor.
|
||||
static LRESULT CALLBACK InternalWndProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam);
|
||||
|
||||
// Used when the control can house other controls.
|
||||
virtual void AddControl(Control* Ctrl);
|
||||
|
||||
// Used to properly clean up the control.
|
||||
virtual void Dispose();
|
||||
|
||||
// Sets the text and background colors of the DC, and returns the background HBRUSH.
|
||||
virtual uintptr_t InitializeDCForWmCtlColor(HDC Dc, int32_t Message);
|
||||
|
||||
// Custom message index cache
|
||||
static uint32_t WM_MOUSEENTER;
|
||||
static uint32_t WM_INVOKEUI;
|
||||
|
||||
// GDI+ palette for rendering
|
||||
static HPALETTE HalftonePalette;
|
||||
|
||||
// Whether or not we are a container
|
||||
virtual bool IsContainerControl();
|
||||
|
||||
// GDI region copying
|
||||
static HRGN CreateCopyOfRgn(HRGN InRgn);
|
||||
|
||||
// Constructs a control from a handle
|
||||
static Control* FromHandle(HWND hWnd);
|
||||
// Constructs a control from a child handle
|
||||
static Control* FromChildHandle(HWND hWnd);
|
||||
|
||||
private:
|
||||
// The control styles
|
||||
ControlStyles _ControlStyles;
|
||||
// The control states
|
||||
ControlStates _ControlStates;
|
||||
|
||||
// Total count of suspended layout transactions
|
||||
uint8_t _LayoutSuspendCount;
|
||||
|
||||
// Whether or not DPI/Font scaling is required
|
||||
bool _RequiredScalingEnabled;
|
||||
// Required scaling mode
|
||||
BoundsSpecified _RequiredScaling;
|
||||
|
||||
// The control drag drop interface
|
||||
std::unique_ptr<DropTarget> _DropTarget;
|
||||
|
||||
// We must define each window message handler here...
|
||||
void WmMouseDown(Message& Msg, MouseButtons Button, uint32_t Clicks);
|
||||
void WmMouseUp(Message& Msg, MouseButtons Button, uint32_t Clicks);
|
||||
void WmMouseEnter(Message& Msg);
|
||||
void WmMouseLeave(Message& Msg);
|
||||
void WmMouseHover(Message& Msg);
|
||||
void WmClose(Message& Msg);
|
||||
void WmEraseBkgnd(Message& Msg);
|
||||
void WmPaint(Message& Msg);
|
||||
void WmCreate(Message& Msg);
|
||||
void WmShowWindow(Message& Msg);
|
||||
void WmMove(Message& Msg);
|
||||
void WmParentNotify(Message& Msg);
|
||||
void WmCommand(Message& Msg);
|
||||
void WmQueryNewPalette(Message& Msg);
|
||||
void WmNotify(Message& Msg);
|
||||
void WmNotifyFormat(Message& Msg);
|
||||
void WmCaptureChanged(Message& Msg);
|
||||
void WmCtlColorControl(Message& Msg);
|
||||
void WmKillFocus(Message& Msg);
|
||||
void WmSetFocus(Message& Msg);
|
||||
void WmMouseMove(Message& Msg);
|
||||
void WmSetCursor(Message& Msg);
|
||||
void WmMouseWheel(Message& Msg);
|
||||
void WmKeyChar(Message& Msg);
|
||||
void WmWindowPosChanged(Message& Msg);
|
||||
void WmInvokeOnUIThread(Message& Msg);
|
||||
|
||||
// Removes pending messages from the message queue.
|
||||
void RemovePendingMessages(uint32_t MsgMin, uint32_t MsgMax);
|
||||
|
||||
// Internal routine to update a child's z-order.
|
||||
void UpdateChildZOrder(Control* Ctrl);
|
||||
// Internal routine to update a childs index in the control array.
|
||||
void UpdateChildControlIndex(Control* Ctrl);
|
||||
|
||||
// This is called recursively when visibility is changed for a control.
|
||||
void SelectNextIfFocused();
|
||||
|
||||
// Internal routine to find the next available control.
|
||||
Control* GetNextSelectableControl(Control* Ctrl, bool Forward, bool TabStopOnly, bool Nested, bool Wrap);
|
||||
// Internal routine to get the first child in tab order.
|
||||
Control* GetFirstChildcontrolInTabOrder(bool Forward);
|
||||
|
||||
// Internal routine used to reflect messages up from a top level control.
|
||||
static bool ReflectMessageInternal(HWND hWnd, Message& Msg);
|
||||
// Internal routine to check for a container control
|
||||
static bool IsFocusManagingContainerControl(Control* Ctrl);
|
||||
|
||||
// Internal routine to make sure a class is registered
|
||||
static string RegisterWndClass(const char* ClassName, DWORD ClassStyle, bool& Subclass);
|
||||
};
|
||||
}
|
143
r5dev/thirdparty/cppnet/cppkore/ControlCollection.cpp
vendored
Normal file
143
r5dev/thirdparty/cppnet/cppkore/ControlCollection.cpp
vendored
Normal file
@ -0,0 +1,143 @@
|
||||
#include "stdafx.h"
|
||||
#include "ControlCollection.h"
|
||||
#include "Control.h"
|
||||
|
||||
namespace Forms
|
||||
{
|
||||
ControlCollection::~ControlCollection()
|
||||
{
|
||||
// We own the control as soon as the collection takes ahold of it...
|
||||
for (auto& Ctrl : this->_Controls)
|
||||
delete Ctrl;
|
||||
}
|
||||
|
||||
void ControlCollection::Add(Control* Ctrl)
|
||||
{
|
||||
this->_Controls.Add(Ctrl);
|
||||
}
|
||||
|
||||
void ControlCollection::Remove(Control* Ctrl)
|
||||
{
|
||||
if (Ctrl == nullptr)
|
||||
return;
|
||||
|
||||
this->_Controls.Remove(Ctrl);
|
||||
delete Ctrl;
|
||||
}
|
||||
|
||||
void ControlCollection::RemoveAt(uint32_t Index)
|
||||
{
|
||||
if (Index < this->_Controls.Count())
|
||||
{
|
||||
auto Ptr = this->_Controls[Index];
|
||||
this->_Controls.RemoveAt(Index);
|
||||
delete Ptr;
|
||||
}
|
||||
}
|
||||
|
||||
int32_t ControlCollection::IndexOf(Control* Ctrl)
|
||||
{
|
||||
auto Result = this->_Controls.IndexOf(Ctrl);
|
||||
|
||||
return (Result == List<Control*>::InvalidPosition) ? -1 : (int32_t)Result;
|
||||
}
|
||||
|
||||
bool ControlCollection::Contains(Control* Ctrl)
|
||||
{
|
||||
return IndexOf(Ctrl) > -1;
|
||||
}
|
||||
|
||||
void ControlCollection::SetChildIndex(Control* Ctrl, int32_t Index)
|
||||
{
|
||||
auto CurrentIndex = IndexOf(Ctrl);
|
||||
|
||||
if (CurrentIndex == Index || CurrentIndex == -1)
|
||||
return;
|
||||
|
||||
if (Index >= (int32_t)Count() || Index == -1)
|
||||
{
|
||||
Index = Count() - 1;
|
||||
}
|
||||
|
||||
MoveElement(Ctrl, CurrentIndex, Index);
|
||||
Ctrl->UpdateZOrder();
|
||||
}
|
||||
|
||||
uint32_t ControlCollection::Count()
|
||||
{
|
||||
return this->_Controls.Count();
|
||||
}
|
||||
|
||||
Control* ControlCollection::operator[](size_t Index)
|
||||
{
|
||||
return (Control*)this->_Controls[Index];
|
||||
}
|
||||
|
||||
Control* ControlCollection::begin() const noexcept
|
||||
{
|
||||
return (Control*)this->_Controls.begin();
|
||||
}
|
||||
|
||||
Control* ControlCollection::end() const noexcept
|
||||
{
|
||||
return (Control*)this->_Controls.end();
|
||||
}
|
||||
|
||||
void ControlCollection::MoveElement(Control* Ctrl, int32_t CurrentIndex, int32_t NewIndex)
|
||||
{
|
||||
int32_t Delta = NewIndex - CurrentIndex;
|
||||
|
||||
switch (Delta)
|
||||
{
|
||||
case -1:
|
||||
case 1:
|
||||
this->_Controls[CurrentIndex] = this->_Controls[NewIndex];
|
||||
break;
|
||||
|
||||
default:
|
||||
{
|
||||
int32_t Start = 0;
|
||||
int32_t Dest = 0;
|
||||
|
||||
if (Delta > 0)
|
||||
{
|
||||
Start = CurrentIndex + 1;
|
||||
Dest = NewIndex;
|
||||
}
|
||||
else
|
||||
{
|
||||
Start = NewIndex;
|
||||
Dest = NewIndex + 1;
|
||||
|
||||
Delta = -Delta;
|
||||
}
|
||||
|
||||
CopyElement(Start, Dest, Delta);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
this->_Controls[NewIndex] = Ctrl;
|
||||
}
|
||||
|
||||
void ControlCollection::CopyElement(int32_t SourceIndex, int32_t DestinationIndex, uint32_t Length)
|
||||
{
|
||||
if (SourceIndex < DestinationIndex)
|
||||
{
|
||||
SourceIndex = SourceIndex + Length;
|
||||
DestinationIndex = DestinationIndex + Length;
|
||||
|
||||
for (; Length > 0; Length--)
|
||||
{
|
||||
this->_Controls[--DestinationIndex] = this->_Controls[--SourceIndex];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (; Length > 0; Length--)
|
||||
{
|
||||
this->_Controls[DestinationIndex++] = this->_Controls[SourceIndex++];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
54
r5dev/thirdparty/cppnet/cppkore/ControlCollection.h
vendored
Normal file
54
r5dev/thirdparty/cppnet/cppkore/ControlCollection.h
vendored
Normal file
@ -0,0 +1,54 @@
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include <cstdint>
|
||||
#include "ListBase.h"
|
||||
|
||||
namespace Forms
|
||||
{
|
||||
// We can't create a circle dependency here, so we define an empty class for use later...
|
||||
class Control;
|
||||
|
||||
// Contains a collection of child controls for a ContainerControl
|
||||
class ControlCollection
|
||||
{
|
||||
public:
|
||||
ControlCollection() = default;
|
||||
~ControlCollection();
|
||||
|
||||
// Adds the specified control to the collection.
|
||||
void Add(Control* Ctrl);
|
||||
// Removes the specified control from the collection.
|
||||
void Remove(Control* Ctrl);
|
||||
// Removes the specified control by index from the collection.
|
||||
void RemoveAt(uint32_t Index);
|
||||
|
||||
// Gets the index of the control in the collection.
|
||||
int32_t IndexOf(Control* Ctrl);
|
||||
// Checks if this collection contains the control.
|
||||
bool Contains(Control* Ctrl);
|
||||
|
||||
// Sets the index of the specified child control.
|
||||
void SetChildIndex(Control* Ctrl, int32_t Index);
|
||||
|
||||
// Returns the count of controls
|
||||
uint32_t Count();
|
||||
|
||||
// Array index operator
|
||||
Control* operator[](size_t Index);
|
||||
|
||||
// Iterator definitions, for for(& :) loop
|
||||
Control* begin() const noexcept;
|
||||
Control* end() const noexcept;
|
||||
|
||||
private:
|
||||
|
||||
// An internal pointer list of controls
|
||||
List<Control*> _Controls;
|
||||
|
||||
// Internal routine to move a control
|
||||
void MoveElement(Control* Ctrl, int32_t CurrentIndex, int32_t NewIndex);
|
||||
// Internal routine to copy controls
|
||||
void CopyElement(int32_t SourceIndex, int32_t DestinationIndex, uint32_t Length);
|
||||
};
|
||||
}
|
51
r5dev/thirdparty/cppnet/cppkore/ControlStates.h
vendored
Normal file
51
r5dev/thirdparty/cppnet/cppkore/ControlStates.h
vendored
Normal file
@ -0,0 +1,51 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <type_traits>
|
||||
|
||||
namespace Forms
|
||||
{
|
||||
// Specifies control states.
|
||||
enum class ControlStates
|
||||
{
|
||||
StateCreated = 0x00000001,
|
||||
StateVisible = 0x00000002,
|
||||
StateEnabled = 0x00000004,
|
||||
StateTabstop = 0x00000008,
|
||||
StateRecreate = 0x00000010,
|
||||
StateModal = 0x00000020,
|
||||
StateAllowDrop = 0x00000040,
|
||||
StateDropTarget = 0x00000080,
|
||||
StateNoZOrder = 0x00000100,
|
||||
StateLayoutDeferred = 0x00000200,
|
||||
StateUseWaitCursor = 0x00000400,
|
||||
StateDisposed = 0x00000800,
|
||||
StateDisposing = 0x00001000,
|
||||
StateMouseEnterPending = 0x00002000,
|
||||
StateTrackingMouseEvent = 0x00004000,
|
||||
StateThreadMarshallPending = 0x00008000,
|
||||
StateSizeLockedByOS = 0x00010000,
|
||||
StateCausesValidation = 0x00020000,
|
||||
StateCreatingHandle = 0x00040000,
|
||||
StateTopLevel = 0x00080000,
|
||||
StateISACCESSIBLE = 0x00100000,
|
||||
StateOwnCtlBrush = 0x00200000,
|
||||
StateExceptionWhilePainting = 0x00400000,
|
||||
StateLayoutIsDirty = 0x00800000,
|
||||
StateCheckedHost = 0x01000000,
|
||||
StateHostedInDialog = 0x02000000,
|
||||
StateDoubleClickFired = 0x04000000,
|
||||
StateMousePressed = 0x08000000,
|
||||
StateValidationCancelled = 0x10000000,
|
||||
StateParentRecreating = 0x20000000,
|
||||
StateMirrored = 0x40000000,
|
||||
};
|
||||
|
||||
//
|
||||
// Allow bitwise operations on this enumeration
|
||||
//
|
||||
constexpr ControlStates operator|(ControlStates Lhs, ControlStates Rhs)
|
||||
{
|
||||
return static_cast<ControlStates>(static_cast<std::underlying_type<ControlStates>::type>(Lhs) | static_cast<std::underlying_type<ControlStates>::type>(Rhs));
|
||||
};
|
||||
}
|
75
r5dev/thirdparty/cppnet/cppkore/ControlStyles.h
vendored
Normal file
75
r5dev/thirdparty/cppnet/cppkore/ControlStyles.h
vendored
Normal file
@ -0,0 +1,75 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <type_traits>
|
||||
|
||||
namespace Forms
|
||||
{
|
||||
// Specifies control functionality.
|
||||
enum class ControlStyles
|
||||
{
|
||||
// Indicates whether the control is a container-like control.
|
||||
ContainerControl = 0x00000001,
|
||||
// The control paints itself; WM_PAINT and WM_ERASEBKGND messages are not passed
|
||||
// on to the underlying NativeWindow.
|
||||
UserPaint = 0x00000002,
|
||||
// If specified, a PaintBackground event will not be raised, OnPaintBackground will not be called,
|
||||
// and Invalidate() will not invalidate the background of the HWND.
|
||||
Opaque = 0x00000004,
|
||||
// The control is completely redrawn when it is resized.
|
||||
ResizeRedraw = 0x00000010,
|
||||
// The control has a fixed width.
|
||||
FixedWidth = 0x00000020,
|
||||
// The control has a fixed height.
|
||||
FixedHeight = 0x00000040,
|
||||
// If set, windows forms calls OnClick and raises the Click event when the control is clicked
|
||||
// (unless it's the second click of a double-click and StandardDoubleClick is specified).
|
||||
// Regardless of this style, the control may call OnClick directly.
|
||||
StandardClick = 0x00000100,
|
||||
// The control can get the focus.
|
||||
Selectable = 0x00000200,
|
||||
// The control does its own mouse processing; WM_MOUSEDOWN, WM_MOUSEMOVE, and WM_MOUSEUP messages are not passed
|
||||
// on to the underlying NativeWindow.
|
||||
UserMouse = 0x00000400,
|
||||
// If the BackColor is set to a color whose alpha component is
|
||||
// less than 255 (i.e., BackColor.A < 255), OnPaintBackground will simulate transparency
|
||||
// by asking its parent control to paint our background. This is not true transparency --
|
||||
// if there is another control between us and our parent, we will not show the control in the middle.
|
||||
SupportsTransparentBackColor = 0x00000800,
|
||||
// If set, windows forms calls OnDoubleClick and raises the DoubleClick event when the control is double clicked.
|
||||
// Regardless of whether it is set, the control may call OnDoubleClick directly.
|
||||
// This style is ignored if StandardClick is not set.
|
||||
StandardDoubleClick = 0x00001000,
|
||||
// If true, WM_ERASEBKGND is ignored, and both OnPaintBackground and OnPaint are called directly from
|
||||
// WM_PAINT. This generally reduces flicker, but can cause problems if other controls
|
||||
// send WM_ERASEBKGND messages to us. (This is sometimes done to achieve a pseudo-transparent effect similar to
|
||||
// ControlStyles.SupportsTransparentBackColor; for instance, ToolBar with flat appearance does this).
|
||||
// This style only makes sense if UserPaint is true.
|
||||
AllPaintingInWmPaint = 0x00002000,
|
||||
// If true, the control keeps a copy of the text rather than going to the hWnd for the
|
||||
// text every time. This improves performance but makes it difficult to keep the control
|
||||
// and hWnd's text synchronized.
|
||||
// This style defaults to false.
|
||||
CacheText = 0x00004000,
|
||||
// If true, the OnNotifyMessage method will be called for every message sent to
|
||||
// the control's WndProc.
|
||||
// This style defaults to false.
|
||||
EnableNotifyMessage = 0x00008000,
|
||||
// If set, control painting is double buffered (OBSOLETE, Use OptimizedDoubleBuffer).
|
||||
DoubleBuffer = 0x00010000,
|
||||
// If set, all control painting will be double buffered.
|
||||
OptimizedDoubleBuffer = 0x00020000,
|
||||
// If this style is set, and there is a value in the control's Text property, that value will be
|
||||
// used to determine the control's default Active Accessibility name and shortcut key. Otherwise,
|
||||
// the text of the preceding Label control will be used instead.
|
||||
UseTextForAccessibility = 0x00040000,
|
||||
};
|
||||
|
||||
//
|
||||
// Allow bitwise operations on this enumeration
|
||||
//
|
||||
constexpr ControlStyles operator|(ControlStyles Lhs, ControlStyles Rhs)
|
||||
{
|
||||
return static_cast<ControlStyles>(static_cast<std::underlying_type<ControlStyles>::type>(Lhs) | static_cast<std::underlying_type<ControlStyles>::type>(Rhs));
|
||||
};
|
||||
}
|
23
r5dev/thirdparty/cppnet/cppkore/ControlTypes.h
vendored
Normal file
23
r5dev/thirdparty/cppnet/cppkore/ControlTypes.h
vendored
Normal file
@ -0,0 +1,23 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
namespace Forms
|
||||
{
|
||||
// Represents the internal RTTI classes for the Forms controls
|
||||
enum class ControlTypes : uint8_t
|
||||
{
|
||||
Control = 0,
|
||||
Button = 1,
|
||||
Label = 2,
|
||||
CheckBox = 3,
|
||||
RadioButton = 4,
|
||||
GroupBox = 5,
|
||||
Form = 6,
|
||||
Panel = 7,
|
||||
ListView = 8,
|
||||
ComboBox = 9,
|
||||
ToolTip = 10,
|
||||
TextBox = 11,
|
||||
};
|
||||
}
|
42
r5dev/thirdparty/cppnet/cppkore/CppKore.natvis
vendored
Normal file
42
r5dev/thirdparty/cppnet/cppkore/CppKore.natvis
vendored
Normal file
@ -0,0 +1,42 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<AutoVisualizer xmlns="http://schemas.microsoft.com/vstudio/debugger/natvis/2010">
|
||||
<Type Name="List<*>">
|
||||
<Expand>
|
||||
<Item Name="[size]">_StoreSize</Item>
|
||||
<Item Name="[capacity]">_BufferSize</Item>
|
||||
<ArrayItems>
|
||||
<Size>_StoreSize</Size>
|
||||
<ValuePointer>_Buffer</ValuePointer>
|
||||
</ArrayItems>
|
||||
</Expand>
|
||||
</Type>
|
||||
<Type Name="StringBase<*>">
|
||||
<DisplayString Condition="_Buffer == nullptr">empty</DisplayString>
|
||||
<DisplayString>{_Buffer}</DisplayString>
|
||||
<Expand>
|
||||
<Item Name="[size]" ExcludeView="simple">_StoreSize</Item>
|
||||
<Item Name="[capacity]" ExcludeView="simple">_BufferSize</Item>
|
||||
<Item Name="[value]">_Buffer</Item>
|
||||
</Expand>
|
||||
</Type>
|
||||
<Type Name="Dictionary<*>">
|
||||
<Expand>
|
||||
<Item Name="[size]">_Count</Item>
|
||||
<Item Name="[capacity]">_BucketLength</Item>
|
||||
<ArrayItems>
|
||||
<Size>_Count</Size>
|
||||
<ValuePointer>_Entries._Mypair._Myval2</ValuePointer>
|
||||
</ArrayItems>
|
||||
</Expand>
|
||||
</Type>
|
||||
<Type Name="Assets::Texture">
|
||||
<Expand>
|
||||
<Item Name="Width">((DirectX::ScratchImage*)DirectXImage)->m_metadata.width</Item>
|
||||
<Item Name="Height">((DirectX::ScratchImage*)DirectXImage)->m_metadata.height</Item>
|
||||
<Item Name="MipLevels">((DirectX::ScratchImage*)DirectXImage)->m_metadata.mipLevels</Item>
|
||||
<Item Name="Format">((DirectX::ScratchImage*)DirectXImage)->m_metadata.format</Item>
|
||||
<Item Name="Dimensions">((DirectX::ScratchImage*)DirectXImage)->m_metadata.dimension</Item>
|
||||
<Item Name="DirectX Image">((DirectX::ScratchImage*)DirectXImage)</Item>
|
||||
</Expand>
|
||||
</Type>
|
||||
</AutoVisualizer>
|
26
r5dev/thirdparty/cppnet/cppkore/CreateParams.h
vendored
Normal file
26
r5dev/thirdparty/cppnet/cppkore/CreateParams.h
vendored
Normal file
@ -0,0 +1,26 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include "StringBase.h"
|
||||
|
||||
namespace Forms
|
||||
{
|
||||
// A structure that contains the CreateWindow parameters for this control.
|
||||
struct CreateParams
|
||||
{
|
||||
string ClassName;
|
||||
string Caption;
|
||||
|
||||
uint32_t Style;
|
||||
uint32_t ExStyle;
|
||||
uint32_t ClassStyle;
|
||||
|
||||
uint32_t X;
|
||||
uint32_t Y;
|
||||
uint32_t Width;
|
||||
uint32_t Height;
|
||||
|
||||
uintptr_t Parent;
|
||||
uintptr_t Param;
|
||||
};
|
||||
}
|
96
r5dev/thirdparty/cppnet/cppkore/Curve.cpp
vendored
Normal file
96
r5dev/thirdparty/cppnet/cppkore/Curve.cpp
vendored
Normal file
@ -0,0 +1,96 @@
|
||||
#include "stdafx.h"
|
||||
#include "Curve.h"
|
||||
|
||||
namespace Assets
|
||||
{
|
||||
Curve::Curve()
|
||||
: Curve("", CurveProperty::Extra, AnimationCurveMode::Absolute)
|
||||
{
|
||||
}
|
||||
|
||||
Curve::Curve(const string& Name, CurveProperty Property)
|
||||
: Curve(Name, Property, AnimationCurveMode::Absolute)
|
||||
{
|
||||
}
|
||||
|
||||
Curve::Curve(const string& Name, CurveProperty Property, AnimationCurveMode Mode)
|
||||
: Name(Name), Property(Property), Mode(Mode), _IsFrameIntegral(true)
|
||||
{
|
||||
}
|
||||
|
||||
bool Curve::IsFrameIntegral() const
|
||||
{
|
||||
return this->_IsFrameIntegral;
|
||||
}
|
||||
|
||||
void Curve::SetFrameIntegral(bool Value)
|
||||
{
|
||||
if (this->_IsFrameIntegral != Value)
|
||||
{
|
||||
this->_IsFrameIntegral = Value;
|
||||
|
||||
for (auto& Key : Keyframes)
|
||||
{
|
||||
if (Value)
|
||||
Key.Frame.Integer32 = (uint32_t)Key.Frame.Float;
|
||||
else
|
||||
Key.Frame.Float = (float)Key.Frame.Integer32;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CurveValue::CurveValue(uint8_t Value)
|
||||
: Byte(Value)
|
||||
{
|
||||
}
|
||||
|
||||
CurveValue::CurveValue(uint32_t Value)
|
||||
: Integer32(Value)
|
||||
{
|
||||
}
|
||||
|
||||
CurveValue::CurveValue(float Value)
|
||||
: Float(Value)
|
||||
{
|
||||
}
|
||||
|
||||
CurveValue::CurveValue(Math::Quaternion Value)
|
||||
: Vector4(Value)
|
||||
{
|
||||
}
|
||||
|
||||
CurveFrame::CurveFrame(uint32_t Value)
|
||||
: Integer32(Value)
|
||||
{
|
||||
}
|
||||
|
||||
CurveFrame::CurveFrame(float Value)
|
||||
: Float(Value)
|
||||
{
|
||||
}
|
||||
|
||||
CurveKeyframe::CurveKeyframe()
|
||||
: Frame(0u), Value({0, 0, 0, 0})
|
||||
{
|
||||
}
|
||||
|
||||
CurveKeyframe::CurveKeyframe(uint32_t Frame, float Value)
|
||||
: Frame(Frame), Value(Value)
|
||||
{
|
||||
}
|
||||
|
||||
CurveKeyframe::CurveKeyframe(float Frame, float Value)
|
||||
: Frame(Frame), Value(Value)
|
||||
{
|
||||
}
|
||||
|
||||
CurveKeyframe::CurveKeyframe(uint32_t Frame, Math::Quaternion Value)
|
||||
: Frame(Frame), Value(Value)
|
||||
{
|
||||
}
|
||||
|
||||
CurveKeyframe::CurveKeyframe(float Frame, Math::Quaternion Value)
|
||||
: Frame(Frame), Value(Value)
|
||||
{
|
||||
}
|
||||
}
|
91
r5dev/thirdparty/cppnet/cppkore/Curve.h
vendored
Normal file
91
r5dev/thirdparty/cppnet/cppkore/Curve.h
vendored
Normal file
@ -0,0 +1,91 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include "StringBase.h"
|
||||
#include "ListBase.h"
|
||||
#include "Vector3.h"
|
||||
#include "Quaternion.h"
|
||||
#include "AnimationTypes.h"
|
||||
|
||||
namespace Assets
|
||||
{
|
||||
// The property of the node being animated
|
||||
enum class CurveProperty
|
||||
{
|
||||
Extra,
|
||||
RotateQuaternion,
|
||||
RotateX,
|
||||
RotateY,
|
||||
RotateZ,
|
||||
TranslateX,
|
||||
TranslateY,
|
||||
TranslateZ,
|
||||
ScaleX,
|
||||
ScaleY,
|
||||
ScaleZ,
|
||||
Visibility,
|
||||
};
|
||||
|
||||
union CurveFrame
|
||||
{
|
||||
uint32_t Integer32;
|
||||
float Float;
|
||||
|
||||
explicit CurveFrame(uint32_t Value);
|
||||
explicit CurveFrame(float Value);
|
||||
};
|
||||
|
||||
union CurveValue
|
||||
{
|
||||
uint8_t Byte;
|
||||
uint32_t Integer32;
|
||||
float Float;
|
||||
Math::Quaternion Vector4;
|
||||
|
||||
explicit CurveValue(uint8_t Value);
|
||||
explicit CurveValue(uint32_t Value);
|
||||
explicit CurveValue(float Value);
|
||||
explicit CurveValue(Math::Quaternion Value);
|
||||
};
|
||||
|
||||
// A keyframe is a pair of frame time and value at that specific frame time
|
||||
struct CurveKeyframe
|
||||
{
|
||||
CurveFrame Frame;
|
||||
CurveValue Value;
|
||||
|
||||
CurveKeyframe();
|
||||
explicit CurveKeyframe(uint32_t Frame, float Value);
|
||||
explicit CurveKeyframe(float Frame, float Value);
|
||||
explicit CurveKeyframe(uint32_t Frame, Math::Quaternion Value);
|
||||
explicit CurveKeyframe(float Frame, Math::Quaternion Value);
|
||||
};
|
||||
|
||||
// Represents a 3D animation curve for a specific node->property.
|
||||
class Curve
|
||||
{
|
||||
public:
|
||||
Curve();
|
||||
Curve(const string& Name, CurveProperty Property);
|
||||
Curve(const string& Name, CurveProperty Property, AnimationCurveMode Mode);
|
||||
|
||||
// The node name of this curve.
|
||||
string Name;
|
||||
// The property of the node for the curve.
|
||||
CurveProperty Property;
|
||||
|
||||
// Whether or not the frame is an integer, or floating point value. (Default: true)
|
||||
bool IsFrameIntegral() const;
|
||||
// Sets whether or not the frame is an integer, or floating point value.
|
||||
void SetFrameIntegral(bool Value);
|
||||
|
||||
// A list of keyframes that make up this curve
|
||||
List<CurveKeyframe> Keyframes;
|
||||
// The mode to apply each curve value using (Default: Absolute)
|
||||
AnimationCurveMode Mode;
|
||||
|
||||
private:
|
||||
// Internal cached values
|
||||
bool _IsFrameIntegral;
|
||||
};
|
||||
}
|
110
r5dev/thirdparty/cppnet/cppkore/DDS.cpp
vendored
Normal file
110
r5dev/thirdparty/cppnet/cppkore/DDS.cpp
vendored
Normal file
@ -0,0 +1,110 @@
|
||||
#include "stdafx.h"
|
||||
#include "DDS.h"
|
||||
|
||||
#include "..\cppkore_incl\DirectXTex\DirectXTex.h"
|
||||
|
||||
#if _WIN64
|
||||
#if _DEBUG
|
||||
#pragma comment(lib, "..\\cppkore_libs\\DirectXTex\\DirectXTex_x64d.lib")
|
||||
#else
|
||||
#pragma comment(lib, "..\\cppkore_libs\\DirectXTex\\DirectXTex_x64r.lib")
|
||||
#endif
|
||||
#else
|
||||
#error DirectXTex doesn't support non x64 builds yet
|
||||
#endif
|
||||
|
||||
namespace Assets
|
||||
{
|
||||
DDSFormat::DDSFormat()
|
||||
: MipLevels(1), CubeMap(false), Format(DXGI_FORMAT::DXGI_FORMAT_UNKNOWN), Flags(DDSFormatFlags::None)
|
||||
{
|
||||
}
|
||||
|
||||
std::unique_ptr<uint8_t[]> DDS::TranscodeRGBToRGBA(const uint8_t* Buffer, uint32_t BufferSize, uint64_t& ResultSize)
|
||||
{
|
||||
// Must be divisible by 3
|
||||
if (BufferSize % 3 != 0)
|
||||
return nullptr;
|
||||
|
||||
ResultSize = (uint64_t)BufferSize + (BufferSize / 3);
|
||||
auto Result = std::make_unique<uint8_t[]>(ResultSize);
|
||||
|
||||
for (uint32_t i = 0; i < ResultSize; i += 4)
|
||||
{
|
||||
Result[i] = Buffer[i];
|
||||
Result[i + 1] = Buffer[i + 1];
|
||||
Result[i + 2] = Buffer[i + 2];
|
||||
Result[i + 3] = 0xFF;
|
||||
}
|
||||
|
||||
return std::move(Result);
|
||||
}
|
||||
|
||||
void DDS::WriteDDSHeader(const std::unique_ptr<IO::Stream>& Stream, uint32_t Width, uint32_t Height, const DDSFormat& Format)
|
||||
{
|
||||
WriteDDSHeader(Stream.get(), Width, Height, Format);
|
||||
}
|
||||
|
||||
void DDS::WriteDDSHeader(IO::Stream* Stream, uint32_t Width, uint32_t Height, const DDSFormat& Format)
|
||||
{
|
||||
// Temporary buffer
|
||||
char Buffer[0x100]{};
|
||||
DirectX::TexMetadata MetaData{};
|
||||
|
||||
MetaData.width = Width;
|
||||
MetaData.height = Height;
|
||||
MetaData.depth = 1;
|
||||
MetaData.arraySize = (Format.CubeMap) ? 6 : 1;
|
||||
MetaData.mipLevels = Format.MipLevels;
|
||||
MetaData.miscFlags = (Format.CubeMap) ? DirectX::TEX_MISC_FLAG::TEX_MISC_TEXTURECUBE : 0;
|
||||
MetaData.dimension = DirectX::TEX_DIMENSION::TEX_DIMENSION_TEXTURE2D;
|
||||
MetaData.format = Format.Format;
|
||||
|
||||
size_t ResultSize = 0;
|
||||
DirectX::EncodeDDSHeader(MetaData, 0, Buffer, sizeof(Buffer), ResultSize);
|
||||
|
||||
Stream->Write((uint8_t*)Buffer, 0, (uint64_t)ResultSize);
|
||||
}
|
||||
|
||||
void DDS::WriteDDSHeader(uint8_t* Buffer, uint32_t Width, uint32_t Height, const DDSFormat& Format, uint32_t& ResultSize)
|
||||
{
|
||||
DirectX::TexMetadata MetaData{};
|
||||
|
||||
MetaData.width = Width;
|
||||
MetaData.height = Height;
|
||||
MetaData.depth = 1;
|
||||
MetaData.arraySize = (Format.CubeMap) ? 6 : 1;
|
||||
MetaData.mipLevels = Format.MipLevels;
|
||||
MetaData.miscFlags = (Format.CubeMap) ? DirectX::TEX_MISC_FLAG::TEX_MISC_TEXTURECUBE : 0;
|
||||
MetaData.dimension = DirectX::TEX_DIMENSION::TEX_DIMENSION_TEXTURE2D;
|
||||
MetaData.format = Format.Format;
|
||||
|
||||
size_t Result = 0;
|
||||
DirectX::EncodeDDSHeader(MetaData, 0, Buffer, sizeof(Buffer), Result);
|
||||
|
||||
ResultSize = (uint32_t)Result;
|
||||
}
|
||||
|
||||
const uint32_t DDS::CalculateBlockSize(uint32_t Width, uint32_t Height, const DDSFormat& Format)
|
||||
{
|
||||
return (uint32_t)(DirectX::BitsPerPixel(Format.Format) * Width * Height) / 8;
|
||||
}
|
||||
|
||||
const uint32_t DDS::CountMipLevels(uint32_t Width, uint32_t Height)
|
||||
{
|
||||
uint32_t Result = 1;
|
||||
|
||||
while (Height > 1 || Width > 1)
|
||||
{
|
||||
if (Height > 1)
|
||||
Height >>= 1;
|
||||
|
||||
if (Width > 1)
|
||||
Width >>= 1;
|
||||
|
||||
++Result;
|
||||
}
|
||||
|
||||
return Result;
|
||||
}
|
||||
}
|
55
r5dev/thirdparty/cppnet/cppkore/DDS.h
vendored
Normal file
55
r5dev/thirdparty/cppnet/cppkore/DDS.h
vendored
Normal file
@ -0,0 +1,55 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <memory>
|
||||
#include <dxgiformat.h>
|
||||
#include "Stream.h"
|
||||
|
||||
namespace Assets
|
||||
{
|
||||
// Flags used to extend the DDS texture format.
|
||||
enum class DDSFormatFlags
|
||||
{
|
||||
None = 0
|
||||
};
|
||||
|
||||
// Contains information about the DDS texture format.
|
||||
struct DDSFormat
|
||||
{
|
||||
// The count of mip levels in this texture (Default: 1) (>= 1)
|
||||
uint32_t MipLevels;
|
||||
// Whether or not this is a cubemapped texture. (Default: false)
|
||||
bool CubeMap;
|
||||
// The block compression format for the texture. (Default: DXGI_FORMAT_UNKNOWN)
|
||||
DXGI_FORMAT Format;
|
||||
// Flags which extend the format for the texture. (Default: None)
|
||||
DDSFormatFlags Flags;
|
||||
|
||||
DDSFormat();
|
||||
};
|
||||
|
||||
// A utility class for building DDS assets.
|
||||
class DDS
|
||||
{
|
||||
// Don't initialize this class
|
||||
DDS() = delete;
|
||||
~DDS() = delete;
|
||||
|
||||
public:
|
||||
// Transcodes a buffer of (legacy) RGB8 data to a DXGI compatible RGBA buffer
|
||||
static std::unique_ptr<uint8_t[]> TranscodeRGBToRGBA(const uint8_t* Buffer, uint32_t BufferSize, uint64_t& ResultSize);
|
||||
|
||||
// Serializes a DDS header to the given stream.
|
||||
static void WriteDDSHeader(const std::unique_ptr<IO::Stream>& Stream, uint32_t Width, uint32_t Height, const DDSFormat& Format);
|
||||
// Serializes a DDS header to the given stream.
|
||||
static void WriteDDSHeader(IO::Stream* Stream, uint32_t Width, uint32_t Height, const DDSFormat& Format);
|
||||
|
||||
// Serializes a DDS header to the buffer.
|
||||
static void WriteDDSHeader(uint8_t* Buffer, uint32_t Width, uint32_t Height, const DDSFormat& Format, uint32_t& ResultSize);
|
||||
|
||||
// Calculate a block size for the given format.
|
||||
static const uint32_t CalculateBlockSize(uint32_t Width, uint32_t Height, const DDSFormat& Format);
|
||||
// Calculate the maximum level of mips.
|
||||
static const uint32_t CountMipLevels(uint32_t Width, uint32_t Height);
|
||||
};
|
||||
}
|
113
r5dev/thirdparty/cppnet/cppkore/DeflateCodec.cpp
vendored
Normal file
113
r5dev/thirdparty/cppnet/cppkore/DeflateCodec.cpp
vendored
Normal file
@ -0,0 +1,113 @@
|
||||
#include "stdafx.h"
|
||||
#include "DeflateCodec.h"
|
||||
|
||||
#include "..\cppkore_incl\ZLib\miniz.h"
|
||||
|
||||
#if _DEBUG
|
||||
#pragma comment(lib, "..\\cppkore_libs\\ZLib\\cppkorezlibx64d.lib")
|
||||
#else
|
||||
#pragma comment(lib, "..\\cppkore_libs\\ZLib\\cppkorezlibx64r.lib")
|
||||
#endif
|
||||
|
||||
namespace Compression
|
||||
{
|
||||
uint64_t DeflateCodec::Compress(uint8_t* Input, uint64_t InputOffset, uint64_t InputLength, uint8_t* Output, uint64_t OutputOffset, uint64_t OutputLength)
|
||||
{
|
||||
z_stream DeflateStream{};
|
||||
|
||||
if (deflateInit2(&DeflateStream, MZ_DEFAULT_LEVEL, MZ_DEFLATED, -MZ_DEFAULT_WINDOW_BITS, 9, MZ_DEFAULT_STRATEGY) != MZ_OK)
|
||||
return 0;
|
||||
|
||||
DeflateStream.avail_in = (uint32_t)InputLength;
|
||||
DeflateStream.avail_out = (uint32_t)OutputLength;
|
||||
DeflateStream.next_in = (const uint8_t*)(Input + InputOffset);
|
||||
DeflateStream.next_out = (uint8_t*)(Output + OutputOffset);
|
||||
|
||||
auto Result = deflate(&DeflateStream, MZ_SYNC_FLUSH);
|
||||
|
||||
deflateEnd(&DeflateStream);
|
||||
|
||||
if (Result == MZ_OK)
|
||||
return (uint64_t)DeflateStream.total_out;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::unique_ptr<uint8_t[]> DeflateCodec::Compress(uint8_t* Input, uint64_t InputOffset, uint64_t InputLength, uint64_t& OutputLength)
|
||||
{
|
||||
auto ResultBounds = compressBound((mz_ulong)InputLength);
|
||||
auto Result = std::make_unique<uint8_t[]>(ResultBounds);
|
||||
|
||||
OutputLength = 0;
|
||||
|
||||
z_stream DeflateStream{};
|
||||
|
||||
if (deflateInit2(&DeflateStream, MZ_DEFAULT_LEVEL, MZ_DEFLATED, -MZ_DEFAULT_WINDOW_BITS, 9, MZ_DEFAULT_STRATEGY) != MZ_OK)
|
||||
return nullptr;
|
||||
|
||||
DeflateStream.avail_in = (uint32_t)InputLength;
|
||||
DeflateStream.avail_out = (uint32_t)ResultBounds;
|
||||
DeflateStream.next_in = (const uint8_t*)(Input + InputOffset);
|
||||
DeflateStream.next_out = (uint8_t*)Result.get();
|
||||
|
||||
auto ResultCode = deflate(&DeflateStream, MZ_SYNC_FLUSH);
|
||||
|
||||
deflateEnd(&DeflateStream);
|
||||
|
||||
if (ResultCode != MZ_OK)
|
||||
return nullptr;
|
||||
|
||||
OutputLength = (uint64_t)DeflateStream.total_out;
|
||||
|
||||
return Result;
|
||||
}
|
||||
|
||||
uint64_t DeflateCodec::Decompress(uint8_t* Input, uint64_t InputOffset, uint64_t InputLength, uint8_t* Output, uint64_t OutputOffset, uint64_t OutputLength)
|
||||
{
|
||||
z_stream DeflateStream{};
|
||||
|
||||
if (inflateInit2(&DeflateStream, -MZ_DEFAULT_WINDOW_BITS) != MZ_OK)
|
||||
return 0;
|
||||
|
||||
DeflateStream.avail_in = (uint32_t)InputLength;
|
||||
DeflateStream.avail_out = (uint32_t)OutputLength;
|
||||
DeflateStream.next_in = (const uint8_t*)(Input + InputOffset);
|
||||
DeflateStream.next_out = (uint8_t*)(Output + OutputOffset);
|
||||
|
||||
auto Result = inflate(&DeflateStream, MZ_SYNC_FLUSH);
|
||||
|
||||
inflateEnd(&DeflateStream);
|
||||
|
||||
if (Result == MZ_OK || (DeflateStream.total_out == OutputLength))
|
||||
return (uint64_t)DeflateStream.total_out;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::unique_ptr<uint8_t[]> DeflateCodec::Decompress(uint8_t* Input, uint64_t InputOffset, uint64_t InputLength, uint64_t KnownOutputLength)
|
||||
{
|
||||
if (InputLength == 0)
|
||||
return nullptr;
|
||||
|
||||
auto Result = std::make_unique<uint8_t[]>(KnownOutputLength);
|
||||
|
||||
z_stream DeflateStream{};
|
||||
|
||||
if (inflateInit2(&DeflateStream, -MZ_DEFAULT_WINDOW_BITS) != MZ_OK)
|
||||
return 0;
|
||||
|
||||
DeflateStream.avail_in = (uint32_t)InputLength;
|
||||
DeflateStream.avail_out = (uint32_t)KnownOutputLength;
|
||||
DeflateStream.next_in = (const uint8_t*)(Input + InputOffset);
|
||||
DeflateStream.next_out = (uint8_t*)Result.get();
|
||||
|
||||
auto ResultCode = inflate(&DeflateStream, MZ_SYNC_FLUSH);
|
||||
|
||||
inflateEnd(&DeflateStream);
|
||||
|
||||
if (ResultCode == MZ_OK || (DeflateStream.total_out == KnownOutputLength))
|
||||
return Result;
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
}
|
23
r5dev/thirdparty/cppnet/cppkore/DeflateCodec.h
vendored
Normal file
23
r5dev/thirdparty/cppnet/cppkore/DeflateCodec.h
vendored
Normal file
@ -0,0 +1,23 @@
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include <cstdint>
|
||||
|
||||
namespace Compression
|
||||
{
|
||||
// A compression codec that implements the Deflate algo.
|
||||
class DeflateCodec
|
||||
{
|
||||
public:
|
||||
|
||||
// Compress the input buffer using the Deflate codec
|
||||
static uint64_t Compress(uint8_t* Input, uint64_t InputOffset, uint64_t InputLength, uint8_t* Output, uint64_t OutputOffset, uint64_t OutputLength);
|
||||
// Compress the input buffer using the Deflate codec
|
||||
static std::unique_ptr<uint8_t[]> Compress(uint8_t* Input, uint64_t InputOffset, uint64_t InputLength, uint64_t& OutputLength);
|
||||
|
||||
// Decompress the input buffer using the Deflate codec
|
||||
static uint64_t Decompress(uint8_t* Input, uint64_t InputOffset, uint64_t InputLength, uint8_t* Output, uint64_t OutputOffset, uint64_t OutputLength);
|
||||
// Decompress the input buffer using the Deflate codec (With known output length)
|
||||
static std::unique_ptr<uint8_t[]> Decompress(uint8_t* Input, uint64_t InputOffset, uint64_t InputLength, uint64_t KnownOutputLength);
|
||||
};
|
||||
}
|
219
r5dev/thirdparty/cppnet/cppkore/DeflateStream.cpp
vendored
Normal file
219
r5dev/thirdparty/cppnet/cppkore/DeflateStream.cpp
vendored
Normal file
@ -0,0 +1,219 @@
|
||||
#include "stdafx.h"
|
||||
#include "DeflateStream.h"
|
||||
|
||||
#include "..\cppkore_incl\ZLib\miniz.h"
|
||||
|
||||
#if _DEBUG
|
||||
#pragma comment(lib, "..\\cppkore_libs\\ZLib\\cppkorezlibx64d.lib")
|
||||
#else
|
||||
#pragma comment(lib, "..\\cppkore_libs\\ZLib\\cppkorezlibx64r.lib")
|
||||
#endif
|
||||
|
||||
namespace Compression
|
||||
{
|
||||
DeflateStream::DeflateStream(std::unique_ptr<IO::Stream> Stream, CompressionMode Mode, bool LeaveOpen)
|
||||
: BaseStream(std::move(Stream)), _Mode(Mode), _LeaveOpen(LeaveOpen), _BufferLength(DeflateStream::DefaultBufferSize), _BufferOffset(0)
|
||||
{
|
||||
this->_Buffer = std::make_unique<uint8_t[]>(DeflateStream::DefaultBufferSize);
|
||||
this->CreateInflatorDeflator();
|
||||
}
|
||||
|
||||
DeflateStream::DeflateStream(IO::Stream* Stream, CompressionMode Mode, bool LeaveOpen)
|
||||
: BaseStream(Stream), _Mode(Mode), _LeaveOpen(LeaveOpen), _BufferLength(DeflateStream::DefaultBufferSize), _BufferOffset(0)
|
||||
{
|
||||
this->_Buffer = std::make_unique<uint8_t[]>(DeflateStream::DefaultBufferSize);
|
||||
this->CreateInflatorDeflator();
|
||||
}
|
||||
|
||||
DeflateStream::~DeflateStream()
|
||||
{
|
||||
this->Close();
|
||||
}
|
||||
|
||||
bool DeflateStream::CanRead()
|
||||
{
|
||||
return (this->_Mode == CompressionMode::Decompress);
|
||||
}
|
||||
|
||||
bool DeflateStream::CanWrite()
|
||||
{
|
||||
return (this->_Mode == CompressionMode::Compress);
|
||||
}
|
||||
|
||||
bool DeflateStream::CanSeek()
|
||||
{
|
||||
return (_Mode == CompressionMode::Decompress);
|
||||
}
|
||||
|
||||
bool DeflateStream::GetIsEndOfFile()
|
||||
{
|
||||
return this->BaseStream->GetIsEndOfFile();
|
||||
}
|
||||
|
||||
uint64_t DeflateStream::GetLength()
|
||||
{
|
||||
return this->BaseStream->GetLength();
|
||||
}
|
||||
|
||||
uint64_t DeflateStream::GetPosition()
|
||||
{
|
||||
return this->BaseStream->GetPosition();
|
||||
}
|
||||
|
||||
void DeflateStream::SetLength(uint64_t Length)
|
||||
{
|
||||
IO::IOError::StreamSetLengthSupport();
|
||||
}
|
||||
|
||||
void DeflateStream::SetPosition(uint64_t Position)
|
||||
{
|
||||
if (_Mode == CompressionMode::Decompress)
|
||||
{
|
||||
this->BaseStream->SetPosition(Position);
|
||||
mz_inflateReset((mz_streamp)this->_DeflateState);
|
||||
}
|
||||
else
|
||||
IO::IOError::StreamNoSeekSupport();
|
||||
}
|
||||
|
||||
void DeflateStream::Close()
|
||||
{
|
||||
if (this->_Mode == CompressionMode::Compress)
|
||||
this->WriteDeflaterOutput(); // Ensure that all data has been written to the stream...
|
||||
|
||||
if (this->_LeaveOpen)
|
||||
this->BaseStream.release();
|
||||
else
|
||||
this->BaseStream.reset();
|
||||
|
||||
this->_Buffer.reset();
|
||||
|
||||
if (this->_Mode == CompressionMode::Compress)
|
||||
deflateEnd((mz_streamp)this->_DeflateState);
|
||||
else
|
||||
inflateEnd((mz_streamp)this->_DeflateState);
|
||||
|
||||
delete (mz_streamp)this->_DeflateState;
|
||||
}
|
||||
|
||||
void DeflateStream::Flush()
|
||||
{
|
||||
if (this->CanWrite())
|
||||
this->BaseStream->Flush();
|
||||
}
|
||||
|
||||
void DeflateStream::Seek(uint64_t Offset, IO::SeekOrigin Origin)
|
||||
{
|
||||
if (_Mode == CompressionMode::Decompress)
|
||||
{
|
||||
this->BaseStream->Seek(Offset, Origin);
|
||||
mz_inflateReset((mz_streamp)this->_DeflateState);
|
||||
}
|
||||
else
|
||||
IO::IOError::StreamNoSeekSupport();
|
||||
}
|
||||
|
||||
uint64_t DeflateStream::Read(uint8_t* Buffer, uint64_t Offset, uint64_t Count)
|
||||
{
|
||||
uint64_t TotalRead = 0;
|
||||
uint64_t TotalOutNow = 0;
|
||||
|
||||
mz_streamp StreamState = (mz_streamp)this->_DeflateState;
|
||||
|
||||
TotalOutNow = StreamState->total_out;
|
||||
|
||||
while (true)
|
||||
{
|
||||
StreamState->avail_out = (unsigned int)(Count - TotalRead);
|
||||
StreamState->next_out = (unsigned char*)(Buffer + Offset + TotalRead);
|
||||
|
||||
auto Result = inflate(StreamState, MZ_SYNC_FLUSH);
|
||||
TotalRead = StreamState->total_out - TotalOutNow;
|
||||
|
||||
if (TotalRead == Count)
|
||||
break;
|
||||
|
||||
if (Result == MZ_STREAM_END)
|
||||
break;
|
||||
|
||||
auto RequiredRead = (StreamState->avail_in > 0) ? (DeflateStream::DefaultBufferSize - StreamState->avail_in) : DeflateStream::DefaultBufferSize;
|
||||
|
||||
//
|
||||
// We must move the z_stream expected block to the front, and then read expected input after...
|
||||
//
|
||||
|
||||
std::memmove(this->_Buffer.get(), this->_Buffer.get() + RequiredRead, StreamState->avail_in);
|
||||
|
||||
auto Bytes = this->BaseStream->Read(this->_Buffer.get(), StreamState->avail_in, RequiredRead);
|
||||
|
||||
if (Bytes == 0)
|
||||
break;
|
||||
|
||||
StreamState->next_in = (const unsigned char*)this->_Buffer.get();
|
||||
StreamState->avail_in = (unsigned int)DeflateStream::DefaultBufferSize;
|
||||
}
|
||||
|
||||
return TotalRead;
|
||||
}
|
||||
|
||||
uint64_t DeflateStream::Read(uint8_t* Buffer, uint64_t Offset, uint64_t Count, uint64_t Position)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void DeflateStream::Write(uint8_t* Buffer, uint64_t Offset, uint64_t Count)
|
||||
{
|
||||
// Continue to write if need be
|
||||
this->WriteDeflaterOutput();
|
||||
|
||||
// Set the new input and size to us
|
||||
mz_streamp StreamState = (mz_streamp)this->_DeflateState;
|
||||
|
||||
StreamState->avail_in = (unsigned int)Count;
|
||||
StreamState->next_in = (const unsigned char*)(Buffer + Offset);
|
||||
|
||||
// Write the last output
|
||||
this->WriteDeflaterOutput();
|
||||
}
|
||||
|
||||
void DeflateStream::Write(uint8_t* Buffer, uint64_t Offset, uint64_t Count, uint64_t Position)
|
||||
{
|
||||
}
|
||||
|
||||
void DeflateStream::CreateInflatorDeflator()
|
||||
{
|
||||
this->_DeflateState = new z_stream();
|
||||
|
||||
if (_Mode == CompressionMode::Compress)
|
||||
deflateInit2((mz_streamp)this->_DeflateState, MZ_DEFAULT_LEVEL, MZ_DEFLATED, -MZ_DEFAULT_WINDOW_BITS, 9, MZ_DEFAULT_STRATEGY);
|
||||
else if (_Mode == CompressionMode::Decompress)
|
||||
inflateInit2((mz_streamp)this->_DeflateState, -MZ_DEFAULT_WINDOW_BITS);
|
||||
|
||||
mz_streamp StreamState = (mz_streamp)this->_DeflateState;
|
||||
|
||||
// Setup default state values...
|
||||
StreamState->avail_in = 0;
|
||||
StreamState->avail_out = 0;
|
||||
StreamState->next_in = nullptr;
|
||||
StreamState->next_out = nullptr;
|
||||
}
|
||||
|
||||
void DeflateStream::WriteDeflaterOutput()
|
||||
{
|
||||
mz_streamp StreamState = (mz_streamp)this->_DeflateState;
|
||||
|
||||
// Loop until we need data again...
|
||||
while (StreamState->avail_in > 0)
|
||||
{
|
||||
// Reset the buffers
|
||||
StreamState->next_out = (unsigned char*)this->_Buffer.get();
|
||||
StreamState->avail_out = (unsigned int)DeflateStream::DefaultBufferSize;
|
||||
|
||||
// Prepare to deflate the data
|
||||
auto Result = deflate(StreamState, MZ_SYNC_FLUSH);
|
||||
|
||||
// Write the data if any
|
||||
this->BaseStream->Write(this->_Buffer.get(), 0, (DeflateStream::DefaultBufferSize - StreamState->avail_out));
|
||||
}
|
||||
}
|
||||
}
|
61
r5dev/thirdparty/cppnet/cppkore/DeflateStream.h
vendored
Normal file
61
r5dev/thirdparty/cppnet/cppkore/DeflateStream.h
vendored
Normal file
@ -0,0 +1,61 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <memory>
|
||||
#include "Stream.h"
|
||||
#include "CompressionMode.h"
|
||||
|
||||
namespace Compression
|
||||
{
|
||||
// DeflateStream supports decompressing and compressing Deflate encoded data
|
||||
class DeflateStream : public IO::Stream
|
||||
{
|
||||
public:
|
||||
DeflateStream(std::unique_ptr<IO::Stream> Stream, CompressionMode Mode, bool LeaveOpen = false);
|
||||
DeflateStream(IO::Stream* Stream, CompressionMode Mode, bool LeaveOpen = false);
|
||||
virtual ~DeflateStream();
|
||||
|
||||
// Implement Getters and Setters
|
||||
virtual bool CanRead();
|
||||
virtual bool CanWrite();
|
||||
virtual bool CanSeek();
|
||||
virtual bool GetIsEndOfFile();
|
||||
virtual uint64_t GetLength();
|
||||
virtual uint64_t GetPosition();
|
||||
virtual void SetLength(uint64_t Length);
|
||||
virtual void SetPosition(uint64_t Position);
|
||||
|
||||
// Implement functions
|
||||
virtual void Close();
|
||||
virtual void Flush();
|
||||
virtual void Seek(uint64_t Offset, IO::SeekOrigin Origin);
|
||||
virtual uint64_t Read(uint8_t* Buffer, uint64_t Offset, uint64_t Count);
|
||||
virtual uint64_t Read(uint8_t* Buffer, uint64_t Offset, uint64_t Count, uint64_t Position);
|
||||
virtual void Write(uint8_t* Buffer, uint64_t Offset, uint64_t Count);
|
||||
virtual void Write(uint8_t* Buffer, uint64_t Offset, uint64_t Count, uint64_t Position);
|
||||
|
||||
private:
|
||||
// Internal cached flags
|
||||
std::unique_ptr<IO::Stream> BaseStream;
|
||||
bool _LeaveOpen;
|
||||
|
||||
// Internal state
|
||||
void* _DeflateState;
|
||||
|
||||
// Internal buffer
|
||||
std::unique_ptr<uint8_t[]> _Buffer;
|
||||
uint32_t _BufferLength;
|
||||
uint32_t _BufferOffset;
|
||||
|
||||
// Mode to use on the data
|
||||
CompressionMode _Mode;
|
||||
|
||||
// An internal routine to setup the deflate state
|
||||
void CreateInflatorDeflator();
|
||||
// An internal routine to write deflater output
|
||||
void WriteDeflaterOutput();
|
||||
|
||||
// The default buffer size for deflate streams
|
||||
constexpr static uint32_t DefaultBufferSize = 8192;
|
||||
};
|
||||
}
|
35
r5dev/thirdparty/cppnet/cppkore/DialogResult.h
vendored
Normal file
35
r5dev/thirdparty/cppnet/cppkore/DialogResult.h
vendored
Normal file
@ -0,0 +1,35 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
namespace Forms
|
||||
{
|
||||
// Specifies identifiers to indicate the return value of a dialog box.
|
||||
enum class DialogResult
|
||||
{
|
||||
// Nothing is returned from the dialog box. This
|
||||
// means that the modal dialog continues running.
|
||||
None = 0,
|
||||
// The dialog box return value is
|
||||
// OK (usually sent from a button labeled OK).
|
||||
OK = 1,
|
||||
// The dialog box return value is Cancel (usually sent
|
||||
// from a button labeled Cancel).
|
||||
Cancel = 2,
|
||||
// The dialog box return value is
|
||||
// Abort (usually sent from a button labeled Abort).
|
||||
Abort = 3,
|
||||
// The dialog box return value is
|
||||
// Retry (usually sent from a button labeled Retry).
|
||||
Retry = 4,
|
||||
// The dialog box return value is Ignore (usually sent
|
||||
// from a button labeled Ignore).
|
||||
Ignore = 5,
|
||||
// The dialog box return value is
|
||||
// Yes (usually sent from a button labeled Yes).
|
||||
Yes = 6,
|
||||
// The dialog box return value is
|
||||
// No (usually sent from a button labeled No).
|
||||
No = 7,
|
||||
};
|
||||
}
|
573
r5dev/thirdparty/cppnet/cppkore/DictionaryBase.h
vendored
Normal file
573
r5dev/thirdparty/cppnet/cppkore/DictionaryBase.h
vendored
Normal file
@ -0,0 +1,573 @@
|
||||
#pragma once
|
||||
|
||||
#include <algorithm>
|
||||
#include <utility>
|
||||
#include <memory>
|
||||
#include "HashHelpers.h"
|
||||
#include "HashComparer.h"
|
||||
|
||||
// A KeyValuePair holds a key and a value from a dictionary.
|
||||
template<class TKey, class TValue>
|
||||
struct KeyValuePair : std::pair<TKey, TValue>
|
||||
{
|
||||
constexpr TKey& Key()
|
||||
{
|
||||
return this->first;
|
||||
}
|
||||
|
||||
constexpr TValue& Value()
|
||||
{
|
||||
return this->second;
|
||||
}
|
||||
|
||||
constexpr TKey& Key() const
|
||||
{
|
||||
return this->first;
|
||||
}
|
||||
|
||||
constexpr TValue& Value() const
|
||||
{
|
||||
return this->second;
|
||||
}
|
||||
};
|
||||
|
||||
// A container class that holds keys and values.
|
||||
template<class TKey, class TValue, class THasher = HashComparer<TKey>>
|
||||
class Dictionary
|
||||
{
|
||||
private:
|
||||
typedef KeyValuePair<TKey, TValue> PairType;
|
||||
|
||||
struct Entry
|
||||
{
|
||||
uint64_t HashCode; // Lower 63 bits of hash code, -1 if unused
|
||||
uint32_t Next; // Index of next entry, -1 if last
|
||||
|
||||
PairType Kvp;
|
||||
|
||||
Entry()
|
||||
: HashCode(-1), Next(-1)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
public:
|
||||
Dictionary();
|
||||
Dictionary(uint32_t Capacity);
|
||||
|
||||
constexpr Dictionary(const Dictionary& Value);
|
||||
constexpr Dictionary(Dictionary&& Value);
|
||||
|
||||
// Assignment operator
|
||||
constexpr Dictionary<TKey, TValue, THasher>& operator=(const Dictionary<TKey, TValue, THasher>& Rhs);
|
||||
|
||||
~Dictionary() = default;
|
||||
|
||||
// Adds the specified key and value to the dictionary (Returns: true if added)
|
||||
constexpr bool Add(TKey Key, TValue Value);
|
||||
// Adds the specified key value pair to the dictionary (Returns: true if added)
|
||||
constexpr bool Add(PairType Kvp);
|
||||
|
||||
// Removes a key and value from the dictionary if exists
|
||||
constexpr bool Remove(TKey Key);
|
||||
|
||||
// Clears the entries in the dictionary
|
||||
constexpr void Clear();
|
||||
|
||||
// Checks whether or not the dictionary contains the key
|
||||
constexpr bool ContainsKey(TKey Key);
|
||||
// Checks whether or not the dictionary contains the key
|
||||
constexpr bool ContainsKey(TKey Key) const;
|
||||
// Checks whether or not the dictionary contains the value
|
||||
constexpr bool ContainsValue(TValue Value);
|
||||
|
||||
// Attempts to get the value from the specified key
|
||||
constexpr bool TryGetValue(TKey Key, TValue& Value);
|
||||
|
||||
// TODO: Keys collection
|
||||
// TODO: Values collection
|
||||
|
||||
// Array index operator
|
||||
constexpr TValue& operator[](TKey& Key);
|
||||
constexpr TValue& operator[](const TKey& Key);
|
||||
constexpr TValue& operator[](TKey& Key) const;
|
||||
constexpr TValue& operator[](const TKey& Key) const;
|
||||
|
||||
// Define custom iterator for loops
|
||||
class DictionaryIterator : public std::iterator<std::forward_iterator_tag, KeyValuePair<TKey, TValue>>
|
||||
{
|
||||
public:
|
||||
DictionaryIterator(const Dictionary<TKey, TValue, THasher>* Dict, uint32_t Index = -1);
|
||||
~DictionaryIterator() = default;
|
||||
|
||||
// Increment operator
|
||||
DictionaryIterator& operator++()
|
||||
{
|
||||
MoveNext();
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Dereference operator
|
||||
KeyValuePair<TKey, TValue>& operator*();
|
||||
// Const dereference operator
|
||||
const KeyValuePair<TKey, TValue>& operator*() const;
|
||||
// Pointer access operator
|
||||
KeyValuePair<TKey, TValue>* operator->();
|
||||
|
||||
// Inequality operator
|
||||
bool operator!=(const DictionaryIterator& Rhs) const;
|
||||
|
||||
protected:
|
||||
// Internal cached flags
|
||||
const Dictionary<TKey, TValue, THasher>* Dict;
|
||||
KeyValuePair<TKey, TValue>* Kvp;
|
||||
uint32_t Index;
|
||||
|
||||
private:
|
||||
// Move the iterator to the next postion
|
||||
void MoveNext();
|
||||
};
|
||||
|
||||
// Iterator definitions, for for(& :) loop
|
||||
DictionaryIterator begin()
|
||||
{
|
||||
return DictionaryIterator(this);
|
||||
}
|
||||
|
||||
DictionaryIterator end()
|
||||
{
|
||||
return DictionaryIterator(this, this->_Count);
|
||||
}
|
||||
|
||||
// Const iterator definitions, for for(& :) loop
|
||||
DictionaryIterator begin() const
|
||||
{
|
||||
return DictionaryIterator(this);
|
||||
}
|
||||
|
||||
DictionaryIterator end() const
|
||||
{
|
||||
return DictionaryIterator(this, this->_Count);
|
||||
}
|
||||
|
||||
// Returns the count of items in the dictionary
|
||||
constexpr uint32_t Count() const;
|
||||
|
||||
private:
|
||||
// Internal buffers
|
||||
std::unique_ptr<uint32_t[]> _Buckets;
|
||||
std::unique_ptr<Entry[]> _Entries;
|
||||
|
||||
// Internal routine to add to the dictionary
|
||||
bool Insert(TKey& Key, TValue& Value, bool Add);
|
||||
// Internal routine to setup the dictionary
|
||||
void Initialize(uint32_t Capacity);
|
||||
// Internal routine to resize the dictionary
|
||||
void Resize();
|
||||
// Internal routine to resize the dictionary
|
||||
void Resize(uint32_t NewSize, bool ForceNewHashCodes);
|
||||
|
||||
// Internal routine to find an entry in the dictionary
|
||||
uint32_t FindEntry(const TKey& Key) const;
|
||||
|
||||
// Internal cached counts
|
||||
uint32_t _Count;
|
||||
uint32_t _FreeList;
|
||||
uint32_t _FreeCount;
|
||||
uint32_t _BucketLength;
|
||||
};
|
||||
|
||||
template<class TKey, class TValue, class THasher>
|
||||
inline Dictionary<TKey, TValue, THasher>::Dictionary()
|
||||
: Dictionary(0)
|
||||
{
|
||||
}
|
||||
|
||||
template<class TKey, class TValue, class THasher>
|
||||
inline Dictionary<TKey, TValue, THasher>::Dictionary(uint32_t Capacity)
|
||||
: _Count(0), _FreeList(-1), _FreeCount(0), _BucketLength(0)
|
||||
{
|
||||
if (Capacity > 0)
|
||||
Initialize(Capacity);
|
||||
}
|
||||
|
||||
template<class TKey, class TValue, class THasher>
|
||||
inline constexpr Dictionary<TKey, TValue, THasher>::Dictionary(const Dictionary& Value)
|
||||
{
|
||||
this->_Buckets.reset(new uint32_t[Value._BucketLength]);
|
||||
std::memcpy(this->_Buckets.get(), Value._Buckets.get(), Value._BucketLength * sizeof(uint32_t));
|
||||
|
||||
this->_Entries.reset(new Entry[Value._BucketLength]);
|
||||
std::copy(Value._Entries.get(), Value._Entries.get() + Value._BucketLength, this->_Entries);
|
||||
|
||||
this->_Count = Value._Count;
|
||||
this->_FreeList = Value._FreeList;
|
||||
this->_FreeCount = Value._FreeCount;
|
||||
this->_BucketLength = Value._BucketLength;
|
||||
}
|
||||
|
||||
template<class TKey, class TValue, class THasher>
|
||||
inline constexpr Dictionary<TKey, TValue, THasher>::Dictionary(Dictionary&& Value)
|
||||
{
|
||||
this->_Buckets.reset(Value._Buckets.release());
|
||||
this->_Entries.reset(Value._Entries.release());
|
||||
|
||||
this->_Count = Value._Count;
|
||||
this->_FreeList = Value._FreeList;
|
||||
this->_FreeCount = Value._FreeCount;
|
||||
this->_BucketLength = Value._BucketLength;
|
||||
|
||||
Value._Count = 0;
|
||||
Value._FreeList = -1;
|
||||
Value._FreeCount = 0;
|
||||
Value._BucketLength = 0;
|
||||
}
|
||||
|
||||
template<class TKey, class TValue, class THasher>
|
||||
inline constexpr Dictionary<TKey, TValue, THasher>& Dictionary<TKey, TValue, THasher>::operator=(const Dictionary<TKey, TValue, THasher>& Rhs)
|
||||
{
|
||||
if (Rhs._BucketLength != 0)
|
||||
{
|
||||
this->_Buckets.reset(new uint32_t[Rhs._BucketLength]());
|
||||
std::memcpy(this->_Buckets.get(), Rhs._Buckets.get(), Rhs._BucketLength * sizeof(uint32_t));
|
||||
|
||||
this->_Entries.reset(new Entry[Rhs._BucketLength]);
|
||||
std::copy(Rhs._Entries.get(), Rhs._Entries.get() + Rhs._BucketLength, this->_Entries.get());
|
||||
}
|
||||
else
|
||||
{
|
||||
this->_Buckets.reset();
|
||||
this->_Entries.reset();
|
||||
}
|
||||
|
||||
this->_Count = Rhs._Count;
|
||||
this->_FreeList = Rhs._FreeList;
|
||||
this->_FreeCount = Rhs._FreeCount;
|
||||
this->_BucketLength = Rhs._BucketLength;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<class TKey, class TValue, class THasher>
|
||||
inline constexpr bool Dictionary<TKey, TValue, THasher>::Add(TKey Key, TValue Value)
|
||||
{
|
||||
return Insert(Key, Value, true);
|
||||
}
|
||||
|
||||
template<class TKey, class TValue, class THasher>
|
||||
inline constexpr bool Dictionary<TKey, TValue, THasher>::Add(PairType Kvp)
|
||||
{
|
||||
return Insert(Kvp.Key(), Kvp.Value(), true);
|
||||
}
|
||||
|
||||
template<class TKey, class TValue, class THasher>
|
||||
inline constexpr bool Dictionary<TKey, TValue, THasher>::Remove(TKey Key)
|
||||
{
|
||||
if (this->_Buckets == nullptr)
|
||||
return false;
|
||||
|
||||
auto HashCode = THasher::GetHashCode(Key) & INT64_MAX;
|
||||
auto Bucket = HashCode % this->_BucketLength;
|
||||
uint32_t Last = -1;
|
||||
|
||||
for (uint32_t i = this->_Buckets[Bucket]; i != -1; Last = i, i = this->_Entries[i].Next)
|
||||
{
|
||||
if (this->_Entries[i].HashCode == HashCode && THasher::Equals(this->_Entries[i].Kvp.Key(), Key))
|
||||
{
|
||||
if (Last == -1)
|
||||
this->_Buckets[Bucket] = this->_Entries[i].Next;
|
||||
else
|
||||
this->_Entries[Last].Next = this->_Entries[i].Next;
|
||||
|
||||
this->_Entries[i].HashCode = -1;
|
||||
this->_Entries[i].Next = this->_FreeList;
|
||||
this->_Entries[i].Kvp.Key() = {};
|
||||
this->_Entries[i].Kvp.Value() = {};
|
||||
|
||||
this->_FreeList = i;
|
||||
this->_FreeCount++;
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
template<class TKey, class TValue, class THasher>
|
||||
inline constexpr void Dictionary<TKey, TValue, THasher>::Clear()
|
||||
{
|
||||
if (this->_Count > 0)
|
||||
{
|
||||
this->_Buckets.reset();
|
||||
this->_Entries.reset();
|
||||
|
||||
this->_FreeList = -1;
|
||||
this->_Count = 0;
|
||||
this->_FreeCount = 0;
|
||||
}
|
||||
}
|
||||
|
||||
template<class TKey, class TValue, class THasher>
|
||||
inline constexpr bool Dictionary<TKey, TValue, THasher>::ContainsKey(TKey Key)
|
||||
{
|
||||
return (FindEntry(Key) != -1);
|
||||
}
|
||||
|
||||
template<class TKey, class TValue, class THasher>
|
||||
inline constexpr bool Dictionary<TKey, TValue, THasher>::ContainsKey(TKey Key) const
|
||||
{
|
||||
return (FindEntry(Key) != -1);
|
||||
}
|
||||
|
||||
template<class TKey, class TValue, class THasher>
|
||||
inline constexpr bool Dictionary<TKey, TValue, THasher>::ContainsValue(TValue Value)
|
||||
{
|
||||
for (uint32_t i = 0; i < this->_Count; i++)
|
||||
if (this->_Entries[i].HashCode != -1 && this->_Entries[i].Value == Value)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
template<class TKey, class TValue, class THasher>
|
||||
inline constexpr bool Dictionary<TKey, TValue, THasher>::TryGetValue(TKey Key, TValue& Value)
|
||||
{
|
||||
auto Index = FindEntry(Key);
|
||||
|
||||
if (Index != -1)
|
||||
{
|
||||
Value = this->_Entries[Index].Kvp.Value();
|
||||
return true;
|
||||
}
|
||||
|
||||
Value = {};
|
||||
return false;
|
||||
}
|
||||
|
||||
template<class TKey, class TValue, class THasher>
|
||||
inline constexpr TValue& Dictionary<TKey, TValue, THasher>::operator[](TKey& Key)
|
||||
{
|
||||
auto Index = FindEntry(Key);
|
||||
|
||||
if (Index == -1)
|
||||
throw std::exception();
|
||||
|
||||
return this->_Entries[Index].Kvp.Value();
|
||||
}
|
||||
|
||||
template<class TKey, class TValue, class THasher>
|
||||
inline constexpr TValue& Dictionary<TKey, TValue, THasher>::operator[](const TKey& Key)
|
||||
{
|
||||
auto Index = FindEntry(Key);
|
||||
|
||||
if (Index == -1)
|
||||
throw std::exception();
|
||||
|
||||
return this->_Entries[Index].Kvp.Value();
|
||||
}
|
||||
|
||||
template<class TKey, class TValue, class THasher>
|
||||
inline constexpr TValue& Dictionary<TKey, TValue, THasher>::operator[](TKey& Key) const
|
||||
{
|
||||
auto Index = FindEntry(Key);
|
||||
|
||||
if (Index == -1)
|
||||
throw std::exception();
|
||||
|
||||
return this->_Entries[Index].Kvp.Value();
|
||||
}
|
||||
|
||||
template<class TKey, class TValue, class THasher>
|
||||
inline constexpr TValue& Dictionary<TKey, TValue, THasher>::operator[](const TKey& Key) const
|
||||
{
|
||||
auto Index = FindEntry(Key);
|
||||
|
||||
if (Index == -1)
|
||||
throw std::exception();
|
||||
|
||||
return this->_Entries[Index].Kvp.Value();
|
||||
}
|
||||
|
||||
template<class TKey, class TValue, class THasher>
|
||||
inline constexpr uint32_t Dictionary<TKey, TValue, THasher>::Count() const
|
||||
{
|
||||
return (this->_Count - this->_FreeCount);
|
||||
}
|
||||
|
||||
template<class TKey, class TValue, class THasher>
|
||||
inline bool Dictionary<TKey, TValue, THasher>::Insert(TKey& Key, TValue& Value, bool Add)
|
||||
{
|
||||
if (this->_Buckets == nullptr)
|
||||
Initialize(0);
|
||||
|
||||
auto HashCode = THasher::GetHashCode(Key) & INT64_MAX;
|
||||
auto TargetBucket = HashCode % this->_BucketLength;
|
||||
|
||||
for (uint32_t i = this->_Buckets[TargetBucket]; i != -1; i = this->_Entries[i].Next)
|
||||
{
|
||||
if (this->_Entries[i].HashCode == HashCode && THasher::Equals(this->_Entries[i].Kvp.Key(), Key))
|
||||
{
|
||||
if (Add)
|
||||
return false;
|
||||
|
||||
this->_Entries[i].Kvp.Value() = Value;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t Index = 0;
|
||||
|
||||
if (this->_FreeCount > 0)
|
||||
{
|
||||
Index = this->_FreeList;
|
||||
this->_FreeList = this->_Entries[Index].Next;
|
||||
this->_FreeCount--;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (this->_Count == this->_BucketLength)
|
||||
{
|
||||
Resize();
|
||||
TargetBucket = HashCode % this->_BucketLength;
|
||||
}
|
||||
|
||||
Index = this->_Count;
|
||||
this->_Count++;
|
||||
}
|
||||
|
||||
this->_Entries[Index].HashCode = HashCode;
|
||||
this->_Entries[Index].Next = this->_Buckets[TargetBucket];
|
||||
this->_Entries[Index].Kvp.Key() = Key;
|
||||
this->_Entries[Index].Kvp.Value() = Value;
|
||||
|
||||
this->_Buckets[TargetBucket] = Index;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
template<class TKey, class TValue, class THasher>
|
||||
inline void Dictionary<TKey, TValue, THasher>::Initialize(uint32_t Capacity)
|
||||
{
|
||||
auto Size = HashHelpers::GetPrime(Capacity);
|
||||
|
||||
this->_Buckets.reset(new uint32_t[Size]);
|
||||
std::memset(this->_Buckets.get(), 0xFF, sizeof(uint32_t) * Size);
|
||||
|
||||
this->_Entries.reset(new Entry[Size]);
|
||||
this->_FreeList = -1;
|
||||
this->_BucketLength = Size;
|
||||
}
|
||||
|
||||
template<class TKey, class TValue, class THasher>
|
||||
inline void Dictionary<TKey, TValue, THasher>::Resize()
|
||||
{
|
||||
Resize(HashHelpers::ExpandPrime(this->_Count), false);
|
||||
}
|
||||
|
||||
template<class TKey, class TValue, class THasher>
|
||||
inline void Dictionary<TKey, TValue, THasher>::Resize(uint32_t NewSize, bool ForceNewHashCodes)
|
||||
{
|
||||
auto NewBuckets = new uint32_t[NewSize];
|
||||
std::memset(NewBuckets, 0xFF, NewSize * sizeof(uint32_t));
|
||||
|
||||
auto NewEntries = new Entry[NewSize]{};
|
||||
std::copy(this->_Entries.get(), this->_Entries.get() + this->_Count, NewEntries);
|
||||
|
||||
if (ForceNewHashCodes)
|
||||
{
|
||||
for (uint32_t i = 0; i < this->_Count; i++)
|
||||
{
|
||||
if (NewEntries[i].HashCode != -1)
|
||||
NewEntries[i].HashCode = (THasher::GetHashCode(NewEntries[i].Kvp.Key()) & INT64_MAX);
|
||||
}
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < this->_Count; i++)
|
||||
{
|
||||
if (NewEntries[i].HashCode != -1)
|
||||
{
|
||||
auto Bucket = NewEntries[i].HashCode % NewSize;
|
||||
NewEntries[i].Next = NewBuckets[Bucket];
|
||||
NewBuckets[Bucket] = i;
|
||||
}
|
||||
}
|
||||
|
||||
this->_Buckets.reset(NewBuckets);
|
||||
this->_Entries.reset(NewEntries);
|
||||
|
||||
this->_BucketLength = NewSize;
|
||||
}
|
||||
|
||||
template<class TKey, class TValue, class THasher>
|
||||
inline uint32_t Dictionary<TKey, TValue, THasher>::FindEntry(const TKey& Key) const
|
||||
{
|
||||
// Strip const modifiers
|
||||
TKey& KeyUse = *((TKey*)(&Key));
|
||||
|
||||
if (this->_Buckets == nullptr)
|
||||
return -1;
|
||||
|
||||
auto HashCode = THasher::GetHashCode(KeyUse) & INT64_MAX;
|
||||
for (uint32_t i = this->_Buckets[HashCode % this->_BucketLength]; i != -1; i = this->_Entries[i].Next)
|
||||
{
|
||||
if (this->_Entries[i].HashCode == HashCode && THasher::Equals(this->_Entries[i].Kvp.Key(), KeyUse))
|
||||
return i;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
template<class TKey, class TValue, class THasher>
|
||||
inline Dictionary<TKey, TValue, THasher>::DictionaryIterator::DictionaryIterator(const Dictionary<TKey, TValue, THasher>* Dict, uint32_t Index)
|
||||
: Dict(Dict), Kvp(nullptr), Index(Index)
|
||||
{
|
||||
if (Index == -1)
|
||||
MoveNext(); // Assigns first kvp
|
||||
}
|
||||
|
||||
template<class TKey, class TValue, class THasher>
|
||||
inline KeyValuePair<TKey, TValue>& Dictionary<TKey, TValue, THasher>::DictionaryIterator::operator*()
|
||||
{
|
||||
return *Kvp;
|
||||
}
|
||||
|
||||
template<class TKey, class TValue, class THasher>
|
||||
inline const KeyValuePair<TKey, TValue>& Dictionary<TKey, TValue, THasher>::DictionaryIterator::operator*() const
|
||||
{
|
||||
return *Kvp;
|
||||
}
|
||||
|
||||
template<class TKey, class TValue, class THasher>
|
||||
inline KeyValuePair<TKey, TValue>* Dictionary<TKey, TValue, THasher>::DictionaryIterator::operator->()
|
||||
{
|
||||
return Kvp;
|
||||
}
|
||||
|
||||
template<class TKey, class TValue, class THasher>
|
||||
inline bool Dictionary<TKey, TValue, THasher>::DictionaryIterator::operator!=(const DictionaryIterator& Rhs) const
|
||||
{
|
||||
if (this->Index != Rhs.Index)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
template<class TKey, class TValue, class THasher>
|
||||
inline void Dictionary<TKey, TValue, THasher>::DictionaryIterator::MoveNext()
|
||||
{
|
||||
Index++;
|
||||
|
||||
while (Index < this->Dict->_Count)
|
||||
{
|
||||
if (this->Dict->_Entries[Index].HashCode != -1)
|
||||
{
|
||||
Kvp = &this->Dict->_Entries[Index].Kvp;
|
||||
return;
|
||||
}
|
||||
|
||||
Index++;
|
||||
}
|
||||
|
||||
Index = this->Dict->_Count;
|
||||
}
|
299
r5dev/thirdparty/cppnet/cppkore/Directory.cpp
vendored
Normal file
299
r5dev/thirdparty/cppnet/cppkore/Directory.cpp
vendored
Normal file
@ -0,0 +1,299 @@
|
||||
#include "stdafx.h"
|
||||
#include "Directory.h"
|
||||
|
||||
namespace IO
|
||||
{
|
||||
void Directory::CreateDirectory(const string& Path)
|
||||
{
|
||||
if (Path.Length() == 0)
|
||||
return;
|
||||
if (Directory::Exists(Path))
|
||||
return;
|
||||
|
||||
int32_t fLength = Path.Length();
|
||||
int32_t rLength = (fLength > 2 && Path[1] == Path::VolumeSeparatorChar && (Path[2] == Path::DirectorySeparatorChar || Path[2] == Path::AltDirectorySeparatorChar)) ? 3 : 0;
|
||||
|
||||
// We need to trim the trailing slash or the code will try to create 2 directories of the same name
|
||||
if (fLength >= 2 && (Path[fLength - 1] == Path::DirectorySeparatorChar || Path[fLength - 1] == Path::AltDirectorySeparatorChar))
|
||||
fLength--;
|
||||
|
||||
// A list of directories to make
|
||||
auto DirectoryStack = List<string>();
|
||||
|
||||
if (fLength > rLength)
|
||||
{
|
||||
int32_t i = fLength - 1;
|
||||
while (i >= rLength)
|
||||
{
|
||||
DirectoryStack.EmplaceBack(std::move(Path.Substring(0, i + 1)));
|
||||
|
||||
while (i > rLength && Path[i] != Path::DirectorySeparatorChar && Path[1] != Path::AltDirectorySeparatorChar)
|
||||
i--;
|
||||
|
||||
i--;
|
||||
}
|
||||
}
|
||||
|
||||
// Iteration in stack-based order FILO
|
||||
for (int32_t i = DirectoryStack.Count() - 1; i >= 0; --i)
|
||||
CreateDirectoryA((const char*)DirectoryStack[i], NULL);
|
||||
}
|
||||
|
||||
bool Directory::Exists(const string& Path)
|
||||
{
|
||||
if (Path.Length() == 0)
|
||||
return false;
|
||||
|
||||
WIN32_FILE_ATTRIBUTE_DATA Data{};
|
||||
auto Result = GetFileAttributesExA((const char*)Path, GET_FILEEX_INFO_LEVELS::GetFileExInfoStandard, &Data);
|
||||
if (Result)
|
||||
{
|
||||
return (Data.dwFileAttributes != -1) && ((Data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
List<string> Directory::GetFiles(const string& Path)
|
||||
{
|
||||
return Directory::GetFiles(Path, "*");
|
||||
}
|
||||
|
||||
List<string> Directory::GetFiles(const string& Path, const string& SearchPattern)
|
||||
{
|
||||
auto Result = List<string>();
|
||||
|
||||
auto sQuery = (Path[Path.Length() - 1] == Path::DirectorySeparatorChar || Path[Path.Length() - 1] == Path::AltDirectorySeparatorChar) ? Path + SearchPattern : Path + Path::DirectorySeparatorChar + SearchPattern;
|
||||
|
||||
WIN32_FIND_DATAA fInfo;
|
||||
auto ResultHandle = FindFirstFileA((const char*)sQuery, &fInfo);
|
||||
|
||||
if (ResultHandle == INVALID_HANDLE_VALUE)
|
||||
return Result;
|
||||
|
||||
if (_strnicmp(fInfo.cFileName, ".", 1) != 0 && _strnicmp(fInfo.cFileName, "..", 2) != 0)
|
||||
{
|
||||
auto isDir = (0 != (fInfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY));
|
||||
if (!isDir)
|
||||
Result.EmplaceBack(std::move(Path::Combine(Path, fInfo.cFileName)));
|
||||
}
|
||||
|
||||
while (FindNextFileA(ResultHandle, &fInfo))
|
||||
{
|
||||
if (_strnicmp(fInfo.cFileName, ".", 1) != 0 && _strnicmp(fInfo.cFileName, "..", 2) != 0)
|
||||
{
|
||||
auto isDir = (0 != (fInfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY));
|
||||
if (!isDir)
|
||||
Result.EmplaceBack(std::move(Path::Combine(Path, fInfo.cFileName)));
|
||||
}
|
||||
}
|
||||
|
||||
FindClose(ResultHandle);
|
||||
|
||||
return Result;
|
||||
}
|
||||
|
||||
List<string> Directory::GetDirectories(const string& Path)
|
||||
{
|
||||
auto Result = List<string>();
|
||||
|
||||
auto sQuery = (Path[Path.Length() - 1] == Path::DirectorySeparatorChar || Path[Path.Length() - 1] == Path::AltDirectorySeparatorChar) ? Path + "*" : Path + Path::DirectorySeparatorChar + "*";
|
||||
|
||||
WIN32_FIND_DATAA fInfo;
|
||||
auto ResultHandle = FindFirstFileA((const char*)sQuery, &fInfo);
|
||||
|
||||
if (ResultHandle == INVALID_HANDLE_VALUE)
|
||||
return Result;
|
||||
|
||||
if (_strnicmp(fInfo.cFileName, ".", 1) != 0 && _strnicmp(fInfo.cFileName, "..", 2) != 0)
|
||||
{
|
||||
auto isDir = (0 != (fInfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY));
|
||||
if (isDir)
|
||||
Result.EmplaceBack(std::move(Path::Combine(Path, fInfo.cFileName)));
|
||||
}
|
||||
|
||||
while (FindNextFileA(ResultHandle, &fInfo))
|
||||
{
|
||||
if (_strnicmp(fInfo.cFileName, ".", 1) != 0 && _strnicmp(fInfo.cFileName, "..", 2) != 0)
|
||||
{
|
||||
auto isDir = (0 != (fInfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY));
|
||||
if (isDir)
|
||||
Result.EmplaceBack(std::move(Path::Combine(Path, fInfo.cFileName)));
|
||||
}
|
||||
}
|
||||
|
||||
FindClose(ResultHandle);
|
||||
|
||||
return Result;
|
||||
}
|
||||
|
||||
List<string> Directory::GetLogicalDrives()
|
||||
{
|
||||
auto Result = List<string>();
|
||||
|
||||
auto dCount = ::GetLogicalDrives();
|
||||
if (dCount == 0)
|
||||
IOError::StreamAccessDenied();
|
||||
|
||||
uint32_t d = (uint32_t)dCount;
|
||||
char Root[] = { 'A', ':', '\\' };
|
||||
|
||||
while (d != 0)
|
||||
{
|
||||
if ((d & 1) != 0)
|
||||
Result.EmplaceBack(std::move(string(Root, 3)));
|
||||
|
||||
d >>= 1;
|
||||
Root[0]++;
|
||||
}
|
||||
|
||||
return Result;
|
||||
}
|
||||
|
||||
string Directory::GetCurrentDirectory()
|
||||
{
|
||||
char Buffer[MAX_PATH + 1]{};
|
||||
if (!GetCurrentDirectoryA(MAX_PATH, (char*)Buffer))
|
||||
{
|
||||
auto Error = GetLastError();
|
||||
switch (Error)
|
||||
{
|
||||
case ERROR_ACCESS_DENIED:
|
||||
IOError::StreamAccessDenied();
|
||||
break;
|
||||
default:
|
||||
IOError::StreamUnknown();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return Buffer;
|
||||
}
|
||||
|
||||
void Directory::SetCurrentDirectory(const string& Path)
|
||||
{
|
||||
auto Result = SetCurrentDirectoryA((const char*)Path);
|
||||
if (!Result)
|
||||
{
|
||||
auto Error = GetLastError();
|
||||
switch (Error)
|
||||
{
|
||||
case ERROR_ACCESS_DENIED:
|
||||
IOError::StreamAccessDenied();
|
||||
break;
|
||||
case ERROR_FILE_NOT_FOUND:
|
||||
case ERROR_PATH_NOT_FOUND:
|
||||
IOError::StreamFileNotFound();
|
||||
break;
|
||||
default:
|
||||
IOError::StreamUnknown();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Directory::Move(const string& SourcePath, const string& DestinationPath)
|
||||
{
|
||||
// Ensure that the roots are the same
|
||||
if (Path::GetPathRoot(SourcePath).ToLower() != Path::GetPathRoot(DestinationPath).ToLower())
|
||||
IOError::StreamRootMismatch();
|
||||
|
||||
auto Result = MoveFileA((const char*)SourcePath, (const char*)DestinationPath);
|
||||
if (!Result)
|
||||
{
|
||||
auto Error = GetLastError();
|
||||
switch (Error)
|
||||
{
|
||||
case ERROR_ACCESS_DENIED:
|
||||
IOError::StreamAccessDenied();
|
||||
break;
|
||||
case ERROR_FILE_NOT_FOUND:
|
||||
case ERROR_PATH_NOT_FOUND:
|
||||
IOError::StreamFileNotFound();
|
||||
break;
|
||||
default:
|
||||
IOError::StreamUnknown();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Directory::Copy(const string& SourcePath, const string& DestinationPath, bool OverWrite)
|
||||
{
|
||||
auto Result = CopyFileA((const char*)SourcePath, (const char*)DestinationPath, !OverWrite);
|
||||
if (!Result)
|
||||
{
|
||||
auto Error = GetLastError();
|
||||
switch (Error)
|
||||
{
|
||||
case ERROR_ACCESS_DENIED:
|
||||
IOError::StreamAccessDenied();
|
||||
break;
|
||||
case ERROR_FILE_NOT_FOUND:
|
||||
case ERROR_PATH_NOT_FOUND:
|
||||
IOError::StreamFileNotFound();
|
||||
break;
|
||||
case ERROR_FILE_EXISTS:
|
||||
IOError::StreamFileExists();
|
||||
break;
|
||||
default:
|
||||
IOError::StreamUnknown();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool Directory::Delete(const string& Path, bool Recursive)
|
||||
{
|
||||
if (Path.Length() == 0)
|
||||
return false;
|
||||
if (!Directory::Exists(Path))
|
||||
return false;
|
||||
|
||||
if (!Recursive)
|
||||
return (RemoveDirectoryA((const char*)Path) != 0);
|
||||
|
||||
//
|
||||
// We must recursively delete each file and folder in the path, because RemoveDirectory doesn't handle non-empty file paths
|
||||
// If one of the operations fails, the entire delete operation fails
|
||||
//
|
||||
|
||||
auto sQuery = (Path[Path.Length() - 1] == Path::DirectorySeparatorChar || Path[Path.Length() - 1] == Path::AltDirectorySeparatorChar) ? Path + "*" : Path + Path::DirectorySeparatorChar + "*";
|
||||
|
||||
WIN32_FIND_DATAA fInfo;
|
||||
auto ResultHandle = FindFirstFileA((const char*)sQuery, &fInfo);
|
||||
|
||||
if (ResultHandle == INVALID_HANDLE_VALUE)
|
||||
return false;
|
||||
|
||||
do
|
||||
{
|
||||
auto bDir = (0 != (fInfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY));
|
||||
if (bDir)
|
||||
{
|
||||
auto bReparse = (0 != (fInfo.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT));
|
||||
if (!bReparse)
|
||||
{
|
||||
return Directory::Delete(Path::Combine(Path, fInfo.cFileName), true);
|
||||
}
|
||||
else if (bReparse && fInfo.dwReserved0 == IO_REPARSE_TAG_MOUNT_POINT)
|
||||
{
|
||||
if (!DeleteVolumeMountPointA((const char*)Path::Combine(Path, string(fInfo.cFileName) + Path::DirectorySeparatorChar)))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!DeleteFileA((const char*)Path::Combine(Path, fInfo.cFileName)))
|
||||
return false;
|
||||
}
|
||||
} while (FindNextFileA(ResultHandle, &fInfo));
|
||||
|
||||
FindClose(ResultHandle);
|
||||
|
||||
if (RemoveDirectoryA((const char*)Path))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
45
r5dev/thirdparty/cppnet/cppkore/Directory.h
vendored
Normal file
45
r5dev/thirdparty/cppnet/cppkore/Directory.h
vendored
Normal file
@ -0,0 +1,45 @@
|
||||
#pragma once
|
||||
|
||||
#include "Path.h"
|
||||
#include "IOError.h"
|
||||
#include "ListBase.h"
|
||||
#include "StringBase.h"
|
||||
|
||||
//
|
||||
// Remove Win32 macros
|
||||
//
|
||||
|
||||
#undef CreateDirectory
|
||||
#undef GetCurrentDirectory
|
||||
#undef SetCurrentDirectory
|
||||
|
||||
namespace IO
|
||||
{
|
||||
class Directory
|
||||
{
|
||||
public:
|
||||
// Checks whether or not the specified path exists
|
||||
static bool Exists(const string& Path);
|
||||
// Creates a new directory at the given path
|
||||
static void CreateDirectory(const string& Path);
|
||||
// Returns the current directory set
|
||||
static string GetCurrentDirectory();
|
||||
// Sets the current directory
|
||||
static void SetCurrentDirectory(const string& Path);
|
||||
// Moves the source path to the destination path
|
||||
static void Move(const string& SourcePath, const string& DestinationPath);
|
||||
// Copies the source path to the destination path
|
||||
static void Copy(const string& SourcePath, const string& DestinationPath, bool OverWrite = false);
|
||||
// Deletes a directory, optionally recursive if it's not empty
|
||||
static bool Delete(const string& Path, bool Recursive = true);
|
||||
|
||||
// Returns an array of files in the current path
|
||||
static List<string> GetFiles(const string& Path);
|
||||
// Returns an array of files in the current path matching the search pattern
|
||||
static List<string> GetFiles(const string& Path, const string& SearchPattern);
|
||||
// Returns an array of folders in the current path
|
||||
static List<string> GetDirectories(const string& Path);
|
||||
// Returns an array of logical drives
|
||||
static List<string> GetLogicalDrives();
|
||||
};
|
||||
}
|
26
r5dev/thirdparty/cppnet/cppkore/DragDropEffects.h
vendored
Normal file
26
r5dev/thirdparty/cppnet/cppkore/DragDropEffects.h
vendored
Normal file
@ -0,0 +1,26 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <type_traits>
|
||||
|
||||
namespace Forms
|
||||
{
|
||||
// Specifies the effects of a drag-and-drop operation.
|
||||
enum class DragDropEffects
|
||||
{
|
||||
None = 0x0,
|
||||
Copy = 0x1,
|
||||
Move = 0x2,
|
||||
Link = 0x4,
|
||||
Scroll = (int)0x80000000,
|
||||
All = Copy | Move | Scroll
|
||||
};
|
||||
|
||||
//
|
||||
// Allow bitwise operations on this enumeration
|
||||
//
|
||||
constexpr DragDropEffects operator|(DragDropEffects Lhs, DragDropEffects Rhs)
|
||||
{
|
||||
return static_cast<DragDropEffects>(static_cast<std::underlying_type<DragDropEffects>::type>(Lhs) | static_cast<std::underlying_type<DragDropEffects>::type>(Rhs));
|
||||
};
|
||||
}
|
10
r5dev/thirdparty/cppnet/cppkore/DragEventArgs.cpp
vendored
Normal file
10
r5dev/thirdparty/cppnet/cppkore/DragEventArgs.cpp
vendored
Normal file
@ -0,0 +1,10 @@
|
||||
#include "stdafx.h"
|
||||
#include "DragEventArgs.h"
|
||||
|
||||
namespace Forms
|
||||
{
|
||||
DragEventArgs::DragEventArgs(IDataObject* Data, const int32_t KeyState, const int32_t X, const int32_t Y, const DragDropEffects AllowedEffect, DragDropEffects Effect)
|
||||
: Data(Data), KeyState(KeyState), X(X), Y(Y), AllowedEffect(AllowedEffect), Effect(Effect)
|
||||
{
|
||||
}
|
||||
}
|
31
r5dev/thirdparty/cppnet/cppkore/DragEventArgs.h
vendored
Normal file
31
r5dev/thirdparty/cppnet/cppkore/DragEventArgs.h
vendored
Normal file
@ -0,0 +1,31 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include "DragDropEffects.h"
|
||||
|
||||
namespace Forms
|
||||
{
|
||||
// Provides data for the DragDrop events.
|
||||
class DragEventArgs
|
||||
{
|
||||
public:
|
||||
DragEventArgs(IDataObject* Data, const int32_t KeyState, const int32_t X, const int32_t Y, const DragDropEffects AllowedEffect, DragDropEffects Effect);;
|
||||
~DragEventArgs() = default;
|
||||
|
||||
// The data associated with this event.
|
||||
IDataObject* Data;
|
||||
// The current statie of the shift, ctrl, and alt keys.
|
||||
const int32_t KeyState;
|
||||
|
||||
// The mouse X location.
|
||||
const int32_t X;
|
||||
// The mouse Y location.
|
||||
const int32_t Y;
|
||||
|
||||
// The effect that should be applied to the mouse cursor.
|
||||
const DragDropEffects AllowedEffect;
|
||||
|
||||
// Gets or sets which drag-and-drop operations are allowed by the target of the drag event.
|
||||
DragDropEffects Effect;
|
||||
};
|
||||
}
|
10
r5dev/thirdparty/cppnet/cppkore/DrawListViewColumnHeaderEventArgs.cpp
vendored
Normal file
10
r5dev/thirdparty/cppnet/cppkore/DrawListViewColumnHeaderEventArgs.cpp
vendored
Normal file
@ -0,0 +1,10 @@
|
||||
#include "stdafx.h"
|
||||
#include "DrawListViewColumnHeaderEventArgs.h"
|
||||
|
||||
namespace Forms
|
||||
{
|
||||
DrawListViewColumnHeaderEventArgs::DrawListViewColumnHeaderEventArgs(HDC Dc, const ColumnHeader* Header, int32_t ColumnIndex, Drawing::Rectangle Bounds, ListViewItemStates State)
|
||||
: Header(Header), ColumnIndex(ColumnIndex), Bounds(Bounds), State(State), DrawDefault(false), Graphics(std::make_unique<Drawing::Graphics>(Dc))
|
||||
{
|
||||
}
|
||||
}
|
33
r5dev/thirdparty/cppnet/cppkore/DrawListViewColumnHeaderEventArgs.h
vendored
Normal file
33
r5dev/thirdparty/cppnet/cppkore/DrawListViewColumnHeaderEventArgs.h
vendored
Normal file
@ -0,0 +1,33 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <memory>
|
||||
#include "DrawingBase.h"
|
||||
#include "ColumnHeader.h"
|
||||
#include "ListViewItemStates.h"
|
||||
|
||||
namespace Forms
|
||||
{
|
||||
// This class contains the information a user needs to paint ListView headers.
|
||||
class DrawListViewColumnHeaderEventArgs
|
||||
{
|
||||
public:
|
||||
DrawListViewColumnHeaderEventArgs(HDC Dc, const ColumnHeader* Header, int32_t ColumnIndex, Drawing::Rectangle Bounds, ListViewItemStates State);
|
||||
~DrawListViewColumnHeaderEventArgs() = default;
|
||||
|
||||
// The header object.
|
||||
const ColumnHeader* Header;
|
||||
// Gets the state of the header to draw.
|
||||
const ListViewItemStates State;
|
||||
// Gets the bounds of the header to draw.
|
||||
const Drawing::Rectangle Bounds;
|
||||
// The index of the header to draw.
|
||||
const int32_t ColumnIndex;
|
||||
|
||||
// Whether or not the system draws the header.
|
||||
bool DrawDefault;
|
||||
|
||||
// The graphics instance used to paint this header.
|
||||
std::unique_ptr<Drawing::Graphics> Graphics;
|
||||
};
|
||||
}
|
10
r5dev/thirdparty/cppnet/cppkore/DrawListViewItemEventArgs.cpp
vendored
Normal file
10
r5dev/thirdparty/cppnet/cppkore/DrawListViewItemEventArgs.cpp
vendored
Normal file
@ -0,0 +1,10 @@
|
||||
#include "stdafx.h"
|
||||
#include "DrawListViewItemEventArgs.h"
|
||||
|
||||
namespace Forms
|
||||
{
|
||||
DrawListViewItemEventArgs::DrawListViewItemEventArgs(HDC Dc, const string& Text, const ListViewItemStyle Style, Drawing::Rectangle Bounds, int32_t ItemIndex, ListViewItemStates State)
|
||||
: Text(Text), Style(Style), Bounds(Bounds), ItemIndex(ItemIndex), DrawDefault(false), Graphics(std::make_unique<Drawing::Graphics>(Dc)), State(State)
|
||||
{
|
||||
}
|
||||
}
|
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