diff --git a/.gitattributes b/.gitattributes
new file mode 100644
index 0000000..1ff0c42
--- /dev/null
+++ b/.gitattributes
@@ -0,0 +1,63 @@
+###############################################################################
+# Set default behavior to automatically normalize line endings.
+###############################################################################
+* text=auto
+
+###############################################################################
+# Set default behavior for command prompt diff.
+#
+# This is need for earlier builds of msysgit that does not have it on by
+# default for csharp files.
+# Note: This is only used by command line
+###############################################################################
+#*.cs diff=csharp
+
+###############################################################################
+# Set the merge driver for project and solution files
+#
+# Merging from the command prompt will add diff markers to the files if there
+# are conflicts (Merging from VS is not affected by the settings below, in VS
+# the diff markers are never inserted). Diff markers may cause the following
+# file extensions to fail to load in VS. An alternative would be to treat
+# these files as binary and thus will always conflict and require user
+# intervention with every merge. To do so, just uncomment the entries below
+###############################################################################
+#*.sln merge=binary
+#*.csproj merge=binary
+#*.vbproj merge=binary
+#*.vcxproj merge=binary
+#*.vcproj merge=binary
+#*.dbproj merge=binary
+#*.fsproj merge=binary
+#*.lsproj merge=binary
+#*.wixproj merge=binary
+#*.modelproj merge=binary
+#*.sqlproj merge=binary
+#*.wwaproj merge=binary
+
+###############################################################################
+# behavior for image files
+#
+# image files are treated as binary by default.
+###############################################################################
+#*.jpg binary
+#*.png binary
+#*.gif binary
+
+###############################################################################
+# diff behavior for common document formats
+#
+# Convert binary document formats to text before diffing them. This feature
+# is only available from the command line. Turn it on by uncommenting the
+# entries below.
+###############################################################################
+#*.doc diff=astextplain
+#*.DOC diff=astextplain
+#*.docx diff=astextplain
+#*.DOCX diff=astextplain
+#*.dot diff=astextplain
+#*.DOT diff=astextplain
+#*.pdf diff=astextplain
+#*.PDF diff=astextplain
+#*.rtf diff=astextplain
+#*.RTF diff=astextplain
diff --git a/COPYING b/COPYING
new file mode 100644
index 0000000..e72bfdd
--- /dev/null
+++ b/COPYING
@@ -0,0 +1,674 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc.
+ 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.
+
+
+ Copyright (C)
+
+ 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 .
+
+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:
+
+ Copyright (C)
+ 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
+.
+
+ 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
+.
\ No newline at end of file
diff --git a/COPYING.LESSER b/COPYING.LESSER
new file mode 100644
index 0000000..153d416
--- /dev/null
+++ b/COPYING.LESSER
@@ -0,0 +1,165 @@
+ GNU LESSER GENERAL PUBLIC LICENSE
+ Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc.
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+
+ This version of the GNU Lesser General Public License incorporates
+the terms and conditions of version 3 of the GNU General Public
+License, supplemented by the additional permissions listed below.
+
+ 0. Additional Definitions.
+
+ As used herein, "this License" refers to version 3 of the GNU Lesser
+General Public License, and the "GNU GPL" refers to version 3 of the GNU
+General Public License.
+
+ "The Library" refers to a covered work governed by this License,
+other than an Application or a Combined Work as defined below.
+
+ An "Application" is any work that makes use of an interface provided
+by the Library, but which is not otherwise based on the Library.
+Defining a subclass of a class defined by the Library is deemed a mode
+of using an interface provided by the Library.
+
+ A "Combined Work" is a work produced by combining or linking an
+Application with the Library. The particular version of the Library
+with which the Combined Work was made is also called the "Linked
+Version".
+
+ The "Minimal Corresponding Source" for a Combined Work means the
+Corresponding Source for the Combined Work, excluding any source code
+for portions of the Combined Work that, considered in isolation, are
+based on the Application, and not on the Linked Version.
+
+ The "Corresponding Application Code" for a Combined Work means the
+object code and/or source code for the Application, including any data
+and utility programs needed for reproducing the Combined Work from the
+Application, but excluding the System Libraries of the Combined Work.
+
+ 1. Exception to Section 3 of the GNU GPL.
+
+ You may convey a covered work under sections 3 and 4 of this License
+without being bound by section 3 of the GNU GPL.
+
+ 2. Conveying Modified Versions.
+
+ If you modify a copy of the Library, and, in your modifications, a
+facility refers to a function or data to be supplied by an Application
+that uses the facility (other than as an argument passed when the
+facility is invoked), then you may convey a copy of the modified
+version:
+
+ a) under this License, provided that you make a good faith effort to
+ ensure that, in the event an Application does not supply the
+ function or data, the facility still operates, and performs
+ whatever part of its purpose remains meaningful, or
+
+ b) under the GNU GPL, with none of the additional permissions of
+ this License applicable to that copy.
+
+ 3. Object Code Incorporating Material from Library Header Files.
+
+ The object code form of an Application may incorporate material from
+a header file that is part of the Library. You may convey such object
+code under terms of your choice, provided that, if the incorporated
+material is not limited to numerical parameters, data structure
+layouts and accessors, or small macros, inline functions and templates
+(ten or fewer lines in length), you do both of the following:
+
+ a) Give prominent notice with each copy of the object code that the
+ Library is used in it and that the Library and its use are
+ covered by this License.
+
+ b) Accompany the object code with a copy of the GNU GPL and this license
+ document.
+
+ 4. Combined Works.
+
+ You may convey a Combined Work under terms of your choice that,
+taken together, effectively do not restrict modification of the
+portions of the Library contained in the Combined Work and reverse
+engineering for debugging such modifications, if you also do each of
+the following:
+
+ a) Give prominent notice with each copy of the Combined Work that
+ the Library is used in it and that the Library and its use are
+ covered by this License.
+
+ b) Accompany the Combined Work with a copy of the GNU GPL and this license
+ document.
+
+ c) For a Combined Work that displays copyright notices during
+ execution, include the copyright notice for the Library among
+ these notices, as well as a reference directing the user to the
+ copies of the GNU GPL and this license document.
+
+ d) Do one of the following:
+
+ 0) Convey the Minimal Corresponding Source under the terms of this
+ License, and the Corresponding Application Code in a form
+ suitable for, and under terms that permit, the user to
+ recombine or relink the Application with a modified version of
+ the Linked Version to produce a modified Combined Work, in the
+ manner specified by section 6 of the GNU GPL for conveying
+ Corresponding Source.
+
+ 1) Use a suitable shared library mechanism for linking with the
+ Library. A suitable mechanism is one that (a) uses at run time
+ a copy of the Library already present on the user's computer
+ system, and (b) will operate properly with a modified version
+ of the Library that is interface-compatible with the Linked
+ Version.
+
+ e) Provide Installation Information, but only if you would otherwise
+ be required to provide such information under section 6 of the
+ GNU GPL, and only to the extent that such information is
+ necessary to install and execute a modified version of the
+ Combined Work produced by recombining or relinking the
+ Application with a modified version of the Linked Version. (If
+ you use option 4d0, the Installation Information must accompany
+ the Minimal Corresponding Source and Corresponding Application
+ Code. If you use option 4d1, you must provide the Installation
+ Information in the manner specified by section 6 of the GNU GPL
+ for conveying Corresponding Source.)
+
+ 5. Combined Libraries.
+
+ You may place library facilities that are a work based on the
+Library side by side in a single library together with other library
+facilities that are not Applications and are not covered by this
+License, and convey such a combined library under terms of your
+choice, if you do both of the following:
+
+ a) Accompany the combined library with a copy of the same work based
+ on the Library, uncombined with any other library facilities,
+ conveyed under the terms of this License.
+
+ b) Give prominent notice with the combined library that part of it
+ is a work based on the Library, and explaining where to find the
+ accompanying uncombined form of the same work.
+
+ 6. Revised Versions of the GNU Lesser General Public License.
+
+ The Free Software Foundation may publish revised and/or new versions
+of the GNU Lesser 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
+Library as you received it specifies that a certain numbered version
+of the GNU Lesser General Public License "or any later version"
+applies to it, you have the option of following the terms and
+conditions either of that published version or of any later version
+published by the Free Software Foundation. If the Library as you
+received it does not specify a version number of the GNU Lesser
+General Public License, you may choose any version of the GNU Lesser
+General Public License ever published by the Free Software Foundation.
+
+ If the Library as you received it specifies that a proxy can decide
+whether future versions of the GNU Lesser General Public License shall
+apply, that proxy's public statement of acceptance of any version is
+permanent authorization for you to choose that version for the
+Library.
\ No newline at end of file
diff --git a/DmResEditor/DmResEditor.cpp b/DmResEditor/DmResEditor.cpp
new file mode 100644
index 0000000..91c1a1b
--- /dev/null
+++ b/DmResEditor/DmResEditor.cpp
@@ -0,0 +1,889 @@
+// DmResEditor.cpp : 定义应用程序的入口点。
+//
+// 8-12-2020 Create
+
+#include "framework.h"
+#include "DmResEditor.h"
+#include
+
+HINSTANCE m_hInstance;
+HWND g_hWnd;
+std::wstring m_title = L"梦月资源编辑器v1.1";
+
+bool g_istip = false;
+
+using namespace Ctrl;
+
+#if MUI_CFG_ENABLE_V1DMRES
+
+DMResources dmRes;
+
+XML::MuiXML* m_xmlui = nullptr;
+
+extern void blockcallback(_m_size size, _m_size allsize, _m_param param);
+
+static HRESULT WINAPI GetDpiForMonitor(
+ _In_ HMONITOR hmonitor,
+ _In_ MONITOR_DPI_TYPE dpiType,
+ _Out_ UINT* dpiX,
+ _Out_ UINT* dpiY)
+{
+ HINSTANCE hInstWinSta = LoadLibraryW(L"SHCore.dll");
+ if (hInstWinSta == nullptr) return E_NOINTERFACE;
+
+ typedef HRESULT(WINAPI* PFN_GDFM)(
+ HMONITOR, MONITOR_DPI_TYPE, UINT*, UINT*);
+
+ PFN_GDFM pGetDpiForMonitor =
+ (PFN_GDFM)GetProcAddress(hInstWinSta, "GetDpiForMonitor");
+ if (pGetDpiForMonitor == nullptr) return E_NOINTERFACE;
+
+ return pGetDpiForMonitor(hmonitor, dpiType, dpiX, dpiY);
+}
+
+int APIENTRY wWinMain(_In_ HINSTANCE hInstance,
+ _In_opt_ HINSTANCE hPrevInstance,
+ _In_ LPWSTR lpCmdLine,
+ _In_ int nCmdShow)
+{
+ CtrlMgr::RegisterMuiControl();
+
+ SetProcessDpiAwarenessContext(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2);
+
+ //ShowDebugRect = true;
+ m_hInstance = hInstance;
+ std::wstring error;
+
+ Render::MRender* render = new Render::MRender_GDIP();
+
+ UINT_PTR gdiplusToken = 0;
+ Gdiplus::GdiplusStartupInput gdiplusStartupInput;
+ Gdiplus::GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
+
+ auto window = new MainWindow(render);
+ if (window->Create(0, m_title, UIRect(CW_USEDEFAULT, CW_USEDEFAULT, 624, 652),
+ std::bind(&MainWindow::AfterCreated, window), (_m_param)(WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX), 0))
+ {
+ window->SetMainWindow(true);
+
+ //DPI缩放
+ UINT dpiX = 0;
+ UINT dpiY = 0;
+ HRESULT hr = GetDpiForMonitor(
+ MonitorFromWindow((HWND)window->GetWindowHandle(), MONITOR_DEFAULTTONEAREST),
+ MDT_EFFECTIVE_DPI, (UINT*)&dpiX, (UINT*)&dpiY);
+ if (FAILED(hr)) {
+ HDC hdc = GetDC(NULL);
+ dpiX = GetDeviceCaps(hdc, LOGPIXELSX);
+ ReleaseDC(NULL, hdc);
+ }
+ float scale = (float)dpiX / 96.f;
+ window->ScaleWindow(int(624 * scale), int(652 * scale));
+
+ window->SetCacheMode(true);
+ window->CenterWindow();
+ //window.ShowDebugRect(true);
+ window->ShowWindow(true);
+
+ Settings::UIMessageLoop();
+ }
+
+ Gdiplus::GdiplusShutdown(gdiplusToken);
+ return 0;
+}
+
+_m_result MainWindow::EventSource(MEventCodeEnum code, _m_param param)
+{
+ //响应DPI更改
+ auto message = ConvertEventCode(code);
+ if (message == WM_DPICHANGED)
+ {
+ thread_local bool flag = false;
+ if (flag)
+ return 0;
+ flag = true;
+ auto pm = (std::pair<_m_param, _m_param>*)param;
+ UINT dpiX = Helper::M_LOWORD((_m_long)pm->first);
+ float scale = (float)dpiX / 96.f;
+ ScaleWindow(int(624.f * scale), int(652.f * scale));
+ flag = false;
+ return 0;
+ }
+ else if(message == WM_DESTROY)
+ {
+ delete this;
+ return 0;
+ }
+ return UIWindowBasic::EventSource(code, param);
+}
+
+bool MainWindow::AfterCreated()
+{
+ g_hWnd = (HWND)GetWindowHandle();
+ HICON hIcon = LoadIconW(m_hInstance, MAKEINTRESOURCEW(IDI_DMRESEDITOR));
+ SendMessageW(g_hWnd, WM_SETICON, ICON_SMALL, (LPARAM)hIcon);
+ CreateControls();
+ return true;
+}
+
+bool MainWindow::EventProc(UINotifyEvent event, UIControl* control, _m_param param)
+{
+ if (MUIEVENT(Event_Mouse_LClick, L"browse"))
+ {
+ std::vector file;
+ if (FS::UI::MBrowseForFile(false, false,
+ {
+ { L"梦月资源文件 (*.dmres;*.dmspt)", L"*.dmres;*.dmspt" },
+ { L"所有文件 All Files (*.*)", L"*.*" }
+ }, (_m_param)g_hWnd, file))
+ {
+ static_cast(GetRootControl()->Child(L"path"))->SetCurText(file[0]);
+ }
+ }
+ //新建资源
+ else if (MUIEVENT(Event_Mouse_LClick, L"newdmres"))
+ {
+ std::wstring path = static_cast(GetRootControl()->Child(L"path"))->GetCurText();
+ if (path != L"")
+ {
+ static_cast(GetRootControl()->Child(L"resclsname"))->SetCurText(L"DMResourceClass");
+ control->SetEnabled(false);
+
+ std::wstring resname = L"Resource1";
+ std::wstring reskey = L"12345678";
+
+ dmRes.CreateResource(L"DMResourceClass");
+ dmRes.AddResource({ UIResource(), false, 0, L"" }, resname, reskey);
+
+ UIListBox* listbox = (UIListBox*)GetRootControl()->Child(L"reslist");
+ ListItem* item = new ListItem();
+ item->SetText(resname);
+ listbox->AddItem(item, -1);
+ listbox->SetEnabled(true, false);
+ listbox->SetCurSelItem(0);
+
+ static_cast(GetRootControl()->Child(L"resname"))->SetCurText(resname);
+ static_cast(GetRootControl()->Child(L"reskey"))->SetCurText(reskey);
+
+ GetRootControl()->Child(L"importres")->SetEnabled(true, false);
+ GetRootControl()->Child(L"importstr")->SetEnabled(true, false);
+ GetRootControl()->Child(L"addres")->SetEnabled(true);
+ GetRootControl()->Child(L"delres")->SetEnabled(true);
+ GetRootControl()->Child(L"savefile")->SetEnabled(true);
+ GetRootControl()->Child(L"exitedit")->SetEnabled(true);
+ GetRootControl()->Child(L"loaddmres")->SetEnabled(false);
+ auto block = (UICheckBox*)GetRootControl()->Child(L"isblock");
+ block->SetSel(false);
+ block->SetEnabled(true);
+ auto blocksize = (UIEditBox*)GetRootControl()->Child(L"blocksize");
+ blocksize->SetCurText(L"1024");
+ blocksize->SetEnabled(true);
+ GetRootControl()->Child(L"upresname")->SetEnabled(false);
+
+ GetRootControl()->Child(L"group")->SetEnabled(true);
+ }
+ else
+ MessageBoxW(g_hWnd, L"文件路径不能为空!", L"失败", MB_ICONERROR);
+ }
+ //类名更改
+ else if (MUIEVENT(Event_Edit_TextChanged, L"resclsname"))
+ {
+ GetRootControl()->Child(L"upclsname")->SetEnabled(true);
+ }
+ //更新类名
+ else if (MUIEVENT(Event_Mouse_LClick, L"upclsname"))
+ {
+ UIEditBox* edit = (UIEditBox*)GetRootControl()->Child(L"resclsname");
+ if (edit->GetCurText() == L"")
+ {
+ MessageBoxW(g_hWnd, L"更新名称失败!名称不能为空", L"更改类名", MB_ICONERROR);
+ return false;
+ }
+ control->SetEnabled(false);
+ dmRes.RenameClassName(edit->GetCurText().c_str());
+ MessageBoxW(g_hWnd, (L"类名已更改为:" + edit->GetCurText()).c_str(), L"更改类名", MB_ICONINFORMATION);
+ }
+ //资源名更改
+ else if (MUIEVENT(Event_Edit_TextChanged, L"resname"))
+ {
+ GetRootControl()->Child(L"upresname")->SetEnabled(true);
+ }
+ //更新资源名
+ else if (MUIEVENT(Event_Mouse_LClick, L"upresname"))
+ {
+ UIEditBox* edit = (UIEditBox*)GetRootControl()->Child(L"resname");
+ UIListBox* listbox = (UIListBox*)GetRootControl()->Child(L"reslist");
+ if (edit->GetCurText() == L"")
+ {
+ MessageBoxW(g_hWnd, L"更新名称失败!名称不能为空", L"更改资源名", MB_ICONERROR);
+ return true;
+ }
+
+ if (dmRes.RenameResource(listbox->GetItem(listbox->GetCurSelItem())->GetText().data(), edit->GetCurText().c_str())) {
+ listbox->GetItem(listbox->GetCurSelItem())->SetText(edit->GetCurText());
+ control->SetEnabled(false);
+ MessageBoxW(g_hWnd, (L"资源名已更改为:" + edit->GetCurText()).c_str(), L"更改资源名", MB_ICONINFORMATION);
+ }
+ else
+ MessageBoxW(g_hWnd, L"类名更新失败..", L"更改资源名", MB_ICONERROR);
+ }
+ //分块选项
+ else if (MUIEVENT(Event_Mouse_LClick, L"isblock"))
+ {
+ GetRootControl()->Child(L"blocksize")->SetEnabled(static_cast(control)->GetSel());
+ }
+ else if (MUIEVENT(Event_Focus_False, L"blocksize"))
+ {
+ UIEditBox* edit = (UIEditBox*)control;
+ if (edit->GetCurText() == L"")
+ edit->SetCurText(L"1024");
+ }
+ //资源文本更改
+ else if (MUIEVENT(Event_Edit_TextChanged, L"strpreview"))
+ {
+ UIEditBox* edit = (UIEditBox*)control;
+ if (edit->GetCurTextLength(0) == 0)
+ {
+ GetRootControl()->Child(L"exportstr")->SetEnabled(false);
+ GetRootControl()->Child(L"cleanstr")->SetEnabled(false);
+ }
+ else
+ {
+ GetRootControl()->Child(L"exportstr")->SetEnabled(true);
+ GetRootControl()->Child(L"importstr")->SetEnabled(true);
+ GetRootControl()->Child(L"cleanstr")->SetEnabled(true);
+ GetRootControl()->Child(L"savestr")->SetEnabled(true);
+ }
+ ShowStrLength(edit->GetCurTextLength(0));
+ }
+ //写入数据
+ else if (MUIEVENT(Event_Mouse_LClick, L"importres"))
+ {
+ WriteRes(control);
+ }
+ //清空数据
+ else if (MUIEVENT(Event_Mouse_LClick, L"cleanres"))
+ {
+ if (MessageBoxW(g_hWnd, L"确定要清空资源数据吗?", L"清空数据", MB_ICONQUESTION | MB_YESNO) == IDYES)
+ {
+ UIListBox* listbox = (UIListBox*)GetRootControl()->Child(L"reslist");
+ UIEditBox* reskey = static_cast(GetRootControl()->Child(L"reskey"));
+ std::wstring resname = listbox->GetItem(listbox->GetCurSelItem())->GetText().data();
+
+ DMResKey key = dmRes.ReadResource(resname, reskey->GetCurText());
+ if (key.res.data)
+ key.res.Release();
+ if (dmRes.ChangeResource(resname, key, reskey->GetCurText()))
+ {
+ GetRootControl()->Child(L"exportres")->SetEnabled(false);
+ GetRootControl()->Child(L"importres")->SetEnabled(true);
+ GetRootControl()->Child(L"isblock")->SetEnabled(true);
+ GetRootControl()->Child(L"blocksize")->SetEnabled(true);
+ control->SetEnabled(false);
+
+ ShowResSize(0);
+
+ MessageBoxW(g_hWnd, L"清空资源数据成功!", L"清空数据", MB_ICONINFORMATION);
+ }
+ }
+ }
+ //写出数据
+ else if (MUIEVENT(Event_Mouse_LClick, L"exportres"))
+ {
+ SaveRes(control);
+ }
+ //写出文本
+ else if (MUIEVENT(Event_Mouse_LClick, L"exportstr"))
+ {
+ std::wstring str = static_cast(GetRootControl()->Child(L"strpreview"))->GetCurText();
+ str = Helper::M_ReplaceString(str, L"\r", L"\r\n");
+ std::vector selfile;
+ if(FS::UI::MBrowseForFile(false, false, {{L"文本文档 (*.txt)", L"*.txt"}}, (_m_param)g_hWnd, selfile))
+ {
+ FILE* file = 0;
+ _wfopen_s(&file, selfile[0].data(), L"wb");
+ if (!file) return true;
+
+ //Unicode文件头
+ fwrite("\xFF\xFE", 1, 2, file);
+ fwrite(str.c_str(), 1, str.length() * sizeof(wchar_t), file);
+ fclose(file);
+ }
+ }
+ //写入文本
+ else if (MUIEVENT(Event_Mouse_LClick, L"importstr"))
+ {
+ std::vector selfile;
+ if (FS::UI::MBrowseForFile(true, false, { {L"UTF16 LE 文本文档 (*.txt)", L"*.txt"} }, (_m_param)g_hWnd, selfile))
+ {
+ FILE* file = 0;
+ _wfopen_s(&file, selfile[0].data(), L"rb");
+ if (!file) return true;
+
+ bool end = false;
+
+ fseek(file, 0L, SEEK_END);
+ _m_long len = ftell(file);
+ _m_long read = 0;
+ //跳过Unicode文件头
+ fseek(file, 2, SEEK_SET);
+ std::wstring str;
+ while (!end)
+ {
+ wchar_t wch;
+ _m_long len_read = fread(&wch, 1, sizeof(wchar_t), file);
+ if (len_read)
+ {
+ read += len_read;
+ str += wch;
+ }
+ if (read + 2 >= len)
+ break;
+ }
+ static_cast(GetRootControl()->Child(L"strpreview"))->SetCurText(str);
+ ShowStrLength(str.length());
+ fclose(file);
+ if (str.length() != 0) {
+ GetRootControl()->Child(L"exportstr")->SetEnabled(true);
+ GetRootControl()->Child(L"cleanstr")->SetEnabled(true);
+ }
+ GetRootControl()->Child(L"savestr")->SetEnabled(true);
+ }
+ }
+ //保存文本数据
+ else if (MUIEVENT(Event_Mouse_LClick, L"savestr"))
+ {
+ UIListBox* listbox = (UIListBox*)GetRootControl()->Child(L"reslist");
+ UIEditBox* reskey = static_cast(GetRootControl()->Child(L"reskey"));
+ UIEditBox* resstrEdit = static_cast(GetRootControl()->Child(L"strpreview"));
+ std::wstring resname = listbox->GetItem(listbox->GetCurSelItem())->GetText().data();
+
+ DMResKey key = dmRes.ReadResource(resname.c_str(), reskey->GetCurText().c_str(), StringRes);
+ key.resText = resstrEdit->GetCurText();
+
+ if (dmRes.ChangeResource(resname.c_str(), key, reskey->GetCurText().c_str(), StringRes))
+ {
+ control->SetEnabled(false);
+ MessageBoxW(g_hWnd, L"更新字符串资源成功!", L"保存文本", MB_ICONINFORMATION);
+ }
+ else
+ MessageBoxW(g_hWnd, L"更新字符串资源失败...", L"保存文本", MB_ICONERROR);
+ }
+ //清空文本数据
+ else if (MUIEVENT(Event_Mouse_LClick, L"cleanstr"))
+ {
+ control->SetEnabled(false);
+ GetRootControl()->Child(L"exportstr")->SetEnabled(false);
+ static_cast(GetRootControl()->Child(L"strpreview"))->SetCurText(L"");
+ ShowStrLength(0);
+ GetRootControl()->Child(L"savestr")->SetEnabled(true);
+ }
+ //添加资源
+ else if (MUIEVENT(Event_Mouse_LClick, L"addres"))
+ {
+ UIListBox* listbox = (UIListBox*)GetRootControl()->Child(L"reslist");
+
+ std::wstring newResname = L"Resource" + std::to_wstring(listbox->GetItemListCount() + 1);
+
+ ListItem* item = new ListItem();
+ item->SetText(newResname);
+ listbox->AddItem(item, -1);
+ listbox->SetCurSelItem(listbox->GetItemListCount() - 1);
+ curSelItem = listbox->GetItemListCount() - 1;
+
+ static_cast(GetRootControl()->Child(L"resname"))->SetCurText(newResname);
+
+ GetRootControl()->Child(L"upresname")->SetEnabled(false);
+
+ GetRootControl()->Child(L"importres")->SetEnabled(true);
+ GetRootControl()->Child(L"importstr")->SetEnabled(true);
+ GetRootControl()->Child(L"exportres")->SetEnabled(false);
+ GetRootControl()->Child(L"exportstr")->SetEnabled(false);
+
+ auto block = (UICheckBox*)GetRootControl()->Child(L"isblock");
+ block->SetSel(false, false);
+ block->SetEnabled(true);
+
+ auto blocksize = (UIEditBox*)GetRootControl()->Child(L"blocksize");
+ blocksize->SetCurText(L"1024");
+ blocksize->SetEnabled(true);
+
+ GetRootControl()->Child(L"decoderes")->SetEnabled(false);
+ GetRootControl()->Child(L"cleanres")->SetEnabled(false);
+ GetRootControl()->Child(L"cleanstr")->SetEnabled(false);
+ GetRootControl()->Child(L"savestr")->SetEnabled(false);
+ GetRootControl()->Child(L"strpreview")->SetEnabled(true);
+
+ GetRootControl()->Child(L"delres")->SetEnabled(true);
+ GetRootControl()->Child(L"savefile")->SetEnabled(true);
+
+ static_cast(GetRootControl()->Child(L"strpreview"))->SetCurText(L"");
+ ShowResSize(0);
+ ShowStrLength(0);
+ GetRootControl()->Child(L"group")->SetEnabled(true);
+
+ UIEditBox* reskey = static_cast(GetRootControl()->Child(L"reskey"));
+ dmRes.AddResource({ UIResource(), false, 0, L"" }, newResname, reskey->GetCurText());
+ }
+ //资源列表项目选中更改
+ else if (MUIEVENT(Event_ListBox_ItemChanged, L"reslist"))
+ {
+ curSelItem = (int)param;
+ OnSelChange(control);
+ }
+ //解码资源
+ else if (MUIEVENT(Event_Mouse_LClick, L"decoderes"))
+ {
+ UIEditBox* preview = static_cast(GetRootControl()->Child(L"strpreview"));
+ UIListBox* listbox = (UIListBox*)GetRootControl()->Child(L"reslist");
+ std::wstring resName = listbox->GetItem(listbox->GetCurSelItem())->GetText().data();
+ UIEditBox* reskey = static_cast(GetRootControl()->Child(L"reskey"));
+
+ DMResKey key = dmRes.ReadResource(resName, reskey->GetCurText(), StringRes);
+
+ preview->SetCurText(key.resText);
+ preview->SetEnabled(true);
+ GetRootControl()->Child(L"importstr")->SetEnabled(true);
+ if (key.resText.length() != 0) {
+ GetRootControl()->Child(L"cleanstr")->SetEnabled(true);
+ GetRootControl()->Child(L"exportstr")->SetEnabled(true);
+ }
+ if (dmRes.ReadResourceSize(resName, DataRes) != 0)
+ {
+ GetRootControl()->Child(L"importres")->SetEnabled(false);
+ GetRootControl()->Child(L"cleanres")->SetEnabled(true);
+ GetRootControl()->Child(L"exportres")->SetEnabled(true);
+ }
+ else {
+ GetRootControl()->Child(L"importres")->SetEnabled(true);
+ GetRootControl()->Child(L"isblock")->SetEnabled(true);
+ GetRootControl()->Child(L"blocksize")->SetEnabled(true);
+ }
+ control->SetEnabled(false);
+
+ if (!g_istip) {
+ g_istip = true;
+ MessageBoxW(g_hWnd, L"资源读取完毕\n提示:\n 如果秘钥与写入资源时的秘钥不符 依然能读取数据 但数据并非正确数据! 请自行效验结果.", L"读取数据", MB_ICONINFORMATION);
+ }
+ }
+ //删除资源
+ else if (MUIEVENT(Event_Mouse_LClick, L"delres"))
+ {
+ UIListBox* listbox = (UIListBox*)GetRootControl()->Child(L"reslist");
+ std::wstring resName = listbox->GetItem(listbox->GetCurSelItem())->GetText().data();
+ if (MessageBoxW(g_hWnd, (L"是否要删除资源\"" + resName + L"\"?").c_str(), L"删除资源", MB_ICONQUESTION | MB_YESNO) == IDYES)
+ {
+ if (dmRes.DeleteResource(resName)) {
+ listbox->DeleteItem(listbox->GetCurSelItem());
+ listbox->SetCurSelItem(-1);
+ curSelItem = -1;
+ UIEditBox* preview = static_cast(GetRootControl()->Child(L"strpreview"));
+ preview->SetCurText(L"");
+ preview->SetEnabled(false);
+ UIEditBox* resName = static_cast(GetRootControl()->Child(L"resname"));
+ resName->SetCurText(L"");
+
+ control->SetEnabled(false);
+ ShowStrLength(0);
+ ShowResSize(0);
+ static_cast(GetRootControl()->Child(L"isblock"))->SetSel(0);
+ static_cast(GetRootControl()->Child(L"blocksize"))->SetCurText(L"1024");
+ GetRootControl()->Child(L"group")->SetEnabled(false);
+
+ MessageBoxW(g_hWnd, L"删除资源成功!", L"删除资源", MB_ICONINFORMATION);
+ }
+ else
+ MessageBoxW(g_hWnd, L"删除资源失败..", L"删除资源", MB_ICONERROR);
+ }
+ }
+ else if (MUIEVENT(Event_Mouse_LClick, L"savefile"))
+ {
+ std::wstring path = static_cast(GetRootControl()->Child(L"path"))->GetCurText();
+ if (dmRes.SaveResource(path))
+ MessageBoxW(g_hWnd, L"资源以成功保存到指定路径~", L"保存", MB_ICONINFORMATION);
+ else
+ MessageBoxW(g_hWnd, L"保存文件失败! 文件可能被占用或不存在", L"保存", MB_ICONERROR);
+ }
+ else if (MUIEVENT(Event_Mouse_LClick, L"exitedit"))
+ {
+ if (MessageBoxW(g_hWnd, L"确定退出编辑模式,返回启动时的状态吗?\n提示:如果修改了资源而未保存文件 将会丢失!", L"退出编辑", MB_ICONQUESTION | MB_YESNO) == IDYES)
+ {
+ control->SetEnabled(false);
+ GetRootControl()->Child(L"loaddmres")->SetEnabled(true);
+ GetRootControl()->Child(L"newdmres")->SetEnabled(true);
+ GetRootControl()->Child(L"delres")->SetEnabled(false);
+ GetRootControl()->Child(L"addres")->SetEnabled(false);
+ GetRootControl()->Child(L"group")->SetEnabled(false);
+ GetRootControl()->Child(L"savefile")->SetEnabled(false);
+ GetRootControl()->Child(L"upclsname")->SetEnabled(false);
+ GetRootControl()->Child(L"exportres")->SetEnabled(false);
+ GetRootControl()->Child(L"exportstr")->SetEnabled(false);
+ GetRootControl()->Child(L"cleanres")->SetEnabled(false);
+ GetRootControl()->Child(L"cleanstr")->SetEnabled(false);
+ GetRootControl()->Child(L"savestr")->SetEnabled(false);
+ GetRootControl()->Child(L"decoderes")->SetEnabled(false);
+ static_cast(GetRootControl()->Child(L"resname"))->SetCurText(L"");
+ UIEditBox* clsName = static_cast(GetRootControl()->Child(L"resclsname"));
+ clsName->SetCurText(L"");
+ UIEditBox* resName = static_cast(GetRootControl()->Child(L"strpreview"));
+ resName->SetCurText(L"");
+ resName->SetEnabled(true);
+ static_cast(GetRootControl()->Child(L"reskey"))->SetCurText(L"");
+ ShowStrLength(0);
+ ShowResSize(0);
+ UIListBox* listbox = (UIListBox*)GetRootControl()->Child(L"reslist");
+ listbox->DeleteAllItem();
+ listbox->SetEnabled(false);
+ dmRes.CloseResource();
+ }
+ }
+ else if (MUIEVENT(Event_Mouse_LClick, L"loaddmres"))
+ {
+ std::wstring path = static_cast(GetRootControl()->Child(L"path"))->GetCurText();
+ if (dmRes.LoadResource(path, true))
+ {
+ control->SetEnabled(false);
+ UIListBox* listbox = (UIListBox*)GetRootControl()->Child(L"reslist");
+
+ std::vector resList;
+ dmRes.EnumResourceName(resList);
+ for (auto name : resList)
+ {
+ ListItem* item = new ListItem();
+ item->SetText(name);
+ listbox->AddItem(item, -1, false);
+ }
+ listbox->SetCurSelItem(-1);
+ listbox->SetEnabled(true);
+
+ static_cast(GetRootControl()->Child(L"resclsname"))->SetCurText(dmRes.GetResClassName());
+
+ GetRootControl()->Child(L"savefile")->SetEnabled(true);
+ GetRootControl()->Child(L"loaddmres")->SetEnabled(false);
+ GetRootControl()->Child(L"exitedit")->SetEnabled(true);
+ GetRootControl()->Child(L"addres")->SetEnabled(true);
+ GetRootControl()->Child(L"newdmres")->SetEnabled(false);
+
+ curSelItem = 0;
+ if (resList.size())
+ {
+ listbox->SetCurSelItem(0);
+ OnSelChange(listbox);
+ }
+ }
+ else
+ MessageBoxW(g_hWnd, L"打开文件失败! ", L"保存", MB_ICONERROR);
+ }
+ return false;
+}
+
+void MainWindow::CreateControls()
+{
+ //这些都是1.x 版本的写法 2x还能用! 懒得改了
+
+ UIControl* root_control = GetRootControl();
+
+ m_xmlui = XMLUI();
+ auto mgr = m_xmlui->Mgr();
+
+ auto editstyle = DMResources::ReadPEResource(IDB_PNG1, L"PNG");
+ auto btnstyle = DMResources::ReadPEResource(IDB_PNG2, L"PNG");
+ auto liststyle = DMResources::ReadPEResource(IDB_PNG3, L"PNG");
+ auto listitemstyle = DMResources::ReadPEResource(IDB_PNG4, L"PNG");
+ auto scrollstyle = DMResources::ReadPEResource(IDB_PNG5, L"PNG");
+ auto checkstyle = DMResources::ReadPEResource(IDB_PNG6, L"PNG");
+ auto progstyle = DMResources::ReadPEResource(IDB_PNG7, L"PNG");
+
+ mgr->AddImageStyle(L"editbox", editstyle, 4, nullptr, true, { 2,2,2,2 });
+ mgr->AddImageStyle(L"btnskin", btnstyle, 4, nullptr, true, { 2,2,2,2 });
+ mgr->AddImageStyle(L"listbox", liststyle, 4, nullptr, true, { 2,2,2,2 });
+ mgr->AddImageStyle(L"listitem", listitemstyle, 8, nullptr, true, { 5,5,5,5 });
+ mgr->AddImageStyle(L"scroll", scrollstyle, 16, nullptr, true, { 2,2,2,2 });
+ mgr->AddImageStyle(L"checkbox", checkstyle, 8, nullptr, true, { 5,5,5,5 });
+ mgr->AddImageStyle(L"progskin", progstyle, 4, nullptr, true, { 1,1,1,1 });
+
+ editstyle.Release();
+ btnstyle.Release();
+ liststyle.Release();
+ listitemstyle.Release();
+ scrollstyle.Release();
+ checkstyle.Release();
+ progstyle.Release();
+
+ UILabel::Attribute itemStyle;
+ itemStyle.textAlign = TextAlign(TextAlign_Left | TextAlign_VCenter);
+ m_xmlui->AddFontStyle(L"listitem", itemStyle);
+
+ std::wstring xml = LR"(
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ )";
+
+ bool ret = m_xmlui->CreateUIFromXML(root_control, xml);
+ if (!ret)
+ MessageBoxW(nullptr, L"创建UI失败!", L"error", MB_ICONERROR);
+}
+
+void MainWindow::WriteRes(UIControl* control)
+{
+ std::vector selfile;
+ if (FS::UI::MBrowseForFile(true, false, { {L"AllFiles (*.*)", L"*.*"} }, (_m_param)g_hWnd, selfile))
+ {
+ UIResource files = dmRes.ReadFiles(selfile[0]);
+ if (files.data)
+ {
+ UIListBox* listbox = (UIListBox*)GetRootControl()->Child(L"reslist");
+ UIEditBox* reskey = static_cast(GetRootControl()->Child(L"reskey"));
+ UICheckBox* isblock = static_cast(GetRootControl()->Child(L"isblock"));
+ std::wstring resname = listbox->GetItem(listbox->GetCurSelItem())->GetText().data();
+
+ DMResKey newKey;
+ newKey.res = files;
+ newKey.block = isblock->GetSel();
+ if(newKey.block)
+ newKey.blockSize = std::stoi(static_cast(GetRootControl()->Child(L"blocksize"))->GetCurText());
+
+ if (newKey.block)
+ EnableWindow(false);
+
+ DMEncBlockCallback callback;
+ if (newKey.block)
+ {
+ auto param = new std::pair>;
+ param->first = this;
+ param->second.first = (UIProgressBar*)GetRootControl()->Child(L"progress");
+ param->second.first->SetVisible(true);
+ param->second.second = files;
+ callback.callback = blockcallback;
+ callback.param = (_m_param)param;
+ }
+
+ if (dmRes.ChangeResource(resname.c_str(), newKey, reskey->GetCurText().c_str(), DataRes, callback))
+ {
+ if (!newKey.block) {
+ files.Release();
+ WriteSuccess(newKey.res.size);
+ }
+ }
+ else {
+ files.Release();
+ EnableWindow(true);
+ MessageBoxW(g_hWnd, L"无法将资源写入资源内存!.", L"写入资源", MB_ICONERROR);
+ }
+ }
+ else
+ MessageBoxW(g_hWnd, L"文件读取失败!无法写入资源.", L"写入资源", MB_ICONERROR);
+ }
+}
+
+void MainWindow::WriteSuccess(_m_size ressize)
+{
+ GetRootControl()->Child(L"importres")->SetEnabled(false);
+ GetRootControl()->Child(L"isblock")->SetEnabled(false);
+ GetRootControl()->Child(L"blocksize")->SetEnabled(false);
+ GetRootControl()->Child(L"importres")->SetEnabled(false);
+ GetRootControl()->Child(L"cleanres")->SetEnabled(true);
+ GetRootControl()->Child(L"exportres")->SetEnabled(true);
+
+ ShowResSize(ressize);
+ SetWindowTextW(g_hWnd, ::m_title.c_str());
+
+ MessageBoxW(g_hWnd, L"写入资源成功!", L"写入资源", MB_ICONINFORMATION);
+}
+
+void MainWindow::SaveRes(UIControl* control)
+{
+ std::vector selfile;
+ if (FS::UI::MBrowseForFile(false, false, { {L"AllFiles (*.*)", L"*.*"} }, (_m_param)g_hWnd, selfile))
+ {
+ UIListBox* listbox = (UIListBox*)GetRootControl()->Child(L"reslist");
+ UIEditBox* reskey = static_cast(GetRootControl()->Child(L"reskey"));
+ std::wstring resname = listbox->GetItem(listbox->GetCurSelItem())->GetText().data();
+
+ _m_size blocksize = 0;
+ if (dmRes.ReadResBlockInfo(resname, &blocksize))
+ {
+ _m_size cur = 0;
+ _m_size size = 0;
+ _m_size allsize = dmRes.ReadResourceSize(resname, DataRes);
+ std::wstring key = reskey->GetCurText();
+ auto progress = (UIProgressBar*)GetRootControl()->Child(L"progress");
+ progress->SetCurValue(0);
+ progress->SetVisible(true, true);
+
+ FILE* file;
+ _wfopen_s(&file, selfile[0].data(), L"wb");
+ EnableWindow(false);
+ for (;;)
+ {
+ if (!file) {
+ MessageBoxW(g_hWnd, L"写出资源失败! 无法写出到磁盘", L"写出数据", MB_ICONERROR);
+ break;
+ }
+
+ _m_size ret = 0;
+ UIResource res = dmRes.ReadResourceBlock(resname, key, cur, blocksize, &ret);
+
+ if(ret)
+ fwrite(res.data, 1, ret, file);
+
+ res.Release();
+
+ cur += blocksize;
+ size += ret;
+ _m_size value = _m_size((double)size / (double)allsize * 100.f);
+ if (value != progress->GetCurValue())
+ progress->SetCurValue(value);
+ if (size == allsize) {
+ fclose(file);
+ MessageBoxW(g_hWnd, L"写出资源成功!", L"写出资源", MB_ICONINFORMATION);
+ break;
+ }
+ Settings::UIMessageLoop();
+ }
+ EnableWindow(true);
+ progress->SetVisible(false, true);
+ }
+ else {
+ DMResKey key = dmRes.ReadResource(resname, reskey->GetCurText(), DataRes);
+
+ if (dmRes.WriteFiles(selfile[0], key.res))
+ MessageBoxW(g_hWnd, L"写出资源成功!", L"写出资源", MB_ICONINFORMATION);
+ else
+ MessageBoxW(g_hWnd, L"写出资源失败! 无法写出到磁盘", L"写出数据", MB_ICONERROR);
+ key.res.Release();
+ }
+ }
+}
+
+void MainWindow::OnSelChange(UIControl* control)
+{
+ UIListBox* listbox = (UIListBox*)control;
+ UIEditBox* resName = static_cast(GetRootControl()->Child(L"resname"));
+ std::wstring resname = listbox->GetItem(curSelItem)->GetText().data();
+ resName->SetCurText(resname);
+ resName->SetEnabled(true);
+
+ auto block = (UICheckBox*)GetRootControl()->Child(L"isblock");
+ _m_size blocksize = 1024;
+ bool isblock = dmRes.ReadResBlockInfo(resname, &blocksize);
+ if (!isblock)
+ blocksize = 1024;
+ block->SetSel(isblock);
+ block->SetEnabled(false);
+ auto blocksizeedit = (UIEditBox*)GetRootControl()->Child(L"blocksize");
+ blocksizeedit->SetCurText(std::to_wstring(blocksize));
+ blocksizeedit->SetEnabled(false);
+
+ GetRootControl()->Child(L"group")->SetEnabled(true);
+ GetRootControl()->Child(L"decoderes")->SetEnabled(true);
+ GetRootControl()->Child(L"upresname")->SetEnabled(false);
+ GetRootControl()->Child(L"exportres")->SetEnabled(false);
+ GetRootControl()->Child(L"importres")->SetEnabled(false);
+ GetRootControl()->Child(L"cleanres")->SetEnabled(false);
+ GetRootControl()->Child(L"importstr")->SetEnabled(false);
+ GetRootControl()->Child(L"exportstr")->SetEnabled(false);
+ GetRootControl()->Child(L"cleanstr")->SetEnabled(false);
+ GetRootControl()->Child(L"savestr")->SetEnabled(false);
+ GetRootControl()->Child(L"delres")->SetEnabled(true);
+ UIEditBox* resEdit = static_cast(GetRootControl()->Child(L"strpreview"));
+ resEdit->SetCurText(L"");
+ resEdit->SetEnabled(false);
+ ShowResSize(dmRes.ReadResourceSize(resname, DataRes));
+ ShowStrLength(dmRes.ReadResourceSize(resname, StringRes));
+}
+
+void MainWindow::ShowResSize(_m_size size)
+{
+ std::wstring size_str, uint;
+
+ double i = pow((double)2, 10);
+
+ if (size < pow((double)2, 10))//dwSize < 1024
+ {
+ size_str = std::to_wstring(size);
+ uint = L"B";
+ }
+ else if (pow((double)2, 10) <= size && size < pow((double)2, 20))// 1024 <= dwSize < 1024*1024
+ {
+ float fSize = (float)(size * 100 / 1024) / 100;
+ size_str = std::to_wstring(fSize);
+ uint = L"KB";
+ }
+ else if (pow((double)2, 20) <= size && size < pow((double)2, 30))// 1024*1024 <= dwSize < 1024*1024*1024
+ {
+ float fSize = (float)(size / 1024 * 100 / 1024) / 100;
+ size_str = std::to_wstring(fSize);
+ uint = L"MB";
+ }
+ else if (pow((double)2, 30) <= size && size < pow((double)2, 40)) // 1024*1024*1024 <= dwSize < 1024*1024*1024*1024
+ {
+ float fSize = (float)(size / 1024 * 100 / 1024 / 1024) / 100;
+ size_str = std::to_wstring(fSize);
+ uint = L"GB";
+ }
+ GetRootControl()->Child(L"ressize")->SetAttribute(
+ L"text", L"字节大小:" + size_str.substr(0, size_str.find(L'.') + 3) + uint);
+}
+
+void MainWindow::ShowStrLength(_m_size lenght)
+{
+ GetRootControl()->Child(L"strsize")->SetAttribute(L"text", L"文本长度:" + std::to_wstring(lenght));
+}
+
+void blockcallback(_m_size size, _m_size allsize, _m_param param)
+{
+ auto param_ = (std::pair>*)param;
+ _m_size value = _m_size((double)size / (double)allsize * 100.f);
+ if (value != param_->second.first->GetCurValue())
+ param_->second.first->SetCurValue(value);
+ if (size == allsize) {
+ param_->second.second.Release();
+ param_->first->WriteSuccess(size);
+ param_->second.first->SetVisible(false, true);
+ param_->first->EnableWindow(true);
+ delete param_;
+ }
+}
+#else
+#error "需要启用DmResFileV1 (MUI_CFG_ENABLE_V1DMRES宏)在Mui_Config.h"
+#endif
\ No newline at end of file
diff --git a/DmResEditor/DmResEditor.h b/DmResEditor/DmResEditor.h
new file mode 100644
index 0000000..06ce0eb
--- /dev/null
+++ b/DmResEditor/DmResEditor.h
@@ -0,0 +1,36 @@
+// 8-12-2020 Create
+#pragma once
+#include "resource.h"
+#include "Mui.h"
+
+extern HINSTANCE m_hInstance;
+
+using namespace Mui;
+
+class MainWindow : public Window::UIWindowsWnd
+{
+public:
+ MainWindow(Render::MRender* pRender) : UIWindowsWnd(pRender) {}
+
+ bool AfterCreated();
+ virtual bool EventProc(UINotifyEvent event, Ctrl::UIControl* control, _m_param param) override;
+ virtual _m_result EventSource(MEventCodeEnum code, _m_param param) override;
+
+private:
+ void CreateControls();
+ //写入资源
+ void WriteRes(Ctrl::UIControl* control);
+ void WriteSuccess(_m_size ressize);
+ //写出资源
+ void SaveRes(Ctrl::UIControl* control);
+ //当前选中表项更改
+ void OnSelChange(Ctrl::UIControl* control);
+ //显示文件大小
+ void ShowResSize(_m_size size);
+ //显示文本长度
+ void ShowStrLength(_m_size lenght);
+
+ int curSelItem = 0;
+
+ friend void blockcallback(_m_size size, _m_size allsize, _m_param param);
+};
\ No newline at end of file
diff --git a/DmResEditor/DmResEditor.ico b/DmResEditor/DmResEditor.ico
new file mode 100644
index 0000000..b3ec03b
Binary files /dev/null and b/DmResEditor/DmResEditor.ico differ
diff --git a/DmResEditor/DmResEditor.rc b/DmResEditor/DmResEditor.rc
new file mode 100644
index 0000000..7b985cf
Binary files /dev/null and b/DmResEditor/DmResEditor.rc differ
diff --git a/DmResEditor/DmResEditor.vcxproj b/DmResEditor/DmResEditor.vcxproj
new file mode 100644
index 0000000..c420063
--- /dev/null
+++ b/DmResEditor/DmResEditor.vcxproj
@@ -0,0 +1,202 @@
+
+
+
+
+ Debug
+ Win32
+
+
+ Release
+ Win32
+
+
+ Debug
+ x64
+
+
+ Release
+ x64
+
+
+
+ 16.0
+ Win32Proj
+ {9d0d532d-c306-47ca-b438-88a0408831d1}
+ DmResEditor
+ 10.0
+
+
+
+ Application
+ true
+ v143
+ Unicode
+
+
+ Application
+ false
+ v143
+ true
+ Unicode
+
+
+ Application
+ true
+ v143
+ Unicode
+
+
+ Application
+ false
+ v143
+ true
+ Unicode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ true
+ $(SolutionDir)bin\$(ProjectName)\Debug\
+ $(SolutionDir)$(ProjectName)\Cache\Debug\
+
+
+ false
+ $(SolutionDir)bin\$(ProjectName)\Release\
+ $(SolutionDir)$(ProjectName)\Cache\Release\
+
+
+ true
+ $(SolutionDir)bin\$(ProjectName)\Debug64\
+ $(SolutionDir)$(ProjectName)\Cache\Debug64\
+
+
+ false
+ $(SolutionDir)bin\$(ProjectName)\Release64\
+ $(SolutionDir)$(ProjectName)\Cache\Release64\
+
+
+
+ Level3
+ true
+ WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)
+ true
+ MultiThreadedDebug
+ $(SolutionDir)MiaoUI\src\include;%(AdditionalIncludeDirectories)
+ stdcpp17
+
+
+ Windows
+ true
+ $(SolutionDir)MiaoUI\library\;%(AdditionalLibraryDirectories)
+
+
+ PerMonitorHighDPIAware
+
+
+
+
+ Level3
+ true
+ true
+ true
+ WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)
+ true
+ MultiThreaded
+ $(SolutionDir)MiaoUI\src\include;%(AdditionalIncludeDirectories)
+ stdcpp17
+
+
+ Windows
+ true
+ true
+ true
+ $(SolutionDir)MiaoUI\library\;%(AdditionalLibraryDirectories)
+
+
+ PerMonitorHighDPIAware
+
+
+
+
+ Level3
+ true
+ _DEBUG;_WINDOWS;%(PreprocessorDefinitions)
+ true
+ MultiThreadedDebug
+ $(SolutionDir)MiaoUI\src\include;%(AdditionalIncludeDirectories)
+ stdcpp17
+
+
+ Windows
+ true
+ $(SolutionDir)MiaoUI\library\;%(AdditionalLibraryDirectories)
+
+
+ false
+
+
+
+
+ Level3
+ true
+ true
+ true
+ NDEBUG;_WINDOWS;%(PreprocessorDefinitions)
+ true
+ MultiThreaded
+ $(SolutionDir)MiaoUI\src\include;%(AdditionalIncludeDirectories)
+ stdcpp17
+
+
+ Windows
+ true
+ true
+ true
+ $(SolutionDir)MiaoUI\library\;%(AdditionalLibraryDirectories)
+
+
+ false
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/DmResEditor/DmResEditor.vcxproj.filters b/DmResEditor/DmResEditor.vcxproj.filters
new file mode 100644
index 0000000..c4c28d6
--- /dev/null
+++ b/DmResEditor/DmResEditor.vcxproj.filters
@@ -0,0 +1,67 @@
+
+
+
+
+ {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
+ cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx
+
+
+ {93995380-89BD-4b04-88EB-625FBE52EBFB}
+ h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd
+
+
+ {67DA6AB6-F800-4c08-8B7A-83BB121AAD01}
+ rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms
+
+
+
+
+ 头文件
+
+
+ 头文件
+
+
+ 头文件
+
+
+
+
+ 源文件
+
+
+
+
+ 资源文件
+
+
+
+
+ 资源文件
+
+
+ 资源文件
+
+
+ 资源文件
+
+
+ 资源文件
+
+
+ 资源文件
+
+
+ 资源文件
+
+
+ 资源文件
+
+
+ 资源文件
+
+
+ 资源文件
+
+
+
\ No newline at end of file
diff --git a/DmResEditor/DmResEditor.vcxproj.user b/DmResEditor/DmResEditor.vcxproj.user
new file mode 100644
index 0000000..88a5509
--- /dev/null
+++ b/DmResEditor/DmResEditor.vcxproj.user
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
diff --git a/DmResEditor/framework.h b/DmResEditor/framework.h
new file mode 100644
index 0000000..f8f8bf7
--- /dev/null
+++ b/DmResEditor/framework.h
@@ -0,0 +1,14 @@
+// header.h: 标准系统包含文件的包含文件,
+// 或特定于项目的包含文件
+//
+
+#pragma once
+#include
+#define WIN32_LEAN_AND_MEAN // 从 Windows 头文件中排除极少使用的内容
+// Windows 头文件
+#include
+// C 运行时头文件
+#include
+#include
+#include
+#include
diff --git a/DmResEditor/res/button.png b/DmResEditor/res/button.png
new file mode 100644
index 0000000..c211475
Binary files /dev/null and b/DmResEditor/res/button.png differ
diff --git a/DmResEditor/res/checkbox.png b/DmResEditor/res/checkbox.png
new file mode 100644
index 0000000..b4e73d0
Binary files /dev/null and b/DmResEditor/res/checkbox.png differ
diff --git a/DmResEditor/res/edit.png b/DmResEditor/res/edit.png
new file mode 100644
index 0000000..fd17d38
Binary files /dev/null and b/DmResEditor/res/edit.png differ
diff --git a/DmResEditor/res/listbox.png b/DmResEditor/res/listbox.png
new file mode 100644
index 0000000..eb3443d
Binary files /dev/null and b/DmResEditor/res/listbox.png differ
diff --git a/DmResEditor/res/listitem.png b/DmResEditor/res/listitem.png
new file mode 100644
index 0000000..019a785
Binary files /dev/null and b/DmResEditor/res/listitem.png differ
diff --git a/DmResEditor/res/progress.png b/DmResEditor/res/progress.png
new file mode 100644
index 0000000..915a93a
Binary files /dev/null and b/DmResEditor/res/progress.png differ
diff --git a/DmResEditor/res/scroll.png b/DmResEditor/res/scroll.png
new file mode 100644
index 0000000..11e60d2
Binary files /dev/null and b/DmResEditor/res/scroll.png differ
diff --git a/DmResEditor/res/wnd.psd b/DmResEditor/res/wnd.psd
new file mode 100644
index 0000000..6a64220
Binary files /dev/null and b/DmResEditor/res/wnd.psd differ
diff --git a/DmResEditor/resource.h b/DmResEditor/resource.h
new file mode 100644
index 0000000..b840055
--- /dev/null
+++ b/DmResEditor/resource.h
@@ -0,0 +1,29 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Visual C++ 生成的包含文件。
+// 供 DmResEditor.rc 使用
+//
+#define IDC_MYICON 2
+#define IDD_DMRESEDITOR_DIALOG 102
+#define IDI_DMRESEDITOR 107
+#define IDI_SMALL 108
+#define IDR_MAINFRAME 128
+#define IDB_PNG1 129
+#define IDB_PNG2 130
+#define IDB_PNG3 131
+#define IDB_PNG4 132
+#define IDB_PNG5 133
+#define IDB_PNG6 134
+#define IDB_PNG7 135
+#define IDC_STATIC -1
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NO_MFC 1
+#define _APS_NEXT_RESOURCE_VALUE 136
+#define _APS_NEXT_COMMAND_VALUE 32771
+#define _APS_NEXT_CONTROL_VALUE 1000
+#define _APS_NEXT_SYMED_VALUE 110
+#endif
+#endif
diff --git a/DmResEditor/small.ico b/DmResEditor/small.ico
new file mode 100644
index 0000000..b3ec03b
Binary files /dev/null and b/DmResEditor/small.ico differ
diff --git a/MiaoUI/.editorconfig b/MiaoUI/.editorconfig
new file mode 100644
index 0000000..86bd7f4
--- /dev/null
+++ b/MiaoUI/.editorconfig
@@ -0,0 +1,6 @@
+# Visual Studio 生成了具有 C++ 设置的 .editorconfig 文件。
+root = true
+
+[*.{c++,cc,cpp,cppm,cu,cuh,cxx,h,h++,hh,hpp,hxx,inl,ipp,ixx,tlh,tli}]
+end_of_line = lf # 行尾 UNIX 格式 LF
+charset = utf-8-bom
\ No newline at end of file
diff --git a/MiaoUI/AttribName.txt b/MiaoUI/AttribName.txt
new file mode 100644
index 0000000..6c6b280
--- /dev/null
+++ b/MiaoUI/AttribName.txt
@@ -0,0 +1,273 @@
+/**
+ * Info: XML属性名列表
+ * Author: Maple
+ *
+ * date: 2021-11-9 Create
+ * @winmoes.com
+ */
+
+
+属性组:
+PropGroup
+ id //属性组ID文本
+ xxx = xxx //任意属性和属性值
+ ....
+例:
+
+ //控件将拥有属性组的属性 frame和text
+
+默认属性组:
+通过函数AddDefPropGroup可以添加全局默认属性组
+xml示例:
+
+
+
+
+
+这为UIButton、UICheckBox、UISlider设置了默认属性
+使用CreateUIFromXML创建控件时 即使不写属性 也包含这些默认属性
+默认属性组中也可以引用普通属性组 实现属性的快速设置
+
+字符串表:
+可以通过函数AddStringList添加默认字符串列表
+
+设置控件属性时 以 '#' 开头后面跟字符串名称 即可引用此字符串
+
+例如 AddStringList(L"测试", L"目标字符串");
+创建控件
+
+控件文本将为 "目标字符串"
+
+同时 如果使用SetStringValue函数修改字符串 那么与之关联的所有控件文本都将发生改变
+
+可以利用此特性实现多语言文本快速切换或者样式组的快速切换
+
+UIBitmap属性如果为普通名称则读取Image、Bitmap类型资源 如果为 "@svg:" 开头则读取SVGImg资源 可追加颜色替换参数 如 "@svg:testimg,0,0,0,255"或"@svg:testimg,@hex:FFFFFFFF"
+_m_color属性直接使用RGBA或RGB颜色值 如 "255,255,255,255" 如果要使用十六进制则写为 "@hex:FFFFFFFF" 格式为RRGGBBAA 或者RRGGBB 不写Alpha默认255或FF
+
+控件类型:
+
+xx - 代表参数数量 如 4x = 111,111,111,111
+bool - 代表文本只能是 true 或 false
+
+xxx : xxx : 代表还有属性继承自xxx控件
+
+style* - UIStyle指针 如果使用MuiXML 则为资源文件的名称
+UILabelConfig* - 代表字体样式结构体指针 如果使用MuiXML 为AddFontStyle所添加到字体列表的名称
+UIResource* - 代表资源结构体指针 如果使用MuiXML 为资源文件中的资源名称
+
+UIControl:
+ pos 2x - 控件位置 左 顶
+ size 2x - 控件尺寸 宽 高 可为百分比 代表使用父窗口的宽度百分比 例如 50%,50% 或者结尾单位为f 50f 代表使用FillMinus布局参数 即相当于 对于父窗口尺寸 - 50
+ frame 4x - 控件框架(如果使用此属性 则代替前两个属性) 左 顶 宽 高
+ - 宽 高 可为百分比 代表使用父窗口的宽度百分比 例如 50%,50%
+ autoSize (bool) - 控件尺寸是否根据子内容自动计算 默认false 这将忽略size和frame的宽高属性值
+ minSize - 控件最小尺寸 即使开启autoSize 也会限制
+ maxSize - 控件最大尺寸 即使开启autoSize 也会限制 值为-1则无限制
+ padding 4x - 内边距
+ name - 控件名称
+ data (_m_param) - 用户自定义数据
+ visible (bool) - 是否可见
+ enable (bool) - 是否可用
+ alpha (_m_byte) - 不透明度 0-255
+ enableFocus (bool) - 是否接受焦点
+ msgFilter (bool) - 是否穿透消息
+ msgLgnore (bool) - 是否忽略消息
+ bgColor 4x - 背景颜色 R,G,B,A
+ frameColor 4x - 边框颜色 R,G,B,A
+ frameWidth (int) - 边框宽度 只能是数字
+ frameRound (float) - 圆角度
+ align (int) - 对齐方式 可以是枚举数字 如 1代表 UIAlignment_Block 也可以是字符串 如 Block、LinearV.....
+ dpiScale (bool) - 单独设置此控件是否支持DPI缩放 (如果窗口dpi缩放关闭 则此选项也不会有效)
+ scale 4x (float) - 设置控件缩放比例 X Y W H 默认 1.0,1.0,1.0,1.0
+ shadowColor (4x) - 阴影颜色
+ shadowOffset (2x) - 阴影偏移位置
+ shadowExtend (int) - 阴影扩展 px
+ shadowRadius (float) - 阴影模糊半径
+
+以下控件都具有UIControl的属性 控件名称排序按A-Z
+
+//该控件autoSize 默认 true
+UIButton: UILabel :
+ * style (UIStyle*)
+ * animate (bool) - 是否启用动画效果
+ * aniAlphaType (bool) - 动画效果方式 混合或覆盖
+ * inset (_m_rect_t) - 内边距 仅autoSize=true 时才有效
+
+//该控件autoSize 默认 true
+UICheckBox: UILabel :
+ * style (UIStyle*)
+ * isSel (bool) - 是否被选中
+ * allowClick (bool) - 是否可通过点击改变选中状态(否则只能手动设置isSel来控制是否选中)
+ * animate (bool) - 是否启用动画效果
+ * aniAlphaType (bool) - 动画效果方式 混合或覆盖
+ * textOffset (int) - 文本和图标之间的距离
+
+UIColorPicker:
+ * color 4x - RGBA颜色
+ * hsv 3x - HSV颜色
+
+//该控件autoSize 默认 true
+UIComBox: UILabel
+ * style (UIStyle*)
+ * dropIcon (UIBitmap*) - 下拉列表图标
+ * dropIconXPos (int) - 下拉列表图标X偏移位置
+ * dropIconAutoPos (bool) - 自动计算下拉列表图标位置
+ * popTop (bool) - 向上弹出菜单
+ * menuHeight (int) - 弹出菜单高度(px)
+ * listShadowBlur (float) - 弹出列表阴影模糊度 默认6.f
+ * listShadowColor (_m_color) 4x - 弹出列表阴影颜色 默认RGBA(0,0,0,50)
+ * listShadowOffset (UIPoint) 2x - 弹出列表阴影偏移位置 x,y 默认 0,5
+ * listShadowExtend (int) - 弹出列表阴影扩展 默认0
+ * 列表属性:
+ * listStyle (UIStyle*) - 列表样式
+ * itemStyle (UIStyle*) - 列表项样式
+ * itemHeight (int) - 列表项高度(px)
+ * lineSpace (int) - 列表行间距(px)
+ * iFontStyle (UIListBox::ItemFont) - 列表项字体默认样式
+ * iFont (std::wstring_view) - 列表项字体默认样式 - 字体名称
+ * iFontSize (_m_ushort) - 列表项字体默认样式 - 字体尺寸 默认12px
+ * iFontBold (bool) - 列表项字体默认样式 - 是否粗体
+ * iFontItalics (bool) - 列表项字体默认样式 - 是否斜体
+ * iFontUnderline (bool) - 列表项字体默认样式 - 是否下划线
+ * iFontStrikeout (bool) - 列表项字体默认样式 - 是否删除线
+ * iFontColor 4x - 列表项字体默认样式 - 字体颜色 默认RGBA(0,0,0,255)
+ * iTextAlign - 列表项字体默认样式 - 文本对齐方式 仅数字 为TextAlignment枚举值 默认LeftTop
+ * iFontCustom (_m_param) - 列表项字体默认样式 - 自定义字体集对象参数
+ * drawOffset (UIPoint) 2x - 列表内容绘制偏移参数(px)
+ * 列表滚动条属性:
+ * styleV (UIStyle*) - 垂直滚动条样式
+ * animate (bool) - 是否启用动画效果
+ * button (bool) - 是否显示滚动条上下调节按钮
+ * dragValueV (int) - 垂直滚动条当前值
+ * barWidth (int) - 滚动条宽度
+ * barMinHeight (int) - 滚动条按钮最小高(宽)度
+ * btnHeight (int) - 滚动条上下调节按钮高度
+ * inset (_m_rect_t) 4x - 内边距
+
+UIEditBox: UIScroll
+ * style (UIStyle*)
+ * fontStyle (UILabel::Attribute*) - 字体样式
+ * text (std::wstring_view) - 当前文本
+ * multiline (bool) - 是否为多行编辑框
+ * password (bool) - 是否为密码输入模式
+ * passChar (wchar_t) - 密码遮掩符
+ * readOnly (bool) - 是否为只读模式
+ * isRich (bool) - 是否为富文本模式
+ * wordWrap (bool) - 是否自动折行
+ * wordAutoSel (bool) - 是否自动选择文本
+ * number (bool) - 是否为数字输入模式
+ * scroll (bool) - 是否有滚动条
+ * autoBar (bool) - 自动显示滚动条
+ * limitText (int) - 最大可输入文本数
+ * editAlign (_m_word) - 编辑框布局样式 ES_XXX
+ * caretColor (_m_color) - 指针颜色
+ * pholderText (std::wstring_view) - 占位符文本
+ * pholderTextColor (_m_color) - 占位符文本颜色
+
+//该控件autoSize 默认 true
+UIImgBox:
+ * img (UIBitmap*)
+ * imgStyle //图片对齐方式 仅数字 为UIImageBoxStyle的枚举值
+
+//该控件autoSize 默认 true
+UILabel:
+ * fontStyle (UILabel::Attribute*)
+ * text (std::wstring_view) - 文本
+ * font (std::wstring_view) - 字体名称
+ * fontSize (_m_ushort) - 字体尺寸 默认12px
+ * fontBold (bool) - 是否粗体
+ * fontItalics (bool) - 是否斜体
+ * fontUnderline (bool) - 是否下划线
+ * fontStrikeout (bool) - 是否删除线
+ * fontColor 4x - 字体颜色 默认RGBA(0,0,0,255)
+ * hyperlink (bool) - 是否为超链接
+ * url (std::wstring_view) - 超链接网址
+ * urlColor 4x - 超链接热点颜色 默认RGBA(167,226,54,255)
+ * textAlign - 文本对齐方式 仅数字 为TextAlign的枚举值组合 默认LeftTop
+ * fontCustom (_m_ptrv) - 自定义字体集对象参数
+ * shadowUse (bool) - 使用文本阴影效果
+ * shadowBlur (float) - 文本阴影模糊度 默认1.f
+ * shadowColor (_m_color) 4x - 文本阴影颜色 默认RGBA(0,0,0,255)
+ * shadowOffset (UIPoint) 2x - 文本阴影偏移位置 x,y 默认 1,1
+ * shadowLow (bool) - 是否使用低质量阴影 如果为true=没有模糊效果 blur属性无效
+
+UIListBox: UIScroll
+ * style (UIStyle*)
+ * itemStyle (UIStyle*) - 列表项样式
+ * itemHeight (int) - 列表项高度(px)
+ * lineSpace (int) - 列表行间距(px)
+ * iFontStyle (UIListBox::ItemFont) - 列表项字体默认样式
+ * iFont (std::wstring_view) - 列表项字体默认样式 - 字体名称
+ * iFontSize (_m_ushort) - 列表项字体默认样式 - 字体尺寸 默认12px
+ * iFontBold (bool) - 列表项字体默认样式 - 是否粗体
+ * iFontItalics (bool) - 列表项字体默认样式 - 是否斜体
+ * iFontUnderline (bool) - 列表项字体默认样式 - 是否下划线
+ * iFontStrikeout (bool) - 列表项字体默认样式 - 是否删除线
+ * iFontColor 4x - 列表项字体默认样式 - 字体颜色 默认RGBA(0,0,0,255)
+ * iTextAlign - 列表项字体默认样式 - 文本对齐方式 仅数字 为TextAlignment枚举值 默认LeftTop
+ * iFontCustom (_m_param) - 列表项字体默认样式 - 自定义字体集对象参数
+ * drawOffset (UIPoint) 2x - 列表内容绘制偏移参数(px)
+ * allowRightSel (bool) - 允许右键点击也能选中列表项目
+
+//该控件autoSize 默认 true
+UINavBar:
+ * fontStyle (UILabel::Attribute*) - 字体样式
+ * font (std::wstring_view) - 字体
+ * fontColor (_m_color) 4x - 字体颜色 默认RGBA(120,120,120,255)
+ * fontHoverColor (_m_color) 4x - 字体颜色 Hover状态 默认RGBA(0,0,0,255)
+ * fontPressColor (_m_color) 4x - 字体颜色 按下状态 默认RGBA(150,150,150,255)
+ * fontSize (_m_ushort) - 字体尺寸 默认12px
+ * fontBold (bool) - 是否粗体
+ * fontItalics (bool) - 是否斜体
+ * fontUnderline (bool) - 是否下划线
+ * fontStrikeout (bool) - 是否删除线
+ * fontCustom (_m_ptrv) - 自定义字体集对象参数
+ * shadowUse (bool) - 使用文本阴影效果
+ * shadowBlur (float) - 文本阴影模糊度 默认1.f
+ * shadowColor (_m_color) 4x - 文本阴影颜色 默认RGBA(0,0,0,255)
+ * shadowOffset (UIPoint) 2x - 文本阴影偏移位置 x,y 默认 1,1
+ * shadowLow (bool) - 是否使用低质量阴影 如果为true=没有模糊效果 blur属性无效
+ * itemSpace (int) - item间距
+ * barSpace (int) - 横条和文字间距
+ * barHeight (int) - 横条高度 默认4px
+ * barAnitime (int) - 横条过渡动画时长(ms) 默认300ms
+ * barRound (float) - 横条圆角度 默认1.5f
+ * barColor (_m_color) 4x - 横条颜色
+
+UIProgressBar:
+ * style (UIStyle*)
+ * maxValue (int) - 最大值
+ * value (int) - 当前值
+ * leftShow (bool) - 如果非垂直 进度从左往右显示 (默认true)
+ * bottomShow (bool) - 如果非水平 进度从下往上显示 (默认true)
+
+UIScroll:
+ * styleV (UIStyle*) - 垂直滚动条样式
+ * styleH (UIStyle*) - 水平滚动条样式
+ * vertical (bool) - 显示垂直滚动条
+ * horizontal (bool) - 显示水平滚动条
+ * active (bool) - 始终显示滚动条(无效)
+ * animate (bool) - 是否启用动画效果
+ * button (bool) - 是否显示滚动条上下调节按钮
+ * range (UISize) - 滚动条最大可滚动区域
+ * rangeV (int) - 垂直滚动条最大可滚动区域
+ * rangeH (int) - 水平滚动条最大可滚动区域
+ * dragValue (UISize) - 滚动条当前值
+ * dragValueV (int) - 垂直滚动条当前值
+ * dragValueH (int) - 水平滚动条当前值
+ * barWidth (int) - 滚动条宽度
+ * barMinHeight (int) - 滚动条按钮最小高(宽)度
+ * btnHeight (int) - 滚动条上下调节按钮高度
+ * inset (_m_rect_t) - 内边距
+
+UISlider:
+ * style (UIStyle*)
+ * btnStyle (UIStyle*) - 滑块按钮样式
+ * maxValue (int) - 最大值
+ * minValue (int) - 最小值
+ * value (int) - 当前值
+ * leftShow (bool) - 如果非垂直 进度从左往右显示 (默认true)
+ * bottomShow (bool) - 如果非水平 进度从下往上显示 (默认true)
+ * trackInset (_m_rect_t) 4x - 轨道内边距
+ * btnSize (UISize) 2x - 拖拽按钮尺寸 0=自动计算
\ No newline at end of file
diff --git a/MiaoUI/COPYING b/MiaoUI/COPYING
new file mode 100644
index 0000000..e72bfdd
--- /dev/null
+++ b/MiaoUI/COPYING
@@ -0,0 +1,674 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc.
+ 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.
+
+
+ Copyright (C)
+
+ 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 .
+
+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:
+
+ Copyright (C)
+ 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
+.
+
+ 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
+.
\ No newline at end of file
diff --git a/MiaoUI/COPYING.LESSER b/MiaoUI/COPYING.LESSER
new file mode 100644
index 0000000..153d416
--- /dev/null
+++ b/MiaoUI/COPYING.LESSER
@@ -0,0 +1,165 @@
+ GNU LESSER GENERAL PUBLIC LICENSE
+ Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc.
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+
+ This version of the GNU Lesser General Public License incorporates
+the terms and conditions of version 3 of the GNU General Public
+License, supplemented by the additional permissions listed below.
+
+ 0. Additional Definitions.
+
+ As used herein, "this License" refers to version 3 of the GNU Lesser
+General Public License, and the "GNU GPL" refers to version 3 of the GNU
+General Public License.
+
+ "The Library" refers to a covered work governed by this License,
+other than an Application or a Combined Work as defined below.
+
+ An "Application" is any work that makes use of an interface provided
+by the Library, but which is not otherwise based on the Library.
+Defining a subclass of a class defined by the Library is deemed a mode
+of using an interface provided by the Library.
+
+ A "Combined Work" is a work produced by combining or linking an
+Application with the Library. The particular version of the Library
+with which the Combined Work was made is also called the "Linked
+Version".
+
+ The "Minimal Corresponding Source" for a Combined Work means the
+Corresponding Source for the Combined Work, excluding any source code
+for portions of the Combined Work that, considered in isolation, are
+based on the Application, and not on the Linked Version.
+
+ The "Corresponding Application Code" for a Combined Work means the
+object code and/or source code for the Application, including any data
+and utility programs needed for reproducing the Combined Work from the
+Application, but excluding the System Libraries of the Combined Work.
+
+ 1. Exception to Section 3 of the GNU GPL.
+
+ You may convey a covered work under sections 3 and 4 of this License
+without being bound by section 3 of the GNU GPL.
+
+ 2. Conveying Modified Versions.
+
+ If you modify a copy of the Library, and, in your modifications, a
+facility refers to a function or data to be supplied by an Application
+that uses the facility (other than as an argument passed when the
+facility is invoked), then you may convey a copy of the modified
+version:
+
+ a) under this License, provided that you make a good faith effort to
+ ensure that, in the event an Application does not supply the
+ function or data, the facility still operates, and performs
+ whatever part of its purpose remains meaningful, or
+
+ b) under the GNU GPL, with none of the additional permissions of
+ this License applicable to that copy.
+
+ 3. Object Code Incorporating Material from Library Header Files.
+
+ The object code form of an Application may incorporate material from
+a header file that is part of the Library. You may convey such object
+code under terms of your choice, provided that, if the incorporated
+material is not limited to numerical parameters, data structure
+layouts and accessors, or small macros, inline functions and templates
+(ten or fewer lines in length), you do both of the following:
+
+ a) Give prominent notice with each copy of the object code that the
+ Library is used in it and that the Library and its use are
+ covered by this License.
+
+ b) Accompany the object code with a copy of the GNU GPL and this license
+ document.
+
+ 4. Combined Works.
+
+ You may convey a Combined Work under terms of your choice that,
+taken together, effectively do not restrict modification of the
+portions of the Library contained in the Combined Work and reverse
+engineering for debugging such modifications, if you also do each of
+the following:
+
+ a) Give prominent notice with each copy of the Combined Work that
+ the Library is used in it and that the Library and its use are
+ covered by this License.
+
+ b) Accompany the Combined Work with a copy of the GNU GPL and this license
+ document.
+
+ c) For a Combined Work that displays copyright notices during
+ execution, include the copyright notice for the Library among
+ these notices, as well as a reference directing the user to the
+ copies of the GNU GPL and this license document.
+
+ d) Do one of the following:
+
+ 0) Convey the Minimal Corresponding Source under the terms of this
+ License, and the Corresponding Application Code in a form
+ suitable for, and under terms that permit, the user to
+ recombine or relink the Application with a modified version of
+ the Linked Version to produce a modified Combined Work, in the
+ manner specified by section 6 of the GNU GPL for conveying
+ Corresponding Source.
+
+ 1) Use a suitable shared library mechanism for linking with the
+ Library. A suitable mechanism is one that (a) uses at run time
+ a copy of the Library already present on the user's computer
+ system, and (b) will operate properly with a modified version
+ of the Library that is interface-compatible with the Linked
+ Version.
+
+ e) Provide Installation Information, but only if you would otherwise
+ be required to provide such information under section 6 of the
+ GNU GPL, and only to the extent that such information is
+ necessary to install and execute a modified version of the
+ Combined Work produced by recombining or relinking the
+ Application with a modified version of the Linked Version. (If
+ you use option 4d0, the Installation Information must accompany
+ the Minimal Corresponding Source and Corresponding Application
+ Code. If you use option 4d1, you must provide the Installation
+ Information in the manner specified by section 6 of the GNU GPL
+ for conveying Corresponding Source.)
+
+ 5. Combined Libraries.
+
+ You may place library facilities that are a work based on the
+Library side by side in a single library together with other library
+facilities that are not Applications and are not covered by this
+License, and convey such a combined library under terms of your
+choice, if you do both of the following:
+
+ a) Accompany the combined library with a copy of the same work based
+ on the Library, uncombined with any other library facilities,
+ conveyed under the terms of this License.
+
+ b) Give prominent notice with the combined library that part of it
+ is a work based on the Library, and explaining where to find the
+ accompanying uncombined form of the same work.
+
+ 6. Revised Versions of the GNU Lesser General Public License.
+
+ The Free Software Foundation may publish revised and/or new versions
+of the GNU Lesser 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
+Library as you received it specifies that a certain numbered version
+of the GNU Lesser General Public License "or any later version"
+applies to it, you have the option of following the terms and
+conditions either of that published version or of any later version
+published by the Free Software Foundation. If the Library as you
+received it does not specify a version number of the GNU Lesser
+General Public License, you may choose any version of the GNU Lesser
+General Public License ever published by the Free Software Foundation.
+
+ If the Library as you received it specifies that a proxy can decide
+whether future versions of the GNU Lesser General Public License shall
+apply, that proxy's public statement of acceptance of any version is
+permanent authorization for you to choose that version for the
+Library.
\ No newline at end of file
diff --git a/MiaoUI/GeometryXML.txt b/MiaoUI/GeometryXML.txt
new file mode 100644
index 0000000..9ff9427
--- /dev/null
+++ b/MiaoUI/GeometryXML.txt
@@ -0,0 +1,32 @@
+通过AddGeometryStyle创建UIStyle时 需要提供的XML格式
+
+每个part部分代表一个控件状态
+例如按钮有4个状态 第一个状态为普通第二为Hover第三为按下第四为禁用状态
+
+可用命令:
+fill_rect - 填充矩形 参数: rc、color
+fill_round - 填充圆角矩形 参数: rc、color、value
+fill_ellipse - 填充椭圆 参数: rc、color
+draw_rect - 绘制矩形边框 参数: rc、color
+draw_round - 绘制圆角矩形边框 参数: rc、color、value、width
+draw_line - 绘制一条线 参数: rc、color、width
+draw_ellipse - 绘制椭圆边框 参数: rc、color、width
+
+参数介绍:
+rc - 为相对于目标的内边距 left、top、right、bottom
+例如原始目标为 100,100,200,200 rc为2,2,2,2 最终绘制为 102,102,198,198
+可以使用l|t|r|b进行相对计算 例如 原始目标为 100,100,200,200 rc为 2,b2,2,0 最终绘制为 102, 198, 198, 200
+l=left t=top r=right b=bottom
+
+color - 为颜色RGBA值
+value - 为圆角度 float类型
+width - 为线宽度 uint类型
+
+
+
+
+
+
+ ...........
+
+..........
\ No newline at end of file
diff --git a/MiaoUI/MiaoUI.vcxproj b/MiaoUI/MiaoUI.vcxproj
new file mode 100644
index 0000000..6c4dd3d
--- /dev/null
+++ b/MiaoUI/MiaoUI.vcxproj
@@ -0,0 +1,327 @@
+
+
+
+
+
+
+ Debug
+ Win32
+
+
+ Release
+ Win32
+
+
+ Debug
+ x64
+
+
+ Release
+ x64
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 16.0
+ Win32Proj
+ {2f7059f0-b4a9-4e52-a553-eb0667880680}
+ MiaoUI
+ 10.0
+ MiaoUILite
+
+
+
+ StaticLibrary
+ true
+ v143
+ Unicode
+
+
+ StaticLibrary
+ false
+ v143
+ true
+ Unicode
+
+
+ StaticLibrary
+ true
+ v143
+ Unicode
+ true
+
+
+ StaticLibrary
+ false
+ v143
+ true
+ Unicode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ true
+ $(SolutionDir)MiaoUI\library\
+ $(SolutionDir)MiaoUI\Cache\Debug\
+ $(ProjectName)32d
+
+
+ false
+ $(SolutionDir)MiaoUI\library\
+ $(SolutionDir)MiaoUI\Cache\Release\
+ $(ProjectName)32
+
+
+ true
+ $(SolutionDir)MiaoUI\library\
+ $(SolutionDir)MiaoUI\Cache\Debug64\
+ $(ProjectName)64d
+ false
+ false
+
+
+ false
+ $(SolutionDir)MiaoUI\library\
+ $(SolutionDir)MiaoUI\Cache\Release64\
+ $(ProjectName)64
+
+
+
+ Level3
+ true
+ WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)
+ true
+ NotUsing
+
+
+ Default
+ MultiThreadedDebug
+ true
+ $(SolutionDir);$(SolutionDir)MiaoUI\src\include;$(SolutionDir)ThirdParty\libvorbis-1.3.7\include;$(SolutionDir)ThirdParty\libogg-1.3.5\include;$(SolutionDir)ThirdParty\cryptopp8.6;$(SolutionDir)ThirdParty\freetype-2.11.1\include;$(SolutionDir)ThirdParty\glew-2.2.0\include;$(SolutionDir)ThirdParty\ffmpeg-4.2.1\include;$(SolutionDir)ThirdParty\glm-0.9.8
+ stdcpp17
+
+
+
+
+ true
+
+
+ $(SolutionDir)ThirdParty\build\static\;%(AdditionalLibraryDirectories)
+ %(AdditionalDependencies)
+
+
+
+
+ Level3
+ true
+ true
+ true
+ WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)
+ true
+ NotUsing
+
+
+ MultiThreaded
+ Default
+ Fast
+ AnySuitable
+ Speed
+ true
+ true
+ true
+ $(SolutionDir);$(SolutionDir)MiaoUI\src\include;$(SolutionDir)ThirdParty\libvorbis-1.3.7\include;$(SolutionDir)ThirdParty\libogg-1.3.5\include;$(SolutionDir)ThirdParty\cryptopp8.6;$(SolutionDir)ThirdParty\freetype-2.11.1\include;$(SolutionDir)ThirdParty\glew-2.2.0\include;$(SolutionDir)ThirdParty\ffmpeg-4.2.1\include;$(SolutionDir)ThirdParty\glm-0.9.8
+ stdcpp17
+ MaxSpeed
+
+
+
+
+ true
+ true
+ true
+
+
+ $(SolutionDir)ThirdParty\build\static\;%(AdditionalLibraryDirectories)
+ %(AdditionalDependencies)
+
+
+
+
+ Level3
+ true
+ _DEBUG;_LIB;%(PreprocessorDefinitions)
+ true
+ NotUsing
+
+
+ Default
+ true
+ MultiThreadedDebug
+ $(SolutionDir);$(SolutionDir)MiaoUI\src\include;$(SolutionDir)ThirdParty\libvorbis-1.3.7\include;$(SolutionDir)ThirdParty\libogg-1.3.5\include;$(SolutionDir)ThirdParty\cryptopp8.6;$(SolutionDir)ThirdParty\freetype-2.11.1\include;$(SolutionDir)ThirdParty\glew-2.2.0\include;$(SolutionDir)ThirdParty\ffmpeg-4.2.1\include;$(SolutionDir)ThirdParty\glm-0.9.8
+ stdcpp17
+
+
+
+
+ true
+
+
+ $(SolutionDir)ThirdParty\build\static\;%(AdditionalLibraryDirectories)
+ %(AdditionalDependencies)
+
+
+
+
+ Level3
+ true
+ true
+ true
+ NDEBUG;_LIB;%(PreprocessorDefinitions)
+ true
+ NotUsing
+
+
+ MultiThreaded
+ Default
+ Fast
+ AnySuitable
+ Speed
+ true
+ true
+ true
+ $(SolutionDir);$(SolutionDir)MiaoUI\src\include;$(SolutionDir)ThirdParty\libvorbis-1.3.7\include;$(SolutionDir)ThirdParty\libogg-1.3.5\include;$(SolutionDir)ThirdParty\cryptopp8.6;$(SolutionDir)ThirdParty\freetype-2.11.1\include;$(SolutionDir)ThirdParty\glew-2.2.0\include;$(SolutionDir)ThirdParty\ffmpeg-4.2.1\include;$(SolutionDir)ThirdParty\glm-0.9.8
+ stdcpp17
+ MaxSpeed
+
+
+
+
+ true
+ true
+ true
+
+
+ $(SolutionDir)ThirdParty\build\static\;%(AdditionalLibraryDirectories)
+ %(AdditionalDependencies)
+
+
+
+
+
+
+
+
+ 这台计算机上缺少此项目引用的 NuGet 程序包。使用“NuGet 程序包还原”可下载这些程序包。有关更多信息,请参见 http://go.microsoft.com/fwlink/?LinkID=322105。缺少的文件是 {0}。
+
+
+
+
+
+
\ No newline at end of file
diff --git a/MiaoUI/MiaoUI.vcxproj.filters b/MiaoUI/MiaoUI.vcxproj.filters
new file mode 100644
index 0000000..4caabf2
--- /dev/null
+++ b/MiaoUI/MiaoUI.vcxproj.filters
@@ -0,0 +1,322 @@
+
+
+
+
+ {288c03d6-d041-419e-b33d-61295165f800}
+
+
+ {7cac8021-7765-43ec-89c7-c92bcceb64bd}
+
+
+ {ad1c4e68-a2e9-4b9b-8093-10df6432f96c}
+
+
+ {2967b425-5f6c-4215-b212-55d90fb1b6d8}
+
+
+ {590f875b-eb7d-47e8-ad67-318673c74394}
+
+
+ {2003f39a-d6d7-4bd8-ac84-7066ab6788ae}
+
+
+ {8d0e9cba-05b8-49da-bfab-8ff5fcde7393}
+
+
+ {b3027ee6-4d1d-4856-b77c-bec05b7c2332}
+
+
+ {757a08fc-930a-4c10-a193-f3af17ba680b}
+
+
+ {f2960082-167a-4f7b-9f25-5be08746562d}
+
+
+ {d0e525dc-1cee-414c-a619-d8fc13149c01}
+
+
+ {48809cc1-0a69-4c67-9098-5193f695f444}
+
+
+ {33819f89-b778-4c80-aadd-cadfce3a024b}
+
+
+ {4476c774-471d-4a86-8310-cde82d196a1c}
+
+
+ {ff780d99-b91e-4b3d-a3bc-2f53fe0adbc7}
+
+
+ {ba1db83f-ffc6-4734-8da7-1041adcf3d15}
+
+
+ {1d3883b1-aaa8-409c-ab9c-42b0a799ff3f}
+
+
+ {2274f20f-90f1-4a5d-909b-61ed9238fd25}
+
+
+ {7703827d-0cc6-48eb-aa06-42d5136e532d}
+
+
+ {4003d539-05d7-4f64-8a09-625b372a86f8}
+
+
+ {5ebd8140-1bb7-42ba-a3ec-f8e1fa8cc4bf}
+
+
+
+
+ 头文件
+
+
+ 头文件
+
+
+ 头文件
+
+
+ 头文件
+
+
+ 头文件\Control
+
+
+ 头文件\Control
+
+
+ 头文件\Control
+
+
+ 头文件\Control
+
+
+ 头文件\Control
+
+
+ 头文件\Control
+
+
+ 头文件\Control
+
+
+ 头文件\Control
+
+
+ 头文件\Control
+
+
+ 头文件\Control
+
+
+ 头文件\Control
+
+
+ 头文件\FileSystem
+
+
+ 头文件\Render
+
+
+ 头文件\Render\Graphs
+
+
+ 头文件\Render\Graphs
+
+
+ 头文件\Window
+
+
+ 头文件\Window
+
+
+ ThirdParty\pugixml
+
+
+ ThirdParty\pugixml
+
+
+ ThirdParty
+
+
+ ThirdParty
+
+
+ 头文件\Control
+
+
+ 头文件\Control
+
+
+ 头文件\Render\Node
+
+
+ 头文件\Render\Node
+
+
+ 头文件\User
+
+
+ 头文件
+
+
+ 头文件
+
+
+ 头文件\Render\Node
+
+
+ 头文件\Manager
+
+
+ 头文件\Manager
+
+
+ 头文件
+
+
+ 头文件
+
+
+ 头文件
+
+
+ 头文件
+
+
+ 头文件
+
+
+ 头文件
+
+
+ 头文件\FileSystem
+
+
+ 头文件\Render\Graphs
+
+
+ 头文件\Render\Graphs
+
+
+
+
+ 源文件
+
+
+ 源文件
+
+
+ 源文件
+
+
+ 源文件\Control
+
+
+ 源文件\Control
+
+
+ 源文件\Control
+
+
+ 源文件\Control
+
+
+ 源文件\Control
+
+
+ 源文件\Control
+
+
+ 源文件\Control
+
+
+ 源文件\Control
+
+
+ 源文件\Control
+
+
+ 源文件\Control
+
+
+ 源文件\Control
+
+
+ 源文件\FileSystem
+
+
+ 源文件\Window
+
+
+ 源文件\Render\Graphs
+
+
+ 源文件\Render
+
+
+ ThirdParty\pugixml
+
+
+ ThirdParty
+
+
+ 源文件\Window
+
+
+ 源文件\Render\Graphs
+
+
+ 源文件\Control
+
+
+ 源文件\Control
+
+
+ 源文件\Render\Node
+
+
+ 源文件\Render\Node
+
+
+ 源文件\User
+
+
+ 源文件
+
+
+ 源文件\Render\Node
+
+
+ 源文件\Manager
+
+
+ 源文件
+
+
+ 源文件\Manager
+
+
+ 源文件
+
+
+ 源文件\FileSystem
+
+
+ 源文件\Render\Graphs
+
+
+ 源文件\Render\Graphs
+
+
+
+
+
+ ThirdParty\license
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/MiaoUI/MiaoUI.vcxproj.user b/MiaoUI/MiaoUI.vcxproj.user
new file mode 100644
index 0000000..88a5509
--- /dev/null
+++ b/MiaoUI/MiaoUI.vcxproj.user
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
diff --git a/MiaoUI/packages.config b/MiaoUI/packages.config
new file mode 100644
index 0000000..43e1ed2
--- /dev/null
+++ b/MiaoUI/packages.config
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/MiaoUI/src/include/Control/Mui_Button.h b/MiaoUI/src/include/Control/Mui_Button.h
new file mode 100644
index 0000000..7eed9b5
--- /dev/null
+++ b/MiaoUI/src/include/Control/Mui_Button.h
@@ -0,0 +1,85 @@
+/**
+ * FileName: Mui_Button.h
+ * Note: UI按钮控件声明
+ *
+ * Copyright (C) 2020-2024 Maplespe (mapleshr@icloud.com)
+ *
+ * This file is part of MiaoUI library.
+ * MiaoUI library is free software: you can redistribute it and/or modify it under the terms of the
+ * GNU Lesser General Public License as published by the Free Software Foundation, either version 3
+ * of the License, or any later version.
+ *
+ * MiaoUI library 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License along with Foobar.
+ * If not, see .
+ *
+ * date: 2020-10-19 Create
+*/
+
+#pragma once
+#include
+
+namespace Mui::Ctrl
+{
+ /* UIButton 控件
+ * 属性列表:
+ * style (UIStyle*)
+ * animate (bool) - 是否启用动画效果 Lite版本无效
+ * aniAlphaType (bool) - 动画效果方式 混合或覆盖 Lite版本无效
+ * inset (_m_rect_t) - 内边距 仅autoSize=true 时才有效
+ * ...
+ * 还继承UILabel的属性...
+ */
+ class UIButton : public UILabel
+ {
+ public:
+ MCTRL_DEFINE_EX
+ (
+ L"UIButton",
+ MCTRL_MAKE_ATTRIB({ CtrlMgr::AttribType::UIStyle, L"style" }),
+ MCTRL_BASE_ATTRIB(UILabel)
+ );
+
+ struct Attribute
+ {
+ UIStylePtr style = nullptr;
+ bool animate = false; //Lite版本无效
+ bool aniAlphaType = false; //Lite版本无效
+ _m_rect_t inset = { 2,2,2,2 };
+ };
+
+ UIButton(UIControl* parent, Attribute attrib, UILabel::Attribute fontStyle = {});
+
+ void SetAttribute(std::wstring_view attribName, std::wstring_view attrib, bool draw = true) override;
+ std::wstring GetAttribute(std::wstring_view attribName) override;
+
+ template
+ bool SetAttributeSrc(std::wstring_view attribName, T&& value, bool draw = true)
+ {
+ if (!m_attrib.SetAttribute(attribName, std::forward(value), draw))
+ return UILabel::SetAttributeSrc(attribName, std::forward(value), draw);
+ m_cacheUpdate = true;
+ if (draw) UpdateDisplay();
+ return true;
+ }
+ [[nodiscard]] const Attribute& GetAttribute() const;
+
+ protected:
+ explicit UIButton(Attribute attrib, UILabel::Attribute fontStyle = {});
+
+ void OnPaintProc(MPCPaintParam param) override;
+ bool OnMouseMessage(MEventCodeEnum message, _m_param wParam, _m_param lParam) override;
+
+ void ChangeStatus(UIControlStatus&& state, UIControlStatus&& oldState);
+
+ _m_sizef GetContentSize() override;
+
+ private:
+ CtrlMgr::UIAttribute m_attrib;
+
+ UIControlStatus m_state = UIControlStatus_Normal;
+ };
+}
diff --git a/MiaoUI/src/include/Control/Mui_CheckBox.h b/MiaoUI/src/include/Control/Mui_CheckBox.h
new file mode 100644
index 0000000..7984e08
--- /dev/null
+++ b/MiaoUI/src/include/Control/Mui_CheckBox.h
@@ -0,0 +1,104 @@
+/**
+ * FileName: Mui_CheckBox.h
+ * Note: UI选择框控件声明
+ *
+ * Copyright (C) 2020-2024 Maplespe (mapleshr@icloud.com)
+ *
+ * This file is part of MiaoUI library.
+ * MiaoUI library is free software: you can redistribute it and/or modify it under the terms of the
+ * GNU Lesser General Public License as published by the Free Software Foundation, either version 3
+ * of the License, or any later version.
+ *
+ * MiaoUI library 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License along with Foobar.
+ * If not, see .
+ *
+ * date: 2020-11-26 Create
+*/
+
+#pragma once
+#include
+
+namespace Mui::Ctrl
+{
+ /* UICheckBox 控件
+ * 属性列表:
+ * style (UIStyle*)
+ * isSel (bool) - 是否被选中
+ * allowClick (bool) - 是否可通过点击改变选中状态(否则只能手动设置isSel来控制是否选中)
+ * animate (bool) - 是否启用动画效果 Lite版本无效
+ * aniAlphaType (bool) - 动画效果方式 混合或覆盖 Lite版本无效
+ * textOffset (int) - 文本和图标之间的距离
+ * ...
+ * 还继承UILabel的属性...
+ */
+ class UICheckBox : public UILabel
+ {
+ public:
+ MCTRL_DEFINE_EX
+ (
+ L"UICheckBox",
+ MCTRL_MAKE_ATTRIB({ CtrlMgr::AttribType::UIStyle, L"style" }),
+ MCTRL_BASE_ATTRIB(UILabel)
+ );
+
+ struct Attribute
+ {
+ UIStylePtr style = nullptr;
+ bool isSel = false;
+ bool allowClick = true;
+ bool animate = false; //Lite版本无效
+ bool aniAlphaType = false; //Lite版本无效
+ int textOffset = 10;
+ };
+
+ UICheckBox(UIControl* parent, Attribute attrib, UILabel::Attribute fontStyle = {});
+
+ void SetAttribute(std::wstring_view attribName, std::wstring_view attrib, bool draw = true) override;
+ std::wstring GetAttribute(std::wstring_view attribName) override;
+
+ template
+ bool SetAttributeSrc(std::wstring_view attribName, T&& value, bool draw = true)
+ {
+ if (!m_attrib.SetAttribute(attribName, std::forward(value), draw))
+ return UILabel::SetAttributeSrc(attribName, std::forward(value), draw);
+ m_cacheUpdate = true;
+ if (draw) UpdateDisplay();
+ return true;
+ }
+ [[nodiscard]] const Attribute& GetAttribute() const;
+
+ virtual void SetSel(bool sel, bool draw = true);
+ virtual bool GetSel() const;
+
+ protected:
+ explicit UICheckBox(Attribute attrib, UILabel::Attribute fontStyle = {});
+
+ enum Status
+ {
+ UICheckBoxNormal, //普通
+ UICheckBoxHover, //热点
+ UICheckBoxPressed, //按下
+ UICheckBoxDisbale, //禁止
+ UICheckBoxNormalSel, //普通选中
+ UICheckBoxHoverSel, //热点选中
+ UICheckBoxPressedSel, //按下选中
+ UICheckBoxDisbaleSel //禁止选中
+ };
+
+ void OnPaintProc(MPCPaintParam param) override;
+ bool OnMouseMessage(MEventCodeEnum message, _m_param wParam, _m_param lParam) override;
+
+ _m_sizef GetContentSize() override;
+
+ void ChangeStatus(Status&& state, Status&& oldState);
+
+ private:
+ CtrlMgr::UIAttribute m_attrib;
+
+ Status m_state = UICheckBoxNormal;
+ };
+}
diff --git a/MiaoUI/src/include/Control/Mui_ColorPicker.h b/MiaoUI/src/include/Control/Mui_ColorPicker.h
new file mode 100644
index 0000000..095a9c9
--- /dev/null
+++ b/MiaoUI/src/include/Control/Mui_ColorPicker.h
@@ -0,0 +1,88 @@
+/**
+ * FileName: Mui_ColorPicker.h
+ * Note: UI颜色选择器声明
+ *
+ * Copyright (C) 2022-2023 Maplespe (mapleshr@icloud.com)
+ *
+ * This file is part of MiaoUI library.
+ * MiaoUI library is free software: you can redistribute it and/or modify it under the terms of the
+ * GNU Lesser General Public License as published by the Free Software Foundation, either version 3
+ * of the License, or any later version.
+ *
+ * MiaoUI library 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License along with Foobar.
+ * If not, see .
+ *
+ * date: 2022-9-5 Create
+*/
+#pragma once
+#include
+
+namespace Mui::Ctrl
+{
+ /* UIColorPicker 控件
+ * 属性列表:
+ * color 4x - RGBA颜色
+ * hsv 3x - HSV颜色
+ */
+ class UIColorPicker : public UIControl
+ {
+ public:
+ MCTRL_DEFNAME(L"UIColorPicker");
+ MCTRL_DEFSLOT
+ (
+ CtrlMgr::EventSlot<_m_color> changed;//颜色已更改
+ );
+
+ UIColorPicker(UIControl* parent);
+
+ struct HSV
+ {
+ _m_ushort hue = 0;
+ _m_ushort sat = 0;
+ _m_ushort val = 0;
+ };
+
+ void SetAttribute(std::wstring_view attribName, std::wstring_view attrib, bool draw = true) override;
+ std::wstring GetAttribute(std::wstring_view attribName) override;
+
+ void SetHSVColor(HSV hsv, bool draw = true);
+ HSV GetHSVColor();
+
+ void SetRGBAColor(_m_color color, bool draw = true);
+ _m_color GetRGBAColor();
+
+ protected:
+ UIColorPicker() { m_cacheSupport = true; }
+
+ void OnLoadResource(MRenderCmd* render, bool recreate) override;
+
+ void OnPaintProc(MPCPaintParam param) override;
+ bool OnMouseMessage(MEventCodeEnum message, _m_param wParam, _m_param lParam) override;
+ bool OnMouseMove(_m_uint flag, const UIPoint& point) override;
+ bool OnLButtonUp(_m_uint flag, const UIPoint& point) override;
+ bool OnSetCursor(_m_param hCur, _m_param lParam) override;
+
+ private:
+ float m_hue = 359.f;
+ float m_sat = 0.f;
+ float m_val = 0.f;
+
+ float m_hue_old = m_hue;
+
+ _m_color m_rgb = 0;
+ _m_color m_rgb_old = 0;
+ _m_byte m_alpha = 255;
+
+ void UpdateRGB();
+ void UpdateHSV();
+
+ MGradientBrushPtr m_colorBrush = nullptr;
+ MGradientBrushPtr m_bottomBrush = nullptr;
+
+ bool m_down = false;
+ };
+}
diff --git a/MiaoUI/src/include/Control/Mui_ComBox.h b/MiaoUI/src/include/Control/Mui_ComBox.h
new file mode 100644
index 0000000..eb3b6e2
--- /dev/null
+++ b/MiaoUI/src/include/Control/Mui_ComBox.h
@@ -0,0 +1,226 @@
+/**
+ * FileName: Mui_Combox.h
+ * Note: UI组合框控件声明
+ *
+ * Copyright (C) 2021-2023 Maplespe (mapleshr@icloud.com)
+ *
+ * This file is part of MiaoUI library.
+ * MiaoUI library is free software: you can redistribute it and/or modify it under the terms of the
+ * GNU Lesser General Public License as published by the Free Software Foundation, either version 3
+ * of the License, or any later version.
+ *
+ * MiaoUI library 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License along with Foobar.
+ * If not, see .
+ *
+ * date: 2021-4-2 Create
+*/
+
+#pragma once
+#include
+#include
+
+namespace Mui::Ctrl
+{
+ /* UIComBox 控件
+ * 属性列表:
+ * style (UIStyle*)
+ * dropIcon (UIResource*) - 下拉列表图标
+ * dropIconXPos (int) - 下拉列表图标X偏移位置
+ * dropIconAutoPos (bool) - 自动计算下拉列表图标位置
+ * popTop (bool) - 向上弹出菜单
+ * menuHeight (int) - 弹出菜单高度(px)
+ * listShadowBlur (float) - 弹出列表阴影模糊度 默认6.f
+ * listShadowColor (_m_color) 4x - 弹出列表阴影颜色 默认RGBA(0,0,0,50)
+ * listShadowOffset (UIPoint) 2x - 弹出列表阴影偏移位置 x,y 默认 0,5
+ * listShadowExtend (int) - 弹出列表阴影扩展 默认0
+ * 列表属性:
+ * listStyle (UIStyle*) - 列表样式
+ * itemStyle (UIStyle*) - 列表项样式
+ * itemHeight (int) - 列表项高度(px)
+ * lineSpace (int) - 列表行间距(px)
+ * iFontStyle (UIListBox::ItemFont) - 列表项字体默认样式
+ * iFont (std::wstring_view) - 列表项字体默认样式 - 字体名称
+ * iFontSize (_m_ushort) - 列表项字体默认样式 - 字体尺寸 默认12px
+ * iFontBold (bool) - 列表项字体默认样式 - 是否粗体
+ * iFontItalics (bool) - 列表项字体默认样式 - 是否斜体
+ * iFontUnderline (bool) - 列表项字体默认样式 - 是否下划线
+ * iFontStrikeout (bool) - 列表项字体默认样式 - 是否删除线
+ * iFontColor 4x - 列表项字体默认样式 - 字体颜色 默认RGBA(0,0,0,255)
+ * iTextAlign - 列表项字体默认样式 - 文本对齐方式 仅数字 为TextAlignment枚举值 默认LeftTop
+ * iFontCustom (_m_param) - 列表项字体默认样式 - 自定义字体集对象参数
+ * drawOffset (UIPoint) 2x - 列表内容绘制偏移参数(px)
+ * 列表滚动条属性:
+ * styleV (UIStyle*) - 垂直滚动条样式
+ * animate (bool) - 是否启用动画效果
+ * button (bool) - 是否显示滚动条上下调节按钮
+ * dragValueV (int) - 垂直滚动条当前值
+ * barWidth (int) - 滚动条宽度
+ * barMinHeight (int) - 滚动条按钮最小高(宽)度
+ * btnHeight (int) - 滚动条上下调节按钮高度
+ * inset (_m_rect_t) 4x - 内边距
+ * ...
+ * 还继承UILabel的属性...
+ */
+ class UIComBox : public UILabel
+ {
+ //重写列表框事件 用于失去焦点隐藏列表
+ class UIListBoxCom : public UIListBox
+ {
+ public:
+ UIListBoxCom(Attribute attrib, UIScroll::Attribute scrollAttrib = {})
+ : UIListBox(std::move(attrib), std::move(scrollAttrib))
+ {
+ HideNode(true, false);
+ }
+
+ protected:
+ bool OnWindowMessage(MEventCodeEnum code, _m_param wParam, _m_param lParam) override;
+ bool SendEvent(UINotifyEvent event, _m_param param) override;
+
+ friend class UIComBox;
+ UIComBox* combox = nullptr;
+ };
+ public:
+ MCTRL_DEFINE_EX
+ (
+ L"UIComBox",
+ MCTRL_MAKE_ATTRIB
+ (
+ { CtrlMgr::AttribType::UIStyle, L"style" },
+ { CtrlMgr::AttribType::UIStyle, L"listStyle" },
+ { CtrlMgr::AttribType::UIBitmap, L"dropIcon" }
+ ),
+ MCTRL_BASE_ATTRIB(UILabel),
+ MCTRL_BASE_ATTRIB(UIListBox)
+ );
+
+ MCTRL_DEFSLOT
+ (
+ CtrlMgr::EventSlot itemClicked;//项目被左键单击
+ CtrlMgr::EventSlot itemDBClicked;//项目被左键双击
+ CtrlMgr::EventSlot itemChanging;//选中项目即将被更改 设置变量为false则阻止更改
+ CtrlMgr::EventSlot itemChanged;//选中项目已被更改
+ );
+
+ struct Attribute
+ {
+ UIStylePtr style = nullptr;
+ UIBitmapPtr dropIcon = nullptr;
+ int dropIconXPos = 0;
+ bool dropIconAutoPos = true;
+ bool popTop = false;
+ int menuHeight = 300;
+
+ float listShadowBlur = 6.f;
+ _m_color listShadowColor = 0x32000000;
+ UIPoint listShadowOffset = { 0, 6 };
+ int listShadowExtend = 0;
+ };
+
+ UIComBox(UIControl* parent, Attribute attrib, UIListBox::Attribute listAttrib = {},
+ UIScroll::Attribute scrollAttrib = {}, UILabel::Attribute fontStyle = {});
+ ~UIComBox() override;
+
+ void SetAttribute(std::wstring_view attribName, std::wstring_view attrib, bool draw = true) override;
+ std::wstring GetAttribute(std::wstring_view attribName) override;
+
+ template
+ bool SetAttributeSrc(std::wstring_view attribName, T&& value, bool draw = true)
+ {
+ if (!m_attrib.SetAttribute(attribName, std::forward(value), this))
+ {
+ if (!UILabel::SetAttributeSrc(attribName, std::forward(value), draw))
+ return m_popList->SetAttributeSrc(attribName, std::forward(value), draw);
+ return true;
+ }
+ m_cacheUpdate = true;
+ if (draw) UpdateDisplay();
+ return true;
+ }
+ [[nodiscard]] const Attribute& GetAttribute() const;
+
+ /*添加一个列表项目
+ * @param item - 自定义列表项目
+ * @param index - 列表位置 -1=尾部
+ * @param draw - 是否立即绘制
+ */
+ int AddItem(ListItem* item, int index, bool draw = true);
+
+ /*获取一个列表项目指针
+ * @param index - 列表索引 -1=尾部
+ *
+ * @return 成功返回列表指针 失败返回nullptr
+ */
+ ListItem* GetItem(int index) const;
+
+ /*设置当前选中的列表项目
+ * @param index - 索引项目 -1=不选中
+ * @param draw - 是否立即绘制
+ *
+ * @return 是否成功 若失败则索引值无效
+ */
+ bool SetCurSelItem(int index, bool draw = true);
+
+ //获取当前选中的列表项目索引 -1=未选中
+ int GetCurSelItem() const;
+
+ //获取列表项目总数
+ int GetItemListCount() const;
+
+ /*删除一个列表项目 这不会删除ListItem的内存
+ * @param index - 列表索引 -1=尾部
+ * @param draw - 是否立即绘制
+ *
+ * @return 当前列表项目总数
+ */
+ int DeleteItem(int index, bool draw = true);
+
+ /*删除一个列表项目
+ * @param index - 列表索引 -1=尾部
+ * @param delItem - 是否删除列表内存 使用delete
+ * @param draw - 是否立即绘制
+ *
+ * @return 当前列表项目总数
+ */
+ int DeleteItem(int index, bool delItem, bool draw = true);
+
+ /*删除所有列表项
+ * @param delItem - 是否删除列表内存
+ * @param draw - 是否立即绘制
+ */
+ void DeleteAllItem(bool delItem = true, bool draw = true);
+
+ protected:
+ explicit UIComBox(Attribute attrib, UIListBox::Attribute listAttrib = {},
+ UIScroll::Attribute scrollAttrib = {}, UILabel::Attribute fontStyle = {});
+
+ void OnPaintProc(MPCPaintParam param) override;
+ bool OnMouseMessage(MEventCodeEnum message, _m_param wParam, _m_param lParam) override;
+ bool OnWindowMessage(MEventCodeEnum code, _m_param wParam, _m_param lParam) override;
+ void OnScale(_m_scale scale) override;
+ void OnLayoutCalced() override;
+
+ private:
+ void ShowMenu(bool show);
+ void CalcMenuFrame();
+ void SetText(std::wstring_view text);
+ bool IsListAttrib(std::wstring_view name);
+
+ CtrlMgr::UIAttribute m_attrib;
+
+ static void BindAttribute();
+
+ bool m_isHover = false;
+
+ UIControl* m_root = nullptr;
+ UIListBoxCom* m_popList = nullptr;
+
+ UIControlStatus m_state = UIControlStatus_Normal;
+
+ friend class UIListBoxCom;
+ };
+}
diff --git a/MiaoUI/src/include/Control/Mui_Control.h b/MiaoUI/src/include/Control/Mui_Control.h
new file mode 100644
index 0000000..61866eb
--- /dev/null
+++ b/MiaoUI/src/include/Control/Mui_Control.h
@@ -0,0 +1,192 @@
+/**
+ * FileName: Mui_Control.h
+ * Note: UI控件基本类型声明
+ *
+ * Copyright (C) 2020-2024 Maplespe (mapleshr@icloud.com)
+ *
+ * This file is part of MiaoUI library.
+ * MiaoUI library is free software: you can redistribute it and/or modify it under the terms of the
+ * GNU Lesser General Public License as published by the Free Software Foundation, either version 3
+ * of the License, or any later version.
+ *
+ * MiaoUI library 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License along with Foobar.
+ * If not, see .
+ *
+ * date: 2020-10-17 Create
+*/
+#pragma once
+#include
+#include
+#include
+#include
+
+namespace Mui::Ctrl
+{
+ using namespace Render;
+
+ class UIControl : public UINodeBase
+ {
+ public:
+ UIControl();
+ ~UIControl() override;
+
+ //控件类名和注册方法
+ static constexpr auto ClassName = L"UIControl";
+ static void Register();
+ virtual std::wstring GetClsName() const { return ClassName; }
+
+ //设置用户参数
+ virtual void SetUserData(_m_param data);
+
+ //获取用户参数
+ [[nodiscard]] virtual _m_param GetUserData() const;
+
+ /*设置控件属性
+ * @param attribName - 属性名
+ * @param attrib - 属性值
+ * @param draw - 立即绘制(默认true)
+ */
+ virtual void SetAttribute(std::wstring_view attribName, std::wstring_view attrib, bool draw = true);
+
+ //获取控件属性
+ virtual std::wstring GetAttribute(std::wstring_view attribName);
+
+ /*设置控件可用性
+ * @param enabled - 可用
+ * @param draw - 立即绘制(默认true)
+ */
+ virtual void SetEnabled(bool enabled, bool draw = true);
+
+ //控件是否可用
+ [[nodiscard]] virtual bool IsEnabled() const;
+
+ //获取父窗口
+ [[nodiscard]] virtual Window::UIWindowBasic* GetParentWin() const;
+
+ template
+ T* FindChildren(const UIString& name) const
+ {
+ return mcast_control(Child(name));
+ }
+
+ //FindChildren
+ [[nodiscard]] UIControl* Child(const UIString& name) const
+ {
+ return mcast_control(UINodeBase::FindChildren(name));
+ }
+
+ template
+ T* Child(const UIString& name) const
+ {
+ return FindChildren(name);
+ }
+
+ void AddChildren(UINodeBase* UINode) override;
+
+ //设置控件焦点状态
+ virtual void SetFocus(bool focus);
+
+ //设置是否可接受焦点
+ virtual void SetEnableFocus(bool enable);
+
+ //设置控件消息穿透 消息向下转发到父窗口
+ virtual void SetMsgFilter(bool filter);
+
+ /*设置控件消息忽略
+ * 该控件将忽略鼠标以及窗口消息 并向下传递
+ * @param ignore - 是否忽略消息
+ * @param child - 是否忽略子控件消息
+ */
+ virtual void SetMsgIgnore(bool ignore, bool child = true);
+
+ /*缩放控件到指定尺寸(使用父窗口缩放比) 会设置Scale
+ * @param width - 目标宽度
+ * @param height - 目标高度
+ * @param child - 等比例缩放子控件
+ */
+ virtual void ScaleControl(_m_uint width, _m_uint height, bool child);
+
+ /*缩放控件到指定比例(使用父窗口缩放比) 会设置Scale
+ * @param scale - 目标缩放比
+ * @param child - 等比例缩放子控件
+ */
+ virtual void ScaleControl(_m_scale scale, bool child);
+
+ protected:
+
+ //设置消息捕获
+ void SetCapture();
+ void ReleaseCapture();
+ bool isCapture();
+
+ //设置计时器
+ MTimers::ID SetTimer(_m_uint uTimeout);
+ void KillTimer(MTimers::ID idTimer);
+
+ virtual UIControl* FindMouseControl(const UIPoint& point);
+
+ //获取窗口顶级控件层
+ UIControl* GetWindowTopCtrl() const;
+ UIControl* GetWindowTopCtrl(Window::UIWindowBasic* wnd) const;
+
+ //设置光标状态
+ virtual void SetCursor(_m_lpcwstr cursor_name);
+
+ //鼠标和窗口消息
+ virtual bool OnMouseMessage(MEventCodeEnum message, _m_param wParam, _m_param lParam);
+ virtual bool OnWindowMessage(MEventCodeEnum code, _m_param wParam, _m_param lParam);
+ //鼠标进入与退出消息
+ virtual bool OnMouseEntered(_m_uint flag, const UIPoint& point);
+ virtual bool OnMouseExited(_m_uint flag, const UIPoint& point);
+ //鼠标左键消息
+ virtual bool OnLButtonDown(_m_uint flag, const UIPoint& point);
+ virtual bool OnLButtonUp(_m_uint flag, const UIPoint& point);
+ virtual bool OnLButtonDoubleClicked(_m_uint flag, const UIPoint& point);
+ //鼠标右键消息
+ virtual bool OnRButtonDown(_m_uint flag, const UIPoint& point);
+ virtual bool OnRButtonUp(_m_uint flag, const UIPoint& point);
+ virtual bool OnRButtonDoubleClicked(_m_uint flag, const UIPoint& point);
+ //鼠标中键消息
+ virtual bool OnMButtonDown(_m_uint flag, const UIPoint& point);
+ virtual bool OnMButtonUp(_m_uint flag, const UIPoint& point);
+ virtual bool OnMButtonDoubleClicked(_m_uint flag, const UIPoint& point);
+ //鼠标滚轮
+ virtual bool OnMouseWheel(_m_uint flag, short delta, const UIPoint& point);
+ //鼠标移动
+ virtual bool OnMouseMove(_m_uint flag, const UIPoint& point);
+ //设置光标
+ virtual bool OnSetCursor(_m_param hCur, _m_param lParam);
+
+ //计时器消息
+ virtual void OnTimer(MTimers::ID idTimer);
+
+ //发送事件
+ virtual bool SendEvent(UINotifyEvent event, _m_param param = 0);
+
+ //获取调试画笔
+ [[nodiscard]] MPenPtr GetDbgFramePen() const;
+
+ //控件数据
+ struct ControlData
+ {
+ _m_param UserData = 0; //用户参数
+ bool Enabled = true; //可用
+ bool ParentEnabled = true; //父控件可用
+ bool MsgFilter = false; //消息穿透
+ bool MsgIgnore = false; //消息忽略 消息将不被处理 控件不会被命中
+ bool MsgIgnoreChild = false;//忽略子控件消息
+ bool IsFocus = true; //是否接受焦点
+ } m_data;
+
+ private:
+ //派发消息
+ bool DispatchMouseMessage(MEventCodeEnum code, _m_param wParam, _m_param lParam);
+ bool DispatchWindowMessage(MEventCodeEnum code, _m_param wParam, _m_param lParam);
+
+ friend class Window::UIWindowBasic;
+ };
+}
diff --git a/MiaoUI/src/include/Control/Mui_EditBox.h b/MiaoUI/src/include/Control/Mui_EditBox.h
new file mode 100644
index 0000000..5399ee5
--- /dev/null
+++ b/MiaoUI/src/include/Control/Mui_EditBox.h
@@ -0,0 +1,530 @@
+/**
+ * FileName: Mui_EditBox.h
+ * Note: UI编辑框控件声明
+ *
+ * Copyright (C) 2020-2024 Maplespe (mapleshr@icloud.com)
+ *
+ * This file is part of MiaoUI library.
+ * MiaoUI library is free software: you can redistribute it and/or modify it under the terms of the
+ * GNU Lesser General Public License as published by the Free Software Foundation, either version 3
+ * of the License, or any later version.
+ *
+ * MiaoUI library 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License along with Foobar.
+ * If not, see .
+ *
+ * date: 2020-10-28 Create
+*/
+
+#pragma once
+#include
+#include
+
+#ifdef _WIN32
+
+#include
+#include
+#include
+#include
+#pragma comment(lib, "imm32.lib")
+#elif __ANDROID__
+#include
+#endif // _WIN32
+
+namespace Mui::Ctrl
+{
+
+#ifndef UIEDITATTRIB
+#define UIEDITATTRIB struct Attribute { \
+ UIStylePtr style; \
+ UILabel::Attribute fontStyle; \
+ bool multiline = false; \
+ bool password = false; \
+ wchar_t passChar = L'*'; \
+ bool readOnly = false; \
+ bool isRich = false; \
+ bool wordWrap = false; \
+ bool wordAutoSel = false; \
+ bool number = false; \
+ bool scroll = false; \
+ bool autoBar = true; \
+ \
+ int limitText = 0x7fffffff; \
+ _m_word editAlign = 0; \
+ _m_color caretColor = 0xff000000;\
+ \
+ UIString pholderText; \
+ _m_color pholderTextColor = 0xFF606060;\
+ }
+#endif
+
+ /* UIEditBox 控件
+ * 属性列表:
+ * style (UIStyle*)
+ * fontStyle (UILabel::Attribute*) - 字体样式
+ * text (std::wstring_view) - 当前文本
+ * multiline (bool) - 是否为多行编辑框
+ * password (bool) - 是否为密码输入模式
+ * passChar (wchar_t) - 密码遮掩符
+ * readOnly (bool) - 是否为只读模式
+ * isRich (bool) - 是否为富文本模式
+ * wordWrap (bool) - 是否自动折行
+ * wordAutoSel (bool) - 是否自动选择文本
+ * number (bool) - 是否为数字输入模式
+ * scroll (bool) - 是否有滚动条
+ * autoBar (bool) - 自动显示滚动条
+ * limitText (int) - 最大可输入文本数
+ * editAlign (_m_word) - 编辑框布局样式 ES_XXX
+ * caretColor (_m_color) - 指针颜色
+ * pholderText (std::wstring_view) - 占位符文本
+ * pholderTextColor (_m_color) - 占位符文本颜色
+ * ...
+ * 还继承UIScroll的属性...
+ */
+#ifdef _WIN32
+ class UIEditBox : public UIScroll
+ {
+ public:
+ MCTRL_DEFINE_EX
+ (
+ L"UIEditBox",
+ MCTRL_MAKE_ATTRIB
+ (
+ { CtrlMgr::AttribType::UIStyle, L"style" },
+ { CtrlMgr::AttribType::labelStyle, L"fontStyle" }
+ ),
+ MCTRL_BASE_ATTRIB(UIScroll)
+ );
+
+ MCTRL_DEFSLOT
+ (
+ CtrlMgr::EventSlot textChanged;//文本已被更改
+ );
+
+ UIEDITATTRIB;
+
+ UIEditBox(UIControl* parent, Attribute attrib, UIScroll::Attribute scrollAttrib = {});
+ ~UIEditBox() override;
+
+ void SetAttribute(std::wstring_view attribName, std::wstring_view attrib, bool draw = true) override;
+ std::wstring GetAttribute(std::wstring_view attribName) override;
+
+ template
+ bool SetAttributeSrc(std::wstring_view attribName, T&& value, bool draw = true)
+ {
+ if (!m_attrib.SetAttribute(attribName, std::forward(value), this))
+ return UIScroll::SetAttributeSrc(attribName, std::forward(value), draw);
+ m_cacheUpdate = true;
+ if (draw) UpdateDisplay();
+ return true;
+ }
+ [[nodiscard]] const Attribute& GetAttribute() const;
+
+ //设置选中
+ void SetSel(int first, int second, bool noScroll = false);
+
+ //替换当前所选内容
+ void ReplaceSel(std::wstring_view text, bool canUndo = true);
+
+ //是否自动折行
+ bool GetWordWrap() const;
+
+ //设置是否自动折行
+ void SetWordWrap(bool wrap);
+
+ //是否只读
+ bool GetReadOnly() const;
+
+ //设置只读
+ void SetReadOnly(bool read);
+
+ //获取最大文本长度限制
+ int GetLimitText() const;
+
+ //设置最大文本长度限制
+ void SetLimitText(int lenght);
+
+ //追加文本
+ void AppendText(std::wstring_view text, bool canUndo = true);
+
+ //获取对齐方式
+ _m_word GetEditAlign() const;
+
+ //设置对齐方式
+ void SetEditAlign(_m_word align);
+
+ //是否为富文本模式
+ bool IsRichMode() const;
+
+ //设置是否支持富文本
+ void SetRichMode(bool rich);
+
+ //设置是否支持多行
+ void SetMultiline(bool multiline);
+
+ //设置数字输入模式
+ void SetNumber(bool number);
+
+ //设置默认字体颜色
+ void SetTextColor(_m_color color);
+
+ //设置当前编辑框内容
+ void SetCurText(std::wstring_view text);
+
+ //获取当前内容
+ std::wstring GetCurText() const;
+
+ //获取当前选中内容
+ std::wstring GetCurSelText() const;
+
+ //获取当前内容长度 GETTEXTLENGTHEX flag
+ int GetCurTextLength(_m_ulong flag) const;
+
+ //全选内容
+ void SelAllText();
+
+ //设置当前字体样式
+ void SetFontStyle(const UILabel::Attribute& fontStyle);
+
+ //添加文本 带颜色 需要富文本支持
+ void AddColorText(std::wstring_view text, _m_color color);
+
+ //设置密码输入模式
+ void SetPassword(bool password);
+
+ //设置密码遮掩符
+ void SetPasswordChar(wchar_t ch = '*');
+
+ //重做
+ bool Redo();
+
+ //撤销
+ bool Undo();
+
+ //清空
+ void Clear();
+
+ //复制
+ void Copy() const;
+
+ //剪切
+ void Cut();
+
+ //粘贴
+ void Paste();
+
+ void SetEnabled(bool enable, bool draw = true) override;
+
+ protected:
+ explicit UIEditBox(Attribute attrib, UIScroll::Attribute scrollAttrib = {});
+
+ void OnLoadResource(MRenderCmd* render, bool recreate) override;
+
+ //绘制
+ void OnPaintProc(MPCPaintParam param) override;
+
+ //消息处理
+ bool OnWindowMessage(MEventCodeEnum code, _m_param wParam, _m_param lParam) override;
+ bool OnMouseMessage(MEventCodeEnum message, _m_param wParam, _m_param lParam) override;
+ bool OnSetCursor(_m_param hCur, _m_param lParam) override;
+
+ void OnTimer(_m_ptrv idTimer) override;
+
+ void OnScale(_m_scale scale) override;
+
+ void OnTextChanged(std::wstring str);
+
+ //光标相关
+ void CreateCaret(int cx, int cy);
+ void ShowCaret(bool show);
+ void SetCaretPos(int x, int y);
+ void SetCaretColor(_m_color color, MRenderCmd* render);
+ _m_rect GetCaretRect();
+
+ //滚动条
+ void OnScrollView(UIScroll*, int dragValue, bool horizontal);
+
+ HRESULT TxSendMessage(UINT msg, WPARAM wparam, LPARAM lparam, LRESULT* plresult) const;
+ void TxServices(std::function task);
+
+ class MTextHost : public ITextHost2
+ {
+ friend class UIEditBox;
+ public:
+ virtual ~MTextHost() = default;
+ ITextServices2* GetServices();
+
+ void SetClientRect(UIRect* prc);
+ void SetWordWrap(bool warp);
+ void SetReadOnly(bool read);
+ void SetFont(HFONT hFont);
+ void SetColor(COLORREF color);
+ void LimitText();
+ WORD GetAlign();
+ void SetAlign(WORD align);
+ void SetRichTextFlag(bool rich);
+ void SetPasswordChar(WCHAR chars);
+ void SetMultiline(bool multiline);
+ void SetBarWidth(_m_ushort width);
+ bool IsITextHost2() { return !IsOldVer; }
+
+ //IUnknown
+ HRESULT __stdcall QueryInterface(REFIID riid, void** ppvObject) override;
+ ULONG __stdcall AddRef() override;
+ ULONG __stdcall Release() override;
+
+ //ITextHost
+ HDC TxGetDC() override { return m_editBox->m_oldPaint.PaintDC; }
+ INT TxReleaseDC(HDC hdc) override { return TRUE; }
+ BOOL TxShowScrollBar(INT fnBar, BOOL fShow) override;
+ BOOL TxEnableScrollBar(INT fuSBFlags, INT fuArrowflags) override { return TRUE; }
+ BOOL TxSetScrollRange(INT fnBar, LONG nMinPos, INT nMaxPos, BOOL fRedraw) override;
+ BOOL TxSetScrollPos(INT fnBar, INT nPos, BOOL fRedraw) override;
+ void TxInvalidateRect(LPCRECT prc, BOOL fMode) override;
+ void TxViewChange(BOOL fUpdate) override;
+ BOOL TxCreateCaret(HBITMAP hbmp, INT xWidth, INT yHeight) override;
+ BOOL TxShowCaret(BOOL fShow) override { return TRUE; }
+ BOOL TxSetCaretPos(INT x, INT y) override;
+ BOOL TxSetTimer(UINT idTimer, UINT uTimeout) override { return TRUE; }
+ void TxKillTimer(UINT idTimer) override { }
+ void TxScrollWindowEx(INT dx, INT dy, LPCRECT lprcScroll, LPCRECT lprcClip, HRGN hrgnUpdate, LPRECT lprcUpdate, UINT fuScroll) override {}
+ void TxSetCapture(BOOL fCapture) override;
+ void TxSetFocus() override;
+ void TxSetCursor(HCURSOR hcur, BOOL fText) override;
+ BOOL TxScreenToClient(LPPOINT lppt) override;
+ BOOL TxClientToScreen(LPPOINT lppt) override;
+ HRESULT TxActivate(LONG* plOldState) override { return S_OK; }
+ HRESULT TxDeactivate(LONG lNewState) override { return S_OK; }
+ HRESULT TxGetClientRect(LPRECT prc) override;
+ HRESULT TxGetViewInset(LPRECT prc) override;
+ HRESULT TxGetCharFormat(const CHARFORMATW** ppCF) override;
+ HRESULT TxGetParaFormat(const PARAFORMAT** ppPF) override;
+ COLORREF TxGetSysColor(int nIndex) override;
+ HRESULT TxGetBackStyle(TXTBACKSTYLE* pstyle) override;
+ HRESULT TxGetMaxLength(DWORD* plength) override;
+ HRESULT TxGetScrollBars(DWORD* pdwScrollBar) override;
+ HRESULT TxGetPasswordChar(TCHAR* pch) override;
+ HRESULT TxGetAcceleratorPos(LONG* pcp) override { return S_OK; }
+ HRESULT TxGetExtent(LPSIZEL lpExtent) override;
+
+ HRESULT OnTxCharFormatChange(const CHARFORMATW* pcf) override { return S_OK; }
+ HRESULT OnTxParaFormatChange(const PARAFORMAT* ppf) override { return S_OK; }
+ HRESULT TxGetPropertyBits(DWORD dwMask, DWORD* pdwBits) override;
+ HRESULT TxNotify(DWORD iNotify, void* pv) override { return S_OK; }
+ HIMC TxImmGetContext() override { return nullptr; }
+ void TxImmReleaseContext(HIMC himc) override { }
+ HRESULT TxGetSelectionBarWidth(LONG* lSelBarWidth) override;
+
+ //ITextHost2
+ HRESULT TxDestroyCaret() override { return S_OK; }
+ void TxFreeTextServicesNotification() override { }
+ HRESULT TxGetEastAsianFlags(LONG* pFlags) override { return S_OK; }
+ HRESULT TxGetEditStyle(DWORD dwItem, DWORD* pdwData) override { return S_OK; }
+ HRESULT TxGetHorzExtent(LONG* plHorzExtent) override { return S_OK; }
+ HPALETTE TxGetPalette() override { return nullptr; }
+ HRESULT TxGetWindow(HWND* phwnd) override { return S_OK; }
+ HRESULT TxGetWindowStyles(DWORD* pdwStyle, DWORD* pdwExStyle) override { return S_OK; }
+ BOOL TxIsDoubleClickPending() override { return FALSE; }
+ HCURSOR TxSetCursor2(HCURSOR hcur, BOOL bText) override { return nullptr; }
+ HRESULT TxSetForegroundWindow() override { return S_OK; }
+ HRESULT TxShowDropCaret(BOOL fShow, HDC hdc, LPCRECT prc) override { return S_OK; }
+
+ BOOL Init(UIEditBox* m_pEdit);
+ HRESULT InitDefaultCharFormat(CHARFORMAT2W* pcf, HFONT hFont);
+
+ HMODULE m_hDll = nullptr;
+ LONG m_dwRef = 0;
+
+ ITextServices2* m_services = nullptr;
+ SIZEL m_sizelExtent = { 0,0 };
+ CHARFORMAT2W m_charFormat = {};
+ PARAFORMAT2 m_paraFormat = {};
+
+ UIEditBox* m_editBox = nullptr;
+
+ bool IsOldVer = false;
+ };
+
+ MTextHost* m_txtHost = nullptr;
+
+ void TextHost(std::function task) const;
+
+ friend class MTextHost;
+
+ UIRect GetInsetFrame(UIRect src);
+
+ struct OldPaintData
+ {
+ UISize bufferSize;
+ HBITMAP PaintBMP;
+ HDC PaintDC;
+ } m_oldPaint;
+ void GDIPaint(MRenderCmd* render, MPCRect destRect, MPCRect insetRect, bool cacheCanvas);
+
+ //ITextHost服务
+ void OnInitTextSer();
+
+ std::wstring GetCurTextInternal() const;
+
+ //字体
+ HFONT m_font = nullptr;
+ HFONT GetFont();
+
+ HBRUSH m_ClearBrush = nullptr;
+
+ mutable CtrlMgr::UIAttribute m_attrib;
+
+ static void BindAttribute();
+
+ //光标
+ UISize CaretSize;
+ UIPoint CaretPos;
+ _m_rect CaretRect;
+ _m_color CaretColor = 0xff000000;
+ MBrushPtr CaretBrush = nullptr;
+ bool CaretVisiable = false;
+ MTimers::ID CaretTimer = 0;
+
+ UIControlStatus m_controlState = UIControlStatus_Normal;
+
+ //鼠标是否在滚动条区域
+ bool m_mouseInScroll = false;
+ bool m_mouseDown = false;
+
+ bool m_autoWordSel = false;
+ };
+#endif
+#ifdef __ANDROID__
+ class UIEditBox : public UILabel
+ {
+ public:
+ UIEditBox();
+ UIEditBox(UIControl* parent, UIEditBoxConfig config);
+ virtual ~UIEditBox();
+
+ M_DEF_CTRL(L"UIEditBox");
+
+ void SetProperty(UIEditBoxConfig config, bool draw = true);
+ UIEditBoxConfig GetProperty();
+
+ virtual void SetAttribute(std::wstring attribName, std::wstring attrib, bool draw = true) override;
+ virtual std::wstring GetAttribute(std::wstring attribName) override;
+
+ //设置选中
+ void SetSel(_m_ulong dwSelection, bool bNoScroll = false) { }
+
+ //替换当前所选内容
+ void ReplaceSel(std::wstring text, bool bCanUndo = true) { }
+
+ //是否自动折行
+ bool GetWordWrap() { return m_config.WordWrap; }
+
+ //设置是否自动折行
+ void SetWordWrap(bool fWordWrap) { m_config.WordWrap = fWordWrap; }
+
+ //是否只读
+ bool GetReadOnly() { return m_config.ReadOnly; }
+
+ //设置只读
+ bool SetReadOnly(bool bReadOnly) { return m_config.ReadOnly = bReadOnly; }
+
+ //获取最大文本长度
+ _m_long GetLimitText() { return m_config.LimitText; }
+
+ //设置最大文本长度
+ bool SetLimitText(_m_long nLength) { m_config.LimitText = nLength; }
+
+ //追加文本
+ void AppendText(std::wstring text, bool bCanUndo = true);
+
+ //获取对齐方式
+ _m_word GetDefaultAlign() { return m_align; }
+
+ //设置对齐方式
+ void SetDefaultAlign(_m_word wNewAlign);
+
+ //是否为富文本模式
+ bool GetRichTextFlag() { return false; }
+
+ //设置是否支持富文本
+ void SetRichTextFlag(bool fRich) { m_config.IsRich = fRich; }
+
+ //设置默认字体颜色
+ _m_color SetDefaultTextColor(_m_color cr);
+
+ //设置当前编辑框内容
+ void SetCurText(std::wstring text);
+
+ //获取当前内容
+ std::wstring GetCurText() { return m_config.m_textConfig.Text; }
+
+ //获取当前选中内容
+ std::wstring GetCurSelText() { return L""; }
+
+ //获取当前内容长度
+ _m_long GetCurTextLength(_m_ulong flag) { return m_config.m_textConfig.Text.length(); }
+
+ //全选内容
+ void SelAllText() {}
+
+ //设置是否支持多行
+ void SetMultiline(bool multiline);
+
+ //设置数字输入模式
+ void SetNumber(bool number);
+
+ //设置当前字体
+ void SetFontStyle(UILabel::Property fontStyle);
+
+ //添加文本 带颜色
+ void AddColorText(std::wstring text, _m_color color);
+
+ //取滚动条滚动范围
+ int GetScrollShift(bool hBar = false) { return 0; };
+
+ //取滚动条滑块位置
+ int GetScrollDragPos(bool hBar = false) { return 0; };
+
+ //设置滚动条滑块位置
+ void SetScrollDragPos(int pos, bool hBar = false) { };
+
+ //设置密码输入模式
+ void SetPassword(bool password);
+
+ //恢复
+ bool Redo() { return true; }
+
+ //撤销
+ bool Undo() { return true; }
+
+ //清空
+ void Clear() { SetCurText(L""); }
+
+ //复制
+ void Copy() {}
+
+ //剪切
+ void Cut() {}
+
+ //粘贴
+ void Paste() {}
+
+ //绘制
+ virtual void OnPaintProc(MRenderCmd* render, MPCRect clipRect, MPCRect destRect, bool cacheCanvas) override;
+
+ protected:
+ virtual bool OnMouseEntered(_m_uint flag, const UIPoint& point) override;
+ virtual bool OnMouseExited(_m_uint flag, const UIPoint& point) override;
+ virtual bool OnLButtonDown(_m_uint flag, const UIPoint& point) override;
+ virtual bool OnLButtonUp(_m_uint flag, const UIPoint& point) override;
+
+ UIEditBoxConfig m_config;
+ std::wstring m_passStr;
+ _m_word m_align = 0;
+ UIControlStatus m_status = UIControlStatus_Normal;
+ };
+#endif
+}
diff --git a/MiaoUI/src/include/Control/Mui_ImgBox.h b/MiaoUI/src/include/Control/Mui_ImgBox.h
new file mode 100644
index 0000000..7f424b1
--- /dev/null
+++ b/MiaoUI/src/include/Control/Mui_ImgBox.h
@@ -0,0 +1,79 @@
+/**
+ * FileName: Mui_ImgBox.h
+ * Note: UI图片框控件声明
+ *
+ * Copyright (C) 2020-2023 Maplespe (mapleshr@icloud.com)
+ *
+ * This file is part of MiaoUI library.
+ * MiaoUI library is free software: you can redistribute it and/or modify it under the terms of the
+ * GNU Lesser General Public License as published by the Free Software Foundation, either version 3
+ * of the License, or any later version.
+ *
+ * MiaoUI library 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License along with Foobar.
+ * If not, see .
+ *
+ * date: 2020-10-23 Create
+*/
+
+#pragma once
+#include
+
+namespace Mui::Ctrl
+{
+ /* UIButton 控件
+ * 属性列表:
+ * img (UIBitmap*) - 图片
+ * imgStyle (ImgStyle) - 图片样式
+ */
+ class UIImgBox : public UIControl
+ {
+ public:
+ MCTRL_DEFINE
+ (
+ L"UIImgBox",
+ { CtrlMgr::AttribType::UIBitmap, L"img" }
+ );
+
+ UIImgBox(UIControl* parent);
+
+ //图片样式
+ enum ImgStyle
+ {
+ ImageBoxStyle_Zoom, //缩放
+ ImageBoxStyle_Original, //原始尺寸
+ ImageBoxStyle_Center, //居中
+ ImageBoxStyle_ZoomFill //缩放并填充
+ };
+
+ //取图像尺寸
+ UISize GetImageSize() const;
+
+ //设置图像
+ void SetImage(UIBitmapPtr img, bool lowQuality = false, bool draw = true);
+
+ //设置图像呈现样式
+ void SetImageStyle(ImgStyle style, bool draw = true);
+
+ //设置图像质量
+ void SetQuality(bool lowQuality, bool draw = true);
+
+ void SetAttribute(std::wstring_view attribName, std::wstring_view attrib, bool draw = true) override;
+ std::wstring GetAttribute(std::wstring_view attribName) override;
+
+ protected:
+ UIImgBox() { m_cacheSupport = true; }
+
+ void OnPaintProc(MPCPaintParam param) override;
+
+ _m_sizef GetContentSize() override;
+
+ ImgStyle m_style = ImageBoxStyle_Zoom;
+ UIBitmapPtr m_image = nullptr;
+ bool m_isLowQuality = false;
+ };
+
+}
diff --git a/MiaoUI/src/include/Control/Mui_Label.h b/MiaoUI/src/include/Control/Mui_Label.h
new file mode 100644
index 0000000..329dc61
--- /dev/null
+++ b/MiaoUI/src/include/Control/Mui_Label.h
@@ -0,0 +1,134 @@
+/**
+ * FileName: Mui_Label.h
+ * Note: UI标签控件声明
+ *
+ * Copyright (C) 2020-2024 Maplespe (mapleshr@icloud.com)
+ *
+ * This file is part of MiaoUI library.
+ * MiaoUI library is free software: you can redistribute it and/or modify it under the terms of the
+ * GNU Lesser General Public License as published by the Free Software Foundation, either version 3
+ * of the License, or any later version.
+ *
+ * MiaoUI library 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License along with Foobar.
+ * If not, see .
+ *
+ * date: 2020-10-23 Create
+*/
+
+#pragma once
+#include
+
+namespace Mui::Ctrl
+{
+ /* UI标签控件
+ * 属性列表:
+ * fontStyle
+ * text (std::wstring_view) - 文本
+ * font (std::wstring_view) - 字体名称
+ * fontSize (_m_ushort) - 字体尺寸 默认12px
+ * fontBold (bool) - 是否粗体
+ * fontItalics (bool) - 是否斜体
+ * fontUnderline (bool) - 是否下划线
+ * fontStrikeout (bool) - 是否删除线
+ * fontColor 4x - 字体颜色 默认RGBA(0,0,0,255)
+ * hyperlink (bool) - 是否为超链接
+ * url (std::wstring_view) - 超链接网址
+ * urlColor 4x - 超链接热点颜色 默认RGBA(167,226,54,255)
+ * textAlign - 文本对齐方式 仅数字 为TextAlignment枚举值 默认LeftTop
+ * fontCustom (_m_ptrv) - 自定义字体集对象参数 Lite版本无效
+ * shadowUse (bool) - 使用文本阴影效果
+ * shadowBlur (float) - 文本阴影模糊度 默认1.f
+ * shadowColor (_m_color) 4x - 文本阴影颜色 默认RGBA(0,0,0,255)
+ * shadowOffset (UIPoint) 2x - 文本阴影偏移位置 x,y 默认 1,1
+ * shadowLow (bool) - 是否使用低质量阴影 如果为true=没有模糊效果 blur属性无效
+ */
+ class UILabel : public UIControl
+ {
+ public:
+ MCTRL_DEFINE
+ (
+ L"UILabel",
+ { CtrlMgr::AttribType::labelStyle, L"fontStyle" }
+ );
+ MCTRL_DEFSLOT
+ (
+ CtrlMgr::EventSlot clicked;//鼠标左键单击
+ );
+
+ struct Attribute
+ {
+ UIString text;
+ UIString font = M_DEF_SYSTEM_FONTNAME;
+ UIString url;
+
+ _m_color fontColor = Color::M_Black;
+ _m_color urlColor = 0xffa7e236;
+ _m_color shadowColor = Color::M_Black;
+
+ _m_ushort fontSize = 12;
+ _m_ptrv fontCustom = 0;
+
+ bool hyperlink = false;
+ bool shadowUse = false;
+ bool shadowLow = false;
+
+ float shadowBlur = 1.f;
+
+ UIPoint shadowOffset = { 1,1 };
+ UIFontStyle fontStyle;
+ TextAlign textAlign = TextAlign_Top;
+ };
+
+ UILabel(UIControl* parent, Attribute attrib);
+
+ void SetAttribute(std::wstring_view attribName, std::wstring_view attrib, bool draw = true) override;
+ std::wstring GetAttribute(std::wstring_view attribName) override;
+
+ template
+ bool SetAttributeSrc(std::wstring_view attribName, T&& value, bool draw = true)
+ {
+ return m_attrib.SetAttribute(attribName, std::forward(value), { this, draw });
+ }
+ [[nodiscard]] const Attribute& GetAttribute() const { return m_attrib.Get(); }
+
+ //取文本尺寸
+ [[nodiscard]] UISize GetTextMetric(bool dpi = true) const;
+
+ protected:
+ explicit UILabel(Attribute attrib);
+
+ UISize CalcSize();
+
+ void OnLoadResource(MRenderCmd* render, bool recreate) override;
+
+ void OnPaintProc(MPCPaintParam param) override;
+
+ bool OnMouseMessage(MEventCodeEnum message, _m_param wParam, _m_param lParam) override;
+
+ bool OnSetCursor(_m_param hCur, _m_param lParam) override;
+
+ void OnScale(_m_scale scale) override;
+
+ _m_sizef GetContentSize() override;
+
+ //偏移绘制
+ bool OffsetDraw = false;
+ _m_rect OffsetDrawRc = { 0,0,0,0 };
+
+ MFontPtr m_font = nullptr;
+ MBrushPtr m_brush = nullptr;
+ MEffectPtr m_effect = nullptr;
+
+ bool m_mouseIn = false;
+ bool m_isClick = false;
+
+ CtrlMgr::UIAttribute> m_attrib;
+ static void BindAttribute();
+ void updateStyle(UIFontStyle& style);
+ bool updateRender(bool draw, bool layout = false);
+ };
+}
diff --git a/MiaoUI/src/include/Control/Mui_ListBox.h b/MiaoUI/src/include/Control/Mui_ListBox.h
new file mode 100644
index 0000000..a5e82a5
--- /dev/null
+++ b/MiaoUI/src/include/Control/Mui_ListBox.h
@@ -0,0 +1,303 @@
+/**
+ * FileName: Mui_ListBox.h
+ * Note: UI列表框控件声明
+ *
+ * Copyright (C) 2020-2024 Maplespe (mapleshr@icloud.com)
+ *
+ * This file is part of MiaoUI library.
+ * MiaoUI library is free software: you can redistribute it and/or modify it under the terms of the
+ * GNU Lesser General Public License as published by the Free Software Foundation, either version 3
+ * of the License, or any later version.
+ *
+ * MiaoUI library 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License along with Foobar.
+ * If not, see .
+ *
+ * date: 2020-11-28 Create
+*/
+#pragma once
+#include
+
+namespace Mui::Ctrl
+{
+ class UIListBox;
+
+ class ListItem
+ {
+ public:
+ ListItem() = default;
+ ListItem(std::wstring_view title, _m_color color = 0, UIFontStyle style = {});
+
+ virtual ~ListItem();
+
+ virtual void SetText(std::wstring_view text, _m_color color = 0, UIFontStyle style = {}, bool updateStyle = false);
+
+ virtual void SetFontSize(_m_uint size);
+
+ virtual std::wstring_view GetText();
+
+ protected:
+ enum ItemStatus
+ {
+ UIListItemNormal, //普通
+ UIListItemHover, //热点
+ UIListItemPressed, //按下
+ UIListItemDisbale, //禁止
+ UIListItemNormalSel, //普通选中
+ UIListItemHoverSel, //热点选中
+ UIListItemPressedSel, //按下选中
+ UIListItemDisbaleSel //禁止选中
+ };
+
+ struct PaintParam
+ {
+ MRenderCmd* render = nullptr;
+ MPCRect dstRect = nullptr;
+ UIStyle* style = nullptr;
+ _m_byte dstAlpha = 0;
+ _m_rcscale dstScale;
+ UIPoint offset;
+ _m_color defcolor = 0;
+ };
+
+ virtual void OnPaintProc(const PaintParam* param);
+
+ virtual void PaintStyle(MRenderCmd* render, UIStyle* style, _m_rect frame,
+ ItemStatus state, _m_byte alpha, _m_scale scale = { 1.f, 1.f });
+
+ virtual bool OnMouseMessage(_m_uint message, _m_param wParam, _m_param lParam);
+
+ bool IsSel();
+
+ UIListBox* m_parent = nullptr;
+ ItemStatus m_state = UIListItemNormal;
+
+ bool m_isClick = false;
+
+ UIString m_text;
+ UIFontStyle m_style;
+ _m_uint m_size = 12;
+ _m_color m_color = 0;
+
+ friend class UIListBox;
+ };
+
+ /* UIListBox 控件
+ * 属性列表:
+ * style (UIStyle*)
+ * itemStyle (UIStyle*) - 列表项样式
+ * itemHeight (int) - 列表项高度(px)
+ * lineSpace (int) - 列表行间距(px)
+ * iFontStyle (UIListBox::ItemFont*) - 列表项字体默认样式
+ * iFont (std::wstring_view) - 列表项字体默认样式 - 字体名称
+ * iFontSize (_m_ushort) - 列表项字体默认样式 - 字体尺寸 默认12px
+ * iFontBold (bool) - 列表项字体默认样式 - 是否粗体
+ * iFontItalics (bool) - 列表项字体默认样式 - 是否斜体
+ * iFontUnderline (bool) - 列表项字体默认样式 - 是否下划线
+ * iFontStrikeout (bool) - 列表项字体默认样式 - 是否删除线
+ * iFontColor 4x - 列表项字体默认样式 - 字体颜色 默认RGBA(0,0,0,255)
+ * iTextAlign - 列表项字体默认样式 - 文本对齐方式 仅数字 为TextAlign枚举值 默认LeftTop
+ * iFontCustom (_m_param) - 列表项字体默认样式 - 自定义字体集对象参数
+ * drawOffset (UIPoint) 2x - 列表内容绘制偏移参数(px)
+ * allowRightSel (bool) - 允许右键点击也能选中列表项目
+ * ...
+ * 还继承UIScroll的属性...
+ */
+ class UIListBox : public UIScroll
+ {
+ public:
+ MCTRL_DEFINE_EX
+ (
+ L"UIListBox",
+ MCTRL_MAKE_ATTRIB
+ (
+ { CtrlMgr::AttribType::UIStyle, L"style" },
+ { CtrlMgr::AttribType::UIStyle, L"itemStyle" },
+ { CtrlMgr::AttribType::listfontStyle, L"iFontStyle" }
+ ),
+ MCTRL_BASE_ATTRIB(UIScroll)
+ );
+
+ MCTRL_DEFSLOT
+ (
+ CtrlMgr::EventSlot itemClicked;//项目被左键单击
+ CtrlMgr::EventSlot itemDBClicked;//项目被左键双击
+ CtrlMgr::EventSlot itemChanging;//选中项目即将被更改 设置变量为false则阻止更改
+ CtrlMgr::EventSlot itemChanged;//选中项目已被更改
+ );
+
+ struct ItemFont
+ {
+ UIString font = M_DEF_SYSTEM_FONTNAME;
+
+ _m_color fontColor = 0xff000000;
+
+ _m_ushort fontSize = 12;
+ _m_ptrv fontCustom = 0;
+
+ UIFontStyle fontStyle;
+ TextAlign textAlign = TextAlign_Top;
+ };
+
+ struct Attribute
+ {
+ UIStylePtr style = nullptr;
+ UIStylePtr itemStyle = nullptr;
+
+ int itemHeight = 30;
+ int lineSpace = 0;
+ bool allowRightSel = false;
+
+ UIPoint drawOffset;
+
+ ItemFont fontStyle;
+ };
+
+ UIListBox(UIControl* parent, Attribute attrib, UIScroll::Attribute scrollAttrib = {});
+ ~UIListBox() override;
+
+ void SetAttribute(std::wstring_view attribName, std::wstring_view attrib, bool draw = true) override;
+ std::wstring GetAttribute(std::wstring_view attribName) override;
+
+ template
+ bool SetAttributeSrc(std::wstring_view attribName, T&& value, bool draw = true)
+ {
+ if (!m_attrib.SetAttribute(attribName, std::forward(value), this))
+ return UIScroll::SetAttributeSrc(attribName, std::forward(value), draw);
+ m_cacheUpdate = true;
+ if (draw) UpdateDisplay();
+ return true;
+ }
+ [[nodiscard]] const Attribute& GetAttribute() const;
+
+ /*添加一个列表项目
+ * @param item - 自定义列表项目
+ * @param index - 列表位置 -1=尾部
+ * @param draw - 是否立即绘制
+ *
+ * @return 返回item总数
+ * @exception MErrorCode::IndexOutOfRange
+ */
+ int AddItem(ListItem* item, int index, bool draw = true);
+
+ /*获取一个列表项目指针
+ * @param index - 列表索引 -1=尾部
+ *
+ * @return 成功返回列表指针 失败返回nullptr
+ */
+ [[nodiscard]] ListItem* GetItem(int index) const;
+
+ /*设置当前选中的列表项目
+ * @param index - 索引项目 -1=不选中
+ * @param draw - 是否立即绘制
+ *
+ * @return 是否成功 若失败则索引值无效
+ */
+ bool SetCurSelItem(int index, bool draw = true);
+
+ //获取当前选中的列表项目索引 -1=未选中
+ [[nodiscard]] int GetCurSelItem() const;
+
+ //获取列表项目总数
+ [[nodiscard]] int GetItemListCount() const;
+
+ /*删除一个列表项目 这不会删除ListItem的内存
+ * @param index - 列表索引 -1=尾部
+ * @param draw - 是否立即绘制
+ *
+ * @return 当前列表项目总数
+ * @exception MErrorCode::IndexOutOfRange
+ */
+ int DeleteItem(int index, bool draw = true);
+
+ /*删除一个列表项目
+ * @param index - 列表索引 -1=尾部
+ * @param delItem - 是否删除列表内存 使用delete
+ * @param draw - 是否立即绘制
+ *
+ * @return 当前列表项目总数
+ * @exception MErrorCode::IndexOutOfRange
+ */
+ int DeleteItem(int index, bool delItem, bool draw = true);
+
+ /*删除所有列表项
+ * @param delItem - 是否删除列表内存 使用delete
+ * @param draw - 是否立即绘制
+ */
+ void DeleteAllItem(bool delItem = true, bool draw = true);
+
+ protected:
+ explicit UIListBox(Attribute attrib, UIScroll::Attribute scrollAttrib = {});
+
+ void OnLoadResource(MRenderCmd* render, bool recreate) override;
+
+ void OnPaintProc(MPCPaintParam param) override;
+
+ bool OnMouseMessage(MEventCodeEnum message, _m_param wParam, _m_param lParam) override;
+
+ void OnScrollView(UIScroll*, int dragValue, bool horizontal);
+
+ bool DispatchItemMsg(UIPoint& point, _m_uint msg, _m_param wParam, _m_param lParam);
+
+ void OnLayoutCalced() override { CalcListView(); }
+
+ //设置视图Top
+ void SetViewTop(int top);
+ //索引检查 防止越界
+ bool IndexCheck(int index) const;
+ //计算当前可视区域
+ void CalcListView();
+ //绘制视图列表
+ void PaintListView(MRenderCmd* render, MPCRect destRect, bool cache);
+ //设置当前选中项目
+ void SetSelItem(ListItem* item, UIPoint pt);
+ //更新索引
+ void UpdateIndex();
+
+ //默认字体和画刷
+ MFontPtr m_fontDef = nullptr;
+ MBrushPtr m_brushDef = nullptr;
+
+ private:
+ CtrlMgr::UIAttribute m_attrib;
+
+ static void BindAttribute();
+
+ void updateStyle(UIFontStyle& style);
+
+ protected:
+ UIControlStatus m_state = UIControlStatus_Normal;
+
+ //项目列表
+ std::vector m_itemList;
+
+ struct ViewData
+ {
+ UIPoint offsetPos;
+ int beginIndex = 0;
+ int indexCount = 0;
+
+ int top = 0;
+ int bottom = 0;
+ int viewHeight = 0;
+ int itemHeight = 0;
+ int lineSpace = 0;
+ UIRect boxRect;
+ _m_rcscale scale;
+ std::vector viewItemRect;
+ } m_view;
+
+ int m_curSelIndex = -1;//当前选中项目索引
+ ListItem* m_hoverIndex = nullptr;//当前焦点项目
+ ListItem* m_curSelItem = nullptr;//当前选中项目
+ UIRect m_curItemRect;
+
+ //模拟触控滑动相关
+ int m_downViewY = 0;
+ friend class ListItem;
+ };
+
+}
diff --git a/MiaoUI/src/include/Control/Mui_NavBar.h b/MiaoUI/src/include/Control/Mui_NavBar.h
new file mode 100644
index 0000000..869901d
--- /dev/null
+++ b/MiaoUI/src/include/Control/Mui_NavBar.h
@@ -0,0 +1,191 @@
+/**
+ * FileName: Mui_NavBar.h
+ * Note: UI导航栏声明
+ *
+ * Copyright (C) 2022-2023 Maplespe (mapleshr@icloud.com)
+ *
+ * This file is part of MiaoUI library.
+ * MiaoUI library is free software: you can redistribute it and/or modify it under the terms of the
+ * GNU Lesser General Public License as published by the Free Software Foundation, either version 3
+ * of the License, or any later version.
+ *
+ * MiaoUI library 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License along with Foobar.
+ * If not, see .
+ *
+ * date: 2022-9-7 Create
+*/
+#pragma once
+#include
+
+namespace Mui::Ctrl
+{
+ /* UINavBar(UINavigationBar) 控件 MiaoUI Core 2.0.6版本
+ * 属性列表:
+ * fontStyle (UILabel::Attribute*) - 字体样式
+ * font (std::wstring_view) - 字体
+ * fontColor (_m_color) 4x - 字体颜色 默认RGBA(120,120,120,255)
+ * fontHoverColor (_m_color) 4x - 字体颜色 Hover状态 默认RGBA(0,0,0,255)
+ * fontPressColor (_m_color) 4x - 字体颜色 按下状态 默认RGBA(150,150,150,255)
+ * fontSize (_m_ushort) - 字体尺寸 默认12px
+ * fontBold (bool) - 是否粗体
+ * fontItalics (bool) - 是否斜体
+ * fontUnderline (bool) - 是否下划线
+ * fontStrikeout (bool) - 是否删除线
+ * fontCustom (_m_ptrv) - 自定义字体集对象参数
+ * shadowUse (bool) - 使用文本阴影效果
+ * shadowBlur (float) - 文本阴影模糊度 默认1.f
+ * shadowColor (_m_color) 4x - 文本阴影颜色 默认RGBA(0,0,0,255)
+ * shadowOffset (UIPoint) 2x - 文本阴影偏移位置 x,y 默认 1,1
+ * shadowLow (bool) - 是否使用低质量阴影 如果为true=没有模糊效果 blur属性无效
+ * itemSpace (int) - item间距
+ * barSpace (int) - 横条和文字间距
+ * barHeight (int) - 横条高度 默认4px
+ * barAnitime (int) - 横条过渡动画时长(ms) 默认300ms
+ * barRound (float) - 横条圆角度 默认1.5f
+ * barColor (_m_color) 4x - 横条颜色
+ */
+ class UINavBar : public UIControl
+ {
+ public:
+ MCTRL_DEFINE
+ (
+ L"UINavBar",
+ { CtrlMgr::AttribType::labelStyle, L"fontStyle" }
+ );
+
+ struct Attribute
+ {
+ UIString font = M_DEF_SYSTEM_FONTNAME;
+ _m_color fontColor = 0xff787878;
+ _m_color fontHoverColor = Color::M_Black;
+ _m_color fontPressColor = 0xff969696;
+ _m_ushort fontSize = 12;
+ UIFontStyle fontStyle;
+ _m_ptrv fontCustom = 0;
+
+ bool shadowUse = false;
+ bool shadowLow = false;
+ float shadowBlur = 1.f;
+ UIPoint shadowOffset = { 1,1 };
+ _m_color shadowColor = Color::M_Black;
+
+ int itemSpace = 10;
+ int barSpace = 5;
+ int barHeight = 4;
+ int barAnitime = 300;
+ float barRound = 1.5f;
+ _m_color barColor = 0xffffb375;
+ };
+
+ UINavBar(UIControl* parent, Attribute attrib);
+
+ void SetAttribute(std::wstring_view attribName, std::wstring_view attrib, bool draw = true) override;
+ std::wstring GetAttribute(std::wstring_view attribName) override;
+
+ template
+ bool SetAttributeSrc(std::wstring_view attribName, T&& value, bool draw = true)
+ {
+ if (m_attrib.SetAttribute(attribName, std::forward(value), this))
+ {
+ m_cacheUpdate = true;
+ if (draw) UpdateDisplay();
+ return true;
+ }
+ return false;
+ }
+ [[nodiscard]] const Attribute& GetAttribute() const { return m_attrib.Get(); }
+
+ void SetFontStyle(UILabel::Attribute& attrib, bool draw = true);
+
+ /*添加一个标题项目
+ * @param title - 标题
+ * @param index - 列表位置 -1=尾部
+ * @param draw - 是否立即绘制
+ *
+ * @return 当前项目总数
+ */
+ int AddItem(std::wstring_view title, int index = -1, bool draw = true);
+
+ //设置项目标题 -1=尾部
+ void SetItemTitle(int index, std::wstring_view title, bool draw = true);
+
+ //获取项目标题 -1=尾部
+ [[nodiscard]] std::wstring GetItemTitle(int index) const;
+
+ /*设置当前选中的列表项目
+ * @param index - 索引项目
+ * @param draw - 是否立即绘制
+ *
+ * @return 是否成功 若失败则索引值无效
+ */
+ bool SetCurSelItem(int index, bool draw = true);
+
+ //获取当前选中的列表项目索引
+ [[nodiscard]] int GetCurSelItem() const;
+
+ //获取列表项目总数
+ [[nodiscard]] int GetItemListCount() const;
+
+ /*删除一个列表项目
+ * @param index - 列表索引 -1=尾部
+ * @param draw - 是否立即绘制
+ *
+ * @return 当前项目总数
+ */
+ int DeleteItem(int index, bool draw = true);
+
+ //删除所有列表项
+ void DeleteAllItem(bool draw = true);
+
+ protected:
+ explicit UINavBar(Attribute attrib);
+
+ void OnLoadResource(MRenderCmd* render, bool recreate) override;
+ void OnPaintProc(MPCPaintParam param) override;
+ bool OnMouseEntered(_m_uint flag, const UIPoint& point) override;
+ bool OnMouseExited(_m_uint flag, const UIPoint& point) override;
+ bool OnLButtonDown(_m_uint flag, const UIPoint& point) override;
+ bool OnLButtonUp(_m_uint flag, const UIPoint& point) override;
+ bool OnMouseMove(_m_uint flag, const UIPoint& point) override;
+
+ void OnScale(_m_scale scale) override;
+ _m_sizef GetContentSize() override;
+ void OnLayoutCalced() override;
+
+ bool IndexCheck(int index) const;
+
+ private:
+ std::pair InitItemRect(std::wstring_view title, int index);
+ void CalcItemRect();
+ bool IsHitItem(const UIPoint& pt);
+
+ CtrlMgr::UIAttribute> m_attrib;
+ static void BindAttribute();
+
+ void updateStyle(UIFontStyle& style);
+ bool updateRender(bool draw, bool layout = false);
+
+ MFontPtr m_font = nullptr;
+ MBrushPtr m_brush = nullptr;
+ MEffectPtr m_effect = nullptr;
+
+ UISize m_size;
+
+ std::vector> m_itemList;
+
+ int m_curSelIndex = 0;
+ int m_curHoverIndex = -1;
+ UIControlStatus m_state = UIControlStatus_Normal;
+
+ bool m_down = false;
+ int m_lastHover = -1;
+
+ protected:
+ int m_baroffset = 0;
+ int m_barwidth = 0;
+ };
+}
\ No newline at end of file
diff --git a/MiaoUI/src/include/Control/Mui_Progress.h b/MiaoUI/src/include/Control/Mui_Progress.h
new file mode 100644
index 0000000..88e91d2
--- /dev/null
+++ b/MiaoUI/src/include/Control/Mui_Progress.h
@@ -0,0 +1,96 @@
+/**
+ * FileName: Mui_Progress.h
+ * Note: UI进度条控件声明
+ *
+ * Copyright (C) 2020-2023 Maplespe (mapleshr@icloud.com)
+ *
+ * This file is part of MiaoUI library.
+ * MiaoUI library is free software: you can redistribute it and/or modify it under the terms of the
+ * GNU Lesser General Public License as published by the Free Software Foundation, either version 3
+ * of the License, or any later version.
+ *
+ * MiaoUI library 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License along with Foobar.
+ * If not, see .
+ *
+ * date: 2020-11-24 Create
+*/
+
+#pragma once
+#include
+
+namespace Mui::Ctrl
+{
+ /* UIProgBar(UIProgressBar) 控件
+ * 属性列表:
+ * style (UIStyle*)
+ * maxValue (int) - 最大值
+ * value (int) - 当前值
+ * vertical (bool) - 是否垂直
+ * leftShow (bool) - 如果非垂直 进度从左往右显示 (默认true)
+ * bottomShow (bool) - 如果非水平 进度从下往上显示 (默认true)
+ */
+ class UIProgressBar : public UIControl
+ {
+ public:
+ MCTRL_DEFINE(L"UIProgBar", { CtrlMgr::AttribType::UIStyle, L"style" });
+
+ struct Attribute
+ {
+ UIStylePtr style = nullptr;
+ int maxValue = 100;
+ int value = 0;
+ bool vertical = false;
+ bool leftShow = true;
+ bool bottomShow = true;
+ };
+
+ UIProgressBar(UIControl* parent, Attribute attrib);
+
+ void SetAttribute(std::wstring_view attribName, std::wstring_view attrib, bool draw = true) override;
+ std::wstring GetAttribute(std::wstring_view attribName) override;
+
+ template
+ bool SetAttributeSrc(std::wstring_view attribName, T&& value, bool draw = true)
+ {
+ if (m_attrib.SetAttribute(attribName, std::forward(value), draw))
+ {
+ m_cacheUpdate = true;
+ if (draw) UpdateDisplay();
+ return true;
+ }
+ return false;
+ }
+ [[nodiscard]] const Attribute& GetAttribute() const { return m_attrib.Get(); }
+
+ //设置最大值
+ void SetMaxValue(int value, bool draw = true);
+ //获取最大值
+ int GetMaxValue() const;
+
+ //设置当前值
+ void SetCurValue(int value, bool draw = true);
+ //获取当前值
+ int GetCurValue() const;
+
+ protected:
+ explicit UIProgressBar(Attribute attrib);
+
+ void OnPaintProc(MPCPaintParam param) override;
+
+ //计算百分比值
+ int Percentage(int value1, int percentValue, int percent);
+ //计算块矩形
+ void CalcDrawRect(MPCRect dest);
+
+ private:
+ CtrlMgr::UIAttribute m_attrib;
+ static void BindAttribute();
+
+ UIRect m_drawRect;
+ };
+
+}
diff --git a/MiaoUI/src/include/Control/Mui_Scroll.h b/MiaoUI/src/include/Control/Mui_Scroll.h
new file mode 100644
index 0000000..ea49e27
--- /dev/null
+++ b/MiaoUI/src/include/Control/Mui_Scroll.h
@@ -0,0 +1,216 @@
+/**
+ * FileName: Mui_Scroll.h
+ * Note: UI滚动条控件声明
+ *
+ * Copyright (C) 2020-2024 Maplespe (mapleshr@icloud.com)
+ *
+ * This file is part of MiaoUI library.
+ * MiaoUI library is free software: you can redistribute it and/or modify it under the terms of the
+ * GNU Lesser General Public License as published by the Free Software Foundation, either version 3
+ * of the License, or any later version.
+ *
+ * MiaoUI library 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License along with Foobar.
+ * If not, see .
+ *
+ * date: 2020-11-15 Create
+*/
+
+#pragma once
+#include
+
+namespace Mui::Ctrl
+{
+ /* UIScroll 控件
+ * 属性列表:
+ * styleV (UIStyle*) - 垂直滚动条样式
+ * styleH (UIStyle*) - 水平滚动条样式
+ * vertical (bool) - 显示垂直滚动条
+ * horizontal (bool) - 显示水平滚动条
+ * active (bool) - 始终显示滚动条(无效)
+ * animate (bool) - 是否启用动画效果 Lite版本无效
+ * button (bool) - 是否显示滚动条上下调节按钮
+ * range (UISize) - 滚动条最大可滚动区域
+ * rangeV (int) - 垂直滚动条最大可滚动区域
+ * rangeH (int) - 水平滚动条最大可滚动区域
+ * dragValue (UISize) - 滚动条当前值
+ * dragValueV (int) - 垂直滚动条当前值
+ * dragValueH (int) - 水平滚动条当前值
+ * barWidth (int) - 滚动条宽度
+ * barMinHeight (int) - 滚动条按钮最小高(宽)度
+ * btnHeight (int) - 滚动条上下调节按钮高度
+ * inset (_m_rect_t) - 内边距
+ */
+ class UIScroll : public UIControl
+ {
+ public:
+ MCTRL_DEFINE
+ (
+ L"UIScroll",
+ { CtrlMgr::AttribType::UIStyle, L"styleV" },
+ { CtrlMgr::AttribType::UIStyle, L"styleH" }
+ );
+
+ /* 回调函数
+ * @param UIScroll* 滚动条控件指针
+ * @param int 滚动条当前值
+ * @param bool 是否为水平滚动条 否则为垂直
+ */
+ using ScrollCallBack = std::function;
+
+ struct Attribute
+ {
+ UIStylePtr styleV = nullptr;
+ UIStylePtr styleH = nullptr;
+
+ ScrollCallBack callback = nullptr;
+
+ bool vertical = false;
+ bool horizontal = false;
+ bool active = true;
+ bool animate = true; //Lite版本无效
+ bool button = true;
+ UISize range;
+ UISize dragValue;
+ int barWidth = 8;
+ int barMinHeight = 20;
+ int btnHeight = 8;
+ _m_rect_t inset = { 0 };
+ };
+
+ UIScroll(UIControl* parent, Attribute attrib);
+
+ void SetAttribute(std::wstring_view attribName, std::wstring_view attrib, bool draw = true) override;
+ std::wstring GetAttribute(std::wstring_view attribName) override;
+
+ template
+ bool SetAttributeSrc(std::wstring_view attribName, T&& value, bool draw = true)
+ {
+ if (m_attrib.SetAttribute(attribName, std::forward(value), this))
+ {
+ m_cacheUpdate = true;
+ if (draw) UpdateDisplay();
+ return true;
+ }
+ return false;
+ }
+ [[nodiscard]] const Attribute& GetAttribute() const { return m_attrib.Get(); }
+
+ /*获取滚动条可拖动范围
+ * @param horizontal - 是否为水平滚动条
+ *
+ * @return 返回指定滚动条值
+ */
+ [[nodiscard]] int GetRange(bool horizontal) const;
+
+ [[nodiscard]] UISize GetRange() const;
+
+ /*设置可滚动范围
+ * @param horizontal - 是否为水平滚动条
+ * @param range - 范围 该值不能小于DragValue
+ * @param draw - 是否立即绘制
+ */
+ void SetRange(bool horizontal, int range, bool draw = true);
+
+ void SetRange(UISize range, bool draw = true);
+
+ /*获取拖拽按钮当前值
+ * @param horizontal - 是否为水平滚动条
+ *
+ * @return 返回指定滚动条值
+ */
+ [[nodiscard]] int GetDragValue(bool horizontal) const;
+
+ [[nodiscard]] UISize GetDragValue() const;
+
+ /*设置拖拽按钮当前值
+ * @param horizontal - 是否为水平滚动条
+ * @param value - 滚动值 0-Range
+ * @param draw - 是否立即绘制
+ */
+ void SetDragValue(bool horizontal, int value, bool draw = true);
+ void SetDragValueNoAni(bool horizontal, int value, bool draw);
+
+ /*计算偏移滚动值,值用于控件的底边和顶边转换
+ * @param horizontal - 是否计算水平滚动条的值
+ * @param dragValue - 要计算的滚动值
+ * @param offset - 要计算的值
+ *
+ * @return 去除offset后的dragValue
+ */
+ int CalcOffsetDragValue(bool horizontal, int dragValue, int offset);
+
+ protected:
+ enum ScrollButtonType
+ {
+ ButtonNull,
+ TopButton,
+ BottomButton,
+ ThumbButton,
+ Track,
+ Intersect
+ };
+
+ explicit UIScroll(Attribute attrib);
+
+ void OnPaintProc(MPCPaintParam param) override;
+
+ bool OnMouseMove(_m_uint flag, const UIPoint& point) override;
+ bool OnMouseExited(_m_uint flag, const UIPoint& point) override;
+ bool OnLButtonDown(_m_uint flag, const UIPoint& point) override;
+ bool OnLButtonUp(_m_uint flag, const UIPoint& point) override;
+ bool OnMouseWheel(_m_uint flag, short delta, const UIPoint& point) override;
+
+ //计算鼠标在哪个部件内
+ ScrollButtonType CalcPointIn(const UIPoint& pt);
+
+ //计算滚动条控件内的各部件矩形
+ void CalcControlRect();
+ //根据DragValue计算拖拽按钮位置
+ void CalcThumbBtnPos(bool horizontal);
+ //根据ThumbButton位置计算DragValue
+ void CalcDragValue(bool horizontal);
+ //绘制部件
+ void PaintControl(MRenderCmd* render, UIStyle* style, UIControlStatus status,
+ ScrollButtonType type, UIRect& drawRect, _m_byte& alpha, _m_scale scale);
+
+ //指定整个控件范围Wheel消息都可以触发滚动条 否则仅限滚动条区域
+ bool m_ALLWheel = false;
+
+ void SetCallback(const ScrollCallBack& callback)
+ {
+ m_attrib.Set().callback = callback;
+ }
+
+ private:
+
+ //获得一个滚动page后的pos
+ int GetScrollPage(bool up, bool horz, float count);
+
+ CtrlMgr::UIAttribute m_attrib;
+
+ static void BindAttribute();
+
+ UISize m_size;
+
+ struct ScrollData
+ {
+ UIRect scrollBtn[2];//滚动调节按钮
+ UIRect thumbButton;//拖拽按钮
+ UIRect track;//轨道
+ };
+
+ UIRect m_intersect;//垂直滚动条与水平滚动条的交汇点
+ ScrollData m_scroll[2];
+
+ UIPoint m_clickPos;
+
+ UIControlStatus m_status = UIControlStatus_Normal;
+ ScrollButtonType m_btnType = ButtonNull;
+ bool m_btnTypeH = false;
+ bool m_isClick = false;
+ };
+}
diff --git a/MiaoUI/src/include/Control/Mui_Slider.h b/MiaoUI/src/include/Control/Mui_Slider.h
new file mode 100644
index 0000000..2cb3194
--- /dev/null
+++ b/MiaoUI/src/include/Control/Mui_Slider.h
@@ -0,0 +1,141 @@
+/**
+ * FileName: Mui_Slider.h
+ * Note: UI滑块条控件声明
+ *
+ * Copyright (C) 2020-2024 Maplespe (mapleshr@icloud.com)
+ *
+ * This file is part of MiaoUI library.
+ * MiaoUI library is free software: you can redistribute it and/or modify it under the terms of the
+ * GNU Lesser General Public License as published by the Free Software Foundation, either version 3
+ * of the License, or any later version.
+ *
+ * MiaoUI library 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License along with Foobar.
+ * If not, see .
+ *
+ * date: 2020-12-20 Create
+*/
+
+#pragma once
+#include
+
+namespace Mui::Ctrl
+{
+ /* UISlider 控件
+ * 属性列表:
+ * style (UIStyle*)
+ * btnStyle (UIStyle*) - 滑块按钮样式
+ * maxValue (int) - 最大值
+ * minValue (int) - 最小值
+ * value (int) - 当前值
+ * vertical (bool) - 是否垂直
+ * leftShow (bool) - 如果非垂直 进度从左往右显示 (默认true)
+ * bottomShow (bool) - 如果非水平 进度从下往上显示 (默认true)
+ * trackInset (_m_rect_t) 4x - 轨道内边距
+ * btnSize (UISize) 2x - 拖拽按钮尺寸 0=自动计算
+ */
+ class UISlider : public UIControl
+ {
+ public:
+ MCTRL_DEFINE
+ (
+ L"UISlider",
+ { CtrlMgr::AttribType::UIStyle, L"style" },
+ { CtrlMgr::AttribType::UIStyle, L"btnStyle" }
+ );
+ MCTRL_DEFSLOT
+ (
+ CtrlMgr::EventSlot valueChanged;//滑块值已更改
+ );
+
+ struct Attribute
+ {
+ UIStylePtr style = nullptr;
+ UIStylePtr btnStyle = nullptr;
+
+ int maxValue = 100;
+ int minValue = 0;
+ int value = 0;
+ bool vertical = false;
+ bool leftShow = true;
+ bool bottomShow = true;
+ _m_rect_t trackInset = { 0 };
+ UISize btnSize;
+ };
+
+ UISlider(UIControl* parent, Attribute attrib);
+
+ void SetAttribute(std::wstring_view attribName, std::wstring_view attrib, bool draw = true) override;
+ std::wstring GetAttribute(std::wstring_view attribName) override;
+
+ template
+ bool SetAttributeSrc(std::wstring_view attribName, T&& value, bool draw = true)
+ {
+ if (m_attrib.SetAttribute(attribName, std::forward(value), draw))
+ {
+ m_cacheUpdate = true;
+ if (draw) UpdateDisplay();
+ return true;
+ }
+ return false;
+ }
+ [[nodiscard]] const Attribute& GetAttribute() const { return m_attrib.Get(); }
+
+ //设置当前值
+ void SetCurValue(int value, bool draw = true);
+ //获取当前值
+ int GetCurValue() const;
+ //设置最大值
+ void SetMaxValue(int max, bool draw = true);
+ //获取最大值
+ int GetMaxValue() const;
+ //设置最小值
+ void SetMinValue(int min, bool draw = true);
+ //获取最小值
+ int GetMinValue() const;
+
+ protected:
+ enum UISliderStatus
+ {
+ UISliderTrackNormal, //轨道背景 普通
+ UISliderTrackDisable = 2, //轨道背景 禁止
+ UISliderBlockNormal = 1, //块前景 普通
+ UISliderBlockDisable = 3, //块前景 禁止
+ UISliderBtnNormal = 0, //拖拽按钮 普通
+ UISliderBtnHover, //拖拽按钮 热点
+ UISliderBtnPressed, //拖拽按钮 按下
+ UISliderBtnDisable //拖拽按钮 禁止
+ };
+
+ explicit UISlider(Attribute attrib);
+
+ void OnPaintProc(MPCPaintParam param) override;
+
+ bool OnMouseMessage(MEventCodeEnum message, _m_param wParam, _m_param lParam) override;
+
+ //计算百分比值
+ int Percentage(int value1, int percentValue, int percent);
+ //计算矩形
+ void CalcDrawRect();
+ //计算值
+ int CalcPtValue(UIPoint pt);
+
+ private:
+ CtrlMgr::UIAttribute m_attrib;
+ static void BindAttribute();
+
+ UISliderStatus btnStatus = UISliderBtnNormal;
+
+ UIRect m_drawRect;
+ UIRect m_drawBtnRect;
+ UIRect m_drawBgRect;
+ bool m_isClick = false;
+ int m_oldValue = 0;
+ UIPoint m_downpos;
+ bool m_hitbtn = false;
+ };
+
+}
diff --git a/MiaoUI/src/include/FileSystem/DreamMoonRes.h b/MiaoUI/src/include/FileSystem/DreamMoonRes.h
new file mode 100644
index 0000000..e7f5994
--- /dev/null
+++ b/MiaoUI/src/include/FileSystem/DreamMoonRes.h
@@ -0,0 +1,204 @@
+/**
+ * FileName: DreamMoonRes.h
+ * Note: 梦月资源类声明
+ *
+ * Copyright (C) 2020-2022 Maplespe (mapleshr@icloud.com)
+ *
+ * This file is part of MiaoUI library.
+ * MiaoUI library is free software: you can redistribute it and/or modify it under the terms of the
+ * GNU Lesser General Public License as published by the Free Software Foundation, either version 3
+ * of the License, or any later version.
+ *
+ * MiaoUI library 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License along with Foobar.
+ * If not, see .
+ *
+ * date: 2020-12-8 Create
+*/
+#pragma once
+#include
+
+#if MUI_CFG_ENABLE_V1DMRES
+
+#define DMResVer L"v1.0.1";
+
+namespace Mui {
+
+ //梦月资源类 资源键类型
+ struct DMResKey
+ {
+ //数据资源
+ UIResource res;
+ //块模式存储
+ bool block = false;
+ //分块尺寸
+ unsigned long blockSize = 0;
+ //文本资源
+ std::wstring resText;
+ };
+
+ //资源类型
+ enum ResType
+ {
+ AllRes,//全部资源
+ DataRes,//数据资源
+ StringRes//字符串资源
+ };
+
+ struct DMEncBlockCallback
+ {
+ std::function callback = nullptr;
+ _m_param param = 0;
+ };
+
+ //梦月资源类
+ //该类仅作为兼容和迁移旧项目使用 由于性能和安全问题 不建议再使用 请使用新的资源管理类DMResFile V2 需要在编译时定义MUI_CFG_ENABLE_V2DMRES
+ class DMResources
+ {
+ public:
+ ~DMResources();
+
+ /*资源读取*/
+
+ /*从文件初始化资源 资源仅初始化一次 多次返回false
+ * @param resfiles dmres文件路径
+ * @param mem 是否使用内存加载模式 内存加载模式支持写入和修改
+ */
+ bool LoadResource(std::wstring resfiles, bool mem = false);
+
+#ifdef _WIN32
+ //从WindowsPE读取资源
+ static UIResource ReadPEResource(DWORD resID, LPCWSTR type);
+
+ //从PE初始化资源 资源仅初始化一次 多次返回false
+ bool LoadResource(_m_ulong resid, _m_lpcwstr restype);
+#endif // _WIN32
+
+ //从内存加载资源文件
+ bool LoadResource(UIResource memres);
+
+ //读取资源数量
+ _m_size GetResourceCount();
+
+ /*读取资源 资源需要使用Release释放
+ * @param resname - 资源名称
+ * @param reskey - 资源秘钥
+ * @param type - 资源类型
+ *
+ * @return 资源数据 如果Type=AllRes那么返回的结构体都有数据 否则仅有数据或文本
+ */
+ DMResKey ReadResource(std::wstring resname, std::wstring reskey, ResType type = AllRes);
+
+ /*读取分块数据资源
+ * @param resname - 资源名称
+ * @param reskey - 资源秘钥
+ * @param offset - 指针偏移位置
+ * @param len - 读取长度
+ * @param out retlen - 返回已读取长度
+ *
+ * @return 资源数据 需要使用Release释放
+ */
+ UIResource ReadResourceBlock(std::wstring resname, std::wstring reskey, _m_uint offset, _m_size len, _m_size* retlen);
+
+ /*读取数据资源尺寸
+ * @param resname - 资源名称
+ * @param type - 资源类型 仅DataRes或StringRes
+ *
+ * @return DataRes为资源字节大小 StringRes为文本长度 AllRes返回0
+ */
+ _m_size ReadResourceSize(std::wstring resname, ResType type);
+
+ /*读取资源块信息
+ * @param resname - 资源名称
+ * @param out - 块尺寸
+ *
+ * @return 资源是否为块模式存储
+ */
+ bool ReadResBlockInfo(std::wstring resname, _m_size* blocksize);
+
+ //枚举资源名称
+ bool EnumResourceName(std::vector& nameList);
+ //获取类名
+ _m_lpcwstr GetResClassName();
+
+ /*资源写入*/
+
+ //新建一个内存资源类 资源仅初始化一次 多次返回false 类名长度不能大于30
+ bool CreateResource(std::wstring classname);
+ //添加一个资源
+ bool AddResource(DMResKey res, std::wstring resname, std::wstring reskey, DMEncBlockCallback callback = DMEncBlockCallback());
+ //重命名一个资源
+ bool RenameResource(std::wstring resname, std::wstring newname);
+ //重命名资源类名
+ void RenameClassName(std::wstring newname);
+ //修改一个资源
+ bool ChangeResource(std::wstring resname, DMResKey newres, std::wstring reskey,
+ ResType type = AllRes, DMEncBlockCallback callback = DMEncBlockCallback());
+ //删除一个资源
+ bool DeleteResource(std::wstring resname);
+ //保存资源文件 将所有更改写入文件
+ bool SaveResource(std::wstring filename);
+
+ //关闭资源文件 成功后可以重新初始化资源
+ bool CloseResource();
+
+ //读取文件
+ UIResource ReadFiles(std::wstring filepath, bool string = false);
+ //写入文件
+ bool WriteFiles(std::wstring filepath, UIResource res);
+
+ private:
+ _m_byte* HexStringToBytes(std::string str);
+ std::string Sha256StringHex(std::wstring str);
+ std::wstring wchar16Towchar32(char16_t * wchar16, _m_uint len);
+ char16_t * wchar32Towchar16(wchar_t * wchar32, _m_uint len);
+ //加密资源
+ UIResource Enciphering(UIResource res, std::wstring key);
+ UIResource EncipheringText(std::wstring text, std::wstring key);
+ //解密资源
+ UIResource Deciphering(UIResource res, std::wstring key);
+ std::wstring DecipheringText(UIResource res, std::wstring key);
+ //编码块资源
+ void EncBlockProc(UIResource res, std::wstring resname, std::wstring key, _m_uint blocksize, UIResource* ret, DMEncBlockCallback callback);
+ UIResource EncBlockResource(UIResource res, std::wstring resname, std::wstring key, _m_uint blocksize, DMEncBlockCallback callback);
+
+ //加载资源列表
+ bool LoadResList(bool file = false);
+
+ //资源头
+ struct DMResHeader
+ {
+ //资源类名
+ std::wstring classname;
+ //资源签名
+ std::wstring ressign;
+ //资源版本号
+ std::wstring resver;
+ //资源数量
+ _m_uint rescount = 0;
+ };
+
+ struct DMResItem
+ {
+ std::wstring resname;//资源名称
+ UIResource res;//被加密过的资源
+ bool block = false;//块资源模式
+ _m_uint blockSize = 0;//块尺寸
+ UIResource text;//被加密过的文本资源
+ std::pair<_m_ulong, _m_uint> resPos;//资源在文件位置的指针
+ std::pair<_m_ulong, _m_uint> strPos;//文本在文件位置的指针
+ };
+
+ std::vector dmResList;
+ DMResHeader m_resheader;
+ UIResource m_resource;
+ FILE* m_files = nullptr;
+
+ std::mutex mx;
+ };
+
+}
+#endif
\ No newline at end of file
diff --git a/MiaoUI/src/include/FileSystem/Mui_FileSystem.h b/MiaoUI/src/include/FileSystem/Mui_FileSystem.h
new file mode 100644
index 0000000..547f73e
--- /dev/null
+++ b/MiaoUI/src/include/FileSystem/Mui_FileSystem.h
@@ -0,0 +1,136 @@
+/**
+ * FileName: Mui_FileSystem.h
+ * Note: 基本文件系统操作
+ *
+ * Copyright (C) 2024 Maplespe (mapleshr@icloud.com)
+ *
+ * This file is part of MiaoUI library.
+ * MiaoUI library is free software: you can redistribute it and/or modify it under the terms of the
+ * GNU Lesser General Public License as published by the Free Software Foundation, either version 3
+ * of the License, or any later version.
+ *
+ * MiaoUI library 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License along with Foobar.
+ * If not, see .
+ *
+ * date: 2024-10-9 Create
+*/
+#pragma once
+#include
+
+namespace Mui::FS
+{
+ namespace UI
+ {
+ struct DlgFilter
+ {
+ //描述信息,扩展名
+ std::wstring description, extension;
+ };
+ /* 打开浏览文件对话框
+ * @param [in] isOpen - 是否为打开文件 否则为保存文件对话框
+ * @param [in] multiple - 是否支持多选文件 保存对话框不支持多选
+ * @param [in] filter - 文件过滤器列表 例如 { L"AllFiles(*.*), L"*.*" },{ L"ImageFiles(*.png;*.jpg)", L"*.png;*.jpg" }
+ * @param [in] parentWndHandle - 父窗口句柄
+ * @param [out] selectedFiles - 返回已选择的文件列表
+ * @param [in] defExtName - 默认文件扩展名
+ *
+ * @return 如果打开对话框失败或者用户关闭对话框 返回false
+ */
+ extern bool MBrowseForFile(bool isOpen, bool multiple, const std::vector& filter,
+ _m_param parentWndHandle, std::vector& selectedFiles, std::wstring_view defExtName = {});
+ }
+
+ //获取当前程序运行所在目录
+ std::wstring MGetCurrentDir();
+
+ /*读取文件
+ * @param filepath - 文件路径
+ * @param string - 是否为字符串类型 如果为true 则结尾长度+1 并添加 '\0'
+ * @return 如果成功返回内存资源 否则为空
+ * @exception MErrorCode::IOError; MErrorCode::OutOfMemory
+ */
+ UIResource MReadFile(std::wstring_view filepath, bool string = false);
+
+ /*写入文件
+ * @param filepath - 文件路径
+ * @param res - 内存数据
+ * @return 返回写入成功的字节数
+ * @exception MErrorCode::IOError;
+ */
+ _m_size MWriteFile(std::wstring_view filepath, UIResource res);
+
+ /*打开文件(64位长度)
+ * @param filepath - 文件路径
+ * @param mode - 打开模式 wb、rb、w、r、a、+
+ * @return C API文件句柄
+ * @exception MErrorCode::IOError;
+ */
+ FILE* MOpenFile(std::wstring_view filepath, const char* mode);
+
+ /*移动文件指针(64位长度)
+ * @param file - 使用OpenFile打开的文件指针
+ * @param offset - 目标位置
+ * @param origin - 移动起点 SEEK_SET、SEEK_CUR、SEEK_END
+ * @exception MErrorCode::IOError; MErrorCode::InvalidParameter
+ */
+ void MSeekFile(FILE* file, _m_long64 offset, int origin = SEEK_SET);
+
+ /*获取路径最后的文件名
+ * @param path - 路径 可以为正斜杠或反斜杠
+ * @return 例如 C:\\Test\\Path\\filename.txt 返回 filename.txt
+ */
+ std::wstring MGetFileName(std::wstring_view path);
+
+ /*枚举目录
+ * @param path - 起始路径
+ * @param [out] dirlist - 返回的目录列表
+ * @param recursive - 递归获取所有子级目录 否则仅获取起始路径下的目录
+ * @exception MErrorCode::STDError; MErrorCode::AccessDenied; MErrorCode::IOError
+ */
+ void MEnumDirectory(std::wstring_view path, std::vector& dirlist, bool recursive = false);
+
+ /*枚举文件
+ * @param path - 起始目录路径
+ * @param filter - 文件过滤器列表 例如 { L".txt", L".png" } 为空{}则输出所有的文件
+ * @param [out] dirlist - 返回的文件路径列表
+ * @param recursive - 递归获取所有子级目录下的文件 否则仅获取起始路径下的文件
+ * @exception MErrorCode::STDError; MErrorCode::AccessDenied; MErrorCode::IOError
+ */
+ void MEnumFiles(std::wstring_view path, const std::vector& filter,
+ std::vector& dirlist, bool recursive = false);
+
+ /*删除文件
+ * @param path - 文件路径
+ * @return 如果删除成功 返回true,文件不存在 返回false
+ * @exception MErrorCode::STDError; MErrorCode::AccessDenied; MErrorCode::IOError
+ */
+ bool MRemoveFile(std::wstring_view path);
+
+ /*删除目录
+ * @param path - 目录路径
+ * @param removeAll - 是否删除非空目录及其子目录的所有的内容
+ * @return 如果删除成功 返回true, 如果目录不存在返回false 如果removeAll=false且目录中有文件 返回false
+ * @exception MErrorCode::STDError; MErrorCode::AccessDenied; MErrorCode::IOError
+ */
+ bool MRemoveDirectory(std::wstring_view path, bool removeAll = false);
+
+ /*检查文件或目录是否存在
+ * @param path - 路径
+ * @param isdir - 是否检查目录
+ * @return 如果文件或目录不存在 返回false
+ * @exception MErrorCode::STDError; MErrorCode::AccessDenied; MErrorCode::IOError
+ */
+ bool MFileExists(std::wstring_view path, bool isdir = false);
+
+ /*创建目录
+ * @param path - 创建路径
+ * @param mult - 是否创建多级目录
+ * @return 如果成功或者目录已存在返回true 如果mult=false 且父目录不存在 返回false
+ * @exception MErrorCode::AccessDenied; MErrorCode::IOError
+ */
+ bool MCreateDirectory(std::wstring_view path, bool mult);
+}
\ No newline at end of file
diff --git a/MiaoUI/src/include/Manager/Mui_ControlMgr.h b/MiaoUI/src/include/Manager/Mui_ControlMgr.h
new file mode 100644
index 0000000..89c7f9e
--- /dev/null
+++ b/MiaoUI/src/include/Manager/Mui_ControlMgr.h
@@ -0,0 +1,601 @@
+/**
+ * FileName: Mui_ControlMgr.h
+ * Note: UI控件管理器声明
+ *
+ * Copyright (C) 2022-2024 Maplespe (mapleshr@icloud.com)
+ *
+ * This file is part of MiaoUI library.
+ * MiaoUI library is free software: you can redistribute it and/or modify it under the terms of the
+ * GNU Lesser General Public License as published by the Free Software Foundation, either version 3
+ * of the License, or any later version.
+ *
+ * MiaoUI library 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License along with Foobar.
+ * If not, see .
+ *
+ * date: 2022-3-8 Create
+*/
+
+#pragma once
+#include
+#include
+#include
+#include
+#include
+#include
+
+/*控件类名和注册方法调用
+ * 用法 在控件类开头使用 定义控件在XML中的名称 和特殊属性:
+ * UICtrlDemo : UILabel
+ * {
+ * public:
+ * //有属性列表的情况:
+ * MCTRL_DEFINE
+ * (
+ * L"UICtrlDemo", //这里是控件类名
+ * //这里是特殊属性列表(AttribType类型)
+ * { CtrlMgr::AttribType::UIStyle, L"style" },
+ * { CtrlMgr::AttribType::UIBitmap, L"icon" },
+ * ....
+ * );
+ *
+ * //无属性列表 直接使用MCTRL_DEFNAME
+ * MCTRL_DEFNAME(L"UICtrlDemo");
+ *
+ * //有属性列表和继承控件的情况:
+ * MCTRL_DEFINE_EX
+ * (
+ * L"UICtrlDemo", //这里是控件类名
+ * //需要使用MCTRL_MAKE_ATTRIB生成属性列表
+ * MCTRL_MAKE_ATTRIB(
+ * { CtrlMgr::AttribType::UIStyle, L"style" },
+ * { CtrlMgr::AttribType::UIBitmap, L"icon" }
+ * ),
+ * //然后是继承的属性
+ * MCTRL_BASE_ATTRIB(UILabel)
+ * ....
+ * );
+ *
+ * //可选 定义事件槽
+ * MCTRL_DEFSLOT
+ (
+ CtrlMgr::EventSlot clicked;//鼠标左键单击
+ ....
+ );
+ * }
+ */
+
+#define MCTRL_ATTRIB _mctrl_attrib_attrib
+
+//获取基类属性列表
+#define MCTRL_BASE_ATTRIB(base) base::MCTRL_ATTRIB
+
+//定义控件Element名称和注册方法
+#define MCTRL_DEFNAME(x) static constexpr auto ClassName = x; \
+virtual std::wstring GetClsName() const override { return ClassName; } \
+static void Register()
+
+//控件特殊属性 CtrlMgr::AttribType
+#define MCTRL_MAKE_ATTRIB(...) Helper::ToArray({__VA_ARGS__})
+
+/*定义控件
+* @param name - 控件在XML中的element名称
+* @param ... 特殊属性列表
+*/
+#define MCTRL_DEFINE(x,...) MCTRL_DEFNAME(x); \
+inline static constexpr std::array MCTRL_ATTRIB = Helper::MergeArrays(MCTRL_MAKE_ATTRIB(__VA_ARGS__))
+
+/*定义控件
+* @param name - 控件在XML中的element名称
+* @param attrib - 特殊属性列表 使用MCTRL_MAKE_ATTRIB生成
+* @param ... 继承的控件属性列表
+*/
+#define MCTRL_DEFINE_EX(x,attrib,...) MCTRL_DEFNAME(x); \
+inline static constexpr std::array MCTRL_ATTRIB = Helper::MergeArrays(attrib, __VA_ARGS__)
+
+#define mslot mctrl_eventslot
+//定义事件槽
+#define MCTRL_DEFSLOT(...) public: struct { __VA_ARGS__ } mslot
+
+/* 注册控件方法
+ * 此宏自动添加了注册的属性列表
+ * 否则也可以手动调用RegisterControl注册
+ */
+#define MCTRL_REGISTER(method) CtrlMgr::RegisterControl(ClassName, method, Helper::ArrayToVector(MCTRL_ATTRIB))
+
+namespace Mui::Ctrl
+{
+ template
+ constexpr bool mis_uinodecls = std::is_base_of_v
+ || std::is_base_of_v;
+
+ template
+ Target* mcast_control(T* control)
+ {
+ //检查参数类型是合法的
+ static_assert(mis_uinodecls, //目标的类型不是UINodeBase的基类或派生类
+ "[MiaoUI cast]: The targettype is not a base or derived class of UINodeBase.");
+
+ static_assert(mis_uinodecls, //目标的类型不是UINodeBase的基类或派生类
+ "[MiaoUI cast]: The targettype is not a base or derived class of UINodeBase.");
+
+ constexpr bool isBase = std::is_base_of_v;
+ constexpr bool isDerived = std::is_base_of_v;
+
+ static_assert(isBase || isDerived, //参数和要转换的目标之间没有继承或派生关系。
+ "[MiaoUI cast]: There is no inheritance or derivation relationship between the parameters and the target to be converted.");
+
+#ifdef _DEBUG
+ Target* ptr = dynamic_cast(control);
+ if (!ptr) //无法转换到目标类型
+ throw std::exception("[MiaoUI cast]: Unable to convert to target type.");
+#endif
+ return static_cast(control);
+ }
+}
+
+namespace Mui::CtrlMgr
+{
+ namespace Attrib
+ {
+ template
+ std::wstring Value_Make2x(T a, T b)
+ {
+ return std::to_wstring(a) + L"," + std::to_wstring(b);
+ }
+
+ template
+ std::wstring Value_Make4x(T a, T b, T c, T d)
+ {
+ return std::to_wstring(a) + L"," + std::to_wstring(b) + L","
+ + std::to_wstring(c) + L"," + std::to_wstring(d);
+ }
+
+ inline std::wstring Value_Make2x(UIPoint pt)
+ {
+ return Value_Make2x(pt.x, pt.y);
+ }
+
+ inline std::wstring Value_Make2x(UISize size)
+ {
+ return Value_Make2x(size.width, size.height);
+ }
+
+ inline std::wstring Value_Make4x(UIRect rect)
+ {
+ return Value_Make4x(rect.left, rect.top, rect.right, rect.bottom);
+ }
+
+ template
+ std::wstring Value_Make4x(_m_rect_t rect)
+ {
+ return Value_Make4x(rect.left, rect.top, rect.right, rect.bottom);
+ }
+ }
+
+ typedef std::function RegMethod;
+
+ struct AttribType
+ {
+ enum type
+ {
+ defaults, //默认文本类型
+ labelStyle, //UILabel::Attribute*属性类型
+ listfontStyle, //UIListBox::ItemFont*属性类型
+ UIStyle, //UIStyle*属性类型
+ UIResource, //UIResource*属性类型
+ UIBitmap //UIBitmap属性类型
+ } attribType = defaults;
+ std::wstring_view attribName;
+ };
+
+ /*inline std::vector MergeAttrib(const std::initializer_list>& lists)
+ {
+ std::vector ret;
+ for (const auto& list : lists)
+ {
+ ret.insert(ret.end(), list.begin(), list.end());
+ }
+ return ret;
+ }*/
+
+
+ class AttribConverter
+ {
+ public:
+ /* 默认转换器
+ * 支持类型:
+ *
+ * bool
+ * float
+ * double
+ *
+ * std::wstring
+ * std::wstring_view
+ * wchar_t
+ *
+ * _m_uchar
+ * _m_byte
+ * _m_short
+ * _m_ushort
+ * _m_int
+ * _m_long
+ * _m_uint
+ * _m_ulong
+ * _m_color
+ * _m_param
+ * _m_long64
+ * _m_ulong64
+ * _m_size
+ * _m_ptr
+ * _m_ptrv
+ *
+ * _m_rect
+ * _m_rect_t
+ *
+ * UIRect
+ * UIPoint
+ * UISize
+ *
+ * void*
+ *
+ * UIStylePtr
+ * UIStyle*
+ * UIBitmapPtr
+ * UIBitmap*
+ */
+ AttribConverter();
+ virtual ~AttribConverter() = default;
+
+ template
+ T Convert(std::wstring_view value)
+ try
+ {
+ auto iter = m_methodList.find(typeid(T).name());
+ if (iter == m_methodList.end())
+ return {};
+ return std::any_cast(iter->second.get(value));
+ }
+ catch(...)
+ {
+#ifdef _DEBUG
+ _M_OutErrorDbg_(L"不支持的类型转换", false);
+#endif
+ return {};
+ }
+
+ template
+ std::wstring Convert(const T& value)
+ try
+ {
+ auto iter = m_methodList.find(typeid(T).name());
+ if (iter == m_methodList.end())
+ return {};
+ return iter->second.set(value);
+ }
+ catch(...)
+ {
+#ifdef _DEBUG
+ _M_OutErrorDbg_(L"不支持的类型转换", false);
+#endif
+ return {};
+ }
+
+ using ConversionMethod_Get = std::function;
+ using ConversionMethod_Set = std::function;
+
+ protected:
+ //添加转换方法
+ template
+ void AddMethod(ConversionMethod_Get get, ConversionMethod_Set set)
+ {
+ m_methodList.insert(std::make_pair((std::string)typeid(T).name(), data{ std::move(get), std::move(set)}));
+ }
+
+ private:
+ struct data
+ {
+ ConversionMethod_Get get = nullptr;
+ ConversionMethod_Set set = nullptr;
+ };
+ static std::unordered_map m_methodList;
+ };
+
+ //member, name, seter, geter
+#define MakeUIAttrib(__struct, ...) decltype(__struct)::MakeAttrib(__VA_ARGS__)
+ //member(final), offset, name, seter, geter
+#define MakeUIAttribEx(__struct, member, offset, ...) decltype(__struct)::MakeAttribAtOffset(member, decltype(__struct)::MOffsetOf(offset), __VA_ARGS__)
+
+ //在赋值属性之后调用Set方法回调
+#define MakeUIAttrib_AfterSetOnly(__struct, member, name, paramname, code) decltype(__struct)::MakeAttrib(member, name, \
+ [](decltype(__struct)::SetData param) \
+ { \
+ param.Assign(member); \
+ return [](decltype(__struct)::SetData& paramname) -> bool \
+ code(paramname); \
+ })
+
+ //在赋值属性之后调用Get方法回调
+#define MakeUIAttrib_AfterGetOnly(__struct, member, name) decltype(__struct)::MakeAttrib(member, name, nullptr, \
+ [](decltype(__struct)::GetData param) \
+ { \
+ code \
+ } \
+
+ //只转换指针类型 不使用AttribConverter类 能减少一些编译代码体积 这不会检查类型是否匹配
+ template
+ T* ConvertAttribPtr(std::wstring_view attrib)
+ {
+ return reinterpret_cast(Helper::M_StoULong64(attrib));
+ }
+
+ template
+ std::wstring ConvertAttribPtr(T* attrib)
+ {
+ return std::to_wstring((_m_ptrv)attrib);
+ }
+
+ template
+ class UIAttribute
+ {
+ public:
+ struct SetData
+ {
+ T* data = nullptr;
+ AttribConverter* converter = nullptr;
+ std::wstring_view attribName;
+ std::wstring_view attribValue;
+ Param param;
+
+ //将属性转换到目标类型
+ template
+ inline Type GetValue()
+ {
+ //退化成void*来转换
+ if constexpr (std::is_pointer_v)
+ return (Type)ConvertAttribPtr(attribValue);
+ //字符串无需转换 用不着再跑一遍Convert类
+ else if constexpr (std::is_same_v)
+ return attribValue.data();
+ else if constexpr (std::is_same_v || std::is_same_v)
+ return attribValue;
+ else if constexpr (std::is_enum_v)
+ return (Type)converter->Convert(attribValue);
+ else
+ return converter->Convert(attribValue);
+ }
+
+ //对属性赋值 将attribValue的值转换并赋值到绑定的结构体成员
+ template
+ void Assign(Member Struct::* member)
+ {
+ auto pData = (Member*)(_m_ptrv(data) + MOffsetOf(member));
+ *pData = GetValue();
+ }
+
+ template
+ void AssignAtOffset(Member Struct::* member, _m_ptrv offset)
+ {
+ auto pData = (Member*)(_m_ptrv(data) + MOffsetOf(member) + offset);
+ *pData = GetValue();
+ }
+ };
+
+ struct GetData
+ {
+ T* data = nullptr;
+ AttribConverter* converter = nullptr;
+ std::wstring_view attribName;
+ Param param;
+ };
+
+ using SetAttribCallback = std::function