diff options
author | fluxgen <fluxgen> | 2003-04-15 12:54:09 (GMT) |
---|---|---|
committer | fluxgen <fluxgen> | 2003-04-15 12:54:09 (GMT) |
commit | 9932f2e49a68248ae2b908b9dbecab03f9ebd286 (patch) | |
tree | 901d460cdf40bc70f0cca9554685053b84114d41 | |
parent | 9a3c7102949736628125de3077951b639491b2b4 (diff) | |
download | fluxbox_pavel-9932f2e49a68248ae2b908b9dbecab03f9ebd286.zip fluxbox_pavel-9932f2e49a68248ae2b908b9dbecab03f9ebd286.tar.bz2 |
removed
-rw-r--r-- | src/Tab.cc | 1206 | ||||
-rw-r--r-- | src/Tab.hh | 151 |
2 files changed, 0 insertions, 1357 deletions
diff --git a/src/Tab.cc b/src/Tab.cc deleted file mode 100644 index 1734e05..0000000 --- a/src/Tab.cc +++ /dev/null | |||
@@ -1,1206 +0,0 @@ | |||
1 | // Tab.cc for Fluxbox Window Manager | ||
2 | // Copyright (c) 2001 - 2002 Henrik Kinnunen (fluxgen at linuxmail.org) | ||
3 | // | ||
4 | // Permission is hereby granted, free of charge, to any person obtaining a | ||
5 | // copy of this software and associated documentation files (the "Software"), | ||
6 | // to deal in the Software without restriction, including without limitation | ||
7 | // the rights to use, copy, modify, merge, publish, distribute, sublicense, | ||
8 | // and/or sell copies of the Software, and to permit persons to whom the | ||
9 | // Software is furnished to do so, subject to the following conditions: | ||
10 | // | ||
11 | // The above copyright notice and this permission notice shall be included in | ||
12 | // all copies or substantial portions of the Software. | ||
13 | // | ||
14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | ||
17 | // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | ||
19 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | ||
20 | // DEALINGS IN THE SOFTWARE. | ||
21 | |||
22 | // $Id: Tab.cc,v 1.56 2003/04/09 13:18:36 fluxgen Exp $ | ||
23 | |||
24 | #include "Tab.hh" | ||
25 | |||
26 | #include "Window.hh" | ||
27 | #include "i18n.hh" | ||
28 | #include "DrawUtil.hh" | ||
29 | #include "Screen.hh" | ||
30 | #include "fluxbox.hh" | ||
31 | #include "ImageControl.hh" | ||
32 | |||
33 | #include <iostream> | ||
34 | using namespace std; | ||
35 | |||
36 | bool Tab::m_stoptabs = false; | ||
37 | Tab::t_tabplacementlist Tab::m_tabplacementlist[] = { | ||
38 | {PTOP, "Top"}, | ||
39 | {PBOTTOM, "Bottom"}, | ||
40 | {PLEFT, "Left"}, | ||
41 | {PRIGHT, "Right"}, | ||
42 | {PNONE, "none"} | ||
43 | }; | ||
44 | |||
45 | Tab::t_tabplacementlist Tab::m_tabalignmentlist[] = { | ||
46 | {ALEFT, "Left"}, | ||
47 | {ACENTER, "Center"}, | ||
48 | {ARIGHT, "Right"}, | ||
49 | {ARELATIVE, "Relative"}, | ||
50 | {ANONE, "none"} | ||
51 | }; | ||
52 | |||
53 | Tab::Tab(FluxboxWindow *win, Tab *prev, Tab *next) { | ||
54 | //set default values | ||
55 | |||
56 | m_focus = m_moving = false; | ||
57 | m_configured = true; // only set to false before Fluxbox::reconfigure | ||
58 | m_move_x = m_move_y = 0; | ||
59 | m_prev = prev; m_next = next; | ||
60 | m_win = win; | ||
61 | m_display = BaseDisplay::getXDisplay(); | ||
62 | |||
63 | if ((m_win->getScreen()->getTabPlacement() == PLEFT || | ||
64 | m_win->getScreen()->getTabPlacement() == PRIGHT) && | ||
65 | m_win->getScreen()->isTabRotateVertical() && | ||
66 | !m_win->isShaded()) { | ||
67 | m_size_w = m_win->getScreen()->getTabHeight(); | ||
68 | m_size_h = m_win->getScreen()->getTabWidth(); | ||
69 | } else { | ||
70 | m_size_w = m_win->getScreen()->getTabWidth(); | ||
71 | m_size_h = m_win->getScreen()->getTabHeight(); | ||
72 | } | ||
73 | |||
74 | createTabWindow(); | ||
75 | |||
76 | calcIncrease(); | ||
77 | } | ||
78 | |||
79 | Tab::~Tab() { | ||
80 | |||
81 | disconnect(); | ||
82 | |||
83 | Fluxbox::instance()->removeTabSearch(m_tabwin); | ||
84 | XDestroyWindow(m_display, m_tabwin); | ||
85 | } | ||
86 | |||
87 | |||
88 | //---------------- createTabWindow --------------- | ||
89 | // (private) | ||
90 | // Creates the Window for tab to be above the title window. | ||
91 | // This should only be called by the constructor. | ||
92 | //------------------------------------------------- | ||
93 | void Tab::createTabWindow() { | ||
94 | unsigned long attrib_mask = CWBackPixmap | CWBackPixel | CWBorderPixel | | ||
95 | CWColormap | CWOverrideRedirect | CWEventMask; | ||
96 | XSetWindowAttributes attrib; | ||
97 | attrib.background_pixmap = None; | ||
98 | attrib.background_pixel = attrib.border_pixel = | ||
99 | m_win->getScreen()->getWindowStyle()->tab.border_color.pixel(); | ||
100 | attrib.colormap = m_win->getScreen()->colormap(); | ||
101 | attrib.override_redirect = True; | ||
102 | attrib.event_mask = ButtonPressMask | ButtonReleaseMask | | ||
103 | ButtonMotionMask | ExposureMask | EnterWindowMask; | ||
104 | //Notice that m_size_w gets the TOTAL width of tabs INCLUDING borders | ||
105 | m_tabwin = XCreateWindow(m_display, m_win->getScreen()->getRootWindow(), | ||
106 | -30000, -30000, //TODO: So that it wont flicker or | ||
107 | // appear before the window do | ||
108 | m_size_w - m_win->getScreen()->getWindowStyle()->tab.border_width_2x, | ||
109 | m_size_h - m_win->getScreen()->getWindowStyle()->tab.border_width_2x, | ||
110 | m_win->getScreen()->getWindowStyle()->tab.border_width, | ||
111 | m_win->getScreen()->getDepth(), InputOutput, | ||
112 | m_win->getScreen()->getVisual(), attrib_mask, &attrib); | ||
113 | |||
114 | //set grab | ||
115 | XGrabButton(m_display, Button1, Mod1Mask, m_tabwin, True, | ||
116 | ButtonReleaseMask | ButtonMotionMask, GrabModeAsync, | ||
117 | GrabModeAsync, None, Fluxbox::instance()->getMoveCursor()); | ||
118 | |||
119 | //save to tabsearch | ||
120 | Fluxbox::instance()->saveTabSearch(m_tabwin, this); | ||
121 | |||
122 | XMapSubwindows(m_display, m_tabwin); | ||
123 | // don't show if the window is iconified | ||
124 | if (!m_win->isIconic()) | ||
125 | XMapWindow(m_display, m_tabwin); | ||
126 | |||
127 | decorate(); | ||
128 | } | ||
129 | |||
130 | //-------------- focus -------------------- | ||
131 | // Called when the focus changes in m_win | ||
132 | // updates pixmap or color and draws the tab | ||
133 | //----------------------------------------- | ||
134 | void Tab::focus() { | ||
135 | |||
136 | if (m_win->isFocused()) { | ||
137 | if (m_focus_pm) | ||
138 | XSetWindowBackgroundPixmap(m_display, m_tabwin, m_focus_pm); | ||
139 | else | ||
140 | XSetWindowBackground(m_display, m_tabwin, m_focus_pixel); | ||
141 | } else { | ||
142 | if (m_unfocus_pm) | ||
143 | XSetWindowBackgroundPixmap(m_display, m_tabwin, m_unfocus_pm); | ||
144 | else | ||
145 | XSetWindowBackground(m_display, m_tabwin, m_unfocus_pixel); | ||
146 | } | ||
147 | XClearWindow(m_display, m_tabwin); | ||
148 | draw(false); | ||
149 | } | ||
150 | |||
151 | //-------------- raise -------------------- | ||
152 | // Raises the tabs in the tablist | ||
153 | //----------------------------------------- | ||
154 | void Tab::raise() { | ||
155 | //get first tab | ||
156 | /* | ||
157 | Tab *tab = 0; | ||
158 | //raise tabs | ||
159 | Workspace::Stack st; | ||
160 | for (tab = getFirst(this); tab!=0; tab = tab->m_next) { | ||
161 | st.push_back(tab->m_tabwin); | ||
162 | } | ||
163 | m_win->getScreen()->raiseWindows(st); | ||
164 | */ | ||
165 | } | ||
166 | |||
167 | //-------------- lower -------------------- | ||
168 | // Lowers the tabs in the tablist AND | ||
169 | // the windows the tabs relate to | ||
170 | //----------------------------------------- | ||
171 | void Tab::lower() { | ||
172 | Tab *current = this; | ||
173 | FluxboxWindow *win = 0; //convenience | ||
174 | //this have to be done in the correct order, otherwise we'll switch the window | ||
175 | //being ontop in the group | ||
176 | do { | ||
177 | XLowerWindow(m_display, current->m_tabwin); //lower tabwin and tabs window | ||
178 | win = current->getWindow(); | ||
179 | win->lower(); | ||
180 | |||
181 | current = current->next(); //get next | ||
182 | if (current == 0) | ||
183 | current = getFirst(this); //there weren't any after, get the first | ||
184 | |||
185 | } while (current != this); | ||
186 | } | ||
187 | |||
188 | //-------------- loadTheme ----------------- | ||
189 | // loads the texture with the correct | ||
190 | // width and height, this is necessary in | ||
191 | // vertical and relative tab modes | ||
192 | // TODO optimize this | ||
193 | //------------------------------------------ | ||
194 | void Tab::loadTheme() { | ||
195 | FbTk::ImageControl *image_ctrl = m_win->getScreen()->getImageControl(); | ||
196 | Pixmap tmp = m_focus_pm; | ||
197 | const FbTk::Texture *texture = &(m_win->getScreen()->getWindowStyle()->tab.l_focus); | ||
198 | |||
199 | if (texture->type() & FbTk::Texture::PARENTRELATIVE ) { | ||
200 | const FbTk::Texture &pt = m_win->getScreen()->getWindowStyle()->tab.t_focus; | ||
201 | if (pt.type() == (FbTk::Texture::FLAT | FbTk::Texture::SOLID)) { | ||
202 | m_focus_pm = None; | ||
203 | m_focus_pixel = pt.color().pixel(); | ||
204 | } else | ||
205 | m_focus_pm = | ||
206 | image_ctrl->renderImage(m_size_w, m_size_h, pt); | ||
207 | |||
208 | if (tmp) image_ctrl->removeImage(tmp); | ||
209 | |||
210 | } else { | ||
211 | if (texture->type() == (FbTk::Texture::FLAT | FbTk::Texture::SOLID)) { | ||
212 | m_focus_pm = None; | ||
213 | m_focus_pixel = texture->color().pixel(); | ||
214 | } else | ||
215 | m_focus_pm = | ||
216 | image_ctrl->renderImage(m_size_w, m_size_h, *texture); | ||
217 | if (tmp) image_ctrl->removeImage(tmp); | ||
218 | } | ||
219 | |||
220 | tmp = m_unfocus_pm; | ||
221 | texture = &(m_win->getScreen()->getWindowStyle()->tab.l_unfocus); | ||
222 | |||
223 | if (texture->type() & FbTk::Texture::PARENTRELATIVE ) { | ||
224 | const FbTk::Texture &pt = m_win->getScreen()->getWindowStyle()->tab.t_unfocus; | ||
225 | if (pt.type() == (FbTk::Texture::FLAT | FbTk::Texture::SOLID)) { | ||
226 | m_unfocus_pm = None; | ||
227 | m_unfocus_pixel = pt.color().pixel(); | ||
228 | } else | ||
229 | m_unfocus_pm = | ||
230 | image_ctrl->renderImage(m_size_w, m_size_h, pt); | ||
231 | } else { | ||
232 | if (texture->type() == (FbTk::Texture::FLAT | FbTk::Texture::SOLID)) { | ||
233 | m_unfocus_pm = None; | ||
234 | m_unfocus_pixel = texture->color().pixel(); | ||
235 | } else | ||
236 | m_unfocus_pm = | ||
237 | image_ctrl->renderImage(m_size_w, m_size_h, *texture); | ||
238 | } | ||
239 | |||
240 | if (tmp) image_ctrl->removeImage(tmp); | ||
241 | } | ||
242 | |||
243 | /** | ||
244 | decorates the tab with current theme | ||
245 | */ | ||
246 | void Tab::decorate() { | ||
247 | loadTheme(); | ||
248 | |||
249 | XSetWindowBorderWidth(m_display, m_tabwin, | ||
250 | m_win->getScreen()->getWindowStyle()->tab.border_width); | ||
251 | XSetWindowBorder(m_display, m_tabwin, | ||
252 | m_win->getScreen()->getWindowStyle()->tab.border_color.pixel()); | ||
253 | } | ||
254 | |||
255 | /** | ||
256 | Deiconifies the tab | ||
257 | Used from FluxboxWindow to deiconify the tab when the window is deiconfied | ||
258 | */ | ||
259 | void Tab::deiconify() { | ||
260 | XMapWindow(m_display, m_tabwin); | ||
261 | } | ||
262 | |||
263 | /** | ||
264 | Iconifies the tab. | ||
265 | Used from FluxboxWindow to hide tab win when window is iconified | ||
266 | disconnects itself from the list | ||
267 | */ | ||
268 | void Tab::iconify() { | ||
269 | disconnect(); | ||
270 | withdraw(); | ||
271 | if(!Fluxbox::instance()->useTabs() && !m_next && !m_prev)//if we don't want to use tabs that much | ||
272 | m_win->setTab(false);//let's get rid of this loner tab | ||
273 | } | ||
274 | |||
275 | /** | ||
276 | Unmaps the tab from display | ||
277 | */ | ||
278 | void Tab::withdraw() { | ||
279 | XUnmapWindow(m_display, m_tabwin); | ||
280 | } | ||
281 | |||
282 | /** | ||
283 | Set/reset the the sticky on all windows in the list | ||
284 | */ | ||
285 | void Tab::stick() { | ||
286 | Tab *tab; | ||
287 | |||
288 | bool wasstuck = m_win->isStuck(); | ||
289 | |||
290 | //now do stick for all windows in the list | ||
291 | for (tab = getFirst(this); tab != 0; tab = tab->m_next) { | ||
292 | FluxboxWindow *win = tab->m_win; //just for convenience | ||
293 | if (wasstuck) { | ||
294 | win->blackbox_attrib.flags ^= BaseDisplay::ATTRIB_OMNIPRESENT; | ||
295 | win->blackbox_attrib.attrib ^= BaseDisplay::ATTRIB_OMNIPRESENT; | ||
296 | win->stuck = false; | ||
297 | |||
298 | } else { | ||
299 | win->stuck = true; | ||
300 | BScreen *screen = win->getScreen(); | ||
301 | if (!win->isIconic() && !(win->getWorkspaceNumber() != | ||
302 | screen->getCurrentWorkspaceID())) { | ||
303 | screen->reassociateWindow(win, screen->getCurrentWorkspaceID(), true); | ||
304 | } | ||
305 | |||
306 | win->blackbox_attrib.flags |= BaseDisplay::ATTRIB_OMNIPRESENT; | ||
307 | win->blackbox_attrib.attrib |= BaseDisplay::ATTRIB_OMNIPRESENT; | ||
308 | } | ||
309 | |||
310 | win->setState(win->current_state); | ||
311 | } | ||
312 | |||
313 | } | ||
314 | |||
315 | /** | ||
316 | Resize the window's in the tablist | ||
317 | */ | ||
318 | void Tab::resize() { | ||
319 | Tab *tab; | ||
320 | |||
321 | //now move and resize the windows in the list | ||
322 | for (tab = getFirst(this); tab != 0; tab = tab->m_next) { | ||
323 | if (tab!=this) { | ||
324 | tab->m_win->moveResize(m_win->getXFrame(), m_win->getYFrame(), | ||
325 | m_win->getWidth(), m_win->getHeight()); | ||
326 | } | ||
327 | } | ||
328 | |||
329 | // need to resize tabs if in relative mode | ||
330 | if (m_win->getScreen()->getTabAlignment() == ARELATIVE) { | ||
331 | calcIncrease(); | ||
332 | setPosition(); | ||
333 | } | ||
334 | } | ||
335 | |||
336 | /** | ||
337 | Shades the windows in the tablist | ||
338 | */ | ||
339 | void Tab::shade() { | ||
340 | Tab *tab; | ||
341 | |||
342 | for(tab = getFirst(this); tab != 0; tab = tab->m_next) { | ||
343 | if (tab==this) | ||
344 | continue; | ||
345 | tab->m_win->shade(); | ||
346 | } | ||
347 | |||
348 | if (m_win->getScreen()->getTabPlacement() == PLEFT || | ||
349 | m_win->getScreen()->getTabPlacement() == PRIGHT) { | ||
350 | resizeGroup(); | ||
351 | calcIncrease(); | ||
352 | } | ||
353 | |||
354 | if (!(m_win->getScreen()->getTabPlacement() == PTOP)) | ||
355 | setPosition(); | ||
356 | } | ||
357 | |||
358 | /** | ||
359 | Draws the tab | ||
360 | if pressed = true then it draws the tab in pressed | ||
361 | mode else it draws it in normal mode | ||
362 | TODO: the "draw in pressed mode" | ||
363 | */ | ||
364 | void Tab::draw(bool pressed) const { | ||
365 | XClearWindow(m_display, m_tabwin); | ||
366 | |||
367 | if (m_win->getTitle().size() == 0) // we don't have anything to draw | ||
368 | return; | ||
369 | |||
370 | GC gc = ((m_win->isFocused()) ? m_win->getScreen()->getWindowStyle()->tab.l_text_focus_gc : | ||
371 | m_win->getScreen()->getWindowStyle()->tab.l_text_unfocus_gc); | ||
372 | |||
373 | Theme::WindowStyle *winstyle = m_win->getScreen()->getWindowStyle(); | ||
374 | size_t dlen = m_win->getTitle().size(); | ||
375 | |||
376 | size_t max_width = m_size_w; // special cases in rotated mode | ||
377 | if (winstyle->tab.font.isRotated() && !m_win->isShaded()) | ||
378 | max_width = m_size_h; | ||
379 | |||
380 | int dx = DrawUtil::doAlignment(max_width, 1, //m_win->frame.bevel_w, | ||
381 | winstyle->tab.justify, | ||
382 | winstyle->tab.font, | ||
383 | m_win->getTitle().c_str(), m_win->getTitle().size(), dlen); | ||
384 | |||
385 | int dy = winstyle->tab.font.ascent() + 1; //m_win->frame.bevel_w; | ||
386 | bool rotate = false; | ||
387 | // swap dx and dy if we're rotated | ||
388 | if (winstyle->tab.font.isRotated() && !m_win->isShaded()) { | ||
389 | int tmp = dy; | ||
390 | dy = m_size_h - dx; // upside down (reverse direction) | ||
391 | dx = tmp; | ||
392 | rotate = true; | ||
393 | } | ||
394 | // draw normal without rotation | ||
395 | winstyle->tab.font.drawText( | ||
396 | m_tabwin, | ||
397 | m_win->getScreen()->getScreenNumber(), | ||
398 | gc, | ||
399 | m_win->getTitle().c_str(), dlen, | ||
400 | dx, dy, | ||
401 | rotate); | ||
402 | } | ||
403 | |||
404 | /** | ||
405 | Helper for the Tab::setPosition() call | ||
406 | returns the y position component correctly | ||
407 | according to shading in cases PBOTTOM and | ||
408 | isShaded() | ||
409 | */ | ||
410 | int Tab::setPositionShadingHelper(bool shaded) { | ||
411 | if (shaded) { | ||
412 | return m_win->getYFrame() + m_win->getTitleHeight() + | ||
413 | m_win->getScreen()->getBorderWidth2x(); | ||
414 | } else { | ||
415 | return m_win->getYFrame() + m_win->getHeight() + | ||
416 | m_win->getScreen()->getBorderWidth2x(); | ||
417 | } | ||
418 | } | ||
419 | |||
420 | /** | ||
421 | Helpers for correct alignment of tabs used | ||
422 | by the setPosition() call | ||
423 | return x/y positions correctly according to | ||
424 | alignment, the 1st for cases PTOP and PBOTTOM | ||
425 | the 2nd for cases PLEFT and PRIGHT | ||
426 | */ | ||
427 | int Tab::setPositionTBAlignHelper(Alignment align) { | ||
428 | switch(align) { | ||
429 | |||
430 | case ARELATIVE: | ||
431 | case ALEFT: | ||
432 | return m_win->getXFrame(); | ||
433 | break; | ||
434 | case ACENTER: | ||
435 | return calcCenterXPos(); | ||
436 | break; | ||
437 | case ARIGHT: | ||
438 | return m_win->getXFrame() + m_win->getWidth() + | ||
439 | m_win->getScreen()->getBorderWidth2x() - m_size_w; | ||
440 | default: | ||
441 | #ifdef DEBUG | ||
442 | cerr << __FILE__ << ":" <<__LINE__ << ": " << | ||
443 | "Unsupported Alignment" << endl; | ||
444 | #endif //DEBUG | ||
445 | return 0; | ||
446 | break; | ||
447 | } | ||
448 | } | ||
449 | |||
450 | int Tab::setPositionLRAlignHelper(Alignment align) { | ||
451 | switch(align) { | ||
452 | case ALEFT: | ||
453 | return m_win->getYFrame() - m_size_h + m_win->getHeight() + | ||
454 | m_win->getScreen()->getBorderWidth2x(); | ||
455 | break; | ||
456 | case ACENTER: | ||
457 | return calcCenterYPos(); | ||
458 | break; | ||
459 | case ARELATIVE: | ||
460 | case ARIGHT: | ||
461 | return m_win->getYFrame(); | ||
462 | break; | ||
463 | default: | ||
464 | #ifdef DEBUG | ||
465 | cerr << __FILE__ << ":"<< __LINE__ << ": " << | ||
466 | "Unsupported Alignment" << endl; | ||
467 | #endif //DEBUG | ||
468 | return 0; | ||
469 | break; | ||
470 | } | ||
471 | } | ||
472 | |||
473 | /** | ||
474 | Position tab ( follow the m_win pos ). | ||
475 | (and resize) | ||
476 | Set new position of the other tabs in the chain | ||
477 | */ | ||
478 | void Tab::setPosition() { | ||
479 | //don't do anything if the tablist is freezed | ||
480 | if (m_stoptabs) | ||
481 | return; | ||
482 | |||
483 | Tab *tab; | ||
484 | int pos_x = 0, pos_y = 0; | ||
485 | |||
486 | m_stoptabs = true; //freeze tablist | ||
487 | |||
488 | //and check for max tabs | ||
489 | |||
490 | //Tab placement + alignment | ||
491 | switch (m_win->getScreen()->getTabPlacement()) { | ||
492 | case PTOP: | ||
493 | pos_y = m_win->getYFrame() - m_size_h; | ||
494 | pos_x = setPositionTBAlignHelper( | ||
495 | m_win->getScreen()->getTabAlignment()); | ||
496 | break; | ||
497 | case PBOTTOM: | ||
498 | pos_y = setPositionShadingHelper(m_win->isShaded()); | ||
499 | pos_x = setPositionTBAlignHelper( | ||
500 | m_win->getScreen()->getTabAlignment()); | ||
501 | break; | ||
502 | case PLEFT: | ||
503 | pos_x = m_win->isShaded() ? | ||
504 | setPositionTBAlignHelper(m_win->getScreen()->getTabAlignment()) : | ||
505 | m_win->getXFrame() - m_size_w; | ||
506 | pos_y = m_win->isShaded() ? | ||
507 | setPositionShadingHelper(true) : | ||
508 | setPositionLRAlignHelper(m_win->getScreen()->getTabAlignment()); | ||
509 | break; | ||
510 | case PRIGHT: | ||
511 | pos_x = m_win->isShaded() ? | ||
512 | setPositionTBAlignHelper(m_win->getScreen()->getTabAlignment()) : | ||
513 | m_win->getXFrame() + m_win->getWidth() + | ||
514 | m_win->getScreen()->getBorderWidth2x(); | ||
515 | pos_y = m_win->isShaded() ? | ||
516 | setPositionShadingHelper(true) : | ||
517 | setPositionLRAlignHelper(m_win->getScreen()->getTabAlignment()); | ||
518 | break; | ||
519 | default: | ||
520 | if(m_win->isShaded()) { | ||
521 | pos_y = setPositionShadingHelper(true); | ||
522 | pos_x = setPositionTBAlignHelper( | ||
523 | m_win->getScreen()->getTabAlignment()); | ||
524 | } else { | ||
525 | setPositionShadingHelper(false); | ||
526 | } | ||
527 | break; | ||
528 | } | ||
529 | |||
530 | for (tab = getFirst(this); | ||
531 | tab!=0; | ||
532 | pos_x += tab->m_inc_x, pos_y += tab->m_inc_y, | ||
533 | tab = tab->m_next){ | ||
534 | |||
535 | XMoveWindow(m_display, tab->m_tabwin, pos_x, pos_y); | ||
536 | |||
537 | //dont move FluxboxWindow if the iterator = this | ||
538 | if (tab != this) { | ||
539 | tab->m_win->moveResize(m_win->getXFrame(), m_win->getYFrame(), | ||
540 | m_win->getWidth(), m_win->getHeight()); | ||
541 | } | ||
542 | } | ||
543 | |||
544 | m_stoptabs = false;//thaw tablist | ||
545 | } | ||
546 | |||
547 | //Moves the tab to the left | ||
548 | void Tab::movePrev() { | ||
549 | insert(m_prev); | ||
550 | } | ||
551 | |||
552 | //Moves the tab to the next tab if m_next != 0 | ||
553 | void Tab::moveNext() { | ||
554 | if(m_next == 0) | ||
555 | return; | ||
556 | Tab *tmp = m_next; | ||
557 | disconnect(); | ||
558 | tmp->insert(this); | ||
559 | } | ||
560 | |||
561 | |||
562 | /** | ||
563 | calculates m_inc_x and m_inc_y for tabs | ||
564 | used for positioning the tabs. | ||
565 | */ | ||
566 | void Tab::calcIncrease() { | ||
567 | Tab *tab; | ||
568 | int inc_x = 0, inc_y = 0; | ||
569 | unsigned int i = 0, tabs = numObjects(); | ||
570 | |||
571 | if (m_win->getScreen()->getTabPlacement() == PTOP || | ||
572 | m_win->getScreen()->getTabPlacement() == PBOTTOM || | ||
573 | m_win->isShaded()) { | ||
574 | inc_y = 0; | ||
575 | |||
576 | switch(m_win->getScreen()->getTabAlignment()) { | ||
577 | case ALEFT: | ||
578 | inc_x = m_size_w; | ||
579 | break; | ||
580 | case ACENTER: | ||
581 | inc_x = m_size_w; | ||
582 | break; | ||
583 | case ARIGHT: | ||
584 | inc_x = -m_size_w; | ||
585 | break; | ||
586 | case ARELATIVE: | ||
587 | inc_x = calcRelativeWidth(); | ||
588 | break; | ||
589 | default: | ||
590 | break; | ||
591 | } | ||
592 | } else if (m_win->getScreen()->getTabPlacement() == PLEFT || | ||
593 | m_win->getScreen()->getTabPlacement() == PRIGHT) { | ||
594 | inc_x = 0; | ||
595 | |||
596 | switch(m_win->getScreen()->getTabAlignment()) { | ||
597 | case ALEFT: | ||
598 | inc_y = -m_size_h; | ||
599 | break; | ||
600 | case ACENTER: | ||
601 | inc_y = m_size_h; | ||
602 | break; | ||
603 | case ARIGHT: | ||
604 | inc_y = m_size_h; | ||
605 | break; | ||
606 | case ARELATIVE: | ||
607 | inc_y = calcRelativeHeight(); | ||
608 | break; | ||
609 | default: | ||
610 | break; | ||
611 | } | ||
612 | } | ||
613 | |||
614 | for (tab = getFirst(this); tab!=0; tab = tab->m_next, i++) { | ||
615 | |||
616 | //TODO: move this out from here? | ||
617 | if ((m_win->getScreen()->getTabPlacement() == PTOP || | ||
618 | m_win->getScreen()->getTabPlacement() == PBOTTOM || | ||
619 | m_win->isShaded()) && | ||
620 | m_win->getScreen()->getTabAlignment() == ARELATIVE) { | ||
621 | if (!((m_win->getWidth() + | ||
622 | m_win->getScreen()->getBorderWidth2x()) % tabs) || | ||
623 | i >= ((m_win->getWidth() + | ||
624 | m_win->getScreen()->getBorderWidth2x()) % tabs)) { | ||
625 | tab->setTabWidth(inc_x); | ||
626 | tab->m_inc_x = inc_x; | ||
627 | } else { // adding 1 extra pixel to get tabs like win width | ||
628 | tab->setTabWidth(inc_x + 1); | ||
629 | tab->m_inc_x = inc_x + 1; | ||
630 | } | ||
631 | tab->m_inc_y = inc_y; | ||
632 | } else if (m_win->getScreen()->getTabAlignment() == ARELATIVE) { | ||
633 | if (!((m_win->getHeight() + | ||
634 | m_win->getScreen()->getBorderWidth2x()) % tabs) || | ||
635 | i >= ((m_win->getHeight() + | ||
636 | m_win->getScreen()->getBorderWidth2x()) % tabs)) { | ||
637 | |||
638 | tab->setTabHeight(inc_y); | ||
639 | tab->m_inc_y = inc_y; | ||
640 | } else { | ||
641 | // adding 1 extra pixel to get tabs match window width | ||
642 | tab->setTabHeight(inc_y + 1); | ||
643 | tab->m_inc_y = inc_y + 1; | ||
644 | } | ||
645 | tab->m_inc_x = inc_x; | ||
646 | } else { // non relative modes | ||
647 | tab->m_inc_x = inc_x; | ||
648 | tab->m_inc_y = inc_y; | ||
649 | } | ||
650 | } | ||
651 | } | ||
652 | |||
653 | /** | ||
654 | Handle button press event here. | ||
655 | */ | ||
656 | void Tab::buttonPressEvent(XButtonEvent *be) { | ||
657 | //draw in pressed mode | ||
658 | draw(true); | ||
659 | |||
660 | //invoke root menu with auto-tab? | ||
661 | /* if (be->button == 3) { | ||
662 | BScreen *screen = m_win->getScreen(); | ||
663 | Rootmenu *rootmenu = screen->getRootmenu(); | ||
664 | if (! rootmenu->isVisible()) { | ||
665 | Fluxbox::instance()->checkMenu(); | ||
666 | screen->getRootmenu()->move(be->x_root, be->y_root-rootmenu->titleHeight()); | ||
667 | rootmenu->setAutoGroupWindow(m_win->getClientWindow()); | ||
668 | rootmenu->show(); | ||
669 | } | ||
670 | } | ||
671 | |||
672 | //otherwise let the window handle the event | ||
673 | else { | ||
674 | //set window to titlewindow so we can take advantage of drag function | ||
675 | be->window = m_win->frame().titlebar().window(); | ||
676 | |||
677 | //call windows buttonpress eventhandler | ||
678 | m_win->buttonPressEvent(*be); | ||
679 | } | ||
680 | */ | ||
681 | } | ||
682 | |||
683 | /** | ||
684 | Handle button release event here. | ||
685 | If tab is dropped then it should try to find | ||
686 | the window where the tab where dropped. | ||
687 | */ | ||
688 | void Tab::buttonReleaseEvent(XButtonEvent *be) { | ||
689 | |||
690 | if (m_moving) { | ||
691 | |||
692 | m_moving = false; | ||
693 | |||
694 | //erase tabmoving rectangle | ||
695 | XDrawRectangle(m_display, m_win->getScreen()->getRootWindow(), | ||
696 | m_win->getScreen()->getOpGC(), | ||
697 | m_move_x, m_move_y, | ||
698 | m_size_w, m_size_h); | ||
699 | |||
700 | Fluxbox::instance()->ungrab(); | ||
701 | XUngrabPointer(m_display, CurrentTime); | ||
702 | |||
703 | //storage of window and pos of window where we dropped the tab | ||
704 | Window child; | ||
705 | int dest_x = 0, dest_y = 0; | ||
706 | |||
707 | //find window on coordinates of buttonReleaseEvent | ||
708 | if (XTranslateCoordinates(m_display, m_win->getScreen()->getRootWindow(), | ||
709 | m_win->getScreen()->getRootWindow(), | ||
710 | be->x_root, be->y_root, &dest_x, &dest_y, &child)) { | ||
711 | |||
712 | Tab *tab = Fluxbox::instance()->searchTab(child); | ||
713 | FluxboxWindow *win = Fluxbox::instance()->searchWindow(child); | ||
714 | if(win!=0 && m_win->getScreen()->isSloppyWindowGrouping()) | ||
715 | win->setTab(true); | ||
716 | //search tablist for a tabwindow | ||
717 | if ( (tab!=0) || (m_win->getScreen()->isSloppyWindowGrouping() && | ||
718 | (win!=0) && (tab = win->getTab())!=0)) { | ||
719 | |||
720 | if (tab == this) // inserting ourself to ourself causes a disconnect | ||
721 | return; | ||
722 | |||
723 | // do only attach a hole chain if we dropped the | ||
724 | // first tab in the dropped chain... | ||
725 | if (m_prev) | ||
726 | disconnect(); | ||
727 | |||
728 | // attach this tabwindow chain to the tabwindow chain we found. | ||
729 | tab->insert(this); | ||
730 | |||
731 | } else { //Dropped nowhere | ||
732 | disconnect(); | ||
733 | |||
734 | // convenience | ||
735 | unsigned int placement = m_win->getScreen()->getTabPlacement(); | ||
736 | |||
737 | // (ab)using dest_x and dest_y | ||
738 | dest_x = be->x_root; | ||
739 | dest_y = be->y_root; | ||
740 | |||
741 | if (placement == PTOP || placement == PBOTTOM || m_win->isShaded()) { | ||
742 | if (placement == PBOTTOM && !m_win->isShaded()) | ||
743 | dest_y -= m_win->getHeight(); | ||
744 | else if (placement != PTOP && m_win->isShaded()) | ||
745 | dest_y -= m_win->getTitleHeight(); | ||
746 | else // PTOP | ||
747 | dest_y += m_win->getTitleHeight(); | ||
748 | |||
749 | switch(m_win->getScreen()->getTabAlignment()) { | ||
750 | case ACENTER: | ||
751 | dest_x -= (m_win->getWidth() / 2) - (m_size_w / 2); | ||
752 | break; | ||
753 | case ARIGHT: | ||
754 | dest_x -= m_win->getWidth() - m_size_w; | ||
755 | break; | ||
756 | default: | ||
757 | break; | ||
758 | } | ||
759 | |||
760 | } else { // PLEFT & PRIGHT | ||
761 | if (placement == PRIGHT) | ||
762 | dest_x = be->x_root - m_win->getWidth(); | ||
763 | |||
764 | switch(m_win->getScreen()->getTabAlignment()) { | ||
765 | case ACENTER: | ||
766 | dest_y -= (m_win->getHeight() / 2) - (m_size_h / 2); | ||
767 | break; | ||
768 | case ALEFT: | ||
769 | dest_y -= m_win->getHeight() - m_size_h; | ||
770 | break; | ||
771 | default: | ||
772 | break; | ||
773 | } | ||
774 | } | ||
775 | //TODO: this causes an calculate increase event, even if we | ||
776 | // only are moving a window | ||
777 | m_win->moveResize(dest_x, dest_y, m_win->getWidth(), m_win->getHeight()); | ||
778 | |||
779 | if(!Fluxbox::instance()->useTabs()) | ||
780 | m_win->setTab(false);//Remove tab from window, as it is now alone... | ||
781 | } | ||
782 | } | ||
783 | } else { | ||
784 | |||
785 | //raise this tabwindow | ||
786 | raise(); | ||
787 | |||
788 | //set window to title window soo we can use m_win handler for menu | ||
789 | be->window = m_win->frame().titlebar().window(); | ||
790 | |||
791 | //call windows buttonrelease event handler so it can popup a menu if needed | ||
792 | m_win->buttonReleaseEvent(*be); | ||
793 | } | ||
794 | |||
795 | } | ||
796 | |||
797 | //------------- exposeEvent ------------ | ||
798 | // Handle expose event here. | ||
799 | // Draws the tab unpressed | ||
800 | //-------------------------------------- | ||
801 | void Tab::exposeEvent(XExposeEvent *ee) { | ||
802 | draw(false); | ||
803 | } | ||
804 | |||
805 | //----------- motionNotifyEvent -------- | ||
806 | // Handles motion event here | ||
807 | // Draws the rectangle of moving tab | ||
808 | //-------------------------------------- | ||
809 | void Tab::motionNotifyEvent(XMotionEvent *me) { | ||
810 | |||
811 | Fluxbox *fluxbox = Fluxbox::instance(); | ||
812 | |||
813 | //if mousebutton 2 is pressed | ||
814 | if (me->state & Button2Mask) { | ||
815 | if (!m_moving) { | ||
816 | m_moving = true; | ||
817 | |||
818 | XGrabPointer(m_display, me->window, False, Button2MotionMask | | ||
819 | ButtonReleaseMask, GrabModeAsync, GrabModeAsync, | ||
820 | None, fluxbox->getMoveCursor(), CurrentTime); | ||
821 | |||
822 | fluxbox->grab(); | ||
823 | |||
824 | m_move_x = me->x_root - 1; | ||
825 | m_move_y = me->y_root - 1; | ||
826 | |||
827 | XDrawRectangle(m_display, m_win->getScreen()->getRootWindow(), | ||
828 | m_win->getScreen()->getOpGC(), | ||
829 | m_move_x, m_move_y, | ||
830 | m_size_w, m_size_h); | ||
831 | |||
832 | } else { | ||
833 | |||
834 | int dx = me->x_root - 1, dy = me->y_root - 1; | ||
835 | |||
836 | dx -= m_win->getScreen()->getBorderWidth(); | ||
837 | dy -= m_win->getScreen()->getBorderWidth(); | ||
838 | |||
839 | if (m_win->getScreen()->getEdgeSnapThreshold()) { | ||
840 | int drx = m_win->getScreen()->getWidth() - (dx + 1); | ||
841 | |||
842 | if (dx > 0 && dx < drx && dx < m_win->getScreen()->getEdgeSnapThreshold()) | ||
843 | dx = 0; | ||
844 | else if (drx > 0 && drx < m_win->getScreen()->getEdgeSnapThreshold()) | ||
845 | dx = m_win->getScreen()->getWidth() - 1; | ||
846 | |||
847 | int dtty, dbby, dty, dby; | ||
848 | |||
849 | dty = dy - dtty; | ||
850 | dby = dbby - (dy + 1); | ||
851 | |||
852 | if (dy > 0 && dty < m_win->getScreen()->getEdgeSnapThreshold()) | ||
853 | dy = dtty; | ||
854 | else if (dby > 0 && dby < m_win->getScreen()->getEdgeSnapThreshold()) | ||
855 | dy = dbby - 1; | ||
856 | |||
857 | } | ||
858 | |||
859 | //erase rectangle | ||
860 | XDrawRectangle(m_display, m_win->getScreen()->getRootWindow(), | ||
861 | m_win->getScreen()->getOpGC(), | ||
862 | m_move_x, m_move_y, | ||
863 | m_size_w, m_size_h); | ||
864 | |||
865 | //redraw rectangle at new pos | ||
866 | m_move_x = dx; | ||
867 | m_move_y = dy; | ||
868 | XDrawRectangle(m_display, m_win->getScreen()->getRootWindow(), | ||
869 | m_win->getScreen()->getOpGC(), | ||
870 | m_move_x, m_move_y, | ||
871 | m_size_w, m_size_h); | ||
872 | |||
873 | } | ||
874 | } | ||
875 | } | ||
876 | |||
877 | //-------------- getFirst() --------- | ||
878 | // Returns the first Tab in the chain | ||
879 | // of currentchain. | ||
880 | //----------------------------------- | ||
881 | Tab *Tab::getFirst(Tab *current) { | ||
882 | if (!current) | ||
883 | return 0; | ||
884 | |||
885 | Tab *i=current; | ||
886 | |||
887 | for (; i->m_prev != 0; i = i->m_prev); | ||
888 | return i; | ||
889 | } | ||
890 | |||
891 | //-------------- getLast() --------- | ||
892 | // Returns the last Tab in the chain | ||
893 | // of currentchain. | ||
894 | //----------------------------------- | ||
895 | Tab *Tab::getLast(Tab *current) { | ||
896 | if (!current) | ||
897 | return 0; | ||
898 | Tab *i=current; | ||
899 | |||
900 | for (; i->m_next != 0; i = i->m_next); | ||
901 | return i; | ||
902 | } | ||
903 | |||
904 | //-------------- insert ------------ | ||
905 | // (private) | ||
906 | // Inserts a tab in the chain | ||
907 | //---------------------------------- | ||
908 | void Tab::insert(Tab *tab) { | ||
909 | |||
910 | if (!tab || tab == this) //dont insert if the tab = 0 or the tab = this | ||
911 | return; | ||
912 | |||
913 | Tab *first = getFirst(this); | ||
914 | |||
915 | //if the tab already in chain then disconnect it | ||
916 | for (; first!=0; first = first->m_next) { | ||
917 | if (first==tab) { | ||
918 | #ifdef DEBUG | ||
919 | cerr<<"Tab already in chain. Disconnecting!"<<endl; | ||
920 | #endif // DEBUG | ||
921 | tab->disconnect(); | ||
922 | break; | ||
923 | } | ||
924 | } | ||
925 | |||
926 | //get last tab in the chain to be inserted | ||
927 | Tab *last = tab; | ||
928 | for (; last->m_next!=0; last=last->m_next); | ||
929 | //do sticky before we connect it to the chain | ||
930 | //sticky bit on window | ||
931 | if (m_win->isStuck() != tab->m_win->isStuck()) { | ||
932 | tab->m_win->stuck = !m_win->stuck; // it will toggle | ||
933 | tab->stick(); //this will set all the m_wins in the list | ||
934 | } | ||
935 | |||
936 | //connect the tab to this chain | ||
937 | |||
938 | if (m_next) | ||
939 | m_next->m_prev = last; | ||
940 | tab->m_prev = this; | ||
941 | last->m_next = m_next; | ||
942 | |||
943 | m_next = tab; | ||
944 | |||
945 | bool resize_tabs = false; | ||
946 | |||
947 | //TODO: cleanup and optimize | ||
948 | //move and resize all windows in the tablist we inserted | ||
949 | //only from first tab of the inserted chain to the last | ||
950 | for (; tab!=last->m_next; tab=tab->m_next) { | ||
951 | if (m_win->isShaded() != tab->m_win->isShaded()) { | ||
952 | tab->m_stoptabs = true; // we don't want any actions performed on the | ||
953 | // tabs, just the tab windows! | ||
954 | if (m_win->getScreen()->getTabPlacement() == PLEFT || | ||
955 | m_win->getScreen()->getTabPlacement() == PRIGHT) | ||
956 | resize_tabs = true; | ||
957 | |||
958 | // if the window we are grouping to, we need to shade the tab window | ||
959 | // _after_ reconfigure | ||
960 | if(m_win->isShaded()) { | ||
961 | tab->m_win->moveResize(m_win->getXFrame(), m_win->getYFrame(), | ||
962 | m_win->getWidth(), m_win->getHeight()); | ||
963 | tab->m_win->shade(); | ||
964 | } else { | ||
965 | tab->m_win->shade(); // switch to correct shade state | ||
966 | tab->m_win->moveResize(m_win->getXFrame(), m_win->getYFrame(), | ||
967 | m_win->getWidth(), m_win->getHeight()); | ||
968 | } | ||
969 | |||
970 | tab->m_stoptabs = false; | ||
971 | |||
972 | // both window have the same shaded state and have different sizes, | ||
973 | // checking this so that I'll only do shade on windows if configure did | ||
974 | // anything. | ||
975 | } else if ((m_win->getWidth() != tab->m_win->getWidth()) || | ||
976 | (m_win->getHeight() != tab->m_win->getHeight())) { | ||
977 | |||
978 | tab->m_win->moveResize(m_win->getXFrame(), m_win->getYFrame(), | ||
979 | m_win->getWidth(), m_win->getHeight()); | ||
980 | |||
981 | // need to shade the tab window as configure will mess it up | ||
982 | if (m_win->isShaded()) | ||
983 | tab->m_win->shade(); | ||
984 | } | ||
985 | } | ||
986 | |||
987 | // resize if in relative mode or resize_tabs is true | ||
988 | if(m_win->getScreen()->getTabAlignment() == ARELATIVE || | ||
989 | resize_tabs) { | ||
990 | resizeGroup(); | ||
991 | calcIncrease(); | ||
992 | } | ||
993 | // reposition tabs | ||
994 | setPosition(); | ||
995 | } | ||
996 | |||
997 | //---------- disconnect() -------------- | ||
998 | // Disconnects the tab from any chain | ||
999 | //-------------------------------------- | ||
1000 | void Tab::disconnect() { | ||
1001 | Tab *tmp = 0; | ||
1002 | |||
1003 | Fluxbox *fluxbox = Fluxbox::instance(); | ||
1004 | if (m_prev) { //if this have a chain to "the left" (previous tab) then set it's next to this next | ||
1005 | m_prev->m_next = m_next; | ||
1006 | if(!m_next && !fluxbox->useTabs())//Only two tabs in list, remove tab from remaining window | ||
1007 | m_prev->m_win->setTab(false); | ||
1008 | else | ||
1009 | tmp = m_prev; | ||
1010 | } | ||
1011 | if (m_next) { //if this have a chain to "the right" (next tab) then set it's prev to this prev | ||
1012 | m_next->m_prev = m_prev; | ||
1013 | if(!m_prev && !fluxbox->useTabs())//Only two tabs in list, remove tab from remaining window | ||
1014 | m_next->m_win->setTab(false); | ||
1015 | else | ||
1016 | tmp = m_next; | ||
1017 | } | ||
1018 | |||
1019 | //mark as no chain, previous and next. | ||
1020 | m_prev = 0; | ||
1021 | m_next = 0; | ||
1022 | |||
1023 | //reposition the tabs | ||
1024 | if (tmp) { | ||
1025 | if (m_win->getScreen()->getTabAlignment() == ARELATIVE) | ||
1026 | tmp->calcIncrease(); | ||
1027 | tmp->setPosition(); | ||
1028 | } | ||
1029 | |||
1030 | if (m_win->getScreen()->getTabAlignment() == ARELATIVE) | ||
1031 | calcIncrease(); | ||
1032 | |||
1033 | setPosition(); | ||
1034 | } | ||
1035 | |||
1036 | // ------------ setTabWidth -------------- | ||
1037 | // Sets Tab width _including_ borders | ||
1038 | // --------------------------------------- | ||
1039 | void Tab::setTabWidth(unsigned int w) { | ||
1040 | if (w > m_win->getScreen()->getWindowStyle()->tab.border_width_2x && | ||
1041 | w != m_size_w) { | ||
1042 | m_size_w = w; | ||
1043 | XResizeWindow(m_display, m_tabwin, | ||
1044 | m_size_w - m_win->getScreen()->getWindowStyle()->tab.border_width_2x, | ||
1045 | m_size_h - m_win->getScreen()->getWindowStyle()->tab.border_width_2x); | ||
1046 | |||
1047 | loadTheme(); // rerender themes to right size | ||
1048 | focus(); // redraw the window | ||
1049 | } | ||
1050 | } | ||
1051 | |||
1052 | // ------------ setTabHeight --------- | ||
1053 | // Sets Tab height _including_ borders | ||
1054 | // --------------------------------------- | ||
1055 | void Tab::setTabHeight(unsigned int h) { | ||
1056 | if (h > m_win->getScreen()->getWindowStyle()->tab.border_width_2x && | ||
1057 | h != m_size_h) { | ||
1058 | m_size_h = h; | ||
1059 | XResizeWindow(m_display, m_tabwin, | ||
1060 | m_size_w - m_win->getScreen()->getWindowStyle()->tab.border_width_2x, | ||
1061 | m_size_h - m_win->getScreen()->getWindowStyle()->tab.border_width_2x); | ||
1062 | |||
1063 | loadTheme(); // rerender themes to right size | ||
1064 | focus(); // redraw the window | ||
1065 | } | ||
1066 | } | ||
1067 | |||
1068 | // ------------ resizeGroup -------------- | ||
1069 | // This function is used when (un)shading | ||
1070 | // to get right size/width of tabs when | ||
1071 | // PLeft || PRight && isTabRotateVertical | ||
1072 | // --------------------------------------- | ||
1073 | void Tab::resizeGroup() { | ||
1074 | |||
1075 | Tab *first; | ||
1076 | for (first = getFirst(this); first != 0; first = first->m_next) { | ||
1077 | if ((m_win->getScreen()->getTabPlacement() == PLEFT || | ||
1078 | m_win->getScreen()->getTabPlacement() == PRIGHT) && | ||
1079 | m_win->getScreen()->isTabRotateVertical() && | ||
1080 | !m_win->isShaded()) { | ||
1081 | first->setTabWidth(m_win->getScreen()->getTabHeight()); | ||
1082 | first->setTabHeight(m_win->getScreen()->getTabWidth()); | ||
1083 | } else { | ||
1084 | first->setTabWidth(m_win->getScreen()->getTabWidth()); | ||
1085 | first->setTabHeight(m_win->getScreen()->getTabHeight()); | ||
1086 | } | ||
1087 | //TODO: do I have to set this all the time? | ||
1088 | first->m_configured = true; //used in Fluxbox::reconfigure() | ||
1089 | } | ||
1090 | } | ||
1091 | |||
1092 | //------------- calcRelativeWidth -------- | ||
1093 | // Returns: Calculated width for relative | ||
1094 | // alignment | ||
1095 | //---------------------------------------- | ||
1096 | unsigned int Tab::calcRelativeWidth() { | ||
1097 | unsigned int num=0; | ||
1098 | //calculate num objs in list (extract this to a function?) | ||
1099 | for (Tab *first=getFirst(this); first!=0; first=first->m_next, num++); | ||
1100 | |||
1101 | return ((m_win->getWidth() + m_win->getScreen()->getBorderWidth2x())/num); | ||
1102 | } | ||
1103 | |||
1104 | /** | ||
1105 | Returns the number of objects in | ||
1106 | the TabGroup. | ||
1107 | */ | ||
1108 | unsigned int Tab::numObjects() { | ||
1109 | unsigned int num = 0; | ||
1110 | for (Tab *tab = getFirst(this); tab != 0; tab = tab->m_next, num++); | ||
1111 | return num; | ||
1112 | } | ||
1113 | |||
1114 | /** | ||
1115 | Returns: Calculated height for relative | ||
1116 | alignment | ||
1117 | */ | ||
1118 | unsigned int Tab::calcRelativeHeight() { | ||
1119 | return ((m_win->getHeight() + | ||
1120 | m_win->getScreen()->getBorderWidth2x())/numObjects()); | ||
1121 | } | ||
1122 | |||
1123 | //------------- calcCenterXPos ----------- | ||
1124 | // Returns: Calculated x position for | ||
1125 | // centered alignment | ||
1126 | //---------------------------------------- | ||
1127 | unsigned int Tab::calcCenterXPos() { | ||
1128 | return (m_win->getXFrame() + ((m_win->getWidth() - | ||
1129 | (m_size_w * numObjects())) / 2)); | ||
1130 | } | ||
1131 | |||
1132 | //------------- calcCenterYPos ----------- | ||
1133 | // Returns: Calculated y position for | ||
1134 | // centered alignment | ||
1135 | //---------------------------------------- | ||
1136 | unsigned int Tab::calcCenterYPos() { | ||
1137 | return (m_win->getYFrame() + ((m_win->getHeight() - | ||
1138 | (m_size_h * numObjects())) / 2)); | ||
1139 | } | ||
1140 | |||
1141 | |||
1142 | //------- getTabPlacementString ---------- | ||
1143 | // Returns the tabplacement string of the | ||
1144 | // tabplacement number on success else 0. | ||
1145 | //---------------------------------------- | ||
1146 | const char *Tab::getTabPlacementString(Tab::Placement placement) { | ||
1147 | for (int i=0; i<(PNONE / 5); i++) { | ||
1148 | if (m_tabplacementlist[i] == placement) | ||
1149 | return m_tabplacementlist[i].string; | ||
1150 | } | ||
1151 | return 0; | ||
1152 | } | ||
1153 | |||
1154 | //------- getTabPlacementNum ------------- | ||
1155 | // Returns the tabplacement number of the | ||
1156 | // tabplacement string on success else | ||
1157 | // the type none on failure. | ||
1158 | //---------------------------------------- | ||
1159 | Tab::Placement Tab::getTabPlacementNum(const char *string) { | ||
1160 | for (int i=0; i<(PNONE / 5); i ++) { | ||
1161 | if (m_tabplacementlist[i] == string) { | ||
1162 | return static_cast<Tab::Placement>(m_tabplacementlist[i].tp); | ||
1163 | } | ||
1164 | } | ||
1165 | return PNONE; | ||
1166 | } | ||
1167 | |||
1168 | //------- getTabAlignmentString ---------- | ||
1169 | // Returns the tabplacement string of the | ||
1170 | // tabplacement number on success else 0. | ||
1171 | //---------------------------------------- | ||
1172 | const char *Tab::getTabAlignmentString(Tab::Alignment alignment) { | ||
1173 | for (int i=0; i<ANONE; i++) { | ||
1174 | if (m_tabalignmentlist[i] == alignment) | ||
1175 | return m_tabalignmentlist[i].string; | ||
1176 | } | ||
1177 | return 0; | ||
1178 | } | ||
1179 | |||
1180 | //------- getTabAlignmentNum ------------- | ||
1181 | // Returns the tabplacement number of the | ||
1182 | // tabplacement string on success else | ||
1183 | // the type none on failure. | ||
1184 | //---------------------------------------- | ||
1185 | Tab::Alignment Tab::getTabAlignmentNum(const char *string) { | ||
1186 | for (int i=0; i<ANONE; i++) { | ||
1187 | if (m_tabalignmentlist[i] == string) { | ||
1188 | return static_cast<Tab::Alignment>(m_tabalignmentlist[i].tp); | ||
1189 | } | ||
1190 | } | ||
1191 | return ANONE; | ||
1192 | } | ||
1193 | |||
1194 | //---------- addWindowToGroup ------------ | ||
1195 | // Add a window the the tabbed group | ||
1196 | //---------------------------------------- | ||
1197 | bool Tab::addWindowToGroup(FluxboxWindow *otherWindow) | ||
1198 | { | ||
1199 | if (!otherWindow || otherWindow == m_win) | ||
1200 | return false; | ||
1201 | Tab *otherTab = otherWindow->getTab(); | ||
1202 | if (!otherTab) | ||
1203 | return false; | ||
1204 | insert(otherTab); | ||
1205 | return true; | ||
1206 | } | ||
diff --git a/src/Tab.hh b/src/Tab.hh deleted file mode 100644 index 3681c09..0000000 --- a/src/Tab.hh +++ /dev/null | |||
@@ -1,151 +0,0 @@ | |||
1 | // Tab.hh for Fluxbox Window Manager | ||
2 | // Copyright (c) 2001-2002 Henrik Kinnunen (fluxgen@linuxmail.org) | ||
3 | // | ||
4 | // Permission is hereby granted, free of charge, to any person obtaining a | ||
5 | // copy of this software and associated documentation files (the "Software"), | ||
6 | // to deal in the Software without restriction, including without limitation | ||
7 | // the rights to use, copy, modify, merge, publish, distribute, sublicense, | ||
8 | // and/or sell copies of the Software, and to permit persons to whom the | ||
9 | // Software is furnished to do so, subject to the following conditions: | ||
10 | // | ||
11 | // The above copyright notice and this permission notice shall be included in | ||
12 | // all copies or substantial portions of the Software. | ||
13 | // | ||
14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | ||
17 | // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | ||
19 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | ||
20 | // DEALINGS IN THE SOFTWARE. | ||
21 | |||
22 | // $Id: Tab.hh,v 1.18 2003/04/09 17:20:03 rathnor Exp $ | ||
23 | |||
24 | #ifndef TAB_HH | ||
25 | #define TAB_HH | ||
26 | |||
27 | #include <X11/Xlib.h> | ||
28 | #include <strings.h> | ||
29 | //class FluxboxWindow; | ||
30 | #include "Window.hh" | ||
31 | /** | ||
32 | Note: Tab is a friend of FluxboxWindow | ||
33 | */ | ||
34 | class Tab { | ||
35 | public: | ||
36 | enum Placement{ PTOP = 0, PBOTTOM = 5, PLEFT = 10, PRIGHT = 15, PNONE = 20}; | ||
37 | enum Alignment{ ALEFT = 0, ACENTER, ARIGHT, ARELATIVE, ANONE }; | ||
38 | |||
39 | Tab(FluxboxWindow *win, Tab *prev=0, Tab *next=0); | ||
40 | ~Tab(); | ||
41 | |||
42 | void setConfigured(bool value) { m_configured = value; } | ||
43 | Tab *next() { return m_next; } | ||
44 | Tab *prev() { return m_prev; } | ||
45 | Tab *last() { return getLast(this); } | ||
46 | Tab *first() { return getFirst(this); } | ||
47 | FluxboxWindow *getWindow() { return m_win; } | ||
48 | |||
49 | void focus(); | ||
50 | void decorate(); | ||
51 | void deiconify(); | ||
52 | void iconify(); | ||
53 | void raise(); | ||
54 | void lower(); | ||
55 | void withdraw(); | ||
56 | void stick(); | ||
57 | void resize(); | ||
58 | void shade(); | ||
59 | void setPosition(); //position tab to follow (FluxboxWindow *) m_win | ||
60 | void moveNext(); | ||
61 | void movePrev(); | ||
62 | void insert(Tab *next); | ||
63 | |||
64 | //event handlers | ||
65 | void buttonReleaseEvent(XButtonEvent *be); | ||
66 | void buttonPressEvent(XButtonEvent *be); | ||
67 | void exposeEvent(XExposeEvent *ee); | ||
68 | void motionNotifyEvent(XMotionEvent *me); | ||
69 | |||
70 | void disconnect(); | ||
71 | |||
72 | //accessors | ||
73 | |||
74 | static const char *getTabPlacementString(Tab::Placement placement); | ||
75 | static Tab::Placement getTabPlacementNum(const char *string); | ||
76 | static const char *getTabAlignmentString(Tab::Alignment alignment); | ||
77 | static Tab::Alignment getTabAlignmentNum(const char *string); | ||
78 | |||
79 | const Tab *next() const { return m_next; } | ||
80 | const Tab *prev() const { return m_prev; } | ||
81 | const Tab *last() const { return getLast(const_cast<Tab *>(this)); } | ||
82 | const Tab *first() const { return getFirst(const_cast<Tab *>(this)); } | ||
83 | |||
84 | const FluxboxWindow *getWindow() const { return m_win; } | ||
85 | Window getTabWindow() const { return m_tabwin; } | ||
86 | unsigned int getTabWidth() const { return m_size_w; } | ||
87 | unsigned int getTabHeight() const { return m_size_h; } | ||
88 | |||
89 | void resizeGroup(); // used when (un)shading windows | ||
90 | void calcIncrease(); | ||
91 | bool configured() const { return m_configured; } | ||
92 | void draw(bool pressed) const; | ||
93 | |||
94 | bool addWindowToGroup(FluxboxWindow *window); | ||
95 | |||
96 | static Tab *getFirst(Tab *current); | ||
97 | static Tab *getLast(Tab *current); | ||
98 | |||
99 | private: | ||
100 | |||
101 | bool m_configured; | ||
102 | |||
103 | |||
104 | //The size of the tab | ||
105 | unsigned int m_size_w; | ||
106 | unsigned int m_size_h; | ||
107 | //Increasements | ||
108 | int m_inc_x; | ||
109 | int m_inc_y; | ||
110 | static const int m_max_tabs; | ||
111 | bool m_focus, m_moving; // moving and focus | ||
112 | void createTabWindow(); // creates the X win of tab | ||
113 | void loadTheme(); // loads the textures with right width and height | ||
114 | int setPositionShadingHelper(bool shaded); | ||
115 | int setPositionTBAlignHelper(Alignment align); | ||
116 | int setPositionLRAlignHelper(Alignment align); | ||
117 | void setTabWidth(unsigned int w); | ||
118 | void setTabHeight(unsigned int h); | ||
119 | unsigned int numObjects(); | ||
120 | unsigned int calcRelativeWidth(); | ||
121 | unsigned int calcRelativeHeight(); | ||
122 | unsigned int calcCenterXPos(); | ||
123 | unsigned int calcCenterYPos(); | ||
124 | int m_move_x, m_move_y; // Move coordinates, holds moving coordinates when draging | ||
125 | Tab *m_prev; | ||
126 | Tab *m_next; | ||
127 | FluxboxWindow *m_win; | ||
128 | Window m_tabwin; | ||
129 | Display *m_display; | ||
130 | Pixmap m_focus_pm, m_unfocus_pm; | ||
131 | unsigned long m_focus_pixel, m_unfocus_pixel; | ||
132 | static bool m_stoptabs; //used to "freeze" the tabs functions | ||
133 | |||
134 | struct t_tabplacementlist{ | ||
135 | int tp; | ||
136 | const char *string; | ||
137 | inline bool operator == (int p) { | ||
138 | return (tp==p); | ||
139 | } | ||
140 | inline bool operator == (const char *str) { | ||
141 | if (strcasecmp(string, str) == 0) | ||
142 | return true; | ||
143 | return false; | ||
144 | } | ||
145 | }; | ||
146 | static t_tabplacementlist m_tabplacementlist[]; | ||
147 | static t_tabplacementlist m_tabalignmentlist[]; | ||
148 | |||
149 | }; | ||
150 | |||
151 | #endif //TAB_HH | ||