summaryrefslogtreecommitdiff
path: root/src/CommandDialog.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/CommandDialog.cc')
-rw-r--r--src/CommandDialog.cc188
1 files changed, 20 insertions, 168 deletions
diff --git a/src/CommandDialog.cc b/src/CommandDialog.cc
index 5e7aa7d..bef8a63 100644
--- a/src/CommandDialog.cc
+++ b/src/CommandDialog.cc
@@ -22,24 +22,16 @@
22 22
23#include "CommandDialog.hh" 23#include "CommandDialog.hh"
24 24
25#include "Screen.hh"
26#include "FbWinFrameTheme.hh"
27#include "WinClient.hh"
28#include "FbTk/CommandParser.hh" 25#include "FbTk/CommandParser.hh"
29#include "FocusControl.hh"
30#include "fluxbox.hh"
31
32#include "FbTk/ImageControl.hh"
33#include "FbTk/EventManager.hh"
34#include "FbTk/StringUtil.hh" 26#include "FbTk/StringUtil.hh"
35#include "FbTk/KeyUtil.hh"
36#include "FbTk/App.hh" 27#include "FbTk/App.hh"
37 28
38#include <X11/keysym.h>
39#include <X11/Xutil.h> 29#include <X11/Xutil.h>
40 30
31#include <algorithm>
41#include <memory> 32#include <memory>
42#include <stdexcept> 33#include <stdexcept>
34#include <vector>
43 35
44using std::string; 36using std::string;
45using std::vector; 37using std::vector;
@@ -47,115 +39,31 @@ using std::auto_ptr;
47using std::less; 39using std::less;
48using std::out_of_range; 40using std::out_of_range;
49 41
50CommandDialog::CommandDialog(BScreen &screen, 42CommandDialog::CommandDialog(BScreen &screen, const string &title,
51 const string &title, const string precommand) : 43 const string precommand) :
52 FbTk::FbWindow(screen.rootWindow().screenNumber(), 0, 0, 200, 1, ExposureMask), 44 TextDialog(screen, title),
53 m_textbox(*this, screen.focusedWinFrameTheme()->font(), ""), 45 m_precommand(precommand) { }
54 m_label(*this, screen.focusedWinFrameTheme()->font(), title), 46
55 m_gc(m_textbox), 47void CommandDialog::exec(const std::string &text){
56 m_screen(screen), 48
57 m_move_x(0), 49 // create Command<void> from line
58 m_move_y(0), 50 auto_ptr<FbTk::Command<void> > cmd(FbTk::CommandParser<void>::instance().parse(m_precommand + text));
59 m_pixmap(0), 51 if (cmd.get())
60 m_precommand(precommand) { 52 cmd->execute();
61 init(); 53 // post execute
62 54 if (*m_postcommand != 0)
63} 55 m_postcommand->execute();
64
65CommandDialog::~CommandDialog() {
66 FbTk::EventManager::instance()->remove(*this);
67 hide();
68 if (m_pixmap != 0)
69 m_screen.imageControl().removeImage(m_pixmap);
70}
71
72void CommandDialog::setText(const string &text) {
73 m_textbox.setText(text);
74}
75
76void CommandDialog::show() {
77 FbTk::FbWindow::show();
78 m_textbox.setInputFocus();
79 m_label.clear();
80 Fluxbox::instance()->setShowingDialog(true);
81 // resize to correct width, which should be the width of label text
82 // no need to truncate label text in this dialog
83 // but if label text size < 200 we set 200
84 if (m_label.textWidth() < 200)
85 return;
86 else {
87 resize(m_label.textWidth(), height());
88 updateSizes();
89 render();
90 }
91}
92
93void CommandDialog::hide() {
94 FbTk::FbWindow::hide();
95 Fluxbox::instance()->setShowingDialog(false);
96}
97
98void CommandDialog::exposeEvent(XExposeEvent &event) {
99 if (event.window == window())
100 clearArea(event.x, event.y, event.width, event.height);
101}
102
103void CommandDialog::buttonPressEvent(XButtonEvent &event) {
104 m_textbox.setInputFocus();
105 m_move_x = event.x_root - x();
106 m_move_y = event.y_root - y();
107}
108
109void CommandDialog::handleEvent(XEvent &event) {
110 if (event.type == ConfigureNotify && event.xconfigure.window != window()) {
111 moveResize(event.xconfigure.x, event.xconfigure.y,
112 event.xconfigure.width, event.xconfigure.height);
113 } else if (event.type == DestroyNotify)
114 delete this;
115}
116
117void CommandDialog::motionNotifyEvent(XMotionEvent &event) {
118 int new_x = event.x_root - m_move_x;
119 int new_y = event.y_root - m_move_y;
120 move(new_x, new_y);
121}
122
123void CommandDialog::keyPressEvent(XKeyEvent &event) {
124 unsigned int state = FbTk::KeyUtil::instance().isolateModifierMask(event.state);
125 if (state)
126 return;
127
128 KeySym ks;
129 char keychar;
130 XLookupString(&event, &keychar, 1, &ks, 0);
131
132 if (ks == XK_Return) {
133 // create Command<void> from line
134 auto_ptr<FbTk::Command<void> > cmd(FbTk::CommandParser<void>::instance().parse(m_precommand + m_textbox.text()));
135 if (cmd.get())
136 cmd->execute();
137 // post execute
138 if (*m_postcommand != 0)
139 m_postcommand->execute();
140
141 delete this; // end this
142 } else if (ks == XK_Escape)
143 delete this; // end this
144 else if (ks == XK_Tab) {
145 // try to expand a command
146 tabComplete();
147 }
148} 56}
149 57
150void CommandDialog::tabComplete() { 58void CommandDialog::tabComplete() {
151 try { 59 try {
152 string::size_type first = m_textbox.text().find_last_not_of("ABCDEFGHIJKLMNOPQRSTUVWXYZ" 60 string::size_type first = m_textbox.text().find_last_not_of("ABCDEFGHIJKLMNOPQRSTUVWXYZ"
153 "abcdefghijklmnopqrstuvwxyz" 61 "abcdefghijklmnopqrstuvwxyz"
154 "0123456789", 62 "0123456789", m_textbox.cursorPosition());
155 m_textbox.cursorPosition());
156 if (first == string::npos) 63 if (first == string::npos)
157 first = 0; 64 first = 0;
158 string prefix = FbTk::StringUtil::toLower(m_textbox.text().substr(first, m_textbox.cursorPosition())); 65 string prefix = FbTk::StringUtil::toLower(m_textbox.text().substr(first,
66 m_textbox.cursorPosition()));
159 if (prefix.empty()) { 67 if (prefix.empty()) {
160 XBell(FbTk::App::instance()->display(), 0); 68 XBell(FbTk::App::instance()->display(), 0);
161 return; 69 return;
@@ -181,59 +89,3 @@ void CommandDialog::tabComplete() {
181 XBell(FbTk::App::instance()->display(), 0); 89 XBell(FbTk::App::instance()->display(), 0);
182 } 90 }
183} 91}
184
185void CommandDialog::render() {
186 Pixmap tmp = m_pixmap;
187 if (!m_screen.focusedWinFrameTheme()->iconbarTheme().texture().usePixmap()) {
188 m_label.setBackgroundColor(m_screen.focusedWinFrameTheme()->iconbarTheme().texture().color());
189 m_pixmap = 0;
190 } else {
191 m_pixmap = m_screen.imageControl().renderImage(m_label.width(), m_label.height(),
192 m_screen.focusedWinFrameTheme()->iconbarTheme().texture());
193 m_label.setBackgroundPixmap(m_pixmap);
194 }
195
196 if (tmp)
197 m_screen.imageControl().removeImage(tmp);
198
199}
200
201void CommandDialog::init() {
202
203
204 // setup label
205 // we listen to motion notify too
206 m_label.setEventMask(m_label.eventMask() | ButtonPressMask | ButtonMotionMask);
207 m_label.setGC(m_screen.focusedWinFrameTheme()->iconbarTheme().text().textGC());
208 m_label.show();
209
210 // setup text box
211 FbTk::Color white("white", m_textbox.screenNumber());
212 m_textbox.setBackgroundColor(white);
213 FbTk::Color black("black", m_textbox.screenNumber());
214 m_gc.setForeground(black);
215 m_textbox.setGC(m_gc.gc());
216 m_textbox.show();
217
218 // setup this window
219 setBorderWidth(1);
220 setBackgroundColor(white);
221 // move to center of the screen
222 move((m_screen.width() - width())/2, (m_screen.height() - height())/2);
223
224 updateSizes();
225 resize(width(), m_textbox.height() + m_label.height());
226
227 render();
228
229 // we need ConfigureNotify from children
230 FbTk::EventManager::instance()->addParent(*this, *this);
231}
232
233void CommandDialog::updateSizes() {
234 m_label.moveResize(0, 0,
235 width(), m_textbox.font().height() + 2);
236
237 m_textbox.moveResize(2, m_label.height(),
238 width() - 4, m_textbox.font().height() + 2);
239}