#include #include #include #include #include #include using namespace std; /* ------------------------------------------------------------------------ A efectos de simplicidad, la definición de las clases, la definición de sus funciones miembro y el programa principal se mantienen en un único fichero. Sin embargo, no hay que olvidar que, en general, lo correcto es dividirlo en módulos y ficheros. ------------------------------------------------------------------------ */ class Fl_EuroConv : public Fl_Group { public: Fl_EuroConv(int x, int y, const char *nombreMoneda, float factor); private: Fl_Value_Input *viMoneda, *viEuro; private: float valorEuro; string *labelMoneda; private: static void convertirAEuros_cb(Fl_Widget *w, void *datos=NULL); static void convertirDeEuros_cb(Fl_Widget *w, void *datos=NULL); }; Fl_EuroConv::Fl_EuroConv(int x, int y, const char *nombreMoneda, float factor) : Fl_Group(x,y,200,70), valorEuro(factor) { // Añadir ":" al final del nombre de la moneda labelMoneda = new string(nombreMoneda); (*labelMoneda)+=string(":"); viMoneda= new Fl_Value_Input(x,y,100,35,labelMoneda->c_str()); viEuro = new Fl_Value_Input(x,y+50,100,35,"Euros:"); end(); viMoneda->callback(convertirAEuros_cb); viEuro->callback(convertirDeEuros_cb); } void Fl_EuroConv::convertirAEuros_cb(Fl_Widget *w, void *datos) { Fl_EuroConv *v = (Fl_EuroConv *) w->parent(); float euros = v->viMoneda->value() / v->valorEuro; v->viEuro->value(euros); } void Fl_EuroConv::convertirDeEuros_cb(Fl_Widget *w, void *datos) { Fl_EuroConv *v = (Fl_EuroConv *) w->parent(); float euros = v->viEuro->value() * v->valorEuro; v->viMoneda->value(euros); } class VentanaPrueba : public Fl_Window { public: VentanaPrueba(int x, int y); private: Fl_EuroConv *pesetas; Fl_EuroConv *marcosAlemanes; Fl_EuroConv *liras; Fl_EuroConv *marcosFinlandeses; Fl_Button *btSalir; private: static void salir_cb(Fl_Widget *w, void *datos=NULL); }; VentanaPrueba::VentanaPrueba(int x, int y) : Fl_Window(x,y,500,300) { int margenX, margenY; margenX = margenY = 50; Fl_EuroConv *pesetas = new Fl_EuroConv(90,10,"Pesetas",166.386); Fl_EuroConv *marcosAlemanes = new Fl_EuroConv(pesetas->x()+pesetas->w()+margenX,10,"Marco alemán",1.95583); Fl_EuroConv *liras = new Fl_EuroConv(pesetas->x(),pesetas->y()+pesetas->h()+margenY,"Lira italiana",1936.27); Fl_EuroConv *marcosFinlandeses = new Fl_EuroConv(marcosAlemanes->x(),marcosAlemanes->y()+marcosAlemanes->h()+margenY,"Marcos finlandeses",5.94573); btSalir = new Fl_Button(200,240,80,35,"&Terminar"); btSalir->callback(salir_cb); end(); } void VentanaPrueba::salir_cb(Fl_Widget *w, void *datos) { VentanaPrueba *v = (VentanaPrueba *) w->parent(); v->hide(); } int main() { VentanaPrueba v(350,10); v.show(); return Fl::run(); } /* ******************************************************** Algunas preguntas (son sencillas): - ¿Por qué Fl_EuroConv deriva de Fl_Group y no de Fl_Window? - ¿Podría usarse Fl_EuroConv en diferentes ventanas de una misma aplicación? ¿Y en otras aplicaciones? ¿Habría que hacer algún cambio en la organización de ficheros respecto a la actual? ¿Cómo sería tal división y cómo se compilaría? - Ahora el nombre de la moneda y el factor de su conversión al euro se proporcionan como parámetros en el constructor. ¿Habría alguna otra forma de hacerlo? ¿Se podrían cambiar estos valores en tiempo de ejecución? - Imagina que, en una aplicación, necesitamos el conversor de pesetas y el de liras juntos, y de forma repetida. ¿Podríamos crear un nuevo control compuesto que sea, a su vez, la composición de dos Fl_EuroConv? ¿Cómo? - ¿Qué hace la función string::c_str()? ¿Para qué nos sirve en este caso? ******************************************************** */