Skip to content

Commit

Permalink
Initial read-only text area
Browse files Browse the repository at this point in the history
Affects: #14
  • Loading branch information
io7m committed Nov 25, 2023
1 parent 646ca4f commit c225d6f
Show file tree
Hide file tree
Showing 21 changed files with 1,242 additions and 13 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
import com.io7m.jsycamore.api.windows.SyWindowViewportAccumulatorType;
import com.io7m.jtensors.core.parameterized.vectors.PVector2I;

import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.function.Predicate;
Expand Down Expand Up @@ -119,6 +120,20 @@ Optional<SyComponentType> componentForWindowRelative(
SyWindowViewportAccumulatorType context,
SyComponentQuery query);

/**
* A convenience function to remove all child components of this component.
*/

default void childrenClear()
{
final var children =
List.copyOf(this.node().children());

for (final var child : children) {
this.node().childRemove(child);
}
}

/**
* A convenience function to add a component as a child of this component.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

package com.io7m.jsycamore.api.components;

import com.io7m.jattribute.core.AttributeReadableType;
import com.io7m.jsycamore.api.themes.SyThemeClassNameType;

import java.util.List;
Expand All @@ -34,4 +35,10 @@ default List<SyThemeClassNameType> themeClassesDefaultForComponent()
{
return List.of(TEXT_AREA);
}

/**
* @return The text sections within the area
*/

AttributeReadableType<List<String>> textSections();
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,5 +23,11 @@
public interface SyTextAreaType
extends SyTextAreaReadableType, SyComponentType
{
/**
* Append a text section to the end of the text area.
*
* @param section The section
*/

void textSectionAppend(String section);
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@

package com.io7m.jsycamore.api.text;

import java.util.List;

/**
* A font.
*/
Expand Down Expand Up @@ -55,4 +57,35 @@ public interface SyFontType
*/

SyFontDescription description();

/**
* Split the given text into lines based on the given wrapping width.
*
* @param text The text
* @param width The width
*
* @return The split lines
*/

List<SyTextSectionLineType> textLayout(
String text,
int width);

/**
* Split the given texts into lines based on the given wrapping width.
*
* @param texts The texts
* @param width The width
*
* @return The split lines
*/

default List<SyTextSectionLineType> textLayoutMultiple(
final List<String> texts,
final int width)
{
return texts.stream()
.flatMap(s -> this.textLayout(s, width).stream())
.toList();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/*
* Copyright © 2023 Mark Raynsford <[email protected]> https://www.io7m.com
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
* IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/


package com.io7m.jsycamore.api.text;

import com.io7m.jregions.core.parameterized.sizes.PAreaSizeI;
import com.io7m.jsycamore.api.spaces.SySpaceParentRelativeType;

/**
* A line that has been produced by splitting a text section into multiple lines
* based on a wrapping width.
*/

public interface SyTextSectionLineType
{
/**
* @return The size of the text line
*/

PAreaSizeI<SySpaceParentRelativeType> size();

/**
* @return The actual line text
*/

String text();
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,19 @@

package com.io7m.jsycamore.awt.internal;

import com.io7m.jregions.core.parameterized.sizes.PAreaSizeI;
import com.io7m.jsycamore.api.spaces.SySpaceParentRelativeType;
import com.io7m.jsycamore.api.text.SyFontDescription;
import com.io7m.jsycamore.api.text.SyFontType;
import com.io7m.jsycamore.api.text.SyTextSectionLineType;

import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.font.LineBreakMeasurer;
import java.awt.font.TextAttribute;
import java.text.AttributedString;
import java.util.LinkedList;
import java.util.List;
import java.util.Objects;

/**
Expand Down Expand Up @@ -80,4 +88,65 @@ public SyFontDescription description()
{
return this.description;
}

@Override
public List<SyTextSectionLineType> textLayout(
final String text,
final int width)
{
Objects.requireNonNull(text, "text");

if (text.isEmpty()) {
return List.of(
new SectionLine(PAreaSizeI.of(0, this.textHeight()), "")
);
}

final var attributedString = new AttributedString(text);
attributedString.addAttribute(TextAttribute.FONT, this.font);

final var breaker =
new LineBreakMeasurer(
attributedString.getIterator(),
this.metrics.getFontRenderContext()
);

final var fWidth = (float) width;

var indexThen = 0;

final var results =
new LinkedList<SyTextSectionLineType>();

while (true) {
final var layout = breaker.nextLayout(fWidth);
if (layout == null) {
break;
}

final var indexNow =
breaker.getPosition();
final var bounds =
layout.getBounds();

final var line =
new SectionLine(
PAreaSizeI.of((int) Math.ceil(bounds.getWidth()), this.textHeight()),
text.substring(indexThen, indexNow)
);

results.add(line);
indexThen = indexNow;
}

return results;
}

private record SectionLine(
PAreaSizeI<SySpaceParentRelativeType> size,
String text)
implements SyTextSectionLineType
{

}
}
Loading

0 comments on commit c225d6f

Please sign in to comment.