5 #include <gtkmm/drawingarea.h>
6 #include <gtkmm/spinbutton.h>
7 #include <gtkmm/stock.h>
10 #include <libglademm.h>
11 #include <gtkmm/entry.h>
12 #include "itemptywnd.h"
13 #include "workplace.h"
15 ///Tipo de estado en el que pueden estar los conectores de un item
16 typedef enum { UNDEF, IN, OUT } ConnectorType;
18 ///Tipo que indica que conector de alguna compuerta esta conectado con algun item. Usado para cargar el XML.
21 Glib::ustring name_dest;
22 int cistern_connector;
25 ///Clase que define un conector del item
28 ///Numero que identifica con quien esta conectado
32 ///Sobrecarga del operador = para poder realizar asignaciones entre dos instancias de Connector
33 Connector& operator= (Connector & c) {
40 /**Esta es la clase padre de todos los items que puedan aparecer
41 *Aca estan definidos todos los comportamientos en comun y en
42 *algunos casos hay funciones abstractas para que cada item defina
43 * su propio comportamiento.
45 /**Acá se definen los comportamientos comunes de todo los
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
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.
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.
59 * Esta clase contiene métodos abstractos ya que cualquier
60 * elemento que descienda de ella deberá 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( FILE archivo).
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 esta conectado.
72 * Al ser esta clase abstracta, no puede ser instanciada,
73 * con lo cual existirá una clase derivada de esta para
74 * cada item que se quiera agregar en la aplicación.
77 class CItem:public Gtk::DrawingArea {
82 ///Constructor, crea el item indicando cual es la imagen que le corresponde
83 CItem(const char *filename);
88 virtual void on_realize();
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);
93 ///Muestra la ventana de propiedades al seleccionarse la opcion en el menu flotante.
94 virtual void on_menu_popup_propiedades();
96 ///Rota el item al seleccionarse la opcion en el menu flotante
97 virtual void on_menu_popup_rotar();
99 ///Elimina el Item al seleccionarse la opcion en el menu flotante
100 virtual void on_menu_popup_eliminar();
102 ///Retorna un puntero a la imagen actual.
103 Glib::RefPtr<Gdk::Pixbuf> get_image() { return image; }
105 ///Funciones para setear y obtener los atributos privados
106 int get_position_x();
107 int get_position_y();
109 int get_img_actual();
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);
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);
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);
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.
128 virtual void save(FILE *archivo) = 0;
130 /**Funcion abstracta que debe ser implementada en las clases descendientes
131 * ya que cada item verifica sus conexione de manera difenrente y todos deben
134 /**Las clases que heredan de CItem son las siguientes:
136 * 1. Conduct: representa un tubo.
138 * 2. Splitter: representa un codo.
140 * 3. Union: representa un empalme ( UNION ó DIVISION).
142 * 4. Cistern: representa un tanque,
144 * 5. Exclusa: representa una exclusa.
146 * 6. Drain: representa un drenaje.
148 * 7. Pump: representa una bomba.
150 * Para las clases Conduct, Splitter y Exclusa, este
151 * método es bastante similar, sobre todo teniendo en
152 * cuenta que una exclusa es un tubo con una propiedad mas
153 * (abierto/cerrado) y el codo es un tubo que en la
154 * aplicación representa un curva.
156 * Estos tres elementos tienen la particularidad que sus
157 * conectores físicos no estan definidos en el momento de
158 * su creación, sino que se definen una vez que pertenecen
161 * La verificación se realiza recorriendo la lista de
162 * items y preguntandole a cada uno que posee en sus extremos.
164 * El tanque, la bomba, el empalme y el drenaje, tiene
165 * definidos sus conectores en el momento de la creación.
167 * Supongamos que el circuito es el siguiente:
168 * \image html ckeck_connection.png
170 * Donde bomba0 y tubo0 son los de la izquiera y bomba1 y
171 * tubo1 son los de la derecha, para poder diferenciarlos.
172 * Cabe aclarar que no importa con cual de los items se
173 * comience la iteración.
174 * Según la imagen actual de la bomba0, este debe
175 * preguntar con quién esta conectado en su salida pero ya
176 * sabe, por ser bomba que tendrá una salida, luego el
177 * tubo0 que en ese momento no esta definido, debe
178 * averiguar como definirse, para hacerlo pregunta en su
179 * otro extremo el cual esta conectado con una unión, que
180 * por ser unión posee dos entradas (horizontales en este
181 * caso) y una salida (vertical). La unión le responde que
182 * posee una entrada, por lo tanto el extremo derecho del
183 * tubo será una salida, lo cual implica que el extremo
184 * izquierdo tiene que ser una entrada, y esto es
185 * compatible con la bomba. De esta forma la bomba0 y el
186 * tubo0 se setean sus conectores y se establecen como "conectados".
187 * Continuando con la iteración, es el turno del tubo0
188 * (por el orden de incersión en la lista), pero este ya
189 * está conectado, por lo tanto no se realizan verificaciones.
191 * Lo mismo ocurre del lado derecho del circuito con la
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.
203 * Así todos los elementos han quedado conectados y
204 * conocen también con quién o quienes lo están.
206 virtual bool check_connection()=0;
208 ///Setea los conectores en su estado inicial.
209 virtual void set_default_connector();
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 );
214 /**Devuelve en _a y _b la posicion de los conectores logicos del item segun su posicion.
216 virtual void get_in_logic_connect_position(int& _a, int& _b);
217 virtual void get_out_logic_connect_position(int& _a, int& _b);
219 /**Actualiza las posiciones de los conectores ante un movimiento o rotacion del item.
221 virtual void update_logic_position();
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
227 virtual void set_out_connected(bool _o);
228 virtual void set_in_connected(bool _o);
230 virtual bool get_out_logic_connect();
231 /**Dibuja los conectores logicos del Item, AZUL == SALIDA, ROJO == ENTRADA.
233 virtual void draw_connectors();
235 ///Puntero al area de trabajo de la ventana principal
236 WorkPlace *workplace;
238 ///Puntero al cuadro de texto de la ventana principal
239 Gtk::Combo *combo_entry;
241 ///Puntero a la barra de estado
242 Gtk::Statusbar *status_bar;
244 ///Puntero a la lista de items
245 std::list<CItem *> *listaItems;
247 ///Puntero a la lista de Items logicos
248 std::list<CItem *> *lista_logic_Items;
250 ///TODO poner esto en Union y crear una ventana nueva de propiedades
253 ///indica si el item ya esta conectado con sus conectores bien definidos
256 ///Indica si es una compuerta logica
259 ///Indica si puede realizarse la conexion logica con una compuerta
260 static bool logic_connect;
262 ///Almacena el ID de la compuerta logica seleccionada
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.
275 std::vector<Connector> connect_vec;
277 void set_img_actual(int i) { imgActual = i; }
279 ///Puntero al cuadro de texo de la ventana principal.
280 std::list<Glib::ustring> *list_pointed;
282 ///Indica el numero que le corresponde a la imagen actual del item.
285 ///Numero "unico" que identifica al item.
288 Glib::RefPtr<Gdk::GC> gc;
290 Gdk::Color blue, red;
295 ///Caudal maximo que puede contener un item.
298 ///Menu flotante del item
299 Gtk::Menu menu_popup;
301 ///Lista de opciones del menu flotante
302 Gtk::Menu::MenuList menulist;
304 ///Imagenes del menu flotante
305 Gtk::Image menu_image_delete, menu_image_rotar, menu_image_propiedades, menu_image_linea;
307 ///Puntero a la imagen del item
308 Glib::RefPtr<Gdk::Pixbuf> image;
310 ///Puntero a la ventana de propiedades del item
311 ItemPtyWnd *property_wnd;
313 ///Posicion del item en el area de trabajo
316 ///Posicion de los conectores logicos.
317 int in_x, in_y, out_x, out_y;