| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287 |
- import {Tile, TileState} from './tile.js';
- import {Direction} from './tileWindowManager.js';
- import {Position} from './position.js';
- export class Monitor {
- _root;
- _index;
- _fullscreenState = false;
- constructor(index) {
- this._index = index;
- this._root = null;
- }
- set root(root) {
- this._root = root;
- }
- get root() {
- return this._root;
- }
- get index() {
- return this._index;
- }
- get fullscreen() {
- return this._fullscreenState;
- }
- set fullscreen(b) {
- this._fullscreenState = b;
- }
- size() {
- return this._root ? this._root._nr_tiles : 0;
- }
- updateSize() {
- if (this._root) {
- const area = global.workspace_manager.get_active_workspace().get_work_area_for_monitor(this.index);
- if (area) {
- let pos = new Position(1.0, 0, 0, area.width, area.height);
- pos.splitProportion = this._root.position.splitProportion;
- this._root.resize(pos);
- }
- }
- }
- static bestFitMonitor(monitors) {
- return monitors.reduce((acc, val) => val.size() < acc.size() ? val : acc, monitors[0]);
- }
- static tileDistance(t1, t2) {
- let vector = [t1.position.x - t2.position.x, t1.position.y - t2.position.y];
- return Math.sqrt(vector[0] * vector[0] + vector[1] * vector[1]);
- }
- closestTile(source, dir) {
- // Class to store the result
- class BestTile {
- tile = null;
- distance = null;
- constructor(tile = null, distance = null) {
- this.tile = tile;
- this.distance = distance;
- }
- }
- ;
- // We search for the closest tile in a Direction. We recursively iterate the tree
- let findClosest = tile => {
- switch (dir) {
- case Direction.East:
- if (tile.leaf && tile.position.x > source.position.x) {
- return new BestTile(tile, Monitor.tileDistance(tile, source));
- } else if (tile.leaf) {
- return new BestTile();
- } else if (tile.child1 && tile.child2) {
- let res1 = findClosest(tile.child1);
- let res2 = findClosest(tile.child2);
- if ((res1.distance && res2.distance && res1.distance > res2.distance) ||
- (res2.distance && !res1.distance))
- return res2;
- else if ((res1.distance && res2.distance && res1.distance < res2.distance) ||
- (res1.distance && !res2.distance))
- return res1;
- else
- return new BestTile();
- }
- return new BestTile();
- case Direction.West:
- if (tile.leaf && tile.position.x < source.position.x) {
- return new BestTile(tile, Monitor.tileDistance(tile, source));
- } else if (tile.leaf) {
- return new BestTile();
- } else if (tile.child1 && tile.child2) {
- let res1 = findClosest(tile.child1);
- let res2 = findClosest(tile.child2);
- if ((res1.distance && res2.distance && res1.distance > res2.distance) ||
- (res2.distance && !res1.distance))
- return res2;
- else if ((res1.distance && res2.distance && res1.distance < res2.distance) ||
- (res1.distance && !res2.distance))
- return res1;
- else
- return new BestTile();
- }
- return new BestTile();
- case Direction.North:
- if (tile.leaf && tile.position.y < source.position.y) {
- return new BestTile(tile, Monitor.tileDistance(tile, source));
- } else if (tile.leaf) {
- return new BestTile();
- } else if (tile.child1 && tile.child2) {
- let res1 = findClosest(tile.child1);
- let res2 = findClosest(tile.child2);
- if ((res1.distance && res2.distance && res1.distance > res2.distance) ||
- (res2.distance && !res1.distance))
- return res2;
- else if ((res1.distance && res2.distance && res1.distance < res2.distance) ||
- (res1.distance && !res2.distance))
- return res1;
- else
- return new BestTile();
- }
- return new BestTile();
- case Direction.South:
- if (tile.leaf && tile.position.y > source.position.y) {
- return new BestTile(tile, Monitor.tileDistance(tile, source));
- } else if (tile.leaf) {
- return new BestTile();
- } else if (tile.child1 && tile.child2) {
- let res1 = findClosest(tile.child1);
- let res2 = findClosest(tile.child2);
- if ((res1.distance && res2.distance && res1.distance > res2.distance) ||
- (res2.distance && !res1.distance))
- return res2;
- else if ((res1.distance && res2.distance && res1.distance < res2.distance) ||
- (res1.distance && !res2.distance))
- return res1;
- else
- return new BestTile();
- }
- return new BestTile();
- default:
- return new BestTile();
- }
- };
- if (this.root) {
- let res = findClosest(this.root);
- return res.tile;
- }
- return null;
- }
- destroy() {
- this._index = -1;
- this._root = null;
- }
- static fromObject(obj) {
- let monitor = new Monitor(obj._index);
- monitor.fullscreen = obj._fullscreenState;
- if (!obj._root)
- monitor.root = null;
- else
- monitor.root = Tile.fromObject(obj._root);
- return monitor;
- }
- closestMonitor(dir) {
- let nMonitors = global.display.get_n_monitors();
- let _currGeo = global.display.get_monitor_geometry(this.index);
- let min;
- let best = null;
- switch (dir) {
- case Direction.North:
- for (let i = 0; i < nMonitors; i++) {
- if (this.index !== i) {
- let _geometry = global.display.get_monitor_geometry(i);
- if (_geometry.y < _currGeo.y && (min === undefined || _geometry.y > min)) {
- min = _geometry.y;
- best = i;
- }
- }
- }
- return best;
- case Direction.South:
- for (let i = 0; i < nMonitors; i++) {
- if (this.index !== i) {
- let _geometry = global.display.get_monitor_geometry(i);
- if (_geometry.y > _currGeo.y && (min === undefined || _geometry.y < min)) {
- min = _geometry.y;
- best = i;
- }
- }
- }
- return best;
- case Direction.East:
- for (let i = 0; i < nMonitors; i++) {
- if (this.index !== i) {
- let _geometry = global.display.get_monitor_geometry(i);
- if (_geometry.x > _currGeo.x && (min === undefined || _geometry.x < min)) {
- min = _geometry.x;
- best = i;
- }
- }
- }
- return best;
- case Direction.West:
- for (let i = 0; i < nMonitors; i++) {
- if (this.index !== i) {
- let _geometry = global.display.get_monitor_geometry(i);
- if (_geometry.x < _currGeo.x && (!min || _geometry.x > min)) {
- min = _geometry.x;
- best = i;
- }
- }
- }
- return best;
- default:
- return null;
- }
- }
- /** Returns tile closest to the edge on a monitor
- * - If the monitor is in fullscreen it returns the maximized window
- *
- * @param {Direction} dir
- * @returns {Tile | null}
- */
- getTile(dir) {
- if (this.root === null)
- return null;
- if (this.fullscreen)
- return this.root.find(t => t.state === TileState.MAXIMIZED);
- let getTileBis = t => {
- switch (dir) {
- case Direction.East:
- if (t.child2 !== null && t.child1 !== null)
- return t.child1.position.x > t.child2.position.x ? getTileBis(t.child1) : getTileBis(t.child2);
- else if (t.child1 !== null)
- return getTileBis(t.child1);
- else if (t.child2 !== null)
- return getTileBis(t.child2);
- else
- return t;
- case Direction.West:
- if (t.child2 !== null && t.child1 !== null)
- return t.child1.position.x < t.child2.position.x ? getTileBis(t.child1) : getTileBis(t.child2);
- else if (t.child1 !== null)
- return getTileBis(t.child1);
- else if (t.child2 !== null)
- return getTileBis(t.child2);
- else
- return t;
- case Direction.North:
- if (t.child2 !== null && t.child1 !== null)
- return t.child1.position.y < t.child2.position.y ? getTileBis(t.child1) : getTileBis(t.child2);
- else if (t.child1 !== null)
- return getTileBis(t.child1);
- else if (t.child2 !== null)
- return getTileBis(t.child2);
- else
- return t;
- case Direction.South:
- if (t.child2 !== null && t.child1 !== null)
- return t.child1.position.y > t.child2.position.y ? getTileBis(t.child1) : getTileBis(t.child2);
- else if (t.child1 !== null)
- return getTileBis(t.child1);
- else if (t.child2 !== null)
- return getTileBis(t.child2);
- else
- return t;
- default:
- return t;
- }
- };
- return getTileBis(this.root);
- }
- }
|