Basic imager suppert, loading documents from resource.

This commit is contained in:
Florian Nücke 2015-04-08 09:37:50 +02:00
parent c1156aab38
commit c65142a059
4 changed files with 108 additions and 28 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 342 B

View File

@ -0,0 +1,22 @@
# Headline with more lines [with link](huehue) and *some* more
This is some test text for the subset of Markdown supported by the planned ingame documentation system for OpenComputers.
![opencomputers:transistor](../../textures/gui/button_power.png)
*This* is *italic* text, ~~strikethrough~~ maybe abc-ter **some** text **in bold**. Is _this underlined_? Oh, no, _it's also italic!_ Well, this \*isn't bold*.
## Smaller headline [also with *link* but this __one__ longer](huehue)
This is *italic
over two* lines. But *this ... no *this is* **_bold italic_** *text*.
### even smaller
*not italic *because ** why would it be*eh
isn't*.
# not a header
asdasd ![Hello There!](button_power.png) qweqwe
And finally, [this is a link!](https://avatars1.githubusercontent.com/u/514903).

View File

@ -2,15 +2,19 @@ package li.cil.oc.client.gui
import java.util
import com.google.common.base.Charsets
import li.cil.oc.Settings
import li.cil.oc.client.Textures
import li.cil.oc.util.PseudoMarkdown
import net.minecraft.client.Minecraft
import net.minecraft.client.gui.Gui
import net.minecraft.client.gui.GuiScreen
import net.minecraft.client.gui.ScaledResolution
import net.minecraft.util.ResourceLocation
import org.lwjgl.input.Mouse
import scala.collection.convert.WrapAsJava._
import scala.io.Source
class Manual extends GuiScreen {
var guiLeft = 0
@ -18,6 +22,7 @@ class Manual extends GuiScreen {
var xSize = 0
var ySize = 0
var offset = 0
var document = Iterable.empty[PseudoMarkdown.Segment]
var documentHeight = 0
final val documentMaxWidth = 230
final val documentMaxHeight = 176
@ -25,33 +30,16 @@ class Manual extends GuiScreen {
final val scrollPosY = 6
final val scrollHeight = 180
val document = PseudoMarkdown.parse( """# Headline with more lines [with link](huehue) and *some* more
|
|This is some test text for the subset of Markdown supported by the planned ingame documentation system for OpenComputers.
|
|*This* is *italic* text, ~~strikethrough~~ maybe abc-ter **some** text **in bold**. Is _this underlined_? Oh, no, _it's also italic!_ Well, this \*isn't bold*.
|
|## Smaller headline [also with *link* but this __one__ longer](huehue)
|
|This is *italic
|over two* lines. But *this ... no *this is* **_bold italic_** *text*.
|
|### even smaller
|
|*not italic *because ** why would it be*eh
|
|isn't*.
|
| # not a header
|
|![](https://avatars1.githubusercontent.com/u/514903)
|
|And finally, [this is a link!](https://avatars1.githubusercontent.com/u/514903).""".stripMargin)
def add[T](list: util.List[T], value: Any) = list.add(value.asInstanceOf[T])
protected var scrollButton: ImageButton = _
def loadPage(location: ResourceLocation): Iterator[String] = {
val resource = Minecraft.getMinecraft.getResourceManager.getResource(location)
val is = resource.getInputStream
Source.fromInputStream(is)(Charsets.UTF_8).getLines()
}
override def doesGuiPauseGame = false
override def initGui(): Unit = {
@ -66,6 +54,7 @@ class Manual extends GuiScreen {
xSize = guiSize.getScaledWidth
ySize = guiSize.getScaledHeight
offset = 0
document = PseudoMarkdown.parse(loadPage(new ResourceLocation(Settings.resourceDomain, "doc/index.md")))
documentHeight = PseudoMarkdown.height(document, documentMaxWidth, fontRendererObj)
scrollButton = new ImageButton(1, guiLeft + scrollPosX, guiTop + scrollPosY, 6, 13, Textures.guiButtonScroll)
@ -80,7 +69,7 @@ class Manual extends GuiScreen {
PseudoMarkdown.render(document, guiLeft + 8, guiTop + 8, documentMaxWidth, documentMaxHeight, offset, fontRendererObj, mouseX, mouseY) match {
case Some(segment) => segment.tooltip match {
case Some(text) => drawHoveringText(seqAsJavaList(text.lines.toSeq), mouseX, mouseY, fontRendererObj)
case Some(text) if text.nonEmpty => drawHoveringText(seqAsJavaList(text.lines.toSeq), mouseX, mouseY, fontRendererObj)
case _ =>
}
case _ =>

View File

@ -1,7 +1,16 @@
package li.cil.oc.util
import java.io.InputStream
import javax.imageio.ImageIO
import li.cil.oc.Settings
import net.minecraft.client.Minecraft
import net.minecraft.client.gui.FontRenderer
import net.minecraft.client.renderer.texture.AbstractTexture
import net.minecraft.client.renderer.texture.TextureUtil
import net.minecraft.client.resources.IResourceManager
import net.minecraft.util.EnumChatFormatting
import net.minecraft.util.ResourceLocation
import org.lwjgl.opengl.GL11
import scala.annotation.tailrec
@ -16,8 +25,8 @@ object PseudoMarkdown {
/**
* Parses a plain text document into a list of segments.
*/
def parse(document: String): Iterable[Segment] = {
var segments = document.lines.flatMap(line => Iterable(new TextSegment(null, line), new NewLineSegment())).toArray
def parse(document: Iterator[String]): Iterable[Segment] = {
var segments = document.flatMap(line => Iterable(new TextSegment(null, line), new NewLineSegment())).toArray
for ((pattern, factory) <- segmentTypes) {
segments = segments.flatMap(_.refine(pattern, factory))
}
@ -118,7 +127,7 @@ object PseudoMarkdown {
def link: Option[String] = None
private[PseudoMarkdown] def notifyHover(): Unit
private[PseudoMarkdown] def notifyHover(): Unit = {}
private[PseudoMarkdown] def checkHovered(mouseX: Int, mouseY: Int, x: Int, y: Int, w: Int, h: Int): Option[InteractiveSegment] = if (mouseX >= x && mouseY >= y && mouseX <= x + w && mouseY <= y + h) Some(this) else None
}
@ -306,7 +315,45 @@ object PseudoMarkdown {
override def toString: String = s"{StrikethroughSegment: text = $text}"
}
private class ImageSegment(val parent: Segment, val tooltip: String, val url: String) extends Segment {
private class ImageSegment(val parent: Segment, val title: String, val url: String) extends InteractiveSegment {
val path = if (url.startsWith("/")) url else "doc/img/" + url
val location = new ResourceLocation(Settings.resourceDomain, path)
val texture = {
val manager = Minecraft.getMinecraft.getTextureManager
manager.getTexture(location) match {
case image: ImageTexture => image
case _ =>
val image = new ImageTexture(location)
manager.loadTexture(location, image)
image
}
}
override def tooltip: Option[String] = Option(title)
override def height(indent: Int, maxWidth: Int, renderer: FontRenderer): Int = math.max(lineHeight(renderer), texture.height + 10 - lineHeight(renderer))
override def width(indent: Int, maxWidth: Int, renderer: FontRenderer): Int = maxWidth
override def render(x: Int, y: Int, indent: Int, maxWidth: Int, maxHeight: Int, renderer: FontRenderer, mouseX: Int, mouseY: Int): Option[InteractiveSegment] = {
Minecraft.getMinecraft.getTextureManager.bindTexture(location)
val xOffset = (maxWidth - texture.width) / 2
val yOffset = 4 + (if (indent > 0) lineHeight(renderer) else 0)
GL11.glColor4f(1, 1, 1, 1)
GL11.glBegin(GL11.GL_QUADS)
GL11.glTexCoord2f(0, 0)
GL11.glVertex2f(x + xOffset, y + yOffset)
GL11.glTexCoord2f(0, 1)
GL11.glVertex2f(x + xOffset, y + yOffset + texture.height)
GL11.glTexCoord2f(1, 1)
GL11.glVertex2f(x + xOffset + texture.width, y + yOffset + texture.height)
GL11.glTexCoord2f(1, 0)
GL11.glVertex2f(x + xOffset + texture.width, y + yOffset)
GL11.glEnd()
checkHovered(mouseX, mouseY, x + xOffset, y + yOffset, texture.width, texture.height)
}
override def toString: String = s"{ImageSegment: tooltip = $tooltip, url = $url}"
}
@ -321,6 +368,28 @@ object PseudoMarkdown {
override def toString: String = s"{NewLineSegment}"
}
private class ImageTexture(val location: ResourceLocation) extends AbstractTexture {
var width = 0
var height = 0
override def loadTexture(manager: IResourceManager): Unit = {
deleteGlTexture()
var is: InputStream = null
try {
val resource = manager.getResource(location)
is = resource.getInputStream
val bi = ImageIO.read(is)
TextureUtil.uploadTextureImageAllocate(getGlTextureId, bi, false, false)
width = bi.getWidth
height = bi.getHeight
}
finally {
Option(is).foreach(_.close())
}
}
}
// ----------------------------------------------------------------------- //
private def HeaderSegment(s: Segment, m: Regex.Match) = new HeaderSegment(s, m.group(2), m.group(1).length)