/* * Copyright 2019 The Chromium Authors. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ package io.flutter.editor; import com.intellij.openapi.editor.Document; import java.util.Arrays; import java.util.List; import static java.lang.Math.max; import static java.lang.Math.min; /** * Class used to determine whether regular indent guides intersect with * WidgetIndentGuides. * <p> * If indent guides are allowed to render that intersect with widget indent * guides, there will be flickering or other strange visual artifacts. * <p> * It is not possible to get indent guides to render in a stable z-order so * there is no way to make regular indent guides render before widget indent * guides. Even if that was possible it would not be desirable as there are * cases where displaying both guides would be distracting such as showing a * regular guide at indent 2 that draws a line through the middle of the * horizontal leg of widget indent guides for a list of children with indent 4. */ public class WidgetIndentHitTester { /** * Whether each line overlaps a Widget Indent Guide. */ private final boolean[] lines; WidgetIndentHitTester(List<WidgetIndentGuideDescriptor> descriptors, Document document) { final int lineCount = document.getLineCount(); lines = new boolean[lineCount]; // TODO(jacobr): optimize using a more clever data structure. for (WidgetIndentGuideDescriptor descriptor : descriptors) { // if (descriptor.parent) { final int last = min(lines.length, descriptor.endLine + 1); for (int i = max(descriptor.startLine - 1, 0); i < last; i++) { lines[i] = true; } } } } @Override public int hashCode() { return Arrays.hashCode(lines); } @Override public boolean equals(Object o) { if (this == o) return true; if (!(o instanceof WidgetIndentHitTester)) return false; final WidgetIndentHitTester other = (WidgetIndentHitTester)o; return Arrays.equals(lines, other.lines); } // TODO(jacobr): we could be smarter about intersection detection by // considering the indent of the intersecting lineRange as well. // If we could do that we would have to filter out fewer regular indent // guides that appear to intersect with the widget indent guides. // This could really be reframed as a rectangle intersection problem but that // would introduce additional complexity and we have yet to receive feedback // complaining about the missing regular indent guides for cases where the // guides overlap horizontally. public boolean intersects(LineRange lineRange) { final int last = min(lines.length, lineRange.endLine + 1); // TODO(jacobr): why the -1 on startLine? for (int i = max(lineRange.startLine - 1, 0); i < last; i++) { if (lines[i]) { return true; } } return false; } }