Skip to content

Commit

Permalink
Add new version promotion
Browse files Browse the repository at this point in the history
  • Loading branch information
italankin committed Dec 17, 2023
1 parent 3cb5d73 commit da262ff
Show file tree
Hide file tree
Showing 11 changed files with 155 additions and 39 deletions.
2 changes: 2 additions & 0 deletions app/src/main/java/com/italankin/fifteen/Colors.java
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,8 @@ public class Colors {
CYAN_F3
};
public static final int ERROR = 0xffd24242;
public static final int NEW_APP = 0xff00639b;
public static final int NEW_APP_TEXT = 0xffffffff;

public static int getBackgroundColor() {
return background[Settings.getColorMode()];
Expand Down
1 change: 1 addition & 0 deletions app/src/main/java/com/italankin/fifteen/Defaults.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,5 @@ class Defaults {
static final boolean STATS = false;
static final boolean RANDOM_MISSING_TILE = false;
static final boolean NEW_GAME_DELAY = true;
static final boolean SHOW_NEW_APP_BANNER = true;
}
26 changes: 17 additions & 9 deletions app/src/main/java/com/italankin/fifteen/GameSurface.java
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
package com.italankin.fifteen;

import android.content.Context;
import android.content.Intent;
import android.content.res.Resources;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.RectF;
import android.net.Uri;
import android.view.MotionEvent;
import android.view.View;
import com.italankin.fifteen.export.ExportCallback;
Expand All @@ -31,6 +29,7 @@ public class GameSurface extends View implements TopPanelView.Callback {

private final Resources mResources;

private NewAppBannerView mNewAppBanner;
private TopPanelView mTopPanel;
private InfoPanelView mInfoPanel;
private FieldView mField;
Expand Down Expand Up @@ -82,6 +81,12 @@ protected void onLayout(boolean changed, int left, int top, int right, int botto
}

private void init() {
mNewAppBanner = new NewAppBannerView(getContext());
if (Settings.showNewAppBanner) {
Settings.showNewAppBanner = false;
Settings.save();
mNewAppBanner.show();
}
mTopPanel = new TopPanelView();
mTopPanel.addButton(BTN_NEW, mResources.getString(R.string.action_new));
mTopPanel.addButton(BTN_SETTINGS, mResources.getString(R.string.action_settings));
Expand All @@ -96,13 +101,7 @@ private void init() {
GameState.get().help = true;
RectF window = new RectF(0, 0, Dimensions.surfaceWidth, Dimensions.surfaceHeight);
mHelpOverlay = new HelpOverlay(getResources(), tileAppearAnimator, window, mRectField);
mHelpOverlay.addCallback(() -> {
Resources res = getResources();
Intent intent = new Intent(Intent.ACTION_VIEW)
.setData(Uri.parse(res.getString(R.string.help_how_to_play_url)));
Intent chooser = Intent.createChooser(intent, res.getString(R.string.help_how_to_play));
getContext().startActivity(chooser);
});
mHelpOverlay.addCallback(() -> Tools.openUrl(getContext(), R.string.help_how_to_play_url));
mHelpOverlay.show();
});

Expand Down Expand Up @@ -157,6 +156,9 @@ public void onImportClicked() {
@Override
protected void onDraw(Canvas canvas) {
long current = System.currentTimeMillis();
if (lastOnDrawTimestamp == 0) {
lastOnDrawTimestamp = current - 1;
}
draw(canvas, current - lastOnDrawTimestamp);
lastOnDrawTimestamp = current;
if (Settings.postInvalidateDelay > 0) {
Expand Down Expand Up @@ -249,6 +251,9 @@ public boolean onTouchEvent(MotionEvent event) {
} else if (state.isSolved() && mRectField.contains(x, y)) {
createNewGame(true);
return true;
} else if (mNewAppBanner.isShown()) {
mNewAppBanner.onClick(x, y);
return true;
} else if (mTopPanel.onClick(x, y)) {
return true;
} else if (Settings.hardmode && mHardModeView.onClick(x, y)) {
Expand Down Expand Up @@ -362,6 +367,9 @@ private void draw(Canvas canvas, long elapsed) {
canvas.drawColor(Colors.getBackgroundColor());

mTopPanel.draw(canvas, elapsed);
if (mNewAppBanner.isShown()) {
mNewAppBanner.draw(canvas, elapsed);
}
mInfoPanel.draw(canvas, elapsed);
boolean helpShown = mHelpOverlay != null && mHelpOverlay.isShown();
if (!helpShown) {
Expand Down
4 changes: 4 additions & 0 deletions app/src/main/java/com/italankin/fifteen/Settings.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ public class Settings {
private static final String KEY_TIME_FORMAT = "time_format";
private static final String KEY_STATS = "stats";
private static final String KEY_MISSING_RANDOM_TILE = "missing_random_tile";
private static final String KEY_SHOW_NEW_APP_BANNER = "show_new_app_banner";

static final String KEY_SAVED_GAME_ARRAY = "puzzle_prev";
static final String KEY_SAVED_GAME_MOVES = "puzzle_prev_moves";
Expand All @@ -49,6 +50,7 @@ public class Settings {
public static int ingameInfoTps = Defaults.INGAME_INFO_TPS;
public static int timeFormat = Defaults.TIME_FORMAT;
public static boolean stats = Defaults.STATS;
public static boolean showNewAppBanner = Defaults.SHOW_NEW_APP_BANNER;

/**
* Used for UI tests to limit event loop queue
Expand Down Expand Up @@ -85,6 +87,7 @@ static void load(Context context) {
timeFormat = prefs.getInt(KEY_TIME_FORMAT, Defaults.TIME_FORMAT);
stats = prefs.getBoolean(KEY_STATS, Defaults.STATS);
randomMissingTile = prefs.getBoolean(KEY_MISSING_RANDOM_TILE, Defaults.RANDOM_MISSING_TILE);
showNewAppBanner = prefs.getBoolean(KEY_SHOW_NEW_APP_BANNER, Defaults.SHOW_NEW_APP_BANNER);

if (prefs.contains("ingame_info")) {
// old logic for backward compatibility
Expand Down Expand Up @@ -146,6 +149,7 @@ static void save(boolean sync) {
editor.putInt(KEY_TIME_FORMAT, timeFormat);
editor.putBoolean(KEY_STATS, stats);
editor.putBoolean(KEY_MISSING_RANDOM_TILE, randomMissingTile);
editor.putBoolean(KEY_SHOW_NEW_APP_BANNER, showNewAppBanner);
SaveGameManager.saveGame(editor);
if (sync) {
editor.commit();
Expand Down
10 changes: 10 additions & 0 deletions app/src/main/java/com/italankin/fifteen/Tools.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
package com.italankin.fifteen;

import android.content.Context;
import android.content.Intent;
import android.graphics.Color;
import android.net.Uri;

import java.util.Locale;

Expand Down Expand Up @@ -45,4 +48,11 @@ public static String formatFloat(float f) {
public static int manhattan(int x1, int y1, int x2, int y2) {
return Math.abs(x1 - x2) + Math.abs(y1 - y2);
}

public static void openUrl(Context context, int urlResource) {
Intent intent = new Intent(Intent.ACTION_VIEW)
.setData(Uri.parse(context.getResources().getString(urlResource)));
Intent chooser = Intent.createChooser(intent, null);
context.startActivity(chooser);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
package com.italankin.fifteen.views;

import android.animation.TimeInterpolator;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.RectF;
import android.view.animation.DecelerateInterpolator;
import com.italankin.fifteen.*;

public class NewAppBannerView extends BaseView {

public static final long DELAY_TIME = 500;
public static final long APPEAR_TIME = 400;
public static final long DISAPPEAR_TIME = 400;
public static final long ACTIVE_TIME = 8000;

private final Context context;
private final Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
private final RectF bannerRect = new RectF();
private final RectF clipRect = new RectF();
private final float buttonTextYOffset;
private final String bannerText;
private final TimeInterpolator timeInterpolator = new DecelerateInterpolator(2f);
private long time;

public NewAppBannerView(Context context) {
this.context = context;
paint.setTextSize(Dimensions.interfaceFontSize);
paint.setTextAlign(Paint.Align.CENTER);
paint.setTypeface(Settings.typeface);
Rect r = new Rect();
paint.getTextBounds("A", 0, 1, r);
buttonTextYOffset = r.centerY();
bannerText = context.getString(R.string.new_app_banner_text);
bannerRect.set(0, 0, Dimensions.surfaceWidth, Dimensions.topBarHeight);
clipRect.set(bannerRect);
}

@Override
public boolean show() {
time = 0;
return super.show();
}

@Override
public void draw(Canvas canvas, long elapsedTime) {
time += elapsedTime;
if (time <= DELAY_TIME) {
return;
}
long realTime = time - DELAY_TIME;
int saveCount = canvas.save();
if (realTime < APPEAR_TIME) {
float p = Math.min(1f, (realTime / (float) APPEAR_TIME));
float w = bannerRect.width() / 2f * timeInterpolator.getInterpolation(p);
clipRect.left = bannerRect.centerX() - w;
clipRect.right = bannerRect.centerX() + w;
canvas.clipRect(clipRect);
} else if (realTime >= APPEAR_TIME + ACTIVE_TIME + DISAPPEAR_TIME) {
hide();
return;
} else if (realTime >= APPEAR_TIME + ACTIVE_TIME) {
float p = Math.max(0f, 1f - ((realTime - APPEAR_TIME - ACTIVE_TIME) / (float) APPEAR_TIME));
float w = bannerRect.width() / 2f * timeInterpolator.getInterpolation(p);
clipRect.left = bannerRect.centerX() - w;
clipRect.right = bannerRect.centerX() + w;
canvas.clipRect(clipRect);
}
paint.setColor(Colors.NEW_APP);
canvas.drawRect(bannerRect, paint);
paint.setColor(Colors.NEW_APP_TEXT);
canvas.drawText(bannerText, bannerRect.centerX(), bannerRect.centerY() - buttonTextYOffset, paint);
canvas.restoreToCount(saveCount);
}

public void onClick(float x, float y) {
if (bannerRect.contains(x, y)) {
Tools.openUrl(context, R.string.fifteen_app_url);
hide();
}
}

@Override
public void update() {
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,7 @@ public boolean hide() {
}

private void initPages(Resources res) {
pages.put(PAGE_BASIC, new BasicPage(mPaintText, mPaintValue, res));
pages.put(PAGE_BASIC, new BasicPage(context, mPaintText, mPaintValue));
pages.put(PAGE_ADVANCED, new AdvancedPage(this, mPaintText, mPaintValue, res));
pages.put(PAGE_INGAME_INFO, new IngameInfoPage(mPaintText, mPaintValue, res));
pages.put(PAGE_ABOUT, new AboutPage(context, mPaintText, mPaintValue));
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
package com.italankin.fifteen.views.settings;

import android.content.Context;
import android.content.Intent;
import android.content.res.Resources;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.RectF;
import android.net.Uri;
import com.italankin.fifteen.Dimensions;
import com.italankin.fifteen.R;
import com.italankin.fifteen.Tools;
import com.italankin.fifteen.views.SettingsView;

public class AboutPage implements SettingsPage {
Expand All @@ -20,14 +19,11 @@ public class AboutPage implements SettingsPage {

private final String mTextSourceCode;
private final String mTextSourceCodeValue;
private final String mTextNewApp;
private final String mTextNewAppValue;
private final String mTextWebsite;
private final String mTextWebsiteValue;

private RectF mRectWebsite;
private RectF mRectSourceCode;
private RectF mRectNewApp;

public AboutPage(Context context, Paint paintText, Paint paintValue) {
this.context = context;
Expand All @@ -38,8 +34,6 @@ public AboutPage(Context context, Paint paintText, Paint paintValue) {
Resources res = context.getResources();
mTextSourceCode = res.getString(R.string.pref_source_code);
mTextSourceCodeValue = res.getString(R.string.pref_source_code_value);
mTextNewApp = res.getString(R.string.pref_new_app);
mTextNewAppValue = res.getString(R.string.pref_new_app_value);
mTextWebsite = res.getString(R.string.pref_website);
mTextWebsiteValue = res.getString(R.string.pref_website_value);
}
Expand All @@ -53,8 +47,6 @@ public void init(int lineSpacing, int topMargin, int padding, int textHeight) {
mRectSourceCode = new RectF(0, topMargin, Dimensions.surfaceWidth, topMargin + textHeight);
mRectSourceCode.inset(0, padding);
topMargin += lineSpacing;
mRectNewApp = new RectF(0, topMargin, Dimensions.surfaceWidth, topMargin + textHeight);
mRectNewApp.inset(0, padding);
}

@Override
Expand All @@ -63,28 +55,17 @@ public void draw(Canvas canvas, float valueRight, float textLeft, float textYOff
canvas.drawText(mTextWebsiteValue, valueRight, mRectWebsite.bottom - textYOffset, mPaintValue);
canvas.drawText(mTextSourceCode, textLeft, mRectSourceCode.bottom - textYOffset, mPaintText);
canvas.drawText(mTextSourceCodeValue, valueRight, mRectSourceCode.bottom - textYOffset, mPaintValue);
canvas.drawText(mTextNewApp, textLeft, mRectNewApp.bottom - textYOffset, mPaintText);
canvas.drawText(mTextNewAppValue, valueRight, mRectNewApp.bottom - textYOffset, mPaintValue);
}

@Override
public void onClick(float x, float y, float dx) {
if (mRectWebsite.contains(x, y)) {
openUrl(R.string.website_url);
Tools.openUrl(context, R.string.website_url);
} else if (mRectSourceCode.contains(x, y)) {
openUrl(R.string.source_code_url);
} else if (mRectNewApp.contains(x, y)) {
openUrl(R.string.fifteen_app_url);
Tools.openUrl(context, R.string.source_code_url);
}
}

private void openUrl(int urlResource) {
Intent intent = new Intent(Intent.ACTION_VIEW)
.setData(Uri.parse(context.getResources().getString(urlResource)));
Intent chooser = Intent.createChooser(intent, null);
context.startActivity(chooser);
}

@Override
public void update() {
}
Expand Down
Loading

0 comments on commit da262ff

Please sign in to comment.