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) {
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
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í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
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.
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.
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;
131 * Verifica que el ítem esté bien conectado.
132 * Las clases que heredan de CItem son las siguientes:
134 * -# Conduct: representa un tubo.
136 * -# Splitter: representa un codo.
138 * -# Union: representa un empalme ( UNION ó DIVISION).
140 * -# Cistern: representa un tanque,
142 * -# Exclusa: representa una exclusa.
144 * -# Drain: representa un drenaje.
146 * -# Pump: representa una bomba.
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.
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
159 * La verificación se realiza recorriendo la lista de
160 * items y preguntandole a cada uno que posee en sus extremos.
162 * El tanque, la bomba, el empalme y el drenaje, tiene
163 * definidos sus conectores en el momento de la creación.
165 * Supongamos que el circuito es el siguiente:
166 * \image html ckeck_connection.png
167 * \image latex ckeck_connection.eps "Planta de ejemplo." width=10cm
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 * tubo0 se setean sus conectores y se establecen como \e conectados.
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.
191 * Lo mismo ocurre del lado derecho del circuito con la
192 * \c bomba1 y el \c tubo1.
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;