diff --git a/src/com/shatteredpixel/shatteredpixeldungeon/ui/Archs.java b/src/com/shatteredpixel/shatteredpixeldungeon/ui/Archs.java index b5653eb27..33fe3df2f 100644 --- a/src/com/shatteredpixel/shatteredpixeldungeon/ui/Archs.java +++ b/src/com/shatteredpixel/shatteredpixeldungeon/ui/Archs.java @@ -40,10 +40,12 @@ public class Archs extends Component { @Override protected void createChildren() { arcsBg = new SkinnedBlock( 1, 1, Assets.ARCS_BG ); + arcsBg.autoAdjust = true; arcsBg.offsetTo( 0, offsB ); add( arcsBg ); arcsFg = new SkinnedBlock( 1, 1, Assets.ARCS_FG ); + arcsFg.autoAdjust = true; arcsFg.offsetTo( 0, offsF ); add( arcsFg ); } diff --git a/src/com/shatteredpixel/shatteredpixeldungeon/ui/BadgesList.java b/src/com/shatteredpixel/shatteredpixeldungeon/ui/BadgesList.java index 8a98561dc..0f1596920 100644 --- a/src/com/shatteredpixel/shatteredpixeldungeon/ui/BadgesList.java +++ b/src/com/shatteredpixel/shatteredpixeldungeon/ui/BadgesList.java @@ -54,7 +54,6 @@ public class BadgesList extends ScrollPane { @Override protected void layout() { - super.layout(); float pos = 0; @@ -65,6 +64,8 @@ public class BadgesList extends ScrollPane { } content.setSize( width, pos ); + + super.layout(); } @Override diff --git a/src/com/shatteredpixel/shatteredpixeldungeon/ui/BuffIndicator.java b/src/com/shatteredpixel/shatteredpixeldungeon/ui/BuffIndicator.java index 8c14b8ba3..d633bc2c3 100644 --- a/src/com/shatteredpixel/shatteredpixeldungeon/ui/BuffIndicator.java +++ b/src/com/shatteredpixel/shatteredpixeldungeon/ui/BuffIndicator.java @@ -77,6 +77,8 @@ public class BuffIndicator extends Component { public static final int LOCKED_FLOOR= 35; public static final int CORRUPT = 36; public static final int BLESS = 37; + public static final int RAGE = 38; + public static final int SACRIFICE = 39; public static final int SIZE = 7; diff --git a/src/com/shatteredpixel/shatteredpixeldungeon/ui/GameLog.java b/src/com/shatteredpixel/shatteredpixeldungeon/ui/GameLog.java index 91c1b940e..d54132959 100644 --- a/src/com/shatteredpixel/shatteredpixeldungeon/ui/GameLog.java +++ b/src/com/shatteredpixel/shatteredpixeldungeon/ui/GameLog.java @@ -20,6 +20,7 @@ */ package com.shatteredpixel.shatteredpixeldungeon.ui; +import java.util.ArrayList; import java.util.regex.Pattern; import com.watabou.noosa.BitmapTextMultiline; @@ -32,20 +33,30 @@ import com.watabou.utils.Signal; public class GameLog extends Component implements Signal.Listener { - private static final int MAX_MESSAGES = 3; - + private static final int MAX_LINES = 3; + private static final Pattern PUNCTUATION = Pattern.compile( ".*[.,;?! ]$" ); - + private BitmapTextMultiline lastEntry; private int lastColor; - + + private static ArrayList entries = new ArrayList(); + public GameLog() { super(); GLog.update.add( this ); - - newLine(); + + recreateLines(); } - + + private void recreateLines() { + for (Entry entry : entries) { + lastEntry = PixelScene.createMultiline( entry.text, 6 ); + lastEntry.hardlight( lastColor = entry.color ); + add( lastEntry ); + } + } + public void newLine() { lastEntry = null; } @@ -70,48 +81,80 @@ public class GameLog extends Component implements Signal.Listener { text = text.substring( GLog.HIGHLIGHT.length() ); color = CharSprite.NEUTRAL; } - + text = Utils.capitalize( text ) + - (PUNCTUATION.matcher( text ).matches() ? "" : "."); - - if (lastEntry != null && color == lastColor) { - + (PUNCTUATION.matcher( text ).matches() ? "" : "."); + + if (lastEntry != null && color == lastColor && lastEntry.nLines < MAX_LINES) { + String lastMessage = lastEntry.text(); lastEntry.text( lastMessage.length() == 0 ? text : lastMessage + " " + text ); lastEntry.measure(); - + + entries.get( entries.size() - 1 ).text = lastEntry.text(); + } else { - + lastEntry = PixelScene.createMultiline( text, 6 ); - lastEntry.maxWidth = (int)width; - lastEntry.measure(); lastEntry.hardlight( color ); lastColor = color; add( lastEntry ); - + + entries.add( new Entry( text, color ) ); + } - - if (length > MAX_MESSAGES) { - remove( members.get( 0 ) ); + + if (length > 0) { + int nLines; + do { + nLines = 0; + for (int i = 0; i < length; i++) { + nLines += ((BitmapTextMultiline) members.get(i)).nLines; + } + + if (nLines > MAX_LINES) { + remove(members.get(0)); + + entries.remove( 0 ); + } + } while (nLines > MAX_LINES); + if (entries.isEmpty()) { + lastEntry = null; + } } - + layout(); } - + @Override protected void layout() { float pos = y; for (int i=length-1; i >= 0; i--) { BitmapTextMultiline entry = (BitmapTextMultiline)members.get( i ); + entry.maxWidth = (int)width; + entry.measure(); entry.x = x; entry.y = pos - entry.height(); pos -= entry.height(); } } - + @Override public void destroy() { GLog.update.remove( this ); super.destroy(); } + + private static class Entry { + public String text; + public int color; + public Entry( String text, int color ) { + this.text = text; + this.color = color; + } + } + + public static void wipe() { + entries.clear(); + } } diff --git a/src/com/shatteredpixel/shatteredpixeldungeon/ui/HighlightedText.java b/src/com/shatteredpixel/shatteredpixeldungeon/ui/HighlightedText.java new file mode 100644 index 000000000..e40494888 --- /dev/null +++ b/src/com/shatteredpixel/shatteredpixeldungeon/ui/HighlightedText.java @@ -0,0 +1,80 @@ +/* + * Pixel Dungeon + * Copyright (C) 2012-2015 Oleg Dolya + * + * Shattered Pixel Dungeon + * Copyright (C) 2014-2015 Evan Debenham + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see + */ +package com.shatteredpixel.shatteredpixeldungeon.ui; + +import com.watabou.noosa.BitmapTextMultiline; +import com.watabou.noosa.ui.Component; +import com.shatteredpixel.shatteredpixeldungeon.scenes.PixelScene; +import com.watabou.utils.Highlighter; + +public class HighlightedText extends Component { + + protected BitmapTextMultiline normal; + protected BitmapTextMultiline highlighted; + + protected int nColor = 0xFFFFFF; + protected int hColor = 0xFFFF44; + + public HighlightedText( float size ) { + normal = PixelScene.createMultiline( size ); + add( normal ); + + highlighted = PixelScene.createMultiline( size ); + add( highlighted ); + + setColor( 0xFFFFFF, 0xFFFF44 ); + } + + @Override + protected void layout() { + normal.x = highlighted.x = x; + normal.y = highlighted.y = y; + } + + public void text( String value, int maxWidth ) { + Highlighter hl = new Highlighter( value ); + + normal.text( hl.text ); + normal.maxWidth = maxWidth; + normal.measure(); + + if (hl.isHighlighted()) { + normal.mask = hl.inverted(); + + highlighted.text( hl.text ); + highlighted.maxWidth = maxWidth; + highlighted.measure(); + + highlighted.mask = hl.mask; + highlighted.visible = true; + } else { + highlighted.visible = false; + } + + width = normal.width(); + height = normal.height(); + } + + public void setColor( int n, int h ) { + normal.hardlight( n ); + highlighted.hardlight( h ); + } +} \ No newline at end of file diff --git a/src/com/shatteredpixel/shatteredpixeldungeon/ui/ScrollPane.java b/src/com/shatteredpixel/shatteredpixeldungeon/ui/ScrollPane.java index dcd598a71..73f3687b7 100644 --- a/src/com/shatteredpixel/shatteredpixeldungeon/ui/ScrollPane.java +++ b/src/com/shatteredpixel/shatteredpixeldungeon/ui/ScrollPane.java @@ -22,6 +22,7 @@ package com.shatteredpixel.shatteredpixeldungeon.ui; import com.watabou.input.Touchscreen.Touch; import com.watabou.noosa.Camera; +import com.watabou.noosa.ColorBlock; import com.watabou.noosa.TouchArea; import com.watabou.noosa.ui.Component; import com.shatteredpixel.shatteredpixeldungeon.scenes.PixelScene; @@ -29,84 +30,100 @@ import com.watabou.utils.Point; import com.watabou.utils.PointF; public class ScrollPane extends Component { - + + protected static final int THUMB_COLOR = 0xFF7b8073; + protected static final float THUMB_ALPHA = 0.5f; + protected TouchController controller; protected Component content; - + protected ColorBlock thumb; + protected float minX; protected float minY; protected float maxX; protected float maxY; - + public ScrollPane( Component content ) { super(); - + this.content = content; addToBack( content ); - + width = content.width(); height = content.height(); - + content.camera = new Camera( 0, 0, 1, 1, PixelScene.defaultZoom ); Camera.add( content.camera ); } - + @Override public void destroy() { super.destroy(); Camera.remove( content.camera ); } - + public void scrollTo( float x, float y ) { content.camera.scroll.set( x, y ); } - + @Override protected void createChildren() { controller = new TouchController(); add( controller ); + + thumb = new ColorBlock( 1, 1, THUMB_COLOR ); + thumb.am = THUMB_ALPHA; + add( thumb ); } - + @Override protected void layout() { - + content.setPos( 0, 0 ); controller.x = x; controller.y = y; controller.width = width; controller.height = height; - + Point p = camera().cameraToScreen( x, y ); Camera cs = content.camera; cs.x = p.x; cs.y = p.y; cs.resize( (int)width, (int)height ); + + thumb.visible = height < content.height(); + if (thumb.visible) { + thumb.scale.set( 2, height * height / content.height() ); + thumb.x = right() - thumb.width(); + thumb.y = y; + } } - + public Component content() { return content; } - + public void onClick( float x, float y ) { } - + public class TouchController extends TouchArea { - + private float dragThreshold; - + public TouchController() { super( 0, 0, 0, 0 ); dragThreshold = PixelScene.defaultZoom * 8; } - + @Override protected void onClick( Touch touch ) { if (dragging) { - + dragging = false; - + thumb.am = THUMB_ALPHA; + } else { - + PointF p = content.camera.screenToCamera( (int)touch.current.x, (int)touch.current.y ); ScrollPane.this.onClick( p.x, p.y ); @@ -115,13 +132,13 @@ public class ScrollPane extends Component { private boolean dragging = false; private PointF lastPos = new PointF(); - + @Override protected void onDrag( Touch t ) { if (dragging) { - + Camera c = content.camera; - + c.scroll.offset( PointF.diff( lastPos, t.current ).invScale( c.zoom ) ); if (c.scroll.x + width > content.width()) { c.scroll.x = content.width() - width; @@ -135,15 +152,17 @@ public class ScrollPane extends Component { if (c.scroll.y < 0) { c.scroll.y = 0; } - - + + thumb.y = y + height * c.scroll.y / content.height(); + lastPos.set( t.current ); - + } else if (PointF.distance( t.current, t.start ) > dragThreshold) { - + dragging = true; lastPos.set( t.current ); - + thumb.am = 1; + } } } diff --git a/src/com/shatteredpixel/shatteredpixeldungeon/ui/StatusPane.java b/src/com/shatteredpixel/shatteredpixeldungeon/ui/StatusPane.java index caa759037..cd6561d26 100644 --- a/src/com/shatteredpixel/shatteredpixeldungeon/ui/StatusPane.java +++ b/src/com/shatteredpixel/shatteredpixeldungeon/ui/StatusPane.java @@ -27,6 +27,7 @@ import com.watabou.noosa.Image; import com.watabou.noosa.NinePatch; import com.watabou.noosa.TouchArea; import com.watabou.noosa.audio.Sample; +import com.watabou.noosa.particles.BitmaskEmitter; import com.watabou.noosa.particles.Emitter; import com.watabou.noosa.ui.Button; import com.watabou.noosa.ui.Component; @@ -90,8 +91,8 @@ public class StatusPane extends Component { avatar = HeroSprite.avatar( Dungeon.hero.heroClass, lastTier ); add( avatar ); - blood = new Emitter(); - blood.pos( avatar ); + blood = new BitmaskEmitter( avatar ); + blood.pour( BloodParticle.FACTORY, 0.3f ); blood.autoKill = false; blood.on = false; @@ -192,8 +193,8 @@ public class StatusPane extends Component { lastLvl = Dungeon.hero.lvl; level.text( Integer.toString( lastLvl ) ); level.measure(); - level.x = 27.0f - level.width() / 2; - level.y = 27.5f - level.baseLine() / 2; + level.x = 27.5f - level.width() / 2; + level.y = 28.0f - level.baseLine() / 2; } int k = IronKey.curDepthQuantity; diff --git a/src/com/shatteredpixel/shatteredpixeldungeon/ui/Window.java b/src/com/shatteredpixel/shatteredpixeldungeon/ui/Window.java index cc02a825c..b7ea09439 100644 --- a/src/com/shatteredpixel/shatteredpixeldungeon/ui/Window.java +++ b/src/com/shatteredpixel/shatteredpixeldungeon/ui/Window.java @@ -20,9 +20,6 @@ */ package com.shatteredpixel.shatteredpixeldungeon.ui; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - import com.watabou.input.Keys; import com.watabou.input.Keys.Key; import com.watabou.input.Touchscreen.Touch; @@ -158,61 +155,4 @@ public class Window extends Group implements Signal.Listener { public void onMenuPressed() { } - - protected static class Highlighter { - - private static final Pattern HIGHLIGHTER = Pattern.compile( "_(.*?)_" ); - private static final Pattern STRIPPER = Pattern.compile( "[ \n]" ); - - public String text; - - public boolean[] mask; - - public Highlighter( String text ) { - - String stripped = STRIPPER.matcher( text ).replaceAll( "" ); - mask = new boolean[stripped.length()]; - - Matcher m = HIGHLIGHTER.matcher( stripped ); - - int pos = 0; - int lastMatch = 0; - - while (m.find()) { - pos += (m.start() - lastMatch); - int groupLen = m.group( 1 ).length(); - for (int i=pos; i < pos + groupLen; i++) { - mask[i] = true; - } - pos += groupLen; - lastMatch = m.end(); - } - - m.reset( text ); - StringBuffer sb = new StringBuffer(); - while (m.find()) { - m.appendReplacement( sb, m.group( 1 ) ); - } - m.appendTail( sb ); - - this.text = sb.toString(); - } - - public boolean[] inverted() { - boolean[] result = new boolean[mask.length]; - for (int i=0; i < result.length; i++) { - result[i] = !mask[i]; - } - return result; - } - - public boolean isHighlighted() { - for (int i=0; i < mask.length; i++) { - if (mask[i]) { - return true; - } - } - return false; - } - } } diff --git a/src/com/shatteredpixel/shatteredpixeldungeon/windows/WndChooseWay.java b/src/com/shatteredpixel/shatteredpixeldungeon/windows/WndChooseWay.java index bc91cf386..57fab900e 100644 --- a/src/com/shatteredpixel/shatteredpixeldungeon/windows/WndChooseWay.java +++ b/src/com/shatteredpixel/shatteredpixeldungeon/windows/WndChooseWay.java @@ -20,14 +20,14 @@ */ package com.shatteredpixel.shatteredpixeldungeon.windows; -import com.watabou.noosa.BitmapTextMultiline; +import com.shatteredpixel.shatteredpixeldungeon.ui.HighlightedText; import com.shatteredpixel.shatteredpixeldungeon.actors.hero.HeroSubClass; import com.shatteredpixel.shatteredpixeldungeon.items.TomeOfMastery; -import com.shatteredpixel.shatteredpixeldungeon.scenes.PixelScene; import com.shatteredpixel.shatteredpixeldungeon.sprites.ItemSprite; import com.shatteredpixel.shatteredpixeldungeon.ui.RedButton; import com.shatteredpixel.shatteredpixeldungeon.ui.Window; import com.shatteredpixel.shatteredpixeldungeon.utils.Utils; +import com.watabou.utils.Highlighter; public class WndChooseWay extends Window { @@ -41,35 +41,17 @@ public class WndChooseWay extends Window { public WndChooseWay( final TomeOfMastery tome, final HeroSubClass way1, final HeroSubClass way2 ) { super(); - + IconTitle titlebar = new IconTitle(); titlebar.icon( new ItemSprite( tome.image(), null ) ); titlebar.label( tome.name() ); titlebar.setRect( 0, 0, WIDTH, 0 ); add( titlebar ); - - Highlighter hl = new Highlighter( way1.desc() + "\n\n" + way2.desc() + "\n\n" + TXT_MESSAGE ); - - BitmapTextMultiline normal = PixelScene.createMultiline( hl.text, 6 ); - normal.maxWidth = WIDTH; - normal.measure(); - normal.x = titlebar.left(); - normal.y = titlebar.bottom() + GAP; - add( normal ); - - if (hl.isHighlighted()) { - normal.mask = hl.inverted(); - - BitmapTextMultiline highlighted = PixelScene.createMultiline( hl.text, 6 ); - highlighted.maxWidth = normal.maxWidth; - highlighted.measure(); - highlighted.x = normal.x; - highlighted.y = normal.y; - add( highlighted ); - - highlighted.mask = hl.mask; - highlighted.hardlight( TITLE_COLOR ); - } + + HighlightedText hl = new HighlightedText( 6 ); + hl.text( way1.desc() + "\n\n" + way2.desc() + "\n\n" + TXT_MESSAGE, WIDTH ); + hl.setPos( titlebar.left(), titlebar.bottom() + GAP ); + add( hl ); RedButton btnWay1 = new RedButton( Utils.capitalize( way1.title() ) ) { @Override @@ -78,7 +60,7 @@ public class WndChooseWay extends Window { tome.choose( way1 ); } }; - btnWay1.setRect( 0, normal.y + normal.height() + GAP, (WIDTH - GAP) / 2, BTN_HEIGHT ); + btnWay1.setRect( 0, hl.bottom() + GAP, (WIDTH - GAP) / 2, BTN_HEIGHT ); add( btnWay1 ); RedButton btnWay2 = new RedButton( Utils.capitalize( way2.title() ) ) {