Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

S08a #8

Open
wants to merge 6 commits into
base: s07a
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
MagicBoxes.dart.js
*~
70 changes: 66 additions & 4 deletions Board.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ class Board {
// The board is redrawn every INTERVAL ms.
static final int INTERVAL = 8;

CanvasElement canvas;
CanvasRenderingContext2D context;

int width;
Expand All @@ -15,14 +16,16 @@ class Board {

Box beforeLastBoxClicked;
Box lastBoxClicked;
Box lastBoxSelected;
Line lastLineSelected;

MenuBar menuBar;
ToolBar toolBar;

num defaultLineWidth;

Board(CanvasElement canvas) {
context = canvas.getContext("2d");
Board(this.canvas) {
context = canvas.getContext('2d');
width = canvas.width;
height = canvas.height;
defaultLineWidth = context.lineWidth;
Expand Down Expand Up @@ -63,6 +66,17 @@ class Board {
}
}

void printBoxNames() {
for (Box box in boxes) {
print(box.title);
}
}

void saveAsPng() {
ImageElement modelImage = document.query('#modelImage');
modelImage.src = canvas.toDataURL("image/png");
}

void createBoxesInDiagonal() {
int x = 0; int y = 0;
while (true) {
Expand Down Expand Up @@ -206,6 +220,56 @@ class Board {
deselectLines();
}

void increaseHeightOfSelectedBoxes() {
for (Box box in boxes) {
if (box.isSelected()) {
box.height = box.height + Box.DEFAULT_INCREMENT;
}
}
}

void decreaseHeightOfSelectedBoxes() {
for (Box box in boxes) {
if (box.isSelected()) {
box.height = box.height - Box.DEFAULT_INCREMENT;
}
}
}

void increaseWidthOfSelectedBoxes() {
for (Box box in boxes) {
if (box.isSelected()) {
box.width = box.width + Box.DEFAULT_INCREMENT;
}
}
}

void decreaseWidthOfSelectedBoxes() {
for (Box box in boxes) {
if (box.isSelected()) {
box.width = box.width - Box.DEFAULT_INCREMENT;
}
}
}

void increaseSizeOfSelectedBoxes() {
for (Box box in boxes) {
if (box.isSelected()) {
box.height = box.height + Box.DEFAULT_INCREMENT;
box.width = box.width + Box.DEFAULT_INCREMENT;
}
}
}

void decreaseSizeOfSelectedBoxes() {
for (Box box in boxes) {
if (box.isSelected()) {
box.height = box.height - Box.DEFAULT_INCREMENT;
box.width = box.width - Box.DEFAULT_INCREMENT;
}
}
}

void hideSelectedBoxes() {
for (Box box in boxes) {
if (box.isSelected()) {
Expand Down Expand Up @@ -248,8 +312,6 @@ class Board {
showHiddenLines();
}

int get nextBoxNo() => boxes.length + 1;

int countSelectedBoxes() {
int count = 0;
for (Box box in boxes) {
Expand Down
128 changes: 109 additions & 19 deletions Box.dart
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
class Box {

static final int DEFAULT_WIDTH = 100;
static final int DEFAULT_HEIGHT = 100;
static final int DEFAULT_WIDTH = 120;
static final int DEFAULT_HEIGHT = 120;
static final int DEFAULT_INCREMENT = 20;

static final int SSS = 6; // selection square size
static final int TBH = 20; // title box height
Expand All @@ -10,25 +11,26 @@ class Box {

final Board board;

String _name = 'Box';
int x;
int y;
int width;
int height;

String textFontSize = 12;
String title = "Box";
int titleNo;
String item = "Item";
List<Item> items;

bool _selected = false;
bool _hidden = false;
bool _mouseDown = false;

String textFontSize = 12;
num defaultLineWidth;

Box(this.board, this.x, this.y, this.width, this.height) {
titleNo = board.nextBoxNo;
defaultLineWidth = board.context.lineWidth;

items = new List();

draw();
// Box events (actually, canvas events).
document.query('#canvas').on.mouseDown.add(onMouseDown);
Expand All @@ -39,17 +41,31 @@ class Box {
void draw() {
if (!isHidden()) {
board.context.beginPath();
board.context.clearRect(x, y, width, height);
board.context.rect(x, y, width, height);
board.context.moveTo(x, y + TBH);
board.context.lineTo(x + width, y + TBH);
board.context.font = "bold " + textFontSize + "px sans-serif";
board.context.textAlign = "start";
board.context.textBaseline = "top";
board.context.fillText(toString(), x + TOS, y + TOS, width - TOS);
board.context.fillText(item + 1, x + TOS, y + TOS + TBH, width - TOS);
board.context.fillText(item + 2, x + TOS, y + TOS + TBH + IOS, width - TOS);
board.context.fillText(item + 3, x + TOS, y + TOS + TBH + 2 * IOS, width - TOS);
board.context.fillText(item + 4, x + TOS, y + TOS + TBH + 3 * IOS, width - TOS);
board.context.font = 'bold ' + textFontSize + 'px sans-serif';
board.context.textAlign = 'start';
board.context.textBaseline = 'top';
board.context.fillText(title, x + TOS, y + TOS, width - TOS);
int i = 0;
for (Item item in items) {
if (item.category == 'attribute') {
board.context.font = '' + textFontSize + 'px sans-serif';
board.context.fillText(item.name, x + TOS, y + TOS + TBH + i * IOS, width - TOS);
} else if (item.category == 'globally unique') {
board.context.font = 'italic ' + textFontSize + 'px sans-serif';
board.context.fillText(item.name, x + TOS, y + TOS + TBH + i * IOS, width - TOS);
} else if (item.category == 'identifier') {
board.context.font = 'bold italic ' + textFontSize + 'px sans-serif';
board.context.fillText(item.name, x + TOS, y + TOS + TBH + i * IOS, width - TOS);
} else if (item.category == 'required') {
board.context.font = 'bold ' + textFontSize + 'px sans-serif';
board.context.fillText(item.name, x + TOS, y + TOS + TBH + i * IOS, width - TOS);
}
i++;
}
if (isSelected()) {
board.context.rect(x, y, SSS, SSS);
board.context.rect(x + width - SSS, y, SSS, SSS);
Expand All @@ -62,16 +78,60 @@ class Box {
}
}

select() => _selected = true;
deselect() => _selected = false;
toggleSelection() => _selected = !_selected;
void select() {
_selected = true;
board.lastBoxSelected = this;
}

void deselect() {
_selected = false;
board.lastBoxSelected = null;
}

void toggleSelection() {
_selected = !_selected;
if (_selected) {
board.lastBoxSelected = this;
} else {
board.lastBoxSelected = null;
}
}

bool isSelected() => _selected;

hide() => _hidden = true;
show() => _hidden = false;
bool isHidden() => _hidden;

String toString() => '$title$titleNo ($x, $y)';
void set title(String name) {
_name = name;
}

String get title() {
return _name;
}

Item findItem(String name) {
for (Item item in items) {
if (item.name == name) {
return item;
}
}
return null;
}

bool removeItem(Item item) {
if (item != null) {
int index = items.indexOf(item, 0);
if (index >= 0) {
items.removeRange(index, 1);
return true;
}
}
return false;
}

String toString() => '$title ($x, $y)';

Point center() {
int centerX = x + width / 2;
Expand All @@ -87,6 +147,36 @@ class Box {
}
}

/**
* Return the intersection point of the line between the begin <x1,y1>
* and end <x2,y2> points with this box;
* <x1,y1> is inside the box, <x2,y2> may be inside or outside.
* Fast algorithm.
*/
Point getIntersectionPoint(Point lineBeginPoint, Point lineEndPoint) {
int x1 = lineBeginPoint.x;
int y1 = lineBeginPoint.y;
int x2 = lineEndPoint.x;
int y2 = lineEndPoint.y;
if (x2 == x1) /* vertical line */
return new Point(x2, (y2 < y1 ? this.y : this.y + this.height));
if (y2 == y1) /* horizontal line */
return new Point((x2 < x1 ? this.x : this.x + this.width), y2);

double m = (y2 - y1) / (x2 - x1);
int x = (x2 < x1 ? this.x : this.x + this.width);
double fy = m * (x - x2) + y2;
int y;
/* float comparison, because fy may be bigger than the biggest integer */
if (fy >= this.y && fy <= this.y + this.height) {
y = fy.toInt();
} else {
y = (y2 < y1 ? this.y : this.y + this.height);
x = ((fy - y2) / m).toInt() + x2;
}
return new Point(x, y);
}

void onMouseDown(MouseEvent e) {
_mouseDown = true;
if (board.toolBar.isSelectToolOn() && contains(e.offsetX, e.offsetY)) {
Expand Down
14 changes: 14 additions & 0 deletions Item.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
class Item {

final Box box;

String name;
String category;

Item(this.box, String name, String category) {
this.name = name;
this.category = category;
box.items.add(this);
}

}
Loading