Настройка запуска в конфиге init.rpy

This commit is contained in:
Victor 2015-06-17 01:42:54 +03:00
parent a7ba5d6398
commit f0e0ffe518
2 changed files with 280 additions and 11 deletions

41
assets/init.rpy Normal file
View File

@ -0,0 +1,41 @@
# Сценарий для автозапуска
#rp.scenario = "meet_you_there.rpy"
# Путь к ресурсам
# sdcard - предустановленный путь к карте памяти, напр. /mnt/sdcard/
# archive - предустановленный путь к архиву программы (папка assets)
#rp.assets = archive + "everlastingsummer/"
rp.assets = sdcard + "everlastingsummer/"
# Использовать стартовое меню
rp.menu = false
rp.menu_background = "bg/ext_road_night.jpg"
rp.menu_items = 4
rp.menu_item1.text = "Начать"
rp.menu_item1.x = 960
rp.menu_item1.y = 560
rp.menu_item1.font = 25
rp.menu_item1.color = "FFFFFFFF"
rp.menu_item1.action = "meet_you_there.rpy"
rp.menu_item2.text = "Загрузить"
rp.menu_item2.x = 960
rp.menu_item2.y = 720
rp.menu_item2.font = 25
rp.menu_item2.color = white
rp.menu_item2.action = load
rp.menu_item3.text = "Выход"
rp.menu_item3.x = 960
rp.menu_item3.y = 880
rp.menu_item3.font = 25
rp.menu_item3.color = white
rp.menu_item3.action = exit
# используется для вывода текста (action не указан)
rp.menu_item4.text = "v" + version
rp.menu_item4.x = 60
rp.menu_item4.y = 1000
rp.menu_item4.font = 16
rp.menu_item4.color = "7AFFFFFF" # прозрачность 7A

View File

@ -1,26 +1,122 @@
package com.annimon.everlastingsummer; package com.annimon.everlastingsummer;
import java.io.IOException; import java.io.IOException;
import android.app.ListActivity; import java.io.InputStream;
import java.util.List;
import android.app.Activity;
import android.content.DialogInterface;
import android.content.Intent; import android.content.Intent;
import android.content.pm.PackageManager.NameNotFoundException;
import android.graphics.drawable.BitmapDrawable;
import android.os.Bundle; import android.os.Bundle;
import android.util.DisplayMetrics;
import android.util.TypedValue;
import android.view.View; import android.view.View;
import android.widget.ArrayAdapter; import android.widget.*;
import android.widget.ListView;
import android.widget.Toast;
/** /**
* Экран выбора сценариев из папки assets. * Экран выбора сценариев из папки assets.
* @author aNNiMON * @author aNNiMON
*/ */
public final class MainActivity extends ListActivity { @SuppressWarnings("deprecation")
public final class MainActivity extends Activity {
private static final double VIRTUAL_WIDTH = 1920d, VIRTUAL_HEIGHT = 1080d;
private static final String ARCHIVE = "archive://";
private static final String LOAD = "%load%";
private static final String EXIT = "%exit%";
private String[] scripts; private String[] scripts;
private boolean needAlignment;
@Override @Override
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
try {
parseInitConfig();
} catch (IOException ioe) {
if (Logger.DEBUG) Logger.log("MainActivity", ioe);
scriptListMode();
}
}
private void openScenario(String name) {
final Intent intent = new Intent(this, ViewActivity.class);
intent.putExtra(ViewActivity.EXTRA_NAME, name);
startActivity(intent);
}
private void parseInitConfig() throws IOException {
final InputStream is = getAssets().open("init.rpy");
final ConfigParser config = ConfigParser.parse(Lexer.tokenize( IOUtil.readContents(is) ));
config.addValue("sdcard", IOUtil.getSdCardPath());
config.addValue("archive", ARCHIVE);
try {
config.addValue("version", getPackageManager().getPackageInfo(getPackageName(), 0).versionName);
} catch (NameNotFoundException ex) {
if (Logger.DEBUG) Logger.log("version", ex);
}
config.addValue("load", LOAD);
config.addValue("exit", EXIT);
config.addValue("white", "FFFFFFFF");
config.addValue("black", "FF000000");
config.parse();
// Настройка пути к ресурсам
if (config.isValueExists("rp.assets")) {
final String path = config.getValue("rp.assets");
if (path.startsWith(ARCHIVE)) {
// Возможность работы с ресурсами внутри программы
IOUtil.useArchive = true;
IOUtil.ASSETS = path.substring(ARCHIVE.length());
} else {
IOUtil.useArchive = false;
IOUtil.ASSETS = path;
}
}
// Автозапуск скрипта
if (config.isValueExists("rp.scenario")) {
finish();
openScenario(config.getValue("rp.scenario"));
}
// Меню
if (config.getValueAsBoolean("rp.menu")) {
menuMode(config);
} else {
scriptListMode();
}
}
@Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
if (!needAlignment) return;
needAlignment = false;
final RelativeLayout root = (RelativeLayout) findViewById(R.id.root);
if (root == null) return;
final int childCount = root.getChildCount();
for (int i = 0; i < childCount; i++) {
final View v = root.getChildAt(i);
if (v instanceof Button) {
final Button button = (Button) v;
RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) button.getLayoutParams();
params.leftMargin -= button.getWidth() / 2;
params.topMargin -= button.getHeight() / 2;
}
}
}
/*
* Выбор скриптов из списка в папке assets/scripts
*/
private void scriptListMode() {
needAlignment = false;
final ListView list = new ListView(this);
try { try {
scripts = getAssets().list(PathResolver.SCRIPT_ASSETS); scripts = getAssets().list(PathResolver.SCRIPT_ASSETS);
} catch (IOException ioe) { } catch (IOException ioe) {
@ -31,13 +127,145 @@ public final class MainActivity extends ListActivity {
Toast.LENGTH_LONG).show(); Toast.LENGTH_LONG).show();
finish(); finish();
} }
setListAdapter(new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, scripts)); list.setAdapter(new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, scripts));
list.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
openScenario(scripts[position]);
}
});
setContentView(list);
} }
/*
* Парсинг и показ меню с пунктами в конфиге init.rpy
*/
private void menuMode(ConfigParser config) {
needAlignment = true;
// Полноэкранный режим
setTheme(R.style.FullscreenTheme);
// Размеры экрана для правильного позиционирования элементов
final DisplayMetrics displaymetrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
final int width = displaymetrics.widthPixels;
final int height = displaymetrics.heightPixels;
setContentView(R.layout.launcher);
if (config.isValueExists("rp.menu_background")) {
final ImageView background = (ImageView) findViewById(R.id.background);
try {
// IOUtil обращается к ViewActivity при useArchive, что приведёт к NPE
// поэтому загружаем вручную
if (IOUtil.useArchive) {
background.setImageDrawable(new BitmapDrawable( getResources(),
getAssets().open(IOUtil.ASSETS + config.getValue("rp.menu_background"))
));
} else {
background.setImageBitmap(IOUtil.readBitmap(config.getValue("rp.menu_background")));
}
} catch (IOException ioe) {
Logger.log("menu background", ioe);
}
}
final RelativeLayout root = (RelativeLayout) findViewById(R.id.root);
final int items = (int) config.getValueAsDouble("rp.menu_items");
for (int i = 0; i < items; i++) {
parseMenuItem(config, root, width, height, i+1);
}
}
private void parseMenuItem(ConfigParser config, RelativeLayout root, int width, int height, int index) {
final String key = "rp.menu_item" + index + ".";
final Button button = new Button(this);
button.setBackgroundDrawable(null);
// текст
if (config.isValueExists(key + "text")) {
button.setText(config.getValue(key + "text"));
}
// шрифт
if (config.isValueExists(key + "font")) {
button.setTextSize(TypedValue.COMPLEX_UNIT_DIP, (float)config.getValueAsDouble(key + "font"));
}
// цвет текста
if (config.isValueExists(key + "color")) {
button.setTextColor(parseColor(config.getValue(key + "color")));
}
// позиция
final RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.WRAP_CONTENT,
RelativeLayout.LayoutParams.WRAP_CONTENT);
params.addRule(RelativeLayout.ALIGN_PARENT_LEFT, RelativeLayout.TRUE);
params.addRule(RelativeLayout.ALIGN_PARENT_TOP, RelativeLayout.TRUE);
if (config.isValueExists(key + "x")) {
final double x = config.getValueAsDouble(key + "x");
params.leftMargin = (int)(x * width / VIRTUAL_WIDTH);
}
if (config.isValueExists(key + "y")) {
final double y = config.getValueAsDouble(key + "y");
params.topMargin = (int)(y * height / VIRTUAL_HEIGHT);
}
// действие
if (config.isValueExists(key + "action")) {
final String action = config.getValue(key + "action");
if (LOAD.equalsIgnoreCase(action)) {
button.setOnClickListener(loadListener);
} else if (EXIT.equalsIgnoreCase(action)) {
button.setOnClickListener(exitListener);
} else {
button.setOnClickListener(new View.OnClickListener() {
@Override @Override
protected void onListItemClick(ListView l, View v, int index, long id) { public void onClick(View v) {
final Intent intent = new Intent(this, ViewActivity.class); openScenario(action);
intent.putExtra(ViewActivity.EXTRA_NAME, scripts[index]); }
});
}
}
root.addView(button, params);
}
private int parseColor(String value) {
try {
return (int) Long.parseLong(value, 16);
} catch (NumberFormatException nfe) {
return 0xFF000000;
}
}
private void showLoadStateDialog() {
final List<SaveInfo> saves = IOUtil.listSaves(getApplicationContext());
if (saves == null || saves.isEmpty()) {
Toast.makeText(this, R.string.no_saves, Toast.LENGTH_SHORT).show();
return;
}
Dialogs.with(this).showSaves(saves, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
final SaveInfo save = saves.get(which);
// Пересоздаём активити
final Intent intent = new Intent(MainActivity.this, ViewActivity.class);
intent.putExtra(ViewActivity.EXTRA_SAVE, save);
startActivity(intent); startActivity(intent);
} }
});
}
private final View.OnClickListener loadListener = new View.OnClickListener() {
@Override
public void onClick(View v) {
showLoadStateDialog();
}
};
private final View.OnClickListener exitListener = new View.OnClickListener() {
@Override
public void onClick(View v) {
finish();
}
};
} }