news download themes documentation links










CommandDialog.cc

00001 // CommandDialog.cc for Fluxbox
00002 // Copyright (c) 2003 Henrik Kinnunen (fluxgen(at)users.sourceforge.net)
00003 //                and Simon Bowden    (rathnor at users.sourceforge.net)
00004 //
00005 // Permission is hereby granted, free of charge, to any person obtaining a
00006 // copy of this software and associated documentation files (the "Software"),
00007 // to deal in the Software without restriction, including without limitation
00008 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
00009 // and/or sell copies of the Software, and to permit persons to whom the
00010 // Software is furnished to do so, subject to the following conditions:
00011 //
00012 // The above copyright notice and this permission notice shall be included in
00013 // all copies or substantial portions of the Software.
00014 //
00015 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
00016 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
00017 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
00018 // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
00019 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
00020 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
00021 // DEALINGS IN THE SOFTWARE.
00022 
00023 // $Id: CommandDialog.cc,v 1.3 2004/01/02 13:53:21 fluxgen Exp $
00024 
00025 #include "CommandDialog.hh"
00026 
00027 #include "Screen.hh"
00028 #include "FbWinFrameTheme.hh"
00029 #include "WinClient.hh"
00030 #include "CommandParser.hh"
00031 #include "fluxbox.hh"
00032 
00033 #include "FbTk/ImageControl.hh"
00034 #include "FbTk/EventManager.hh"
00035 #include "FbTk/StringUtil.hh"
00036 #include "FbTk/App.hh"
00037 
00038 #include <X11/keysym.h>
00039 #include <X11/Xutil.h>
00040 
00041 #include <iostream>
00042 #include <memory>
00043 #include <stdexcept>
00044 using namespace std;
00045 
00046 CommandDialog::CommandDialog(BScreen &screen, const std::string &title):
00047     FbWindow(screen.rootWindow().screenNumber(),
00048              0, 0, 200, 1, ExposureMask),
00049     m_font("fixed"),
00050     m_textbox(*this, m_font, ""),
00051     m_label(*this, screen.winFrameTheme().font(), title),    
00052     m_gc(m_textbox),
00053     m_screen(screen),
00054     m_move_x(0),
00055     m_move_y(0),
00056     m_pixmap(0) {
00057     init();
00058 
00059 }
00060 
00061 CommandDialog::CommandDialog(BScreen &screen, const std::string &title, const std::string &precommand):
00062     FbWindow(screen.rootWindow().screenNumber(),
00063              0, 0, 200, 1, ExposureMask),
00064     m_font("fixed"),
00065     m_textbox(*this, m_font, ""),
00066     m_label(*this, screen.winFrameTheme().font(), title),    
00067     m_gc(m_textbox),
00068     m_screen(screen),
00069     m_move_x(0),
00070     m_move_y(0),
00071     m_pixmap(0),
00072     m_precommand(precommand) {
00073     init();
00074 
00075 }
00076 
00077 CommandDialog::~CommandDialog() {
00078     FbTk::EventManager::instance()->remove(*this);
00079     hide();
00080     if (m_pixmap != 0)
00081         m_screen.imageControl().removeImage(m_pixmap);
00082 }
00083 
00084 void CommandDialog::setText(const std::string &text) {
00085     m_textbox.setText(text);
00086 }
00087 
00088 void CommandDialog::show() {
00089     FbTk::FbWindow::show();
00090     m_textbox.setInputFocus();
00091     m_label.clear();
00092     // resize to correct width, which should be the width of label text
00093     // no need to truncate label text in this dialog
00094     // but if label text size < 200 we set 200
00095     if (m_label.textWidth() < 200)
00096         return;
00097     else {
00098         resize(m_label.textWidth(), height());
00099         updateSizes();
00100         render();
00101     }
00102 }
00103 
00104 void CommandDialog::hide() {
00105     FbTk::FbWindow::hide();
00106 
00107     // return focus to fluxbox window
00108     if (Fluxbox::instance()->getFocusedWindow() &&
00109         Fluxbox::instance()->getFocusedWindow()->fbwindow())
00110         Fluxbox::instance()->getFocusedWindow()->fbwindow()->setInputFocus();
00111 
00112 }
00113 
00114 void CommandDialog::exposeEvent(XExposeEvent &event) {
00115     if (event.window == window())
00116         clearArea(event.x, event.y, event.width, event.height);
00117 }
00118 
00119 void CommandDialog::buttonPressEvent(XButtonEvent &event) {
00120     m_textbox.setInputFocus();
00121     m_move_x = event.x_root - x();
00122     m_move_y = event.y_root - y();
00123 }
00124 
00125 void CommandDialog::handleEvent(XEvent &event) {
00126     if (event.type == ConfigureNotify && event.xconfigure.window != window()) {
00127         moveResize(event.xconfigure.x, event.xconfigure.y,
00128                    event.xconfigure.width, event.xconfigure.height);
00129     } else if (event.type == DestroyNotify)
00130         delete this;
00131 }
00132 
00133 void CommandDialog::motionNotifyEvent(XMotionEvent &event) {
00134     int new_x = event.x_root - m_move_x;
00135     int new_y = event.y_root - m_move_y;
00136     move(new_x, new_y);
00137 }
00138 
00139 void CommandDialog::keyPressEvent(XKeyEvent &event) {
00140     if (event.state)
00141         return;
00142 
00143     KeySym ks;
00144     char keychar[1];
00145     XLookupString(&event, keychar, 1, &ks, 0);
00146 
00147     if (ks == XK_Return) {
00148         hide(); // hide and return focus to a FluxboxWindow
00149         // create command from line
00150         std::auto_ptr<FbTk::Command> cmd(CommandParser::instance().
00151             parseLine(m_precommand + m_textbox.text()));
00152         if (cmd.get())
00153             cmd->execute();
00154         // post execute 
00155         if (*m_postcommand != 0)
00156             m_postcommand->execute();
00157 
00158         delete this; // end this
00159     } else if (ks == XK_Escape)
00160         delete this; // end this
00161     else if (ks == XK_Tab) {
00162         // try to expand a command
00163         tabComplete();
00164     }
00165 }
00166 
00167 void CommandDialog::tabComplete() {
00168     try {
00169         string::size_type first = m_textbox.text().find_last_not_of("ABCDEFGHIJKLMNOPQRSTUVWXYZ"
00170                                                                     "abcdefghijklmnopqrstuvwxyz"
00171                                                                     "0123456789", 
00172                                                                     m_textbox.cursorPosition());
00173         if (first == string::npos)
00174             first = 0;
00175         string prefix = FbTk::StringUtil::toLower(m_textbox.text().substr(first, m_textbox.cursorPosition()));
00176         if (prefix.size() == 0) {
00177             XBell(FbTk::App::instance()->display(), 0);
00178             return;
00179         }
00180 
00181         CommandParser::CommandFactoryMap::const_iterator it = CommandParser::instance().factorys().begin();
00182         const CommandParser::CommandFactoryMap::const_iterator it_end = CommandParser::instance().factorys().end();
00183         std::vector<std::string> matches;
00184         for (; it != it_end; ++it) {
00185             if ((*it).first.find(prefix) == 0) {
00186                 matches.push_back((*it).first);
00187             }
00188         }
00189 
00190         if (!matches.empty()) {
00191             // sort and apply larges match
00192             std::sort(matches.begin(), matches.end(), less<string>());        
00193             m_textbox.setText(m_textbox.text() + matches[0].substr(prefix.size()));
00194         } else
00195             XBell(FbTk::App::instance()->display(), 0);
00196 
00197     } catch (std::out_of_range &oor) {
00198         XBell(FbTk::App::instance()->display(), 0);
00199     }
00200 }
00201 
00202 void CommandDialog::render() {
00203     Pixmap tmp = m_pixmap;
00204     if (!m_screen.winFrameTheme().labelFocusTexture().usePixmap()) {
00205         m_label.setBackgroundColor(m_screen.winFrameTheme().labelFocusTexture().color());
00206         m_pixmap = 0;
00207     } else {
00208         m_pixmap = m_screen.imageControl().renderImage(m_label.width(), m_label.height(),
00209                                                        m_screen.winFrameTheme().labelFocusTexture());
00210         m_label.setBackgroundPixmap(m_pixmap);
00211     }
00212 
00213     if (tmp)
00214         m_screen.imageControl().removeImage(tmp);
00215 
00216 }
00217 
00218 void CommandDialog::init() {
00219 
00220 
00221     // setup label
00222     // we listen to motion notify too
00223     m_label.setEventMask(m_label.eventMask() | ButtonPressMask | ButtonMotionMask); 
00224     m_label.setGC(m_screen.winFrameTheme().labelTextFocusGC());
00225     m_label.show();
00226 
00227     // setup text box
00228     FbTk::Color white("white", m_textbox.screenNumber());
00229     m_textbox.setBackgroundColor(white);
00230     FbTk::Color black("black", m_textbox.screenNumber());
00231     m_gc.setForeground(black);
00232     m_textbox.setGC(m_gc.gc());
00233     m_textbox.show();
00234 
00235     // setup this window
00236     setBorderWidth(1);
00237     setBackgroundColor(white);
00238     // move to center of the screen
00239     move((m_screen.width() - width())/2, (m_screen.height() - height())/2);
00240 
00241     updateSizes();
00242     resize(width(), m_textbox.height() + m_label.height());
00243 
00244     render();
00245 
00246     // we need ConfigureNotify from children
00247     FbTk::EventManager::instance()->addParent(*this, *this);
00248 }
00249 
00250 void CommandDialog::updateSizes() {
00251     m_label.moveResize(0, 0,
00252                        width(), m_font.height() + 2);
00253     
00254     m_textbox.moveResize(2, m_label.height(),
00255                          width() - 4, m_font.height() + 2);    
00256 }

Fluxbox CVS-Jan-2003




      



Got comments about the page? Send them to webmaster.
If you have general Fluxbox related questions ask them on our irc channel or mailing lists.

Show Source








Designed by aLEczapKA