Add support for nearest corner or edge resizing
This commit is contained in:
parent
7b6ab828c7
commit
391712b980
5 changed files with 96 additions and 33 deletions
|
@ -178,8 +178,16 @@ Start dragging to resize the window as if you had grabbed the window
|
|||
at the specified 'corner'.
|
||||
+
|
||||
By default 'corner' is *BottomRight*, but may be overridden with one of:;;
|
||||
*NearestCorner NearestEdge Center TopLeft Top TopRight Left Right BottomLeft
|
||||
Bottom BottomRight*
|
||||
*NearestCorner NearestEdge NearestCornerOrEdge Center TopLeft Top TopRight
|
||||
Left Right BottomLeft Bottom BottomRight*
|
||||
|
||||
+
|
||||
If *NearestCornerOrEdge* is specified the size of the corner can also be
|
||||
specified to be the larger of one or two following numbers: ['pixel-size'
|
||||
['percent-size']] or 'percent-size'%, where 'percent-size' is the
|
||||
percentage of half the window width or height. If no size is given, it
|
||||
defaults to 50 pixels and 30%.
|
||||
|
||||
|
||||
*StartTabbing*::
|
||||
Start dragging to add this window to another's tabgroup.
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#include <string.h>
|
||||
#include "CurrentWindowCmd.hh"
|
||||
|
||||
#include "fluxbox.hh"
|
||||
|
@ -369,15 +370,13 @@ void StartMovingCmd::real_execute() {
|
|||
FbTk::Command<void> *StartResizingCmd::parse(const string &cmd, const string &args,
|
||||
bool trusted) {
|
||||
FluxboxWindow::ResizeModel mode = FluxboxWindow::DEFAULTRESIZE;
|
||||
int corner_size_px = 0;
|
||||
int corner_size_pc = 0;
|
||||
std::vector<string> tokens;
|
||||
FbTk::StringUtil::stringtok<std::vector<string> >(tokens, args);
|
||||
if (!tokens.empty()) {
|
||||
string arg = FbTk::StringUtil::toLower(tokens[0]);
|
||||
if (arg == "nearestcorner")
|
||||
mode = FluxboxWindow::QUADRANTRESIZE;
|
||||
else if (arg == "nearestedge")
|
||||
mode = FluxboxWindow::NEARESTEDGERESIZE;
|
||||
else if (arg == "center")
|
||||
if (arg == "center")
|
||||
mode = FluxboxWindow::CENTERRESIZE;
|
||||
else if (arg == "topleft")
|
||||
mode = FluxboxWindow::TOPLEFTRESIZE;
|
||||
|
@ -395,8 +394,35 @@ FbTk::Command<void> *StartResizingCmd::parse(const string &cmd, const string &ar
|
|||
mode = FluxboxWindow::BOTTOMRESIZE;
|
||||
else if (arg == "bottomright")
|
||||
mode = FluxboxWindow::BOTTOMRIGHTRESIZE;
|
||||
else if (arg == "nearestcorner") {
|
||||
mode = FluxboxWindow::EDGEORCORNERRESIZE;
|
||||
corner_size_pc = 100;
|
||||
} else if (arg == "nearestedge") {
|
||||
mode = FluxboxWindow::EDGEORCORNERRESIZE;
|
||||
} else if (arg == "nearestcorneroredge") {
|
||||
mode = FluxboxWindow::EDGEORCORNERRESIZE;
|
||||
/* The NearestCornerOrEdge can be followed by a corner size in
|
||||
* one of three forms:
|
||||
* <size in pixels>
|
||||
* <size in pixels> <size in percent>
|
||||
* <size in percent>%
|
||||
* If no corner size is given then it defaults to 50 pixels, 30%. */
|
||||
if (tokens.size() > 1) {
|
||||
const char * size1 = tokens[1].c_str();
|
||||
if (size1[strlen(size1)-1] == '%')
|
||||
corner_size_pc = atoi(size1);
|
||||
else {
|
||||
corner_size_px = atoi(size1);
|
||||
if (tokens.size() > 2)
|
||||
corner_size_pc = atoi(tokens[2].c_str());
|
||||
}
|
||||
} else {
|
||||
corner_size_px = 50;
|
||||
corner_size_pc = 30;
|
||||
}
|
||||
}
|
||||
}
|
||||
return new StartResizingCmd(mode);
|
||||
return new StartResizingCmd(mode, corner_size_px, corner_size_pc);
|
||||
}
|
||||
|
||||
REGISTER_COMMAND_PARSER(startresizing, StartResizingCmd::parse, void);
|
||||
|
@ -422,7 +448,8 @@ void StartResizingCmd::real_execute() {
|
|||
x -= fbwindow().x() - fbwindow().frame().window().borderWidth();
|
||||
y -= fbwindow().y() - fbwindow().frame().window().borderWidth();
|
||||
|
||||
fbwindow().startResizing(x, y, fbwindow().getResizeDirection(x, y, m_mode));
|
||||
fbwindow().startResizing(x, y, fbwindow().getResizeDirection(
|
||||
x, y, m_mode, m_corner_size_px, m_corner_size_pc));
|
||||
}
|
||||
|
||||
REGISTER_COMMAND(starttabbing, StartTabbingCmd, void);
|
||||
|
|
|
@ -124,13 +124,16 @@ protected:
|
|||
// begin resizing with mouse
|
||||
class StartResizingCmd: public WindowHelperCmd {
|
||||
public:
|
||||
explicit StartResizingCmd(FluxboxWindow::ResizeModel mode):m_mode(mode) { }
|
||||
explicit StartResizingCmd(FluxboxWindow::ResizeModel mode, int corner_size_px, int corner_size_pc):
|
||||
m_mode(mode), m_corner_size_px(corner_size_px), m_corner_size_pc(corner_size_pc) { }
|
||||
static FbTk::Command<void> *parse(const std::string &command,
|
||||
const std::string &args, bool trusted);
|
||||
protected:
|
||||
void real_execute();
|
||||
private:
|
||||
const FluxboxWindow::ResizeModel m_mode;
|
||||
const int m_corner_size_px; // Corner size in pixels
|
||||
const int m_corner_size_pc; // and in percent of half window width/height
|
||||
};
|
||||
|
||||
// begin tabbing with mouse
|
||||
|
|
|
@ -251,6 +251,18 @@ private:
|
|||
int m_mode;
|
||||
};
|
||||
|
||||
|
||||
// Helper class for getResizeDirection below
|
||||
// Tests whether a point is on an edge or the corner.
|
||||
struct TestEdgeHelper {
|
||||
int corner_size_px, corner_size_pc;
|
||||
inline bool operator()(int xy, int wh)
|
||||
{
|
||||
/* The % checking must be right: 0% must fail, 100% must succeed. */
|
||||
return xy < corner_size_px || 100 * xy < corner_size_pc * wh;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -3004,30 +3016,44 @@ void FluxboxWindow::doSnapping(int &orig_left, int &orig_top) {
|
|||
|
||||
}
|
||||
|
||||
FluxboxWindow::ReferenceCorner FluxboxWindow::getResizeDirection(int x, int y,
|
||||
ResizeModel model) const {
|
||||
|
||||
int cx = frame().width() / 2;
|
||||
int cy = frame().height() / 2;
|
||||
if (model == CENTERRESIZE)
|
||||
return CENTER;
|
||||
if (model == NEARESTEDGERESIZE) {
|
||||
FluxboxWindow::ReferenceCorner FluxboxWindow::getResizeDirection(int x, int y,
|
||||
ResizeModel model, int corner_size_px, int corner_size_pc) const
|
||||
{
|
||||
if (model == TOPLEFTRESIZE) return LEFTTOP;
|
||||
if (model == TOPRESIZE) return TOP;
|
||||
if (model == TOPRIGHTRESIZE) return RIGHTTOP;
|
||||
if (model == LEFTRESIZE) return LEFT;
|
||||
if (model == RIGHTRESIZE) return RIGHT;
|
||||
if (model == BOTTOMLEFTRESIZE) return LEFTBOTTOM;
|
||||
if (model == BOTTOMRESIZE) return BOTTOM;
|
||||
if (model == CENTERRESIZE) return CENTER;
|
||||
|
||||
if (model == EDGEORCORNERRESIZE)
|
||||
{
|
||||
int w = frame().width();
|
||||
int h = frame().height();
|
||||
int cx = w / 2;
|
||||
int cy = h / 2;
|
||||
TestEdgeHelper test_edge = { corner_size_px, corner_size_pc };
|
||||
if (x < cx && test_edge(x, cx)) {
|
||||
if (y < cy && test_edge(y, cy))
|
||||
return LEFTTOP;
|
||||
else if (test_edge(h - y - 1, h - cy))
|
||||
return LEFTBOTTOM;
|
||||
} else if (test_edge(w - x - 1, w - cx)) {
|
||||
if (y < cy && test_edge(y, cy))
|
||||
return RIGHTTOP;
|
||||
else if (test_edge(h - y - 1, h - cy))
|
||||
return RIGHTBOTTOM;
|
||||
}
|
||||
|
||||
/* Nope, not a corner; find the nearest edge instead. */
|
||||
if (cy - abs(y - cy) < cx - abs(x - cx)) // y is nearest
|
||||
return (y > cy) ? BOTTOM : TOP;
|
||||
return (x > cx) ? RIGHT : LEFT;
|
||||
else
|
||||
return (x > cx) ? RIGHT : LEFT;
|
||||
}
|
||||
if (model == QUADRANTRESIZE) {
|
||||
if (x < cx)
|
||||
return (y < cy) ? LEFTTOP : LEFTBOTTOM;
|
||||
return (y < cy) ? RIGHTTOP : RIGHTBOTTOM;
|
||||
}
|
||||
if (model == TOPLEFTRESIZE) return LEFTTOP;
|
||||
if (model == TOPRESIZE) return TOP;
|
||||
if (model == TOPRIGHTRESIZE) return RIGHTTOP;
|
||||
if (model == LEFTRESIZE) return LEFT;
|
||||
if (model == RIGHTRESIZE) return RIGHT;
|
||||
if (model == BOTTOMLEFTRESIZE) return LEFTBOTTOM;
|
||||
if (model == BOTTOMRESIZE) return BOTTOM;
|
||||
return RIGHTBOTTOM;
|
||||
}
|
||||
|
||||
|
|
|
@ -89,9 +89,7 @@ public:
|
|||
|
||||
/// Different resize modes when resizing a window
|
||||
enum ResizeModel {
|
||||
QUADRANTRESIZE, ///< resizes from one quadrant
|
||||
CENTERRESIZE, ///< resizes from center
|
||||
NEARESTEDGERESIZE, ///< resizes the nearest edge
|
||||
TOPLEFTRESIZE, ///< resizes top left corner
|
||||
TOPRESIZE, ///< resizes top edge
|
||||
TOPRIGHTRESIZE, ///< resizes top right corner
|
||||
|
@ -100,6 +98,7 @@ public:
|
|||
BOTTOMLEFTRESIZE, ///< resizes bottom left corner
|
||||
BOTTOMRESIZE, ///< resizes bottom edge
|
||||
BOTTOMRIGHTRESIZE, ///< resizes bottom right corner
|
||||
EDGEORCORNERRESIZE, ///< resizes nearest edge or corner
|
||||
DEFAULTRESIZE = BOTTOMRIGHTRESIZE ///< default resize mode
|
||||
};
|
||||
|
||||
|
@ -341,7 +340,7 @@ public:
|
|||
*/
|
||||
void startResizing(int x, int y, ReferenceCorner dir);
|
||||
/// determine which edge or corner to resize
|
||||
ReferenceCorner getResizeDirection(int x, int y, ResizeModel model) const;
|
||||
ReferenceCorner getResizeDirection(int x, int y, ResizeModel model, int corner_size_px, int corner_size_pc) const;
|
||||
/// stops the resizing
|
||||
void stopResizing(bool interrupted = false);
|
||||
/// starts tabbing
|
||||
|
|
Loading…
Reference in a new issue