Programando con Fox-Toolkit
Raul Vazquez CastilloHace algún tiempo publiqué que Fox-Toolkit era un excelente opción para aquellos que queremos programar en un ambiente multiplataforma y además necesitamos:
- Aplicaciones que corran en cualquier plataforma: linux, unix, windows, etc.
- No estar reinventando el hilo negro cada vez que desarrollamos algo, como por ejemplo uso o no uso esta librería, programo con la librería para Gnome ó con la de KDE, etc.. Esto es no estar perdiendo el tiempo en aprender cómo hacer un botón u elemento gráfico con esta librería y con esta otra, y además con esta otra también.
- Aprender de una vez por todas una herramienta y un lenguaje (“C++ por supuesto”) que me servirá para el futuro, bueno al menos esto se cumple mientras siga existiendo el sistema X y siga existiendo winrocks.
- Desarrollar aplicaciones de escritorio.
En fin, después de tanto rollo de evangelización, vamos al grano.
Es bueno echarle un ojo a estos screenshots de aplicaciones desarrolladas utilizando fox-toolkit
Primeramente, para empezar a jugar con esta herramienta, hay que bajarla y instalarla.
Y pues seguimos el procedimiento habitual:
tar xvfz fox-1.1.24.tar.gz./configuremakemake install
Podemos echarle un ojo a los ejemplos, cambiándonos al directorio de éstos y haciendo un simple make para compilarlos todos.
He aquí el código para hacer un menú y un diálogo con los elementos mas comunes.
Primeramente la declaración de la clase de nuestro dialogo:
#include "fx.h"class CDlgTest : public FXDialogBox { FXDECLARE(CDlgTest)public: enum { ID_TEXTFIELD = FXDialogBox::ID_LAST, ID_COMBOBOX, ID_LIST, ID_TEXTFIELD2, ID_TEXTFIELD3, ID_LAST }; CDlgTest(FXWindow* pWnd); FXVerticalFrame* getContentArea() const { return m_pContent; } long onCmdAccept(FXObject* pSender, FXSelector sel, void* pv);protected: FXButton* m_pBtnAccept; FXButton* m_pBtnCancel; CDlgTest() {}private: FXVerticalFrame* m_pContent; FXTextField* m_pTxf; FXComboBox* m_pCmb; FXList* m_pLst; FXTextField* m_pTxf2; FXTextField* m_pTxf3; void construct(const FXString& sAccept, const FXString& sCancel);};
La implementación del diálogo:
#include "DlgTest.h"FXDEFMAP(CDlgTest) CDlgTestMap[] = { FXMAPFUNC(SEL_COMMAND, CDlgTest::ID_ACCEPT, CDlgTest::onCmdAccept),};FXIMPLEMENT(CDlgTest, FXDialogBox, CDlgTestMap, ARRAYNUMBER(CDlgTestMap));CDlgTest::CDlgTest(FXWindow* pWnd) : FXDialogBox(pWnd, "Default Button Test",DECOR_ALL){ construct("Aceptar", "Cancelar");//// FXMatrix* pMtx = new FXMatrix(getContentArea(), 2, MATRIX_BY_COLUMNS | LAYOUT_FILL_X | LAYOUT_FILL_Y); new FXLabel(pMtx, "Campo de Texto:", NULL, LABEL_NORMAL | LAYOUT_RIGHT); m_pTxf = new FXTextField(pMtx, 40, this, ID_TEXTFIELD, TEXTFIELD_PASSWD | LAYOUT_FILL_X); new FXLabel(pMtx, "Combo Box:", NULL, LABEL_NORMAL | LAYOUT_RIGHT); m_pCmb = new FXComboBox(pMtx, 40, 13, this, ID_COMBOBOX, TEXTFIELD_NORMAL | LAYOUT_FILL_X); m_pCmb->appendItem("combo1"); m_pCmb->appendItem("combo2"); m_pCmb->appendItem("combo3"); m_pCmb->appendItem("combo4"); m_pCmb->appendItem("combo5"); m_pCmb->appendItem("combo6"); m_pCmb->appendItem("combo7"); m_pCmb->appendItem("combo8"); m_pCmb->appendItem("combo9"); m_pCmb->appendItem("combo10"); m_pCmb->appendItem("combo11"); m_pCmb->appendItem("combo12"); m_pCmb->appendItem("combo13"); new FXLabel(pMtx, "Lista :", NULL, LABEL_NORMAL | LAYOUT_RIGHT); m_pLst = new FXList( new FXHorizontalFrame(pMtx, FRAME_NORMAL | LAYOUT_FILL_X | LAYOUT_FILL_Y, 0,0,0,0, 0,0,0,0), 8, this, ID_LIST, LIST_NORMAL | LAYOUT_FILL_X | LAYOUT_FILL_Y); m_pLst->appendItem("Item 1"); m_pLst->appendItem("Item 2"); m_pLst->appendItem("Item 3"); m_pLst->appendItem("Item 4"); m_pLst->appendItem("Item 5"); m_pLst->appendItem("Item 6"); m_pLst->appendItem("Item 7"); m_pLst->appendItem("Item 8"); new FXLabel(pMtx, "Text ENTERO:", NULL, LABEL_NORMAL | LAYOUT_RIGHT); m_pTxf2 = new FXTextField(pMtx, 12, this, ID_TEXTFIELD2, TEXTFIELD_INTEGER|JUSTIFY_RIGHT|FRAME_THICK); new FXLabel(pMtx, "Text REAL:", NULL, LABEL_NORMAL | LAYOUT_RIGHT); m_pTxf3 = new FXTextField(pMtx, 12, this, ID_TEXTFIELD3, TEXTFIELD_REAL|JUSTIFY_RIGHT|FRAME_THICK);}long CDlgTest::onCmdAccept(FXObject* pSender, FXSelector sel, void* pv){ return FXDialogBox::onCmdAccept(pSender, sel, pv);}void CDlgTest::construct(const FXString& sAccept, const FXString& sCancel){ FXVerticalFrame* pVFrm = new FXVerticalFrame(this, LAYOUT_FILL_X | LAYOUT_FILL_Y, 0,0,0,0, 0,0,0,0); m_pContent = new FXVerticalFrame(pVFrm, LAYOUT_FILL_X | LAYOUT_FILL_Y, 0,0,0,0, 0,0,0,0); FXHorizontalFrame* pHFrm = new FXHorizontalFrame(pVFrm, LAYOUT_BOTTOM | LAYOUT_CENTER_X | PACK_UNIFORM_WIDTH); m_pBtnAccept = new FXButton(pHFrm, sAccept, NULL, this, ID_ACCEPT, BUTTON_NORMAL | BUTTON_DEFAULT | BUTTON_INITIAL | LAYOUT_FIX_WIDTH); m_pBtnAccept->setWidth(80); new FXHorizontalFrame(pHFrm, LAYOUT_FIX_WIDTH, 0,0,10,0); m_pBtnCancel = new FXButton(pHFrm, sAccept, NULL, this, ID_CANCEL, BUTTON_NORMAL | BUTTON_DEFAULT | LAYOUT_FIX_WIDTH); m_pBtnCancel = new FXButton(pHFrm, sCancel, NULL, this, ID_CANCEL); m_pBtnCancel->setWidth(80);}
Finalmente nuestro programa principal:
#include "fx.h"#include "DlgTest.h"class CSimpleWnd;//============================================================================//// Declaracion clase CSimpleApp////----------------------------------------------------------------------------class CSimpleApp : public FXApp { FXDECLARE(CSimpleApp)public: CSimpleApp(); ~CSimpleApp(); void create(); const char* getAppName() const { return m_pchAppName; } CSimpleWnd* getSimpleWnd() const { return (CSimpleWnd*)getMainWindow(); }private: static const char* m_pchAppName;};FXIMPLEMENT(CSimpleApp, FXApp, NULL, 0);const char* CSimpleApp::m_pchAppName = "SimpleApp";CSimpleApp::CSimpleApp() : FXApp(getAppName()){}CSimpleApp::~CSimpleApp(){}void CSimpleApp::create(){ FXApp::create();}//============================================================================//// Declaracion de clase CSimpleWnd////----------------------------------------------------------------------------class CSimpleWnd : public FXMainWindow { FXDECLARE(CSimpleWnd)public: enum { ID_QUIT = FXMainWindow::ID_LAST, ID_DLG, ID_LAST }; CSimpleWnd(CSimpleApp* pApp); ~CSimpleWnd(); CSimpleApp* getSimpleApp() const { return dynamic_cast(FXMainWindow::getApp()); } long onClose(FXObject* pSender, FXSelector sel, void* pv); long onCmdDlg(FXObject* pObject, FXSelector sel, void* pv);private: FXMenubar* m_pMenuBar; FXMenuPane* m_pFilePane; FXToolbar* m_pToolBar; FXVerticalFrame* m_pViewArea; FXStatusbar* m_pStatusBar; CSimpleWnd() {}};FXDEFMAP(CSimpleWnd) CSimpleWndMap[] = { FXMAPFUNC(SEL_CLOSE, 0, CSimpleWnd::onClose), FXMAPFUNC(SEL_COMMAND, CSimpleWnd::ID_DLG, CSimpleWnd::onCmdDlg), FXMAPFUNC(SEL_COMMAND, CSimpleWnd::ID_QUIT, CSimpleWnd::onClose),};FXIMPLEMENT(CSimpleWnd, FXMainWindow, CSimpleWndMap, ARRAYNUMBER(CSimpleWndMap));CSimpleWnd::CSimpleWnd(CSimpleApp* pApp) : FXMainWindow(pApp, "Simple Application", NULL, NULL, DECOR_ALL, 200,100 ,200,100, 0,0){ // Creamos la barra de menu m_pMenuBar = new FXMenubar(this, FRAME_RAISED | LAYOUT_SIDE_TOP | LAYOUT_FILL_X); // Creamos el oolBar FXToolbarShell* pTbShell = new FXToolbarShell(this, 0, 100, 100); m_pToolBar = new FXToolbar(this, pTbShell, FRAME_RAISED|LAYOUT_SIDE_TOP|LAYOUT_FILL_X |PACK_UNIFORM_HEIGHT, 0,0,0,0, 2,2,2,2, 0,0); // Createmos File Menu m_pFilePane = new FXMenuPane(this); new FXMenuCommand(m_pFilePane, "Dialogo...tCtrl-QtLlamar el dialogo", NULL, this, ID_DLG); new FXMenuSeparator(m_pFilePane); new FXMenuCommand(m_pFilePane, "SalirtCtrl-QtSalir de la Aplicacion", NULL, this, ID_QUIT); new FXMenuTitle(m_pMenuBar, "Menu", NULL, m_pFilePane); // Barra de Status // m_pStatusBar = new FXStatusbar(this, LAYOUT_SIDE_BOTTOM | LAYOUT_FILL_X | STATUSBAR_WITH_DRAGCORNER); // // Ventana Principal // m_pViewArea = new FXVerticalFrame(this, LAYOUT_FILL_X | LAYOUT_FILL_Y | FRAME_NORMAL);}CSimpleWnd::~CSimpleWnd(){ delete m_pFilePane;}long CSimpleWnd::onClose(FXObject*, FXSelector, void*){ getApp()->stop(); return 1;}long CSimpleWnd::onCmdDlg(FXObject*, FXSelector, void*){ CDlgTest dlg(this); if (dlg.execute(PLACEMENT_OWNER) == TRUE) { fxmessage("Aceptar has sido presionadon"); } else { fxmessage("Cancelar ha sido presionadon"); } return 1;}//============================================================================//// Main////----------------------------------------------------------------------------CSimpleApp* g_pApp(NULL);int main(int argc, char* argv[]){ g_pApp = new CSimpleApp; g_pApp->init(argc, argv); // Cambiar font de default // FXFont* pOldFont = g_pApp->getNormalFont(); g_pApp->setNormalFont(new FXFont(g_pApp, "MS Sans Serif", 8)); delete pOldFont; new CSimpleWnd(g_pApp); g_pApp->create(); g_pApp->getSimpleWnd()->show(); g_pApp->run(); delete g_pApp; return 0;}CSimpleApp*GetSimpleApp(){ return g_pApp;}
Bueno, lo que resta es únicamente compilar y ligar con las librerías y listo, ya tenemos nuestra primera aplicación utilizando fox-toolkit
Hasta aquí llegamos con este ejemplo, espero asistir a la próxima reunión para comentar un poco más acerca de esta librería.