remove kiss-flixel subtree
This commit is contained in:
@@ -1,504 +0,0 @@
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
Version 2.1, February 1999
|
||||
|
||||
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
[This is the first released version of the Lesser GPL. It also counts
|
||||
as the successor of the GNU Library Public License, version 2, hence
|
||||
the version number 2.1.]
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
Licenses are intended to guarantee your freedom to share and change
|
||||
free software--to make sure the software is free for all its users.
|
||||
|
||||
This license, the Lesser General Public License, applies to some
|
||||
specially designated software packages--typically libraries--of the
|
||||
Free Software Foundation and other authors who decide to use it. You
|
||||
can use it too, but we suggest you first think carefully about whether
|
||||
this license or the ordinary General Public License is the better
|
||||
strategy to use in any particular case, based on the explanations below.
|
||||
|
||||
When we speak of free software, we are referring to freedom of use,
|
||||
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 this service if you wish); that you receive source code or can get
|
||||
it if you want it; that you can change the software and use pieces of
|
||||
it in new free programs; and that you are informed that you can do
|
||||
these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
distributors to deny you these rights or to ask you to surrender these
|
||||
rights. These restrictions translate to certain responsibilities for
|
||||
you if you distribute copies of the library or if you modify it.
|
||||
|
||||
For example, if you distribute copies of the library, whether gratis
|
||||
or for a fee, you must give the recipients all the rights that we gave
|
||||
you. You must make sure that they, too, receive or can get the source
|
||||
code. If you link other code with the library, you must provide
|
||||
complete object files to the recipients, so that they can relink them
|
||||
with the library after making changes to the library and recompiling
|
||||
it. And you must show them these terms so they know their rights.
|
||||
|
||||
We protect your rights with a two-step method: (1) we copyright the
|
||||
library, and (2) we offer you this license, which gives you legal
|
||||
permission to copy, distribute and/or modify the library.
|
||||
|
||||
To protect each distributor, we want to make it very clear that
|
||||
there is no warranty for the free library. Also, if the library is
|
||||
modified by someone else and passed on, the recipients should know
|
||||
that what they have is not the original version, so that the original
|
||||
author's reputation will not be affected by problems that might be
|
||||
introduced by others.
|
||||
|
||||
Finally, software patents pose a constant threat to the existence of
|
||||
any free program. We wish to make sure that a company cannot
|
||||
effectively restrict the users of a free program by obtaining a
|
||||
restrictive license from a patent holder. Therefore, we insist that
|
||||
any patent license obtained for a version of the library must be
|
||||
consistent with the full freedom of use specified in this license.
|
||||
|
||||
Most GNU software, including some libraries, is covered by the
|
||||
ordinary GNU General Public License. This license, the GNU Lesser
|
||||
General Public License, applies to certain designated libraries, and
|
||||
is quite different from the ordinary General Public License. We use
|
||||
this license for certain libraries in order to permit linking those
|
||||
libraries into non-free programs.
|
||||
|
||||
When a program is linked with a library, whether statically or using
|
||||
a shared library, the combination of the two is legally speaking a
|
||||
combined work, a derivative of the original library. The ordinary
|
||||
General Public License therefore permits such linking only if the
|
||||
entire combination fits its criteria of freedom. The Lesser General
|
||||
Public License permits more lax criteria for linking other code with
|
||||
the library.
|
||||
|
||||
We call this license the "Lesser" General Public License because it
|
||||
does Less to protect the user's freedom than the ordinary General
|
||||
Public License. It also provides other free software developers Less
|
||||
of an advantage over competing non-free programs. These disadvantages
|
||||
are the reason we use the ordinary General Public License for many
|
||||
libraries. However, the Lesser license provides advantages in certain
|
||||
special circumstances.
|
||||
|
||||
For example, on rare occasions, there may be a special need to
|
||||
encourage the widest possible use of a certain library, so that it becomes
|
||||
a de-facto standard. To achieve this, non-free programs must be
|
||||
allowed to use the library. A more frequent case is that a free
|
||||
library does the same job as widely used non-free libraries. In this
|
||||
case, there is little to gain by limiting the free library to free
|
||||
software only, so we use the Lesser General Public License.
|
||||
|
||||
In other cases, permission to use a particular library in non-free
|
||||
programs enables a greater number of people to use a large body of
|
||||
free software. For example, permission to use the GNU C Library in
|
||||
non-free programs enables many more people to use the whole GNU
|
||||
operating system, as well as its variant, the GNU/Linux operating
|
||||
system.
|
||||
|
||||
Although the Lesser General Public License is Less protective of the
|
||||
users' freedom, it does ensure that the user of a program that is
|
||||
linked with the Library has the freedom and the wherewithal to run
|
||||
that program using a modified version of the Library.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow. Pay close attention to the difference between a
|
||||
"work based on the library" and a "work that uses the library". The
|
||||
former contains code derived from the library, whereas the latter must
|
||||
be combined with the library in order to run.
|
||||
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License Agreement applies to any software library or other
|
||||
program which contains a notice placed by the copyright holder or
|
||||
other authorized party saying it may be distributed under the terms of
|
||||
this Lesser General Public License (also called "this License").
|
||||
Each licensee is addressed as "you".
|
||||
|
||||
A "library" means a collection of software functions and/or data
|
||||
prepared so as to be conveniently linked with application programs
|
||||
(which use some of those functions and data) to form executables.
|
||||
|
||||
The "Library", below, refers to any such software library or work
|
||||
which has been distributed under these terms. A "work based on the
|
||||
Library" means either the Library or any derivative work under
|
||||
copyright law: that is to say, a work containing the Library or a
|
||||
portion of it, either verbatim or with modifications and/or translated
|
||||
straightforwardly into another language. (Hereinafter, translation is
|
||||
included without limitation in the term "modification".)
|
||||
|
||||
"Source code" for a work means the preferred form of the work for
|
||||
making modifications to it. For a library, complete source code means
|
||||
all the source code for all modules it contains, plus any associated
|
||||
interface definition files, plus the scripts used to control compilation
|
||||
and installation of the library.
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running a program using the Library is not restricted, and output from
|
||||
such a program is covered only if its contents constitute a work based
|
||||
on the Library (independent of the use of the Library in a tool for
|
||||
writing it). Whether that is true depends on what the Library does
|
||||
and what the program that uses the Library does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Library's
|
||||
complete source code as you receive it, in any medium, provided that
|
||||
you conspicuously and appropriately publish on each copy an
|
||||
appropriate copyright notice and disclaimer of warranty; keep intact
|
||||
all the notices that refer to this License and to the absence of any
|
||||
warranty; and distribute a copy of this License along with the
|
||||
Library.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy,
|
||||
and you may at your option offer warranty protection in exchange for a
|
||||
fee.
|
||||
|
||||
2. You may modify your copy or copies of the Library or any portion
|
||||
of it, thus forming a work based on the Library, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) The modified work must itself be a software library.
|
||||
|
||||
b) You must cause the files modified to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
c) You must cause the whole of the work to be licensed at no
|
||||
charge to all third parties under the terms of this License.
|
||||
|
||||
d) If a facility in the modified Library refers to a function or a
|
||||
table of data to be supplied by an application program that uses
|
||||
the facility, other than as an argument passed when the facility
|
||||
is invoked, then you must make a good faith effort to ensure that,
|
||||
in the event an application does not supply such function or
|
||||
table, the facility still operates, and performs whatever part of
|
||||
its purpose remains meaningful.
|
||||
|
||||
(For example, a function in a library to compute square roots has
|
||||
a purpose that is entirely well-defined independent of the
|
||||
application. Therefore, Subsection 2d requires that any
|
||||
application-supplied function or table used by this function must
|
||||
be optional: if the application does not supply it, the square
|
||||
root function must still compute square roots.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Library,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Library, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote
|
||||
it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Library.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Library
|
||||
with the Library (or with a work based on the Library) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may opt to apply the terms of the ordinary GNU General Public
|
||||
License instead of this License to a given copy of the Library. To do
|
||||
this, you must alter all the notices that refer to this License, so
|
||||
that they refer to the ordinary GNU General Public License, version 2,
|
||||
instead of to this License. (If a newer version than version 2 of the
|
||||
ordinary GNU General Public License has appeared, then you can specify
|
||||
that version instead if you wish.) Do not make any other change in
|
||||
these notices.
|
||||
|
||||
Once this change is made in a given copy, it is irreversible for
|
||||
that copy, so the ordinary GNU General Public License applies to all
|
||||
subsequent copies and derivative works made from that copy.
|
||||
|
||||
This option is useful when you wish to copy part of the code of
|
||||
the Library into a program that is not a library.
|
||||
|
||||
4. You may copy and distribute the Library (or a portion or
|
||||
derivative of it, under Section 2) in object code or executable form
|
||||
under the terms of Sections 1 and 2 above provided that you accompany
|
||||
it with the complete corresponding machine-readable source code, which
|
||||
must be distributed under the terms of Sections 1 and 2 above on a
|
||||
medium customarily used for software interchange.
|
||||
|
||||
If distribution of object code is made by offering access to copy
|
||||
from a designated place, then offering equivalent access to copy the
|
||||
source code from the same place satisfies the requirement to
|
||||
distribute the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
5. A program that contains no derivative of any portion of the
|
||||
Library, but is designed to work with the Library by being compiled or
|
||||
linked with it, is called a "work that uses the Library". Such a
|
||||
work, in isolation, is not a derivative work of the Library, and
|
||||
therefore falls outside the scope of this License.
|
||||
|
||||
However, linking a "work that uses the Library" with the Library
|
||||
creates an executable that is a derivative of the Library (because it
|
||||
contains portions of the Library), rather than a "work that uses the
|
||||
library". The executable is therefore covered by this License.
|
||||
Section 6 states terms for distribution of such executables.
|
||||
|
||||
When a "work that uses the Library" uses material from a header file
|
||||
that is part of the Library, the object code for the work may be a
|
||||
derivative work of the Library even though the source code is not.
|
||||
Whether this is true is especially significant if the work can be
|
||||
linked without the Library, or if the work is itself a library. The
|
||||
threshold for this to be true is not precisely defined by law.
|
||||
|
||||
If such an object file uses only numerical parameters, data
|
||||
structure layouts and accessors, and small macros and small inline
|
||||
functions (ten lines or less in length), then the use of the object
|
||||
file is unrestricted, regardless of whether it is legally a derivative
|
||||
work. (Executables containing this object code plus portions of the
|
||||
Library will still fall under Section 6.)
|
||||
|
||||
Otherwise, if the work is a derivative of the Library, you may
|
||||
distribute the object code for the work under the terms of Section 6.
|
||||
Any executables containing that work also fall under Section 6,
|
||||
whether or not they are linked directly with the Library itself.
|
||||
|
||||
6. As an exception to the Sections above, you may also combine or
|
||||
link a "work that uses the Library" with the Library to produce a
|
||||
work containing portions of the Library, and distribute that work
|
||||
under terms of your choice, provided that the terms permit
|
||||
modification of the work for the customer's own use and reverse
|
||||
engineering for debugging such modifications.
|
||||
|
||||
You must give prominent notice with each copy of the work that the
|
||||
Library is used in it and that the Library and its use are covered by
|
||||
this License. You must supply a copy of this License. If the work
|
||||
during execution displays copyright notices, you must include the
|
||||
copyright notice for the Library among them, as well as a reference
|
||||
directing the user to the copy of this License. Also, you must do one
|
||||
of these things:
|
||||
|
||||
a) Accompany the work with the complete corresponding
|
||||
machine-readable source code for the Library including whatever
|
||||
changes were used in the work (which must be distributed under
|
||||
Sections 1 and 2 above); and, if the work is an executable linked
|
||||
with the Library, with the complete machine-readable "work that
|
||||
uses the Library", as object code and/or source code, so that the
|
||||
user can modify the Library and then relink to produce a modified
|
||||
executable containing the modified Library. (It is understood
|
||||
that the user who changes the contents of definitions files in the
|
||||
Library will not necessarily be able to recompile the application
|
||||
to use the modified definitions.)
|
||||
|
||||
b) Use a suitable shared library mechanism for linking with the
|
||||
Library. A suitable mechanism is one that (1) uses at run time a
|
||||
copy of the library already present on the user's computer system,
|
||||
rather than copying library functions into the executable, and (2)
|
||||
will operate properly with a modified version of the library, if
|
||||
the user installs one, as long as the modified version is
|
||||
interface-compatible with the version that the work was made with.
|
||||
|
||||
c) Accompany the work with a written offer, valid for at
|
||||
least three years, to give the same user the materials
|
||||
specified in Subsection 6a, above, for a charge no more
|
||||
than the cost of performing this distribution.
|
||||
|
||||
d) If distribution of the work is made by offering access to copy
|
||||
from a designated place, offer equivalent access to copy the above
|
||||
specified materials from the same place.
|
||||
|
||||
e) Verify that the user has already received a copy of these
|
||||
materials or that you have already sent this user a copy.
|
||||
|
||||
For an executable, the required form of the "work that uses the
|
||||
Library" must include any data and utility programs needed for
|
||||
reproducing the executable from it. However, as a special exception,
|
||||
the materials to be distributed need not include anything that is
|
||||
normally distributed (in either source or binary form) with the major
|
||||
components (compiler, kernel, and so on) of the operating system on
|
||||
which the executable runs, unless that component itself accompanies
|
||||
the executable.
|
||||
|
||||
It may happen that this requirement contradicts the license
|
||||
restrictions of other proprietary libraries that do not normally
|
||||
accompany the operating system. Such a contradiction means you cannot
|
||||
use both them and the Library together in an executable that you
|
||||
distribute.
|
||||
|
||||
7. 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 not covered by this License, and distribute such a combined
|
||||
library, provided that the separate distribution of the work based on
|
||||
the Library and of the other library facilities is otherwise
|
||||
permitted, and provided that you do these two things:
|
||||
|
||||
a) Accompany the combined library with a copy of the same work
|
||||
based on the Library, uncombined with any other library
|
||||
facilities. This must be distributed under the terms of the
|
||||
Sections above.
|
||||
|
||||
b) Give prominent notice with the combined library of the fact
|
||||
that part of it is a work based on the Library, and explaining
|
||||
where to find the accompanying uncombined form of the same work.
|
||||
|
||||
8. You may not copy, modify, sublicense, link with, or distribute
|
||||
the Library except as expressly provided under this License. Any
|
||||
attempt otherwise to copy, modify, sublicense, link with, or
|
||||
distribute the Library is void, and will automatically terminate your
|
||||
rights under this License. However, parties who have received copies,
|
||||
or rights, from you under this License will not have their licenses
|
||||
terminated so long as such parties remain in full compliance.
|
||||
|
||||
9. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Library or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Library (or any work based on the
|
||||
Library), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Library or works based on it.
|
||||
|
||||
10. Each time you redistribute the Library (or any work based on the
|
||||
Library), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute, link with or modify the Library
|
||||
subject to these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties with
|
||||
this License.
|
||||
|
||||
11. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
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
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Library at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Library by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Library.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under any
|
||||
particular circumstance, the balance of the section is intended to apply,
|
||||
and the section as a whole is intended to apply in other circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
12. If the distribution and/or use of the Library is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Library under this License may add
|
||||
an explicit geographical distribution limitation excluding those countries,
|
||||
so that distribution is permitted only in or among countries not thus
|
||||
excluded. In such case, this License incorporates the limitation as if
|
||||
written in the body of this License.
|
||||
|
||||
13. The Free Software Foundation may publish revised and/or new
|
||||
versions of the 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
|
||||
specifies a version number of this License which applies to it and
|
||||
"any later version", you have the option of following the terms and
|
||||
conditions either of that version or of any later version published by
|
||||
the Free Software Foundation. If the Library does not specify a
|
||||
license version number, you may choose any version ever published by
|
||||
the Free Software Foundation.
|
||||
|
||||
14. If you wish to incorporate parts of the Library into other free
|
||||
programs whose distribution conditions are incompatible with these,
|
||||
write to the author to ask for permission. For software which is
|
||||
copyrighted by the Free Software Foundation, write to the Free
|
||||
Software Foundation; we sometimes make exceptions for this. Our
|
||||
decision will be guided by the two goals of preserving the free status
|
||||
of all derivatives of our free software and of promoting the sharing
|
||||
and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
|
||||
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
|
||||
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
|
||||
OTHER PARTIES PROVIDE THE LIBRARY "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
|
||||
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
|
||||
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
|
||||
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
|
||||
AND/OR REDISTRIBUTE THE LIBRARY 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
|
||||
LIBRARY (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 LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
|
||||
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
|
||||
DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Libraries
|
||||
|
||||
If you develop a new library, and you want it to be of the greatest
|
||||
possible use to the public, we recommend making it free software that
|
||||
everyone can redistribute and change. You can do so by permitting
|
||||
redistribution under these terms (or, alternatively, under the terms of the
|
||||
ordinary General Public License).
|
||||
|
||||
To apply these terms, attach the following notices to the library. It is
|
||||
safest to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least the
|
||||
"copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the library's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This 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 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This 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 this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
|
||||
USA
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the library, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the
|
||||
library `Frob' (a library for tweaking knobs) written by James Random
|
||||
Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1990
|
||||
Ty Coon, President of Vice
|
||||
|
||||
That's all there is to it!
|
@@ -1,18 +0,0 @@
|
||||
{
|
||||
"name": "kiss-flixel",
|
||||
"description": "",
|
||||
"classPath": "src/",
|
||||
"dependencies": {
|
||||
"kiss": "",
|
||||
"kiss-tools": "",
|
||||
"flixel": ""
|
||||
},
|
||||
"url": "https://github.com/NQNStudios/kisslang",
|
||||
"contributors": [
|
||||
"NQNStudios"
|
||||
],
|
||||
"version": "0.0.0",
|
||||
"releasenote": "",
|
||||
"tags": [],
|
||||
"license": "LGPL"
|
||||
}
|
@@ -1,21 +0,0 @@
|
||||
package kiss_flixel;
|
||||
|
||||
import kiss.Prelude;
|
||||
import kiss.List;
|
||||
import flash.geom.Rectangle;
|
||||
import flash.display.BitmapData;
|
||||
import flixel.FlxCamera;
|
||||
import flixel.math.FlxVector;
|
||||
import flixel.math.FlxPoint;
|
||||
import flixel.math.FlxRect;
|
||||
import flixel.FlxSprite;
|
||||
import flixel.FlxG;
|
||||
import flixel.util.FlxColor;
|
||||
import flixel.FlxObject;
|
||||
import flixel.group.FlxGroup;
|
||||
import kiss_flixel.GroupTools;
|
||||
|
||||
using Lambda;
|
||||
|
||||
@:build(kiss.Kiss.build())
|
||||
class CameraTools {}
|
@@ -1,113 +0,0 @@
|
||||
(function updateKeyControl [:FlxCamera camera :Float elapsed :Float speed :Void->Bool leftKey :Void->Bool rightKey :Void->Bool upKey :Void->Bool downKey]
|
||||
(let [scrollAmount (* speed elapsed)
|
||||
&mut :FlxVector movement (new FlxPoint)]
|
||||
(when (leftKey) (-= movement.x 1))
|
||||
(when (rightKey) (+= movement.x 1))
|
||||
(when (upKey) (-= movement.y 1))
|
||||
(when (downKey) (+= movement.y 1))
|
||||
(when (< 0 movement.length)
|
||||
(set movement (movement.normalize)))
|
||||
(movement.scale scrollAmount)
|
||||
(+= camera.scroll.x movement.x)
|
||||
(+= camera.scroll.y movement.y)))
|
||||
|
||||
(var :Map<FlxCamera,FlxCamera> borderCameras (new Map))
|
||||
|
||||
// Add a border sprite on top of this camera's viewport, scaling the border to frame the viewport,
|
||||
// and downsizing and shifting the viewport to fit within the border's opaque frame
|
||||
(function addBorder [:FlxCamera camera :FlxSprite border]
|
||||
(let [borderCamera
|
||||
(new FlxCamera (Std.int camera.x) (Std.int camera.y) camera.width camera.height)
|
||||
:BitmapData borderPixels
|
||||
(border.updateFramePixels)
|
||||
isTransparent
|
||||
->c (= c FlxColor.TRANSPARENT)
|
||||
borderHorizontal
|
||||
(borderPixels.getVector (new Rectangle 0 (iHalf border.height) border.width 1))
|
||||
borderVertical
|
||||
(borderPixels.getVector (new Rectangle (iHalf border.width) 0 1 border.height))
|
||||
borderSizeLeft
|
||||
(borderHorizontal.findIndex isTransparent)
|
||||
borderSizeTop
|
||||
(borderVertical.findIndex isTransparent)
|
||||
borderSizeRight
|
||||
(.findIndex (borderHorizontal.reverse) isTransparent)
|
||||
borderSizeBottom
|
||||
(.findIndex (borderVertical.reverse) isTransparent)]
|
||||
(set border.x 0) // It will be 0,0 relative to its own camera
|
||||
(set border.y 0)
|
||||
(border.setGraphicSize camera.width camera.height)
|
||||
(border.updateHitbox)
|
||||
(FlxG.cameras.add borderCamera false)
|
||||
(dictSet borderCameras camera borderCamera)
|
||||
(set border.cameras [borderCamera])
|
||||
(set borderCamera.bgColor FlxColor.TRANSPARENT)
|
||||
(FlxG.state.add border)
|
||||
(let [dx (* border.scale.x borderSizeLeft)
|
||||
dy (* border.scale.y borderSizeTop)]
|
||||
(+= camera.x dx)
|
||||
(+= camera.y dy)
|
||||
(-= camera.width dx (* border.scale.x borderSizeRight))
|
||||
(-= camera.height dy (* border.scale.y borderSizeBottom)))))
|
||||
|
||||
// GOTCHA: if you change FlxG.camera to a moving camera, you MUST provide a default camera for FlxG.mouse.getScreenPosition()
|
||||
(function updateMouseBorderControl [:FlxCamera camera :Float elapsed :Float speed :Float heightFraction :FlxCamera screenCamera]
|
||||
(let [viewport (ifLet [bc (dictGet borderCameras camera)] bc camera)
|
||||
left viewport.x
|
||||
top viewport.y
|
||||
right (+ viewport.x viewport.width)
|
||||
bottom (+ viewport.y viewport.height)
|
||||
// Use the same margin size for x and y, and calculate it based on height
|
||||
// (in a landscape view, this just makes more sense to me)
|
||||
margin (* viewport.height heightFraction)
|
||||
mPos (FlxG.mouse.getScreenPosition screenCamera)]
|
||||
(updateKeyControl camera elapsed speed
|
||||
// when the camera takes the whole screen, count the letterbox zones as margin
|
||||
->(if (= left 0)
|
||||
(<= mPos.x (+ left margin))
|
||||
(<= left mPos.x (+ left margin)))
|
||||
->(if (= right FlxG.width)
|
||||
(<= (- right margin) mPos.x)
|
||||
(<= (- right margin) mPos.x right))
|
||||
->(if (= top 0)
|
||||
(<= mPos.y (+ top margin))
|
||||
(<= top mPos.y (+ top margin)))
|
||||
->(if (= bottom FlxG.height)
|
||||
(<= (- bottom margin) mPos.y)
|
||||
(<= (- bottom margin) mPos.y bottom)))))
|
||||
|
||||
// GOTCHA: if you change FlxG.camera to a moving camera, you MUST provide a default camera for FlxG.mouse.getScreenPosition()
|
||||
(function updateScrollWheelZoom [:FlxCamera camera :Float elapsed :Float speed &opt :FlxCamera screenCamera]
|
||||
(case FlxG.mouse.wheel
|
||||
(0 null)
|
||||
(v
|
||||
(let [deltaZoom (* camera.zoom v elapsed speed)
|
||||
scrollPosition (camera.scroll.copyTo)
|
||||
mouseWorldPosition (FlxG.mouse.getWorldPosition camera)]
|
||||
(+= camera.zoom deltaZoom)
|
||||
(let [newMouseWorldPosition (FlxG.mouse.getWorldPosition camera)
|
||||
deltaMousePosition (newMouseWorldPosition.subtractPoint mouseWorldPosition)]
|
||||
(camera.scroll.subtractPoint deltaMousePosition))
|
||||
// Undo any zooming out that expands the viewport past its bounds
|
||||
(when (> 0 deltaZoom)
|
||||
(unless (.equals (camera.getViewRect) (.intersection (getScrollBounds camera) (camera.getViewRect)))
|
||||
(-= camera.zoom deltaZoom)
|
||||
(set camera.scroll scrollPosition)))))
|
||||
(otherwise null)))
|
||||
|
||||
(function getScrollBounds [:FlxCamera camera]
|
||||
(.fromTwoPoints (new FlxRect) (new FlxPoint camera.minScrollX camera.minScrollY) (new FlxPoint camera.maxScrollX camera.maxScrollY)))
|
||||
|
||||
// GOTCHA: if you change FlxG.camera to a moving camera, you MUST provide a default camera for FlxG.mouse.getScreenPosition()
|
||||
(function calculateScrollBounds <>[:FlxSprite T] [:FlxCamera camera :FlxTypedGroup<T> group &opt :FlxCamera screenCamera :Float margin]
|
||||
(let [r (GroupTools.calculateScreenBounds group screenCamera margin)]
|
||||
(camera.setScrollBoundsRect r.x r.y r.width r.height)))
|
||||
|
||||
// GOTCHA: if you change FlxG.camera to a moving camera, you MUST provide a default camera for FlxG.mouse.getScreenPosition()
|
||||
(function extendScrollBounds [:FlxCamera camera :FlxSprite sprite &opt :FlxCamera screenCamera :Float margin]
|
||||
// if the given object is out of bounds, extend the bounds
|
||||
(let [r (sprite.getScreenBounds camera)]
|
||||
(setMin camera.minScrollX (- r.left margin))
|
||||
(setMin camera.minScrollY (- r.top margin))
|
||||
(setMax camera.maxScrollX (+ r.right margin))
|
||||
(setMax camera.maxScrollY (+ r.bottom margin))))
|
@@ -1,71 +0,0 @@
|
||||
package kiss_flixel;
|
||||
|
||||
import kiss.Prelude;
|
||||
import kiss.List;
|
||||
import flixel.FlxG;
|
||||
import flixel.FlxSprite;
|
||||
import flixel.math.FlxRect;
|
||||
import flixel.group.FlxGroup;
|
||||
import flixel.util.FlxSpriteUtil;
|
||||
import flixel.util.FlxColor;
|
||||
using flixel.util.FlxSpriteUtil;
|
||||
using kiss_flixel.DebugLayer;
|
||||
|
||||
@:build(kiss.Kiss.build())
|
||||
class DebugLayer extends FlxTypedGroup<FlxSprite> {
|
||||
function thisCamera() {
|
||||
if (cameras != null && cameras.length > 0)
|
||||
return cameras[0];
|
||||
return FlxG.camera;
|
||||
}
|
||||
function _thickness(thickness:Float) {
|
||||
return Math.max(1, thickness / thisCamera().zoom);
|
||||
}
|
||||
public function drawLine(X:Float, Y:Float, X2:Float, Y2:Float, color:FlxColor = FlxColor.WHITE, thickness = 1.0):FlxSprite {
|
||||
thickness = _thickness(thickness);
|
||||
var s = new FlxSprite(Math.min(X,X2)-thickness/2, Math.min(Y,Y2)-thickness/2);
|
||||
var Width = Math.abs(X2 - X);
|
||||
var Height = Math.abs(Y2 - Y);
|
||||
|
||||
// TODO test where thickness appears - is it center-out from the given border?
|
||||
s.mg(Width + thickness, Height + thickness);
|
||||
s.drawLine(X-s.x, Y-s.y, X2-s.x, Y2-s.y, {color: color, thickness: thickness});
|
||||
add(s);
|
||||
return s;
|
||||
}
|
||||
|
||||
public function drawRect(X:Float, Y:Float, Width:Float, Height:Float, outlineColor:FlxColor = FlxColor.WHITE, thickness = 1.0):FlxSprite {
|
||||
thickness = _thickness(thickness);
|
||||
|
||||
var s = new FlxSprite(X-thickness/2, Y-thickness/2);
|
||||
|
||||
// TODO test where thickness appears - is it center-out from the given border?
|
||||
s.mg(Width + thickness, Height + thickness);
|
||||
s.drawRect(thickness/2, thickness/2, Width, Height, FlxColor.TRANSPARENT, {color: outlineColor, thickness: thickness});
|
||||
add(s);
|
||||
return s;
|
||||
}
|
||||
|
||||
public function drawFlxRect(rect:FlxRect, outlineColor:FlxColor = FlxColor.WHITE, thickness = 1.0):FlxSprite {
|
||||
return drawRect(rect.x, rect.y, rect.width, rect.height, outlineColor, thickness);
|
||||
}
|
||||
|
||||
public function drawCircle(x:Float, y:Float, radius: Float, color = FlxColor.WHITE, thickness = 1.0):FlxSprite {
|
||||
thickness = _thickness(thickness);
|
||||
|
||||
var s = new FlxSprite(x - radius - thickness/2, y - radius - thickness/2);
|
||||
s.mg(2 * (radius + thickness), 2 * (radius + thickness));
|
||||
s.drawCircle(s.width / 2, s.height / 2, FlxColor.TRANSPARENT, {color:color, thickness:thickness});
|
||||
add(s);
|
||||
return s;
|
||||
}
|
||||
|
||||
public static function mg(s:FlxSprite, Width:Float, Height:Float):FlxSprite {
|
||||
return s.makeGraphic(Math.ceil(Width), Math.ceil(Height), FlxColor.TRANSPARENT, true);
|
||||
}
|
||||
|
||||
public override function clear() {
|
||||
forEach((s)->{s.destroy();});
|
||||
super.clear();
|
||||
}
|
||||
}
|
@@ -1,2 +0,0 @@
|
||||
(defNew []
|
||||
(super))
|
@@ -1,166 +0,0 @@
|
||||
package kiss_flixel;
|
||||
|
||||
import flixel.FlxG;
|
||||
import flixel.addons.plugin.FlxMouseControl;
|
||||
import flixel.FlxState;
|
||||
import flixel.FlxCamera;
|
||||
import flixel.FlxBasic;
|
||||
import flixel.math.FlxPoint;
|
||||
import flixel.math.FlxRect;
|
||||
import openfl.geom.Rectangle;
|
||||
import flixel.util.FlxColor;
|
||||
|
||||
typedef DragState = {
|
||||
camera:Null<FlxCamera>,
|
||||
debugLayer:DebugLayer,
|
||||
enabledSprites:Array<KissExtendedSprite>,
|
||||
selectedSprites:Array<KissExtendedSprite>,
|
||||
firstCorner:Null<FlxPoint>,
|
||||
secondCorner:Null<FlxPoint>
|
||||
};
|
||||
|
||||
/**
|
||||
* Added automatically when you call enableDragToSelect() on a KissExtendedSprite.
|
||||
*/
|
||||
class DragToSelectPlugin extends FlxBasic {
|
||||
var dragStates:Map<FlxState,DragState> = [];
|
||||
|
||||
public function new() {
|
||||
super();
|
||||
}
|
||||
|
||||
public function clearEnabledSprites(?state:FlxState) {
|
||||
if (state == null) state = FlxG.state;
|
||||
dragStates[state].enabledSprites = [];
|
||||
dragStates[state].selectedSprites = [];
|
||||
}
|
||||
|
||||
// Don't use this on a whole list of sprites! It will be O(N^2)
|
||||
public function disableSprite(s: KissExtendedSprite, ?state:FlxState) {
|
||||
if (state == null) state = FlxG.state;
|
||||
dragStates[state].enabledSprites.remove(s);
|
||||
dragStates[state].selectedSprites.remove(s);
|
||||
}
|
||||
|
||||
public function enableSprite(s:KissExtendedSprite, ?state:FlxState, ?camera:FlxCamera) {
|
||||
if (state == null) state = FlxG.state;
|
||||
if (!dragStates.exists(state)) {
|
||||
dragStates[state] = {
|
||||
camera: camera,
|
||||
debugLayer: new DebugLayer(),
|
||||
enabledSprites: [s],
|
||||
selectedSprites: [],
|
||||
firstCorner: null,
|
||||
secondCorner: null
|
||||
};
|
||||
if (camera == null) camera = FlxG.camera;
|
||||
dragStates[state].debugLayer.cameras = [camera];
|
||||
state.add(dragStates[state].debugLayer);
|
||||
} else {
|
||||
dragStates[state].enabledSprites.push(s);
|
||||
}
|
||||
}
|
||||
|
||||
public function selectedSprites() {
|
||||
return dragStates[FlxG.state].selectedSprites;
|
||||
}
|
||||
|
||||
public function selectSprites(sprites:Array<KissExtendedSprite>) {
|
||||
deselectSprites();
|
||||
dragStates[FlxG.state].selectedSprites = sprites;
|
||||
for (s in sprites) {
|
||||
if (s.onSelected != null) {
|
||||
s.onSelected();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public function deselectSprites() {
|
||||
for (sprite in dragStates[FlxG.state].selectedSprites) {
|
||||
if (sprite.onDeselected != null) {
|
||||
sprite.onDeselected();
|
||||
}
|
||||
}
|
||||
dragStates[FlxG.state].selectedSprites = [];
|
||||
}
|
||||
|
||||
var wasJustPressed = false;
|
||||
public static var boxColor = FlxColor.LIME;
|
||||
|
||||
public override function update(elapsed:Float) {
|
||||
if (dragStates.exists(FlxG.state)) {
|
||||
var dragState = dragStates[FlxG.state];
|
||||
dragState.debugLayer.clear();
|
||||
|
||||
var camera = dragState.camera;
|
||||
if (camera == null) camera = FlxG.camera;
|
||||
|
||||
// If FlxMouseControl has a mouseZone enabled, respect it
|
||||
var mousePos = FlxG.mouse.getWorldPosition(camera);
|
||||
if (FlxMouseControl.mouseZone != null && !FlxMouseControl.mouseZone.containsPoint(mousePos)) {
|
||||
dragState.firstCorner = null;
|
||||
dragState.secondCorner = null;
|
||||
return;
|
||||
}
|
||||
|
||||
// have to skip a frame after justPressed, so KissExtendedSprites
|
||||
// can get first access to the mouse input
|
||||
if (FlxMouseControl.dragTarget == null) {
|
||||
if (wasJustPressed && FlxMouseControl.clickTarget == null) {
|
||||
deselectSprites();
|
||||
dragState.firstCorner = mousePos;
|
||||
}
|
||||
dragState.secondCorner = mousePos;
|
||||
if (dragState.firstCorner != null && dragState.selectedSprites.length == 0) {
|
||||
var rounded1 = dragState.firstCorner.copyTo();
|
||||
var rounded2 = dragState.secondCorner.copyTo();
|
||||
for (r in [rounded1, rounded2]) {
|
||||
r.x = Std.int(r.x);
|
||||
r.y = Std.int(r.y);
|
||||
}
|
||||
var rect = new FlxRect().fromTwoPoints(rounded1, rounded2);
|
||||
if (FlxG.mouse.justReleased && dragState.selectedSprites.length == 0) {
|
||||
dragState.firstCorner = null;
|
||||
for (s in dragState.enabledSprites) {
|
||||
if (s.scale.x != 1 || s.scale.y != 1) {
|
||||
throw "DragToSelectPlugin can't handle scaled sprites yet!";
|
||||
}
|
||||
var intersection = s.getRotatedBounds().intersection(rect);
|
||||
if (!intersection.isEmpty) {
|
||||
// TODO if pixel perfect is true, get the pixels in the intersection and hit test them for transparency
|
||||
var pixelPerfectCheck = false;
|
||||
if (s.pixelPerfectDrag()) {
|
||||
var alpha = s.pixelPerfectAlpha();
|
||||
s.updateFramePixels();
|
||||
var intersectionInFrame = new Rectangle(Std.int(intersection.x - s.x), Std.int(intersection.y - s.y), Math.min(s.framePixels.width, Std.int(intersection.width)), Math.min(s.framePixels.height, Std.int(intersection.height)));
|
||||
var pixels = s.framePixels.getPixels(intersectionInFrame);
|
||||
while (pixels.bytesAvailable > 0) {
|
||||
var color:FlxColor = pixels.readUnsignedInt();
|
||||
if (color.alpha * s.alpha >= alpha) {
|
||||
pixelPerfectCheck = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
pixelPerfectCheck = true;
|
||||
}
|
||||
if (pixelPerfectCheck) {
|
||||
dragState.selectedSprites.push(s);
|
||||
}
|
||||
}
|
||||
}
|
||||
for (s in dragState.selectedSprites) {
|
||||
if (s.onSelected != null) {
|
||||
s.onSelected();
|
||||
}
|
||||
}
|
||||
} else if (!rect.isEmpty) {
|
||||
dragState.debugLayer.drawFlxRect(rect, boxColor);
|
||||
}
|
||||
}
|
||||
}
|
||||
wasJustPressed = FlxG.mouse.justPressed;
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,14 +0,0 @@
|
||||
package kiss_flixel;
|
||||
|
||||
import kiss.Prelude;
|
||||
import kiss.List;
|
||||
import flixel.FlxObject;
|
||||
import flixel.FlxState;
|
||||
import flixel.math.FlxRect;
|
||||
import flixel.math.FlxPoint;
|
||||
import flixel.FlxCamera;
|
||||
import flixel.group.FlxGroup;
|
||||
import flixel.FlxSprite;
|
||||
|
||||
@:build(kiss.Kiss.build())
|
||||
class GroupTools {}
|
@@ -1,39 +0,0 @@
|
||||
(function :Void bringToFront <>[:FlxObject T] [:FlxTypedGroup<T> group :T obj]
|
||||
(when (contains group.members obj)
|
||||
(group.members.remove obj)
|
||||
(group.members.push obj)))
|
||||
|
||||
(function :Void sendToBack <>[:FlxObject T] [:FlxTypedGroup<T> group :T obj]
|
||||
(when (contains group.members obj)
|
||||
(group.remove obj)
|
||||
(group.insert 0 obj)))
|
||||
|
||||
(function :Void bringAllToFront <>[:FlxObject T] [:FlxTypedGroup<T> group :Array<T> arr]
|
||||
(doFor s (group.members.copy)
|
||||
(when (contains arr s) (bringToFront group s))))
|
||||
|
||||
(function :Void sendAllToBack <>[:FlxObject T] [:FlxTypedGroup<T> group :Array<T> arr]
|
||||
(doFor s (reverse (group.members.copy))
|
||||
(when (contains arr s) (sendToBack group s))))
|
||||
|
||||
(function :FlxRect calculateScreenBounds <>[:FlxSprite T] [:FlxTypedGroup<T> group &opt :FlxCamera camera :Float margin]
|
||||
(unless margin (set margin 0))
|
||||
(ifLet [s (group.getFirstAlive)]
|
||||
(let [r (new FlxRect)
|
||||
bounds (s.getScreenBounds r camera)
|
||||
&mut minX bounds.left
|
||||
&mut maxX bounds.right
|
||||
&mut minY bounds.top
|
||||
&mut maxY bounds.bottom]
|
||||
|
||||
(group.forEach ->sprite
|
||||
(let [bounds (sprite.getScreenBounds r camera)]
|
||||
(setMin minX bounds.left)
|
||||
(setMin minY bounds.top)
|
||||
(setMax maxX bounds.right)
|
||||
(setMax maxY bounds.bottom)))
|
||||
|
||||
(r.fromTwoPoints
|
||||
(new FlxPoint (- minX margin) (- minY margin))
|
||||
(new FlxPoint (+ maxX margin) (+ maxY margin))))
|
||||
(new FlxRect 0 0 0 0)))
|
@@ -1,251 +0,0 @@
|
||||
package kiss_flixel;
|
||||
|
||||
import flixel.FlxG;
|
||||
import flixel.FlxCamera;
|
||||
import flixel.FlxSprite;
|
||||
import flixel.FlxState;
|
||||
import flixel.math.FlxPoint;
|
||||
import flixel.math.FlxAngle;
|
||||
import flixel.math.FlxMath;
|
||||
import flixel.system.FlxAssets;
|
||||
import flixel.util.FlxColor;
|
||||
import flixel.addons.plugin.FlxMouseControl;
|
||||
import flixel.util.FlxCollision;
|
||||
import flash.display.BitmapData;
|
||||
import kiss_flixel.DragToSelectPlugin;
|
||||
|
||||
class KissExtendedSprite extends flixel.addons.display.FlxExtendedSprite {
|
||||
public function new(X:Float = 0, Y:Float = 0, ?SimpleGraphic:FlxGraphicAsset)
|
||||
{
|
||||
super(X, Y, SimpleGraphic);
|
||||
}
|
||||
|
||||
var dragStartPos:FlxPoint = null;
|
||||
var mouseStartPos:FlxPoint = null;
|
||||
|
||||
public var connectedSprites:Array<KissExtendedSprite> = [];
|
||||
public function connectedAndSelectedSprites() {
|
||||
var l = connectedSprites;
|
||||
var map = [for (s in l) s => true];
|
||||
if (_dragToSelectEnabled) {
|
||||
var plugin = FlxG.plugins.get(DragToSelectPlugin);
|
||||
for (s in plugin.selectedSprites()) {
|
||||
map[s] = true;
|
||||
for (c in s.connectedSprites) {
|
||||
map[c] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Remove duplicates and return
|
||||
l = [for (s => bool in map) s];
|
||||
return l;
|
||||
}
|
||||
var connectedSpritesStartPos:Array<FlxPoint> = [];
|
||||
|
||||
function resetStartPos() {
|
||||
dragStartPos = new FlxPoint(x, y);
|
||||
connectedSpritesStartPos = [for (s in connectedAndSelectedSprites()) new FlxPoint(s.x, s.y)];
|
||||
mouseStartPos = FlxG.mouse.getWorldPosition();
|
||||
}
|
||||
|
||||
public override function startDrag() {
|
||||
super.startDrag();
|
||||
|
||||
if (_dragToSelectEnabled) {
|
||||
var plugin = FlxG.plugins.get(DragToSelectPlugin);
|
||||
if (plugin.selectedSprites().indexOf(this) == -1)
|
||||
plugin.deselectSprites();
|
||||
}
|
||||
|
||||
resetStartPos();
|
||||
}
|
||||
|
||||
public override function stopDrag() {
|
||||
super.stopDrag();
|
||||
}
|
||||
|
||||
private var rotationPadding = new FlxPoint();
|
||||
public function getRotationPadding() {
|
||||
return rotationPadding.copyTo();
|
||||
}
|
||||
|
||||
public override function loadRotatedGraphic(Graphic:FlxGraphicAsset, Rotations:Int = 16, Frame:Int = -1, AntiAliasing:Bool = false, AutoBuffer:Bool = false, ?Key:String) {
|
||||
var ow = frameWidth;
|
||||
var oh = frameHeight;
|
||||
var g = super.loadRotatedGraphic(Graphic, Rotations, Frame, AntiAliasing, AutoBuffer, Key);
|
||||
if (ow != frameWidth || oh != frameHeight) {
|
||||
rotationPadding.set(frameWidth - ow, frameHeight - oh).scale(0.5);
|
||||
}
|
||||
return g;
|
||||
}
|
||||
|
||||
public override function isSimpleRender(?camera:FlxCamera) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// For some reason this change to HaxeFlixel broke this code:
|
||||
// https://github.com/HaxeFlixel/flixel/commit/1c11ea1cbf56b5f9c44bc04c0b30b38e0fa23045?diff=split#diff-ca3dcf1bf29575d0e8931904cc90bacd182ffd1af266761804d18387dc5014dcL361
|
||||
// This function is adapted from the old code pre-change because
|
||||
// I don't have time to figure out if upstream flixel is broken now
|
||||
// and contribute a fix, or if the behavior is just different now.
|
||||
function oldRotate(point:FlxPoint, pivot:FlxPoint, degrees:Float) {
|
||||
var radians:Float = degrees * FlxAngle.TO_RAD;
|
||||
var sin:Float = FlxMath.fastSin(radians);
|
||||
var cos:Float = FlxMath.fastCos(radians);
|
||||
var dx:Float = point.x - pivot.x;
|
||||
var dy:Float = point.y - pivot.y;
|
||||
point.x = cos * dx - sin * dy + pivot.x;
|
||||
point.y = sin * dx + cos * dy + pivot.y;
|
||||
}
|
||||
|
||||
// Sleazy method just for Habit Puzzles
|
||||
public function rotate(deg:Float) {
|
||||
if (deg < 0) {
|
||||
deg += 360 * Math.ceil(Math.abs(deg / 360));
|
||||
}
|
||||
function _rot(s:KissExtendedSprite, deg) {
|
||||
var angle = (s.angle + deg) % 360;
|
||||
s.angle = angle;
|
||||
if (s != this) {
|
||||
var thisCenter = new FlxPoint(x + origin.x, y + origin.y);
|
||||
var sCenter = new FlxPoint(s.x + s.origin.x, s.y + s.origin.y);
|
||||
var offset = sCenter.subtractPoint(thisCenter);
|
||||
oldRotate(offset, new FlxPoint(0, 0), deg);
|
||||
s.x = thisCenter.x + offset.x - s.origin.x;
|
||||
s.y = thisCenter.y + offset.y - s.origin.y;
|
||||
}
|
||||
}
|
||||
_rot(this, deg);
|
||||
for (c in connectedAndSelectedSprites()) {
|
||||
if (c != this) {
|
||||
_rot(c, deg);
|
||||
}
|
||||
}
|
||||
resetStartPos();
|
||||
}
|
||||
|
||||
var _dragToSelectEnabled = false;
|
||||
public var onSelected:Void->Void = null;
|
||||
public var onDeselected:Void->Void;
|
||||
public function enableDragToSelect(?onSelected:Void->Void, ?onDeselected:Void->Void, ?state:FlxState, ?camera:FlxCamera) {
|
||||
this.onSelected = onSelected;
|
||||
this.onDeselected = onDeselected;
|
||||
var plugin = FlxG.plugins.get(DragToSelectPlugin);
|
||||
if (plugin == null) {
|
||||
plugin = new DragToSelectPlugin();
|
||||
FlxG.plugins.add(plugin);
|
||||
}
|
||||
plugin.enableSprite(this, state, camera);
|
||||
_dragToSelectEnabled = true;
|
||||
}
|
||||
public function disableDragToSelect(?state:FlxState) {
|
||||
var plugin = FlxG.plugins.get(DragToSelectPlugin);
|
||||
plugin.disableSprite(this, state);
|
||||
_dragToSelectEnabled = false;
|
||||
}
|
||||
|
||||
public override function destroy() {
|
||||
if (_dragToSelectEnabled)
|
||||
disableDragToSelect();
|
||||
super.destroy();
|
||||
}
|
||||
|
||||
public override function update(elapsed:Float) {
|
||||
#if debug
|
||||
// color = (mouseOver && pixelPerfect(_dragPixelPerfectAlpha)) ? FlxColor.LIME : FlxColor.WHITE;
|
||||
#end
|
||||
super.update(elapsed);
|
||||
}
|
||||
|
||||
override function updateDrag() {
|
||||
var mouseTotalMovement = FlxG.mouse.getWorldPosition().subtractPoint(mouseStartPos);
|
||||
var nextPos = dragStartPos.copyTo().addPoint(mouseTotalMovement);
|
||||
x = nextPos.x;
|
||||
y = nextPos.y;
|
||||
var l = connectedAndSelectedSprites();
|
||||
for (i in 0...l.length) {
|
||||
var sprite = l[i];
|
||||
var startPos = connectedSpritesStartPos[i];
|
||||
var nextPos = startPos.copyTo().addPoint(mouseTotalMovement);
|
||||
sprite.x = nextPos.x;
|
||||
sprite.y = nextPos.y;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public function pixelPerfectDrag() {
|
||||
return _dragPixelPerfect;
|
||||
}
|
||||
|
||||
public function pixelPerfectAlpha() {
|
||||
return _dragPixelPerfectAlpha;
|
||||
}
|
||||
|
||||
function thisCamera() {
|
||||
if (cameras != null && cameras.length > 0)
|
||||
return cameras[0];
|
||||
return FlxG.camera;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#if FLX_MOUSE
|
||||
override function get_mouseOver() {
|
||||
var mouseOver = getScreenBounds(thisCamera()).containsPoint(FlxG.mouse.getScreenPosition(thisCamera()));
|
||||
|
||||
return mouseOver;
|
||||
}
|
||||
|
||||
function pixelPerfect(alpha) {
|
||||
return pixelPerfectPointCheck(Math.floor(FlxG.mouse.x), Math.floor(FlxG.mouse.y), this, alpha);
|
||||
}
|
||||
|
||||
static function pixelPerfectPointCheck(PointX:Int, PointY:Int, Target:FlxSprite, AlphaTolerance:Int = 1):Bool
|
||||
{
|
||||
if (FlxG.renderTile)
|
||||
{
|
||||
Target.drawFrame();
|
||||
}
|
||||
|
||||
// How deep is pointX/Y within the rect?
|
||||
var test:BitmapData = Target.framePixels;
|
||||
|
||||
var pixelAlpha = FlxColor.fromInt(test.getPixel32(Math.floor(PointX - Target.x), Math.floor(PointY - Target.y))).alpha;
|
||||
|
||||
if (FlxG.renderTile)
|
||||
{
|
||||
pixelAlpha = Std.int(pixelAlpha * Target.alpha);
|
||||
}
|
||||
|
||||
// How deep is pointX/Y within the rect?
|
||||
return pixelAlpha >= AlphaTolerance;
|
||||
}
|
||||
|
||||
override function checkForClick():Void
|
||||
{
|
||||
#if FLX_MOUSE
|
||||
if (mouseOver && FlxG.mouse.justPressed)
|
||||
{
|
||||
// If we don't need a pixel perfect check, then don't bother running one! By this point we know the mouse is over the sprite already
|
||||
if (_clickPixelPerfect == false && _dragPixelPerfect == false)
|
||||
{
|
||||
FlxMouseControl.addToStack(this);
|
||||
return;
|
||||
}
|
||||
|
||||
if (_clickPixelPerfect && pixelPerfect(_clickPixelPerfectAlpha))
|
||||
{
|
||||
FlxMouseControl.addToStack(this);
|
||||
return;
|
||||
}
|
||||
|
||||
if (_dragPixelPerfect && pixelPerfect(_dragPixelPerfectAlpha))
|
||||
{
|
||||
FlxMouseControl.addToStack(this);
|
||||
return;
|
||||
}
|
||||
}
|
||||
#end
|
||||
}
|
||||
#end
|
||||
}
|
@@ -1,989 +0,0 @@
|
||||
package kiss_flixel;
|
||||
|
||||
import flash.errors.Error;
|
||||
import flash.events.KeyboardEvent;
|
||||
import flash.geom.Rectangle;
|
||||
import flixel.addons.ui.FlxUI.NamedString;
|
||||
import flixel.FlxG;
|
||||
import flixel.FlxSprite;
|
||||
import flixel.math.FlxPoint;
|
||||
import flixel.math.FlxRect;
|
||||
import flixel.text.FlxText;
|
||||
import flixel.util.FlxColor;
|
||||
import flixel.util.FlxDestroyUtil;
|
||||
import flixel.util.FlxTimer;
|
||||
import flixel.FlxCamera;
|
||||
|
||||
/**
|
||||
* KissInputText is based on FlxInputText.
|
||||
*
|
||||
* It is modified to be compatible with kiss_flixel's SimpleWindow
|
||||
*
|
||||
* FlxInputText v1.11, ported to Haxe
|
||||
* @author larsiusprime, (Lars Doucet)
|
||||
* @link http://github.com/haxeflixel/flixel-ui
|
||||
*
|
||||
* FlxInputText v1.10, Input text field extension for Flixel
|
||||
* @author Gama11, Mr_Walrus, nitram_cero (Martín Sebastián Wain)
|
||||
* @link http://forums.flixel.org/index.php/topic,272.0.html
|
||||
*
|
||||
* Copyright (c) 2009 Martín Sebastián Wain
|
||||
* License: Creative Commons Attribution 3.0 United States
|
||||
* @link http://creativecommons.org/licenses/by/3.0/us/
|
||||
*/
|
||||
class KissInputText extends FlxText
|
||||
{
|
||||
public static inline var NO_FILTER:Int = 0;
|
||||
public static inline var ONLY_ALPHA:Int = 1;
|
||||
public static inline var ONLY_NUMERIC:Int = 2;
|
||||
public static inline var ONLY_ALPHANUMERIC:Int = 3;
|
||||
public static inline var CUSTOM_FILTER:Int = 4;
|
||||
|
||||
public static inline var ALL_CASES:Int = 0;
|
||||
public static inline var UPPER_CASE:Int = 1;
|
||||
public static inline var LOWER_CASE:Int = 2;
|
||||
|
||||
public static inline var BACKSPACE_ACTION:String = "backspace"; // press backspace
|
||||
public static inline var DELETE_ACTION:String = "delete"; // press delete
|
||||
public static inline var ENTER_ACTION:String = "enter"; // press enter
|
||||
public static inline var INPUT_ACTION:String = "input"; // manually edit
|
||||
|
||||
/**
|
||||
* This regular expression will filter out (remove) everything that matches.
|
||||
* Automatically sets filterMode = FlxInputText.CUSTOM_FILTER.
|
||||
*/
|
||||
public var customFilterPattern(default, set):EReg;
|
||||
|
||||
function set_customFilterPattern(cfp:EReg)
|
||||
{
|
||||
customFilterPattern = cfp;
|
||||
filterMode = CUSTOM_FILTER;
|
||||
return customFilterPattern;
|
||||
}
|
||||
|
||||
/**
|
||||
* A function called whenever the value changes from user input, or enter is pressed
|
||||
*/
|
||||
public var callback:String->String->Void;
|
||||
|
||||
/**
|
||||
* Whether or not the textbox has a background
|
||||
*/
|
||||
public var background:Bool = false;
|
||||
|
||||
/**
|
||||
* The caret's color. Has the same color as the text by default.
|
||||
*/
|
||||
public var caretColor(default, set):Int;
|
||||
|
||||
function set_caretColor(i:Int):Int
|
||||
{
|
||||
caretColor = i;
|
||||
dirty = true;
|
||||
return caretColor;
|
||||
}
|
||||
|
||||
public var caretWidth(default, set):Int = 1;
|
||||
|
||||
function set_caretWidth(i:Int):Int
|
||||
{
|
||||
caretWidth = i;
|
||||
dirty = true;
|
||||
return caretWidth;
|
||||
}
|
||||
|
||||
public var params(default, set):Array<Dynamic>;
|
||||
|
||||
/**
|
||||
* Whether or not the textfield is a password textfield
|
||||
*/
|
||||
public var passwordMode(get, set):Bool;
|
||||
|
||||
/**
|
||||
* Whether or not the text box is the active object on the screen.
|
||||
*/
|
||||
public var hasFocus(default, set):Bool = false;
|
||||
|
||||
/**
|
||||
* The position of the selection cursor. An index of 0 means the carat is before the character at index 0.
|
||||
*/
|
||||
public var caretIndex(default, set):Int = 0;
|
||||
|
||||
/**
|
||||
* callback that is triggered when this text field gets focus
|
||||
* @since 2.2.0
|
||||
*/
|
||||
public var focusGained:Void->Void;
|
||||
|
||||
/**
|
||||
* callback that is triggered when this text field loses focus
|
||||
* @since 2.2.0
|
||||
*/
|
||||
public var focusLost:Void->Void;
|
||||
|
||||
/**
|
||||
* The Case that's being enforced. Either ALL_CASES, UPPER_CASE or LOWER_CASE.
|
||||
*/
|
||||
public var forceCase(default, set):Int = ALL_CASES;
|
||||
|
||||
/**
|
||||
* Set the maximum length for the field (e.g. "3"
|
||||
* for Arcade type hi-score initials). 0 means unlimited.
|
||||
*/
|
||||
public var maxLength(default, set):Int = 0;
|
||||
|
||||
/**
|
||||
* Change the amount of lines that are allowed.
|
||||
*/
|
||||
public var lines(default, set):Int;
|
||||
|
||||
/**
|
||||
* Defines what text to filter. It can be NO_FILTER, ONLY_ALPHA, ONLY_NUMERIC, ONLY_ALPHA_NUMERIC or CUSTOM_FILTER
|
||||
* (Remember to append "FlxInputText." as a prefix to those constants)
|
||||
*/
|
||||
public var filterMode(default, set):Int = NO_FILTER;
|
||||
|
||||
/**
|
||||
* The color of the fieldBorders
|
||||
*/
|
||||
public var fieldBorderColor(default, set):Int = FlxColor.BLACK;
|
||||
|
||||
/**
|
||||
* The thickness of the fieldBorders
|
||||
*/
|
||||
public var fieldBorderThickness(default, set):Int = 1;
|
||||
|
||||
/**
|
||||
* The color of the background of the textbox.
|
||||
*/
|
||||
public var backgroundColor(default, set):Int = FlxColor.WHITE;
|
||||
|
||||
/**
|
||||
* A FlxSprite representing the background sprite
|
||||
*/
|
||||
private var backgroundSprite:FlxSprite;
|
||||
|
||||
/**
|
||||
* A timer for the flashing caret effect.
|
||||
*/
|
||||
private var _caretTimer:FlxTimer;
|
||||
|
||||
/**
|
||||
* A FlxSprite representing the flashing caret when editing text.
|
||||
*/
|
||||
private var caret:FlxSprite;
|
||||
|
||||
/**
|
||||
* A FlxSprite representing the fieldBorders.
|
||||
*/
|
||||
private var fieldBorderSprite:FlxSprite;
|
||||
|
||||
/**
|
||||
* The left- and right- most fully visible character indeces
|
||||
*/
|
||||
private var _scrollBoundIndeces:{left:Int, right:Int} = {left: 0, right: 0};
|
||||
|
||||
// workaround to deal with non-availability of getCharIndexAtPoint or getCharBoundaries on cpp/neko targets
|
||||
private var _charBoundaries:Array<FlxRect>;
|
||||
|
||||
/**
|
||||
* Stores last input text scroll.
|
||||
*/
|
||||
private var lastScroll:Int;
|
||||
|
||||
/**
|
||||
* @param X The X position of the text.
|
||||
* @param Y The Y position of the text.
|
||||
* @param Width The width of the text object (height is determined automatically).
|
||||
* @param Text The actual text you would like to display initially.
|
||||
* @param size Initial size of the font
|
||||
* @param TextColor The color of the text
|
||||
* @param BackgroundColor The color of the background (FlxColor.TRANSPARENT for no background color)
|
||||
* @param EmbeddedFont Whether this text field uses embedded fonts or not
|
||||
*/
|
||||
public function new(X:Float = 0, Y:Float = 0, Width:Int = 150, ?Text:String, size:Int = 8, TextColor:Int = FlxColor.BLACK,
|
||||
BackgroundColor:Int = FlxColor.WHITE, EmbeddedFont:Bool = true)
|
||||
{
|
||||
super(X, Y, Width, Text, size, EmbeddedFont);
|
||||
backgroundColor = BackgroundColor;
|
||||
|
||||
if (BackgroundColor != FlxColor.TRANSPARENT)
|
||||
{
|
||||
background = true;
|
||||
}
|
||||
|
||||
color = TextColor;
|
||||
caretColor = TextColor;
|
||||
|
||||
caret = new FlxSprite();
|
||||
caret.makeGraphic(caretWidth, Std.int(size + 2));
|
||||
_caretTimer = new FlxTimer();
|
||||
|
||||
caretIndex = 0;
|
||||
hasFocus = false;
|
||||
if (background)
|
||||
{
|
||||
fieldBorderSprite = new FlxSprite(X, Y);
|
||||
backgroundSprite = new FlxSprite(X, Y);
|
||||
}
|
||||
|
||||
lines = 1;
|
||||
FlxG.stage.addEventListener(KeyboardEvent.KEY_DOWN, onKeyDown);
|
||||
|
||||
if (Text == null)
|
||||
{
|
||||
Text = "";
|
||||
}
|
||||
|
||||
text = Text; // ensure set_text is called to avoid bugs (like not preparing _charBoundaries on sys target, making it impossible to click)
|
||||
|
||||
calcFrame();
|
||||
}
|
||||
|
||||
/**
|
||||
* Clean up memory
|
||||
*/
|
||||
override public function destroy():Void
|
||||
{
|
||||
FlxG.stage.removeEventListener(KeyboardEvent.KEY_DOWN, onKeyDown);
|
||||
|
||||
backgroundSprite = FlxDestroyUtil.destroy(backgroundSprite);
|
||||
fieldBorderSprite = FlxDestroyUtil.destroy(fieldBorderSprite);
|
||||
callback = null;
|
||||
|
||||
#if sys
|
||||
if (_charBoundaries != null)
|
||||
{
|
||||
while (_charBoundaries.length > 0)
|
||||
{
|
||||
_charBoundaries.pop();
|
||||
}
|
||||
_charBoundaries = null;
|
||||
}
|
||||
#end
|
||||
|
||||
super.destroy();
|
||||
}
|
||||
|
||||
/**
|
||||
* Draw the caret in addition to the text.
|
||||
*/
|
||||
override public function draw():Void
|
||||
{
|
||||
drawSprite(fieldBorderSprite);
|
||||
drawSprite(backgroundSprite);
|
||||
|
||||
super.draw();
|
||||
|
||||
// In case caretColor was changed
|
||||
if (caretColor != caret.color || caret.height != size + 2)
|
||||
{
|
||||
caret.color = caretColor;
|
||||
}
|
||||
|
||||
drawSprite(caret);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function that makes sure sprites are drawn up even though they haven't been added.
|
||||
* @param Sprite The Sprite to be drawn.
|
||||
*/
|
||||
private function drawSprite(Sprite:FlxSprite):Void
|
||||
{
|
||||
if (Sprite != null && Sprite.visible)
|
||||
{
|
||||
Sprite.scrollFactor = scrollFactor;
|
||||
Sprite.cameras = cameras;
|
||||
Sprite.draw();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles keypresses generated on the stage.
|
||||
*/
|
||||
private function onKeyDown(e:KeyboardEvent):Void
|
||||
{
|
||||
var key:Int = e.keyCode;
|
||||
|
||||
if (hasFocus)
|
||||
{
|
||||
// Do nothing for Shift, Ctrl, Esc, and flixel console hotkey
|
||||
if (key == 16 || key == 17 || key == 220 || key == 27)
|
||||
{
|
||||
return;
|
||||
}
|
||||
// Left arrow
|
||||
else if (key == 37)
|
||||
{
|
||||
if (caretIndex > 0)
|
||||
{
|
||||
caretIndex--;
|
||||
text = text; // forces scroll update
|
||||
}
|
||||
}
|
||||
// Right arrow
|
||||
else if (key == 39)
|
||||
{
|
||||
if (caretIndex < text.length)
|
||||
{
|
||||
caretIndex++;
|
||||
text = text; // forces scroll update
|
||||
}
|
||||
}
|
||||
// End key
|
||||
else if (key == 35)
|
||||
{
|
||||
caretIndex = text.length;
|
||||
text = text; // forces scroll update
|
||||
}
|
||||
// Home key
|
||||
else if (key == 36)
|
||||
{
|
||||
caretIndex = 0;
|
||||
text = text;
|
||||
}
|
||||
// Backspace
|
||||
else if (key == 8)
|
||||
{
|
||||
if (caretIndex > 0)
|
||||
{
|
||||
caretIndex--;
|
||||
text = text.substring(0, caretIndex) + text.substring(caretIndex + 1);
|
||||
onChange(BACKSPACE_ACTION);
|
||||
}
|
||||
}
|
||||
// Delete
|
||||
else if (key == 46)
|
||||
{
|
||||
if (text.length > 0 && caretIndex < text.length)
|
||||
{
|
||||
text = text.substring(0, caretIndex) + text.substring(caretIndex + 1);
|
||||
onChange(DELETE_ACTION);
|
||||
}
|
||||
}
|
||||
// Enter
|
||||
else if (key == 13)
|
||||
{
|
||||
onChange(ENTER_ACTION);
|
||||
}
|
||||
// Actually add some text
|
||||
else
|
||||
{
|
||||
if (e.charCode == 0) // non-printable characters crash String.fromCharCode
|
||||
{
|
||||
return;
|
||||
}
|
||||
var newText:String = filter(String.fromCharCode(e.charCode));
|
||||
|
||||
if (newText.length > 0 && (maxLength == 0 || (text.length + newText.length) < maxLength))
|
||||
{
|
||||
text = insertSubstring(text, newText, caretIndex);
|
||||
caretIndex++;
|
||||
onChange(INPUT_ACTION);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function onChange(action:String):Void
|
||||
{
|
||||
if (callback != null)
|
||||
{
|
||||
callback(text, action);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Inserts a substring into a string at a specific index
|
||||
*
|
||||
* @param Insert The string to have something inserted into
|
||||
* @param Insert The string to insert
|
||||
* @param Index The index to insert at
|
||||
* @return Returns the joined string for chaining.
|
||||
*/
|
||||
private function insertSubstring(Original:String, Insert:String, Index:Int):String
|
||||
{
|
||||
if (Index != Original.length)
|
||||
{
|
||||
Original = Original.substring(0, Index) + (Insert) + (Original.substring(Index));
|
||||
}
|
||||
else
|
||||
{
|
||||
Original = Original + (Insert);
|
||||
}
|
||||
return Original;
|
||||
}
|
||||
|
||||
var reusablePoint:FlxPoint = new FlxPoint();
|
||||
var reusableRect:FlxRect = new FlxRect();
|
||||
|
||||
/**
|
||||
* Gets the index of the character in this box under the mouse cursor
|
||||
* @return The index of the character.
|
||||
* between 0 and the length of the text
|
||||
*/
|
||||
public function getCaretIndex(camera:FlxCamera):Int
|
||||
{
|
||||
#if FLX_MOUSE
|
||||
var bounds = getScreenBounds(reusableRect, camera);
|
||||
var mousePos = FlxG.mouse.getScreenPosition(camera, reusablePoint);
|
||||
var hit = FlxPoint.get(mousePos.x - bounds.x, mousePos.y - bounds.y);
|
||||
return getCharIndexAtPoint(hit.x, hit.y);
|
||||
#else
|
||||
return 0;
|
||||
#end
|
||||
}
|
||||
|
||||
private function getCharBoundaries(charIndex:Int):Rectangle
|
||||
{
|
||||
if (_charBoundaries != null && charIndex >= 0 && _charBoundaries.length > 0)
|
||||
{
|
||||
var r:Rectangle = new Rectangle();
|
||||
if (charIndex >= _charBoundaries.length)
|
||||
{
|
||||
_charBoundaries[_charBoundaries.length - 1].copyToFlash(r);
|
||||
}
|
||||
else
|
||||
{
|
||||
_charBoundaries[charIndex].copyToFlash(r);
|
||||
}
|
||||
return r;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private override function set_text(Text:String):String
|
||||
{
|
||||
#if !js
|
||||
if (textField != null)
|
||||
{
|
||||
lastScroll = textField.scrollH;
|
||||
}
|
||||
#end
|
||||
var return_text:String = super.set_text(Text);
|
||||
|
||||
if (textField == null)
|
||||
{
|
||||
return return_text;
|
||||
}
|
||||
|
||||
var numChars:Int = Text.length;
|
||||
prepareCharBoundaries(numChars);
|
||||
textField.text = "";
|
||||
var textH:Float = 0;
|
||||
var textW:Float = 0;
|
||||
var lastW:Float = 0;
|
||||
|
||||
// Flash textFields have a "magic number" 2 pixel gutter all around
|
||||
// It does not seem to vary with font, size, border, etc, and does not seem to be customizable.
|
||||
// We simply reproduce this behavior here
|
||||
var magicX:Float = 2;
|
||||
var magicY:Float = 2;
|
||||
|
||||
for (i in 0...numChars)
|
||||
{
|
||||
textField.appendText(Text.substr(i, 1)); // add a character
|
||||
textW = textField.textWidth; // count up total text width
|
||||
if (i == 0)
|
||||
{
|
||||
textH = textField.textHeight; // count height after first char
|
||||
}
|
||||
_charBoundaries[i].x = magicX + lastW; // place x at end of last character
|
||||
_charBoundaries[i].y = magicY; // place y at zero
|
||||
_charBoundaries[i].width = (textW - lastW); // place width at (width so far) minus (last char's end point)
|
||||
_charBoundaries[i].height = textH;
|
||||
lastW = textW;
|
||||
}
|
||||
textField.text = Text;
|
||||
onSetTextCheck();
|
||||
return return_text;
|
||||
}
|
||||
|
||||
private function getCharIndexAtPoint(X:Float, Y:Float):Int
|
||||
{
|
||||
var i:Int = 0;
|
||||
#if !js
|
||||
X += textField.scrollH + 2;
|
||||
#end
|
||||
|
||||
// offset X according to text alignment when there is no scroll.
|
||||
if (_charBoundaries != null && _charBoundaries.length > 0)
|
||||
{
|
||||
if (textField.textWidth <= textField.width)
|
||||
{
|
||||
switch (getAlignStr())
|
||||
{
|
||||
case RIGHT:
|
||||
X = X - textField.width + textField.textWidth
|
||||
;
|
||||
case CENTER:
|
||||
X = X - textField.width / 2 + textField.textWidth / 2
|
||||
;
|
||||
default:
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// place caret at matching char position
|
||||
if (_charBoundaries != null)
|
||||
{
|
||||
for (r in _charBoundaries)
|
||||
{
|
||||
if (X >= r.left && X <= r.right)
|
||||
{
|
||||
return i;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
// place caret at rightmost position
|
||||
if (_charBoundaries != null && _charBoundaries.length > 0)
|
||||
{
|
||||
if (X > textField.textWidth)
|
||||
{
|
||||
return _charBoundaries.length;
|
||||
}
|
||||
}
|
||||
|
||||
// place caret at leftmost position
|
||||
return 0;
|
||||
}
|
||||
|
||||
private function prepareCharBoundaries(numChars:Int):Void
|
||||
{
|
||||
if (_charBoundaries == null)
|
||||
{
|
||||
_charBoundaries = [];
|
||||
}
|
||||
|
||||
if (_charBoundaries.length > numChars)
|
||||
{
|
||||
var diff:Int = _charBoundaries.length - numChars;
|
||||
for (i in 0...diff)
|
||||
{
|
||||
_charBoundaries.pop();
|
||||
}
|
||||
}
|
||||
|
||||
for (i in 0...numChars)
|
||||
{
|
||||
if (_charBoundaries.length - 1 < i)
|
||||
{
|
||||
_charBoundaries.push(FlxRect.get(0, 0, 0, 0));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called every time the text is changed (for both flash/cpp) to update scrolling, etc
|
||||
*/
|
||||
private function onSetTextCheck():Void
|
||||
{
|
||||
#if !js
|
||||
var boundary:Rectangle = null;
|
||||
if (caretIndex == -1)
|
||||
{
|
||||
boundary = getCharBoundaries(text.length - 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
boundary = getCharBoundaries(caretIndex);
|
||||
}
|
||||
|
||||
if (boundary != null)
|
||||
{
|
||||
// Checks if carret is out of textfield bounds
|
||||
// if it is update scroll, otherwise maintain the same scroll as last check.
|
||||
var diffW:Int = 0;
|
||||
if (boundary.right > lastScroll + textField.width - 2)
|
||||
{
|
||||
diffW = -Std.int((textField.width - 2) - boundary.right); // caret to the right of textfield.
|
||||
}
|
||||
else if (boundary.left < lastScroll)
|
||||
{
|
||||
diffW = Std.int(boundary.left) - 2; // caret to the left of textfield
|
||||
}
|
||||
else
|
||||
{
|
||||
diffW = lastScroll; // no scroll change
|
||||
}
|
||||
|
||||
#if !js
|
||||
textField.scrollH = diffW;
|
||||
#end
|
||||
calcFrame();
|
||||
}
|
||||
#end
|
||||
}
|
||||
|
||||
/**
|
||||
* Draws the frame of animation for the input text.
|
||||
*
|
||||
* @param RunOnCpp Whether the frame should also be recalculated if we're on a non-flash target
|
||||
*/
|
||||
private override function calcFrame(RunOnCpp:Bool = false):Void
|
||||
{
|
||||
super.calcFrame(RunOnCpp);
|
||||
|
||||
if (fieldBorderSprite != null)
|
||||
{
|
||||
if (fieldBorderThickness > 0)
|
||||
{
|
||||
fieldBorderSprite.makeGraphic(Std.int(width + fieldBorderThickness * 2), Std.int(height + fieldBorderThickness * 2), fieldBorderColor);
|
||||
fieldBorderSprite.x = x - fieldBorderThickness;
|
||||
fieldBorderSprite.y = y - fieldBorderThickness;
|
||||
}
|
||||
else if (fieldBorderThickness == 0)
|
||||
{
|
||||
fieldBorderSprite.visible = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (backgroundSprite != null)
|
||||
{
|
||||
if (background)
|
||||
{
|
||||
backgroundSprite.makeGraphic(Std.int(width), Std.int(height), backgroundColor);
|
||||
backgroundSprite.x = x;
|
||||
backgroundSprite.y = y;
|
||||
}
|
||||
else
|
||||
{
|
||||
backgroundSprite.visible = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (caret != null)
|
||||
{
|
||||
// Generate the properly sized caret and also draw a border that matches that of the textfield (if a border style is set)
|
||||
// borderQuality can be safely ignored since the caret is always a rectangle
|
||||
|
||||
var cw:Int = caretWidth; // Basic size of the caret
|
||||
var ch:Int = Std.int(size + 2);
|
||||
|
||||
// Make sure alpha channels are correctly set
|
||||
var borderC:Int = (0xff000000 | (borderColor & 0x00ffffff));
|
||||
var caretC:Int = (0xff000000 | (caretColor & 0x00ffffff));
|
||||
|
||||
// Generate unique key for the caret so we don't cause weird bugs if someone makes some random flxsprite of this size and color
|
||||
var caretKey:String = "caret" + cw + "x" + ch + "c:" + caretC + "b:" + borderStyle + "," + borderSize + "," + borderC;
|
||||
switch (borderStyle)
|
||||
{
|
||||
case NONE:
|
||||
// No border, just make the caret
|
||||
caret.makeGraphic(cw, ch, caretC, false, caretKey);
|
||||
caret.offset.x = caret.offset.y = 0;
|
||||
|
||||
case SHADOW:
|
||||
// Shadow offset to the lower-right
|
||||
cw += Std.int(borderSize);
|
||||
ch += Std.int(borderSize); // expand canvas on one side for shadow
|
||||
caret.makeGraphic(cw, ch, FlxColor.TRANSPARENT, false, caretKey); // start with transparent canvas
|
||||
var r:Rectangle = new Rectangle(borderSize, borderSize, caretWidth, Std.int(size + 2));
|
||||
caret.pixels.fillRect(r, borderC); // draw shadow
|
||||
r.x = r.y = 0;
|
||||
caret.pixels.fillRect(r, caretC); // draw caret
|
||||
caret.offset.x = caret.offset.y = 0;
|
||||
|
||||
case OUTLINE_FAST, OUTLINE:
|
||||
// Border all around it
|
||||
cw += Std.int(borderSize * 2);
|
||||
ch += Std.int(borderSize * 2); // expand canvas on both sides
|
||||
caret.makeGraphic(cw, ch, borderC, false, caretKey); // start with borderColor canvas
|
||||
var r = new Rectangle(borderSize, borderSize, caretWidth, Std.int(size + 2));
|
||||
caret.pixels.fillRect(r, caretC); // draw caret
|
||||
// we need to offset caret's drawing position since the caret is now larger than normal
|
||||
caret.offset.x = caret.offset.y = borderSize;
|
||||
}
|
||||
// Update width/height so caret's dimensions match its pixels
|
||||
caret.width = cw;
|
||||
caret.height = ch;
|
||||
|
||||
caretIndex = caretIndex; // force this to update
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Turns the caret on/off for the caret flashing animation.
|
||||
*/
|
||||
private function toggleCaret(timer:FlxTimer):Void
|
||||
{
|
||||
caret.visible = !caret.visible;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks an input string against the current
|
||||
* filter and returns a filtered string
|
||||
*/
|
||||
private function filter(text:String):String
|
||||
{
|
||||
if (forceCase == UPPER_CASE)
|
||||
{
|
||||
text = text.toUpperCase();
|
||||
}
|
||||
else if (forceCase == LOWER_CASE)
|
||||
{
|
||||
text = text.toLowerCase();
|
||||
}
|
||||
|
||||
if (filterMode != NO_FILTER)
|
||||
{
|
||||
var pattern:EReg;
|
||||
switch (filterMode)
|
||||
{
|
||||
case ONLY_ALPHA:
|
||||
pattern = ~/[^a-zA-Z]*/g;
|
||||
case ONLY_NUMERIC:
|
||||
pattern = ~/[^0-9]*/g;
|
||||
case ONLY_ALPHANUMERIC:
|
||||
pattern = ~/[^a-zA-Z0-9]*/g;
|
||||
case CUSTOM_FILTER:
|
||||
pattern = customFilterPattern;
|
||||
default:
|
||||
throw new Error("FlxInputText: Unknown filterMode (" + filterMode + ")");
|
||||
}
|
||||
text = pattern.replace(text, "");
|
||||
}
|
||||
return text;
|
||||
}
|
||||
|
||||
private function set_params(p:Array<Dynamic>):Array<Dynamic>
|
||||
{
|
||||
params = p;
|
||||
if (params == null)
|
||||
{
|
||||
params = [];
|
||||
}
|
||||
var namedValue:NamedString = {name: "value", value: text};
|
||||
params.push(namedValue);
|
||||
return p;
|
||||
}
|
||||
|
||||
private override function set_x(X:Float):Float
|
||||
{
|
||||
if ((fieldBorderSprite != null) && fieldBorderThickness > 0)
|
||||
{
|
||||
fieldBorderSprite.x = X - fieldBorderThickness;
|
||||
}
|
||||
if ((backgroundSprite != null) && background)
|
||||
{
|
||||
backgroundSprite.x = X;
|
||||
}
|
||||
return super.set_x(X);
|
||||
}
|
||||
|
||||
private override function set_y(Y:Float):Float
|
||||
{
|
||||
if ((fieldBorderSprite != null) && fieldBorderThickness > 0)
|
||||
{
|
||||
fieldBorderSprite.y = Y - fieldBorderThickness;
|
||||
}
|
||||
if ((backgroundSprite != null) && background)
|
||||
{
|
||||
backgroundSprite.y = Y;
|
||||
}
|
||||
return super.set_y(Y);
|
||||
}
|
||||
|
||||
private function set_hasFocus(newFocus:Bool):Bool
|
||||
{
|
||||
if (newFocus)
|
||||
{
|
||||
if (hasFocus != newFocus)
|
||||
{
|
||||
_caretTimer = new FlxTimer().start(0.5, toggleCaret, 0);
|
||||
caret.visible = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Graphics
|
||||
caret.visible = false;
|
||||
if (_caretTimer != null)
|
||||
{
|
||||
_caretTimer.cancel();
|
||||
}
|
||||
}
|
||||
|
||||
if (newFocus != hasFocus)
|
||||
{
|
||||
calcFrame();
|
||||
}
|
||||
return hasFocus = newFocus;
|
||||
}
|
||||
|
||||
private function getAlignStr():FlxTextAlign
|
||||
{
|
||||
var alignStr:FlxTextAlign = LEFT;
|
||||
if (_defaultFormat != null && _defaultFormat.align != null)
|
||||
{
|
||||
alignStr = alignment;
|
||||
}
|
||||
return alignStr;
|
||||
}
|
||||
|
||||
private function set_caretIndex(newCaretIndex:Int):Int
|
||||
{
|
||||
var offx:Float = 0;
|
||||
|
||||
var alignStr:FlxTextAlign = getAlignStr();
|
||||
|
||||
switch (alignStr)
|
||||
{
|
||||
case RIGHT:
|
||||
offx = textField.width - 2 - textField.textWidth - 2;
|
||||
if (offx < 0)
|
||||
offx = 0; // hack, fix negative offset.
|
||||
|
||||
case CENTER:
|
||||
#if !js
|
||||
offx = (textField.width - 2 - textField.textWidth) / 2 + textField.scrollH / 2;
|
||||
#end
|
||||
if (offx <= 1)
|
||||
offx = 0; // hack, fix ofset rounding alignment.
|
||||
|
||||
default:
|
||||
offx = 0;
|
||||
}
|
||||
|
||||
caretIndex = newCaretIndex;
|
||||
|
||||
// If caret is too far to the right something is wrong
|
||||
if (caretIndex > (text.length + 1))
|
||||
{
|
||||
caretIndex = -1;
|
||||
}
|
||||
|
||||
// Caret is OK, proceed to position
|
||||
if (caretIndex != -1)
|
||||
{
|
||||
var boundaries:Rectangle = null;
|
||||
|
||||
// Caret is not to the right of text
|
||||
if (caretIndex < text.length)
|
||||
{
|
||||
boundaries = getCharBoundaries(caretIndex);
|
||||
if (boundaries != null)
|
||||
{
|
||||
caret.x = offx + boundaries.left + x;
|
||||
caret.y = boundaries.top + y;
|
||||
}
|
||||
}
|
||||
// Caret is to the right of text
|
||||
else
|
||||
{
|
||||
boundaries = getCharBoundaries(caretIndex - 1);
|
||||
if (boundaries != null)
|
||||
{
|
||||
caret.x = offx + boundaries.right + x;
|
||||
caret.y = boundaries.top + y;
|
||||
}
|
||||
// Text box is empty
|
||||
else if (text.length == 0)
|
||||
{
|
||||
// 2 px gutters
|
||||
caret.x = x + offx + 2;
|
||||
caret.y = y + 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if !js
|
||||
caret.x -= textField.scrollH;
|
||||
#end
|
||||
|
||||
// Make sure the caret doesn't leave the textfield on single-line input texts
|
||||
if ((lines == 1) && (caret.x + caret.width) > (x + width))
|
||||
{
|
||||
caret.x = x + width - 2;
|
||||
}
|
||||
|
||||
return caretIndex;
|
||||
}
|
||||
|
||||
private function set_forceCase(Value:Int):Int
|
||||
{
|
||||
forceCase = Value;
|
||||
text = filter(text);
|
||||
return forceCase;
|
||||
}
|
||||
|
||||
override private function set_size(Value:Int):Int
|
||||
{
|
||||
super.size = Value;
|
||||
caret.makeGraphic(1, Std.int(size + 2));
|
||||
return Value;
|
||||
}
|
||||
|
||||
private function set_maxLength(Value:Int):Int
|
||||
{
|
||||
maxLength = Value;
|
||||
if (text.length > maxLength)
|
||||
{
|
||||
text = text.substring(0, maxLength);
|
||||
}
|
||||
return maxLength;
|
||||
}
|
||||
|
||||
private function set_lines(Value:Int):Int
|
||||
{
|
||||
if (Value == 0)
|
||||
return 0;
|
||||
|
||||
if (Value > 1)
|
||||
{
|
||||
textField.wordWrap = true;
|
||||
textField.multiline = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
textField.wordWrap = false;
|
||||
textField.multiline = false;
|
||||
}
|
||||
|
||||
lines = Value;
|
||||
calcFrame();
|
||||
return lines;
|
||||
}
|
||||
|
||||
private function get_passwordMode():Bool
|
||||
{
|
||||
return textField.displayAsPassword;
|
||||
}
|
||||
|
||||
private function set_passwordMode(value:Bool):Bool
|
||||
{
|
||||
textField.displayAsPassword = value;
|
||||
calcFrame();
|
||||
return value;
|
||||
}
|
||||
|
||||
private function set_filterMode(Value:Int):Int
|
||||
{
|
||||
filterMode = Value;
|
||||
text = filter(text);
|
||||
return filterMode;
|
||||
}
|
||||
|
||||
private function set_fieldBorderColor(Value:Int):Int
|
||||
{
|
||||
fieldBorderColor = Value;
|
||||
calcFrame();
|
||||
return fieldBorderColor;
|
||||
}
|
||||
|
||||
private function set_fieldBorderThickness(Value:Int):Int
|
||||
{
|
||||
fieldBorderThickness = Value;
|
||||
calcFrame();
|
||||
return fieldBorderThickness;
|
||||
}
|
||||
|
||||
private function set_backgroundColor(Value:Int):Int
|
||||
{
|
||||
backgroundColor = Value;
|
||||
calcFrame();
|
||||
return backgroundColor;
|
||||
}
|
||||
}
|
@@ -1,19 +0,0 @@
|
||||
package kiss_flixel;
|
||||
|
||||
import kiss.Prelude;
|
||||
import kiss.List;
|
||||
import flixel.FlxG;
|
||||
import flixel.FlxCamera;
|
||||
import flixel.ui.FlxButton;
|
||||
import kiss_flixel.KissInputText;
|
||||
import flixel.text.FlxText;
|
||||
import flixel.FlxSprite;
|
||||
import flixel.util.FlxColor;
|
||||
import flixel.group.FlxGroup;
|
||||
import kiss_tools.FlxKeyShortcutHandler;
|
||||
|
||||
typedef ShortcutAction = Void->Void;
|
||||
typedef Action = FlxSprite->Void;
|
||||
|
||||
@:build(kiss.Kiss.build())
|
||||
class SimpleWindow extends FlxSprite {}
|
@@ -1,368 +0,0 @@
|
||||
(loadFrom "kiss-tools" "src/kiss_tools/RefactorUtil.kiss")
|
||||
|
||||
// All windows share the same text size
|
||||
(var &mut textSize 16)
|
||||
(var :kiss.List<SimpleWindow> windowStack [])
|
||||
(var &mut :flixel.FlxCamera defaultCamera null)
|
||||
|
||||
(prop :FlxCamera controlCamera)
|
||||
|
||||
(prop &mut keyboardEnabled true)
|
||||
|
||||
// TODO tooltip support with left-click and right-click action
|
||||
// icons and explanations?
|
||||
|
||||
(defNew [&opt :String _title
|
||||
:FlxColor bgColor
|
||||
:FlxColor _textColor
|
||||
:Float percentWidth
|
||||
:Float percentHeight
|
||||
:Bool _xButton :String _xKey
|
||||
:String _leftKey :String _rightKey
|
||||
:ShortcutAction _onClose]
|
||||
|
||||
[:String title (or _title "")
|
||||
&mut :Float nextControlX 0
|
||||
&mut :Float nextControlY 0
|
||||
&mut :Int controlsPerColumn 0
|
||||
:FlxColor titleColor (or _textColor FlxColor.WHITE)
|
||||
&mut :FlxColor textColor (or _textColor FlxColor.WHITE)
|
||||
:Bool xButton ?_xButton
|
||||
:String xKey _xKey
|
||||
:String leftKey _leftKey
|
||||
:String rightKey _rightKey
|
||||
:ShortcutAction onClose _onClose
|
||||
:FlxTypedGroup<FlxSprite> controls (new FlxTypedGroup)
|
||||
:FlxKeyShortcutHandler<ShortcutAction> keyHandler (new FlxKeyShortcutHandler)
|
||||
// The xHandler exists so that when keyboard shortcuts are disabled,
|
||||
// UI key controls are still available. it also handles left and right.
|
||||
:FlxKeyShortcutHandler<ShortcutAction> xHandler (new FlxKeyShortcutHandler)]
|
||||
|
||||
(assert FlxG.camera "SimpleWindow.new() must be called in or after create()")
|
||||
(super 0 0)
|
||||
(when defaultCamera (set this.cameras [defaultCamera]))
|
||||
(makeGraphic
|
||||
(Std.int (* FlxG.width (or percentWidth 0.5)))
|
||||
(Std.int (* FlxG.height (or percentHeight 0.5)))
|
||||
(or bgColor FlxColor.BLACK))
|
||||
(screenCenter)
|
||||
|
||||
(set controlCamera (new FlxCamera (Std.int x) (Std.int y) (Std.int width) (Std.int height)))
|
||||
(set controlCamera.bgColor FlxColor.TRANSPARENT)
|
||||
|
||||
// Top-left corner for controls is (0,0) because a camera displays them
|
||||
(set nextControlX 0)
|
||||
(set nextControlY 0)
|
||||
|
||||
(let [textHeight
|
||||
.height (new FlxText 0 0 0 "a" textSize)]
|
||||
(set controlsPerColumn (Math.floor (/ height textHeight)))
|
||||
(-= controlsPerColumn 1) // Column at the bottom for left/right scroll arrows
|
||||
(when title (-= controlsPerColumn 1)))
|
||||
|
||||
(when title
|
||||
(set titleText (makeText title titleColor)))
|
||||
|
||||
(set keyHandler.onBadKey ->:Void [key context]
|
||||
(unless (= key xKey)
|
||||
(#when debug
|
||||
(print "bad key $key in context $context"))
|
||||
// TODO do SOMETHING like visual/audio bell, cancel and restart
|
||||
))
|
||||
(set keyHandler.onSelectItem
|
||||
->:Void [:ShortcutAction a] {
|
||||
(a)
|
||||
(keyHandler.start)
|
||||
})
|
||||
|
||||
(set xHandler.cancelKey null)
|
||||
(set xHandler.onBadKey ->:Void [key context] 0)
|
||||
(set xHandler.onSelectItem
|
||||
->:Void [:ShortcutAction a] {
|
||||
(a)
|
||||
(xHandler.start)
|
||||
})
|
||||
|
||||
(defAndCall method makeXControls
|
||||
(let [closeAction ->:Void {(hide)(when onClose (onClose))}]
|
||||
(when xButton
|
||||
(let [ftext (new FlxText width 0 0 "X" textSize)]
|
||||
(set ftext.cameras [controlCamera])
|
||||
(-= ftext.x ftext.width)
|
||||
(set ftext.color textColor)
|
||||
(dictSet _colors ftext ftext.color)
|
||||
(dictSet _actions ftext ->:Void _ (closeAction))
|
||||
(set xText ftext)
|
||||
(controls.add xText)))
|
||||
|
||||
(when xKey
|
||||
(when (= keyHandler.cancelKey xKey)
|
||||
(set keyHandler.cancelKey null))
|
||||
(xHandler.registerItem "{${xKey}}" closeAction true))))
|
||||
|
||||
// TODO show which shortcuts' prefixes are partially highlighted?
|
||||
)
|
||||
|
||||
(prop :FlxTypedGroup<KissInputText> inputTexts (new FlxTypedGroup))
|
||||
|
||||
(method addControl [:FlxSprite control]
|
||||
|
||||
(when (Std.isOfType control KissInputText)
|
||||
(inputTexts.add (cast control KissInputText)))
|
||||
(set control.cameras [controlCamera])
|
||||
(set control.x nextControlX)
|
||||
(set control.y nextControlY)
|
||||
(controls.add control)
|
||||
(+= nextControlY control.height)
|
||||
// TODO controls that aren't the same height as text will be able to vertically overflow
|
||||
(let [columnControls (controls.members.slice (if title 1 0))]
|
||||
// Don't count special controls as part of any column:
|
||||
(doFor c [xText leftText rightText]
|
||||
(when c (columnControls.remove c)))
|
||||
(doFor c columnTexts
|
||||
(when c (columnControls.remove c)))
|
||||
|
||||
(setNth columnWidths -1 (max (+ control.width textSize) (last columnWidths)))
|
||||
(when (and columnControls (= 0 (% columnControls.length controlsPerColumn)))
|
||||
(set nextControlY 0)
|
||||
(when title (+= nextControlY control.height))
|
||||
(+= nextControlX (last columnWidths))
|
||||
(columnWidths.push 0)
|
||||
(when (> (apply + columnWidths) width)
|
||||
(makeScrollArrows))))
|
||||
control)
|
||||
|
||||
(prop &mut :FlxText titleText)
|
||||
(prop &mut :FlxText leftText)
|
||||
(prop &mut :FlxText rightText)
|
||||
(prop &mut :Array<FlxText> columnTexts [])
|
||||
(prop &mut :FlxText xText)
|
||||
|
||||
(method columnTextStr [:Int column]
|
||||
(if (= cameraColumn column) ">${column}<" "$column"))
|
||||
|
||||
(method makeScrollArrows []
|
||||
(unless hasScrollArrows
|
||||
// The left arrow control is not added until the window scrolls right
|
||||
(let [ftext (new FlxText 0 height 0 "<-" textSize)]
|
||||
(set ftext.cameras [controlCamera])
|
||||
(-= ftext.y ftext.height)
|
||||
(set ftext.color textColor)
|
||||
(dictSet _colors ftext ftext.color)
|
||||
(dictSet _actions ftext ->:Void _ (scrollLeft))
|
||||
(set leftText ftext))
|
||||
(when leftKey
|
||||
(xHandler.registerItem "{${leftKey}}" scrollLeft true))
|
||||
(let [ftext (new FlxText width height 0 "->" textSize)]
|
||||
(set ftext.cameras [controlCamera])
|
||||
(-= ftext.x ftext.width)
|
||||
(-= ftext.y ftext.height)
|
||||
(set ftext.color textColor)
|
||||
(dictSet _colors ftext ftext.color)
|
||||
(controls.add ftext)
|
||||
(dictSet _actions ftext ->:Void _ (scrollRight))
|
||||
(set rightText ftext))
|
||||
(when rightKey
|
||||
(xHandler.registerItem "{${rightKey}}" scrollRight true))
|
||||
(refreshColumnTexts)
|
||||
|
||||
(set hasScrollArrows true))
|
||||
// A column could be added while the same window is shown.
|
||||
(refreshColumnTexts))
|
||||
|
||||
(method refreshColumnTexts []
|
||||
(doFor i (range columnWidths.length)
|
||||
(unless (> columnTexts.length i)
|
||||
(let [ftext (new FlxText (fHalf width) height 0 (columnTextStr i) textSize)]
|
||||
(set ftext.cameras [controlCamera])
|
||||
(-= ftext.x (fHalf ftext.width))
|
||||
(-= ftext.y ftext.height)
|
||||
(set ftext.color textColor)
|
||||
(dictSet _colors ftext ftext.color)
|
||||
(dictSet _actions ftext
|
||||
->:Void _
|
||||
(until (= cameraColumn i)
|
||||
(if (< cameraColumn i)
|
||||
(scrollRight)
|
||||
(scrollLeft))))
|
||||
(controls.add ftext)
|
||||
(columnTexts.push ftext)))
|
||||
(let [ftext (nth columnTexts i)]
|
||||
(set ftext.text (columnTextStr i))
|
||||
(set ftext.x (+ (fHalf width) controlCamera.scroll.x))
|
||||
(-= ftext.x (* (- (fHalf columnWidths.length) i) textSize 3))
|
||||
(when (= cameraColumn i) (-= ftext.x .width (new FlxText 0 0 0 ">" textSize))))))
|
||||
|
||||
(prop :Map<FlxSprite,Action> _actions (new Map))
|
||||
(prop :Map<FlxSprite,FlxColor> _colors (new Map))
|
||||
(method makeText [:String text &opt :FlxColor color :Action onClick :Bool noShortcut]
|
||||
(let [ftext (new FlxText nextControlX nextControlY 0 text textSize)]
|
||||
(set ftext.color (or color textColor))
|
||||
(dictSet _colors ftext ftext.color)
|
||||
(addControl ftext)
|
||||
(when onClick
|
||||
(dictSet _actions ftext onClick)
|
||||
// TODO right click?
|
||||
(unless noShortcut
|
||||
(keyHandler.registerItem text ->:Void (onClick ftext))))
|
||||
ftext))
|
||||
|
||||
// TODO makeButton
|
||||
// TODO make inputText
|
||||
|
||||
(prop &mut _shown false)
|
||||
(method isShown [] _shown)
|
||||
|
||||
(prop &mut :kiss.List<Float> columnWidths [0.0])
|
||||
(prop &mut cameraColumn 0)
|
||||
(prop &mut hasScrollArrows false)
|
||||
|
||||
(method clearControls []
|
||||
(set columnWidths [0.0])
|
||||
(set columnTexts [])
|
||||
(set hasScrollArrows false)
|
||||
(_actions.clear)
|
||||
(controls.clear)
|
||||
(inputTexts.clear)
|
||||
(keyHandler.clear)
|
||||
(makeXControls)
|
||||
(set nextControlX 0)
|
||||
(set nextControlY 0)
|
||||
(set titleText (makeText title titleColor)))
|
||||
|
||||
(method :Void show [&opt :Int _cameraColumn]
|
||||
(when (and _cameraColumn !(= cameraColumn _cameraColumn))
|
||||
(assert (<= 0 _cameraColumn (- columnWidths.length 1)) "Tried to show out-of-bounds camera column ${_cameraColumn} of ${columnWidths.length}")
|
||||
(while (> cameraColumn _cameraColumn)
|
||||
(scrollLeft))
|
||||
(while (< cameraColumn _cameraColumn)
|
||||
(scrollRight)))
|
||||
|
||||
(unless _shown
|
||||
(FlxG.cameras.add controlCamera)
|
||||
(FlxG.state.add this)
|
||||
(FlxG.state.add controls)
|
||||
(windowStack.push this)
|
||||
(keyHandler.start)
|
||||
(xHandler.start)
|
||||
(set _shown true)))
|
||||
|
||||
(method :Void hide []
|
||||
(when _shown
|
||||
(FlxG.cameras.remove controlCamera false)
|
||||
(FlxG.state.remove this)
|
||||
(FlxG.state.remove controls)
|
||||
(windowStack.remove this)
|
||||
(keyHandler.cancel)
|
||||
(xHandler.cancel)
|
||||
(set _shown false)))
|
||||
|
||||
(function getHighlighted [:FlxColor color &opt :Float amount]
|
||||
(unless amount (set amount 0.2))
|
||||
(cond ((> color.lightness amount)
|
||||
(color.getDarkened amount))
|
||||
(true
|
||||
(color.getLightened amount))))
|
||||
|
||||
(prop &mut otherIsSelected false)
|
||||
(method &override update [:Float elapsed]
|
||||
(super.update elapsed)
|
||||
(set otherIsSelected false)
|
||||
(when (= (last windowStack) this)
|
||||
(when keyboardEnabled
|
||||
(unless (apply or (for textBox inputTexts.members textBox.hasFocus))
|
||||
(keyHandler.update)))
|
||||
(xHandler.update)
|
||||
// Handle mouse input
|
||||
(let [mousePos (FlxG.mouse.getScreenPosition controlCamera)]
|
||||
// Click and hover on clickable text entries
|
||||
(controls.forEach ->text
|
||||
(whenLet [onClick (dictGet _actions text)]
|
||||
(let [color (dictGet _colors text)]
|
||||
(if (and !otherIsSelected (.containsPoint (text.getScreenBounds controlCamera) mousePos))
|
||||
{
|
||||
(when FlxG.mouse.justPressed
|
||||
(onClick text))
|
||||
(set otherIsSelected true)
|
||||
(set text.color (getHighlighted color))
|
||||
}
|
||||
{
|
||||
(set text.color color)
|
||||
}))))
|
||||
// Click on text boxes to focus them
|
||||
(inputTexts.forEach ->text
|
||||
(when FlxG.mouse.justPressed
|
||||
(when (.containsPoint (text.getScreenBounds controlCamera) mousePos)
|
||||
(inputTexts.forEach ->text (set text.hasFocus false))
|
||||
(set otherIsSelected true)
|
||||
(set text.caretIndex (text.getCaretIndex controlCamera))
|
||||
(set text.hasFocus true))))
|
||||
// Click anywhere else to take focus away from text boxes
|
||||
(when (and !otherIsSelected FlxG.mouse.justPressed)
|
||||
(inputTexts.forEach ->text (set text.hasFocus false))))))
|
||||
|
||||
(function :SimpleWindow promptForChoice <>[T] [:String prompt
|
||||
:Array<T> choices
|
||||
:T->Void onChoice
|
||||
&opt :FlxColor bgColor
|
||||
:FlxColor titleColor
|
||||
:FlxColor choiceColor
|
||||
:Float percentWidth
|
||||
:Float percentHeight
|
||||
:Bool xButton
|
||||
:String xKey
|
||||
:String leftKey
|
||||
:String rightKey
|
||||
:ShortcutAction onClose
|
||||
:Bool noShortcuts]
|
||||
(let [window (new SimpleWindow prompt bgColor titleColor percentWidth percentHeight xButton xKey leftKey rightKey onClose)
|
||||
choiceColor (or choiceColor titleColor FlxColor.WHITE)]
|
||||
(doFor choice choices
|
||||
(window.makeText (Std.string choice) choiceColor
|
||||
->:Void s {
|
||||
(window.hide)
|
||||
(onChoice choice)
|
||||
}
|
||||
noShortcuts))
|
||||
(window.show)
|
||||
window))
|
||||
|
||||
(method scrollLeft []
|
||||
(when (> cameraColumn 0)
|
||||
(-= cameraColumn 1)
|
||||
(when (= cameraColumn 0)
|
||||
(controls.remove leftText))
|
||||
(controls.add rightText)
|
||||
(let [scrollAmount (nth columnWidths cameraColumn)]
|
||||
(-= controlCamera.scroll.x scrollAmount)
|
||||
(when titleText
|
||||
(-= titleText.x scrollAmount))
|
||||
(-= leftText.x scrollAmount)
|
||||
(-= rightText.x scrollAmount)
|
||||
(doFor columnText columnTexts
|
||||
(-= columnText.x scrollAmount))
|
||||
(when xText
|
||||
(-= xText.x scrollAmount)))
|
||||
(refreshColumnTexts)))
|
||||
|
||||
(method scrollRight []
|
||||
(when (< cameraColumn (- columnWidths.length 1 ))
|
||||
(let [scrollAmount (nth columnWidths cameraColumn)]
|
||||
(+= controlCamera.scroll.x scrollAmount)
|
||||
(when titleText
|
||||
(+= titleText.x scrollAmount))
|
||||
(+= leftText.x scrollAmount)
|
||||
(+= rightText.x scrollAmount)
|
||||
(doFor columnText columnTexts
|
||||
(+= columnText.x scrollAmount))
|
||||
(when xText
|
||||
(+= xText.x scrollAmount)))
|
||||
(+= cameraColumn 1)
|
||||
(when (< (apply + (columnWidths.slice cameraColumn)) width)
|
||||
(controls.remove rightText))
|
||||
(controls.add leftText)
|
||||
(refreshColumnTexts)))
|
||||
|
||||
// Irreversibly disable the window's buttons (for when you're going to hide it in the next frame)
|
||||
(method clearActions []
|
||||
(_actions.clear))
|
@@ -1,33 +0,0 @@
|
||||
package kiss_flixel;
|
||||
|
||||
import kiss.Prelude;
|
||||
import kiss.List;
|
||||
import flixel.FlxSprite;
|
||||
import flixel.util.FlxColor;
|
||||
import flixel.text.FlxText;
|
||||
import flixel.math.FlxPoint;
|
||||
import flash.display.PNGEncoderOptions;
|
||||
import flash.utils.ByteArray;
|
||||
#if sys
|
||||
import sys.io.File;
|
||||
#end
|
||||
|
||||
enum RelativeCoordinate {
|
||||
// Negative means to count back from the far edge
|
||||
Pixels(p:Int); // Pixels from an edge.
|
||||
Percent(p:Float); // Percent from an edge. -1 to 1
|
||||
}
|
||||
|
||||
typedef RelativePosition = {
|
||||
x:RelativeCoordinate,
|
||||
y:RelativeCoordinate,
|
||||
?anchorX:RelativeCoordinate, // default Percent(0.5)
|
||||
?anchorY:RelativeCoordinate, // default Percent(0.5)
|
||||
?sizeX:RelativeCoordinate,
|
||||
?sizeY:RelativeCoordinate,
|
||||
?offsetX:Int,
|
||||
?offsetY:Int
|
||||
};
|
||||
|
||||
@:build(kiss.Kiss.build())
|
||||
class SpriteTools {}
|
@@ -1,61 +0,0 @@
|
||||
// Calculate where to draw the given stamp sprite on the given canvas sprite, as percentages or pixels from edge
|
||||
(function :Array<Int> positionOn [:FlxSprite stamp :FlxSprite canvas :RelativePosition pos]
|
||||
(unless pos.anchorX (set pos.anchorX (Percent 0.5)))
|
||||
(unless pos.anchorY (set pos.anchorY (Percent 0.5)))
|
||||
(let [&mut x (coordIn pos.x (/ canvas.width canvas.scale.x) pos.offsetX)
|
||||
&mut y (coordIn pos.y (/ canvas.height canvas.scale.y) pos.offsetY)]
|
||||
(-= x (coordIn pos.anchorX stamp.width))
|
||||
(-= y (coordIn pos.anchorY stamp.height))
|
||||
[x y]))
|
||||
|
||||
(function :Int coordIn [:RelativeCoordinate coord :Float range &opt :Int offset]
|
||||
(+ (or offset 0)
|
||||
(Math.round
|
||||
(case coord
|
||||
((when (and (>= p -1) (< p 0)) (Percent p))
|
||||
(+ range (* p range)))
|
||||
((when (and (>= p -range) (< p 0)) (Pixels p))
|
||||
(+ range p))
|
||||
((when (<= p 1) (Percent p))
|
||||
(* range p))
|
||||
((when (<= p range) (Pixels p))
|
||||
p)
|
||||
(otherwise (throw "$coord is out of range $range"))))))
|
||||
|
||||
(function :Void scaleStampOn [:FlxSprite stamp :FlxSprite canvas :RelativePosition pos]
|
||||
(let [&mut x 0 &mut y 0]
|
||||
(when pos.sizeX
|
||||
(set x (coordIn pos.sizeX canvas.frameWidth)))
|
||||
(when pos.sizeY
|
||||
(set y (coordIn pos.sizeY canvas.frameHeight)))
|
||||
(stamp.setGraphicSize x y)
|
||||
(stamp.updateHitbox)))
|
||||
|
||||
(function :Void drawOnSprite [:FlxSprite stamp :FlxSprite canvas :RelativePosition pos]
|
||||
(scaleStampOn stamp canvas pos)
|
||||
(let [[x y] (positionOn stamp canvas pos)]
|
||||
(let [oX stamp.origin.x
|
||||
oY stamp.origin.y]
|
||||
(stamp.origin.set 0 0)
|
||||
(canvas.stamp stamp x y)
|
||||
(stamp.origin.set oX oY))))
|
||||
|
||||
// TODO allow specifying size relative to canvas
|
||||
(function :Void writeOnSprite [:String text :Int size :FlxSprite canvas :RelativePosition pos &opt :FlxColor color]
|
||||
(let [lines (text.split "\n")
|
||||
&mut offsetY (/ (* size lines.length) -2)]
|
||||
(doFor text lines
|
||||
(set pos.offsetY offsetY)
|
||||
(+= offsetY size)
|
||||
(let [text (new FlxText 0 0 0 text size)]
|
||||
(when color
|
||||
(set text.color color))
|
||||
(drawOnSprite text canvas pos)))))
|
||||
|
||||
// Source: https://gist.github.com/miltoncandelero/0c452f832fa924bfdd60fe9d507bc581
|
||||
(#when sys
|
||||
(function :Void saveToPNG [:FlxSprite sprite :String file]
|
||||
(let [bitmapData sprite.pixels
|
||||
&mut bytes (new ByteArray)]
|
||||
(set bytes (bitmapData.encode bitmapData.rect (new PNGEncoderOptions true) bytes))
|
||||
(File.saveBytes file bytes))))
|
1
projects/kiss-flixel/template/.gitignore
vendored
1
projects/kiss-flixel/template/.gitignore
vendored
@@ -1 +0,0 @@
|
||||
export/
|
@@ -1,6 +0,0 @@
|
||||
{
|
||||
"recommendations": [
|
||||
"openfl.lime-vscode-extension",
|
||||
"redhat.vscode-xml"
|
||||
]
|
||||
}
|
@@ -1,21 +0,0 @@
|
||||
{
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"name": "Build + Debug",
|
||||
"type": "lime",
|
||||
"request": "launch"
|
||||
},
|
||||
{
|
||||
"name": "Debug",
|
||||
"type": "lime",
|
||||
"request": "launch",
|
||||
"preLaunchTask": null
|
||||
},
|
||||
{
|
||||
"name": "Macro",
|
||||
"type": "haxe-eval",
|
||||
"request": "launch"
|
||||
}
|
||||
]
|
||||
}
|
@@ -1,13 +0,0 @@
|
||||
{
|
||||
"search.exclude": {
|
||||
"export/**/*.hx": true
|
||||
},
|
||||
"[haxe]": {
|
||||
"editor.formatOnSave": true,
|
||||
"editor.formatOnPaste": true,
|
||||
"editor.codeActionsOnSave": {
|
||||
"source.sortImports": true
|
||||
}
|
||||
},
|
||||
"haxe.enableExtendedIndentation": true
|
||||
}
|
13
projects/kiss-flixel/template/.vscode/tasks.json
vendored
13
projects/kiss-flixel/template/.vscode/tasks.json
vendored
@@ -1,13 +0,0 @@
|
||||
{
|
||||
"version": "2.0.0",
|
||||
"tasks": [
|
||||
{
|
||||
"type": "lime",
|
||||
"command": "test",
|
||||
"group": {
|
||||
"kind": "build",
|
||||
"isDefault": true
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
@@ -1,87 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<project xmlns="http://lime.software/project/1.0.2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://lime.software/project/1.0.2 http://lime.software/xsd/project-1.0.2.xsd">
|
||||
|
||||
<!-- _________________________ Application Settings _________________________ -->
|
||||
|
||||
<app title="FlxProject" file="FlxProject" main="Main" version="0.0.1" company="HaxeFlixel" />
|
||||
|
||||
<!--The flixel preloader is not accurate in Chrome. You can use it regularly if you embed the swf into a html file
|
||||
or you can set the actual size of your file manually at "FlxPreloaderBase-onUpdate-bytesTotal"-->
|
||||
<app preloader="flixel.system.FlxPreloader" />
|
||||
|
||||
<!--Minimum without FLX_NO_GAMEPAD: 11.8, without FLX_NO_NATIVE_CURSOR: 11.2-->
|
||||
<set name="SWF_VERSION" value="11.8" />
|
||||
|
||||
<!-- ____________________________ Window Settings ___________________________ -->
|
||||
|
||||
<!--These window settings apply to all targets-->
|
||||
<window width="640" height="480" fps="60" background="#000000" hardware="true" vsync="false" />
|
||||
|
||||
<!--HTML5-specific-->
|
||||
<window if="html5" resizable="false" />
|
||||
|
||||
<!--Desktop-specific-->
|
||||
<window if="desktop" orientation="landscape" fullscreen="false" resizable="true" />
|
||||
|
||||
<!--Mobile-specific-->
|
||||
<window if="mobile" orientation="landscape" fullscreen="true" width="0" height="0" />
|
||||
|
||||
<!-- _____________________________ Path Settings ____________________________ -->
|
||||
|
||||
<set name="BUILD_DIR" value="export" />
|
||||
<source path="source" />
|
||||
<assets path="assets" />
|
||||
|
||||
<!-- _______________________________ Libraries ______________________________ -->
|
||||
|
||||
<haxelib name="flixel" />
|
||||
|
||||
<haxelib name="kiss" />
|
||||
<haxelib name="kiss-flixel" />
|
||||
|
||||
<!--In case you want to use the addons package-->
|
||||
<!--<haxelib name="flixel-addons" />-->
|
||||
|
||||
<!--In case you want to use the ui package-->
|
||||
<!--<haxelib name="flixel-ui" />-->
|
||||
|
||||
<!--In case you want to use nape with flixel-->
|
||||
<!--<haxelib name="nape-haxe4" />-->
|
||||
|
||||
<!-- ______________________________ Haxedefines _____________________________ -->
|
||||
|
||||
<!--Enable the Flixel core recording system-->
|
||||
<!--<haxedef name="FLX_RECORD" />-->
|
||||
|
||||
<!--Disable the right and middle mouse buttons-->
|
||||
<!--<haxedef name="FLX_NO_MOUSE_ADVANCED" />-->
|
||||
|
||||
<!--Disable the native cursor API on Flash-->
|
||||
<!--<haxedef name="FLX_NO_NATIVE_CURSOR" />-->
|
||||
|
||||
<!--Optimise inputs, be careful you will get null errors if you don't use conditionals in your game-->
|
||||
<haxedef name="FLX_NO_MOUSE" if="mobile" />
|
||||
<haxedef name="FLX_NO_KEYBOARD" if="mobile" />
|
||||
<haxedef name="FLX_NO_TOUCH" if="desktop" />
|
||||
<!--<haxedef name="FLX_NO_GAMEPAD" />-->
|
||||
|
||||
<!--Disable the Flixel core sound tray-->
|
||||
<!--<haxedef name="FLX_NO_SOUND_TRAY" />-->
|
||||
|
||||
<!--Disable the Flixel sound management code-->
|
||||
<!--<haxedef name="FLX_NO_SOUND_SYSTEM" />-->
|
||||
|
||||
<!--Disable the Flixel core focus lost screen-->
|
||||
<!--<haxedef name="FLX_NO_FOCUS_LOST_SCREEN" />-->
|
||||
|
||||
<!--Disable the Flixel core debugger. Automatically gets set whenever you compile in release mode!-->
|
||||
<haxedef name="FLX_NO_DEBUG" unless="debug" />
|
||||
|
||||
<!--Enable this for Nape release builds for a serious peformance improvement-->
|
||||
<haxedef name="NAPE_RELEASE_BUILD" unless="debug" />
|
||||
|
||||
<!-- _________________________________ Custom _______________________________ -->
|
||||
|
||||
<!--Place custom nodes like icons here (higher priority to override the HaxeFlixel icon)-->
|
||||
</project>
|
@@ -1,15 +0,0 @@
|
||||
{
|
||||
"lineEnds": {
|
||||
"leftCurly": "both",
|
||||
"rightCurly": "both",
|
||||
"objectLiteralCurly": {
|
||||
"leftCurly": "after"
|
||||
}
|
||||
},
|
||||
"sameLine": {
|
||||
"ifElse": "next",
|
||||
"doWhile": "next",
|
||||
"tryBody": "next",
|
||||
"tryCatch": "next"
|
||||
}
|
||||
}
|
@@ -1,4 +0,0 @@
|
||||
package;
|
||||
|
||||
@:build(flixel.system.FlxAssets.buildFileReferences("assets", true))
|
||||
class AssetPaths {}
|
@@ -1,13 +0,0 @@
|
||||
package;
|
||||
|
||||
import flixel.FlxGame;
|
||||
import openfl.display.Sprite;
|
||||
|
||||
class Main extends Sprite
|
||||
{
|
||||
public function new()
|
||||
{
|
||||
super();
|
||||
addChild(new FlxGame(0, 0, PlayState));
|
||||
}
|
||||
}
|
@@ -1,8 +0,0 @@
|
||||
(import flixel.FlxState)
|
||||
(extends FlxState)
|
||||
|
||||
(method &override :Void create []
|
||||
(super.create))
|
||||
|
||||
(method &override :Void update [:Float elapsed]
|
||||
(super.update elapsed))
|
Reference in New Issue
Block a user