# Home    # nevrax.com   
Nevrax
Nevrax.org
#News
#Mailing-list
#Documentation
#CVS
#Bugs
#License
Docs
 
Documentation  
Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members   Related Pages   Search  

gtk_displayer.cpp

Go to the documentation of this file.
00001 
00007 /* Copyright, 2001 Nevrax Ltd.
00008  *
00009  * This file is part of NEVRAX NEL.
00010  * NEVRAX NEL is free software; you can redistribute it and/or modify
00011  * it under the terms of the GNU General Public License as published by
00012  * the Free Software Foundation; either version 2, or (at your option)
00013  * any later version.
00014 
00015  * NEVRAX NEL is distributed in the hope that it will be useful, but
00016  * WITHOUT ANY WARRANTY; without even the implied warranty of
00017  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
00018  * General Public License for more details.
00019 
00020  * You should have received a copy of the GNU General Public License
00021  * along with NEVRAX NEL; see the file COPYING. If not, write to the
00022  * Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
00023  * MA 02111-1307, USA.
00024  */
00025 
00026 #include "stdmisc.h"
00027 
00028 #ifdef NL_USE_GTK
00029 
00030 #include <gtk/gtk.h>
00031 #include <gdk/gdkkeysyms.h>
00032 
00033 #ifdef NL_OS_WINDOWS
00034 // automatically add gtk library
00035 #pragma comment(lib, "gtk-1.3.lib")
00036 #pragma comment(lib, "gdk-1.3.lib")
00037 #pragma comment(lib, "glib-1.3.lib")
00038 #pragma comment(lib, "gthread-1.3.lib")
00039 #endif
00040 
00041 #include <iostream>
00042 #include <fstream>
00043 #include <iomanip>
00044 #include <signal.h>
00045 
00046 #include "nel/misc/path.h"
00047 #include "nel/misc/command.h"
00048 #include "nel/misc/thread.h"
00049 
00050 #include "nel/misc/gtk_displayer.h"
00051 
00052 using namespace std;
00053 
00054 namespace NLMISC {
00055 
00056 GtkWidget *RootWindow = NULL, *OutputText = NULL, *InputText = NULL, *hrootbox = NULL;
00057 
00058 CGtkDisplayer::~CGtkDisplayer ()
00059 {
00060         if (_Init)
00061         {
00062         }
00063 }
00064 
00065 void CGtkDisplayer::updateLabels ()
00066 {
00067         {
00068                 CSynchronized<std::vector<CLabelEntry> >::CAccessor access (&_Labels);
00069                 for (uint i = 0; i < access.value().size(); i++)
00070                 {
00071                         if (access.value()[i].Hwnd == NULL)
00072                         {
00073                                 access.value()[i].Hwnd = gtk_label_new ("");
00074                                 gtk_label_set_justify (GTK_LABEL (access.value()[i].Hwnd), GTK_JUSTIFY_LEFT);
00075                                 gtk_label_set_line_wrap (GTK_LABEL (access.value()[i].Hwnd), FALSE);
00076                                 gtk_widget_show (GTK_WIDGET (access.value()[i].Hwnd));
00077                                 gtk_box_pack_start (GTK_BOX (hrootbox), GTK_WIDGET (access.value()[i].Hwnd), TRUE, TRUE, 0);
00078                         }
00079                         if (!access.value()[i].Value.empty())
00080                         {
00081                                 gtk_label_set_text (GTK_LABEL (access.value()[i].Hwnd), access.value()[i].Value.c_str());
00082                                 access.value()[i].Value = "";
00083                         }
00084                 }
00085         }
00086 }
00087 
00088 // windows delete event => quit
00089 gint delete_event (GtkWidget *widget, GdkEvent *event, gpointer data)
00090 {
00091         gtk_main_quit();
00092 
00093         exit(1);
00094         return FALSE;
00095 }
00096 
00097 vector<string> CommandHistory;
00098 uint32 CommandHistoryPos = 0;
00099 
00100 gint KeyIn(GtkWidget *Widget, GdkEventKey *Event, gpointer *Data)
00101 {
00102         switch (Event->keyval)
00103         {
00104         case GDK_Escape : gtk_entry_set_text (GTK_ENTRY(Widget), ""); break;
00105         case GDK_Up : if (CommandHistoryPos > 0) { CommandHistoryPos--; gtk_entry_set_text (GTK_ENTRY(Widget), CommandHistory[CommandHistoryPos].c_str()); } break;
00106         case GDK_Down : if (CommandHistoryPos + 1 < CommandHistory.size()) { CommandHistoryPos++; gtk_entry_set_text (GTK_ENTRY(Widget), CommandHistory[CommandHistoryPos].c_str()); } break;
00107         case GDK_KP_Enter : gtk_signal_emit_by_name(GTK_OBJECT(Widget),"activate"); return FALSE; break;
00108         default : return FALSE;
00109         }
00110         gtk_signal_emit_stop_by_name(GTK_OBJECT(Widget),"key_press_event");
00111         return TRUE;
00112 }
00113 
00114 void updateInput ()
00115 {
00116         gtk_widget_grab_focus (InputText);
00117 }
00118 
00119 gint KeyOut(GtkWidget *Widget, GdkEventKey *Event, gpointer *Data)
00120 {
00121         updateInput();
00122         gtk_signal_emit_stop_by_name(GTK_OBJECT(Widget),"key_press_event");
00123         return TRUE;
00124 }
00125 
00126 
00127 gint ButtonClear(GtkWidget *Widget, GdkEventKey *Event, gpointer *Data)
00128 {
00129         CGtkDisplayer *disp = (CGtkDisplayer *) Data;
00130 
00131         disp->clear ();
00132         return TRUE;
00133 }
00134 
00135 // the user typed  command, execute it
00136 gint cbValidateCommand (GtkWidget *widget, GdkEvent *event, gpointer data)
00137 {
00138         string cmd = gtk_entry_get_text (GTK_ENTRY(widget));
00139         CommandHistory.push_back (cmd);
00140         // execute the command
00141         ICommand::execute (cmd, *InfoLog);
00142         // clear the input text
00143         gtk_entry_set_text (GTK_ENTRY(widget), "");
00144         CommandHistoryPos = CommandHistory.size();
00145         return TRUE;
00146 }
00147 
00148 
00149 void CGtkDisplayer::open (string windowNameEx, sint x, sint y, sint w, sint h, sint hs)
00150 {
00151         _HistorySize = hs;
00152 
00153         gtk_init (NULL, NULL);
00154 
00155         // Root window
00156         RootWindow = gtk_window_new (GTK_WINDOW_TOPLEVEL);
00157         string wn;
00158         if (!windowNameEx.empty())
00159         {
00160                 wn += windowNameEx;
00161                 wn += ": ";
00162         }
00163         wn += "Nel Service Console (compiled " __DATE__ " " __TIME__ ") ";
00164         gtk_window_set_title (GTK_WINDOW (RootWindow), wn.c_str());
00165         gtk_window_set_default_size (GTK_WINDOW (RootWindow), w, h);
00166         gtk_signal_connect (GTK_OBJECT (RootWindow), "delete_event", GTK_SIGNAL_FUNC (delete_event), NULL);
00167 
00168         // Vertical box
00169         GtkWidget *vrootbox = gtk_vbox_new (FALSE, 0);
00170         nlassert (vrootbox != NULL);
00171         gtk_container_add (GTK_CONTAINER (RootWindow), vrootbox);
00172 
00173         // Horizontal box (for labels)
00174         hrootbox = gtk_hbox_new (FALSE, 0);
00175         nlassert (hrootbox != NULL);
00176         gtk_box_pack_start (GTK_BOX (vrootbox), hrootbox, FALSE, FALSE, 0);
00177 
00178         // Clear button
00179     GtkWidget *button = gtk_button_new_with_label ("Clear");
00180         nlassert (button != NULL);
00181     gtk_signal_connect (GTK_OBJECT (button), "clicked", GTK_SIGNAL_FUNC (ButtonClear), (gpointer) this);
00182         gtk_box_pack_start (GTK_BOX (hrootbox), button, FALSE, FALSE, 0);
00183 
00184         // Output text
00185         GtkWidget *scrolled_win2 = gtk_scrolled_window_new (NULL, NULL);
00186         nlassert (scrolled_win2 != NULL);
00187         gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_win2), GTK_POLICY_NEVER, GTK_POLICY_ALWAYS);
00188         gtk_widget_show (scrolled_win2);
00189         gtk_container_add (GTK_CONTAINER (vrootbox), scrolled_win2);
00190 
00191         OutputText = gtk_text_new (NULL, NULL);
00192         nlassert (OutputText != NULL);
00193         gtk_signal_connect(GTK_OBJECT(OutputText),"key_press_event",GTK_SIGNAL_FUNC(KeyOut),NULL);
00194         gtk_text_set_editable (GTK_TEXT (OutputText), FALSE);
00195         gtk_container_add (GTK_CONTAINER (scrolled_win2), OutputText);
00196 
00197         // Input text
00198         InputText = gtk_entry_new ();
00199         nlassert (InputText != NULL);
00200         gtk_signal_connect (GTK_OBJECT(InputText), "activate", GTK_SIGNAL_FUNC(cbValidateCommand), NULL);
00201         gtk_signal_connect(GTK_OBJECT(InputText),"key_press_event",GTK_SIGNAL_FUNC(KeyIn),NULL);
00202         gtk_box_pack_start (GTK_BOX (vrootbox), InputText, FALSE, FALSE, 0);
00203 
00204         gtk_widget_show (button);
00205         gtk_widget_show (OutputText);
00206         gtk_widget_show (InputText);
00207         
00208         gtk_widget_show (hrootbox);
00209         gtk_widget_show (vrootbox);
00210     gtk_widget_show (RootWindow);
00211 
00212         _Init = true;
00213 }
00214 
00215 void CGtkDisplayer::clear ()
00216 {
00217         int n;
00218 
00219         gtk_text_set_point(GTK_TEXT(OutputText),0);
00220         n = gtk_text_get_length(GTK_TEXT(OutputText));
00221         gtk_text_forward_delete(GTK_TEXT(OutputText),n);
00222 }
00223 
00224 gint updateInterf (gpointer data)
00225 {
00226         CGtkDisplayer *disp = (CGtkDisplayer *)data;
00227 
00228         //
00229         // Update labels
00230         //
00231 
00232         disp->updateLabels ();
00233 
00234         //
00235         // Display the bufferized string
00236         //
00237 
00238         string str;
00239         {
00240                 CSynchronized<std::string>::CAccessor access (&disp->_Buffer);
00241                 str = access.value();
00242                 access.value() = "";
00243         }
00244 
00245         // nothing to do
00246         if (str.empty ())
00247                 return TRUE;
00248 
00249         GtkAdjustment *Adj = (GTK_TEXT(OutputText))->vadj;
00250         bool Bottom = (Adj->value >= Adj->upper - Adj->page_size);
00251 
00252         gtk_text_freeze (GTK_TEXT (OutputText));
00253         gtk_text_insert (GTK_TEXT (OutputText), NULL, NULL, NULL, str.c_str(), -1);
00254         gtk_text_thaw (GTK_TEXT (OutputText));
00255 
00256         if (Bottom)
00257         {
00258                 gtk_adjustment_set_value(Adj,Adj->upper-Adj->page_size);
00259         }
00260 
00261         return TRUE;
00262 }
00263 
00264 
00265 void CGtkDisplayer::display_main ()
00266 {
00267         //
00268         // Manage windows message
00269         //
00270 
00271         gtk_timeout_add (10, updateInterf, this);
00272         gtk_main ();    
00273 }
00274 
00275 } // NLMISC
00276 
00277 #endif // NL_USE_GTK