diff options
author | Michael Abbott <michael@araneidae.co.uk> | 2012-09-29 07:10:48 (GMT) |
---|---|---|
committer | Mathias Gumz <akira at fluxbox dot org> | 2012-10-04 07:36:23 (GMT) |
commit | 391712b9805eda9d56a100f49d69b38863910565 (patch) | |
tree | 05d5a6eea9fef53a371676f76ec4c1e1ef0893a1 | |
parent | 7b6ab828c7e5453a2720462156d165707935c9ef (diff) | |
download | fluxbox-391712b9805eda9d56a100f49d69b38863910565.zip fluxbox-391712b9805eda9d56a100f49d69b38863910565.tar.bz2 |
Add support for nearest corner or edge resizing
-rw-r--r-- | doc/asciidoc/fluxbox-keys.txt | 12 | ||||
-rw-r--r-- | src/CurrentWindowCmd.cc | 41 | ||||
-rw-r--r-- | src/CurrentWindowCmd.hh | 5 | ||||
-rw-r--r-- | src/Window.cc | 66 | ||||
-rw-r--r-- | src/Window.hh | 5 |
5 files changed, 96 insertions, 33 deletions
diff --git a/doc/asciidoc/fluxbox-keys.txt b/doc/asciidoc/fluxbox-keys.txt index 0d0b52e..96b1141 100644 --- a/doc/asciidoc/fluxbox-keys.txt +++ b/doc/asciidoc/fluxbox-keys.txt | |||
@@ -178,8 +178,16 @@ Start dragging to resize the window as if you had grabbed the window | |||
178 | at the specified 'corner'. | 178 | at the specified 'corner'. |
179 | + | 179 | + |
180 | By default 'corner' is *BottomRight*, but may be overridden with one of:;; | 180 | By default 'corner' is *BottomRight*, but may be overridden with one of:;; |
181 | *NearestCorner NearestEdge Center TopLeft Top TopRight Left Right BottomLeft | 181 | *NearestCorner NearestEdge NearestCornerOrEdge Center TopLeft Top TopRight |
182 | Bottom BottomRight* | 182 | Left Right BottomLeft Bottom BottomRight* |
183 | |||
184 | + | ||
185 | If *NearestCornerOrEdge* is specified the size of the corner can also be | ||
186 | specified to be the larger of one or two following numbers: ['pixel-size' | ||
187 | ['percent-size']] or 'percent-size'%, where 'percent-size' is the | ||
188 | percentage of half the window width or height. If no size is given, it | ||
189 | defaults to 50 pixels and 30%. | ||
190 | |||
183 | 191 | ||
184 | *StartTabbing*:: | 192 | *StartTabbing*:: |
185 | Start dragging to add this window to another's tabgroup. | 193 | Start dragging to add this window to another's tabgroup. |
diff --git a/src/CurrentWindowCmd.cc b/src/CurrentWindowCmd.cc index 4363d0d..6138e64 100644 --- a/src/CurrentWindowCmd.cc +++ b/src/CurrentWindowCmd.cc | |||
@@ -20,6 +20,7 @@ | |||
20 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | 20 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
21 | // DEALINGS IN THE SOFTWARE. | 21 | // DEALINGS IN THE SOFTWARE. |
22 | 22 | ||
23 | #include <string.h> | ||
23 | #include "CurrentWindowCmd.hh" | 24 | #include "CurrentWindowCmd.hh" |
24 | 25 | ||
25 | #include "fluxbox.hh" | 26 | #include "fluxbox.hh" |
@@ -369,15 +370,13 @@ void StartMovingCmd::real_execute() { | |||
369 | FbTk::Command<void> *StartResizingCmd::parse(const string &cmd, const string &args, | 370 | FbTk::Command<void> *StartResizingCmd::parse(const string &cmd, const string &args, |
370 | bool trusted) { | 371 | bool trusted) { |
371 | FluxboxWindow::ResizeModel mode = FluxboxWindow::DEFAULTRESIZE; | 372 | FluxboxWindow::ResizeModel mode = FluxboxWindow::DEFAULTRESIZE; |
373 | int corner_size_px = 0; | ||
374 | int corner_size_pc = 0; | ||
372 | std::vector<string> tokens; | 375 | std::vector<string> tokens; |
373 | FbTk::StringUtil::stringtok<std::vector<string> >(tokens, args); | 376 | FbTk::StringUtil::stringtok<std::vector<string> >(tokens, args); |
374 | if (!tokens.empty()) { | 377 | if (!tokens.empty()) { |
375 | string arg = FbTk::StringUtil::toLower(tokens[0]); | 378 | string arg = FbTk::StringUtil::toLower(tokens[0]); |
376 | if (arg == "nearestcorner") | 379 | if (arg == "center") |
377 | mode = FluxboxWindow::QUADRANTRESIZE; | ||
378 | else if (arg == "nearestedge") | ||
379 | mode = FluxboxWindow::NEARESTEDGERESIZE; | ||
380 | else if (arg == "center") | ||
381 | mode = FluxboxWindow::CENTERRESIZE; | 380 | mode = FluxboxWindow::CENTERRESIZE; |
382 | else if (arg == "topleft") | 381 | else if (arg == "topleft") |
383 | mode = FluxboxWindow::TOPLEFTRESIZE; | 382 | mode = FluxboxWindow::TOPLEFTRESIZE; |
@@ -395,8 +394,35 @@ FbTk::Command<void> *StartResizingCmd::parse(const string &cmd, const string &ar | |||
395 | mode = FluxboxWindow::BOTTOMRESIZE; | 394 | mode = FluxboxWindow::BOTTOMRESIZE; |
396 | else if (arg == "bottomright") | 395 | else if (arg == "bottomright") |
397 | mode = FluxboxWindow::BOTTOMRIGHTRESIZE; | 396 | mode = FluxboxWindow::BOTTOMRIGHTRESIZE; |
397 | else if (arg == "nearestcorner") { | ||
398 | mode = FluxboxWindow::EDGEORCORNERRESIZE; | ||
399 | corner_size_pc = 100; | ||
400 | } else if (arg == "nearestedge") { | ||
401 | mode = FluxboxWindow::EDGEORCORNERRESIZE; | ||
402 | } else if (arg == "nearestcorneroredge") { | ||
403 | mode = FluxboxWindow::EDGEORCORNERRESIZE; | ||
404 | /* The NearestCornerOrEdge can be followed by a corner size in | ||
405 | * one of three forms: | ||
406 | * <size in pixels> | ||
407 | * <size in pixels> <size in percent> | ||
408 | * <size in percent>% | ||
409 | * If no corner size is given then it defaults to 50 pixels, 30%. */ | ||
410 | if (tokens.size() > 1) { | ||
411 | const char * size1 = tokens[1].c_str(); | ||
412 | if (size1[strlen(size1)-1] == '%') | ||
413 | corner_size_pc = atoi(size1); | ||
414 | else { | ||
415 | corner_size_px = atoi(size1); | ||
416 | if (tokens.size() > 2) | ||
417 | corner_size_pc = atoi(tokens[2].c_str()); | ||
418 | } | ||
419 | } else { | ||
420 | corner_size_px = 50; | ||
421 | corner_size_pc = 30; | ||
422 | } | ||
423 | } | ||
398 | } | 424 | } |
399 | return new StartResizingCmd(mode); | 425 | return new StartResizingCmd(mode, corner_size_px, corner_size_pc); |
400 | } | 426 | } |
401 | 427 | ||
402 | REGISTER_COMMAND_PARSER(startresizing, StartResizingCmd::parse, void); | 428 | REGISTER_COMMAND_PARSER(startresizing, StartResizingCmd::parse, void); |
@@ -422,7 +448,8 @@ void StartResizingCmd::real_execute() { | |||
422 | x -= fbwindow().x() - fbwindow().frame().window().borderWidth(); | 448 | x -= fbwindow().x() - fbwindow().frame().window().borderWidth(); |
423 | y -= fbwindow().y() - fbwindow().frame().window().borderWidth(); | 449 | y -= fbwindow().y() - fbwindow().frame().window().borderWidth(); |
424 | 450 | ||
425 | fbwindow().startResizing(x, y, fbwindow().getResizeDirection(x, y, m_mode)); | 451 | fbwindow().startResizing(x, y, fbwindow().getResizeDirection( |
452 | x, y, m_mode, m_corner_size_px, m_corner_size_pc)); | ||
426 | } | 453 | } |
427 | 454 | ||
428 | REGISTER_COMMAND(starttabbing, StartTabbingCmd, void); | 455 | REGISTER_COMMAND(starttabbing, StartTabbingCmd, void); |
diff --git a/src/CurrentWindowCmd.hh b/src/CurrentWindowCmd.hh index f406796..95175f2 100644 --- a/src/CurrentWindowCmd.hh +++ b/src/CurrentWindowCmd.hh | |||
@@ -124,13 +124,16 @@ protected: | |||
124 | // begin resizing with mouse | 124 | // begin resizing with mouse |
125 | class StartResizingCmd: public WindowHelperCmd { | 125 | class StartResizingCmd: public WindowHelperCmd { |
126 | public: | 126 | public: |
127 | explicit StartResizingCmd(FluxboxWindow::ResizeModel mode):m_mode(mode) { } | 127 | explicit StartResizingCmd(FluxboxWindow::ResizeModel mode, int corner_size_px, int corner_size_pc): |
128 | m_mode(mode), m_corner_size_px(corner_size_px), m_corner_size_pc(corner_size_pc) { } | ||
128 | static FbTk::Command<void> *parse(const std::string &command, | 129 | static FbTk::Command<void> *parse(const std::string &command, |
129 | const std::string &args, bool trusted); | 130 | const std::string &args, bool trusted); |
130 | protected: | 131 | protected: |
131 | void real_execute(); | 132 | void real_execute(); |
132 | private: | 133 | private: |
133 | const FluxboxWindow::ResizeModel m_mode; | 134 | const FluxboxWindow::ResizeModel m_mode; |
135 | const int m_corner_size_px; // Corner size in pixels | ||
136 | const int m_corner_size_pc; // and in percent of half window width/height | ||
134 | }; | 137 | }; |
135 | 138 | ||
136 | // begin tabbing with mouse | 139 | // begin tabbing with mouse |
diff --git a/src/Window.cc b/src/Window.cc index 33a4c9e..0b8d1e5 100644 --- a/src/Window.cc +++ b/src/Window.cc | |||
@@ -251,6 +251,18 @@ private: | |||
251 | int m_mode; | 251 | int m_mode; |
252 | }; | 252 | }; |
253 | 253 | ||
254 | |||
255 | // Helper class for getResizeDirection below | ||
256 | // Tests whether a point is on an edge or the corner. | ||
257 | struct TestEdgeHelper { | ||
258 | int corner_size_px, corner_size_pc; | ||
259 | inline bool operator()(int xy, int wh) | ||
260 | { | ||
261 | /* The % checking must be right: 0% must fail, 100% must succeed. */ | ||
262 | return xy < corner_size_px || 100 * xy < corner_size_pc * wh; | ||
263 | } | ||
264 | }; | ||
265 | |||
254 | } | 266 | } |
255 | 267 | ||
256 | 268 | ||
@@ -3004,30 +3016,44 @@ void FluxboxWindow::doSnapping(int &orig_left, int &orig_top) { | |||
3004 | 3016 | ||
3005 | } | 3017 | } |
3006 | 3018 | ||
3019 | |||
3007 | FluxboxWindow::ReferenceCorner FluxboxWindow::getResizeDirection(int x, int y, | 3020 | FluxboxWindow::ReferenceCorner FluxboxWindow::getResizeDirection(int x, int y, |
3008 | ResizeModel model) const { | 3021 | ResizeModel model, int corner_size_px, int corner_size_pc) const |
3022 | { | ||
3023 | if (model == TOPLEFTRESIZE) return LEFTTOP; | ||
3024 | if (model == TOPRESIZE) return TOP; | ||
3025 | if (model == TOPRIGHTRESIZE) return RIGHTTOP; | ||
3026 | if (model == LEFTRESIZE) return LEFT; | ||
3027 | if (model == RIGHTRESIZE) return RIGHT; | ||
3028 | if (model == BOTTOMLEFTRESIZE) return LEFTBOTTOM; | ||
3029 | if (model == BOTTOMRESIZE) return BOTTOM; | ||
3030 | if (model == CENTERRESIZE) return CENTER; | ||
3031 | |||
3032 | if (model == EDGEORCORNERRESIZE) | ||
3033 | { | ||
3034 | int w = frame().width(); | ||
3035 | int h = frame().height(); | ||
3036 | int cx = w / 2; | ||
3037 | int cy = h / 2; | ||
3038 | TestEdgeHelper test_edge = { corner_size_px, corner_size_pc }; | ||
3039 | if (x < cx && test_edge(x, cx)) { | ||
3040 | if (y < cy && test_edge(y, cy)) | ||
3041 | return LEFTTOP; | ||
3042 | else if (test_edge(h - y - 1, h - cy)) | ||
3043 | return LEFTBOTTOM; | ||
3044 | } else if (test_edge(w - x - 1, w - cx)) { | ||
3045 | if (y < cy && test_edge(y, cy)) | ||
3046 | return RIGHTTOP; | ||
3047 | else if (test_edge(h - y - 1, h - cy)) | ||
3048 | return RIGHTBOTTOM; | ||
3049 | } | ||
3009 | 3050 | ||
3010 | int cx = frame().width() / 2; | 3051 | /* Nope, not a corner; find the nearest edge instead. */ |
3011 | int cy = frame().height() / 2; | ||
3012 | if (model == CENTERRESIZE) | ||
3013 | return CENTER; | ||
3014 | if (model == NEARESTEDGERESIZE) { | ||
3015 | if (cy - abs(y - cy) < cx - abs(x - cx)) // y is nearest | 3052 | if (cy - abs(y - cy) < cx - abs(x - cx)) // y is nearest |
3016 | return (y > cy) ? BOTTOM : TOP; | 3053 | return (y > cy) ? BOTTOM : TOP; |
3017 | return (x > cx) ? RIGHT : LEFT; | 3054 | else |
3018 | } | 3055 | return (x > cx) ? RIGHT : LEFT; |
3019 | if (model == QUADRANTRESIZE) { | 3056 | } |
3020 | if (x < cx) | ||
3021 | return (y < cy) ? LEFTTOP : LEFTBOTTOM; | ||
3022 | return (y < cy) ? RIGHTTOP : RIGHTBOTTOM; | ||
3023 | } | ||
3024 | if (model == TOPLEFTRESIZE) return LEFTTOP; | ||
3025 | if (model == TOPRESIZE) return TOP; | ||
3026 | if (model == TOPRIGHTRESIZE) return RIGHTTOP; | ||
3027 | if (model == LEFTRESIZE) return LEFT; | ||
3028 | if (model == RIGHTRESIZE) return RIGHT; | ||
3029 | if (model == BOTTOMLEFTRESIZE) return LEFTBOTTOM; | ||
3030 | if (model == BOTTOMRESIZE) return BOTTOM; | ||
3031 | return RIGHTBOTTOM; | 3057 | return RIGHTBOTTOM; |
3032 | } | 3058 | } |
3033 | 3059 | ||
diff --git a/src/Window.hh b/src/Window.hh index 09374af..b7975f5 100644 --- a/src/Window.hh +++ b/src/Window.hh | |||
@@ -89,9 +89,7 @@ public: | |||
89 | 89 | ||
90 | /// Different resize modes when resizing a window | 90 | /// Different resize modes when resizing a window |
91 | enum ResizeModel { | 91 | enum ResizeModel { |
92 | QUADRANTRESIZE, ///< resizes from one quadrant | ||
93 | CENTERRESIZE, ///< resizes from center | 92 | CENTERRESIZE, ///< resizes from center |
94 | NEARESTEDGERESIZE, ///< resizes the nearest edge | ||
95 | TOPLEFTRESIZE, ///< resizes top left corner | 93 | TOPLEFTRESIZE, ///< resizes top left corner |
96 | TOPRESIZE, ///< resizes top edge | 94 | TOPRESIZE, ///< resizes top edge |
97 | TOPRIGHTRESIZE, ///< resizes top right corner | 95 | TOPRIGHTRESIZE, ///< resizes top right corner |
@@ -100,6 +98,7 @@ public: | |||
100 | BOTTOMLEFTRESIZE, ///< resizes bottom left corner | 98 | BOTTOMLEFTRESIZE, ///< resizes bottom left corner |
101 | BOTTOMRESIZE, ///< resizes bottom edge | 99 | BOTTOMRESIZE, ///< resizes bottom edge |
102 | BOTTOMRIGHTRESIZE, ///< resizes bottom right corner | 100 | BOTTOMRIGHTRESIZE, ///< resizes bottom right corner |
101 | EDGEORCORNERRESIZE, ///< resizes nearest edge or corner | ||
103 | DEFAULTRESIZE = BOTTOMRIGHTRESIZE ///< default resize mode | 102 | DEFAULTRESIZE = BOTTOMRIGHTRESIZE ///< default resize mode |
104 | }; | 103 | }; |
105 | 104 | ||
@@ -341,7 +340,7 @@ public: | |||
341 | */ | 340 | */ |
342 | void startResizing(int x, int y, ReferenceCorner dir); | 341 | void startResizing(int x, int y, ReferenceCorner dir); |
343 | /// determine which edge or corner to resize | 342 | /// determine which edge or corner to resize |
344 | ReferenceCorner getResizeDirection(int x, int y, ResizeModel model) const; | 343 | ReferenceCorner getResizeDirection(int x, int y, ResizeModel model, int corner_size_px, int corner_size_pc) const; |
345 | /// stops the resizing | 344 | /// stops the resizing |
346 | void stopResizing(bool interrupted = false); | 345 | void stopResizing(bool interrupted = false); |
347 | /// starts tabbing | 346 | /// starts tabbing |