diff options
Diffstat (limited to 'src/CommandDialog.cc')
-rw-r--r-- | src/CommandDialog.cc | 188 |
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 | ||
44 | using std::string; | 36 | using std::string; |
45 | using std::vector; | 37 | using std::vector; |
@@ -47,115 +39,31 @@ using std::auto_ptr; | |||
47 | using std::less; | 39 | using std::less; |
48 | using std::out_of_range; | 40 | using std::out_of_range; |
49 | 41 | ||
50 | CommandDialog::CommandDialog(BScreen &screen, | 42 | CommandDialog::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), | 47 | void 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 | |||
65 | CommandDialog::~CommandDialog() { | ||
66 | FbTk::EventManager::instance()->remove(*this); | ||
67 | hide(); | ||
68 | if (m_pixmap != 0) | ||
69 | m_screen.imageControl().removeImage(m_pixmap); | ||
70 | } | ||
71 | |||
72 | void CommandDialog::setText(const string &text) { | ||
73 | m_textbox.setText(text); | ||
74 | } | ||
75 | |||
76 | void 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 | |||
93 | void CommandDialog::hide() { | ||
94 | FbTk::FbWindow::hide(); | ||
95 | Fluxbox::instance()->setShowingDialog(false); | ||
96 | } | ||
97 | |||
98 | void CommandDialog::exposeEvent(XExposeEvent &event) { | ||
99 | if (event.window == window()) | ||
100 | clearArea(event.x, event.y, event.width, event.height); | ||
101 | } | ||
102 | |||
103 | void 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 | |||
109 | void 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 | |||
117 | void 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 | |||
123 | void 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 | ||
150 | void CommandDialog::tabComplete() { | 58 | void 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 | |||
185 | void 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 | |||
201 | void 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 | |||
233 | void 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 | } | ||