Tooltips for tabs.

This commit is contained in:
Florian Nücke 2015-04-09 19:07:46 +02:00
parent 770bd5c28a
commit 23266b776e
10 changed files with 48 additions and 24 deletions

View File

@ -26,11 +26,12 @@ public class Manual {
* usually be one, for your main index page. * usually be one, for your main index page.
* *
* @param renderer the renderer used to render the icon on your tab. * @param renderer the renderer used to render the icon on your tab.
* @param tooltip the unlocalized tooltip of the tab, or <tt>null</tt>.
* @param path the path to the page to open when the tab is clicked. * @param path the path to the page to open when the tab is clicked.
*/ */
public static void addTab(TabIconRenderer renderer, String path) { public static void addTab(TabIconRenderer renderer, String tooltip, String path) {
if (API.manual != null) if (API.manual != null)
API.manual.addTab(renderer, path); API.manual.addTab(renderer, tooltip, path);
} }
/** /**

View File

@ -17,9 +17,10 @@ public interface ManualAPI {
* usually be one, for your main index page. * usually be one, for your main index page.
* *
* @param renderer the renderer used to render the icon on your tab. * @param renderer the renderer used to render the icon on your tab.
* @param tooltip the unlocalized tooltip of the tab, or <tt>null</tt>.
* @param path the path to the page to open when the tab is clicked. * @param path the path to the page to open when the tab is clicked.
*/ */
void addTab(TabIconRenderer renderer, String path); void addTab(TabIconRenderer renderer, String tooltip, String path);
/** /**
* Register a path provider. * Register a path provider.

View File

@ -1,5 +1,8 @@
package li.cil.oc.api.manual; package li.cil.oc.api.manual;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
/** /**
* Allows defining a renderer for a manual tab. * Allows defining a renderer for a manual tab.
* <p/> * <p/>
@ -18,5 +21,6 @@ public interface TabIconRenderer {
* This should render something in a 16x16 area. The OpenGL state has been * This should render something in a 16x16 area. The OpenGL state has been
* adjusted so that drawing starts at (0,0,0), and should go to (16,16,0). * adjusted so that drawing starts at (0,0,0), and should go to (16,16,0).
*/ */
@SideOnly(Side.CLIENT)
void render(); void render();
} }

View File

@ -1,5 +1,7 @@
package li.cil.oc.api.prefab; package li.cil.oc.api.prefab;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import li.cil.oc.api.manual.TabIconRenderer; import li.cil.oc.api.manual.TabIconRenderer;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.OpenGlHelper; import net.minecraft.client.renderer.OpenGlHelper;
@ -20,6 +22,7 @@ public class ItemStackTabIconRenderer implements TabIconRenderer {
this.stack = stack; this.stack = stack;
} }
@SideOnly(Side.CLIENT)
@Override @Override
public void render() { public void render() {
GL11.glEnable(GL12.GL_RESCALE_NORMAL); GL11.glEnable(GL12.GL_RESCALE_NORMAL);

View File

@ -1,5 +1,7 @@
package li.cil.oc.api.prefab; package li.cil.oc.api.prefab;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import li.cil.oc.api.manual.TabIconRenderer; import li.cil.oc.api.manual.TabIconRenderer;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.Tessellator; import net.minecraft.client.renderer.Tessellator;
@ -17,6 +19,7 @@ public class TextureTabIconRenderer implements TabIconRenderer {
} }
@Override @Override
@SideOnly(Side.CLIENT)
public void render() { public void render() {
Minecraft.getMinecraft().getTextureManager().bindTexture(location); Minecraft.getMinecraft().getTextureManager().bindTexture(location);
final Tessellator t = Tessellator.instance; final Tessellator t = Tessellator.instance;

View File

@ -183,6 +183,8 @@ oc:gui.Error.NoCPU=Im Computer ist kein Hauptprozessor (CPU) installiert.
oc:gui.Error.NoEnergy=Nicht genug Energie. oc:gui.Error.NoEnergy=Nicht genug Energie.
oc:gui.Error.NoRAM=Im Computer ist kein RAM installiert. oc:gui.Error.NoRAM=Im Computer ist kein RAM installiert.
oc:gui.Error.OutOfMemory=Nicht genug Arbeitsspeicher. oc:gui.Error.OutOfMemory=Nicht genug Arbeitsspeicher.
oc:gui.Manual.Blocks=Blöcke
oc:gui.Manual.Items=Gegenstände
oc:gui.Raid.Warning=§4Eine Platte einzufügen löscht sie.[nl] Eine Platte zu entfernen löscht das Raid. oc:gui.Raid.Warning=§4Eine Platte einzufügen löscht sie.[nl] Eine Platte zu entfernen löscht das Raid.
oc:gui.Robot.Power=Energie oc:gui.Robot.Power=Energie
oc:gui.Robot.TurnOff=Ausschalten oc:gui.Robot.TurnOff=Ausschalten

View File

@ -183,6 +183,8 @@ oc:gui.Error.NoCPU=No CPU is installed in the computer.
oc:gui.Error.NoEnergy=Not enough energy. oc:gui.Error.NoEnergy=Not enough energy.
oc:gui.Error.NoRAM=No RAM is installed in the computer. oc:gui.Error.NoRAM=No RAM is installed in the computer.
oc:gui.Error.OutOfMemory=Out of memory. oc:gui.Error.OutOfMemory=Out of memory.
oc:gui.Manual.Blocks=Blocks
oc:gui.Manual.Items=Items
oc:gui.Raid.Warning=§4Adding a disk wipes it.[nl] Removing a disk wipes the raid. oc:gui.Raid.Warning=§4Adding a disk wipes it.[nl] Removing a disk wipes the raid.
oc:gui.Robot.Power=Energy oc:gui.Robot.Power=Energy
oc:gui.Robot.TurnOff=Turn off oc:gui.Robot.TurnOff=Turn off

View File

@ -24,7 +24,7 @@ object Manual extends ManualAPI {
class History(val path: String, var offset: Int = 0) class History(val path: String, var offset: Int = 0)
class Tab(val renderer: TabIconRenderer, val path: String) class Tab(val renderer: TabIconRenderer, val tooltip: Option[String], val path: String)
val tabs = mutable.Buffer.empty[Tab] val tabs = mutable.Buffer.empty[Tab]
@ -36,8 +36,8 @@ object Manual extends ManualAPI {
reset() reset()
override def addTab(renderer: TabIconRenderer, path: String): Unit = { override def addTab(renderer: TabIconRenderer, tooltip: String, path: String): Unit = {
tabs += new Tab(renderer, path) tabs += new Tab(renderer, Option(tooltip), path)
} }
override def addProvider(provider: PathProvider): Unit = { override def addProvider(provider: PathProvider): Unit = {

View File

@ -5,8 +5,8 @@ import java.util
import li.cil.oc.Localization import li.cil.oc.Localization
import li.cil.oc.api import li.cil.oc.api
import li.cil.oc.client.Manual
import li.cil.oc.client.Textures import li.cil.oc.client.Textures
import li.cil.oc.client.{Manual => ManualAPI}
import li.cil.oc.util.PseudoMarkdown import li.cil.oc.util.PseudoMarkdown
import net.minecraft.client.Minecraft import net.minecraft.client.Minecraft
import net.minecraft.client.gui.Gui import net.minecraft.client.gui.Gui
@ -43,7 +43,7 @@ class Manual extends GuiScreen {
private def canScroll = maxOffset > 0 private def canScroll = maxOffset > 0
def offset = Manual.history.top.offset def offset = ManualAPI.history.top.offset
def maxOffset = documentHeight - documentMaxHeight def maxOffset = documentHeight - documentMaxHeight
@ -58,21 +58,21 @@ class Manual extends GuiScreen {
} }
def refreshPage(): Unit = { def refreshPage(): Unit = {
document = PseudoMarkdown.parse(api.Manual.contentFor(Manual.history.top.path)) document = PseudoMarkdown.parse(api.Manual.contentFor(ManualAPI.history.top.path))
documentHeight = PseudoMarkdown.height(document, documentMaxWidth, fontRendererObj) documentHeight = PseudoMarkdown.height(document, documentMaxWidth, fontRendererObj)
scrollTo(offset) scrollTo(offset)
} }
def pushPage(path: String): Unit = { def pushPage(path: String): Unit = {
if (path != Manual.history.top.path) { if (path != ManualAPI.history.top.path) {
Manual.history.push(new Manual.History(path)) ManualAPI.history.push(new ManualAPI.History(path))
refreshPage() refreshPage()
} }
} }
def popPage(): Unit = { def popPage(): Unit = {
if (Manual.history.size > 1) { if (ManualAPI.history.size > 1) {
Manual.history.pop() ManualAPI.history.pop()
refreshPage() refreshPage()
} }
else { else {
@ -83,8 +83,8 @@ class Manual extends GuiScreen {
override def doesGuiPauseGame = false override def doesGuiPauseGame = false
override def actionPerformed(button: GuiButton): Unit = { override def actionPerformed(button: GuiButton): Unit = {
if (button.id >= 0 && button.id < Manual.tabs.length) { if (button.id >= 0 && button.id < ManualAPI.tabs.length) {
api.Manual.navigate(Manual.tabs(button.id).path) api.Manual.navigate(ManualAPI.tabs(button.id).path)
} }
} }
@ -103,7 +103,7 @@ class Manual extends GuiScreen {
scrollButton = new ImageButton(-1, guiLeft + scrollPosX, guiTop + scrollPosY, 6, 13, Textures.guiButtonScroll) scrollButton = new ImageButton(-1, guiLeft + scrollPosX, guiTop + scrollPosY, 6, 13, Textures.guiButtonScroll)
add(buttonList, scrollButton) add(buttonList, scrollButton)
for ((tab, i) <- Manual.tabs.zipWithIndex if i < 7) { for ((tab, i) <- ManualAPI.tabs.zipWithIndex if i < 7) {
val x = guiLeft + tabPosX val x = guiLeft + tabPosX
val y = guiTop + tabPosY + i * (tabHeight - 1) val y = guiTop + tabPosY + i * (tabHeight - 1)
add(buttonList, new ImageButton(i, x, y, tabWidth, tabHeight, Textures.guiManualTab)) add(buttonList, new ImageButton(i, x, y, tabWidth, tabHeight, Textures.guiManualTab))
@ -121,7 +121,7 @@ class Manual extends GuiScreen {
super.drawScreen(mouseX, mouseY, dt) super.drawScreen(mouseX, mouseY, dt)
for ((tab, i) <- Manual.tabs.zipWithIndex if i < 7) { for ((tab, i) <- ManualAPI.tabs.zipWithIndex if i < 7) {
val x = guiLeft + tabPosX val x = guiLeft + tabPosX
val y = guiTop + tabPosY + i * (tabHeight - 1) val y = guiTop + tabPosY + i * (tabHeight - 1)
GL11.glPushMatrix() GL11.glPushMatrix()
@ -133,12 +133,20 @@ class Manual extends GuiScreen {
PseudoMarkdown.render(document, guiLeft + 8, guiTop + 8, documentMaxWidth, documentMaxHeight, offset, fontRendererObj, mouseX, mouseY) match { PseudoMarkdown.render(document, guiLeft + 8, guiTop + 8, documentMaxWidth, documentMaxHeight, offset, fontRendererObj, mouseX, mouseY) match {
case Some(segment) => case Some(segment) =>
segment.tooltip match { segment.tooltip match {
case Some(text) if text.nonEmpty => drawHoveringText(seqAsJavaList(text.lines.toSeq), mouseX, mouseY, fontRendererObj) case Some(text) if text.nonEmpty => drawHoveringText(seqAsJavaList(Localization.localizeImmediately(text).lines.toSeq), mouseX, mouseY, fontRendererObj)
case _ => case _ =>
} }
hoveredLink = segment.link hoveredLink = segment.link
case _ => hoveredLink = None case _ => hoveredLink = None
} }
for ((tab, i) <- ManualAPI.tabs.zipWithIndex if i < 7) {
val x = guiLeft + tabPosX
val y = guiTop + tabPosY + i * (tabHeight - 1)
if (mouseX > x && mouseX < x + tabWidth && mouseY > y && mouseY < y + tabHeight) tab.tooltip.foreach(text => {
drawHoveringText(seqAsJavaList(Localization.localizeImmediately(text).lines.toSeq), mouseX, mouseY, fontRendererObj)
})
}
} }
override protected def mouseMovedOrUp(mouseX: Int, mouseY: Int, button: Int) { override protected def mouseMovedOrUp(mouseX: Int, mouseY: Int, button: Int) {
@ -159,7 +167,7 @@ class Manual extends GuiScreen {
// Left click, did we hit a link? // Left click, did we hit a link?
hoveredLink.foreach(link => { hoveredLink.foreach(link => {
if (link.startsWith("http://") || link.startsWith("https://")) handleUrl(link) if (link.startsWith("http://") || link.startsWith("https://")) handleUrl(link)
else pushPage(Manual.makeRelative(link, Manual.history.top.path)) else pushPage(ManualAPI.makeRelative(link, ManualAPI.history.top.path))
}) })
} }
else if (button == 1) { else if (button == 1) {
@ -204,7 +212,7 @@ class Manual extends GuiScreen {
private def scrollDown() = scrollTo(offset + PseudoMarkdown.lineHeight(fontRendererObj) * 3) private def scrollDown() = scrollTo(offset + PseudoMarkdown.lineHeight(fontRendererObj) * 3)
private def scrollTo(row: Int): Unit = { private def scrollTo(row: Int): Unit = {
Manual.history.top.offset = math.max(0, math.min(maxOffset, row)) ManualAPI.history.top.offset = math.max(0, math.min(maxOffset, row))
val yMin = guiTop + scrollPosY val yMin = guiTop + scrollPosY
if (maxOffset > 0) { if (maxOffset > 0) {
scrollButton.yPosition = yMin + (scrollHeight - 13) * offset / maxOffset scrollButton.yPosition = yMin + (scrollHeight - 13) * offset / maxOffset

View File

@ -200,8 +200,8 @@ object ModOpenComputers extends ModProxy {
api.Manual.addProvider(DefinitionPathProvider) api.Manual.addProvider(DefinitionPathProvider)
api.Manual.addProvider(new ResourceContentProvider(Settings.resourceDomain)) api.Manual.addProvider(new ResourceContentProvider(Settings.resourceDomain))
api.Manual.addTab(new ItemStackTabIconRenderer(api.Items.get("case1").createItemStack(1)), "doc/%LANGUAGE%/block/index.md") api.Manual.addTab(new ItemStackTabIconRenderer(api.Items.get("case1").createItemStack(1)), "oc:gui.Manual.Blocks", "doc/%LANGUAGE%/block/index.md")
api.Manual.addTab(new ItemStackTabIconRenderer(api.Items.get("chip1").createItemStack(1)), "doc/%LANGUAGE%/item/index.md") api.Manual.addTab(new ItemStackTabIconRenderer(api.Items.get("chip1").createItemStack(1)), "oc:gui.Manual.Items", "doc/%LANGUAGE%/item/index.md")
} }
private def blacklistHost(host: Class[_], itemNames: String*) { private def blacklistHost(host: Class[_], itemNames: String*) {
@ -231,8 +231,8 @@ object ModOpenComputers extends ModProxy {
private def checkBlacklisted(info: ItemInfo): String = private def checkBlacklisted(info: ItemInfo): String =
if (info == null || Blacklist.contains(info.name)) null if (info == null || Blacklist.contains(info.name)) null
else if (info.block != null) "block/" + info.name + ".md" else if (info.block != null) "doc/%LANGUAGE%/block/" + info.name + ".md"
else "item/" + info.name + ".md" else "doc/%LANGUAGE%/item/" + info.name + ".md"
} }
} }