├── .gitignore
├── CMakeLists.txt
├── LICENSE
├── README.md
├── TODO
├── demo
├── lol.e
├── mandelbrot.e
└── uk.e
├── plugins
├── CMakeLists.txt
├── color
│ ├── CMakeLists.txt
│ ├── ColorNode.cpp
│ ├── ColorNode.h
│ ├── ColorPlugin.cpp
│ ├── ColorPlugin.h
│ ├── color.png
│ ├── color.qrc
│ └── fromToStream.cpp
├── compare
│ ├── CMakeLists.txt
│ ├── CompNode.cpp
│ ├── CompNode.h
│ ├── ComparePlugin.cpp
│ ├── ComparePlugin.h
│ ├── comp.qrc
│ ├── eq.png
│ ├── gt.png
│ ├── lt.png
│ └── ne.png
├── condition
│ ├── CMakeLists.txt
│ ├── ConditionPlugin.cpp
│ ├── ConditionPlugin.h
│ ├── IfNode.cpp
│ ├── IfNode.h
│ ├── cond.qrc
│ └── if.png
├── functions
│ ├── CMakeLists.txt
│ ├── Function.cpp
│ ├── Function.h
│ ├── FunctionManager.cpp
│ ├── FunctionManager.h
│ ├── FunctionNode.cpp
│ ├── FunctionNode.h
│ ├── FunctionPlugin.cpp
│ ├── FunctionPlugin.h
│ ├── arrow.png
│ ├── fromToStream.cpp
│ ├── func.qrc
│ └── functionmanager.ui
├── image
│ ├── BitmapNode.cpp
│ ├── BitmapNode.h
│ ├── CMakeLists.txt
│ ├── ImagePlugin.cpp
│ ├── ImagePlugin.h
│ ├── fromToStream.cpp
│ ├── image.png
│ └── image.qrc
├── io
│ ├── CMakeLists.txt
│ ├── ExportImageDialog.cpp
│ ├── ExportImageDialog.h
│ ├── InputNode.cpp
│ ├── InputNode.h
│ ├── IoPlugin.cpp
│ ├── IoPlugin.h
│ ├── OutputNode.cpp
│ ├── OutputNode.h
│ ├── exportimagedialog.ui
│ ├── io.qrc
│ ├── output.png
│ ├── x.png
│ └── y.png
├── logic
│ ├── CMakeLists.txt
│ ├── LogicNode.cpp
│ ├── LogicNode.h
│ ├── LogicPlugin.cpp
│ ├── LogicPlugin.h
│ ├── and.png
│ ├── logic.qrc
│ ├── not.png
│ ├── or.png
│ └── xor.png
├── lut
│ ├── CMakeLists.txt
│ ├── Gradient.cpp
│ ├── Gradient.h
│ ├── LUTNode.cpp
│ ├── LUTNode.h
│ ├── LUTPlugin.cpp
│ ├── LUTPlugin.h
│ ├── dialog
│ │ ├── lut_dialog.cpp
│ │ └── lut_dialog.h
│ └── fromToStream.cpp
└── math
│ ├── CMakeLists.txt
│ ├── ComplexNode.cpp
│ ├── ComplexNode.h
│ ├── MathNode.cpp
│ ├── MathNode.h
│ ├── MathPlugin.cpp
│ ├── MathPlugin.h
│ ├── RealNode.cpp
│ ├── RealNode.h
│ ├── add.png
│ ├── complex.png
│ ├── cos.png
│ ├── divide.png
│ ├── fromToStream.cpp
│ ├── math.qrc
│ ├── multiply.png
│ ├── neg.png
│ ├── real.png
│ ├── sin.png
│ ├── sqrt.png
│ └── subtract.png
└── src
├── CMakeLists.txt
├── EmergenceInterface.h
├── Node.cpp
├── Node.h
├── NodeBox.cpp
├── NodeBox.h
├── PluginManager.cpp
├── PluginManager.h
├── Workspace.cpp
├── Workspace.h
├── data_t.cpp
├── data_t.h
├── emgc.ico
├── icons
├── copy.png
├── cut.png
├── delete.png
├── exit.png
├── export.png
├── no_icon.png
├── open.png
├── paste.png
├── redo.png
├── save.png
└── undo.png
├── main.cpp
├── mainwindow.cpp
├── mainwindow.h
├── mainwindow.ui
├── signalManager.h
└── src.qrc
/.gitignore:
--------------------------------------------------------------------------------
1 | Emergence.pro.user
2 | wiki
3 | build
4 | **/*.pro.user
5 | **/CMakeLists.txt.user
6 | CMakeLists.txt.user
7 |
--------------------------------------------------------------------------------
/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | cmake_minimum_required(VERSION 3.0.0)
2 |
3 | project(Emergence)
4 |
5 | if ( NOT CMAKE_BUILD_TYPE )
6 | set( CMAKE_BUILD_TYPE Release)
7 | endif()
8 |
9 | set(PLUGIN_OUTPUT_PATH ${CMAKE_CURRENT_BINARY_DIR}/lib)
10 | set(MAIN_SRC_DIR ${CMAKE_CURRENT_SOURCE_DIR}/src)
11 | set(BIN_SRC_DIR ${CMAKE_CURRENT_BINARY_DIR}/src)
12 |
13 | add_subdirectory(src)
14 | add_subdirectory(plugins)
15 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | GNU GENERAL PUBLIC LICENSE
2 | Version 3, 29 June 2007
3 |
4 | Copyright (C) 2007 Free Software Foundation, Inc.
5 | Everyone is permitted to copy and distribute verbatim copies
6 | of this license document, but changing it is not allowed.
7 |
8 | Preamble
9 |
10 | The GNU General Public License is a free, copyleft license for
11 | software and other kinds of works.
12 |
13 | The licenses for most software and other practical works are designed
14 | to take away your freedom to share and change the works. By contrast,
15 | the GNU General Public License is intended to guarantee your freedom to
16 | share and change all versions of a program--to make sure it remains free
17 | software for all its users. We, the Free Software Foundation, use the
18 | GNU General Public License for most of our software; it applies also to
19 | any other work released this way by its authors. You can apply it to
20 | your programs, too.
21 |
22 | When we speak of free software, we are referring to freedom, not
23 | price. Our General Public Licenses are designed to make sure that you
24 | have the freedom to distribute copies of free software (and charge for
25 | them if you wish), that you receive source code or can get it if you
26 | want it, that you can change the software or use pieces of it in new
27 | free programs, and that you know you can do these things.
28 |
29 | To protect your rights, we need to prevent others from denying you
30 | these rights or asking you to surrender the rights. Therefore, you have
31 | certain responsibilities if you distribute copies of the software, or if
32 | you modify it: responsibilities to respect the freedom of others.
33 |
34 | For example, if you distribute copies of such a program, whether
35 | gratis or for a fee, you must pass on to the recipients the same
36 | freedoms that you received. You must make sure that they, too, receive
37 | or can get the source code. And you must show them these terms so they
38 | know their rights.
39 |
40 | Developers that use the GNU GPL protect your rights with two steps:
41 | (1) assert copyright on the software, and (2) offer you this License
42 | giving you legal permission to copy, distribute and/or modify it.
43 |
44 | For the developers' and authors' protection, the GPL clearly explains
45 | that there is no warranty for this free software. For both users' and
46 | authors' sake, the GPL requires that modified versions be marked as
47 | changed, so that their problems will not be attributed erroneously to
48 | authors of previous versions.
49 |
50 | Some devices are designed to deny users access to install or run
51 | modified versions of the software inside them, although the manufacturer
52 | can do so. This is fundamentally incompatible with the aim of
53 | protecting users' freedom to change the software. The systematic
54 | pattern of such abuse occurs in the area of products for individuals to
55 | use, which is precisely where it is most unacceptable. Therefore, we
56 | have designed this version of the GPL to prohibit the practice for those
57 | products. If such problems arise substantially in other domains, we
58 | stand ready to extend this provision to those domains in future versions
59 | of the GPL, as needed to protect the freedom of users.
60 |
61 | Finally, every program is threatened constantly by software patents.
62 | States should not allow patents to restrict development and use of
63 | software on general-purpose computers, but in those that do, we wish to
64 | avoid the special danger that patents applied to a free program could
65 | make it effectively proprietary. To prevent this, the GPL assures that
66 | patents cannot be used to render the program non-free.
67 |
68 | The precise terms and conditions for copying, distribution and
69 | modification follow.
70 |
71 | TERMS AND CONDITIONS
72 |
73 | 0. Definitions.
74 |
75 | "This License" refers to version 3 of the GNU General Public License.
76 |
77 | "Copyright" also means copyright-like laws that apply to other kinds of
78 | works, such as semiconductor masks.
79 |
80 | "The Program" refers to any copyrightable work licensed under this
81 | License. Each licensee is addressed as "you". "Licensees" and
82 | "recipients" may be individuals or organizations.
83 |
84 | To "modify" a work means to copy from or adapt all or part of the work
85 | in a fashion requiring copyright permission, other than the making of an
86 | exact copy. The resulting work is called a "modified version" of the
87 | earlier work or a work "based on" the earlier work.
88 |
89 | A "covered work" means either the unmodified Program or a work based
90 | on the Program.
91 |
92 | To "propagate" a work means to do anything with it that, without
93 | permission, would make you directly or secondarily liable for
94 | infringement under applicable copyright law, except executing it on a
95 | computer or modifying a private copy. Propagation includes copying,
96 | distribution (with or without modification), making available to the
97 | public, and in some countries other activities as well.
98 |
99 | To "convey" a work means any kind of propagation that enables other
100 | parties to make or receive copies. Mere interaction with a user through
101 | a computer network, with no transfer of a copy, is not conveying.
102 |
103 | An interactive user interface displays "Appropriate Legal Notices"
104 | to the extent that it includes a convenient and prominently visible
105 | feature that (1) displays an appropriate copyright notice, and (2)
106 | tells the user that there is no warranty for the work (except to the
107 | extent that warranties are provided), that licensees may convey the
108 | work under this License, and how to view a copy of this License. If
109 | the interface presents a list of user commands or options, such as a
110 | menu, a prominent item in the list meets this criterion.
111 |
112 | 1. Source Code.
113 |
114 | The "source code" for a work means the preferred form of the work
115 | for making modifications to it. "Object code" means any non-source
116 | form of a work.
117 |
118 | A "Standard Interface" means an interface that either is an official
119 | standard defined by a recognized standards body, or, in the case of
120 | interfaces specified for a particular programming language, one that
121 | is widely used among developers working in that language.
122 |
123 | The "System Libraries" of an executable work include anything, other
124 | than the work as a whole, that (a) is included in the normal form of
125 | packaging a Major Component, but which is not part of that Major
126 | Component, and (b) serves only to enable use of the work with that
127 | Major Component, or to implement a Standard Interface for which an
128 | implementation is available to the public in source code form. A
129 | "Major Component", in this context, means a major essential component
130 | (kernel, window system, and so on) of the specific operating system
131 | (if any) on which the executable work runs, or a compiler used to
132 | produce the work, or an object code interpreter used to run it.
133 |
134 | The "Corresponding Source" for a work in object code form means all
135 | the source code needed to generate, install, and (for an executable
136 | work) run the object code and to modify the work, including scripts to
137 | control those activities. However, it does not include the work's
138 | System Libraries, or general-purpose tools or generally available free
139 | programs which are used unmodified in performing those activities but
140 | which are not part of the work. For example, Corresponding Source
141 | includes interface definition files associated with source files for
142 | the work, and the source code for shared libraries and dynamically
143 | linked subprograms that the work is specifically designed to require,
144 | such as by intimate data communication or control flow between those
145 | subprograms and other parts of the work.
146 |
147 | The Corresponding Source need not include anything that users
148 | can regenerate automatically from other parts of the Corresponding
149 | Source.
150 |
151 | The Corresponding Source for a work in source code form is that
152 | same work.
153 |
154 | 2. Basic Permissions.
155 |
156 | All rights granted under this License are granted for the term of
157 | copyright on the Program, and are irrevocable provided the stated
158 | conditions are met. This License explicitly affirms your unlimited
159 | permission to run the unmodified Program. The output from running a
160 | covered work is covered by this License only if the output, given its
161 | content, constitutes a covered work. This License acknowledges your
162 | rights of fair use or other equivalent, as provided by copyright law.
163 |
164 | You may make, run and propagate covered works that you do not
165 | convey, without conditions so long as your license otherwise remains
166 | in force. You may convey covered works to others for the sole purpose
167 | of having them make modifications exclusively for you, or provide you
168 | with facilities for running those works, provided that you comply with
169 | the terms of this License in conveying all material for which you do
170 | not control copyright. Those thus making or running the covered works
171 | for you must do so exclusively on your behalf, under your direction
172 | and control, on terms that prohibit them from making any copies of
173 | your copyrighted material outside their relationship with you.
174 |
175 | Conveying under any other circumstances is permitted solely under
176 | the conditions stated below. Sublicensing is not allowed; section 10
177 | makes it unnecessary.
178 |
179 | 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
180 |
181 | No covered work shall be deemed part of an effective technological
182 | measure under any applicable law fulfilling obligations under article
183 | 11 of the WIPO copyright treaty adopted on 20 December 1996, or
184 | similar laws prohibiting or restricting circumvention of such
185 | measures.
186 |
187 | When you convey a covered work, you waive any legal power to forbid
188 | circumvention of technological measures to the extent such circumvention
189 | is effected by exercising rights under this License with respect to
190 | the covered work, and you disclaim any intention to limit operation or
191 | modification of the work as a means of enforcing, against the work's
192 | users, your or third parties' legal rights to forbid circumvention of
193 | technological measures.
194 |
195 | 4. Conveying Verbatim Copies.
196 |
197 | You may convey verbatim copies of the Program's source code as you
198 | receive it, in any medium, provided that you conspicuously and
199 | appropriately publish on each copy an appropriate copyright notice;
200 | keep intact all notices stating that this License and any
201 | non-permissive terms added in accord with section 7 apply to the code;
202 | keep intact all notices of the absence of any warranty; and give all
203 | recipients a copy of this License along with the Program.
204 |
205 | You may charge any price or no price for each copy that you convey,
206 | and you may offer support or warranty protection for a fee.
207 |
208 | 5. Conveying Modified Source Versions.
209 |
210 | You may convey a work based on the Program, or the modifications to
211 | produce it from the Program, in the form of source code under the
212 | terms of section 4, provided that you also meet all of these conditions:
213 |
214 | a) The work must carry prominent notices stating that you modified
215 | it, and giving a relevant date.
216 |
217 | b) The work must carry prominent notices stating that it is
218 | released under this License and any conditions added under section
219 | 7. This requirement modifies the requirement in section 4 to
220 | "keep intact all notices".
221 |
222 | c) You must license the entire work, as a whole, under this
223 | License to anyone who comes into possession of a copy. This
224 | License will therefore apply, along with any applicable section 7
225 | additional terms, to the whole of the work, and all its parts,
226 | regardless of how they are packaged. This License gives no
227 | permission to license the work in any other way, but it does not
228 | invalidate such permission if you have separately received it.
229 |
230 | d) If the work has interactive user interfaces, each must display
231 | Appropriate Legal Notices; however, if the Program has interactive
232 | interfaces that do not display Appropriate Legal Notices, your
233 | work need not make them do so.
234 |
235 | A compilation of a covered work with other separate and independent
236 | works, which are not by their nature extensions of the covered work,
237 | and which are not combined with it such as to form a larger program,
238 | in or on a volume of a storage or distribution medium, is called an
239 | "aggregate" if the compilation and its resulting copyright are not
240 | used to limit the access or legal rights of the compilation's users
241 | beyond what the individual works permit. Inclusion of a covered work
242 | in an aggregate does not cause this License to apply to the other
243 | parts of the aggregate.
244 |
245 | 6. Conveying Non-Source Forms.
246 |
247 | You may convey a covered work in object code form under the terms
248 | of sections 4 and 5, provided that you also convey the
249 | machine-readable Corresponding Source under the terms of this License,
250 | in one of these ways:
251 |
252 | a) Convey the object code in, or embodied in, a physical product
253 | (including a physical distribution medium), accompanied by the
254 | Corresponding Source fixed on a durable physical medium
255 | customarily used for software interchange.
256 |
257 | b) Convey the object code in, or embodied in, a physical product
258 | (including a physical distribution medium), accompanied by a
259 | written offer, valid for at least three years and valid for as
260 | long as you offer spare parts or customer support for that product
261 | model, to give anyone who possesses the object code either (1) a
262 | copy of the Corresponding Source for all the software in the
263 | product that is covered by this License, on a durable physical
264 | medium customarily used for software interchange, for a price no
265 | more than your reasonable cost of physically performing this
266 | conveying of source, or (2) access to copy the
267 | Corresponding Source from a network server at no charge.
268 |
269 | c) Convey individual copies of the object code with a copy of the
270 | written offer to provide the Corresponding Source. This
271 | alternative is allowed only occasionally and noncommercially, and
272 | only if you received the object code with such an offer, in accord
273 | with subsection 6b.
274 |
275 | d) Convey the object code by offering access from a designated
276 | place (gratis or for a charge), and offer equivalent access to the
277 | Corresponding Source in the same way through the same place at no
278 | further charge. You need not require recipients to copy the
279 | Corresponding Source along with the object code. If the place to
280 | copy the object code is a network server, the Corresponding Source
281 | may be on a different server (operated by you or a third party)
282 | that supports equivalent copying facilities, provided you maintain
283 | clear directions next to the object code saying where to find the
284 | Corresponding Source. Regardless of what server hosts the
285 | Corresponding Source, you remain obligated to ensure that it is
286 | available for as long as needed to satisfy these requirements.
287 |
288 | e) Convey the object code using peer-to-peer transmission, provided
289 | you inform other peers where the object code and Corresponding
290 | Source of the work are being offered to the general public at no
291 | charge under subsection 6d.
292 |
293 | A separable portion of the object code, whose source code is excluded
294 | from the Corresponding Source as a System Library, need not be
295 | included in conveying the object code work.
296 |
297 | A "User Product" is either (1) a "consumer product", which means any
298 | tangible personal property which is normally used for personal, family,
299 | or household purposes, or (2) anything designed or sold for incorporation
300 | into a dwelling. In determining whether a product is a consumer product,
301 | doubtful cases shall be resolved in favor of coverage. For a particular
302 | product received by a particular user, "normally used" refers to a
303 | typical or common use of that class of product, regardless of the status
304 | of the particular user or of the way in which the particular user
305 | actually uses, or expects or is expected to use, the product. A product
306 | is a consumer product regardless of whether the product has substantial
307 | commercial, industrial or non-consumer uses, unless such uses represent
308 | the only significant mode of use of the product.
309 |
310 | "Installation Information" for a User Product means any methods,
311 | procedures, authorization keys, or other information required to install
312 | and execute modified versions of a covered work in that User Product from
313 | a modified version of its Corresponding Source. The information must
314 | suffice to ensure that the continued functioning of the modified object
315 | code is in no case prevented or interfered with solely because
316 | modification has been made.
317 |
318 | If you convey an object code work under this section in, or with, or
319 | specifically for use in, a User Product, and the conveying occurs as
320 | part of a transaction in which the right of possession and use of the
321 | User Product is transferred to the recipient in perpetuity or for a
322 | fixed term (regardless of how the transaction is characterized), the
323 | Corresponding Source conveyed under this section must be accompanied
324 | by the Installation Information. But this requirement does not apply
325 | if neither you nor any third party retains the ability to install
326 | modified object code on the User Product (for example, the work has
327 | been installed in ROM).
328 |
329 | The requirement to provide Installation Information does not include a
330 | requirement to continue to provide support service, warranty, or updates
331 | for a work that has been modified or installed by the recipient, or for
332 | the User Product in which it has been modified or installed. Access to a
333 | network may be denied when the modification itself materially and
334 | adversely affects the operation of the network or violates the rules and
335 | protocols for communication across the network.
336 |
337 | Corresponding Source conveyed, and Installation Information provided,
338 | in accord with this section must be in a format that is publicly
339 | documented (and with an implementation available to the public in
340 | source code form), and must require no special password or key for
341 | unpacking, reading or copying.
342 |
343 | 7. Additional Terms.
344 |
345 | "Additional permissions" are terms that supplement the terms of this
346 | License by making exceptions from one or more of its conditions.
347 | Additional permissions that are applicable to the entire Program shall
348 | be treated as though they were included in this License, to the extent
349 | that they are valid under applicable law. If additional permissions
350 | apply only to part of the Program, that part may be used separately
351 | under those permissions, but the entire Program remains governed by
352 | this License without regard to the additional permissions.
353 |
354 | When you convey a copy of a covered work, you may at your option
355 | remove any additional permissions from that copy, or from any part of
356 | it. (Additional permissions may be written to require their own
357 | removal in certain cases when you modify the work.) You may place
358 | additional permissions on material, added by you to a covered work,
359 | for which you have or can give appropriate copyright permission.
360 |
361 | Notwithstanding any other provision of this License, for material you
362 | add to a covered work, you may (if authorized by the copyright holders of
363 | that material) supplement the terms of this License with terms:
364 |
365 | a) Disclaiming warranty or limiting liability differently from the
366 | terms of sections 15 and 16 of this License; or
367 |
368 | b) Requiring preservation of specified reasonable legal notices or
369 | author attributions in that material or in the Appropriate Legal
370 | Notices displayed by works containing it; or
371 |
372 | c) Prohibiting misrepresentation of the origin of that material, or
373 | requiring that modified versions of such material be marked in
374 | reasonable ways as different from the original version; or
375 |
376 | d) Limiting the use for publicity purposes of names of licensors or
377 | authors of the material; or
378 |
379 | e) Declining to grant rights under trademark law for use of some
380 | trade names, trademarks, or service marks; or
381 |
382 | f) Requiring indemnification of licensors and authors of that
383 | material by anyone who conveys the material (or modified versions of
384 | it) with contractual assumptions of liability to the recipient, for
385 | any liability that these contractual assumptions directly impose on
386 | those licensors and authors.
387 |
388 | All other non-permissive additional terms are considered "further
389 | restrictions" within the meaning of section 10. If the Program as you
390 | received it, or any part of it, contains a notice stating that it is
391 | governed by this License along with a term that is a further
392 | restriction, you may remove that term. If a license document contains
393 | a further restriction but permits relicensing or conveying under this
394 | License, you may add to a covered work material governed by the terms
395 | of that license document, provided that the further restriction does
396 | not survive such relicensing or conveying.
397 |
398 | If you add terms to a covered work in accord with this section, you
399 | must place, in the relevant source files, a statement of the
400 | additional terms that apply to those files, or a notice indicating
401 | where to find the applicable terms.
402 |
403 | Additional terms, permissive or non-permissive, may be stated in the
404 | form of a separately written license, or stated as exceptions;
405 | the above requirements apply either way.
406 |
407 | 8. Termination.
408 |
409 | You may not propagate or modify a covered work except as expressly
410 | provided under this License. Any attempt otherwise to propagate or
411 | modify it is void, and will automatically terminate your rights under
412 | this License (including any patent licenses granted under the third
413 | paragraph of section 11).
414 |
415 | However, if you cease all violation of this License, then your
416 | license from a particular copyright holder is reinstated (a)
417 | provisionally, unless and until the copyright holder explicitly and
418 | finally terminates your license, and (b) permanently, if the copyright
419 | holder fails to notify you of the violation by some reasonable means
420 | prior to 60 days after the cessation.
421 |
422 | Moreover, your license from a particular copyright holder is
423 | reinstated permanently if the copyright holder notifies you of the
424 | violation by some reasonable means, this is the first time you have
425 | received notice of violation of this License (for any work) from that
426 | copyright holder, and you cure the violation prior to 30 days after
427 | your receipt of the notice.
428 |
429 | Termination of your rights under this section does not terminate the
430 | licenses of parties who have received copies or rights from you under
431 | this License. If your rights have been terminated and not permanently
432 | reinstated, you do not qualify to receive new licenses for the same
433 | material under section 10.
434 |
435 | 9. Acceptance Not Required for Having Copies.
436 |
437 | You are not required to accept this License in order to receive or
438 | run a copy of the Program. Ancillary propagation of a covered work
439 | occurring solely as a consequence of using peer-to-peer transmission
440 | to receive a copy likewise does not require acceptance. However,
441 | nothing other than this License grants you permission to propagate or
442 | modify any covered work. These actions infringe copyright if you do
443 | not accept this License. Therefore, by modifying or propagating a
444 | covered work, you indicate your acceptance of this License to do so.
445 |
446 | 10. Automatic Licensing of Downstream Recipients.
447 |
448 | Each time you convey a covered work, the recipient automatically
449 | receives a license from the original licensors, to run, modify and
450 | propagate that work, subject to this License. You are not responsible
451 | for enforcing compliance by third parties with this License.
452 |
453 | An "entity transaction" is a transaction transferring control of an
454 | organization, or substantially all assets of one, or subdividing an
455 | organization, or merging organizations. If propagation of a covered
456 | work results from an entity transaction, each party to that
457 | transaction who receives a copy of the work also receives whatever
458 | licenses to the work the party's predecessor in interest had or could
459 | give under the previous paragraph, plus a right to possession of the
460 | Corresponding Source of the work from the predecessor in interest, if
461 | the predecessor has it or can get it with reasonable efforts.
462 |
463 | You may not impose any further restrictions on the exercise of the
464 | rights granted or affirmed under this License. For example, you may
465 | not impose a license fee, royalty, or other charge for exercise of
466 | rights granted under this License, and you may not initiate litigation
467 | (including a cross-claim or counterclaim in a lawsuit) alleging that
468 | any patent claim is infringed by making, using, selling, offering for
469 | sale, or importing the Program or any portion of it.
470 |
471 | 11. Patents.
472 |
473 | A "contributor" is a copyright holder who authorizes use under this
474 | License of the Program or a work on which the Program is based. The
475 | work thus licensed is called the contributor's "contributor version".
476 |
477 | A contributor's "essential patent claims" are all patent claims
478 | owned or controlled by the contributor, whether already acquired or
479 | hereafter acquired, that would be infringed by some manner, permitted
480 | by this License, of making, using, or selling its contributor version,
481 | but do not include claims that would be infringed only as a
482 | consequence of further modification of the contributor version. For
483 | purposes of this definition, "control" includes the right to grant
484 | patent sublicenses in a manner consistent with the requirements of
485 | this License.
486 |
487 | Each contributor grants you a non-exclusive, worldwide, royalty-free
488 | patent license under the contributor's essential patent claims, to
489 | make, use, sell, offer for sale, import and otherwise run, modify and
490 | propagate the contents of its contributor version.
491 |
492 | In the following three paragraphs, a "patent license" is any express
493 | agreement or commitment, however denominated, not to enforce a patent
494 | (such as an express permission to practice a patent or covenant not to
495 | sue for patent infringement). To "grant" such a patent license to a
496 | party means to make such an agreement or commitment not to enforce a
497 | patent against the party.
498 |
499 | If you convey a covered work, knowingly relying on a patent license,
500 | and the Corresponding Source of the work is not available for anyone
501 | to copy, free of charge and under the terms of this License, through a
502 | publicly available network server or other readily accessible means,
503 | then you must either (1) cause the Corresponding Source to be so
504 | available, or (2) arrange to deprive yourself of the benefit of the
505 | patent license for this particular work, or (3) arrange, in a manner
506 | consistent with the requirements of this License, to extend the patent
507 | license to downstream recipients. "Knowingly relying" means you have
508 | actual knowledge that, but for the patent license, your conveying the
509 | covered work in a country, or your recipient's use of the covered work
510 | in a country, would infringe one or more identifiable patents in that
511 | country that you have reason to believe are valid.
512 |
513 | If, pursuant to or in connection with a single transaction or
514 | arrangement, you convey, or propagate by procuring conveyance of, a
515 | covered work, and grant a patent license to some of the parties
516 | receiving the covered work authorizing them to use, propagate, modify
517 | or convey a specific copy of the covered work, then the patent license
518 | you grant is automatically extended to all recipients of the covered
519 | work and works based on it.
520 |
521 | A patent license is "discriminatory" if it does not include within
522 | the scope of its coverage, prohibits the exercise of, or is
523 | conditioned on the non-exercise of one or more of the rights that are
524 | specifically granted under this License. You may not convey a covered
525 | work if you are a party to an arrangement with a third party that is
526 | in the business of distributing software, under which you make payment
527 | to the third party based on the extent of your activity of conveying
528 | the work, and under which the third party grants, to any of the
529 | parties who would receive the covered work from you, a discriminatory
530 | patent license (a) in connection with copies of the covered work
531 | conveyed by you (or copies made from those copies), or (b) primarily
532 | for and in connection with specific products or compilations that
533 | contain the covered work, unless you entered into that arrangement,
534 | or that patent license was granted, prior to 28 March 2007.
535 |
536 | Nothing in this License shall be construed as excluding or limiting
537 | any implied license or other defenses to infringement that may
538 | otherwise be available to you under applicable patent law.
539 |
540 | 12. No Surrender of Others' Freedom.
541 |
542 | If conditions are imposed on you (whether by court order, agreement or
543 | otherwise) that contradict the conditions of this License, they do not
544 | excuse you from the conditions of this License. If you cannot convey a
545 | covered work so as to satisfy simultaneously your obligations under this
546 | License and any other pertinent obligations, then as a consequence you may
547 | not convey it at all. For example, if you agree to terms that obligate you
548 | to collect a royalty for further conveying from those to whom you convey
549 | the Program, the only way you could satisfy both those terms and this
550 | License would be to refrain entirely from conveying the Program.
551 |
552 | 13. Use with the GNU Affero General Public License.
553 |
554 | Notwithstanding any other provision of this License, you have
555 | permission to link or combine any covered work with a work licensed
556 | under version 3 of the GNU Affero General Public License into a single
557 | combined work, and to convey the resulting work. The terms of this
558 | License will continue to apply to the part which is the covered work,
559 | but the special requirements of the GNU Affero General Public License,
560 | section 13, concerning interaction through a network will apply to the
561 | combination as such.
562 |
563 | 14. Revised Versions of this License.
564 |
565 | The Free Software Foundation may publish revised and/or new versions of
566 | the GNU General Public License from time to time. Such new versions will
567 | be similar in spirit to the present version, but may differ in detail to
568 | address new problems or concerns.
569 |
570 | Each version is given a distinguishing version number. If the
571 | Program specifies that a certain numbered version of the GNU General
572 | Public License "or any later version" applies to it, you have the
573 | option of following the terms and conditions either of that numbered
574 | version or of any later version published by the Free Software
575 | Foundation. If the Program does not specify a version number of the
576 | GNU General Public License, you may choose any version ever published
577 | by the Free Software Foundation.
578 |
579 | If the Program specifies that a proxy can decide which future
580 | versions of the GNU General Public License can be used, that proxy's
581 | public statement of acceptance of a version permanently authorizes you
582 | to choose that version for the Program.
583 |
584 | Later license versions may give you additional or different
585 | permissions. However, no additional obligations are imposed on any
586 | author or copyright holder as a result of your choosing to follow a
587 | later version.
588 |
589 | 15. Disclaimer of Warranty.
590 |
591 | THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
592 | APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
593 | HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
594 | OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
595 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
596 | PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
597 | IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
598 | ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
599 |
600 | 16. Limitation of Liability.
601 |
602 | IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
603 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
604 | THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
605 | GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
606 | USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
607 | DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
608 | PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
609 | EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
610 | SUCH DAMAGES.
611 |
612 | 17. Interpretation of Sections 15 and 16.
613 |
614 | If the disclaimer of warranty and limitation of liability provided
615 | above cannot be given local legal effect according to their terms,
616 | reviewing courts shall apply local law that most closely approximates
617 | an absolute waiver of all civil liability in connection with the
618 | Program, unless a warranty or assumption of liability accompanies a
619 | copy of the Program in return for a fee.
620 |
621 | END OF TERMS AND CONDITIONS
622 |
623 | How to Apply These Terms to Your New Programs
624 |
625 | If you develop a new program, and you want it to be of the greatest
626 | possible use to the public, the best way to achieve this is to make it
627 | free software which everyone can redistribute and change under these terms.
628 |
629 | To do so, attach the following notices to the program. It is safest
630 | to attach them to the start of each source file to most effectively
631 | state the exclusion of warranty; and each file should have at least
632 | the "copyright" line and a pointer to where the full notice is found.
633 |
634 |
635 | Copyright (C)
636 |
637 | This program is free software: you can redistribute it and/or modify
638 | it under the terms of the GNU General Public License as published by
639 | the Free Software Foundation, either version 3 of the License, or
640 | (at your option) any later version.
641 |
642 | This program is distributed in the hope that it will be useful,
643 | but WITHOUT ANY WARRANTY; without even the implied warranty of
644 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
645 | GNU General Public License for more details.
646 |
647 | You should have received a copy of the GNU General Public License
648 | along with this program. If not, see .
649 |
650 | Also add information on how to contact you by electronic and paper mail.
651 |
652 | If the program does terminal interaction, make it output a short
653 | notice like this when it starts in an interactive mode:
654 |
655 | Copyright (C)
656 | This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
657 | This is free software, and you are welcome to redistribute it
658 | under certain conditions; type `show c' for details.
659 |
660 | The hypothetical commands `show w' and `show c' should show the appropriate
661 | parts of the General Public License. Of course, your program's commands
662 | might be different; for a GUI interface, you would use an "about box".
663 |
664 | You should also get your employer (if you work as a programmer) or school,
665 | if any, to sign a "copyright disclaimer" for the program, if necessary.
666 | For more information on this, and how to apply and follow the GNU GPL, see
667 | .
668 |
669 | The GNU General Public License does not permit incorporating your program
670 | into proprietary programs. If your program is a subroutine library, you
671 | may consider it more useful to permit linking proprietary applications with
672 | the library. If this is what you want to do, use the GNU Lesser General
673 | Public License instead of this License. But first, please read
674 | .
675 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Emergence
2 | Generate bitmaps using nodes.
3 |
4 | 
5 | 
6 | 
7 |
8 | For more information check out the [wiki](https://github.com/bsella/Emergence/wiki).
9 |
10 | ---
11 |
12 | # Building Emergence
13 | For now, Emergence is supported only on the GNU/Linux system. To build it you will need `cmake` and the `Qt5Widgets` library.
14 |
15 | It's highly recommended to build out of the source directory. For example, type the following commands:
16 |
17 | $ mkdir build
18 | $ cd build
19 | $ cmake ..
20 | $ make
21 |
22 | ---
23 |
24 | Check out my TODO-List!
25 |
26 | Feel free to send your feedback to `karim.salama@univ-tlse3.fr`
27 |
28 | ---
29 |
--------------------------------------------------------------------------------
/TODO:
--------------------------------------------------------------------------------
1 | - [ ] Navigate/Zoom
2 | - [x] Zoom
3 | - [ ] Navigate
4 | - [x] File oriented
5 | - [x] Clipboard
6 | - [x] Undo/Redo
7 | - [x] Add
8 | - [x] Remove
9 | - [x] Connect
10 | - [x] Disconnect
11 | - [x] Move
12 | - [ ] Change Constant
13 | - [ ] Change Image
14 | - [ ] Change/rename Function
15 | - [x] Multiple outputs
16 | - [x] LUT interface (dialog)
17 | - [ ] Transparancy
18 | - [x] Functions
19 | - [x] Function Manager
20 | - [x] New save format
21 | - [x] Adapt with latest optimisation (pixel ID)
22 | - [x] Draw FunctionNodes
23 | - [ ] Recursive Functions (obsolete if using OpenGL)
24 | - [x] New save format
25 | - [ ] Data structures and lists
26 | - [x] Preventing cycles
27 | - [x] More icons
28 | - [ ] Auto-arrange
29 | - [ ] Options
30 | - [ ] Command line
31 | - [ ] Documentation
32 | - [x] Modularity (Plugin system)
33 | - [ ] Integrate with OpenGL
34 | - [x] Binary and Text save protocol (*.ebin / *.e)
35 | - [ ] Tidy up the architecture
36 | - [ ] A more intuitive way to disconnect node
37 | - [ ] A more intuitive way to change constants
38 | - [ ] Zoom and navigate on render area
39 | - [ ] Time nodes => videos
40 | - [ ] Curvy connections
41 | - [ ] Interpolate colors
42 | - [ ] Themes
43 |
--------------------------------------------------------------------------------
/demo/lol.e:
--------------------------------------------------------------------------------
1 | 6
2 | 12
3 | div lut lerp x cos sin neg real out add clamp y
4 | 0
5 | 17
6 | div 283 84
7 | lut 352 77 3 4294901760 0 4278190335 0.5 4278255360 1
8 | lerp 17 75
9 | x -103 -31
10 | cos 87 100
11 | lerp 17 -66
12 | sin 84 -41
13 | neg 80 28
14 | real 19 -129 1
15 | out 510 87
16 | add 224 27
17 | neg -110 40
18 | clamp 163 -66
19 | clamp 164 63
20 | real 224 131 2
21 | y -111 116
22 | real -177 -67 15
23 | 10 14 0 16 15 11 2 16 3 11 5 8 1 12 13 16 8 6 7 8 4 7
24 |
--------------------------------------------------------------------------------
/demo/mandelbrot.e:
--------------------------------------------------------------------------------
1 | 6
2 | 9
3 | x real y mul lerp add cplx out neg
4 | 0
5 | 22
6 | x -508 -168
7 | real -497 -116 -2
8 | y -511 -41
9 | real -497 -220 1
10 | mul -176 -198
11 | mul 8 -39
12 | lerp -417 -78
13 | mul -238 -251
14 | add -114 -93
15 | lerp -418 -194
16 | mul 69 14
17 | real -590 -78 1.5
18 | mul -115 -145
19 | mul -54 -92
20 | cplx -357 -107
21 | out 142 66
22 | neg -496 18
23 | add -175 -146
24 | add -237 -199
25 | add -53 -40
26 | add 9 13
27 | add 70 66
28 | 18 18 19 19 11 2 16 14 14 12 14 3 0 1 20 20 17 17 8 8 9 6 21 11 4 14 7 14 13 14 5 14 10 14
29 |
--------------------------------------------------------------------------------
/demo/uk.e:
--------------------------------------------------------------------------------
1 | 6
2 | 12
3 | lt real color or gt and add if sub y x out
4 | 0
5 | 89
6 | lt -722 557
7 | real -157 169 0.334
8 | real -157 270 0.666
9 | real -158 321 0.6
10 | real -156 118 0.4
11 | real -156 -86 0.417
12 | real -156 15 0.583
13 | color -23 571 4278199421
14 | real -157 66 0.55
15 | color 135 40 4294967295
16 | real -155 -137 0.45
17 | color -40 380 4294967295
18 | real -450 525 1
19 | real -916 235 1
20 | real -918 394 0.5
21 | lt -63 135
22 | or -92 537
23 | gt -213 461
24 | and 75 -33
25 | and -1 -32
26 | add -450 473
27 | lt -63 186
28 | gt -213 513
29 | and -2 223
30 | if 219 214
31 | and 74 222
32 | or 135 92
33 | color 22 302 4291761195
34 | and -662 374
35 | and -602 -6
36 | gt -722 453
37 | or -544 386
38 | add -916 183
39 | and -603 150
40 | sub -918 291
41 | real -335 453 0.1
42 | y -167 220
43 | and -661 62
44 | and -663 530
45 | and -662 218
46 | real -918 343 0.066
47 | sub -855 210
48 | x -1008 158
49 | out 363 7
50 | out 361 107
51 | out 242 347
52 | out 175 545
53 | and -152 590
54 | and -152 486
55 | gt -213 617
56 | lt -61 1
57 | or 58 93
58 | if 278 84
59 | lt -62 256
60 | if 158 405
61 | if 55 361
62 | gt -213 565
63 | sub -452 581
64 | lt -62 -69
65 | if 278 -18
66 | lt -61 52
67 | if 56 511
68 | lt -62 -120
69 | lt -62 307
70 | and -603 306
71 | gt -721 37
72 | and -604 462
73 | and 56 461
74 | gt -722 89
75 | or -483 248
76 | lt -722 193
77 | lt -722 141
78 | or -543 75
79 | lt -722 245
80 | lt -722 297
81 | gt -723 401
82 | gt -721 -15
83 | gt -723 349
84 | sub -389 500
85 | lt -722 505
86 | real -333 626 -0.1
87 | y -546 578
88 | color -214 402 4294967295
89 | x -542 448
90 | color 136 -11 4291761195
91 | x -167 -35
92 | real -915 131 -0.066
93 | y -1012 288
94 | real -915 79 0
95 | 41 40 4 36 48 47 35 78 62 60 58 50 83 81 1 36 78 80 21 53 82 51 54 15 63 18 25 77 75 76 37 41 88 64 66 42 87 71 39 42 87 65 68 79 0 70 73 32 13 59 52 55 61 56 49 17 22 57 80 85 6 19 23 84 26 24 36 2 27 67 61 27 16 11 35 57 83 81 5 85 84 26 9 85 8 82 16 7 10 85 36 3 74 28 42 14 30 38 69 16 41 86 72 31 87 14 34 88 29 33 86 34 88 34 40 34 88 41 87 14 20 12 42 14
96 |
--------------------------------------------------------------------------------
/plugins/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | add_subdirectory(color)
2 | add_subdirectory(compare)
3 | add_subdirectory(condition)
4 | add_subdirectory(functions)
5 | add_subdirectory(image)
6 | add_subdirectory(logic)
7 | add_subdirectory(lut)
8 | add_subdirectory(math)
9 | add_subdirectory(io)
10 |
--------------------------------------------------------------------------------
/plugins/color/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | cmake_minimum_required(VERSION 3.0.0)
2 | project(ColorPlugin)
3 |
4 | find_package(Qt5Widgets REQUIRED)
5 |
6 | set(CMAKE_AUTOMOC ON)
7 | set(CMAKE_AUTORCC ON)
8 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC")
9 | qt5_add_resources(QRC color.qrc)
10 | add_custom_target(color_qrc DEPENDS ${QRC})
11 |
12 | set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PLUGIN_OUTPUT_PATH})
13 |
14 | include_directories(${MAIN_SRC_DIR} ${BIN_SRC_DIR} ${Qt5Widgets_INCLUDE_DIRS})
15 |
16 | add_library(${PROJECT_NAME} SHARED ColorPlugin.cpp ColorPlugin.h)
17 | add_library(color
18 | fromToStream.cpp
19 | ColorNode.cpp
20 | ColorNode.h)
21 |
22 | target_link_libraries(${PROJECT_NAME} color data_t ${QRC})
23 | add_dependencies(${PROJECT_NAME} color_qrc)
24 |
--------------------------------------------------------------------------------
/plugins/color/ColorNode.cpp:
--------------------------------------------------------------------------------
1 | #include "ColorNode.h"
2 |
3 | #include
4 | #include
5 |
6 | ColorNode::ColorNode(const data_t::color& c):Node("color",50,50,c){
7 | cache=c;
8 | constant=true;
9 | }
10 |
11 | void ColorNode::paint(QPainter *painter, const QStyleOptionGraphicsItem*option, QWidget*widget){
12 | Node::paint(painter,option,widget);
13 | painter->drawText(boundingRect().center()-QPoint(16,-2),"Color");
14 | }
15 | void ColorNode::contextMenuEvent(QGraphicsSceneContextMenuEvent *event){
16 | menu=new QMenu;
17 | connect(menu->addAction(QString("Change color")), &QAction::triggered,this,&ColorNode::changeColor);
18 | Node::contextMenuEvent(event);
19 | }
20 | void ColorNode::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *){
21 | changeColor();
22 | }
23 |
24 | void ColorNode::changeColor(){
25 | QColor c =QColorDialog::getColor(Qt::white,(QWidget*)parentWidget());
26 | if(c.isValid()){
27 | cache=c.rgba();
28 | color=c;
29 | updateVal();
30 | emit sm.updateOutputs();
31 | update();
32 | }
33 | }
34 |
35 | RGBNode::RGBNode():Node("rgb",50,100,Qt::white,3){}
36 | HSVNode::HSVNode():Node("hsv",50,100,Qt::white,3){}
37 |
38 | void RGBNode::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget){
39 | Node::paint(painter, option, widget);
40 | painter->fillRect(QRect(socketSize+2,height/4-5,width-4,10),Qt::red);
41 | painter->fillRect(QRect(socketSize+2,2*height/4-5,width-4,10),Qt::green);
42 | painter->fillRect(QRect(socketSize+2,3*height/4-5,width-4,10),Qt::blue);
43 | }
44 |
45 | void HSVNode::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget){
46 | Node::paint(painter, option, widget);
47 | painter->drawText(width/4,height/4+4,"H");
48 | painter->drawText(width/4,2*height/4+4,"S");
49 | painter->drawText(width/4,3*height/4+4,"V");
50 | }
51 |
52 | data_t RGBNode::kernel()const{
53 | int r=double(iNodes[0]->eval())*255,
54 | g=double(iNodes[1]->eval())*255,
55 | b=double(iNodes[2]->eval())*255;
56 | r=qMax(r,0); r= qMin(r,255);
57 | g=qMax(g,0); g= qMin(g,255);
58 | b=qMax(b,0); b= qMin(b,255);
59 | return qRgb(r,g,b);
60 | }
61 |
62 | data_t HSVNode::kernel()const{
63 | int h=double(iNodes[0]->eval())*360,
64 | s=double(iNodes[1]->eval())*255,
65 | v=double(iNodes[2]->eval())*255;
66 | h=qMax(h,0); h= qMin(h,359);
67 | s=qMax(s,0); s= qMin(s,255);
68 | v=qMax(v,0); v= qMin(v,255);
69 | return QColor::fromHsv(h,s,v).rgb();
70 | }
71 |
--------------------------------------------------------------------------------
/plugins/color/ColorNode.h:
--------------------------------------------------------------------------------
1 | #ifndef COLORNODE_H
2 | #define COLORNODE_H
3 |
4 | #include "Node.h"
5 | #include "data_t.h"
6 |
7 | class ColorNode : public Node{
8 | public:
9 | ColorNode(const data_t::color& c= 0xff000000);
10 | static Node* makeFromBin(std::istream&);
11 | static Node* makeFromText(std::istream&);
12 | private:
13 | inline data_t kernel()const{return cache;}
14 | void paint(QPainter*,
15 | const QStyleOptionGraphicsItem*,
16 | QWidget*);
17 | void contextMenuEvent(QGraphicsSceneContextMenuEvent*);
18 | void mouseDoubleClickEvent(QGraphicsSceneMouseEvent*)override;
19 | void changeColor();
20 | void toBin(std::ostream&)const override;
21 | void toText(std::ostream&)const override;
22 | };
23 |
24 | class RGBNode : public Node{
25 | public:
26 | RGBNode();
27 | inline static Node* makeNode(std::istream&){return new RGBNode;}
28 | private:
29 | data_t kernel()const;
30 | void paint(QPainter* painter,
31 | const QStyleOptionGraphicsItem*option,
32 | QWidget *widget);
33 | };
34 |
35 | class HSVNode : public Node{
36 | public:
37 | HSVNode();
38 | inline static Node* makeNode(std::istream&){return new HSVNode;}
39 | private:
40 | data_t kernel()const;
41 | void paint(QPainter* painter,
42 | const QStyleOptionGraphicsItem*option,
43 | QWidget *widget);
44 | };
45 | #endif // COLORNODE_H
46 |
--------------------------------------------------------------------------------
/plugins/color/ColorPlugin.cpp:
--------------------------------------------------------------------------------
1 | #include "ColorPlugin.h"
2 | #include "ColorNode.h"
3 |
4 | void ColorPlugin::updateUI(Ui::MainWindow *ui) const{
5 | QMenu* colorMenu = new QMenu("Color",ui->menuInsert);
6 | ui->menuInsert->addAction(colorMenu->menuAction());
7 | QAction* colorAction= new QAction(QIcon(":/color.png"),"Color");
8 | QAction* rgbAction= new QAction("RGB");
9 | QAction* hsvAction= new QAction("HSV");
10 |
11 | Workspace* ws= (Workspace*)ui->workspace->scene();
12 | connect(colorAction,&QAction::triggered,ws,[=]{ws->addNode(Node::nodeMalloc("color"));});
13 | connect(rgbAction,&QAction::triggered,ws,[=]{ws->addNode(Node::nodeMalloc("rgb"));});
14 | connect(hsvAction,&QAction::triggered,ws,[=]{ws->addNode(Node::nodeMalloc("hsv"));});
15 |
16 | colorMenu->addAction(colorAction);
17 | colorMenu->addAction(rgbAction);
18 | colorMenu->addAction(hsvAction);
19 |
20 | }
21 |
22 | void ColorPlugin::init()const{
23 | Node::makeNodeBinTextMethods["color"] = {&ColorNode::makeFromBin, &ColorNode::makeFromText};
24 | Node::makeNodeBinTextMethods["rgb"] = {&RGBNode::makeNode, &RGBNode::makeNode};
25 | Node::makeNodeBinTextMethods["hsv"] = {&HSVNode::makeNode, &HSVNode::makeNode};
26 |
27 | NodeBox::addTool("color","Color",QIcon(":/color.png"),"Color");
28 | NodeBox::addTool("rgb","RGB","Color");
29 | NodeBox::addTool("hsv","HSV","Color");
30 | }
31 |
--------------------------------------------------------------------------------
/plugins/color/ColorPlugin.h:
--------------------------------------------------------------------------------
1 | #ifndef COLORPLUGIN_H
2 | #define COLORPLUGIN_H
3 |
4 | #include
5 | #include
6 |
7 | #include "EmergenceInterface.h"
8 |
9 | class ColorPlugin: public QObject, EmergenceInterface{
10 | Q_OBJECT
11 | Q_PLUGIN_METADATA(IID "Emergence.Plugin")
12 | Q_INTERFACES(EmergenceInterface)
13 | public:
14 | void updateUI(Ui::MainWindow*)const override;
15 | void init()const override;
16 | };
17 |
18 | #endif
19 |
--------------------------------------------------------------------------------
/plugins/color/color.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bsella/Emergence/fdb8f58545ed708bcd9ce670fe85d4a840ddb965/plugins/color/color.png
--------------------------------------------------------------------------------
/plugins/color/color.qrc:
--------------------------------------------------------------------------------
1 |
2 |
3 | color.png
4 |
5 |
6 |
--------------------------------------------------------------------------------
/plugins/color/fromToStream.cpp:
--------------------------------------------------------------------------------
1 | #include "ColorNode.h"
2 | #include
3 |
4 | static Node* askForColor(){
5 | QColor c= QColorDialog::getColor(Qt::white);
6 | if(c.isValid())
7 | return new ColorNode(c.rgba());
8 | return nullptr;
9 | }
10 |
11 | Node* ColorNode::makeFromBin(std::istream& in){
12 | if(in.peek()!=EOF){
13 | data_t::color clr;
14 | in.read(reinterpret_cast(&clr),sizeof(data_t::color));
15 | return new ColorNode(clr);
16 | }
17 | return askForColor();
18 | }
19 |
20 | Node* ColorNode::makeFromText(std::istream& in){
21 | if(in.peek()!=EOF){
22 | data_t::color clr;
23 | in>>clr;
24 | return new ColorNode(clr);
25 | }
26 | return askForColor();
27 | }
28 |
29 | void ColorNode::toBin(std::ostream &out) const{
30 | Node::toBin(out);
31 | out.write(reinterpret_cast(&cache.clr),sizeof(data_t::color));
32 | }
33 |
34 | void ColorNode::toText(std::ostream &out) const{
35 | Node::toText(out);
36 | out <<' '<eval() > iNodes[1]->eval();
29 | }
30 | data_t LTNode::kernel()const{
31 | return iNodes[0]->eval() < iNodes[1]->eval();
32 | }
33 | data_t EQNode::kernel()const{
34 | return iNodes[0]->eval() == iNodes[1]->eval();
35 | }
36 | data_t NENode::kernel()const{
37 | return iNodes[0]->eval() != iNodes[1]->eval();
38 | }
39 |
--------------------------------------------------------------------------------
/plugins/compare/CompNode.h:
--------------------------------------------------------------------------------
1 | #ifndef COMPNODE_H
2 | #define COMPNODE_H
3 |
4 | #include "Node.h"
5 |
6 | class CompNode:public Node{
7 | protected:
8 | CompNode(const std::string &type);
9 | virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem*option, QWidget*widget)=0;
10 | };
11 |
12 | class GTNode:public CompNode{
13 | data_t kernel()const;
14 | void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
15 | public:
16 | GTNode();
17 | inline static Node* makeNode(std::istream&){return new GTNode;}
18 | };
19 |
20 | class LTNode:public CompNode{
21 | data_t kernel()const;
22 | void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
23 | public:
24 | LTNode();
25 | inline static Node* makeNode(std::istream&){return new LTNode;}
26 | };
27 |
28 | class EQNode:public CompNode{
29 | data_t kernel()const;
30 | void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
31 | public:
32 | EQNode();
33 | inline static Node* makeNode(std::istream&){return new EQNode;}
34 | };
35 |
36 | class NENode:public CompNode{
37 | data_t kernel()const;
38 | void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
39 | public:
40 | NENode();
41 | inline static Node* makeNode(std::istream&){return new NENode;}
42 | };
43 |
44 | #endif
45 |
--------------------------------------------------------------------------------
/plugins/compare/ComparePlugin.cpp:
--------------------------------------------------------------------------------
1 | #include "ComparePlugin.h"
2 | #include "CompNode.h"
3 |
4 | void ComparePlugin::updateUI(Ui::MainWindow*ui) const{
5 | QMenu* compMenu = new QMenu("Compare",ui->menuInsert);
6 | ui->menuInsert->addAction(compMenu->menuAction());
7 | QAction* gtAction= new QAction(QIcon(":/gt.png"), "Greater Than");
8 | QAction* ltAction= new QAction(QIcon(":/lt.png"), "Less Than");
9 | QAction* eqAction= new QAction(QIcon(":/eq.png"), "Equal");
10 | QAction* neAction= new QAction(QIcon(":/ne.png"), "Not Equal");
11 |
12 | Workspace* ws= (Workspace*)ui->workspace->scene();
13 | connect(gtAction,&QAction::triggered,ws,[=]{ws->addNode(Node::nodeMalloc("gt"));});
14 | connect(ltAction,&QAction::triggered,ws,[=]{ws->addNode(Node::nodeMalloc("lt"));});
15 | connect(eqAction,&QAction::triggered,ws,[=]{ws->addNode(Node::nodeMalloc("eq"));});
16 | connect(neAction,&QAction::triggered,ws,[=]{ws->addNode(Node::nodeMalloc("ne"));});
17 |
18 | compMenu->addAction(gtAction);
19 | compMenu->addAction(ltAction);
20 | compMenu->addAction(eqAction);
21 | compMenu->addAction(neAction);
22 |
23 | }
24 |
25 | void ComparePlugin::init()const{
26 | Node::makeNodeBinTextMethods["gt"] = {>Node::makeNode,>Node::makeNode};
27 | Node::makeNodeBinTextMethods["lt"] = {<Node::makeNode,<Node::makeNode};
28 | Node::makeNodeBinTextMethods["eq"] = {&EQNode::makeNode,&EQNode::makeNode};
29 | Node::makeNodeBinTextMethods["ne"] = {&NENode::makeNode,&NENode::makeNode};
30 |
31 | NodeBox::addTool("gt","Greater Than",QIcon(":/gt.png"),"Compare");
32 | NodeBox::addTool("lt","Less Than",QIcon(":/lt.png"),"Compare");
33 | NodeBox::addTool("eq","Equal",QIcon(":/eq.png"),"Compare");
34 | NodeBox::addTool("ne","Not Equal",QIcon(":/ne.png"),"Compare");
35 | }
36 |
--------------------------------------------------------------------------------
/plugins/compare/ComparePlugin.h:
--------------------------------------------------------------------------------
1 | #ifndef COMPAREPLUGIN_H
2 | #define COMPAREPLUGIN_H
3 |
4 | #include
5 | #include
6 |
7 | #include "EmergenceInterface.h"
8 |
9 | class ComparePlugin: public QObject, EmergenceInterface{
10 | Q_OBJECT
11 | Q_PLUGIN_METADATA(IID "Emergence.Plugin")
12 | Q_INTERFACES(EmergenceInterface)
13 | public:
14 | void updateUI(Ui::MainWindow*)const override;
15 | void init()const;
16 | };
17 |
18 | #endif
19 |
--------------------------------------------------------------------------------
/plugins/compare/comp.qrc:
--------------------------------------------------------------------------------
1 |
2 |
3 | eq.png
4 | gt.png
5 | lt.png
6 | ne.png
7 |
8 |
9 |
--------------------------------------------------------------------------------
/plugins/compare/eq.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bsella/Emergence/fdb8f58545ed708bcd9ce670fe85d4a840ddb965/plugins/compare/eq.png
--------------------------------------------------------------------------------
/plugins/compare/gt.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bsella/Emergence/fdb8f58545ed708bcd9ce670fe85d4a840ddb965/plugins/compare/gt.png
--------------------------------------------------------------------------------
/plugins/compare/lt.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bsella/Emergence/fdb8f58545ed708bcd9ce670fe85d4a840ddb965/plugins/compare/lt.png
--------------------------------------------------------------------------------
/plugins/compare/ne.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bsella/Emergence/fdb8f58545ed708bcd9ce670fe85d4a840ddb965/plugins/compare/ne.png
--------------------------------------------------------------------------------
/plugins/condition/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | cmake_minimum_required(VERSION 3.0.0)
2 | project(ConditionPlugin)
3 |
4 | find_package(Qt5Widgets REQUIRED)
5 |
6 | set(CMAKE_AUTOMOC ON)
7 | set(CMAKE_AUTORCC ON)
8 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC")
9 | qt5_add_resources(QRC cond.qrc)
10 | add_custom_target(cond_qrc DEPENDS ${QRC})
11 |
12 | set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PLUGIN_OUTPUT_PATH})
13 |
14 | include_directories(${MAIN_SRC_DIR} ${BIN_SRC_DIR} ${Qt5Widgets_INCLUDE_DIRS})
15 |
16 | add_library(${PROJECT_NAME} SHARED ConditionPlugin.cpp ConditionPlugin.h)
17 | add_library(cond
18 | IfNode.cpp
19 | IfNode.h)
20 |
21 | target_link_libraries(${PROJECT_NAME} cond data_t ${QRC})
22 | add_dependencies(${PROJECT_NAME} cond_qrc)
23 |
--------------------------------------------------------------------------------
/plugins/condition/ConditionPlugin.cpp:
--------------------------------------------------------------------------------
1 | #include "ConditionPlugin.h"
2 | #include "IfNode.h"
3 |
4 | void ConditionPlugin::updateUI(Ui::MainWindow*ui) const{
5 | QAction* ifAction= new QAction(QIcon(":/if.png"),"Condition");
6 |
7 | Workspace* ws=(Workspace*)ui->workspace->scene();
8 | connect(ifAction,&QAction::triggered,ws,[=]{ws->addNode(Node::nodeMalloc("if"));});
9 |
10 | ui->menuInsert->addAction(ifAction);
11 | }
12 |
13 | void ConditionPlugin::init()const{
14 | Node::makeNodeBinTextMethods["if"] = {&IfNode::makeNode,&IfNode::makeNode};
15 |
16 | NodeBox::addTool("if","Condition",QIcon(":/if.png"));
17 | }
18 |
--------------------------------------------------------------------------------
/plugins/condition/ConditionPlugin.h:
--------------------------------------------------------------------------------
1 | #ifndef CONDITIONPLUGIN_H
2 | #define CONDITIONPLUGIN_H
3 |
4 | #include
5 | #include
6 |
7 | #include "EmergenceInterface.h"
8 |
9 | class ConditionPlugin: public QObject, EmergenceInterface{
10 | Q_OBJECT
11 | Q_PLUGIN_METADATA(IID "Emergence.Plugin")
12 | Q_INTERFACES(EmergenceInterface)
13 | public:
14 | void updateUI(Ui::MainWindow*)const override;
15 | void init()const;
16 | };
17 |
18 | #endif
19 |
--------------------------------------------------------------------------------
/plugins/condition/IfNode.cpp:
--------------------------------------------------------------------------------
1 | #include "IfNode.h"
2 |
3 | #include
4 |
5 | IfNode::IfNode():Node("if",50,100,QColor(180,180,255),3){}
6 |
7 | void IfNode::paint(QPainter* painter,
8 | const QStyleOptionGraphicsItem*option,
9 | QWidget*widget){
10 | Node::paint(painter,option,widget);
11 | painter->setPen(QPen(Qt::black,1));
12 | QRectF rect=boundingRect();
13 | painter->drawText(rect.topLeft()+QPointF(8,rect.height()/4.0+4),"THEN");
14 | painter->drawText(rect.topLeft()+QPointF(8,2*rect.height()/4.0+4),"IF");
15 | painter->drawText(rect.topLeft()+QPointF(8,3*rect.height()/4.0+4),"ELSE");
16 | }
17 |
18 | data_t IfNode::kernel()const{
19 | return iNodes[1]->eval()? iNodes[0]->eval() : iNodes[2]->eval();
20 | }
21 |
--------------------------------------------------------------------------------
/plugins/condition/IfNode.h:
--------------------------------------------------------------------------------
1 | #ifndef IFNODE_H
2 | #define IFNODE_H
3 |
4 | #include "Node.h"
5 |
6 | class IfNode:public Node{
7 | public:
8 | IfNode();
9 | inline static Node* makeNode(std::istream&){return new IfNode;}
10 | private:
11 | data_t kernel()const;
12 | void paint(QPainter* painter,
13 | const QStyleOptionGraphicsItem* option,
14 | QWidget*widget);
15 | };
16 |
17 | #endif
18 |
--------------------------------------------------------------------------------
/plugins/condition/cond.qrc:
--------------------------------------------------------------------------------
1 |
2 |
3 | if.png
4 |
5 |
6 |
--------------------------------------------------------------------------------
/plugins/condition/if.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bsella/Emergence/fdb8f58545ed708bcd9ce670fe85d4a840ddb965/plugins/condition/if.png
--------------------------------------------------------------------------------
/plugins/functions/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | cmake_minimum_required(VERSION 3.0.0)
2 | project(FunctionsPlugin)
3 |
4 | find_package(Qt5Widgets REQUIRED)
5 |
6 | set(CMAKE_AUTOMOC ON)
7 | set(CMAKE_AUTOUIC ON)
8 | set(CMAKE_AUTORCC ON)
9 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC")
10 | qt5_add_resources(QRC func.qrc)
11 | add_custom_target(func_qrc DEPENDS ${QRC})
12 |
13 | qt5_wrap_ui(UI_HEADERS functionmanager.ui)
14 |
15 | set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PLUGIN_OUTPUT_PATH})
16 |
17 | include_directories(${MAIN_SRC_DIR} ${BIN_SRC_DIR} ${CMAKE_CURRENT_BINARY_DIR} ${Qt5Widgets_INCLUDE_DIRS})
18 |
19 | add_library(${PROJECT_NAME} SHARED FunctionPlugin.cpp FunctionPlugin.h)
20 | add_library(func
21 | FunctionNode.cpp
22 | Function.cpp
23 | FunctionManager.cpp
24 | FunctionNode.h
25 | Function.h
26 | FunctionManager.h
27 | fromToStream.cpp
28 | ${UI_HEADERS})
29 |
30 | target_link_libraries(${PROJECT_NAME} func data_t ${QRC})
31 | add_dependencies(${PROJECT_NAME} func_qrc)
32 |
--------------------------------------------------------------------------------
/plugins/functions/Function.cpp:
--------------------------------------------------------------------------------
1 | #include "Function.h"
2 | #include "FunctionNode.h"
3 |
4 | #include
5 |
6 | Function::FunctionInputNode::FunctionInputNode(int rank):Node("fin",40,40,Qt::lightGray),_rank(rank){
7 | actionDelete->setEnabled(false);
8 | }
9 | void Function::FunctionInputNode::paint(QPainter *p, const QStyleOptionGraphicsItem *o, QWidget *w){
10 | Node::paint(p,o,w);
11 | QRectF rect= boundingRect();
12 | p->drawText(rect.topLeft()+QPointF(8,2*rect.height()/4.0+4),QString::number(_rank));
13 | }
14 | data_t Function::FunctionInputNode::kernel()const{
15 | return FunctionNode::current->iNodes[_rank]->eval();
16 | }
17 |
18 | Function::FunctionOutputNode::FunctionOutputNode():Node("fout",50,50,Qt::lightGray,1,true){
19 | actionDelete->setEnabled(false);
20 | }
21 | void Function::FunctionOutputNode::paint(QPainter *p, const QStyleOptionGraphicsItem *o, QWidget *w){
22 | Node::paint(p,o,w);
23 | Node::drawIcon(p,":/arrow.png");
24 | }
25 |
26 | Function::Function(int n, const QString& name):QListWidgetItem(name), nbArgs(n){
27 | scene= new Workspace;
28 | start= new FunctionOutputNode;
29 | scene->addItem(start);
30 | for(int i=0;iaddItem(iNodes[i]);
33 | }
34 | }
35 | Function::Function(){
36 | scene= new Workspace;
37 | }
38 | Function::~Function(){
39 | for(int i=nbArgs-1;i>=0;i--)
40 | delete iNodes[i];
41 | delete start;
42 | // delete scene;
43 | }
44 |
45 | Function::FunctionOutputNode * Function::getOutputFromScene()const{
46 | for(const auto& n: scene->nodes())
47 | if(n->_type=="fout")
48 | return (FunctionOutputNode*)n;
49 | return nullptr;
50 | }
51 | Function::FunctionInputNode *Function::getNthInputFromScene(int n)const{
52 | for(const auto& node: scene->nodes())
53 | if(node->_type=="fin"&& ((FunctionInputNode*)node)->_rank==n)
54 | return (FunctionInputNode*)node;
55 | return nullptr;
56 | }
57 |
--------------------------------------------------------------------------------
/plugins/functions/Function.h:
--------------------------------------------------------------------------------
1 | #ifndef FUNCTION_H
2 | #define FUNCTION_H
3 |
4 | #include "Node.h"
5 | #include
6 | #include "Workspace.h"
7 |
8 | class Function: public QListWidgetItem{
9 | public:
10 | struct FunctionInputNode: public Node{
11 | FunctionInputNode(int rank);
12 | const int _rank;
13 | data_t kernel()const;
14 | void paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget *);
15 | void toBin(std::ostream &)const;
16 | void toText(std::ostream &)const;
17 | static Node* makefromBin(std::istream&);
18 | static Node* makefromText(std::istream&);
19 | };
20 | struct FunctionOutputNode: Node{
21 | FunctionOutputNode();
22 | inline data_t kernel()const{return iNodes[0]->eval();}
23 | inline static Node* makeNode(std::istream&){return new FunctionOutputNode;}
24 | void paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget *);
25 | };
26 | Function(int,const QString&);
27 | Function();
28 | ~Function();
29 | int nbArgs;
30 | FunctionOutputNode* start;
31 | QVector iNodes;
32 | Workspace* scene;
33 | void toBin(std::ostream& out)const;
34 | void toText(std::ostream& out)const;
35 | FunctionOutputNode* getOutputFromScene()const;
36 | FunctionInputNode* getNthInputFromScene(int n)const;
37 | };
38 |
39 |
40 | #endif // FUNCTION_H
41 |
--------------------------------------------------------------------------------
/plugins/functions/FunctionManager.cpp:
--------------------------------------------------------------------------------
1 | #include "FunctionManager.h"
2 | #include "ui_functionmanager.h"
3 |
4 | FunctionManager* FunctionManager::singleton=0;
5 | FunctionManager* FunctionManager::instance(){
6 | if(singleton==0)
7 | singleton= new FunctionManager;
8 | return singleton;
9 | }
10 | FunctionManager::FunctionManager(QWidget *parent):
11 | QDialog(parent), ui(new Ui::FunctionManager){
12 | ui->setupUi(this);
13 | ui->workspace->setAcceptDrops(true);
14 | ui->workspace->setDragMode(QGraphicsView::DragMode::RubberBandDrag);
15 | ui->removeFunctionButton->setEnabled(false);
16 | connect(ui->listWidget,SIGNAL(itemDoubleClicked(QListWidgetItem*)),this,SLOT(renameFunction(QListWidgetItem*)));
17 | connect(ui->listWidget,&QListWidget::currentItemChanged,this,&FunctionManager::setFunction);
18 | connect(ui->buttonBox,SIGNAL(accepted()),this,SLOT(accept()));
19 | connect(ui->buttonBox,SIGNAL(rejected()),this,SLOT(reject()));
20 |
21 | del.setShortcut(QKeySequence::Delete);
22 | copy.setShortcut(QKeySequence::Copy);
23 | cut.setShortcut(QKeySequence::Cut);
24 | paste.setShortcut(QKeySequence::Paste);
25 | select_all.setShortcut(QKeySequence::SelectAll);
26 | undo.setShortcut(QKeySequence::Undo);
27 | redo.setShortcut(QKeySequence::Redo);
28 | addAction(&undo);
29 | addAction(&redo);
30 | addAction(&select_all);
31 | addAction(&paste);
32 | addAction(&cut);
33 | addAction(©);
34 | addAction(&del);
35 | }
36 |
37 | void FunctionManager::accept(){
38 | undoStack.setClean();
39 | for(int i=0; ilistWidget->count();i++)
40 | ((Function*)ui->listWidget->item(i))->scene->undoStack.setClean();
41 | QDialog::accept();
42 | }
43 | void FunctionManager::reject(){
44 | while(!undoStack.isClean())
45 | undoStack.undo();
46 | for(int i=0; ilistWidget->count();i++){
47 | Function *f=(Function*)ui->listWidget->item(i);
48 | while(!f->scene->undoStack.isClean())
49 | f->scene->undoStack.undo();
50 | }
51 | QDialog::reject();
52 | }
53 |
54 | FunctionManager::~FunctionManager(){
55 | delete ui;
56 | }
57 |
58 | Function* FunctionManager::functionAt(int i){
59 | return (Function*)instance()->ui->listWidget->item(i);
60 | }
61 | int FunctionManager::indexOf(Function *f){
62 | return instance()->ui->listWidget->row(f);
63 | }
64 | int FunctionManager::count(){
65 | return instance()->ui->listWidget->count();
66 | }
67 |
68 | void FunctionManager::on_addFunctionButton_clicked(){
69 | undoStack.push(new AddFunctionCommand);
70 | }
71 | void FunctionManager::on_removeFunctionButton_clicked(){
72 | undoStack.push(new RemoveFunctionCommand);
73 | }
74 | void FunctionManager::renameFunction(QListWidgetItem *item){
75 | QString newname= QInputDialog::getText(this,"Change function name", "Name :");
76 | if(!newname.isNull()){
77 | newname.replace(' ','_');
78 | undoStack.push(new RenameFunctionCommand((Function*)item,newname));
79 | }
80 | }
81 |
82 | Function* FunctionManager::getFunction(FunctionNode *node){
83 | if(node) instance()->ui->listWidget->setCurrentItem(node->func);
84 | if(instance()->exec())
85 | return (Function*)instance()->ui->listWidget->currentItem();
86 | return nullptr;
87 | }
88 |
89 | bool FunctionManager::userIntented=true;
90 |
91 | void FunctionManager::on_spinBox_valueChanged(int arg1){
92 | if(userIntented){
93 | Function* func=(Function*)ui->listWidget->currentItem();
94 | func->scene->undoStack.push(new ChangeNbArgsCommand(func,func->nbArgs,arg1));
95 | }
96 | }
97 |
98 | void FunctionManager::setFunction(QListWidgetItem* curr, QListWidgetItem* prev){
99 | if(!curr){
100 | ui->workspace->setScene(0);
101 | ui->spinBox->setEnabled(false);
102 | ui->removeFunctionButton->setEnabled(false);
103 | return;
104 | }
105 | ui->spinBox->setEnabled(true);
106 | ui->removeFunctionButton->setEnabled(true);
107 | if(Function* fPrev=(Function*)prev){
108 | disconnect(&redo,SIGNAL(triggered(bool)),&fPrev->scene->undoStack,SLOT(redo()));
109 | disconnect(&undo,SIGNAL(triggered(bool)),&fPrev->scene->undoStack,SLOT(undo()));
110 | disconnect(&select_all,SIGNAL(triggered(bool)),fPrev->scene,SLOT(select_all()));
111 | disconnect(&paste,SIGNAL(triggered(bool)),fPrev->scene,SLOT(paste()));
112 | disconnect(&cut,SIGNAL(triggered(bool)),fPrev->scene,SLOT(cut()));
113 | disconnect(©,SIGNAL(triggered(bool)),fPrev->scene,SLOT(copy()));
114 | disconnect(&del,SIGNAL(triggered(bool)),fPrev->scene,SLOT(delete_selected()));
115 | }
116 | if(Function* fCurr=(Function*)curr){
117 | ui->workspace->setScene(fCurr->scene);
118 | userIntented=false;
119 | ui->spinBox->setValue(fCurr->nbArgs);
120 | userIntented=true;
121 | connect(&del,SIGNAL(triggered(bool)),fCurr->scene,SLOT(delete_selected()));
122 | connect(©,SIGNAL(triggered(bool)),fCurr->scene,SLOT(copy()));
123 | connect(&cut,SIGNAL(triggered(bool)),fCurr->scene,SLOT(cut()));
124 | connect(&paste,SIGNAL(triggered(bool)),fCurr->scene,SLOT(paste()));
125 | connect(&select_all,SIGNAL(triggered(bool)),fCurr->scene,SLOT(select_all()));
126 | connect(&undo,SIGNAL(triggered(bool)),&fCurr->scene->undoStack,SLOT(undo()));
127 | connect(&redo,SIGNAL(triggered(bool)),&fCurr->scene->undoStack,SLOT(redo()));
128 | }
129 | }
130 |
131 | ChangeNbArgsCommand::ChangeNbArgsCommand(Function* f,int from, int to,QUndoCommand* parent)
132 | :QUndoCommand(parent){
133 | _from=from;
134 | _to=to;
135 | func=f;
136 | }
137 | void ChangeNbArgsCommand::undo(){
138 | if(_to>_from)
139 | for(int i=_from; i<_to; i++){
140 | func->scene->removeItem(func->iNodes[i]);
141 | delete func->iNodes[i];
142 | func->iNodes.pop_back();
143 | }
144 | else
145 | for(int i=_to; i<_from; i++){
146 | func->iNodes.push_back(new Function::FunctionInputNode(i));
147 | func->scene->addItem(func->iNodes[i]);
148 | }
149 | func->nbArgs=_from;
150 | FunctionManager::userIntented=false;
151 | FunctionManager::instance()->ui->spinBox->setValue(_from);
152 | FunctionManager::userIntented=true;
153 | func->scene->update();
154 | }
155 | void ChangeNbArgsCommand::redo(){
156 | if(_to>_from)
157 | for(int i=_from; i<_to; i++){
158 | func->iNodes.push_back(new Function::FunctionInputNode(i));
159 | func->scene->addItem(func->iNodes[i]);
160 | }
161 | else
162 | for(int i=_to; i<_from; i++){
163 | func->scene->removeItem(func->iNodes[i]);
164 | delete func->iNodes[i];
165 | func->iNodes.pop_back();
166 | }
167 | func->nbArgs=_to;
168 | FunctionManager::userIntented=false;
169 | FunctionManager::instance()->ui->spinBox->setValue(_to);
170 | FunctionManager::userIntented=true;
171 | func->scene->update();
172 | }
173 |
174 | AddFunctionCommand::AddFunctionCommand(QUndoCommand*parent)
175 | :QUndoCommand(parent){
176 | func= new Function(0,"New_Function");
177 | }
178 | void AddFunctionCommand::undo(){
179 | QObject::disconnect(func->start,SIGNAL(disconnected(Node::Socket*)),func->scene,SLOT(disconnectNode(Node::Socket*)));
180 | QObject::disconnect(func->start,SIGNAL(connected(Node::Socket*,Node*)),func->scene,SLOT(connectNode(Node::Socket*,Node*)));
181 | for(Node* n:func->iNodes){
182 | QObject::disconnect(n,SIGNAL(connected(Node::Socket*,Node*)),func->scene,SLOT(connectNode(Node::Socket*,Node*)));
183 | QObject::disconnect(n,SIGNAL(disconnected(Node::Socket*)),func->scene,SLOT(disconnectNode(Node::Socket*)));
184 | }
185 | delete func;
186 | FunctionManager::instance()->ui->removeFunctionButton->setEnabled(
187 | FunctionManager::instance()->ui->listWidget->count()>1);
188 | }
189 | void AddFunctionCommand::redo(){
190 | FunctionManager::instance()->ui->listWidget->addItem(func);
191 |
192 | QObject::connect(func->start,SIGNAL(connected(Node::Socket*,Node*)),func->scene,SLOT(connectNode(Node::Socket*,Node*)));
193 | QObject::connect(func->start,SIGNAL(disconnected(Node::Socket*)),func->scene,SLOT(disconnectNode(Node::Socket*)));
194 | for(Node* n:func->iNodes){
195 | QObject::connect(n,SIGNAL(connected(Node::Socket*,Node*)),func->scene,SLOT(connectNode(Node::Socket*,Node*)));
196 | QObject::connect(n,SIGNAL(disconnected(Node::Socket*)),func->scene,SLOT(disconnectNode(Node::Socket*)));
197 | }
198 | FunctionManager::instance()->ui->removeFunctionButton->setEnabled(true);
199 | }
200 |
201 | RemoveFunctionCommand::RemoveFunctionCommand(QUndoCommand *parent)
202 | :QUndoCommand(parent){
203 | _rank=FunctionManager::instance()->ui->listWidget->currentRow();
204 | }
205 | void RemoveFunctionCommand::undo(){
206 | FunctionManager::instance()->ui->listWidget->insertItem(_rank,func);
207 | FunctionManager::instance()->ui->removeFunctionButton->setEnabled(true);
208 | }
209 | void RemoveFunctionCommand::redo(){
210 | func=(Function*)FunctionManager::instance()->ui->listWidget->takeItem(_rank);
211 | FunctionManager::instance()->ui->removeFunctionButton->setEnabled(
212 | FunctionManager::instance()->ui->listWidget->count());
213 | }
214 |
215 | RenameFunctionCommand::RenameFunctionCommand(Function *f, const QString &to, QUndoCommand *parent)
216 | :QUndoCommand(parent){
217 | func=f;
218 | _from=f->text();
219 | _to=to;
220 | }
221 | void RenameFunctionCommand::undo(){
222 | func->setText(_from);
223 | }
224 | void RenameFunctionCommand::redo(){
225 | func->setText(_to);
226 | }
227 |
228 | void FunctionManager::clear(){
229 | instance()->ui->workspace->setScene(0);
230 | while(instance()->ui->listWidget->count())
231 | delete instance()->ui->listWidget->takeItem(0);
232 | instance()->ui->removeFunctionButton->setEnabled(false);
233 | instance()->ui->spinBox->setEnabled(false);
234 | }
235 | void FunctionManager::fromBin(std::istream& in)const{
236 | Function *f= new Function;
237 | std::string str;
238 | in >> str;
239 | in.ignore(1);
240 | f->setText(QString::fromStdString(str));
241 | f->scene->fromBin(in);
242 |
243 | f->start= f->getOutputFromScene();
244 | in.read(reinterpret_cast(&f->nbArgs),sizeof(int));
245 | for(int i=0; inbArgs;i++)
246 | f->iNodes.push_back(f->getNthInputFromScene(i));
247 | ui->listWidget->addItem(f);
248 | }
249 | void FunctionManager::fromText(std::istream& in)const{
250 | Function *f= new Function;
251 | std::string str;
252 | in >> str;
253 | f->setText(QString::fromStdString(str));
254 | f->scene->fromText(in);
255 |
256 | f->start= f->getOutputFromScene();
257 | in >> f->nbArgs;
258 | for(int i=0; inbArgs;i++)
259 | f->iNodes.push_back(f->getNthInputFromScene(i));
260 | ui->listWidget->addItem(f);
261 | }
262 |
--------------------------------------------------------------------------------
/plugins/functions/FunctionManager.h:
--------------------------------------------------------------------------------
1 | #ifndef FUNCTIONMANAGER_H
2 | #define FUNCTIONMANAGER_H
3 |
4 | #include
5 | #include
6 | #include
7 | #include
8 | #include
9 | #include "Function.h"
10 | #include "FunctionNode.h"
11 |
12 | namespace Ui {
13 | class FunctionManager;
14 | }
15 |
16 | class FunctionManager : public QDialog{
17 | Q_OBJECT
18 | public:
19 | static FunctionManager* instance();
20 | static Function* getFunction(FunctionNode* node=0);
21 | static Function* functionAt(int);
22 | static int indexOf(Function*);
23 | static int count();
24 | static void clear();
25 | void fromBin(std::istream&)const;
26 | void fromText(std::istream&)const;
27 | private:
28 | explicit FunctionManager(QWidget *parent = 0);
29 | ~FunctionManager();
30 | static FunctionManager* singleton;
31 | static bool userIntented;
32 | Ui::FunctionManager *ui;
33 | QAction del,copy,cut,paste,undo,redo,select_all;
34 | QUndoStack undoStack;
35 | void setFunction(QListWidgetItem *,QListWidgetItem*);
36 | friend class ChangeNbArgsCommand;
37 | friend class AddFunctionCommand;
38 | friend class RemoveFunctionCommand;
39 | friend class RenameFunctionCommand;
40 | private slots:
41 | void accept();
42 | void reject();
43 | void renameFunction(QListWidgetItem*);
44 | void on_spinBox_valueChanged(int arg1);
45 | void on_addFunctionButton_clicked();
46 | void on_removeFunctionButton_clicked();
47 | };
48 |
49 | class ChangeNbArgsCommand:public QUndoCommand{
50 | public:
51 | ChangeNbArgsCommand(Function*, int, int, QUndoCommand* parent=0);
52 | private:
53 | int _from;
54 | int _to;
55 | Function* func;
56 | void undo();
57 | void redo();
58 | };
59 |
60 | class AddFunctionCommand:public QUndoCommand{
61 | public:
62 | explicit AddFunctionCommand(QUndoCommand*parent=0);
63 | private:
64 | Function* func;
65 | void undo();
66 | void redo();
67 | };
68 | class RemoveFunctionCommand:public QUndoCommand{
69 | public:
70 | explicit RemoveFunctionCommand(QUndoCommand*parent=0);
71 | private:
72 | uint _rank;
73 | Function* func;
74 | void undo();
75 | void redo();
76 | };
77 | class RenameFunctionCommand:public QUndoCommand{
78 | public:
79 | RenameFunctionCommand(Function*,const QString& to,
80 | QUndoCommand* parent=0);
81 | private:
82 | Function* func;
83 | QString _from;
84 | QString _to;
85 | void undo();
86 | void redo();
87 | };
88 |
89 | #endif // FUNCTIONMANAGER_H
90 |
--------------------------------------------------------------------------------
/plugins/functions/FunctionNode.cpp:
--------------------------------------------------------------------------------
1 | #include "FunctionNode.h"
2 |
3 | #include
4 | #include "FunctionManager.h"
5 |
6 | uint FunctionNode::nbNodes=0;
7 | FunctionNode::FunctionNode(Function* f)
8 | :Node("fun",60,50+10*f->nbArgs,Qt::lightGray,f->nbArgs),
9 | func(f),nodeNumber(nbNodes++){}
10 | FunctionNode::FunctionNode():Node("fun",60,50,Qt::lightGray),nodeNumber(nbNodes++){}
11 | FunctionNode::~FunctionNode(){
12 | nbNodes--;
13 | }
14 |
15 | void FunctionNode::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *){
16 | Function* newFunc=FunctionManager::getFunction();
17 | if(newFunc){
18 | func=newFunc;
19 | changeNbArgs(func->nbArgs);
20 | }
21 | update();
22 | }
23 |
24 | void FunctionNode::paint(QPainter *p, const QStyleOptionGraphicsItem *o, QWidget *w){
25 | Node::paint(p,o,w);
26 | QRectF rect = boundingRect();
27 | if(func)
28 | p->drawText(rect.topLeft()+QPointF(8,rect.height()/2.0+4),func->text());
29 | }
30 |
31 | void FunctionNode::changeNbArgs(uint args){
32 | if(nbArgs==args) return;
33 | height=50+10*args;
34 | if(args>nbArgs)
35 | for(uint i=nbArgs; idisconnectNode();
42 | delete sockets.back();
43 | sockets.pop_back();
44 | iNodes.pop_back();
45 | }
46 | nbArgs=args;
47 | update();
48 | }
49 |
50 | FunctionNode::operator bool()const{
51 | if(func)
52 | return Node::operator bool()&& *func->start;
53 | return false;
54 | }
55 |
56 | FunctionNode* FunctionNode::current;
57 |
58 | data_t FunctionNode::eval(){
59 | if(constant) return cache;
60 | if(pixelID==lastPixelID) return cache;
61 |
62 | current=this;
63 | pixelID+=nodeNumber+1;
64 |
65 | cache=kernel();
66 |
67 | /// I have no idea why the next line causes a segfault
68 | /// when using the same function more than once
69 | // pixelID-=nodeNumber+1;
70 | current=nullptr;
71 |
72 | lastPixelID=pixelID;
73 | return cache;
74 | }
75 |
--------------------------------------------------------------------------------
/plugins/functions/FunctionNode.h:
--------------------------------------------------------------------------------
1 | #ifndef FUNCTIONNODE_H
2 | #define FUNCTIONNODE_H
3 |
4 | #include "Node.h"
5 | #include "Function.h"
6 |
7 | class FunctionNode: public Node{
8 | public:
9 | FunctionNode(Function *f);
10 | FunctionNode();
11 | ~FunctionNode();
12 | data_t eval();
13 | static Node* makefromBin(std::istream&);
14 | static Node* makefromText(std::istream&);
15 | static FunctionNode* current;
16 | Function* func;
17 | const uint nodeNumber;
18 | private:
19 | static uint nbNodes;
20 | inline data_t kernel()const{return func->start->eval();}
21 | void mouseDoubleClickEvent(QGraphicsSceneMouseEvent*);
22 | void paint(QPainter*, const QStyleOptionGraphicsItem*, QWidget*);
23 | operator bool()const;
24 | void changeNbArgs(uint args);
25 | void toBin(std::ostream&)const override;
26 | void toText(std::ostream&)const override;
27 | };
28 |
29 | #endif // FUNCTIONNODE_H
30 |
--------------------------------------------------------------------------------
/plugins/functions/FunctionPlugin.cpp:
--------------------------------------------------------------------------------
1 | #include "FunctionPlugin.h"
2 |
3 | #include "FunctionNode.h"
4 | #include "FunctionManager.h"
5 |
6 | void FunctionPlugin::updateUI(Ui::MainWindow* ui) const{
7 | QAction* funcAction= new QAction("Function");
8 |
9 | Workspace* ws=(Workspace*)ui->workspace->scene();
10 | connect(funcAction,&QAction::triggered,ws,[=]{
11 | Function* f= FunctionManager::getFunction();
12 | if(f){
13 | std::istringstream in(std::to_string(FunctionManager::indexOf(f)));
14 | ws->addNode(Node::nodeMalloc("fun",in));
15 | }
16 | });
17 |
18 | ui->menuInsert->addAction(funcAction);
19 |
20 | QAction* fmAction= new QAction("Function Manager");
21 | connect(fmAction,SIGNAL(triggered(bool)),FunctionManager::instance(),SLOT(exec()));
22 | ui->menuTools->addAction(fmAction);
23 | }
24 |
25 | void FunctionPlugin::init()const{
26 | Node::makeNodeBinTextMethods["fun"] = {&FunctionNode::makefromBin,&FunctionNode::makefromText};
27 | Node::makeNodeBinTextMethods["fin"] =
28 | {&Function::FunctionInputNode::makefromBin,&Function::FunctionInputNode::makefromText};
29 | Node::makeNodeBinTextMethods["fout"] =
30 | {&Function::FunctionOutputNode::makeNode, &Function::FunctionOutputNode::makeNode};
31 | NodeBox::addTool("fun","Function");
32 | }
33 |
34 | void FunctionPlugin::toBin(std::ostream &out)const{
35 | int tmp= FunctionManager::count();
36 | out.write(reinterpret_cast(&tmp),sizeof(int));
37 | for(int i=0; itoBin(out);
39 | }
40 | void FunctionPlugin::toText(std::ostream &out)const{
41 | int tmp= FunctionManager::count();
42 | out << tmp << '\n';
43 | for(int i=0; itoText(out);
45 | }
46 | void FunctionPlugin::fromBin(std::istream &in) const{
47 | FunctionManager::clear();
48 | int tmp;
49 | in.read(reinterpret_cast(&tmp),sizeof(int));
50 | for(int i=0;ifromBin(in);
52 | }
53 | void FunctionPlugin::fromText(std::istream &in) const{
54 | FunctionManager::clear();
55 | int tmp;
56 | in>>tmp;
57 | for(int i=0;ifromText(in);
59 | }
60 |
--------------------------------------------------------------------------------
/plugins/functions/FunctionPlugin.h:
--------------------------------------------------------------------------------
1 | #ifndef FUNCPLUGIN_H
2 | #define FUNCPLUGIN_H
3 |
4 | #include
5 | #include
6 |
7 | #include "EmergenceInterface.h"
8 |
9 | class FunctionPlugin: public QObject, EmergenceInterface{
10 | Q_OBJECT
11 | Q_PLUGIN_METADATA(IID "Emergence.Plugin")
12 | Q_INTERFACES(EmergenceInterface)
13 | public:
14 | void updateUI(Ui::MainWindow*)const override;
15 | void init()const override;
16 | void toBin(std::ostream&)const override;
17 | void toText(std::ostream&)const override;
18 | void fromBin(std::istream&)const override;
19 | void fromText(std::istream&)const override;
20 | inline bool redefineSaveLoad()const override{return true;}
21 | };
22 |
23 | #endif
24 |
--------------------------------------------------------------------------------
/plugins/functions/arrow.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bsella/Emergence/fdb8f58545ed708bcd9ce670fe85d4a840ddb965/plugins/functions/arrow.png
--------------------------------------------------------------------------------
/plugins/functions/fromToStream.cpp:
--------------------------------------------------------------------------------
1 | #include "FunctionNode.h"
2 | #include "FunctionManager.h"
3 |
4 | Node* Function::FunctionInputNode::makefromBin(std::istream &in){
5 | int r;
6 | in.read(reinterpret_cast(&r),sizeof(int));
7 | return new FunctionInputNode(r);
8 | }
9 | Node* Function::FunctionInputNode::makefromText(std::istream &in){
10 | int r;
11 | in >>r;
12 | return new FunctionInputNode(r);
13 | }
14 |
15 | void Function::FunctionInputNode::toBin(std::ostream&out)const{
16 | Node::toBin(out);
17 | out.write(reinterpret_cast(&_rank),sizeof(int));
18 | }
19 | void Function::FunctionInputNode::toText(std::ostream&out)const{
20 | Node::toText(out);
21 | out <<' '<< _rank;
22 | }
23 |
24 | void Function::toBin(std::ostream& out)const{
25 | const std::string tmp= text().toStdString();
26 | out.write(tmp.data(),sizeof(char)*tmp.size());
27 | out << '\n';
28 | scene->toBin(out);
29 | out.write(reinterpret_cast(&nbArgs),sizeof(int));
30 | }
31 |
32 | void Function::toText(std::ostream& out)const{
33 | out << text().toStdString()<<"\n";
34 | scene->toText(out);
35 | out << nbArgs << '\n';
36 | }
37 |
38 | Node* FunctionNode::makefromBin(std::istream&in){
39 | Function* f;
40 | if(in.peek()!=EOF){
41 | int i;
42 | in.read(reinterpret_cast(&i),sizeof(int));
43 | f=FunctionManager::functionAt(i);
44 | }else{
45 | f=FunctionManager::getFunction();
46 | if(!f) return nullptr;
47 | }
48 | return new FunctionNode(f);
49 | }
50 | Node* FunctionNode::makefromText(std::istream&in){
51 | Function* f;
52 | if(in.peek()!=EOF){
53 | int i;
54 | in >> i;
55 | f=FunctionManager::functionAt(i);
56 | }else{
57 | f=FunctionManager::getFunction();
58 | if(!f) return nullptr;
59 | }
60 | return new FunctionNode(f);
61 | }
62 |
63 | void FunctionNode::toBin(std::ostream &out) const{
64 | Node::toBin(out);
65 | const int tmp= FunctionManager::indexOf(func);
66 | out.write(reinterpret_cast(&tmp),sizeof(int));
67 | }
68 | void FunctionNode::toText(std::ostream &out) const{
69 | Node::toText(out);
70 | out <<' '<< FunctionManager::indexOf(func);
71 | }
72 |
--------------------------------------------------------------------------------
/plugins/functions/func.qrc:
--------------------------------------------------------------------------------
1 |
2 |
3 | arrow.png
4 |
5 |
6 |
--------------------------------------------------------------------------------
/plugins/functions/functionmanager.ui:
--------------------------------------------------------------------------------
1 |
2 |
3 | FunctionManager
4 |
5 |
6 |
7 | 0
8 | 0
9 | 747
10 | 417
11 |
12 |
13 |
14 | Function Manager
15 |
16 |
17 | -
18 |
19 |
20 |
21 | 150
22 | 16777215
23 |
24 |
25 |
26 | -1
27 |
28 |
29 |
30 | -
31 |
32 |
33 |
34 | 0
35 | 0
36 |
37 |
38 |
39 |
40 | 100
41 | 16777215
42 |
43 |
44 |
45 |
46 | -
47 |
48 |
-
49 |
50 |
51 | Qt::Vertical
52 |
53 |
54 |
55 | 20
56 | 40
57 |
58 |
59 |
60 |
61 | -
62 |
63 |
64 | Add
65 |
66 |
67 |
68 | -
69 |
70 |
71 | false
72 |
73 |
74 | Remove
75 |
76 |
77 |
78 | -
79 |
80 |
81 | false
82 |
83 |
84 |
85 | -
86 |
87 |
88 | Qt::Vertical
89 |
90 |
91 | QDialogButtonBox::Cancel|QDialogButtonBox::Ok
92 |
93 |
94 | true
95 |
96 |
97 |
98 | -
99 |
100 |
101 | Qt::Vertical
102 |
103 |
104 |
105 | 20
106 | 40
107 |
108 |
109 |
110 |
111 |
112 |
113 | -
114 |
115 |
116 |
117 |
118 |
119 |
120 | NodeBox
121 | QToolBox
122 |
123 | 1
124 |
125 |
126 |
127 |
128 |
129 |
--------------------------------------------------------------------------------
/plugins/image/BitmapNode.cpp:
--------------------------------------------------------------------------------
1 | #include "BitmapNode.h"
2 |
3 | #include
4 | #include
5 | #include
6 |
7 | BitmapNode::BitmapNode(const std::string& filename):
8 | Node("img",70,70,Qt::lightGray,2),path(filename){
9 | setBMP(filename);
10 | }
11 |
12 | BitmapNode::~BitmapNode(){
13 | delete bmp;
14 | }
15 |
16 | void BitmapNode::setBMP(const std::string& filename){
17 | path=filename;
18 | bmp= new QPixmap(QString::fromStdString(filename));
19 | bmpWidth=bmp->width();
20 | bmpHeight=bmp->height();
21 | }
22 |
23 | data_t BitmapNode::kernel()const{
24 | if(!bmp) return 0xff000000;
25 | int g0 = double(iNodes[0]->eval())*bmpWidth;
26 | int g1 = double(iNodes[1]->eval())*bmpHeight;
27 | if(g0<0 || g0>=bmpWidth || g1<0 || g1>=bmpHeight)
28 | return 0xff000000;
29 | return bmp->toImage().pixel(g0,g1);
30 | }
31 |
32 | QImage BitmapNode::scaleImage(uint w, uint h) const{
33 | QImage image(w,h,QImage::Format_ARGB32_Premultiplied);
34 | for(uint i=0; itoImage().pixel(double(i)/w*bmpWidth,double(j)/h*bmpHeight));
37 | return image;
38 | }
39 |
40 | void BitmapNode::paint(QPainter *painter, const QStyleOptionGraphicsItem*, QWidget*){
41 | pen.setWidth(isSelected()?2:1);
42 | painter->setPen(pen);
43 | painter->drawLine(QPointF(0,height/(3.0)),QPointF(socketSize,height/(3.0)));
44 | painter->drawLine(QPointF(0,2*height/(3.0)),QPointF(socketSize,2*height/(3.0)));
45 | painter->drawRect(socketSize,0,width,height);
46 | QRectF rect= boundingRect();
47 | painter->drawLine(rect.center()+QPointF(rect.width()/2,0),rect.center()+QPointF(rect.width()/2-socketSize,0));
48 | if(bmp->isNull()){
49 | painter->drawText(boundingRect().center()+QPointF(-20,-2),"Bitmap");
50 | painter->drawText(boundingRect().center()+QPointF(-28,12),"not found");
51 | }
52 | else
53 | painter->drawImage(socketSize+1,1,scaleImage(width-1,height-1));
54 | }
55 |
56 | void BitmapNode::contextMenuEvent(QGraphicsSceneContextMenuEvent* event){
57 | menu=new QMenu;
58 | connect(menu->addAction(QString("Choose image")), &QAction::triggered,this,&BitmapNode::changeBMP);
59 | menu->addSeparator();
60 | Node::contextMenuEvent(event);
61 | }
62 |
63 | void BitmapNode::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *){
64 | changeBMP();
65 | }
66 |
67 | void BitmapNode::changeBMP(){
68 | QString f= QFileDialog::getOpenFileName(0,"Choose Image",".","Images (*.bmp)");
69 | if(f.isNull())return;
70 | setBMP(f.toStdString());
71 | updateVal();
72 | emit sm.updateOutputs();
73 | update();
74 | }
75 |
--------------------------------------------------------------------------------
/plugins/image/BitmapNode.h:
--------------------------------------------------------------------------------
1 | #ifndef BITMAPNODE_H
2 | #define BITMAPNODE_H
3 |
4 | #include "Node.h"
5 |
6 | class BitmapNode : public Node{
7 | public:
8 | BitmapNode(const std::string &filename);
9 | ~BitmapNode();
10 | void setBMP(const std::string &filename);
11 | static Node* makeFromBin(std::istream &);
12 | static Node* makeFromText(std::istream &);
13 | private:
14 | std::string path;
15 | QPixmap *bmp;
16 | int bmpWidth, bmpHeight;
17 | data_t kernel()const;
18 | void paint(QPainter *painter,
19 | const QStyleOptionGraphicsItem* option,
20 | QWidget* widget);
21 | void contextMenuEvent(QGraphicsSceneContextMenuEvent* event);
22 | void mouseDoubleClickEvent(QGraphicsSceneMouseEvent*);
23 | QImage scaleImage(uint w, uint h)const;
24 | void toBin(std::ostream &)const override;
25 | void toText(std::ostream &)const override;
26 | private slots:
27 | void changeBMP();
28 | };
29 |
30 | #endif // BITMAPNODE_H
31 |
--------------------------------------------------------------------------------
/plugins/image/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | cmake_minimum_required(VERSION 3.0.0)
2 | project(ImagePlugin)
3 |
4 | find_package(Qt5Widgets REQUIRED)
5 |
6 | set(CMAKE_AUTOMOC ON)
7 | set(CMAKE_AUTORCC ON)
8 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC")
9 | qt5_add_resources(QRC image.qrc)
10 | add_custom_target(image_qrc DEPENDS ${QRC})
11 |
12 | set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PLUGIN_OUTPUT_PATH})
13 |
14 | include_directories(${MAIN_SRC_DIR} ${BIN_SRC_DIR} ${Qt5Widgets_INCLUDE_DIRS})
15 |
16 | add_library(${PROJECT_NAME} SHARED ImagePlugin.cpp ImagePlugin.h)
17 | add_library(image
18 | fromToStream.cpp
19 | BitmapNode.cpp
20 | BitmapNode.h)
21 |
22 | target_link_libraries(${PROJECT_NAME} image data_t ${QRC})
23 | add_dependencies(${PROJECT_NAME} image_qrc)
24 |
--------------------------------------------------------------------------------
/plugins/image/ImagePlugin.cpp:
--------------------------------------------------------------------------------
1 | #include "ImagePlugin.h"
2 | #include "BitmapNode.h"
3 |
4 | void ImagePlugin::updateUI(Ui::MainWindow* ui) const{
5 | QAction* imageAction= new QAction(QIcon(":/image.png"),"Image");
6 |
7 | Workspace* ws= (Workspace*)ui->workspace->scene();
8 | connect(imageAction,&QAction::triggered,ws,[=]{ws->addNode(Node::nodeMalloc("img"));});
9 |
10 | ui->menuInsert->addAction(imageAction);
11 |
12 | }
13 |
14 | void ImagePlugin::init()const{
15 | Node::makeNodeBinTextMethods["img"] = {&BitmapNode::makeFromBin,&BitmapNode::makeFromText};
16 | NodeBox::addTool("img","Image",QIcon(":/image.png"));
17 | }
18 |
--------------------------------------------------------------------------------
/plugins/image/ImagePlugin.h:
--------------------------------------------------------------------------------
1 | #ifndef IMAGEPLUGIN_H
2 | #define IMAGEPLUGIN_H
3 |
4 | #include
5 | #include
6 |
7 | #include "EmergenceInterface.h"
8 |
9 | class ImagePlugin: public QObject, EmergenceInterface{
10 | Q_OBJECT
11 | Q_PLUGIN_METADATA(IID "Emergence.Plugin")
12 | Q_INTERFACES(EmergenceInterface)
13 | public:
14 | void updateUI(Ui::MainWindow*)const override;
15 | void init()const;
16 | };
17 |
18 | #endif
19 |
--------------------------------------------------------------------------------
/plugins/image/fromToStream.cpp:
--------------------------------------------------------------------------------
1 | #include "BitmapNode.h"
2 | #include
3 |
4 | static Node* askForBMP(){
5 | QString filename = QFileDialog::getOpenFileName(0,"Choose Image",".","Images (*.bmp)");
6 | if(filename.isNull()) return nullptr;
7 | return new BitmapNode(filename.toStdString());
8 | }
9 |
10 | Node* BitmapNode::makeFromBin(std::istream&in){
11 | if(in.peek()!=EOF){
12 | std::string path;
13 | in >> path;
14 | in.ignore(1);
15 | return new BitmapNode(path);
16 | }
17 | return askForBMP();
18 | }
19 | Node* BitmapNode::makeFromText(std::istream&in){
20 | if(in.peek()!=EOF){
21 | std::string path;
22 | in >> path;
23 | return new BitmapNode(path);
24 | }
25 | return askForBMP();
26 | }
27 |
28 | void BitmapNode::toBin(std::ostream &out) const{
29 | Node::toBin(out);
30 | out <<' '<< path << '\n';
31 | }
32 | void BitmapNode::toText(std::ostream &out) const{
33 | Node::toText(out);
34 | out <<' '<< path;
35 | }
36 |
--------------------------------------------------------------------------------
/plugins/image/image.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bsella/Emergence/fdb8f58545ed708bcd9ce670fe85d4a840ddb965/plugins/image/image.png
--------------------------------------------------------------------------------
/plugins/image/image.qrc:
--------------------------------------------------------------------------------
1 |
2 |
3 | image.png
4 |
5 |
6 |
--------------------------------------------------------------------------------
/plugins/io/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | cmake_minimum_required(VERSION 3.0.0)
2 | project(IOPlugin)
3 |
4 | find_package(Qt5Widgets REQUIRED)
5 |
6 | set(CMAKE_AUTOMOC ON)
7 | set(CMAKE_AUTORCC ON)
8 | set(CMAKE_AUTOUIC ON)
9 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC")
10 | qt5_add_resources(QRC io.qrc)
11 | add_custom_target(io_qrc DEPENDS ${QRC})
12 |
13 | qt5_wrap_ui(UI_HEADERS exportimagedialog.ui)
14 |
15 | set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PLUGIN_OUTPUT_PATH})
16 |
17 | include_directories(${MAIN_SRC_DIR} ${BIN_SRC_DIR} ${CMAKE_CURRENT_BINARY_DIR} ${Qt5Widgets_INCLUDE_DIRS})
18 |
19 | add_library(${PROJECT_NAME} SHARED IoPlugin.cpp IoPlugin.h)
20 | add_library(io
21 | InputNode.cpp
22 | OutputNode.cpp
23 | ExportImageDialog.cpp
24 | InputNode.h
25 | OutputNode.h
26 | ExportImageDialog.h
27 | ${UI_HEADERS})
28 |
29 | target_link_libraries(${PROJECT_NAME} io data_t ${QRC})
30 | add_dependencies(${PROJECT_NAME} io_qrc)
31 |
--------------------------------------------------------------------------------
/plugins/io/ExportImageDialog.cpp:
--------------------------------------------------------------------------------
1 | #include "ExportImageDialog.h"
2 | #include "ui_exportimagedialog.h"
3 |
4 | #include
5 |
6 | ExportImageDialog::ExportImageDialog(QWidget *parent) :
7 | QDialog(parent),
8 | ui(new Ui::ExportImageDialog){
9 | ui->setupUi(this);
10 | }
11 |
12 | ExportImageDialog::~ExportImageDialog(){
13 | delete ui;
14 | }
15 |
16 | void ExportImageDialog::exportBMP(OutputNode *node){
17 | QString f= QFileDialog::getSaveFileName(0,"Export Image",".","Images (*.bmp)");
18 | if(f.isNull()) return;
19 | if(!f.endsWith(".bmp"))
20 | f.append(".bmp");
21 | ExportImageDialog dial;
22 | if(!dial.exec()) return;
23 | int w = dial.ui->widthBox->value();
24 | int h = dial.ui->heightBox->value();
25 | QPixmap::fromImage(node->output->renderImage(w,h)).save(f);
26 | }
27 |
--------------------------------------------------------------------------------
/plugins/io/ExportImageDialog.h:
--------------------------------------------------------------------------------
1 | #ifndef EXPORTIMAGEDIALOG_H
2 | #define EXPORTIMAGEDIALOG_H
3 |
4 | #include
5 | #include "OutputNode.h"
6 |
7 | namespace Ui {
8 | class ExportImageDialog;
9 | }
10 |
11 | class ExportImageDialog : public QDialog{
12 | Q_OBJECT
13 |
14 | public:
15 | explicit ExportImageDialog(QWidget *parent = 0);
16 | ~ExportImageDialog();
17 | static void exportBMP(OutputNode *node);
18 |
19 | private:
20 | Ui::ExportImageDialog *ui;
21 | };
22 |
23 | #endif // EXPORTIMAGEDIALOG_H
24 |
--------------------------------------------------------------------------------
/plugins/io/InputNode.cpp:
--------------------------------------------------------------------------------
1 | #include "InputNode.h"
2 |
3 | #include
4 |
5 | double InputNode::input_x;
6 | double InputNode::input_y;
7 | double RatioNode::ratio;
8 | InputNode::InputNode(const std::string& type):Node(type,70,50,Qt::lightGray){}
9 | XNode::XNode():InputNode("x"){}
10 | YNode::YNode():InputNode("y"){}
11 | RatioNode::RatioNode():Node("ratio",70,50,Qt::lightGray){
12 | constant=true;
13 | connect(&sm,SIGNAL(updateRatio()),this,SLOT(updateVal()));
14 | }
15 | RatioNode::~RatioNode(){
16 | disconnect(&sm,SIGNAL(updateRatio()),this,SLOT(updateVal()));
17 | }
18 |
19 | void InputNode::paint(QPainter *painter, const QStyleOptionGraphicsItem*option, QWidget*widget){
20 | Node::paint(painter,option,widget);
21 | }
22 |
23 | void XNode::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget){
24 | InputNode::paint(painter,option,widget);
25 | QRectF rect=boundingRect();
26 | painter->drawText(rect.center()+QPointF(-5,3),"X");
27 | }
28 | void YNode::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget){
29 | InputNode::paint(painter,option,widget);
30 | QRectF rect=boundingRect();
31 | painter->drawText(rect.center()+QPoint(-5,3),"Y");
32 | }
33 |
34 | void RatioNode::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget){
35 | Node::paint(painter,option,widget);
36 | QRectF rect=boundingRect();
37 | painter->drawText(rect.x()+rect.width()/3,rect.y()+rect.height()/2+3,"W/H");
38 | }
39 |
40 |
--------------------------------------------------------------------------------
/plugins/io/InputNode.h:
--------------------------------------------------------------------------------
1 | #ifndef INPUTNODE_H
2 | #define INPUTNODE_H
3 |
4 | #include "Node.h"
5 |
6 | class InputNode:public Node{
7 | protected:
8 | InputNode(const std::string &);
9 | virtual void paint(QPainter* painter, const QStyleOptionGraphicsItem*, QWidget*);
10 | static double input_x, input_y;
11 | friend class OutputNode;
12 | };
13 |
14 | class XNode:public InputNode{
15 | public:
16 | XNode();
17 | inline static Node* makeNode(std::istream&){return new XNode;}
18 | private:
19 | void paint(QPainter* painter,
20 | const QStyleOptionGraphicsItem* option,
21 | QWidget* widget);
22 | inline data_t kernel()const{return input_x;}
23 | };
24 |
25 | class YNode:public InputNode{
26 | public:
27 | YNode();
28 | inline static Node* makeNode(std::istream&){return new YNode;}
29 | private:
30 | void paint(QPainter* painter,
31 | const QStyleOptionGraphicsItem* option,
32 | QWidget* widget);
33 | inline data_t kernel()const{return input_y;}
34 | };
35 |
36 | class RatioNode:public Node{
37 | void paint(QPainter* painter,
38 | const QStyleOptionGraphicsItem* option,
39 | QWidget* widget);
40 | static double ratio;
41 | inline data_t kernel()const{return ratio;}
42 | friend class OutputNode;
43 | public:
44 | RatioNode();
45 | ~RatioNode();
46 | inline static Node* makeNode(std::istream&){return new RatioNode;}
47 | };
48 |
49 | #endif
50 |
--------------------------------------------------------------------------------
/plugins/io/IoPlugin.cpp:
--------------------------------------------------------------------------------
1 | #include "IoPlugin.h"
2 | #include "Node.h"
3 | #include "InputNode.h"
4 | #include "OutputNode.h"
5 | #include "ExportImageDialog.h"
6 |
7 | void IoPlugin::updateUI(Ui::MainWindow* ui) const{
8 | QMenu* ioMenu = new QMenu("Input/Output",ui->menuInsert);
9 | ui->menuInsert->addAction(ioMenu->menuAction());
10 | QAction* xAction= new QAction(QIcon(":/x.png"),"X");
11 | QAction* yAction= new QAction(QIcon(":/y.png"),"Y");
12 | QAction* ratioAction= new QAction("Ratio");
13 | QAction* outAction= new QAction(QIcon(":/output.png"),"Output");
14 |
15 | Workspace* ws=(Workspace*)ui->workspace->scene();
16 | connect(xAction,&QAction::triggered,ws,[=]{ws->addNode(Node::nodeMalloc("x"));});
17 | connect(yAction,&QAction::triggered,ws,[=]{ws->addNode(Node::nodeMalloc("y"));});
18 | connect(ratioAction,&QAction::triggered,ws,[=]{ws->addNode(Node::nodeMalloc("ratio"));});
19 | connect(outAction,&QAction::triggered,ws,[=]{ws->addNode(Node::nodeMalloc("out"));});
20 |
21 | ioMenu->addAction(xAction);
22 | ioMenu->addAction(yAction);
23 | ioMenu->addAction(ratioAction);
24 | ioMenu->addAction(outAction);
25 |
26 | QAction* exportAction= new QAction("Export");
27 | exportAction->setShortcut(QKeySequence("Ctrl+E"));
28 | connect(exportAction,&QAction::triggered,ws,[=]{
29 | for(const auto& node: ws->selectedItems()){
30 | OutputNode* out = (OutputNode*)node;
31 | if(out->_type=="out" && *out)
32 | ExportImageDialog::exportBMP(out);
33 | }
34 | });
35 | ui->menuFile->insertAction(ui->actionOpen,exportAction);
36 | }
37 |
38 | void IoPlugin::init()const{
39 | Node::makeNodeBinTextMethods["x"] = {&XNode::makeNode,&XNode::makeNode};
40 | Node::makeNodeBinTextMethods["y"] = {&YNode::makeNode,&YNode::makeNode};
41 | Node::makeNodeBinTextMethods["ratio"]= {&RatioNode::makeNode,&RatioNode::makeNode};
42 | Node::makeNodeBinTextMethods["out"]= {&OutputNode::makeNode,&OutputNode::makeNode};
43 |
44 | NodeBox::addTool("x","X",QIcon(":/x.png"));
45 | NodeBox::addTool("y","Y",QIcon(":/y.png"));
46 | NodeBox::addTool("ratio","Width/Height");
47 | NodeBox::addTool("out","Output",QIcon(":/output.png"));
48 | }
49 |
--------------------------------------------------------------------------------
/plugins/io/IoPlugin.h:
--------------------------------------------------------------------------------
1 | #ifndef IOPLUGIN_H
2 | #define IOPLUGIN_H
3 |
4 | #include
5 | #include
6 |
7 | #include "EmergenceInterface.h"
8 |
9 | class IoPlugin: public QObject, EmergenceInterface{
10 | Q_OBJECT
11 | Q_PLUGIN_METADATA(IID "Emergence.Plugin")
12 | Q_INTERFACES(EmergenceInterface)
13 | public:
14 | void updateUI(Ui::MainWindow*)const override;
15 | void init()const override;
16 | };
17 |
18 | #endif
19 |
--------------------------------------------------------------------------------
/plugins/io/OutputNode.cpp:
--------------------------------------------------------------------------------
1 | #include "OutputNode.h"
2 |
3 | #include
4 | #include "InputNode.h"
5 |
6 | OutputNode::RenderArea::RenderArea(OutputNode *node, QWidget *parent):QDockWidget(parent){
7 | start=node;
8 | setFeatures(0);
9 | setWindowTitle("Output "+QString::number(start->outputNumber));
10 | }
11 |
12 | QImage OutputNode::RenderArea::renderImage(int w, int h){
13 | QImage image(w,h ,QImage::Format_ARGB32_Premultiplied);
14 | RatioNode::ratio=double(w)/h;
15 | Node::widthByHeight=w*h;
16 | emit sm.updateRatio();
17 | for(int i=0;ieval());
23 | }
24 | return image;
25 | }
26 |
27 | void OutputNode::RenderArea::paintEvent(QPaintEvent *){
28 | if(*start)
29 | QPainter(this).drawImage(0,0,renderImage(width(),height()));
30 | }
31 |
32 | uint OutputNode::outputs=0;
33 |
34 | void OutputNode::RenderArea::closeEvent(QCloseEvent*){
35 | start->inside=true;
36 | start->update();
37 | }
38 | void OutputNode::RenderArea::resizeEvent(QResizeEvent *){
39 | RatioNode::ratio=double(width())/height();
40 | Node::widthByHeight=width()*height();
41 | emit sm.updateRatio();
42 | }
43 |
44 | OutputNode::OutputNode():Node("out",50, 50, Qt::white,1,true){
45 | outputNumber=outputs++;
46 | output= new RenderArea(this);
47 | connect(&sm,&SignalManager::updateOutputs,this,&OutputNode::updateOutput);
48 | }
49 |
50 | OutputNode::~OutputNode(){
51 | disconnect(&sm,&SignalManager::updateOutputs,this,&OutputNode::updateOutput);
52 | delete output;
53 | outputs--;
54 | }
55 |
56 | data_t OutputNode::kernel()const{
57 | return iNodes[0]->eval();
58 | }
59 |
60 | void OutputNode::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget){
61 | pen.setColor(isSelected()?Qt::darkGreen:Qt::black);
62 | if(inside){
63 | pen.setWidth(isSelected()?2:1);
64 | painter->setPen(pen);
65 | painter->drawLine(QPointF(0,height/2.0),QPointF(socketSize,height/2.0));
66 | painter->drawRect(QRectF(socketSize,0,width,height));
67 | if(*this)
68 | painter->drawImage(socketSize+1,1,output->renderImage(width-1,height-1));
69 | }else{
70 | Node::paint(painter, option, widget);
71 | painter->setFont(QFont("",8));
72 | painter->drawText(boundingRect().center()-QPoint(18,-2),"Output "+QString::number(outputNumber));
73 | }
74 | }
75 |
76 | void OutputNode::updateOutput(){
77 | update();
78 | output->update();
79 | }
80 |
81 | void OutputNode::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *){
82 | if(inside)
83 | output->show();
84 | else
85 | output->close();
86 | inside=!inside;
87 | update();
88 | }
89 |
--------------------------------------------------------------------------------
/plugins/io/OutputNode.h:
--------------------------------------------------------------------------------
1 | #ifndef OutputNODE_H
2 | #define OutputNODE_H
3 |
4 | #include "Node.h"
5 | #include
6 |
7 | class OutputNode : public Node{
8 | public:
9 | OutputNode();
10 | ~OutputNode();
11 | class RenderArea : public QDockWidget{
12 | public:
13 | RenderArea(OutputNode* node,QWidget* parent=0);
14 | QImage renderImage(int w,int h);
15 | private:
16 | OutputNode *start;
17 | void closeEvent(QCloseEvent *);
18 | void resizeEvent(QResizeEvent*);
19 | void paintEvent(QPaintEvent*);
20 | };
21 | inline static Node* makeNode(std::istream&){return new OutputNode;}
22 | private slots:
23 | void updateOutput();
24 | private:
25 | RenderArea *output;
26 | bool inside=true;
27 | uint outputNumber;
28 | static uint outputs;
29 | data_t kernel()const;
30 | void paint(QPainter* painter,
31 | const QStyleOptionGraphicsItem* option,
32 | QWidget* widget);
33 | void mouseDoubleClickEvent(QGraphicsSceneMouseEvent*);
34 | friend class ExportImageDialog;
35 | };
36 | #endif // RENDERNODE_H
37 |
--------------------------------------------------------------------------------
/plugins/io/exportimagedialog.ui:
--------------------------------------------------------------------------------
1 |
2 |
3 | ExportImageDialog
4 |
5 |
6 |
7 | 0
8 | 0
9 | 401
10 | 134
11 |
12 |
13 |
14 | Choose dimension
15 |
16 |
17 | -
18 |
19 |
20 | 1
21 |
22 |
23 | 1000000
24 |
25 |
26 |
27 | -
28 |
29 |
30 | Qt::Horizontal
31 |
32 |
33 | QDialogButtonBox::Cancel|QDialogButtonBox::Ok
34 |
35 |
36 |
37 | -
38 |
39 |
40 | 1
41 |
42 |
43 | 1000000
44 |
45 |
46 |
47 | -
48 |
49 |
50 | Width :
51 |
52 |
53 |
54 | -
55 |
56 |
57 | Height :
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 | buttonBox
67 | accepted()
68 | ExportImageDialog
69 | accept()
70 |
71 |
72 | 248
73 | 254
74 |
75 |
76 | 157
77 | 274
78 |
79 |
80 |
81 |
82 | buttonBox
83 | rejected()
84 | ExportImageDialog
85 | reject()
86 |
87 |
88 | 316
89 | 260
90 |
91 |
92 | 286
93 | 274
94 |
95 |
96 |
97 |
98 |
99 |
--------------------------------------------------------------------------------
/plugins/io/io.qrc:
--------------------------------------------------------------------------------
1 |
2 |
3 | output.png
4 | x.png
5 | y.png
6 |
7 |
8 |
--------------------------------------------------------------------------------
/plugins/io/output.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bsella/Emergence/fdb8f58545ed708bcd9ce670fe85d4a840ddb965/plugins/io/output.png
--------------------------------------------------------------------------------
/plugins/io/x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bsella/Emergence/fdb8f58545ed708bcd9ce670fe85d4a840ddb965/plugins/io/x.png
--------------------------------------------------------------------------------
/plugins/io/y.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bsella/Emergence/fdb8f58545ed708bcd9ce670fe85d4a840ddb965/plugins/io/y.png
--------------------------------------------------------------------------------
/plugins/logic/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | cmake_minimum_required(VERSION 3.0.0)
2 | project(LogicPlugin)
3 |
4 | find_package(Qt5Widgets REQUIRED)
5 |
6 | set(CMAKE_AUTOMOC ON)
7 | set(CMAKE_AUTORCC ON)
8 | SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC")
9 | qt5_add_resources(QRC logic.qrc)
10 | add_custom_target(logic_qrc DEPENDS ${QRC})
11 |
12 | set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PLUGIN_OUTPUT_PATH})
13 |
14 | include_directories(${MAIN_SRC_DIR} ${BIN_SRC_DIR} ${Qt5Widgets_INCLUDE_DIRS})
15 |
16 | add_library(${PROJECT_NAME} SHARED LogicPlugin.cpp LogicPlugin.h)
17 | add_library(logic LogicNode.cpp LogicNode.h)
18 |
19 | target_link_libraries(${PROJECT_NAME} logic data_t ${QRC})
20 | add_dependencies(${PROJECT_NAME} logic_qrc)
21 |
--------------------------------------------------------------------------------
/plugins/logic/LogicNode.cpp:
--------------------------------------------------------------------------------
1 | #include "LogicNode.h"
2 |
3 | #include
4 |
5 | LogicNode::LogicNode(const std::string &type, unsigned n):Node(type,50,50,QColor(255,180,180),n){}
6 |
7 | ORNode::ORNode():LogicNode("or",2){}
8 | ANDNode::ANDNode():LogicNode("and",2){}
9 | XORNode::XORNode():LogicNode("xor",2){}
10 | NOTNode::NOTNode():LogicNode("not",1){}
11 |
12 | void ORNode::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget){
13 | Node::paint(painter,option, widget);
14 | painter->drawText(boundingRect().center()-QPoint(10,-2),"OR");
15 | }
16 | void ANDNode::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget){
17 | Node::paint(painter,option, widget);
18 | painter->drawText(boundingRect().center()-QPoint(12,-2),"AND");
19 | }
20 | void XORNode::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget){
21 | Node::paint(painter,option, widget);
22 | painter->drawText(boundingRect().center()-QPoint(12,-2),"XOR");
23 | }
24 | void NOTNode::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget){
25 | Node::paint(painter,option, widget);
26 | painter->drawText(boundingRect().center()-QPoint(12,-2),"NOT");
27 | }
28 |
29 | data_t ORNode::kernel()const{
30 | return iNodes[0]->eval() || iNodes[1]->eval();
31 | }
32 | data_t ANDNode::kernel()const{
33 | return iNodes[0]->eval() && iNodes[1]->eval();
34 | }
35 | data_t XORNode::kernel()const{
36 | return bool(bool(iNodes[0]->eval()) ^ bool(iNodes[1]->eval()));
37 | }
38 | data_t NOTNode::kernel()const{
39 | return !iNodes[0]->eval();
40 | }
41 |
--------------------------------------------------------------------------------
/plugins/logic/LogicNode.h:
--------------------------------------------------------------------------------
1 | #ifndef LOGICNODE_H
2 | #define LOGICNODE_H
3 |
4 | #include "Node.h"
5 |
6 | class LogicNode:public Node{
7 | protected:
8 | LogicNode(const std::string &type, unsigned n);
9 | virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)=0;
10 | };
11 |
12 | class ORNode:public LogicNode{
13 | public:
14 | ORNode();
15 | inline static Node* makeNode(std::istream&){return new ORNode;}
16 | private:
17 | data_t kernel()const;
18 | void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
19 | };
20 |
21 | class ANDNode:public LogicNode{
22 | public:
23 | ANDNode();
24 | inline static Node* makeNode(std::istream&){return new ANDNode;}
25 | private:
26 | data_t kernel()const;
27 | void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
28 | };
29 |
30 | class XORNode:public LogicNode{
31 | public:
32 | XORNode();
33 | inline static Node* makeNode(std::istream&){return new XORNode;}
34 | private:
35 | data_t kernel()const;
36 | void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
37 | };
38 |
39 | class NOTNode:public LogicNode{
40 | public:
41 | NOTNode();
42 | inline static Node* makeNode(std::istream&){return new NOTNode;}
43 | private:
44 | data_t kernel()const;
45 | void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
46 | };
47 | #endif
48 |
--------------------------------------------------------------------------------
/plugins/logic/LogicPlugin.cpp:
--------------------------------------------------------------------------------
1 | #include "LogicPlugin.h"
2 | #include "LogicNode.h"
3 |
4 | void LogicPlugin::updateUI(Ui::MainWindow* ui) const{
5 | QMenu* logicMenu = new QMenu("Logic",ui->menuInsert);
6 | ui->menuInsert->addAction(logicMenu->menuAction());
7 | QAction* andAction= new QAction(QIcon(":/and.png"), "And");
8 | QAction* orAction= new QAction(QIcon(":/or.png"), "Or");
9 | QAction* xorAction= new QAction(QIcon(":/xor.png"), "Xor");
10 | QAction* notAction= new QAction(QIcon(":/not.png"), "Not");
11 |
12 | Workspace* ws=(Workspace*)ui->workspace->scene();
13 | connect(andAction,&QAction::triggered,ws,[=]{ws->addNode(Node::nodeMalloc("and"));});
14 | connect(orAction,&QAction::triggered,ws,[=]{ws->addNode(Node::nodeMalloc("or"));});
15 | connect(xorAction,&QAction::triggered,ws,[=]{ws->addNode(Node::nodeMalloc("xor"));});
16 | connect(notAction,&QAction::triggered,ws,[=]{ws->addNode(Node::nodeMalloc("not"));});
17 |
18 | logicMenu->addAction(andAction);
19 | logicMenu->addAction(orAction);
20 | logicMenu->addAction(xorAction);
21 | logicMenu->addAction(notAction);
22 |
23 | }
24 |
25 | void LogicPlugin::init()const{
26 | Node::makeNodeBinTextMethods["and"] = {&ANDNode::makeNode,&ANDNode::makeNode};
27 | Node::makeNodeBinTextMethods["or"] = {&ORNode::makeNode ,&ORNode::makeNode };
28 | Node::makeNodeBinTextMethods["xor"] = {&XORNode::makeNode,&XORNode::makeNode};
29 | Node::makeNodeBinTextMethods["not"] = {&NOTNode::makeNode,&NOTNode::makeNode};
30 |
31 | NodeBox::addTool("and","And",QIcon(":/and.png"),"Logic");
32 | NodeBox::addTool("or","Or",QIcon(":/or.png"),"Logic");
33 | NodeBox::addTool("xor","Xor",QIcon(":/xor.png"),"Logic");
34 | NodeBox::addTool("not","Not",QIcon(":/not.png"),"Logic");
35 | }
36 |
--------------------------------------------------------------------------------
/plugins/logic/LogicPlugin.h:
--------------------------------------------------------------------------------
1 | #ifndef LOGICPLUGIN_H
2 | #define LOGICPLUGIN_H
3 |
4 | #include
5 | #include
6 |
7 | #include "EmergenceInterface.h"
8 |
9 | class LogicPlugin: public QObject, EmergenceInterface{
10 | Q_OBJECT
11 | Q_PLUGIN_METADATA(IID "Emergence.Plugin")
12 | Q_INTERFACES(EmergenceInterface)
13 | public:
14 | void updateUI(Ui::MainWindow*)const override;
15 | void init()const;
16 | };
17 |
18 | #endif
19 |
--------------------------------------------------------------------------------
/plugins/logic/and.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bsella/Emergence/fdb8f58545ed708bcd9ce670fe85d4a840ddb965/plugins/logic/and.png
--------------------------------------------------------------------------------
/plugins/logic/logic.qrc:
--------------------------------------------------------------------------------
1 |
2 |
3 | and.png
4 | not.png
5 | or.png
6 | xor.png
7 |
8 |
9 |
--------------------------------------------------------------------------------
/plugins/logic/not.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bsella/Emergence/fdb8f58545ed708bcd9ce670fe85d4a840ddb965/plugins/logic/not.png
--------------------------------------------------------------------------------
/plugins/logic/or.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bsella/Emergence/fdb8f58545ed708bcd9ce670fe85d4a840ddb965/plugins/logic/or.png
--------------------------------------------------------------------------------
/plugins/logic/xor.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bsella/Emergence/fdb8f58545ed708bcd9ce670fe85d4a840ddb965/plugins/logic/xor.png
--------------------------------------------------------------------------------
/plugins/lut/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | cmake_minimum_required(VERSION 3.0.0)
2 | project(LUTPlugin)
3 |
4 | find_package(Qt5Widgets REQUIRED)
5 |
6 | set(CMAKE_AUTOMOC ON)
7 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC")
8 |
9 | set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PLUGIN_OUTPUT_PATH})
10 |
11 | include_directories(${MAIN_SRC_DIR} ${BIN_SRC_DIR} ${CMAKE_CURRENT_BINARY_DIR} ${Qt5Widgets_INCLUDE_DIRS})
12 |
13 | add_library(dialog
14 | dialog/lut_dialog.cpp
15 | dialog/lut_dialog.h)
16 | add_library(${PROJECT_NAME} SHARED LUTPlugin.cpp LUTPlugin.h)
17 | add_library(lut fromToStream.cpp LUTNode.cpp Gradient.cpp LUTNode.h Gradient.h)
18 |
19 | target_link_libraries(${PROJECT_NAME} lut data_t dialog)
20 |
--------------------------------------------------------------------------------
/plugins/lut/Gradient.cpp:
--------------------------------------------------------------------------------
1 | #include "Gradient.h"
2 | #include
3 | /*Uint32 = [.ALPHA..][...RED..][.GREEN..][..BLUE..]*/
4 |
5 | void getRGB(unsigned color, uint8_t &r, uint8_t &g, uint8_t &b){
6 | b=color;
7 | color>>=8;
8 | g=color;
9 | color>>=8;
10 | r=color;
11 | }
12 |
13 | unsigned makeRGB(uint8_t r, uint8_t g, uint8_t b){
14 | unsigned c=0xff;
15 | c<<=8; c|=r;
16 | c<<=8; c|=g;
17 | c<<=8; c|=b;
18 | return c;
19 | }
20 |
21 | Gradient::Gradient(){}
22 | Gradient::Gradient(const Gradient &p){
23 | if(!p.empty()){
24 | first= new color(p.first);
25 | color* tmp= first;
26 | for(color*tmpOther=p.first->next;tmpOther;tmpOther=tmpOther->next){
27 | tmp->next= new color(tmpOther);
28 | tmp->next->prev=tmp;
29 | tmp->next->gr=this;
30 | tmp=tmp->next;
31 | }
32 | last=tmp;
33 | }
34 | }
35 |
36 | Gradient::color::color(Gradient*g,unsigned c, double a):gr(g),clr(c), alpha(a){}
37 | Gradient::color::color(color *c):clr(c->clr),alpha(c->alpha){}
38 | void Gradient::color::updateAlpha(double newAlpha){
39 | if(next && newAlpha>next->alpha){
40 | if(this==gr->first)
41 | gr->first=next;
42 | else prev->next=next;
43 | next->prev=prev;
44 |
45 | color* tmp= next->next;
46 | while(tmp&&newAlpha>tmp->alpha)
47 | tmp=tmp->next;
48 | if(tmp){
49 | prev=tmp->prev;
50 | tmp->prev=this;
51 | prev->next=this;
52 | next=tmp;
53 | }else{
54 | prev=gr->last;
55 | prev->next=this;
56 | gr->last=this;
57 | next=nullptr;
58 | }
59 | }else if(prev && newAlphaalpha){
60 | if(this==gr->last)
61 | gr->last=prev;
62 | else next->prev=prev;
63 | prev->next=next;
64 |
65 | color* tmp= prev->prev;
66 | while(tmp&&newAlphaalpha)
67 | tmp=tmp->prev;
68 | if(tmp){
69 | next=tmp->next;
70 | tmp->next=this;
71 | next->prev=this;
72 | prev=tmp;
73 | }else{
74 | next=gr->first;
75 | next->prev=this;
76 | gr->first=this;
77 | prev=nullptr;
78 | }
79 | }
80 | alpha=newAlpha;
81 | }
82 |
83 | bool Gradient::empty()const{
84 | return first==nullptr;
85 | }
86 |
87 | Gradient::color *Gradient::add(unsigned color, double alpha){
88 | if(alpha<0)alpha=0;
89 | if(alpha>1)alpha=1;
90 | Gradient::color* n= new Gradient::color(this,color, alpha);
91 | if(empty())
92 | first=last=n;
93 | else{
94 | if(first->alpha > alpha){
95 | n->next=first;
96 | first->prev=n;
97 | first=n;
98 | }
99 | else{
100 | for(auto it =first; it !=nullptr; it=it->next)
101 | if(it->alpha >= alpha){
102 | struct color* before= it->prev;
103 | it->prev=n;
104 | before->next=n;
105 | n->prev=before;
106 | n->next=it;
107 | return n;
108 | }
109 | last->next=n;
110 | n->prev=last;
111 | last=n;
112 | }
113 | }
114 | return n;
115 | }
116 |
117 | unsigned Gradient::average(color c1, color c2, double i){
118 | i=(i-c1.alpha)/(c2.alpha-c1.alpha);
119 | uint8_t r1,g1,b1, r2,g2,b2;
120 | getRGB(c1.clr, r1, g1, b1);
121 | getRGB(c2.clr, r2, g2, b2);
122 |
123 | return makeRGB(r2*i+(1.0-i)*r1
124 | ,g2*i+(1.0-i)*g1
125 | ,b2*i+(1.0-i)*b1);
126 | }
127 |
128 | unsigned Gradient::operator[](double alpha)const{
129 | if(empty()) return 0xff000000;
130 | if(alpha<0) return first->clr;
131 | if(alphaalpha) return first->clr;
132 | for(auto it= first->next; it!= nullptr; it=it->next){
133 | if(alphaalpha)
134 | return average(*it->prev, *it, alpha);
135 | }
136 | return last->clr;
137 | }
138 |
139 | void Gradient::remove(color *c){
140 | if(!c)return;
141 | if(c==first) first=c->next;
142 | else c->prev->next=c->next;
143 | if(c==last) last=c->prev;
144 | else c->next->prev=c->prev;
145 | delete c;
146 | }
147 | Gradient::~Gradient(){
148 | while (!empty()) remove(first);
149 | }
150 |
--------------------------------------------------------------------------------
/plugins/lut/Gradient.h:
--------------------------------------------------------------------------------
1 | #ifndef GRADIENT_H
2 | #define GRADIENT_H
3 |
4 | #include
5 |
6 | class Gradient{
7 | private:
8 | struct color{
9 | color(Gradient* p,unsigned c, double a);
10 | color(color*);
11 | Gradient* gr;
12 | struct color* next=nullptr;
13 | struct color* prev=nullptr;
14 | const unsigned clr;
15 | double alpha;
16 | void updateAlpha(double newAlpha);
17 | };
18 | void remove(color* c);
19 | static unsigned average(color c1, color c2, double i);
20 | struct color*first=nullptr;
21 | struct color*last=nullptr;
22 | friend class LutCursor;
23 | friend class LutView;
24 | friend std::ostream& operator<<(std::ostream&,const Gradient&);
25 | public:
26 | Gradient();
27 | Gradient(const Gradient&);
28 | ~Gradient();
29 | color* add(unsigned color, double alpha);
30 | unsigned operator[](double alpha)const;
31 | bool empty()const;
32 | void toBin(std::ostream&)const;
33 | void toText(std::ostream&)const;
34 | };
35 |
36 | #endif
37 |
--------------------------------------------------------------------------------
/plugins/lut/LUTNode.cpp:
--------------------------------------------------------------------------------
1 | #include "LUTNode.h"
2 |
3 | #include "dialog/lut_dialog.h"
4 | #include
5 |
6 | LUTNode::LUTNode(Gradient *g): Node("lut",140,70,Qt::white,1), gradient(*g){}
7 |
8 | data_t LUTNode::kernel()const{
9 | return gradient[iNodes[0]->eval()];
10 | }
11 |
12 | void LUTNode::paint(QPainter *painter, const QStyleOptionGraphicsItem* option, QWidget* widget){
13 | Node::paint(painter, option, widget);
14 | for(uint i=socketSize*2; isetPen(gradient[i/(double)width]);
16 | painter->drawLine(QPoint(i,10),QPoint(i,height-10));
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/plugins/lut/LUTNode.h:
--------------------------------------------------------------------------------
1 | #ifndef LUTNODE_H
2 | #define LUTNODE_H
3 |
4 | #include "Gradient.h"
5 | #include "Node.h"
6 |
7 | class LUTNode:public Node{
8 | public:
9 | explicit LUTNode(Gradient *p);
10 | static Node* makeFromBin(std::istream&);
11 | static Node* makeFromText(std::istream&);
12 | private:
13 | void paint(QPainter* painter, const QStyleOptionGraphicsItem*option, QWidget*widget);
14 | data_t kernel()const;
15 | Gradient gradient;
16 | void toBin(std::ostream &)const override;
17 | void toText(std::ostream &)const override;
18 | };
19 |
20 | #endif
21 |
--------------------------------------------------------------------------------
/plugins/lut/LUTPlugin.cpp:
--------------------------------------------------------------------------------
1 | #include "LUTPlugin.h"
2 | #include "LUTNode.h"
3 |
4 | void LUTPlugin::updateUI(Ui::MainWindow* ui) const{
5 | QAction* lutAction= new QAction("LUT");
6 |
7 | Workspace* ws=(Workspace*)ui->workspace->scene();
8 | connect(lutAction,&QAction::triggered,ws,[=]{ws->addNode(Node::nodeMalloc("lut"));});
9 |
10 | ui->menuInsert->addAction(lutAction);
11 | }
12 |
13 | void LUTPlugin::init()const{
14 | Node::makeNodeBinTextMethods["lut"] = {&LUTNode::makeFromBin,&LUTNode::makeFromText};
15 | NodeBox::addTool("lut","LUT","Color");
16 | }
17 |
--------------------------------------------------------------------------------
/plugins/lut/LUTPlugin.h:
--------------------------------------------------------------------------------
1 | #ifndef LUTPLUGIN_H
2 | #define LUTPLUGIN_H
3 |
4 | #include
5 | #include
6 |
7 | #include "EmergenceInterface.h"
8 |
9 | class LUTPlugin: public QObject, EmergenceInterface{
10 | Q_OBJECT
11 | Q_PLUGIN_METADATA(IID "Emergence.Plugin")
12 | Q_INTERFACES(EmergenceInterface)
13 | public:
14 | void updateUI(Ui::MainWindow*)const override;
15 | void init()const override;
16 | };
17 |
18 | #endif
19 |
--------------------------------------------------------------------------------
/plugins/lut/dialog/lut_dialog.cpp:
--------------------------------------------------------------------------------
1 | #include "lut_dialog.h"
2 |
3 | #include
4 | #include
5 | #include
6 | #include
7 | #include
8 | #include
9 |
10 | LutDialog::LutDialog(QWidget *parent) :
11 | QDialog(parent){
12 | QVBoxLayout* vbl= new QVBoxLayout;
13 | QColorDialog* colorDialog= new QColorDialog;
14 | colorDialog->setWindowFlag(Qt::Widget);
15 | colorDialog->setOptions(QColorDialog::DontUseNativeDialog|QColorDialog::NoButtons);
16 | QDialogButtonBox* buttons= new QDialogButtonBox(this);
17 | buttons->setStandardButtons(QDialogButtonBox::Cancel|QDialogButtonBox::Ok);
18 |
19 | buttons->setWindowFlag(Qt::Widget);
20 | vbl->setMargin(2);
21 | vbl->addWidget(colorDialog);
22 | view= new LutView(this);
23 | vbl->addWidget(view);
24 | vbl->addWidget(buttons);
25 | setLayout(vbl);
26 |
27 | connect(buttons,SIGNAL(accepted()),this,SLOT(accept()));
28 | connect(buttons,SIGNAL(rejected()),this,SLOT(reject()));
29 | connect(colorDialog,SIGNAL(accepted()),this,SLOT(accept()));
30 | connect(colorDialog,SIGNAL(rejected()),this,SLOT(reject()));
31 | setFixedSize(minimumSize());
32 | }
33 | Gradient* LutDialog::getGradient(){
34 | LutDialog dial;
35 | if(dial.exec())
36 | return new Gradient(dial.view->grd);
37 | return nullptr;
38 | }
39 |
40 | LutDialog::~LutDialog(){
41 | delete view;
42 | }
43 |
44 | LutCursor* LutView::curs;
45 | LutView::LutView(QWidget* parent):QGraphicsView(parent){
46 | setScene(_scene=new QGraphicsScene);
47 | setAcceptDrops(true);
48 | setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
49 | setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
50 | background= new LutBackground(&grd);
51 | _scene->addItem(background);
52 | }
53 | LutView::~LutView(){
54 | delete background;
55 | delete _scene;
56 | }
57 | void LutView::dragEnterEvent(QDragEnterEvent *event){
58 | _scene->setSceneRect(rect());
59 | LutCursor::setDim(width(),height());
60 | background->width=width();
61 | background->height=height();
62 | if(event->mimeData()->hasColor()){
63 | event->setAccepted(true);
64 | curs= new LutCursor(event->mimeData()->colorData().value());
65 | curs->c=grd.add(event->mimeData()->colorData().value().rgb(),event->posF().x()/width());
66 | curs->setPos(event->pos().x(),height()/2);
67 | _scene->addItem(curs);
68 | }
69 | background->update();
70 | }
71 | void LutView::dragMoveEvent(QDragMoveEvent *event){
72 | curs->setPos(event->pos().x(),height()/2);
73 | background->update();
74 | }
75 | void LutView::dragLeaveEvent(QDragLeaveEvent *){
76 | _scene->removeItem(curs);
77 | grd.remove(curs->c);
78 | delete curs;
79 | background->update();
80 | }
81 |
82 | int LutCursor::height;
83 | int LutCursor::width;
84 | LutCursor::LutCursor(const QColor& color):color(color){
85 | setFlag(ItemSendsGeometryChanges);
86 | }
87 | void LutCursor::setDim(int w, int h){
88 | width=w;
89 | height=h;
90 | }
91 | QRectF LutCursor::boundingRect()const{
92 | return QRect(-cursorRadius, -height/2, 2*cursorRadius, height);
93 | }
94 | void LutCursor::paint(QPainter *p, const QStyleOptionGraphicsItem *, QWidget *){
95 | p->drawLine(0,-height/2,0,height/2);
96 | p->setBrush(color);
97 | p->drawEllipse({0,0},cursorRadius,cursorRadius);
98 | }
99 |
100 | QVariant LutCursor::itemChange(GraphicsItemChange change, const QVariant &v){
101 | if(change==ItemPositionChange&&x()){
102 | QPointF p= v.toPointF();
103 | p.setY(height/2);
104 | c->updateAlpha(x()/width);
105 | return p;
106 | }
107 | return QGraphicsItem::itemChange(change, v);
108 | }
109 |
110 | void LutCursor::mouseReleaseEvent(QGraphicsSceneMouseEvent*){
111 | setCursor(Qt::ArrowCursor);
112 | if(scenePos().x()<0 || scenePos().x()>scene()->width()){
113 | scene()->removeItem(this);
114 | c->gr->remove(c);
115 | delete this;
116 | }
117 | }
118 | void LutCursor::mouseMoveEvent(QGraphicsSceneMouseEvent*event){
119 | setCursor(Qt::SizeHorCursor);
120 | setPos(event->scenePos());
121 | QGraphicsItem::mouseMoveEvent(event);
122 | }
123 |
124 | LutBackground::LutBackground(Gradient *g):grd(g){
125 | setZValue(INT_MIN);
126 | }
127 | void LutBackground::paint(QPainter *p, const QStyleOptionGraphicsItem *, QWidget *){
128 | if(!grd->empty())
129 | for(int x=0;xsetPen(QColor::fromRgb((*grd)[(double)x/width]));
131 | p->drawLine(x,0,x,height);
132 | }
133 | scene()->update();
134 | }
135 | QRectF LutBackground::boundingRect()const{
136 | return QRectF(0,0,width,height);
137 | }
138 |
--------------------------------------------------------------------------------
/plugins/lut/dialog/lut_dialog.h:
--------------------------------------------------------------------------------
1 | #ifndef LUT_DIALOG_H
2 | #define LUT_DIALOG_H
3 |
4 | #include
5 | #include
6 | #include
7 | #include "../Gradient.h"
8 |
9 | class LutBackground:public QGraphicsItem{
10 | public:
11 | LutBackground(Gradient*);
12 | int width,height;
13 | private:
14 | const Gradient*grd;
15 | void paint(QPainter*, const QStyleOptionGraphicsItem*, QWidget*);
16 | QRectF boundingRect()const;
17 | };
18 |
19 | class LutCursor:public QGraphicsItem{
20 | public:
21 | LutCursor(const QColor &color);
22 | static void setDim(int w, int h);
23 | private:
24 | static int height;
25 | static int width;
26 | const QColor color;
27 | Gradient::color* c;
28 | QRectF boundingRect()const;
29 | static const int cursorRadius=5;
30 | QVariant itemChange(GraphicsItemChange, const QVariant &);
31 | void paint(QPainter*,const QStyleOptionGraphicsItem*,QWidget*);
32 | void mousePressEvent(QGraphicsSceneMouseEvent*){}
33 | void mouseReleaseEvent(QGraphicsSceneMouseEvent*);
34 | void mouseMoveEvent(QGraphicsSceneMouseEvent *);
35 | friend class LutView;
36 | };
37 |
38 | class LutView:public QGraphicsView{
39 | public:
40 | LutView(QWidget* parent=0);
41 | ~LutView();
42 | private:
43 | QGraphicsScene* _scene;
44 | static LutCursor* curs;
45 | Gradient grd;
46 | LutBackground* background;
47 | void dragEnterEvent(QDragEnterEvent*);
48 | void dragLeaveEvent(QDragLeaveEvent*);
49 | void dragMoveEvent(QDragMoveEvent*);
50 | friend class LutDialog;
51 | };
52 |
53 | class LutDialog : public QDialog{
54 | Q_OBJECT
55 | public:
56 | explicit LutDialog(QWidget *parent = 0);
57 | static Gradient *getGradient();
58 | private:
59 | LutView* view;
60 | ~LutDialog();
61 | };
62 |
63 | #endif // LUT_DIALOG_H
64 |
--------------------------------------------------------------------------------
/plugins/lut/fromToStream.cpp:
--------------------------------------------------------------------------------
1 | #include "LUTNode.h"
2 | #include "dialog/lut_dialog.h"
3 |
4 | void Gradient::toBin(std::ostream& out)const{
5 | uint n=0;
6 | for(auto it=first; it;it=it->next)
7 | n++;
8 | out.write(reinterpret_cast(&n),sizeof(uint));
9 | for(auto it= first; it; it=it->next){
10 | out.write(reinterpret_cast(&it->clr),sizeof(uint));
11 | out.write(reinterpret_cast(&it->alpha),sizeof(double));
12 | }
13 | }
14 | void Gradient::toText(std::ostream& out)const{
15 | uint n=0;
16 | for(auto it=first; it;it=it->next)
17 | n++;
18 | out << n <<' ';
19 | for(auto it= first; it; it=it->next){
20 | out << it->clr <<' '<< it->alpha;
21 | if(it->next) out<<' ';
22 | }
23 | }
24 |
25 | Node* LUTNode::makeFromBin(std::istream&in){
26 | Gradient *g;
27 | if(in.peek()!=EOF){
28 | g= new Gradient;
29 | uint n;
30 | in.read(reinterpret_cast(&n),sizeof(uint));
31 | double alpha;
32 | data_t::color color;
33 | for(uint i=0;i(&color),sizeof(data_t::color));
35 | in.read(reinterpret_cast(&alpha),sizeof(double));
36 | g->add(color,alpha);
37 | }
38 | }
39 | else g= LutDialog::getGradient();
40 | if(g)return new LUTNode(g);
41 | return nullptr;
42 | }
43 | Node* LUTNode::makeFromText(std::istream&in){
44 | Gradient *g;
45 | if(in.peek()!=EOF){
46 | g= new Gradient;
47 | uint n;
48 | in>>n;
49 | double alpha;
50 | data_t::color color;
51 | for(uint i=0;i> color;
53 | in >> alpha;
54 | g->add(color,alpha);
55 | }
56 | }
57 | else g= LutDialog::getGradient();
58 | if(g)return new LUTNode(g);
59 | return nullptr;
60 | }
61 |
62 | void LUTNode::toBin(std::ostream &out)const{
63 | Node::toBin(out);
64 | gradient.toBin(out);
65 | }
66 | void LUTNode::toText(std::ostream &out)const{
67 | Node::toText(out);
68 | out<< ' ';
69 | gradient.toText(out);
70 | }
71 |
--------------------------------------------------------------------------------
/plugins/math/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | cmake_minimum_required(VERSION 3.0.0)
2 | project(MathPlugin)
3 |
4 | find_package(Qt5Widgets REQUIRED)
5 |
6 | set(CMAKE_AUTOMOC ON)
7 | set(CMAKE_AUTORCC ON)
8 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC")
9 | qt5_add_resources(QRC math.qrc)
10 | add_custom_target(math_qrc DEPENDS ${QRC})
11 |
12 | set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PLUGIN_OUTPUT_PATH})
13 |
14 | include_directories(${MAIN_SRC_DIR} ${BIN_SRC_DIR} ${Qt5Widgets_INCLUDE_DIRS})
15 |
16 | add_library(${PROJECT_NAME} SHARED MathPlugin.cpp MathPlugin.h)
17 | add_library(math
18 | MathNode.cpp
19 | RealNode.cpp
20 | ComplexNode.cpp
21 | MathNode.h
22 | RealNode.h
23 | fromToStream.cpp
24 | ComplexNode.h)
25 |
26 | target_link_libraries(${PROJECT_NAME} math data_t ${QRC})
27 | add_dependencies(${PROJECT_NAME} math_qrc)
28 |
--------------------------------------------------------------------------------
/plugins/math/ComplexNode.cpp:
--------------------------------------------------------------------------------
1 | #include "ComplexNode.h"
2 |
3 | ComplexNode::ComplexNode():Node("cplx",50,50,Qt::white,2){}
4 |
5 | void ComplexNode::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget){
6 | Node::paint(painter,option,widget);
7 | drawIcon(painter,":/complex.png");
8 | }
9 |
10 | data_t ComplexNode::kernel()const{
11 | return cplx(iNodes[0]->eval(),iNodes[1]->eval());
12 | }
13 |
--------------------------------------------------------------------------------
/plugins/math/ComplexNode.h:
--------------------------------------------------------------------------------
1 | #ifndef COMPLEXNODE_H
2 | #define COMPLEXNODE_H
3 |
4 | #include "Node.h"
5 |
6 | class ComplexNode : public Node{
7 | public:
8 | ComplexNode();
9 | inline static Node* makeNode(std::istream&){return new ComplexNode;}
10 | private:
11 | data_t kernel()const;
12 | void paint(QPainter* painter, const QStyleOptionGraphicsItem*, QWidget*);
13 | };
14 |
15 | #endif // COMPLEXNODE_H
16 |
--------------------------------------------------------------------------------
/plugins/math/MathNode.cpp:
--------------------------------------------------------------------------------
1 | #include "MathNode.h"
2 |
3 | #include
4 | #include
5 |
6 | MathNode::MathNode(const std::string &type, unsigned n, unsigned w, unsigned h):Node(type,w,h,QColor(180,255,180),n){}
7 |
8 | ADDNode::ADDNode():MathNode("add",2){}
9 | SUBNode::SUBNode():MathNode("sub",2){}
10 | MULNode::MULNode():MathNode("mul",2){}
11 | DIVNode::DIVNode():MathNode("div",2){}
12 | NEGNode::NEGNode():MathNode("neg",1){}
13 | SQRTNode::SQRTNode():MathNode("sqrt",1){}
14 | ABSNode::ABSNode():MathNode("abs",1){}
15 | LERPNode::LERPNode():MathNode("lerp",3,50,100){}
16 | CLAMPNode::CLAMPNode():MathNode("clamp",3,50,100){}
17 | SINNode::SINNode():MathNode("sin",1){}
18 | COSNode::COSNode():MathNode("cos",1){}
19 | MINNode::MINNode():MathNode("min",2){}
20 | MAXNode::MAXNode():MathNode("max",2){}
21 | POWNode::POWNode():MathNode("pow",2){}
22 | LOGNode::LOGNode():MathNode("log",1){}
23 |
24 | void ADDNode::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget){
25 | Node::paint(painter,option,widget);
26 | drawIcon(painter,":/add.png");
27 | }
28 |
29 | void SUBNode::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget){
30 | Node::paint(painter,option,widget);
31 | drawIcon(painter,":/subtract.png");
32 | }
33 |
34 | void MULNode::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget){
35 | Node::paint(painter,option,widget);
36 | drawIcon(painter,":/multiply.png");
37 | }
38 |
39 | void DIVNode::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget){
40 | Node::paint(painter,option,widget);
41 | drawIcon(painter,":/divide.png");
42 | }
43 |
44 | void NEGNode::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget){
45 | Node::paint(painter,option,widget);
46 | drawIcon(painter,":/neg.png");
47 | }
48 |
49 | void SQRTNode::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget){
50 | Node::paint(painter,option,widget);
51 | QImage icon=QImage(":/sqrt.png");
52 | painter->drawImage(width/2-icon.width()/2+5,height/2-icon.height()/2,icon);
53 | }
54 | void ABSNode::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget){
55 | Node::paint(painter,option,widget);
56 | painter->drawText(boundingRect().center()-QPointF(12,0),"abs");
57 | }
58 | void LERPNode::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget){
59 | Node::paint(painter,option,widget);
60 | QRectF rect=boundingRect();
61 | painter->drawText(rect.topLeft()+QPointF(8,rect.height()/4.0+4),"1");
62 | painter->drawText(rect.topLeft()+QPointF(width/2,2*rect.height()/4.0+4),"lerp");
63 | painter->drawText(rect.topLeft()+QPointF(8,3*rect.height()/4.0+4),"0");
64 | }
65 | void CLAMPNode::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget){
66 | Node::paint(painter,option,widget);
67 | QRectF rect=boundingRect();
68 | painter->drawText(rect.topLeft()+QPointF(8,rect.height()/4.0+4),"1");
69 | painter->drawText(rect.topLeft()+QPointF(width/2-10,2*rect.height()/4.0+4),"clamp");
70 | painter->drawText(rect.topLeft()+QPointF(8,3*rect.height()/4.0+4),"0");
71 | }
72 | void SINNode::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget){
73 | Node::paint(painter,option,widget);
74 | painter->drawText(boundingRect().center()-QPointF(12,0),"sin");
75 | }
76 | void COSNode::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget){
77 | Node::paint(painter,option,widget);
78 | painter->drawText(boundingRect().center()-QPointF(12,0),"cos");
79 | }
80 | void MINNode::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget){
81 | Node::paint(painter,option,widget);
82 | painter->drawText(boundingRect().center()-QPointF(12,0),"min");
83 | }
84 | void MAXNode::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget){
85 | Node::paint(painter,option,widget);
86 | painter->drawText(boundingRect().center()-QPointF(12,0),"max");
87 | }
88 | void POWNode::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget){
89 | Node::paint(painter,option,widget);
90 | painter->drawText(boundingRect().center()-QPointF(12,0),"pow");
91 | }
92 | void LOGNode::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget){
93 | Node::paint(painter,option,widget);
94 | painter->drawText(boundingRect().center()-QPointF(12,0),"log");
95 | }
96 | data_t ADDNode::kernel()const{
97 | return iNodes[0]->eval()+iNodes[1]->eval();
98 | }
99 | data_t SUBNode::kernel()const{
100 | return iNodes[0]->eval()-iNodes[1]->eval();
101 | }
102 | data_t MULNode::kernel()const{
103 | return iNodes[0]->eval()*iNodes[1]->eval();
104 | }
105 | data_t DIVNode::kernel()const{
106 | return iNodes[0]->eval()/iNodes[1]->eval();
107 | }
108 | data_t NEGNode::kernel()const{
109 | return -iNodes[0]->eval();
110 | }
111 | data_t SQRTNode::kernel()const{
112 | return iNodes[0]->eval().sqrt();
113 | }
114 | data_t ABSNode::kernel()const{
115 | return qAbs((double)iNodes[0]->eval());
116 | }
117 | data_t LERPNode::kernel()const{
118 | double alpha=iNodes[1]->eval();
119 | return (1.0-alpha)*double(iNodes[2]->eval())+alpha*double(iNodes[0]->eval());
120 | }
121 | data_t CLAMPNode::kernel()const{
122 | double min=iNodes[2]->eval(), max=iNodes[0]->eval();
123 | if(!(max-min)) return 0.0;
124 | return (double(iNodes[1]->eval())-min)/(max-min);
125 | }
126 | data_t SINNode::kernel()const{
127 | return iNodes[0]->eval().sin();
128 | }
129 | data_t COSNode::kernel()const{
130 | return iNodes[0]->eval().cos();
131 | }
132 | data_t MINNode::kernel()const{
133 | return qMin(iNodes[0]->eval(),iNodes[1]->eval());
134 | }
135 | data_t MAXNode::kernel()const{
136 | return qMax(iNodes[0]->eval(),iNodes[1]->eval());
137 | }
138 | data_t POWNode::kernel()const{
139 | return pow(iNodes[0]->eval(),iNodes[1]->eval());
140 | }
141 | data_t LOGNode::kernel()const{
142 | return iNodes[0]->eval().log();
143 | }
144 |
--------------------------------------------------------------------------------
/plugins/math/MathNode.h:
--------------------------------------------------------------------------------
1 | #ifndef MATHNODE_H
2 | #define MATHNODE_H
3 |
4 | #include "Node.h"
5 |
6 | class MathNode:public Node{
7 | protected:
8 | MathNode(const std::string &type, unsigned n, unsigned w=50, unsigned h=50);
9 | virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)=0;
10 | };
11 |
12 | class ADDNode:public MathNode{
13 | public:
14 | ADDNode();
15 | inline static Node* makeNode(std::istream&){return new ADDNode;}
16 | private:
17 | data_t kernel()const;
18 | void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
19 | };
20 |
21 | class SUBNode:public MathNode{
22 | public:
23 | SUBNode();
24 | inline static Node* makeNode(std::istream&){return new SUBNode;}
25 | private:
26 | data_t kernel()const;
27 | void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
28 | };
29 |
30 | class MULNode:public MathNode{
31 | public:
32 | MULNode();
33 | inline static Node* makeNode(std::istream&){return new MULNode;}
34 | private:
35 | data_t kernel()const;
36 | void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
37 | };
38 |
39 | class DIVNode:public MathNode{
40 | public:
41 | DIVNode();
42 | inline static Node* makeNode(std::istream&){return new DIVNode;}
43 | private:
44 | data_t kernel()const;
45 | void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
46 | };
47 |
48 | class NEGNode:public MathNode{
49 | public:
50 | NEGNode();
51 | inline static Node* makeNode(std::istream&){return new NEGNode;}
52 | private:
53 | data_t kernel()const;
54 | void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
55 | };
56 |
57 | class SQRTNode:public MathNode{
58 | public:
59 | SQRTNode();
60 | inline static Node* makeNode(std::istream&){return new SQRTNode;}
61 | private:
62 | data_t kernel()const;
63 | void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
64 | };
65 |
66 | class ABSNode:public MathNode{
67 | public:
68 | ABSNode();
69 | inline static Node* makeNode(std::istream&){return new ABSNode;}
70 | private:
71 | data_t kernel()const;
72 | void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
73 | };
74 | class LERPNode:public MathNode{
75 | public:
76 | LERPNode();
77 | inline static Node* makeNode(std::istream&){return new LERPNode;}
78 | private:
79 | data_t kernel()const;
80 | void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
81 | };
82 | class CLAMPNode:public MathNode{
83 | public:
84 | CLAMPNode();
85 | inline static Node* makeNode(std::istream&){return new CLAMPNode;}
86 | private:
87 | data_t kernel()const;
88 | void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
89 | };
90 | class SINNode:public MathNode{
91 | public:
92 | SINNode();
93 | inline static Node* makeNode(std::istream&){return new SINNode;}
94 | private:
95 | data_t kernel()const;
96 | void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
97 | };
98 | class COSNode:public MathNode{
99 | public:
100 | COSNode();
101 | inline static Node* makeNode(std::istream&){return new COSNode;}
102 | private:
103 | data_t kernel()const;
104 | void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
105 | };
106 |
107 | class MINNode:public MathNode{
108 | public:
109 | MINNode();
110 | inline static Node* makeNode(std::istream&){return new MINNode;}
111 | private:
112 | data_t kernel()const;
113 | void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
114 | };
115 | class MAXNode:public MathNode{
116 | public:
117 | MAXNode();
118 | inline static Node* makeNode(std::istream&){return new MAXNode;}
119 | private:
120 | data_t kernel()const;
121 | void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
122 | };
123 | class POWNode:public MathNode{
124 | public:
125 | POWNode();
126 | inline static Node* makeNode(std::istream&){return new POWNode;}
127 | private:
128 | data_t kernel()const;
129 | void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
130 | };
131 | class LOGNode:public MathNode{
132 | public:
133 | LOGNode();
134 | inline static Node* makeNode(std::istream&){return new LOGNode;}
135 | private:
136 | data_t kernel()const;
137 | void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
138 | };
139 | #endif // MATHNODE_H
140 |
--------------------------------------------------------------------------------
/plugins/math/MathPlugin.cpp:
--------------------------------------------------------------------------------
1 | #include "MathPlugin.h"
2 | #include "MathNode.h"
3 | #include "RealNode.h"
4 | #include "ComplexNode.h"
5 |
6 | void MathPlugin::updateUI(Ui::MainWindow* ui) const{
7 | QMenu* mathMenu = new QMenu("Math",ui->menuInsert);
8 | ui->menuInsert->addAction(mathMenu->menuAction());
9 | QAction* addAction= new QAction(QIcon(":/add.png"),"Add");
10 | QAction* subAction= new QAction(QIcon(":/subtract.png"),"Subtract");
11 | QAction* mulAction= new QAction(QIcon(":/multiply.png"),"Multiply");
12 | QAction* divAction= new QAction(QIcon(":/divide.png"),"Divide");
13 | QAction* realAction= new QAction(QIcon(":/real.png"),"Real");
14 | QAction* complexAction= new QAction(QIcon(":/complex.png"),"Complex");
15 | QAction* sqrtAction= new QAction(QIcon(":/sqrt.png"),"Square Root");
16 | QAction* absAction= new QAction("Absolute Value");
17 | QAction* negAction= new QAction(QIcon(":/neg.png"),"Neg");
18 | QAction* minAction= new QAction("Min");
19 | QAction* maxAction= new QAction("Max");
20 | QAction* powAction= new QAction("Power");
21 | QAction* logAction= new QAction("Logarithm");
22 | QAction* sinAction= new QAction(QIcon(":/sin.png"),"Sin");
23 | QAction* cosAction= new QAction(QIcon(":/cos.png"),"Cos");
24 | QAction* lerpAction= new QAction("Linear Interpolation");
25 | QAction* clampAction= new QAction("Clamp");
26 |
27 | Workspace* ws=(Workspace*)ui->workspace->scene();
28 | connect(addAction,&QAction::triggered,ws,[=]{ws->addNode(Node::nodeMalloc("add"));});
29 | connect(subAction,&QAction::triggered,ws,[=]{ws->addNode(Node::nodeMalloc("sub"));});
30 | connect(mulAction,&QAction::triggered,ws,[=]{ws->addNode(Node::nodeMalloc("mul"));});
31 | connect(divAction,&QAction::triggered,ws,[=]{ws->addNode(Node::nodeMalloc("div"));});
32 | connect(realAction,&QAction::triggered,ws,[=]{ws->addNode(Node::nodeMalloc("real"));});
33 | connect(complexAction,&QAction::triggered,ws,[=]{ws->addNode(Node::nodeMalloc("cplx"));});
34 | connect(sqrtAction,&QAction::triggered,ws,[=]{ws->addNode(Node::nodeMalloc("sqrt"));});
35 | connect(absAction,&QAction::triggered,ws,[=]{ws->addNode(Node::nodeMalloc("abs"));});
36 | connect(negAction,&QAction::triggered,ws,[=]{ws->addNode(Node::nodeMalloc("neg"));});
37 | connect(minAction,&QAction::triggered,ws,[=]{ws->addNode(Node::nodeMalloc("min"));});
38 | connect(maxAction,&QAction::triggered,ws,[=]{ws->addNode(Node::nodeMalloc("max"));});
39 | connect(powAction,&QAction::triggered,ws,[=]{ws->addNode(Node::nodeMalloc("pow"));});
40 | connect(logAction,&QAction::triggered,ws,[=]{ws->addNode(Node::nodeMalloc("log"));});
41 | connect(sinAction,&QAction::triggered,ws,[=]{ws->addNode(Node::nodeMalloc("sin"));});
42 | connect(cosAction,&QAction::triggered,ws,[=]{ws->addNode(Node::nodeMalloc("cos"));});
43 | connect(lerpAction,&QAction::triggered,ws,[=]{ws->addNode(Node::nodeMalloc("lerp"));});
44 | connect(clampAction,&QAction::triggered,ws,[=]{ws->addNode(Node::nodeMalloc("clamp"));});
45 |
46 | mathMenu->addAction(addAction);
47 | mathMenu->addAction(subAction);
48 | mathMenu->addAction(mulAction);
49 | mathMenu->addAction(divAction);
50 | mathMenu->addAction(realAction);
51 | mathMenu->addAction(complexAction);
52 | mathMenu->addAction(sqrtAction);
53 | mathMenu->addAction(absAction);
54 | mathMenu->addAction(negAction);
55 | mathMenu->addAction(minAction);
56 | mathMenu->addAction(maxAction);
57 | mathMenu->addAction(powAction);
58 | mathMenu->addAction(logAction);
59 | mathMenu->addAction(sinAction);
60 | mathMenu->addAction(cosAction);
61 | mathMenu->addAction(lerpAction);
62 | mathMenu->addAction(clampAction);
63 | }
64 |
65 | void MathPlugin::init()const{
66 | Node::makeNodeBinTextMethods["add"] = {&ADDNode::makeNode,&ADDNode::makeNode};
67 | Node::makeNodeBinTextMethods["sub"] = {&SUBNode::makeNode,&SUBNode::makeNode};
68 | Node::makeNodeBinTextMethods["mul"] = {&MULNode::makeNode,&MULNode::makeNode};
69 | Node::makeNodeBinTextMethods["div"] = {&DIVNode::makeNode,&DIVNode::makeNode};
70 | Node::makeNodeBinTextMethods["real"] = {&RealNode::makeFromBin,&RealNode::makeFromText};
71 | Node::makeNodeBinTextMethods["cplx"] = {&ComplexNode::makeNode,&ComplexNode::makeNode};
72 | Node::makeNodeBinTextMethods["sqrt"] = {&SQRTNode::makeNode,&SQRTNode::makeNode};
73 | Node::makeNodeBinTextMethods["abs"] = {&ABSNode::makeNode,&ABSNode::makeNode};
74 | Node::makeNodeBinTextMethods["neg"] = {&NEGNode::makeNode,&NEGNode::makeNode};
75 | Node::makeNodeBinTextMethods["min"] = {&MINNode::makeNode,&MINNode::makeNode};
76 | Node::makeNodeBinTextMethods["max"] = {&MAXNode::makeNode,&MAXNode::makeNode};
77 | Node::makeNodeBinTextMethods["pow"] = {&POWNode::makeNode,&POWNode::makeNode};
78 | Node::makeNodeBinTextMethods["log"] = {&LOGNode::makeNode,&LOGNode::makeNode};
79 | Node::makeNodeBinTextMethods["sin"] = {&SINNode::makeNode,&SINNode::makeNode};
80 | Node::makeNodeBinTextMethods["cos"] = {&COSNode::makeNode,&COSNode::makeNode};
81 | Node::makeNodeBinTextMethods["lerp"] = {&LERPNode::makeNode,&LERPNode::makeNode};
82 | Node::makeNodeBinTextMethods["clamp"]= {&CLAMPNode::makeNode,&CLAMPNode::makeNode};
83 |
84 | NodeBox::addTool("add","Add",QIcon(":/add.png"),"Math");
85 | NodeBox::addTool("sub","Subtract",QIcon(":/subtract.png"),"Math");
86 | NodeBox::addTool("mul","Multiply",QIcon(":/multiply.png"),"Math");
87 | NodeBox::addTool("div","Divide",QIcon(":/divide.png"),"Math");
88 | NodeBox::addTool("real","Real",QIcon(":/real.png"),"Math");
89 | NodeBox::addTool("cplx","Complex",QIcon(":/complex.png"),"Math");
90 | NodeBox::addTool("sqrt","Square Root",QIcon(":/sqrt.png"),"Math");
91 | NodeBox::addTool("abs","Absolute Value","Math");
92 | NodeBox::addTool("neg","Negative",QIcon(":/neg.png"),"Math");
93 | NodeBox::addTool("min","Min","Math");
94 | NodeBox::addTool("max","Max","Math");
95 | NodeBox::addTool("pow","Power","Math");
96 | NodeBox::addTool("log","Logarithm","Math");
97 | NodeBox::addTool("sin","Sin",QIcon(":/sin.png"),"Math");
98 | NodeBox::addTool("cos","Cos",QIcon(":/cos.png"),"Math");
99 | NodeBox::addTool("lerp","Linear Interpolation","Math");
100 | NodeBox::addTool("clamp","Clamp","Math");
101 | }
102 |
--------------------------------------------------------------------------------
/plugins/math/MathPlugin.h:
--------------------------------------------------------------------------------
1 | #ifndef MATHPLUGIN_H
2 | #define MATHPLUGIN_H
3 |
4 | #include
5 | #include
6 |
7 | #include "EmergenceInterface.h"
8 |
9 | class MathPlugin: public QObject, EmergenceInterface{
10 | Q_OBJECT
11 | Q_PLUGIN_METADATA(IID "Emergence.Node.Plugin")
12 | Q_INTERFACES(EmergenceInterface)
13 | public:
14 | void updateUI(Ui::MainWindow*)const override;
15 | void init()const override;
16 | };
17 |
18 | #endif
19 |
--------------------------------------------------------------------------------
/plugins/math/RealNode.cpp:
--------------------------------------------------------------------------------
1 | #include "RealNode.h"
2 |
3 | #include
4 | #include
5 |
6 | RealNode::RealNode(double v):Node("real",50,50,QColor(255,255,180)){
7 | cache=v;
8 | constant=true;
9 | }
10 |
11 | void RealNode::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget*widget){
12 | Node::paint(painter,option,widget);
13 | painter->drawText(boundingRect().center()-QPoint(12,-2),QString::number(cache.d));
14 | }
15 |
16 | void RealNode::contextMenuEvent(QGraphicsSceneContextMenuEvent* event){
17 | menu=new QMenu;
18 | connect(menu->addAction(QString("Change number")), &QAction::triggered,this,&RealNode::changeNumber);
19 | Node::contextMenuEvent(event);
20 | }
21 |
22 | void RealNode::mouseDoubleClickEvent(QGraphicsSceneMouseEvent*){
23 | changeNumber();
24 | }
25 |
26 | void RealNode::changeNumber(){
27 | bool ok;
28 | double d =QInputDialog::getDouble((QWidget*)parentWidget(),"Choose Number","",0,-2147483647,2147483647,3,&ok);
29 | if(ok){
30 | cache=d;
31 | updateVal();
32 | emit sm.updateOutputs();
33 | update();
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/plugins/math/RealNode.h:
--------------------------------------------------------------------------------
1 | #ifndef REALNODE_H
2 | #define REALNODE_H
3 |
4 | #include "Node.h"
5 |
6 | class RealNode:public Node{
7 | public:
8 | RealNode(double v=0);
9 | static Node* makeFromBin(std::istream&);
10 | static Node* makeFromText(std::istream&);
11 | private:
12 | inline data_t kernel()const{return cache;}
13 | virtual void paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget*widget);
14 | void contextMenuEvent(QGraphicsSceneContextMenuEvent* event);
15 | void mouseDoubleClickEvent(QGraphicsSceneMouseEvent*);
16 | void toBin(std::ostream &)const override;
17 | void toText(std::ostream &)const override;
18 | private slots:
19 | void changeNumber();
20 | };
21 |
22 | #endif
23 |
--------------------------------------------------------------------------------
/plugins/math/add.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bsella/Emergence/fdb8f58545ed708bcd9ce670fe85d4a840ddb965/plugins/math/add.png
--------------------------------------------------------------------------------
/plugins/math/complex.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bsella/Emergence/fdb8f58545ed708bcd9ce670fe85d4a840ddb965/plugins/math/complex.png
--------------------------------------------------------------------------------
/plugins/math/cos.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bsella/Emergence/fdb8f58545ed708bcd9ce670fe85d4a840ddb965/plugins/math/cos.png
--------------------------------------------------------------------------------
/plugins/math/divide.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bsella/Emergence/fdb8f58545ed708bcd9ce670fe85d4a840ddb965/plugins/math/divide.png
--------------------------------------------------------------------------------
/plugins/math/fromToStream.cpp:
--------------------------------------------------------------------------------
1 | #include "RealNode.h"
2 |
3 | Node* RealNode::makeFromBin(std::istream &in){
4 | if(in.peek()!=EOF){
5 | double d;
6 | in.read(reinterpret_cast(&d) ,sizeof(double));
7 | return new RealNode(d);
8 | }
9 | return new RealNode;
10 | }
11 | Node* RealNode::makeFromText(std::istream &in){
12 | if(in.peek()!=EOF){
13 | double d;
14 | in>>d;
15 | return new RealNode(d);
16 | }
17 | return new RealNode;
18 | }
19 |
20 | void RealNode::toBin(std::ostream &out) const{
21 | Node::toBin(out);
22 | out.write(reinterpret_cast(&cache.d),sizeof(double));
23 | }
24 | void RealNode::toText(std::ostream &out) const{
25 | Node::toText(out);
26 | out <<' '<< cache.d;
27 | }
28 |
--------------------------------------------------------------------------------
/plugins/math/math.qrc:
--------------------------------------------------------------------------------
1 |
2 |
3 | add.png
4 | complex.png
5 | cos.png
6 | divide.png
7 | multiply.png
8 | neg.png
9 | real.png
10 | sqrt.png
11 | sin.png
12 | subtract.png
13 |
14 |
15 |
--------------------------------------------------------------------------------
/plugins/math/multiply.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bsella/Emergence/fdb8f58545ed708bcd9ce670fe85d4a840ddb965/plugins/math/multiply.png
--------------------------------------------------------------------------------
/plugins/math/neg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bsella/Emergence/fdb8f58545ed708bcd9ce670fe85d4a840ddb965/plugins/math/neg.png
--------------------------------------------------------------------------------
/plugins/math/real.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bsella/Emergence/fdb8f58545ed708bcd9ce670fe85d4a840ddb965/plugins/math/real.png
--------------------------------------------------------------------------------
/plugins/math/sin.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bsella/Emergence/fdb8f58545ed708bcd9ce670fe85d4a840ddb965/plugins/math/sin.png
--------------------------------------------------------------------------------
/plugins/math/sqrt.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bsella/Emergence/fdb8f58545ed708bcd9ce670fe85d4a840ddb965/plugins/math/sqrt.png
--------------------------------------------------------------------------------
/plugins/math/subtract.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bsella/Emergence/fdb8f58545ed708bcd9ce670fe85d4a840ddb965/plugins/math/subtract.png
--------------------------------------------------------------------------------
/src/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | cmake_minimum_required(VERSION 3.0.0)
2 |
3 | find_package(Qt5Widgets REQUIRED)
4 |
5 | set(CMAKE_AUTOUIC ON)
6 | set(CMAKE_AUTOMOC ON)
7 | set(CMAKE_AUTORCC ON)
8 |
9 | file(GLOB FORMS *.ui)
10 | qt5_wrap_ui(UI_HEADERS ${FORMS})
11 | qt5_add_resources(QRC src.qrc)
12 |
13 | SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC")
14 |
15 | include_directories(${MAIN_SRC_DIR} ${BIN_SRC_DIR} ${Qt5Widgets_INCLUDE_DIRS})
16 |
17 | add_library(data_t data_t.cpp data_t.h)
18 |
19 | add_library(core
20 | mainwindow.cpp
21 | Node.cpp
22 | NodeBox.cpp
23 | Workspace.cpp
24 | PluginManager.cpp
25 | mainwindow.h
26 | Node.h
27 | NodeBox.h
28 | Workspace.h
29 | PluginManager.h
30 | signalManager.h
31 | ${UI_HEADERS})
32 |
33 | set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ..)
34 | add_executable(${PROJECT_NAME} main.cpp ${QRC})
35 |
36 | target_link_libraries(${PROJECT_NAME} data_t core Qt5::Widgets)
37 |
--------------------------------------------------------------------------------
/src/EmergenceInterface.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 |
5 | #include "Workspace.h"
6 | #include "ui_mainwindow.h"
7 |
8 | class EmergenceInterface{
9 | public:
10 | virtual void updateUI(Ui::MainWindow*)const{}
11 | virtual void init()const{}
12 | inline virtual bool redefineSaveLoad()const{return false;}
13 | virtual void toBin(std::ostream&)const{}
14 | virtual void toText(std::ostream&)const{}
15 | virtual void fromBin(std::istream&)const{}
16 | virtual void fromText(std::istream&)const{}
17 | };
18 |
19 | Q_DECLARE_INTERFACE(EmergenceInterface, "Emergence.Node.Plugin")
20 |
--------------------------------------------------------------------------------
/src/Node.cpp:
--------------------------------------------------------------------------------
1 | #include "Node.h"
2 |
3 | #include
4 | #include
5 | #include
6 |
7 | Node::Socket::Socket(unsigned i, double y, Node *parent):QGraphicsObject(parent)
8 | ,line(headSize,0,headSize,0),rank(i),iy(y),parent(parent){
9 | setZValue(parent->zValue()+1);
10 | setPos(-headSize-1,y);
11 | setAcceptHoverEvents(true);
12 | line.setParentItem(this);
13 | connect(this,&Node::Socket::xChanged,this,&Node::Socket::updateLine);
14 | connect(this,&Node::Socket::yChanged,this,&Node::Socket::updateLine);
15 | }
16 |
17 | Node::Socket::~Socket(){
18 | disconnect(this,&Node::Socket::yChanged,this,&Node::Socket::updateLine);
19 | disconnect(this,&Node::Socket::xChanged,this,&Node::Socket::updateLine);
20 | }
21 |
22 | QRectF Node::Socket::boundingRect()const{
23 | return QRectF(-headSize,-headSize,headSize*2+1,headSize*2+1);
24 | }
25 |
26 | void Node::Socket::updateLine(){
27 | line.setLine(QLine({headSize,0},(parentItem()->pos()-scenePos()-QPointF(0,-iy)).toPoint()));
28 | }
29 |
30 | void Node::Socket::paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *){
31 | if(visible){
32 | painter->setPen(pen);
33 | painter->setRenderHint(QPainter::Antialiasing);
34 | painter->drawEllipse(boundingRect().center(),headSize,headSize);
35 | }
36 | }
37 |
38 | void Node::Socket::hoverEnterEvent(QGraphicsSceneHoverEvent *){
39 | pen.setWidth(2);
40 | update();
41 | }
42 |
43 | void Node::Socket::hoverLeaveEvent(QGraphicsSceneHoverEvent *){
44 | pen.setWidth(1);
45 | update();
46 | }
47 |
48 | Node* Node::Socket::collidesWithNode() const{
49 | for(auto& i:collidingItems())
50 | if(i->data(0)=="node")
51 | return (Node*)i;
52 | return nullptr;
53 | }
54 |
55 | void Node::Socket::mouseMoveEvent(QGraphicsSceneMouseEvent*event){
56 | Node*i=collidesWithNode();
57 | if(i&&!i->isLooping(parent)&&i->contains(event->scenePos()-i->scenePos())){
58 | hover=i;
59 | for(const auto& ii: i->collidingItems())
60 | if(i->zValue()<= ii->zValue())
61 | i->setZValue(ii->zValue()+1);
62 | parent->setZValue(i->zValue());
63 | setZValue(i->zValue());
64 | setPos(i->pos()+QPoint(i->boundingRect().width()+Socket::headSize-1,i->height/2)-parent->pos());
65 | }else{
66 | hover=nullptr;
67 | setPos(event->scenePos()- boundingRect().center()-parent->pos());
68 | }
69 | }
70 |
71 | void Node::Socket::connectToNode(Node* n){
72 | if(n==parent) return;
73 | if(parent->nbArgs>=rank+1 && !parent->iNodes[rank]){
74 | QRectF r= n->boundingRect();
75 | setPos(n->pos()+QPoint(r.width()-Socket::headSize,r.height()/2)-parent->pos());
76 | parent->iNodes[rank]=n;
77 | n->oConnections.push_back({parent,rank});
78 | connect(n,&Node::xChanged,this,&Node::Socket::updateLine);
79 | connect(n,&Node::yChanged,this,&Node::Socket::updateLine);
80 | setEnabled(false);
81 | visible=false;
82 | parent->updateConstant();
83 | emit sm.updateOutputs();
84 | }
85 | }
86 |
87 | void Node::Socket::disconnectNode(){
88 | if(parent->iNodes[rank]){
89 | for(auto l=parent->iNodes[rank]->oConnections.begin();
90 | l!=parent->iNodes[rank]->oConnections.end();++l)
91 | if(l->first==parent && l->second==rank){
92 | parent->iNodes[rank]->oConnections.erase(l);
93 | break;
94 | }
95 | disconnect(parent->iNodes[rank],&Node::xChanged,this,&Node::Socket::updateLine);
96 | disconnect(parent->iNodes[rank],&Node::yChanged,this,&Node::Socket::updateLine);
97 | parent->iNodes[rank]=nullptr;
98 | reset();
99 | parent->updateConstant();
100 | emit sm.updateOutputs();
101 | }
102 | }
103 |
104 | void Node::Socket::mousePressEvent(QGraphicsSceneMouseEvent*){}
105 |
106 | void Node::Socket::mouseReleaseEvent(QGraphicsSceneMouseEvent*){
107 | if(hover) emit parent->connected(this,hover);
108 | else reset();
109 | }
110 |
111 | void Node::Socket::reset(){
112 | pen.setWidth(1);
113 | visible=true;
114 | setEnabled(true);
115 | setPos(-headSize-1,iy);
116 | line.setLine(headSize,0,headSize,0);
117 | }
118 |
119 | Node* Node::Socket::hover;
120 | SignalManager Node::sm;
121 |
122 | ulong Node::pixelID;
123 | uint Node::widthByHeight;
124 |
125 | Node::Node(const std::string &type, unsigned w, unsigned h, QColor c, uint n, bool spec):
126 | width(w),height(h),_type(type),special(spec),color(c),pen(QPen(Qt::black,1)),nbArgs(n){
127 | setCursor(Qt::OpenHandCursor);
128 | if(!spec)setData(0,"node");
129 | setData(1,"countMe");
130 | for(uint i=0; isetRenderHint(QPainter::Antialiasing);
157 | QPainterPath path;
158 | path.addRoundedRect(rect, 10, 10);
159 | pen.setWidth(isSelected()?2:1);
160 | painter->setPen(pen);
161 | painter->fillPath(path, color);
162 | painter->drawPath(path);
163 | for(uint i=1; i<=nbArgs; i++)//draw input sockets
164 | painter->drawLine(rect.topLeft()+QPointF(0,i*height/(nbArgs+1.0)),rect.topLeft()+QPointF(-socketSize,i*height/(nbArgs+1.0)));
165 | if(!special)//draw output socket
166 | painter->drawLine(rect.center()+QPointF(rect.width()/2,0),rect.center()+QPointF(rect.width()/2+socketSize,0));
167 | }
168 |
169 | void Node::updateLines()const{
170 | for(int i = 0; iboundingRect();
173 | sockets[i]->setPos(iNodes[i]->pos()-pos()+QPointF(r.width()-Socket::headSize,r.height()/2));
174 | }
175 | for(auto l=oConnections.begin(); l!=oConnections.end();++l)
176 | l->first->sockets[l->second]->setPos(pos()-l->first->pos()+QPointF(boundingRect().width()-Socket::headSize,height/2));
177 | }
178 |
179 | QPointF Node::tmpPos;
180 |
181 | void Node::mousePressEvent(QGraphicsSceneMouseEvent* event){
182 | if(event->button()==Qt::LeftButton){
183 | setCursor(Qt::ClosedHandCursor);
184 | setZValue(INT32_MAX);
185 | }else
186 | setCursor(Qt::ArrowCursor);
187 | tmpPos=pos();
188 | QGraphicsItem::mousePressEvent(event);
189 | }
190 | void Node::mouseReleaseEvent(QGraphicsSceneMouseEvent*event){
191 | scene()->setSceneRect(scene()->itemsBoundingRect());
192 | setCursor(Qt::OpenHandCursor);
193 | setZValue(0);
194 | for(const auto& i: collidingItems())
195 | if(zValue()<= i->zValue())
196 | setZValue(i->zValue()+1);
197 | if(pos()-tmpPos!=QPointF(0,0))
198 | emit moved();
199 | QGraphicsItem::mouseReleaseEvent(event);
200 | }
201 |
202 | void Node::contextMenuEvent(QGraphicsSceneContextMenuEvent *event){
203 | if(!menu) menu= new QMenu;
204 | for(unsigned i = 0; iaddAction(QString("Disconnect ")+QString::number(i+1));
206 | a->setEnabled(iNodes[i]!=nullptr);
207 | connect(a,&QAction::triggered,this,[=](){emit disconnected(sockets[i]);});
208 | }
209 | menu->addSeparator();
210 | menu->addAction(actionDelete);
211 | menu->exec(event->screenPos());
212 | delete menu;
213 | menu=nullptr;
214 | }
215 |
216 | Node::operator bool()const{
217 | for(auto g:iNodes)
218 | if(g==nullptr || !(*g))
219 | return false;
220 | return true;
221 | }
222 |
223 | void Node::drawIcon(QPainter *painter, QString filename){
224 | QImage icon=QImage(filename);
225 | painter->drawImage(width/2-icon.width()/2+socketSize,height/2-icon.height()/2,icon);
226 | }
227 |
228 | void Node::updateVal(){
229 | if(constant){
230 | cache=kernel();
231 | for(const auto& i : oConnections)
232 | i.first->updateVal();
233 | }
234 | }
235 |
236 | bool Node::isLooping(Node* n)const{
237 | if(this==n) return true;
238 | for(const auto& node:iNodes)
239 | if(node && node->isLooping(n))
240 | return true;
241 | return false;
242 | }
243 | void Node::updateConstant(){
244 | constant=true;
245 | for(const auto& node: iNodes)
246 | if(!node || !node->constant)
247 | constant=false;
248 | if(constant)
249 | cache=kernel();
250 | for(const auto& i : oConnections)
251 | i.first->updateConstant();
252 | }
253 |
254 | std::map> Node::makeNodeBinTextMethods;
255 |
256 | Node* Node::nodeMalloc(const std::string& type){
257 | std::istringstream in;
258 | return nodeMalloc(type,in);
259 | }
260 | Node* Node::nodeMalloc(const std::string& type, std::istream&in){
261 | if(makeNodeBinTextMethods.find(type)!= makeNodeBinTextMethods.end())
262 | return makeNodeBinTextMethods[type].first(in);
263 | return nullptr;
264 | }
265 |
266 | data_t Node::eval(){
267 | if(constant) return cache;
268 | if(pixelID==lastPixelID) return cache;
269 | lastPixelID=pixelID;
270 | return cache=kernel();
271 | }
272 |
273 | void Node::toBin(std::ostream& out) const{
274 | out << _type<<'\n';
275 | int fx,fy;
276 | fx=scenePos().x();
277 | fy=scenePos().y();
278 | out.write(reinterpret_cast(&fx),sizeof(int));
279 | out.write(reinterpret_cast(&fy),sizeof(int));
280 | }
281 | void Node::toText(std::ostream& out) const{
282 | out << _type<<' ';
283 | out << scenePos().x()<< ' ';
284 | out << scenePos().y();
285 | }
286 | //Reads the BINARY data from a stream and creates a list of nodes
287 | std::istream& operator>>(std::istream& in, QList&nodes){
288 | int tmp;
289 | in.read(reinterpret_cast(&tmp),sizeof(int));
290 |
291 | std::string type;
292 | int xx,yy;
293 | for(int i=0;i> type;
295 | in.ignore(1);
296 | in.read(reinterpret_cast(&xx),sizeof(int));
297 | in.read(reinterpret_cast(&yy),sizeof(int));
298 | Node* n= Node::makeNodeBinTextMethods[type].first(in);
299 | n->setPos(xx,yy);
300 | nodes.push_back(n);
301 | }
302 | for(const auto& n:nodes)
303 | for(uint i=0; inbArgs; i++){
304 | in.read(reinterpret_cast(&tmp),sizeof(int));
305 | if(tmp>=0)
306 | n->sockets[i]->connectToNode(nodes.at(tmp));
307 | }
308 | return in;
309 | }
310 |
--------------------------------------------------------------------------------
/src/Node.h:
--------------------------------------------------------------------------------
1 | #ifndef NODE_H
2 | #define NODE_H
3 |
4 | #include
5 | #include
6 | #include
7 |
8 | #include "data_t.h"
9 | #include "signalManager.h"
10 |
11 | class Node: public QGraphicsObject{
12 | Q_OBJECT
13 | public:
14 | Node(const std::string& type, unsigned w=50, unsigned h=50, QColor c=Qt::white, uint n=0, bool spec=false);
15 | ~Node();
16 | unsigned width, height;
17 | const std::string _type;
18 | virtual data_t eval();
19 | static Node* nodeMalloc(const std::string &);
20 | static Node* nodeMalloc(const std::string &, std::istream &in);
21 | QVector iNodes; //INPUT NODES
22 | static SignalManager sm;
23 | virtual operator bool()const;
24 | static std::map> makeNodeBinTextMethods;
27 | // friend std::ostream& operator<<(std::ostream& out, const Node&);
28 | // friend std::istream& operator>>(std::istream& in , Node*);
29 | friend std::istream& operator>>(std::istream& in , QList&);
30 | private:
31 | friend class MainWindow;
32 | friend class Workspace;
33 | friend class DeleteNodeCommand;
34 | friend class ConnectNodeCommand;
35 | friend class DisconnectNodeCommand;
36 | friend class MoveNodeCommand;
37 | friend class Function;
38 | bool special;
39 | QPointF initialPos;
40 | static QPointF tmpPos;
41 | void mousePressEvent(QGraphicsSceneMouseEvent *event);
42 | void mouseReleaseEvent(QGraphicsSceneMouseEvent *event);
43 | virtual data_t kernel()const=0;
44 | bool isLooping(Node *n)const;
45 | void updateConstant();
46 | protected slots:
47 | void updateLines()const;
48 | void updateVal();
49 | protected:
50 | struct Socket : public QGraphicsObject{
51 | Socket(unsigned i, double y, Node *parent);
52 | ~Socket();
53 | QGraphicsLineItem line;
54 | unsigned rank;
55 | double iy;
56 | static Node *hover;
57 | Node *parent;
58 | bool visible=true;
59 | static const int headSize=8;
60 | QPen pen=QPen(Qt::black);
61 | void connectToNode(Node*n);
62 | void disconnectNode();
63 | QRectF boundingRect() const;
64 | void updateLine();
65 | Node* collidesWithNode()const;
66 | void paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *);
67 | void hoverEnterEvent(QGraphicsSceneHoverEvent*);
68 | void hoverLeaveEvent(QGraphicsSceneHoverEvent*);
69 | void mouseMoveEvent(QGraphicsSceneMouseEvent*);
70 | void mousePressEvent(QGraphicsSceneMouseEvent*);
71 | void mouseReleaseEvent(QGraphicsSceneMouseEvent*);
72 | void reset();
73 | };
74 | static const int socketSize=5;
75 | static uint widthByHeight;
76 | static ulong pixelID;
77 | ulong lastPixelID=0;
78 | data_t cache; //value returned by node
79 | bool constant=false; //value is constant
80 | QColor color;
81 | QMenu *menu=nullptr;
82 | QPen pen;
83 | uint nbArgs;
84 | QList> oConnections;
85 | QVector sockets;
86 | QAction* actionDelete;
87 |
88 | QRectF boundingRect()const;
89 | virtual void toBin(std::ostream&)const;
90 | virtual void toText(std::ostream&)const;
91 | virtual void paint(QPainter* painter,
92 | const QStyleOptionGraphicsItem* option,
93 | QWidget* widget);
94 | virtual void contextMenuEvent(QGraphicsSceneContextMenuEvent* event);
95 | void drawIcon(QPainter *painter, QString filename);
96 | signals:
97 | void connected(Node::Socket* s,Node* n);
98 | void disconnected(Node::Socket* s);
99 | void moved();
100 | };
101 |
102 | #endif
103 |
--------------------------------------------------------------------------------
/src/NodeBox.cpp:
--------------------------------------------------------------------------------
1 | #include "NodeBox.h"
2 |
3 | #include
4 | #include
5 | #include
6 | #include
7 | #include
8 | #include
9 | #include
10 |
11 | Workspace* NodeTool::workspace;
12 | QPointF NodeTool::point;
13 | NodeTool::NodeTool(const std::string& id,const QString& text, const QIcon& icon)
14 | :id(id),icon(icon){
15 | setMinimumHeight(30);
16 | setMaximumHeight(30);
17 | QLabel *lblIcon= new QLabel;
18 | lblIcon->setPixmap(icon.pixmap(24,24));
19 | QLabel *lbl= new QLabel(text);
20 | QHBoxLayout* hbl= new QHBoxLayout(this);
21 | hbl->setSpacing(1);
22 | hbl->setMargin(0);
23 | hbl->addWidget(lblIcon);
24 | hbl->addWidget(lbl);
25 | hbl->addItem(new QSpacerItem(0,0,QSizePolicy::Expanding));
26 | lbl->setAttribute(Qt::WA_TransparentForMouseEvents);
27 | setFrameShape(StyledPanel);
28 | setFrameShadow(Raised);
29 | // setAutoFillBackground(true);
30 | // setBackgroundRole(QPalette::Base);
31 | }
32 |
33 | void NodeTool::mouseMoveEvent(QMouseEvent *event){
34 | QDrag* drag= new QDrag(this);
35 | drag->setPixmap(icon.pixmap(24,24));
36 | drag->setMimeData(new QMimeData);
37 | workspace=nullptr;
38 | drag->exec();
39 | if(workspace)
40 | workspace->addNode(Node::nodeMalloc(id),point);
41 | QWidget::mouseMoveEvent(event);
42 | }
43 |
44 | std::vector NodeBox::nodeboxes;
45 | std::vector NodeBox::tools;
46 | NodeBox::NodeBox(QWidget *parent):QToolBox(parent){
47 | for(const auto& tool:tools)
48 | addTool(tool);
49 | nodeboxes.push_back(this);
50 | }
51 | void NodeBox::addTool(const nodeToolData &tool){
52 | int i=0;
53 | while(itemText(i)!=tool.category && itemText(i)!="") i++;
54 | QVBoxLayout *vbl;
55 | if(i==count()){ //The Widget-container(page) was not found
56 | QWidget* page = new QWidget;
57 | vbl= new QVBoxLayout(page);
58 | vbl->setSpacing(1);
59 | vbl->setMargin(0);
60 | vbl->addWidget(new NodeTool(tool.id,tool.text,tool.icon));
61 | vbl->addItem(new QSpacerItem(0,0,QSizePolicy::Minimum,QSizePolicy::Expanding));
62 | addItem(page,tool.category);
63 | }else{
64 | vbl = (QVBoxLayout*)widget(i)->layout();
65 | vbl->insertWidget(vbl->count()-1,new NodeTool(tool.id,tool.text,tool.icon));
66 | }
67 | }
68 | void NodeBox::addTool(const std::string &id, const QString &text, const QString &category){
69 | addTool(id,text,QIcon(":/no_icon.png"),category);
70 | }
71 | void NodeBox::addTool(const std::string& id, const QString&text,
72 | const QIcon& icon, const QString &category){
73 | tools.push_back({id,text,icon,category});
74 | for(auto nb:nodeboxes)
75 | nb->addTool(tools.back());
76 | }
77 |
--------------------------------------------------------------------------------
/src/NodeBox.h:
--------------------------------------------------------------------------------
1 | #ifndef NODEBOX_H
2 | #define NODEBOX_H
3 |
4 | #include
5 | #include "Workspace.h"
6 |
7 | class NodeTool : public QFrame{
8 | public:
9 | NodeTool(const std::string& id,
10 | const QString &text,
11 | const QIcon&icon);
12 | private:
13 | static Workspace* workspace;
14 | static QPointF point;
15 | std::string id;
16 | QIcon icon;
17 | void mouseMoveEvent(QMouseEvent *event);
18 | friend class Workspace;
19 | };
20 |
21 | struct nodeToolData{
22 | const std::string id;
23 | const QString text;
24 | const QIcon icon;
25 | const QString category;
26 | };
27 |
28 | class NodeBox : public QToolBox{
29 | public:
30 | NodeBox(QWidget* parent=0);
31 | static void addTool(const std::string &id,
32 | const QString &text,
33 | const QIcon&icon=QIcon(":/no_icon.png"),
34 | const QString &category="Miscellaneous");
35 | static void addTool(const std::string &id,
36 | const QString &text,
37 | const QString &category);
38 | private:
39 | static std::vector nodeboxes;
40 | static std::vector tools;
41 | void addTool(const nodeToolData&);
42 | };
43 |
44 | #endif // NODEBOX_H
45 |
--------------------------------------------------------------------------------
/src/PluginManager.cpp:
--------------------------------------------------------------------------------
1 | #include "PluginManager.h"
2 |
3 | #include
4 | #include
5 | #include
6 |
7 | PluginManager::PluginManager(Ui::MainWindow *mw):ui(mw){}
8 |
9 | bool PluginManager::loadPlugins(){
10 | QDir dir(qApp->applicationDirPath());
11 | dir.cd("lib");
12 | bool success=false;
13 | for(const auto& fileName: dir.entryList(QDir::Files)){
14 | QPluginLoader pluginLoader(dir.absoluteFilePath(dir.absoluteFilePath(fileName)));
15 | if (auto plugin = pluginLoader.instance()){
16 | EmergenceInterface* interface= qobject_cast(plugin);
17 | if (interface){
18 | interface->init();
19 | interface->updateUI(ui);
20 | success= true;
21 | if(interface->redefineSaveLoad())
22 | plugins.push_back(interface);
23 | }
24 | }
25 | }
26 | return success;
27 | }
28 |
29 | void PluginManager::toBin(std::ostream &out)const{
30 | std::vector usedPlugins;
31 | Workspace* ws = (Workspace*)ui->workspace->scene();
32 | for(const auto& node: ws->nodes())
33 | if(std::find(usedPlugins.cbegin(),usedPlugins.cend(),node->_type)==usedPlugins.cend())
34 | usedPlugins.push_back(node->_type);
35 | int tmp=usedPlugins.size();
36 | out.write(reinterpret_cast(&tmp),sizeof(int));
37 | for(const auto& x: usedPlugins){
38 | out.write(x.data(),sizeof(char)*x.size());
39 | out<<'\n';
40 | }
41 | for(const auto& plugin: plugins)
42 | plugin->toBin(out);
43 | }
44 |
45 | void PluginManager::toText(std::ostream &out)const{
46 | std::vector usedPlugins;
47 | Workspace* ws = (Workspace*)ui->workspace->scene();
48 | for(const auto& node: ws->nodes())
49 | if(std::find(usedPlugins.cbegin(),usedPlugins.cend(),node->_type)==usedPlugins.cend())
50 | usedPlugins.push_back(node->_type);
51 | out << usedPlugins.size() << '\n';
52 | for(const auto& x: usedPlugins)
53 | out << x << ' ';
54 | out << '\n';
55 | for(const auto& plugin: plugins)
56 | plugin->toText(out);
57 | }
58 | void PluginManager::fromBin(std::istream &in)const{
59 | int nbPlugins;
60 | in.read(reinterpret_cast(&nbPlugins),sizeof(int));
61 | std::vector known;
62 | known.reserve(Node::makeNodeBinTextMethods.size());
63 | for(const auto& keyValue : Node::makeNodeBinTextMethods)
64 | known.push_back(keyValue.first);
65 | std::string tmp;
66 | for(int i=0; i> tmp;
68 | if(std::find(known.cbegin(),known.cend(),tmp)==known.cend()){
69 | const std::string message="A plugin containing the implementation of the \""+tmp+"\" node is missing.";
70 | QMessageBox::warning(0,"Missing Plugin",QString::fromStdString(message));
71 | return;
72 | }
73 | }
74 | in.ignore(1);
75 | for(const auto& plugin: plugins)
76 | plugin->fromBin(in);
77 | }
78 | void PluginManager::fromText(std::istream &in)const{
79 | int nbPlugins;
80 | in>> nbPlugins;
81 | std::vector known;
82 | known.reserve(Node::makeNodeBinTextMethods.size());
83 | for(const auto& keyValue : Node::makeNodeBinTextMethods)
84 | known.push_back(keyValue.first);
85 | std::string tmp;
86 | for(int i=0; i> tmp;
88 | if(std::find(known.cbegin(),known.cend(),tmp)==known.cend()){
89 | const std::string message="A plugin containing the implementation of the \""+tmp+"\" node is missing.";
90 | QMessageBox::warning(0,"Missing Plugin",QString::fromStdString(message));
91 | return;
92 | }
93 | }
94 | for(const auto& plugin: plugins)
95 | plugin->fromText(in);
96 | }
97 |
--------------------------------------------------------------------------------
/src/PluginManager.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include "ui_mainwindow.h"
4 | #include "EmergenceInterface.h"
5 |
6 | class PluginManager{
7 | public:
8 | explicit PluginManager(Ui::MainWindow*);
9 | Ui::MainWindow *ui;
10 | bool loadPlugins();
11 | void toBin(std::ostream&)const;
12 | void toText(std::ostream&)const;
13 | void fromBin(std::istream&)const;
14 | void fromText(std::istream&)const;
15 | std::vector plugins;
16 | std::vector evalFunctions;
17 | };
18 |
--------------------------------------------------------------------------------
/src/Workspace.cpp:
--------------------------------------------------------------------------------
1 | #include "Workspace.h"
2 |
3 | #include
4 | #include
5 | #include
6 | #include
7 |
8 | #include "NodeBox.h"
9 |
10 | Workspace::Workspace(QWidget *parent):QGraphicsScene(parent){}
11 |
12 | void Workspace::dragEnterEvent(QGraphicsSceneDragDropEvent *event){
13 | QGraphicsScene::dragEnterEvent(event);
14 | event->accept();
15 | }
16 |
17 | void Workspace::dropEvent(QGraphicsSceneDragDropEvent *event){
18 | NodeTool::workspace=this;
19 | NodeTool::point=event->scenePos();
20 | }
21 |
22 | void Workspace::dragMoveEvent(QGraphicsSceneDragDropEvent*event){
23 | QGraphicsScene::dragMoveEvent(event);
24 | event->accept();
25 | }
26 |
27 | void Workspace::addNode(Node* n){
28 | addNode(n,sceneRect().center());
29 | }
30 |
31 | void Workspace::addNode(Node *n, const QPointF& pos){
32 | if(!n) return;
33 | clearSelection();
34 | n->setPos(pos);
35 | n->initialPos=pos;
36 | connect(n,SIGNAL(moved()),this,SLOT(moveNodes()));
37 | connect(n,SIGNAL(connected(Node::Socket*,Node*)),this,SLOT(connectNode(Node::Socket*,Node*)));
38 | connect(n,SIGNAL(disconnected(Node::Socket*)),this,SLOT(disconnectNode(Node::Socket*)));
39 | connect(n->actionDelete,&QAction::triggered,this,[=](){undoStack.push(new DeleteNodeCommand(n,this));});
40 | undoStack.push(new AddNodeCommand(n,this));
41 | }
42 |
43 | void Workspace::addNodes(const QList &n){
44 | undoStack.beginMacro("add_node");
45 | for(auto& i: n){
46 | if(!i) continue;
47 | i->initialPos=i->pos();
48 | connect(i,SIGNAL(moved()),this,SLOT(moveNodes()));
49 | connect(i,SIGNAL(connected(Node::Socket*,Node*)),this,SLOT(connectNode(Node::Socket*,Node*)));
50 | connect(i,SIGNAL(disconnected(Node::Socket*)),this,SLOT(disconnectNode(Node::Socket*)));
51 | connect(i->actionDelete,&QAction::triggered,this,[=](){undoStack.push(new DeleteNodeCommand(i,this));});
52 | undoStack.push(new AddNodeCommand(i,this));
53 | }
54 | undoStack.endMacro();
55 | }
56 |
57 | void Workspace::paste(){
58 | clearSelection();
59 | const QMimeData* mime= QApplication::clipboard()->mimeData();
60 | if(mime->text()=="Emergence_Nodes"){
61 | QList nodes;
62 | std::istringstream istr(mime->data("copy").toStdString());
63 | istr >> nodes;
64 | addNodes(nodes);
65 | }
66 | }
67 |
68 | void Workspace::select_all() const{
69 | for(const auto& n : items())
70 | n->setSelected(true);
71 | }
72 |
73 | void Workspace::delete_selected(){
74 | bool found=false;
75 | for(auto& n:selectedItems()){
76 | if(((Node*)n)->_type!="output"&&((Node*)n)->_type!="input"){
77 | if(!found) undoStack.beginMacro("delete");
78 | found=true;
79 | undoStack.push(new DeleteNodeCommand((Node*)n,this));
80 | }
81 | }
82 | if(found)undoStack.endMacro();
83 | }
84 |
85 | void Workspace::moveNodes(){
86 | undoStack.beginMacro("move");
87 | for(auto& n: selectedItems())
88 | undoStack.push(new MoveNodeCommand((Node*)n));
89 | undoStack.endMacro();
90 | }
91 |
92 | void Workspace::connectNode(Node::Socket* s, Node* n){
93 | undoStack.push(new ConnectNodeCommand(s,n));
94 | }
95 | void Workspace::disconnectNode(Node::Socket* s){
96 | undoStack.push(new DisconnectNodeCommand(s));
97 | }
98 |
99 | void Workspace::copy()const{
100 | QMimeData * mime=new QMimeData;
101 | mime->setText("Emergence_Nodes");
102 | QList selectedNodes;
103 | for(const auto& i: selectedItems())
104 | selectedNodes.append((Node*)i);
105 | std::ostringstream oss;
106 | int tmp=selectedNodes.size();
107 | oss.write(reinterpret_cast(&tmp),sizeof(int));
108 | for(const auto& n:selectedNodes)
109 | n->toBin(oss);
110 | for(const auto& n:selectedNodes)
111 | for(const auto& nn:n->iNodes){
112 | tmp= selectedNodes.indexOf(nn);
113 | oss.write(reinterpret_cast(&tmp),sizeof(int));
114 | }
115 | std::string str= oss.str();
116 |
117 | QByteArray ba(str.c_str(),str.length());
118 | mime->setData("copy",ba);
119 | QApplication::clipboard()->setMimeData(mime);
120 | }
121 |
122 | void Workspace::cut(){
123 | copy();
124 | delete_selected();
125 | }
126 |
127 | QList Workspace::nodes()const{
128 | QList ret;
129 | for(const auto& n:items())
130 | if(n->data(1)=="countMe")
131 | ret.append((Node*)n);
132 | return ret;
133 | }
134 | int Workspace::count()const{
135 | return nodes().size();
136 | }
137 | Node* Workspace::nodeAt(int i) const{
138 | return nodes().at(i);
139 | }
140 | int Workspace::nodeIndex(Node* n) const{
141 | return nodes().indexOf(n);
142 | }
143 | void Workspace::toBin(std::ostream& out) const{
144 | int tmp=nodes().size();
145 | out.write(reinterpret_cast(&tmp),sizeof(int));
146 | for(const auto& n:nodes())
147 | n->toBin(out);
148 | for(const auto& n:nodes())
149 | for(const auto& nn:n->iNodes){
150 | tmp= nodes().indexOf(nn);
151 | out.write(reinterpret_cast(&tmp),sizeof(int));
152 | }
153 | }
154 | void Workspace::toText(std::ostream& out) const{
155 | out << nodes().size()<< '\n';
156 | for(const auto& n:nodes()){
157 | n->toText(out);
158 | out << '\n';
159 | }
160 | for(const auto& n:nodes())
161 | for(const auto& nn:n->iNodes)
162 | out << nodes().indexOf(nn) << ' ';
163 | out << '\n';
164 | }
165 |
166 | void Workspace::fromBin(std::istream& in){
167 | QList nodes;
168 | in >> nodes;
169 | addNodes(nodes);
170 | }
171 | void Workspace::fromText(std::istream& in){
172 | QList nodes;
173 | int tmp;
174 | in>>tmp;
175 |
176 | for(int i=0;i> type >>xx >> yy;
180 | Node* n;
181 | n= Node::makeNodeBinTextMethods[type].second(in);
182 | n->setPos(xx,yy);
183 | nodes.push_back(n);
184 | }
185 | for(const auto& n:nodes)
186 | for(uint i=0; inbArgs; i++){
187 | in>>tmp;
188 | if(tmp>=0)
189 | n->sockets[i]->connectToNode(nodes.at(tmp));
190 | }
191 | addNodes(nodes);
192 | }
193 |
194 | AddNodeCommand::AddNodeCommand(Node* node, QGraphicsScene* scene,
195 | QUndoCommand* parent): QUndoCommand(parent){
196 | _scene=scene;
197 | _node=node;
198 | }
199 | void AddNodeCommand::undo(){
200 | _node->setSelected(false);
201 | _scene->removeItem(_node);
202 | _scene->update();
203 | }
204 | void AddNodeCommand::redo(){
205 | _scene->addItem(_node);
206 | _node->setSelected(true);
207 | _node->setZValue(0);
208 | for(const auto& i: _node->collidingItems())
209 | if(_node->zValue()<= i->zValue())
210 | _node->setZValue(i->zValue()+1);
211 | _scene->update();
212 | }
213 | AddNodeCommand::~AddNodeCommand(){
214 | delete _node;
215 | }
216 |
217 | DeleteNodeCommand::DeleteNodeCommand(Node* node,QGraphicsScene *scene, QUndoCommand *parent):QUndoCommand(parent){
218 | _scene=scene;
219 | _node=node;
220 | iNodes=node->iNodes;
221 | oConnections=node->oConnections;
222 | }
223 | void DeleteNodeCommand::undo(){
224 | _scene->addItem(_node);
225 | for(int j=0; jsockets[j]->connectToNode(iNodes[j]);
228 | for(int j=0; jsockets[oConnections[j].second]->connectToNode(_node);
230 | _scene->update();
231 | }
232 | void DeleteNodeCommand::redo(){
233 | for(auto& s:_node->sockets)
234 | s->disconnectNode();
235 | for(auto& c:_node->oConnections)
236 | c.first->sockets[c.second]->disconnectNode();
237 | _scene->removeItem(_node);
238 | _scene->update();
239 | }
240 |
241 | ConnectNodeCommand::ConnectNodeCommand(Node::Socket *s, Node *in,
242 | QUndoCommand *parent): QUndoCommand(parent){
243 | _socket=s;
244 | _iNode=in;
245 | }
246 | void ConnectNodeCommand::undo(){
247 | _socket->disconnectNode();
248 | }
249 | void ConnectNodeCommand::redo(){
250 | _socket->connectToNode(_iNode);
251 | }
252 |
253 | DisconnectNodeCommand::DisconnectNodeCommand(Node::Socket *s,
254 | QUndoCommand *parent): QUndoCommand(parent){
255 | _node=s->parent->iNodes[s->rank];
256 | _socket=s;
257 | }
258 | void DisconnectNodeCommand::undo(){
259 | _socket->connectToNode(_node);
260 | }
261 | void DisconnectNodeCommand::redo(){
262 | _socket->disconnectNode();
263 | }
264 |
265 | MoveNodeCommand::MoveNodeCommand(Node* node,
266 | QUndoCommand *parent): QUndoCommand(parent){
267 | _node=node;
268 | _pos=node->pos();
269 | _oldPos=node->initialPos;
270 | }
271 | void MoveNodeCommand::undo(){
272 | _node->setPos(_oldPos);
273 | _node->initialPos=_oldPos;
274 | }
275 | void MoveNodeCommand::redo(){
276 | _node->setPos(_pos);
277 | _node->initialPos=_pos;
278 | }
279 |
--------------------------------------------------------------------------------
/src/Workspace.h:
--------------------------------------------------------------------------------
1 | #ifndef WORKSPACE_H
2 | #define WORKSPACE_H
3 |
4 | #include
5 | #include
6 | #include "Node.h"
7 |
8 | class Workspace : public QGraphicsScene{
9 | Q_OBJECT
10 | public:
11 | Workspace(QWidget *parent=0);
12 | QUndoStack undoStack;
13 | constexpr static double scaleFactor=1.05;
14 | void addNode(Node*);
15 | void addNode(Node*, const QPointF&);
16 | void addNodes(const QList&);
17 | void toBin(std::ostream&)const;
18 | void toText(std::ostream&)const;
19 | void fromBin(std::istream&);
20 | void fromText(std::istream&);
21 | int count()const;
22 | Node* nodeAt(int)const;
23 | int nodeIndex(Node*)const;
24 | QList nodes()const;
25 | private:
26 | void dragEnterEvent(QGraphicsSceneDragDropEvent *);
27 | void dragMoveEvent(QGraphicsSceneDragDropEvent*);
28 | void dropEvent(QGraphicsSceneDragDropEvent*);
29 | public slots:
30 | void paste();
31 | void select_all()const;
32 | void delete_selected();
33 | void copy()const;
34 | void cut();
35 | void moveNodes();
36 | void connectNode(Node::Socket*, Node*);
37 | void disconnectNode(Node::Socket*);
38 | };
39 |
40 | class AddNodeCommand: public QUndoCommand{
41 | public:
42 | AddNodeCommand(Node* node, QGraphicsScene* scene,
43 | QUndoCommand* parent=0);
44 | ~AddNodeCommand();
45 | void undo()override;
46 | void redo()override;
47 | private:
48 | Node* _node;
49 | QGraphicsScene* _scene;
50 | };
51 |
52 | class DeleteNodeCommand: public QUndoCommand{
53 | public:
54 | DeleteNodeCommand(Node* node,QGraphicsScene* scene,
55 | QUndoCommand* parent=0);
56 | void undo()override;
57 | void redo()override;
58 | private:
59 | Node* _node;
60 | QVector iNodes;
61 | QList> oConnections;
62 | QGraphicsScene* _scene;
63 | };
64 |
65 | class ConnectNodeCommand: public QUndoCommand{
66 | public:
67 | ConnectNodeCommand(Node::Socket* s, Node* in,
68 | QUndoCommand* parent=0);
69 | void undo()override;
70 | void redo()override;
71 | private:
72 | Node::Socket* _socket;
73 | Node* _iNode;
74 | };
75 |
76 | class DisconnectNodeCommand: public QUndoCommand{
77 | public:
78 | DisconnectNodeCommand(Node::Socket *s,
79 | QUndoCommand* parent=0);
80 | void undo()override;
81 | void redo()override;
82 | private:
83 | Node::Socket* _socket;
84 | Node* _node;
85 | };
86 |
87 | class MoveNodeCommand: public QUndoCommand{
88 | public:
89 | MoveNodeCommand(Node *node, QUndoCommand* parent=0);
90 | void undo()override;
91 | void redo()override;
92 | private:
93 | Node* _node;
94 | QPointF _pos;
95 | QPointF _oldPos;
96 | };
97 |
98 | #endif // WORKSPACE_H
99 |
--------------------------------------------------------------------------------
/src/data_t.cpp:
--------------------------------------------------------------------------------
1 | #include "data_t.h"
2 |
3 | data_t::operator bool()const{
4 | switch (t) {
5 | case TypeEnum::DOUBLE: return d>=1;
6 | case TypeEnum::COLOR: return clr!=0;
7 | case TypeEnum::COMPLEX: return std::real(c)>0 && std::imag(c)>0;
8 | default:return b;
9 | }
10 | }
11 |
12 | data_t::operator double()const{
13 | switch (t) {
14 | case TypeEnum::BOOL:
15 | return b? 1.0:0.0;
16 | case TypeEnum::COLOR:
17 | return ((clr&0xff)*.0722+ //BLUE
18 | ((clr&0xff00)>>8)*.7152+ //GREEN
19 | ((clr&0xff0000)>>16)*.2126 //RED
20 | )/256.0;
21 | case TypeEnum::COMPLEX:
22 | return std::abs(c);
23 | default: return d;
24 | }
25 | }
26 |
27 | data_t::operator color()const{
28 | if(t==TypeEnum::BOOL) return b? 0xffffffff:0xff000000;
29 | if(t==TypeEnum::DOUBLE){
30 | if(d>=1)return 0xffffffff;
31 | if(d<=0)return 0xff000000;
32 | uint8_t c= d*256;
33 | return 0xff000000+c+(c<<8)+(c<<16);
34 | }
35 | if(t==TypeEnum::COMPLEX){
36 | return QColor::fromHsv(359*(std::arg(c)+M_PI)/(M_PI*2),
37 | 255,
38 | std::abs(c)>1?255:std::abs(c)*255).rgb();
39 | }
40 | return clr;
41 | }
42 |
43 | data_t::operator cplx()const{
44 | if(t==TypeEnum::BOOL) return b? 1:0;
45 | if(t==TypeEnum::DOUBLE) return cplx(d,0);
46 | return c;
47 | }
48 |
49 | data_t& data_t::operator=(double dd){
50 | t=TypeEnum::DOUBLE;
51 | d=dd;
52 | return *this;
53 | }
54 | data_t& data_t::operator=(bool bb){
55 | t=TypeEnum::BOOL;
56 | b=bb;
57 | return *this;
58 | }
59 | data_t& data_t::operator=(color uu){
60 | t=TypeEnum::COLOR;
61 | clr=uu;
62 | return *this;
63 | }
64 | data_t& data_t::operator=(QColor uu){
65 | t=TypeEnum::COLOR;
66 | clr=uu.rgb();
67 | return *this;
68 | }
69 | data_t& data_t::operator=(cplx cc){
70 | t=TypeEnum::COMPLEX;
71 | c=cc;
72 | return *this;
73 | }
74 |
75 | data_t operator> (data_t d1, data_t d2){return double(d1)>double(d2);}
76 | data_t operator< (data_t d1, data_t d2){return double(d1)=(data_t d1, data_t d2){return double(d1)>=double(d2);}
80 | data_t operator<=(data_t d1, data_t d2){return double(d1)<=double(d2);}
81 |
82 | data_t operator+ (data_t d1, data_t d2){
83 | if(d1.t==TypeEnum::COMPLEX||d2.t==TypeEnum::COMPLEX)
84 | return d1.operator cplx()+d2.operator cplx();
85 | return double(d1)+double(d2);
86 | }
87 | data_t operator- (data_t d1, data_t d2){
88 | if(d1.t==TypeEnum::COMPLEX||d2.t==TypeEnum::COMPLEX)
89 | return d1.operator cplx()-d2.operator cplx();
90 | return double(d1)-double(d2);
91 | }
92 | data_t operator* (data_t d1, data_t d2){
93 | if(d1.t==TypeEnum::COMPLEX||d2.t==TypeEnum::COMPLEX)
94 | return d1.operator cplx()*d2.operator cplx();
95 | return double(d1)*double(d2);
96 | }
97 | data_t operator/ (data_t d1, data_t d2){
98 | if(d1.t==TypeEnum::COMPLEX||d2.t==TypeEnum::COMPLEX)
99 | return d1.operator cplx()/d2.operator cplx();
100 | return double(d1)/double(d2);
101 | }
102 |
103 | data_t data_t::operator-()const{
104 | if(t==TypeEnum::DOUBLE) return -d;
105 | return -c;
106 | }
107 |
108 | data_t data_t::sin()const{
109 | if(t==TypeEnum::DOUBLE)return qSin(d);
110 | return std::sin(c);
111 | }
112 | data_t data_t::cos()const{
113 | if(t==TypeEnum::DOUBLE)return qCos(d);
114 | return std::cos(c);
115 | }
116 | data_t data_t::sqrt()const{
117 | if(t==TypeEnum::DOUBLE)return qSqrt(d);
118 | return std::sqrt(c);
119 | }
120 | data_t pow(data_t d1, data_t d2){
121 | if(d1.t==TypeEnum::COMPLEX||d2.t==TypeEnum::COMPLEX)
122 | return std::pow(d1.c,d2.c);
123 | return qPow(d1.d,d2.d);
124 | }
125 |
126 | data_t data_t::log()const{
127 | if(t==TypeEnum::DOUBLE) return std::log(d);
128 | return std::log(c);
129 | }
130 |
--------------------------------------------------------------------------------
/src/data_t.h:
--------------------------------------------------------------------------------
1 | #ifndef DATA_T_H
2 | #define DATA_T_H
3 |
4 | #include
5 | #include
6 | #include
7 |
8 | enum class TypeEnum{
9 | BOOL=0x1,
10 | DOUBLE=0x2,
11 | COLOR=0x4,
12 | COMPLEX=0x8,
13 | ANY=0xf
14 | };
15 |
16 | typedef std::complex cplx;
17 |
18 | struct data_t{
19 | typedef uint32_t color;
20 | TypeEnum t;
21 | union{
22 | bool b;
23 | double d;
24 | color clr;
25 | cplx c;
26 | };
27 | explicit data_t():t(TypeEnum::ANY){}
28 | data_t(double v):t(TypeEnum::DOUBLE), d(v){}
29 | data_t(bool v):t(TypeEnum::BOOL), b(v){}
30 | data_t(unsigned v):t(TypeEnum::COLOR), clr(v){}
31 | data_t(cplx v):t(TypeEnum::COMPLEX), c(v){}
32 | operator bool()const;
33 | operator double()const;
34 | operator color()const;
35 | operator cplx()const;
36 | data_t& operator=(double dd);
37 | data_t& operator=(bool bb);
38 | data_t& operator=(color uu);
39 | data_t& operator=(QColor uu);
40 | data_t& operator=(cplx cc);
41 | data_t operator-()const;
42 | data_t sin()const;
43 | data_t cos()const;
44 | data_t sqrt()const;
45 | data_t log()const;
46 | friend data_t pow(data_t d1, data_t d2);
47 | friend data_t operator> (data_t d1, data_t d2);
48 | friend data_t operator< (data_t d1, data_t d2);
49 | friend data_t operator==(data_t d1, data_t d2);
50 | friend data_t operator!=(data_t d1, data_t d2);
51 | friend data_t operator>=(data_t d1, data_t d2);
52 | friend data_t operator<=(data_t d1, data_t d2);
53 | friend data_t operator+ (data_t d1, data_t d2);
54 | friend data_t operator- (data_t d1, data_t d2);
55 | friend data_t operator* (data_t d1, data_t d2);
56 | friend data_t operator/ (data_t d1, data_t d2);
57 | };
58 |
59 | #endif // DATA_T_H
60 |
--------------------------------------------------------------------------------
/src/emgc.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bsella/Emergence/fdb8f58545ed708bcd9ce670fe85d4a840ddb965/src/emgc.ico
--------------------------------------------------------------------------------
/src/icons/copy.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bsella/Emergence/fdb8f58545ed708bcd9ce670fe85d4a840ddb965/src/icons/copy.png
--------------------------------------------------------------------------------
/src/icons/cut.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bsella/Emergence/fdb8f58545ed708bcd9ce670fe85d4a840ddb965/src/icons/cut.png
--------------------------------------------------------------------------------
/src/icons/delete.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bsella/Emergence/fdb8f58545ed708bcd9ce670fe85d4a840ddb965/src/icons/delete.png
--------------------------------------------------------------------------------
/src/icons/exit.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bsella/Emergence/fdb8f58545ed708bcd9ce670fe85d4a840ddb965/src/icons/exit.png
--------------------------------------------------------------------------------
/src/icons/export.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bsella/Emergence/fdb8f58545ed708bcd9ce670fe85d4a840ddb965/src/icons/export.png
--------------------------------------------------------------------------------
/src/icons/no_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bsella/Emergence/fdb8f58545ed708bcd9ce670fe85d4a840ddb965/src/icons/no_icon.png
--------------------------------------------------------------------------------
/src/icons/open.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bsella/Emergence/fdb8f58545ed708bcd9ce670fe85d4a840ddb965/src/icons/open.png
--------------------------------------------------------------------------------
/src/icons/paste.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bsella/Emergence/fdb8f58545ed708bcd9ce670fe85d4a840ddb965/src/icons/paste.png
--------------------------------------------------------------------------------
/src/icons/redo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bsella/Emergence/fdb8f58545ed708bcd9ce670fe85d4a840ddb965/src/icons/redo.png
--------------------------------------------------------------------------------
/src/icons/save.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bsella/Emergence/fdb8f58545ed708bcd9ce670fe85d4a840ddb965/src/icons/save.png
--------------------------------------------------------------------------------
/src/icons/undo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bsella/Emergence/fdb8f58545ed708bcd9ce670fe85d4a840ddb965/src/icons/undo.png
--------------------------------------------------------------------------------
/src/main.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include "mainwindow.h"
3 |
4 | int main(int argc, char *argv[]){
5 | QApplication a(argc, argv);
6 | MainWindow w;
7 | w.show();
8 | return a.exec();
9 | }
10 |
--------------------------------------------------------------------------------
/src/mainwindow.cpp:
--------------------------------------------------------------------------------
1 | #include "mainwindow.h"
2 | #include "ui_mainwindow.h"
3 |
4 | #include
5 | #include
6 | #include
7 | #include
8 |
9 | const int MainWindow::_magic_number;
10 | const int MainWindow::_version;
11 | const int MainWindow::_bin_version;
12 | MainWindow::MainWindow(QWidget *parent) :
13 | QMainWindow(parent),
14 | ui(new Ui::MainWindow){
15 |
16 | ui->setupUi(this);
17 |
18 | QWidget::setWindowTitle("Emergence");
19 | QWidget::setWindowIcon(QIcon(":/emgc.ico"));
20 |
21 | ui->workspace->setScene(scene=new Workspace);
22 | ui->workspace->setAcceptDrops(true);
23 | ui->workspace->setDragMode(QGraphicsView::DragMode::RubberBandDrag);
24 |
25 | connect(ui->actionCopy,SIGNAL(triggered(bool)),scene,SLOT(copy()));
26 | connect(ui->actionPaste,SIGNAL(triggered(bool)),scene,SLOT(paste()));
27 | connect(ui->actionCut,SIGNAL(triggered(bool)),scene,SLOT(cut()));
28 | connect(ui->actionDelete,SIGNAL(triggered(bool)),scene,SLOT(delete_selected()));
29 | connect(ui->actionSelect_all,SIGNAL(triggered(bool)),scene,SLOT(select_all()));
30 |
31 | connect(ui->actionUndo,SIGNAL(triggered(bool)),&scene->undoStack,SLOT(undo()));
32 | connect(ui->actionRedo,SIGNAL(triggered(bool)),&scene->undoStack,SLOT(redo()));
33 | ui->actionUndo->setEnabled(false); ui->actionRedo->setEnabled(false);
34 | connect(&scene->undoStack,SIGNAL(canUndoChanged(bool)),ui->actionUndo,SLOT(setEnabled(bool)));
35 | connect(&scene->undoStack,SIGNAL(canRedoChanged(bool)),ui->actionRedo,SLOT(setEnabled(bool)));
36 |
37 | // connect(scene,SIGNAL(selectionChanged()),this,SLOT(updateActions()));
38 | // updateActions();
39 | // ui->actionPaste->setEnabled(QApplication::clipboard()->mimeData()->text()=="Emergence_Nodes");
40 | // connect(ui->actionCopy,SIGNAL(triggered(bool)),ui->actionPaste,SLOT(setDisabled(bool)));
41 | zoomIN.setShortcut(QKeySequence::ZoomIn);
42 | zoomOUT.setShortcut(QKeySequence::ZoomOut);
43 | connect(&zoomIN,SIGNAL(triggered(bool)),this,SLOT(zoomIn()));
44 | connect(&zoomOUT,SIGNAL(triggered(bool)),this,SLOT(zoomOut()));
45 | addAction(&zoomIN);
46 | addAction(&zoomOUT);
47 | pluginManager= new PluginManager(ui);
48 | if(!pluginManager->loadPlugins()){
49 | ui->menuInsert->setEnabled(false);
50 | delete ui->toolboxDock;
51 | }
52 | connect(&scene->undoStack,SIGNAL(indexChanged(int)),this,SLOT(updateModified()));
53 | connect(&scene->undoStack,SIGNAL(cleanChanged(bool)),this,SLOT(updateModified()));
54 | }
55 |
56 | MainWindow::~MainWindow(){
57 | delete ui;
58 | }
59 | void MainWindow::zoomIn()const{
60 | ui->workspace->scale(Workspace::scaleFactor,Workspace::scaleFactor);
61 | }
62 | void MainWindow::zoomOut()const{
63 | ui->workspace->scale(1/Workspace::scaleFactor,1/Workspace::scaleFactor);
64 | }
65 |
66 | bool MainWindow::on_actionSave_triggered(){
67 | if(_filePath=="")
68 | return on_actionSave_as_triggered();
69 | std::ofstream ofs(_filePath.toStdString());
70 |
71 | if(_filePath.endsWith(".ebin")){
72 | ofs.write(reinterpret_cast(&_magic_number),sizeof(uint));
73 | ofs.write(reinterpret_cast(&_bin_version),sizeof(uint));
74 | pluginManager->toBin(ofs);
75 | scene->toBin(ofs);
76 | }else{
77 | ofs << _version << '\n';
78 | pluginManager->toText(ofs);
79 | scene->toText(ofs);
80 | }
81 | ofs.close();
82 |
83 | scene->undoStack.setClean();
84 | return true;
85 | }
86 | bool MainWindow::on_actionSave_as_triggered(){
87 | QString fileName= QFileDialog::getSaveFileName(ui->workspace,"Save as...",".","Emergence Files (*.e *.ebin)");
88 | if(fileName.isEmpty()) return false;
89 | if(!fileName.endsWith(".e") && !fileName.endsWith(".ebin"))
90 | fileName.append(".ebin");
91 | _filePath=fileName;
92 | return on_actionSave_triggered();
93 | }
94 | void MainWindow::on_actionOpen_triggered(){
95 | QString fileName= QFileDialog::getOpenFileName(parentWidget(),"Open File",".","Emergence Files (*.e *.ebin)");
96 | if(fileName.isNull()) return;
97 |
98 | switch (areYouSure()) {
99 | case QMessageBox::Yes:
100 | if(!on_actionSave_triggered()) return;
101 | break;
102 | case QMessageBox::No:break;
103 | case QMessageBox::Cancel:return;
104 | default:break;
105 | }
106 |
107 | scene->select_all();
108 | scene->undoStack.beginMacro("load");
109 | scene->delete_selected();
110 |
111 | std::ifstream ifs(fileName.toStdString());
112 | int tmp;
113 | if(fileName.endsWith(".e")){
114 | ifs >> tmp;
115 | if(tmp<_version){
116 | QMessageBox::warning(0,"Wrong version","Sorry, this save file is too old.");
117 | ifs.close();
118 | return;
119 | }
120 | pluginManager->fromText(ifs);
121 | scene->fromText(ifs);
122 | }else{
123 | ifs.read(reinterpret_cast(&tmp),sizeof(uint));
124 | if(tmp!=_magic_number){
125 | QMessageBox::warning(0,"Wrong format","Bad File Format");
126 | ifs.close();
127 | return;
128 | }
129 | ifs.read(reinterpret_cast(&tmp),sizeof(uint));
130 | if(tmp<_bin_version){
131 | QMessageBox::warning(0,"Wrong version","Sorry, this save file is too old.");
132 | ifs.close();
133 | return;
134 | }
135 | pluginManager->fromBin(ifs);
136 | scene->fromBin(ifs);
137 | }
138 |
139 | scene->undoStack.endMacro();
140 | scene->clearSelection();
141 | ifs.close();
142 | _filePath=fileName;
143 | scene->undoStack.setClean();
144 | }
145 |
146 | void MainWindow::updateModified(){
147 | fileModified=!scene->undoStack.isClean();
148 | QString title = "Emergence";
149 | if(_filePath!="")
150 | title+=" - "+_filePath.split('/').back();
151 | if(fileModified)
152 | title+="*";
153 | setWindowTitle(title);
154 | }
155 |
156 | void MainWindow::on_actionNew_triggered(){
157 | switch (areYouSure()) {
158 | case QMessageBox::Yes:
159 | if(!on_actionSave_triggered()) return;
160 | break;
161 | case QMessageBox::No:break;
162 | case QMessageBox::Cancel:return;
163 | default:break;
164 | }
165 | scene->undoStack.clear();
166 | scene->undoStack.setClean();
167 | _filePath="";
168 | updateModified();
169 | }
170 |
171 | void MainWindow::on_actionExit_triggered(){
172 | close();
173 | }
174 | int MainWindow::areYouSure(){
175 | if(fileModified){
176 | return QMessageBox::question(this,"Save changes",
177 | "Save changes to "+_filePath+" before closing?",
178 | (QMessageBox::Yes|QMessageBox::No|QMessageBox::Cancel));
179 | }
180 | return QMessageBox::No;
181 | }
182 | void MainWindow::closeEvent(QCloseEvent*event){
183 | switch (areYouSure()){
184 | case QMessageBox::Yes:
185 | if(!on_actionSave_triggered())
186 | event->ignore();
187 | break;
188 | case QMessageBox::No:break;
189 | case QMessageBox::Cancel:
190 | event->ignore();
191 | break;
192 | default:
193 | break;
194 | }
195 | }
196 | //void MainWindow::updateActions(){
197 | // ui->actionExport->setEnabled(false);
198 | // bool someNodeIsSelected=false;
199 | // for(auto& n: scene->selectedItems()){
200 | // if(((Node*)n)->id!=Node::OUTPUT_G &&((Node*)n)->id!=Node::INPUT_G)
201 | // someNodeIsSelected=true;
202 | // if(((Node*)n)->id==Node::RENDER_G){
203 | // ui->actionExport->setEnabled(true);
204 | // break;
205 | // }
206 | // }
207 | // ui->actionCut->setEnabled(someNodeIsSelected);
208 | // ui->actionCopy->setEnabled(someNodeIsSelected);
209 | // ui->actionDelete->setEnabled(someNodeIsSelected);
210 | //}
211 |
--------------------------------------------------------------------------------
/src/mainwindow.h:
--------------------------------------------------------------------------------
1 | #ifndef MAINWINDOW_H
2 | #define MAINWINDOW_H
3 |
4 | #include
5 |
6 | #include "Workspace.h"
7 | #include "PluginManager.h"
8 |
9 | namespace Ui {
10 | class MainWindow;
11 | }
12 |
13 | class MainWindow : public QMainWindow{
14 | Q_OBJECT
15 |
16 | public:
17 | explicit MainWindow(QWidget *parent = 0);
18 | ~MainWindow();
19 | Ui::MainWindow *ui;
20 | private:
21 | static const int _magic_number=0xa1b2affd;
22 | static const int _version=6;
23 | static const int _bin_version=0;
24 | Workspace* scene;
25 | PluginManager *pluginManager;
26 | QAction zoomIN, zoomOUT;
27 | QString _filePath="";
28 | bool fileModified=false;
29 | void closeEvent(QCloseEvent*)override;
30 | int areYouSure();
31 | private slots:
32 | // void updateActions();
33 | void zoomIn()const;
34 | void zoomOut()const;
35 | void updateModified();
36 |
37 | void on_actionNew_triggered();
38 | void on_actionOpen_triggered();
39 | bool on_actionSave_triggered();
40 | bool on_actionSave_as_triggered();
41 | void on_actionExit_triggered();
42 | };
43 |
44 | #endif // MAINWINDOW_H
45 |
--------------------------------------------------------------------------------
/src/mainwindow.ui:
--------------------------------------------------------------------------------
1 |
2 |
3 | MainWindow
4 |
5 |
6 |
7 | 0
8 | 0
9 | 641
10 | 493
11 |
12 |
13 |
14 | MainWindow
15 |
16 |
17 |
18 | -
19 |
20 |
21 |
22 |
23 |
72 |
73 |
74 |
75 | 190
76 | 237
77 |
78 |
79 |
80 | false
81 |
82 |
83 | QDockWidget::DockWidgetFloatable|QDockWidget::DockWidgetMovable
84 |
85 |
86 | Toolbox
87 |
88 |
89 | 1
90 |
91 |
92 |
93 |
94 | QLayout::SetMinimumSize
95 |
96 |
97 | 2
98 |
99 |
100 | 0
101 |
102 |
103 | 0
104 |
105 |
106 | 0
107 |
108 | -
109 |
110 |
111 | -1
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 | :/icons/exit.png:/icons/exit.png
122 |
123 |
124 | Exit
125 |
126 |
127 | Ctrl+Q
128 |
129 |
130 |
131 |
132 | Save As...
133 |
134 |
135 | Ctrl+Shift+S
136 |
137 |
138 |
139 |
140 |
141 | :/icons/open.png:/icons/open.png
142 |
143 |
144 | Open
145 |
146 |
147 | Ctrl+O
148 |
149 |
150 |
151 |
152 |
153 | :/icons/undo.png:/icons/undo.png
154 |
155 |
156 | Undo
157 |
158 |
159 | Ctrl+Z
160 |
161 |
162 |
163 |
164 |
165 | :/icons/redo.png:/icons/redo.png
166 |
167 |
168 | Redo
169 |
170 |
171 | Ctrl+Shift+Z
172 |
173 |
174 |
175 |
176 |
177 | :/icons/cut.png:/icons/cut.png
178 |
179 |
180 | Cut
181 |
182 |
183 | Ctrl+X
184 |
185 |
186 |
187 |
188 |
189 | :/icons/copy.png:/icons/copy.png
190 |
191 |
192 | Copy
193 |
194 |
195 | Ctrl+C
196 |
197 |
198 |
199 |
200 |
201 | :/icons/paste.png:/icons/paste.png
202 |
203 |
204 | Paste
205 |
206 |
207 | Ctrl+V
208 |
209 |
210 |
211 |
212 |
213 | :/icons/delete.png:/icons/delete.png
214 |
215 |
216 | Delete
217 |
218 |
219 | Del
220 |
221 |
222 |
223 |
224 | Select All
225 |
226 |
227 | Ctrl+A
228 |
229 |
230 |
231 |
232 |
233 | :/icons/save.png:/icons/save.png
234 |
235 |
236 | Save
237 |
238 |
239 | Ctrl+S
240 |
241 |
242 |
243 |
244 | New
245 |
246 |
247 | Ctrl+N
248 |
249 |
250 |
251 |
252 |
253 |
254 | NodeBox
255 | QWidget
256 |
257 | 1
258 |
259 |
260 |
261 | workspace
262 |
263 |
264 |
265 |
266 |
267 |
268 |
--------------------------------------------------------------------------------
/src/signalManager.h:
--------------------------------------------------------------------------------
1 | #ifndef SIGNALMANAGER_H
2 | #define SIGNALMANAGER_H
3 |
4 | #include
5 |
6 | class SignalManager: public QObject{
7 | Q_OBJECT
8 | public:
9 | SignalManager(){}
10 | ~SignalManager(){}
11 | signals:
12 | void updateRatio();
13 | void updateOutputs();
14 | void nbArgChanged(void*,uint);
15 | };
16 |
17 | #endif // SIGNALMANAGER_H
18 |
--------------------------------------------------------------------------------
/src/src.qrc:
--------------------------------------------------------------------------------
1 |
2 |
3 | emgc.ico
4 | icons/copy.png
5 | icons/cut.png
6 | icons/delete.png
7 | icons/exit.png
8 | icons/export.png
9 | icons/no_icon.png
10 | icons/open.png
11 | icons/paste.png
12 | icons/redo.png
13 | icons/save.png
14 | icons/undo.png
15 |
16 |
17 |
--------------------------------------------------------------------------------