m_target = new GridTarget();
// prepare location in model
Point location = mouseLocation.getCopy();
PolicyUtils.translateAbsoluteToModel(this, location);
// prepare grid information
IGridInfo gridInfo = m_layout.getGridInfo();
Interval[] columnIntervals = gridInfo.getColumnIntervals();
Interval[] rowIntervals = gridInfo.getRowIntervals();
int lastX = columnIntervals.length != 0 ? columnIntervals[columnIntervals.length - 1].end() : 0;
int lastY = rowIntervals.length != 0 ? rowIntervals[rowIntervals.length - 1].end() : 0;
// prepare insert bounds
{
if (columnIntervals.length != 0) {
m_target.m_rowInsertBounds.x = columnIntervals[0].begin - INSERT_MARGINS;
m_target.m_rowInsertBounds.setRight(lastX + INSERT_MARGINS);
} else {
m_target.m_rowInsertBounds.x = 0;
m_target.m_rowInsertBounds.setRight(getHostFigure().getSize().width);
}
if (rowIntervals.length != 0) {
m_target.m_columnInsertBounds.y = rowIntervals[0].begin - INSERT_MARGINS;
m_target.m_columnInsertBounds.setBottom(lastY + INSERT_MARGINS);
} else {
m_target.m_columnInsertBounds.y = 0;
m_target.m_columnInsertBounds.setBottom(getHostFigure().getSize().height);
}
}
// find existing column
for (int columnIndex = 0; columnIndex < columnIntervals.length; columnIndex++) {
boolean isLast = columnIndex == columnIntervals.length - 1;
Interval interval = columnIntervals[columnIndex];
Interval nextInterval = !isLast ? columnIntervals[columnIndex + 1] : null;
// before first
if (location.x < columnIntervals[0].begin) {
m_target.m_column = 0;
m_target.m_columnInsert = true;
// prepare parameters
int[] parameters =
getInsertFeedbackParameters(new Interval(0, 0), interval, INSERT_COLUMN_SIZE);
// feedback
m_target.m_feedbackBounds.x = parameters[3];
m_target.m_feedbackBounds.width = parameters[4] - parameters[3];
// insert
m_target.m_columnInsertBounds.x = parameters[1];
m_target.m_columnInsertBounds.width = parameters[2] - parameters[1];
// stop
break;
}
// gap or near to end of interval
if (!isLast) {
int gap = nextInterval.begin - interval.end();
boolean directGap = interval.end() <= location.x && location.x < nextInterval.begin;
boolean narrowGap = gap < 2 * INSERT_COLUMN_SIZE;
boolean nearEnd = Math.abs(location.x - interval.end()) < INSERT_COLUMN_SIZE;
boolean nearBegin = Math.abs(location.x - nextInterval.begin) < INSERT_COLUMN_SIZE;
if (directGap || narrowGap && (nearEnd || nearBegin)) {
m_target.m_column = columnIndex + 1;
m_target.m_columnInsert = true;
// prepare parameters
int[] parameters =
getInsertFeedbackParameters(interval, nextInterval, INSERT_COLUMN_SIZE);
// feedback
m_target.m_feedbackBounds.x = parameters[3];
m_target.m_feedbackBounds.width = parameters[4] - parameters[3];
// insert
m_target.m_columnInsertBounds.x = parameters[1];
m_target.m_columnInsertBounds.width = parameters[2] - parameters[1];
// stop
break;
}
}
// column
if (interval.contains(location.x)) {
m_target.m_column = columnIndex;
// feedback
m_target.m_feedbackBounds.x = interval.begin;
m_target.m_feedbackBounds.width = interval.length + 1;
// stop
break;
}
}
// find virtual column
if (m_target.m_column == -1) {
int columnGap = gridInfo.getVirtualColumnGap();
int columnSize = gridInfo.getVirtualColumnSize();
//
int newWidth = columnSize + columnGap;
int newDelta = (location.x - lastX - columnGap / 2) / newWidth;
//
m_target.m_column = columnIntervals.length + newDelta;
m_target.m_feedbackBounds.x = lastX + columnGap + newWidth * newDelta;
m_target.m_feedbackBounds.width = columnSize + 1;
}
// find existing row
for (int rowIndex = 0; rowIndex < rowIntervals.length; rowIndex++) {
boolean isLast = rowIndex == rowIntervals.length - 1;
Interval interval = rowIntervals[rowIndex];
Interval nextInterval = !isLast ? rowIntervals[rowIndex + 1] : null;
// before first
if (location.y < rowIntervals[0].begin) {
m_target.m_row = 0;
m_target.m_rowInsert = true;
// prepare parameters
int[] parameters =
getInsertFeedbackParameters(new Interval(0, 0), interval, INSERT_ROW_SIZE);
// feedback
m_target.m_feedbackBounds.y = parameters[3];
m_target.m_feedbackBounds.height = parameters[4] - parameters[3];
// insert
m_target.m_rowInsertBounds.y = parameters[1];
m_target.m_rowInsertBounds.height = parameters[2] - parameters[1];
// stop
break;
}
// gap or near to end of interval
if (!isLast) {
int gap = nextInterval.begin - interval.end();
boolean directGap = interval.end() <= location.y && location.y < nextInterval.begin;
boolean narrowGap = gap < 2 * INSERT_ROW_SIZE;
boolean nearEnd = Math.abs(location.y - interval.end()) < INSERT_ROW_SIZE;
boolean nearBegin = Math.abs(location.y - nextInterval.begin) < INSERT_ROW_SIZE;
if (directGap || narrowGap && (nearEnd || nearBegin)) {
m_target.m_row = rowIndex + 1;
m_target.m_rowInsert = true;
// prepare parameters
int[] parameters = getInsertFeedbackParameters(interval, nextInterval, INSERT_ROW_SIZE);
// feedback
m_target.m_feedbackBounds.y = parameters[3];
m_target.m_feedbackBounds.height = parameters[4] - parameters[3];
// insert
m_target.m_rowInsertBounds.y = parameters[1];
m_target.m_rowInsertBounds.height = parameters[2] - parameters[1];
// stop
break;
}
}
// row
if (interval.contains(location.y)) {
m_target.m_row = rowIndex;
// feedback
m_target.m_feedbackBounds.y = interval.begin;
m_target.m_feedbackBounds.height = interval.length + 1;
// stop
break;
}
}
// find virtual row
if (m_target.m_row == -1) {
int rowGap = gridInfo.getVirtualRowGap();
int rowSize = gridInfo.getVirtualRowSize();
//
int newHeight = rowSize + rowGap;
int newDelta = (location.y - lastY - rowGap / 2) / newHeight;
//
m_target.m_row = rowIntervals.length + newDelta;