blob: d214ce79a951065512449b8209b8dcbb3d934302 [file] [log] [blame]
// Copyright (c) 2010 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef WINDOW_MANAGER_GEOMETRY_H_
#define WINDOW_MANAGER_GEOMETRY_H_
#include <algorithm>
#include <iosfwd>
namespace window_manager {
// This file defines a few simple types for storing geometry-related data.
// We define our own instead of using Chrome's since its base/gfx/rect.h
// file references some GDK types that we don't want.
// This enum is used for resize operations in a manner similar to X's
// concept of gravity -- it describes which corner of an object will be
// kept at a fixed position as the object is resized. For example, if a
// 10x10 rectangle with its top-left corner at (20, 20) is resized to 5x5
// with GRAVITY_SOUTHEAST, the resulting 5x5 rectangle will be located at
// (25, 25).
enum Gravity {
GRAVITY_NORTHWEST = 0,
GRAVITY_NORTHEAST,
GRAVITY_SOUTHWEST,
GRAVITY_SOUTHEAST,
};
struct Point {
Point() : x(0), y(0) {}
Point(int x, int y) : x(x), y(y) {}
void reset(int new_x, int new_y) {
x = new_x;
y = new_y;
}
bool operator==(const Point& o) const {
return x == o.x && y == o.y;
}
bool operator!=(const Point& o) const {
return x != o.x || y != o.y;
}
int x;
int y;
};
struct Size {
Size() : width(0), height(0) {}
Size(int width, int height) : width(width), height(height) {}
void reset(int new_width, int new_height) {
width = new_width;
height = new_height;
}
bool operator==(const Size& o) const {
return width == o.width && height == o.height;
}
bool operator!=(const Size& o) const {
return width != o.width || height != o.height;
}
int width;
int height;
};
struct Rect {
Rect() : x(0), y(0), width(0), height(0) {}
Rect(int x, int y, int w, int h) : x(x), y(y), width(w), height(h) {}
Rect(const Point& pos, const Size& size) { reset(pos, size); }
Point position() const { return Point(x, y); }
Size size() const { return Size(width, height); }
void reset(const Point& pos, const Size& size) {
reset(pos.x, pos.y, size.width, size.height);
}
void reset(int new_x, int new_y, int new_width, int new_height) {
x = new_x;
y = new_y;
width = new_width;
height = new_height;
}
void move(const Point& pos) { move(pos.x, pos.y); }
void move(int new_x, int new_y) {
x = new_x;
y = new_y;
}
void resize(const Size& size, Gravity gravity) {
resize(size.width, size.height, gravity);
}
void resize(int w, int h, Gravity gravity) {
if (gravity == GRAVITY_NORTHEAST || gravity == GRAVITY_SOUTHEAST)
x += (width - w);
if (gravity == GRAVITY_SOUTHWEST || gravity == GRAVITY_SOUTHEAST)
y += (height - h);
width = w;
height = h;
}
bool empty() const { return width <= 0 || height <= 0; }
void merge(const Rect& other) {
if (other.empty())
return;
if (empty()) {
*this = other;
} else {
int x_max = std::max(x + width, other.x + other.width);
x = std::min(x, other.x);
width = x_max - x;
int y_max = std::max(y + height, other.y + other.height);
y = std::min(y, other.y);
height = y_max - y;
}
}
void intersect(const Rect& other) {
if (other.empty() || empty()) {
width = height = 0;
return;
}
int max_x = std::min(x + width, other.x + other.width);
x = std::max(x, other.x);
width = std::max(0, max_x - x);
int max_y = std::min(y + height, other.y + other.height);
y = std::max(y, other.y);
height = std::max(0, max_y - y);
}
bool operator==(const Rect& o) const {
return x == o.x && y == o.y && width == o.width && height == o.height;
}
bool operator!=(const Rect& o) const {
return x != o.x || y != o.y || width != o.width || height != o.height;
}
int left() const { return x; }
int top() const { return y; }
int right() const { return x + width; }
int bottom() const { return y + height; }
int x;
int y;
int width;
int height;
};
} // namespace window_manager
std::ostream& operator<<(std::ostream& out, const window_manager::Point& point);
std::ostream& operator<<(std::ostream& out, const window_manager::Size& size);
std::ostream& operator<<(std::ostream& out, const window_manager::Rect& rect);
#endif // WINDOW_MANAGER_GEOMETRY_H_