]> git.llucax.com Git - z.facultad/75.42/plaqui.git/blob - Constructor/include/item.h
-pregunta si quiere guardar antes de salir, solo si no estaba guardado
[z.facultad/75.42/plaqui.git] / Constructor / include / item.h
1 #ifndef _ITEM_H_
2 #define _ITEM_H_
3
4 #include <iostream>
5 #include <gtkmm/drawingarea.h>
6 #include <gtkmm/spinbutton.h>
7 #include <gtkmm/stock.h>
8 #include <gtkmm.h>
9 #include <gdkmm.h>
10 #include <libglademm.h>
11 #include <gtkmm/entry.h>
12 #include "itemptywnd.h"
13 #include "workplace.h"
14
15 ///Tipo de estado en el que pueden estar los conectores de un item
16 typedef enum { UNDEF, IN, OUT } ConnectorType;
17
18 ///Tipo que indica que conector de alguna compuerta esta conectado con algun item. Usado para cargar el XML.
19 typedef struct {
20         ConnectorType type;
21         Glib::ustring name_dest;
22         int cistern_connector;
23 }t_logic_connector;
24
25 ///Clase que define un conector del item
26 class Connector {
27         public: 
28                 ///Numero que identifica con quien esta conectado
29                 int id_dest;
30                 ///Tipo de conector
31                 ConnectorType type;
32                 ///Sobrecarga del operador = para poder realizar asignaciones entre dos instancias de Connector
33                 Connector& operator= (Connector & c) {
34                         id_dest = c.id_dest;
35                         type = c.type;
36                         return *this;
37                 }
38 };
39
40 /**
41  * Clase padre de todos los items que puedan aparecer.
42  * En esta clase están definidos todos los comportamientos en común
43  * y en algunos casos hay funciones abstractas para que cada item
44  * defina su propio comportamiento.
45  * Comportamientos comunes que se definen son, por ejemplo,
46  * items de la aplicación, como puede ser la imagen 
47  * actual, la posición en la grilla, el caudal máximo,el 
48  * número único de identificación y diferentes punteros a 
49  * otros objetos.
50  * 
51  * Por cuestiones de diseño los elementos de la planta 
52  * además de tener un número único que los identifica, 
53  * también deben tener nombres difrerentes.
54  * 
55  * También esta definida en esta clase la estuctura que 
56  * representa los conectores físicos, y otra que 
57  * representa a los conectores lógicos.
58  * 
59  * Esta clase contiene métodos abstractos ya que cualquier 
60  * elemento que descienda de ella debería poder implementar 
61  * los mismos porque, por ejemplo, ningún item se guarda 
62  * en un archivo de la misma manera; este es el caso del 
63  * método save().
64  * 
65  * Existe otro método abstracto dentro de esta clase que 
66  * es check_connection(). Del mismo modo que un item se 
67  * guarda de forma diferente que otro, también verifica su 
68  * conexión de distinta forma, es por eso que cada item 
69  * debe implementar su manera de verificar como y con 
70  * quién está conectado.
71  * 
72  * Al ser esta clase abstracta, no puede ser instanciada, 
73  * con lo cual existiría una clase derivada de esta para 
74  * cada item que se quiera agregar en la aplicación.
75 */
76
77 class CItem:public Gtk::DrawingArea {
78 public:
79         ///Constructor
80         CItem();
81
82         ///Constructor, crea el item indicando cual es la imagen que le corresponde
83         CItem(const char *filename);
84         ///Destructor
85         virtual ~CItem();
86         
87         
88         virtual void on_realize();
89
90         ///Dibuja el item cada vez que este evento es llamado por la ventana que lo contiene.
91         virtual bool on_expose_event(GdkEventExpose* event);
92
93         ///Muestra la ventana de propiedades al seleccionarse la opcion en el menu flotante.
94         virtual void on_menu_popup_propiedades();
95         
96         ///Rota el item al seleccionarse la opcion en el menu flotante
97         virtual void on_menu_popup_rotar();
98         
99         ///Elimina el Item al seleccionarse la opcion en el menu flotante
100         virtual void on_menu_popup_eliminar();
101                 
102         ///Retorna un puntero a la imagen actual.
103         Glib::RefPtr<Gdk::Pixbuf> get_image() { return image; }
104         
105         ///Funciones para setear y obtener los atributos privados
106         int get_position_x();
107         int get_position_y();
108         int get_id();
109         int get_img_actual();
110         double get_caudal();
111         Glib::ustring get_name();
112         Glib::ustring get_other_name(int _id);
113         void set_position(int _x, int _y);
114         void set_id(int _id);
115         void set_caudal(double _caudal);
116         void set_name(Glib::ustring _name);
117         
118         ///Retorna true si las coordenadas (_a, _b) pertenecen a otro item que ya fue colocado en el area de trabajo
119         bool is_occupied_area(int _a, int _b);
120         
121         ///Devuelve el tipo de conector de el item que este en (_a, _b) y un puntero a este. Devolvera UNDEF si no hay nada. 
122         ConnectorType is_other_connection_area(int _a, int _b, CItem ** _item);
123         
124         /**Funcion abstracta que debe ser redefinida en cada clase descendiente. 
125           * Cada clase descendiente debe implementar su manera de guardarse en 
126           * en el archivo que se pasa por parametro.
127         */
128         virtual void save(FILE *archivo) = 0;
129         
130         /**
131          * Verifica que el ítem esté bien conectado.
132          * Las clases que heredan de CItem son las siguientes:
133          *
134          *      -# Conduct: representa un tubo.
135          *              
136          *      -# Splitter: representa un codo.
137          *              
138          *      -# Union: representa un empalme ( UNION ó DIVISION).
139          *      
140          *      -# Cistern: representa un tanque,
141          *      
142          *      -# Exclusa: representa una exclusa.
143          *      
144          *      -# Drain: representa un drenaje.
145          *      
146          *      -# Pump: representa una bomba.
147          *      
148          *      Para las clases Conduct, Splitter y Exclusa, este 
149          *      método es bastante similar, sobre todo teniendo en 
150          *      cuenta que una exclusa es un tubo con una propiedad mas 
151          *      (abierto/cerrado) y el codo es un tubo que en la 
152          *      aplicación representa un curva.
153          *      
154          *      Estos tres elementos tienen la particularidad que sus 
155          *      conectores físicos no estan definidos en el momento de 
156          *      su creación, sino que se definen una vez que pertenecen 
157          *      a un circuito.
158          *      
159          *      La verificación se realiza recorriendo la lista de 
160          *      items y preguntandole a cada uno que posee en sus extremos.
161          *      
162          *      El tanque, la bomba, el empalme y el drenaje, tiene 
163          *      definidos sus conectores en el momento de la creación.
164          *      
165          *      Supongamos que el circuito es el siguiente:
166          *       \image html check_connection.png
167          *       \image latex check_connection.eps "Planta de ejemplo." width=10cm
168          *       
169          *      Donde \c bomba0 y \c tubo0 son los de la izquiera y \c bomba1 y 
170          *      \c tubo1 son los de la derecha, para poder diferenciarlos.
171          *      Cabe aclarar que no importa con cual de los items se 
172          *      comience la iteración.
173          *      Según la imagen actual de la \c bomba0, este debe 
174          *      preguntar con quién esta conectado en su salida pero ya 
175          *      sabe, por ser bomba que tendrá una salida, luego el 
176          *      \c tubo0 que en ese momento no esta definido, debe 
177          *      averiguar como definirse, para hacerlo pregunta en su 
178          *      otro extremo el cual esta conectado con una unión, que 
179          *      por ser unión posee dos entradas (horizontales en este 
180          *      caso) y una salida (vertical). La unión le responde que 
181          *      posee una entrada, por lo tanto el extremo derecho del 
182          *      tubo será una salida, lo cual implica que el extremo 
183          *      izquierdo tiene que ser una entrada, y esto es 
184          *      compatible con la bomba. De esta forma la \c bomba0 y el 
185          *      \c tubo0 se setean sus conectores y se establecen como \e conectados.
186          *
187          *      Continuando con la iteración, es el turno del \c tubo0 
188          *      (por el orden de incersión en la lista), pero este ya 
189          *      está conectado, por lo tanto no se realizan verificaciones.
190          *      
191          *      Lo mismo ocurre del lado derecho del circuito con la 
192          *      \c bomba1 y el \c tubo1.
193          *      
194          *      Algo similar ocurre cuando la unión pregunta que tiene 
195          *      en su salida, la exclusa debe preguntarle al tanque y 
196          *      este le responderá que posee una entrada, luego la 
197          *      exculsa tendrá una entrada en el extremo superior y una 
198          *      salida en el inferior; nuevamente el circuito es 
199          *      compatible. Por último el tanque le solicita al codo 
200          *      que le informe su estado y el proceso se repite con el 
201          *      drenaje que posee solamente una salida.
202          *      
203          *      Así todos los elementos han quedado conectados y 
204          *      conocen también con quién o quienes lo estén.
205          */
206         virtual bool check_connection()=0;
207         
208         ///Setea los conectores en su estado inicial.
209         virtual void set_default_connector();   
210         
211         ///Devuelve el tipo de conector que tiene el item en la posicion (_a,_b).
212         virtual ConnectorType get_connector_type( int _a, int _b );
213         
214         /**Devuelve en _a y _b la posicion de los conectores logicos del item segun su posicion.
215         */
216         virtual void get_in_logic_connect_position(int& _a, int& _b);
217         virtual void get_out_logic_connect_position(int& _a, int& _b);
218         
219         /**Actualiza las posiciones de los conectores ante un movimiento o rotacion del item.
220         */
221         virtual void update_logic_position();
222         
223         /**Funciones para no permitir mas de una conexion a la salida de las compuertas.
224           *En el caso de la compuerta NOT, tampoco puede tener mas de una conexion 
225           *a la entrada.          
226         */
227         virtual void set_out_connected(bool _o);
228         virtual void set_in_connected(bool _o);
229         
230         virtual bool get_out_logic_connect();
231         /**Dibuja los conectores logicos del Item, AZUL == SALIDA, ROJO == ENTRADA.
232         */
233         virtual void draw_connectors();
234         
235         ///Puntero al area de trabajo de la ventana principal
236         WorkPlace *workplace;
237         
238         ///Puntero al cuadro de texto de la ventana principal
239         Gtk::Combo *combo_entry;
240         
241         ///Puntero a la barra de estado
242         Gtk::Statusbar *status_bar;
243         
244         ///Puntero a la lista de items
245         std::list<CItem *> *listaItems;
246         
247         ///Puntero a la lista de Items logicos
248         std::list<CItem *> *lista_logic_Items;
249         
250         ///TODO poner esto en Union y crear una ventana nueva de propiedades
251         bool is_union;
252         
253         ///indica si el item ya esta conectado con sus conectores bien definidos
254         bool is_connected;
255         
256         ///Indica si es una compuerta logica
257         bool is_logic;
258         
259         ///Indica si puede realizarse la conexion logica con una compuerta
260         static bool logic_connect;
261         
262         ///Almacena el ID de la compuerta logica seleccionada
263         static int gate_id;
264         
265         /**Vector de connectores donde se mantiene la siguiente referencia:
266          * indice 0 = "arriba/izquierda" para la exclusa, el tubo, el codo, el empalme y el tanque.
267          *                                      "derecha" para la bomba.
268          *                                      es unico para el drenaje.
269          * indice 1 = "abajo/derecha" para la exclusa, el tubo, el codo, el empalme y el tanque.
270          *                                      "izquierda" para el tanque
271          * indice 2 = "medio" para el empalme.
272          *La referencia se toma para las imagenes iniciales en el orden izquierda-derecha-medio, 
273          *excepto el tanque que seria derecha-izquierda.
274          */                                                             
275         std::vector<Connector> connect_vec;
276
277         void set_img_actual(int i) { imgActual = i; }
278         
279         ///Puntero al cuadro de texo de la ventana principal.
280         std::list<Glib::ustring> *list_pointed;
281 protected:
282         ///Indica el numero que le corresponde a la imagen actual del item.
283         int imgActual;
284
285         ///Numero "unico" que identifica al item.
286         int ID;
287
288         Glib::RefPtr<Gdk::GC> gc;
289
290         Gdk::Color blue, red;
291
292         ///Nombre del item
293         Glib::ustring name;
294         
295         ///Caudal maximo que puede contener un item.
296         double caudal_max;
297         
298         ///Menu flotante del item
299         Gtk::Menu menu_popup;
300         
301         ///Lista de opciones del menu flotante
302         Gtk::Menu::MenuList menulist;
303         
304         ///Imagenes del menu flotante
305         Gtk::Image menu_image_delete, menu_image_rotar, menu_image_propiedades, menu_image_linea;
306         
307         ///Puntero a la imagen del item
308         Glib::RefPtr<Gdk::Pixbuf> image;
309         
310         ///Puntero a la ventana de propiedades del item
311         ItemPtyWnd *property_wnd;
312
313         ///Posicion del item en el area de trabajo
314         int x, y;
315         
316         ///Posicion de los conectores logicos.
317         int in_x, in_y, out_x, out_y;
318 };
319
320 #endif