From ae0e6ec634d8ab515ae381145a89d9ce649ba082 Mon Sep 17 00:00:00 2001 From: evgenyzinoviev Date: Fri, 14 Aug 2015 17:11:48 +0300 Subject: initial --- src/org/happysanta/gd/Menu/ActionMenuElement.java | 141 ++ src/org/happysanta/gd/Menu/BigTextMenuElement.java | 30 + .../happysanta/gd/Menu/ClickableMenuElement.java | 196 +++ .../gd/Menu/DownloadLevelsMenuScreen.java | 222 +++ .../happysanta/gd/Menu/EmptyLineMenuElement.java | 42 + .../gd/Menu/HighScoreTextMenuElement.java | 100 ++ .../gd/Menu/InstalledLevelsMenuScreen.java | 103 ++ src/org/happysanta/gd/Menu/LevelMenuElement.java | 370 +++++ src/org/happysanta/gd/Menu/LevelsAdapter.java | 53 + .../gd/Menu/LevelsCountTextMenuElement.java | 86 ++ src/org/happysanta/gd/Menu/LevelsMenuScreen.java | 429 ++++++ src/org/happysanta/gd/Menu/Menu.java | 1554 ++++++++++++++++++++ src/org/happysanta/gd/Menu/MenuElement.java | 20 + src/org/happysanta/gd/Menu/MenuElementOld.java | 32 + src/org/happysanta/gd/Menu/MenuHandler.java | 12 + src/org/happysanta/gd/Menu/MenuScreen.java | 277 ++++ .../happysanta/gd/Menu/NameInputMenuScreen.java | 175 +++ .../gd/Menu/OnMenuElementHighlightListener.java | 10 + src/org/happysanta/gd/Menu/OptionsMenuElement.java | 301 ++++ src/org/happysanta/gd/Menu/SimpleMenuElement.java | 176 +++ .../happysanta/gd/Menu/SimpleMenuElementNew.java | 77 + src/org/happysanta/gd/Menu/TextMenuElement.java | 80 + .../gd/Menu/Views/LevelNameLeadingMarginSpan2.java | 38 + .../happysanta/gd/Menu/Views/MenuHelmetView.java | 111 ++ .../happysanta/gd/Menu/Views/MenuImageView.java | 34 + .../happysanta/gd/Menu/Views/MenuLinearLayout.java | 68 + .../gd/Menu/Views/MenuRelativeLayout.java | 55 + src/org/happysanta/gd/Menu/Views/MenuTextView.java | 73 + .../gd/Menu/Views/MenuTitleLinearLayout.java | 39 + src/org/happysanta/gd/Menu/Views/MenuView.java | 12 + .../gd/Menu/Views/ObservableScrollView.java | 31 + 31 files changed, 4947 insertions(+) create mode 100755 src/org/happysanta/gd/Menu/ActionMenuElement.java create mode 100644 src/org/happysanta/gd/Menu/BigTextMenuElement.java create mode 100644 src/org/happysanta/gd/Menu/ClickableMenuElement.java create mode 100755 src/org/happysanta/gd/Menu/DownloadLevelsMenuScreen.java create mode 100755 src/org/happysanta/gd/Menu/EmptyLineMenuElement.java create mode 100755 src/org/happysanta/gd/Menu/HighScoreTextMenuElement.java create mode 100644 src/org/happysanta/gd/Menu/InstalledLevelsMenuScreen.java create mode 100755 src/org/happysanta/gd/Menu/LevelMenuElement.java create mode 100644 src/org/happysanta/gd/Menu/LevelsAdapter.java create mode 100644 src/org/happysanta/gd/Menu/LevelsCountTextMenuElement.java create mode 100644 src/org/happysanta/gd/Menu/LevelsMenuScreen.java create mode 100755 src/org/happysanta/gd/Menu/Menu.java create mode 100644 src/org/happysanta/gd/Menu/MenuElement.java create mode 100755 src/org/happysanta/gd/Menu/MenuElementOld.java create mode 100755 src/org/happysanta/gd/Menu/MenuHandler.java create mode 100755 src/org/happysanta/gd/Menu/MenuScreen.java create mode 100644 src/org/happysanta/gd/Menu/NameInputMenuScreen.java create mode 100644 src/org/happysanta/gd/Menu/OnMenuElementHighlightListener.java create mode 100644 src/org/happysanta/gd/Menu/OptionsMenuElement.java create mode 100755 src/org/happysanta/gd/Menu/SimpleMenuElement.java create mode 100644 src/org/happysanta/gd/Menu/SimpleMenuElementNew.java create mode 100755 src/org/happysanta/gd/Menu/TextMenuElement.java create mode 100644 src/org/happysanta/gd/Menu/Views/LevelNameLeadingMarginSpan2.java create mode 100644 src/org/happysanta/gd/Menu/Views/MenuHelmetView.java create mode 100644 src/org/happysanta/gd/Menu/Views/MenuImageView.java create mode 100644 src/org/happysanta/gd/Menu/Views/MenuLinearLayout.java create mode 100644 src/org/happysanta/gd/Menu/Views/MenuRelativeLayout.java create mode 100644 src/org/happysanta/gd/Menu/Views/MenuTextView.java create mode 100644 src/org/happysanta/gd/Menu/Views/MenuTitleLinearLayout.java create mode 100644 src/org/happysanta/gd/Menu/Views/MenuView.java create mode 100644 src/org/happysanta/gd/Menu/Views/ObservableScrollView.java (limited to 'src/org/happysanta/gd/Menu') diff --git a/src/org/happysanta/gd/Menu/ActionMenuElement.java b/src/org/happysanta/gd/Menu/ActionMenuElement.java new file mode 100755 index 0000000..fb0b706 --- /dev/null +++ b/src/org/happysanta/gd/Menu/ActionMenuElement.java @@ -0,0 +1,141 @@ +package org.happysanta.gd.Menu; + +import android.content.Context; +import android.view.View; +import android.widget.ImageView; +import android.widget.LinearLayout; +import org.happysanta.gd.Menu.Views.MenuImageView; +import org.happysanta.gd.Menu.Views.MenuTextView; +import org.happysanta.gd.R; + +import static org.happysanta.gd.Helpers.getDp; +import static org.happysanta.gd.Helpers.getGDActivity; + +public class ActionMenuElement + extends ClickableMenuElement + implements MenuHandler, MenuElement { + + protected static final int DISABLED_COLOR = 0xff999999; + public static final int LOCK_IMAGE_MARGIN_RIGHT = 5; + public static final int locks[] = new int[]{ + R.drawable.s_lock0, + R.drawable.s_lock1, + R.drawable.s_lock2 + }; + + public static final int LINE_SPACING = 15; + public static final int X_OFFSET = 48; + + public static final int OK = 0; + public static final int BACK = 1; + public static final int EXIT = 2; + public static final int YES = 3; + public static final int NO = 4; + public static final int PLAY_MENU = 5; + public static final int GO_TO_MAIN = 6; + public static final int RESTART = 7; + public static final int NEXT = 8; + public static final int CONTINUE = 9; + public static final int INSTALL = 10; + public static final int LOAD = 11; + public static final int SELECT_FILE = 12; + public static final int DELETE = 13; + public static final int RESTART_WITH_NEW_LEVEL = 14; + public static final int SEND_LOGS = 15; + + protected MenuHandler handler; + protected boolean isLocked = false; + protected boolean isBlackLock = true; + protected MenuImageView lockImage = null; + + protected int actionValue = -1; + + public ActionMenuElement(String s, int value, MenuHandler handler) { + actionValue = value; + this.handler = handler; + + text = s; + + createAllViews(); + } + + @Override + protected void createAllViews() { + super.createAllViews(); + + Context context = getGDActivity(); + lockImage = new MenuImageView(context); + lockImage.setScaleType(ImageView.ScaleType.CENTER); + lockImage.setVisibility(View.GONE); + + LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.MATCH_PARENT); + lp.setMargins(0, 0, getDp(ActionMenuElement.LOCK_IMAGE_MARGIN_RIGHT), 0); + lockImage.setLayoutParams(lp); + + layout.addView(lockImage, 1); + } + + public ActionMenuElement(String s, MenuHandler handler/*, MenuScreen screen*/) { + this(s, -1, handler); + } + + public int getActionValue() { + return actionValue; + } + + public void setHandler(MenuHandler hander) { + this.handler = hander; + } + + public void setLock(boolean flag, boolean flag1) { + isLocked = flag; + isBlackLock = flag1; + + lockImage.setVisibility(isLocked ? View.VISIBLE : View.GONE); + lockImage.setImageResource(locks[isBlackLock ? 0 : 1]); + } + + @Override + public void setText(String s) { + text = s; + updateViewText(); + } + + @Override + public void performAction(int k) { + if (disabled || handler == null) return; + + if (k == MenuScreen.KEY_FIRE) { + handler.handleAction(this); + } + } + + @Override + protected void onHighlightChanged() { + lockImage.setImageResource(locks[isHighlighted ? 2 : (isBlackLock ? 0 : 1)]); + } + + @Override + public MenuScreen getCurrentMenu() { + return null; + } + + @Override + public void setCurrentMenu(MenuScreen e1, boolean flag) { + } + + @Override + public void handleAction(MenuElement item) { + } + + public void setDisabled(boolean disabled) { + this.disabled = disabled; + + if (disabled) { + ((MenuTextView) textView).setTextColor(DISABLED_COLOR); + } else { + ((MenuTextView) textView).setTextColor(defaultColorStateList()); + } + } + +} diff --git a/src/org/happysanta/gd/Menu/BigTextMenuElement.java b/src/org/happysanta/gd/Menu/BigTextMenuElement.java new file mode 100644 index 0000000..8b30e64 --- /dev/null +++ b/src/org/happysanta/gd/Menu/BigTextMenuElement.java @@ -0,0 +1,30 @@ +package org.happysanta.gd.Menu; + +import android.text.Spanned; +import org.happysanta.gd.Global; +import org.happysanta.gd.Menu.Views.MenuTextView; + +public class BigTextMenuElement + extends TextMenuElement { + + public static final int TEXT_SIZE = 19; + + public BigTextMenuElement(String s) { + super(s); + createTextView(); + setTextParams(textView); + } + + public BigTextMenuElement(Spanned s) { + super(s); + createTextView(); + setTextParams(textView); + } + + protected static void setTextParams(MenuTextView textView) { + textView.setTextSize(TEXT_SIZE); + textView.setTypeface(Global.robotoCondensedTypeface); + textView.setLineSpacing(0f, 1.2f); + } + +} diff --git a/src/org/happysanta/gd/Menu/ClickableMenuElement.java b/src/org/happysanta/gd/Menu/ClickableMenuElement.java new file mode 100644 index 0000000..f33db34 --- /dev/null +++ b/src/org/happysanta/gd/Menu/ClickableMenuElement.java @@ -0,0 +1,196 @@ +package org.happysanta.gd.Menu; + +import android.content.Context; +import android.content.res.ColorStateList; +import android.graphics.Rect; +import android.view.MotionEvent; +import android.view.View; +import android.view.ViewGroup; +import android.widget.LinearLayout; +import org.happysanta.gd.Global; +import org.happysanta.gd.Menu.Views.MenuHelmetView; +import org.happysanta.gd.Menu.Views.MenuTextView; +import org.happysanta.gd.R; + +import static org.happysanta.gd.Helpers.getDp; +import static org.happysanta.gd.Helpers.getGDActivity; +import static org.happysanta.gd.Helpers.logDebug; + +public class ClickableMenuElement + implements MenuElement { + + public static final int TEXT_SIZE = 20; + public static final int PADDING_TOP = 5; + protected View textView; + protected String text; + protected View.OnTouchListener onTouchListener; + protected LinearLayout layout; + protected MenuHelmetView helmet; + protected OnMenuElementHighlightListener onMenuElementHighlightListener = null; + protected boolean isHighlighted = false; + protected Thread originalThread = null; + protected boolean disabled = false; + + public ClickableMenuElement() { + } + + public ClickableMenuElement(String text) { + this.text = text; + originalThread = Thread.currentThread(); + + createAllViews(); + } + + protected boolean inViewBounds(View view, int x, int y) { + Rect rect = new Rect(); + int location[] = new int[2]; + + view.getDrawingRect(rect); + view.getLocationOnScreen(location); + rect.offset(location[0], location[1]); + + return rect.contains(x, y); + } + + protected void createAllViews() { + final ClickableMenuElement self = this; + Context context = getGDActivity(); + + layout = new LinearLayout(context); + layout.setOrientation(LinearLayout.HORIZONTAL); + layout.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT)); + + helmet = new MenuHelmetView(context); + helmet.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.MATCH_PARENT)); + + /*if (!isSDK11OrHigher()) { + helmet.setMeasuredHeight(true); + }*/ + + onTouchListener = new View.OnTouchListener() { + @Override + public boolean onTouch(View view, MotionEvent motionEvent) { + if (disabled) return false; + + switch (motionEvent.getAction()) { + case MotionEvent.ACTION_DOWN: + view.setSelected(true); + helmet.setShow(true); + + if (onMenuElementHighlightListener != null) + onMenuElementHighlightListener.onElementHighlight(self); + + setHighlighted(true); + break; + + case MotionEvent.ACTION_CANCEL: + case MotionEvent.ACTION_UP: + view.setSelected(false); + + if (motionEvent.getAction() == MotionEvent.ACTION_UP && inViewBounds(view, (int) motionEvent.getRawX(), (int) motionEvent.getRawY())) { + performAction(MenuScreen.KEY_FIRE); + } + + setHighlighted(false); + break; + + case MotionEvent.ACTION_MOVE: + if (!inViewBounds(view, (int) motionEvent.getRawX(), (int) motionEvent.getRawY())) { + view.setSelected(false); + setHighlighted(false); + } else { + view.setSelected(true); + setHighlighted(true); + } + break; + } + return true; + } + }; + + textView = createMainView(); + + layout.addView(helmet); + layout.addView(textView); + layout.setOnTouchListener(onTouchListener); + } + + protected View createMainView() { + Context context = getGDActivity(); + MenuTextView mtv = new MenuTextView(context); + mtv.setText(getTextForView()); + mtv.setTextColor(defaultColorStateList()); + mtv.setTypeface(Global.robotoCondensedTypeface); + mtv.setTextSize(TEXT_SIZE); + mtv.setLayoutParams(new ViewGroup.LayoutParams( + ViewGroup.LayoutParams.MATCH_PARENT, + ViewGroup.LayoutParams.WRAP_CONTENT + )); + mtv.setPadding(0, getDp(PADDING_TOP), 0, getDp(PADDING_TOP)); + + return mtv; + } + + protected ColorStateList defaultColorStateList() { + return getGDActivity().getResources().getColorStateList(R.drawable.menu_item_color); + } + + @Override + public boolean isSelectable() { + return true; + } + + @Override + public View getView() { + return layout; + } + + protected MenuTextView getMenuTextView() { + return (MenuTextView) textView; + } + + @Override + public void setText(String text) { + this.text = text; + updateViewText(); + } + + public String getText() { + return text; + } + + protected void updateViewText() { + if (textView != null && textView instanceof MenuTextView) + ((MenuTextView) textView).setTextOnUiThread(getTextForView()); + } + + protected String getTextForView() { + return text; + } + + @Override + public void performAction(int k) { + + } + + public void setOnHighlightListener(OnMenuElementHighlightListener listener) { + onMenuElementHighlightListener = listener; + } + + public void showHelmet() { + helmet.setShow(true); + } + + private void setHighlighted(boolean highlighted) { + isHighlighted = highlighted; + onHighlightChanged(); + } + + protected void onHighlightChanged() { + } + + public boolean isDisabled() { + return disabled; + } + +} diff --git a/src/org/happysanta/gd/Menu/DownloadLevelsMenuScreen.java b/src/org/happysanta/gd/Menu/DownloadLevelsMenuScreen.java new file mode 100755 index 0000000..fe072ce --- /dev/null +++ b/src/org/happysanta/gd/Menu/DownloadLevelsMenuScreen.java @@ -0,0 +1,222 @@ +package org.happysanta.gd.Menu; + +import android.app.AlertDialog; +import android.content.Context; +import android.content.DialogInterface; +import android.view.View; +import android.widget.RelativeLayout; +import android.widget.Toast; +import org.happysanta.gd.API.*; +import org.happysanta.gd.GDActivity; +import org.happysanta.gd.Menu.Views.MenuImageView; +import org.happysanta.gd.R; +import org.happysanta.gd.API.Response; +import org.happysanta.gd.Settings; +import org.happysanta.gd.WaitForNetworkConnection; + +import static org.happysanta.gd.Helpers.*; +import static org.happysanta.gd.Helpers.getDp; + +public class DownloadLevelsMenuScreen extends LevelsMenuScreen { + + protected final static int API_LIMIT = 100; + public static API.LevelsSortType sort; + + protected MenuImageView sortImage; + // protected API api; + protected Request request; + protected int offset = 0; + protected boolean isLoading = false; + protected boolean fullLoaded = false; + protected WaitForNetworkConnection waitForNetworkConnection = null; + protected Toast toast; + + public DownloadLevelsMenuScreen(String title, MenuScreen navTarget) { + super(title, navTarget); + + // api = new API(); + // api.setSort(sort); + + Context context = getGDActivity(); + + // Sort icon + sortImage = new MenuImageView(context); + sortImage.setImageResource(R.drawable.ic_sort); + sortImage.setAdjustViewBounds(true); + sortImage.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + showSortDialog(); + } + }); + sortImage.setVisibility(View.GONE); + sortImage.setPadding(getDp(10), 0, 0, 0); + + RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams( + RelativeLayout.LayoutParams.WRAP_CONTENT, + getDp(40) + ); + params.addRule(RelativeLayout.ALIGN_PARENT_RIGHT); + + sortImage.setLayoutParams(params); + } + + @Override + protected void loadLevels() { + try { + if (!checkNetwork()) + return; + + showLoading(); + isLoading = true; + request = API.getLevels(offset, API_LIMIT, sort, new ResponseHandler() { + @Override + public void onResponse(final Response response) { + final LevelsResponse levelsResponse = new LevelsResponse(response); + if (status != Statuses.NORMAL) { + clearList(); + setStatus(Statuses.NORMAL); + } + + hideLoading(); + + addElements = new AsyncAddElements() { + @Override + protected void onPostExecute(Void v) { + logDebug("offset = " + offset + ", totalCount = " + levelsResponse.getTotalCount()); + fullLoaded = offset >= levelsResponse.getTotalCount(); + if (!fullLoaded) + showLoading(); + + isLoading = false; + } + }; + addElements.execute(levelsResponse.getLevels()); + } + + @Override + public void onError(APIException error) { + showError(error.getMessage()); + isLoading = false; + } + }); + + offset += API_LIMIT; + } catch (Exception e) { + e.printStackTrace(); + showError(getString(R.string.download_error)); + + isLoading = false; + } + } + + @Override + public void reloadLevels() { + if (request != null) request.cancel(); + offset = 0; + isLoading = false; + fullLoaded = false; + + super.reloadLevels(); + } + + protected void showSortDialog() { + final CharSequence[] items = getStringArray(R.array.sort_variants); + + AlertDialog dialog = new AlertDialog.Builder(getGDActivity()) + .setTitle(getString(R.string.sort_by)) + .setSingleChoiceItems(items, API.getIdBySortType(sort), new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int item) { + API.LevelsSortType newSort = API.getSortTypeById(item); + + if (newSort != sort) { + sort = newSort; + // api.setSort(newSort); + Settings.setLevelsSort(sort); + reloadLevels(); + } + + dialog.dismiss(); + } + }) + .create(); + + dialog.show(); + } + + protected boolean checkNetwork() { + if (!isOnline()) { + if (elements.isEmpty()) { + showError(getString(R.string.waiting_for_network)); + + if (waitForNetworkConnection != null) + waitForNetworkConnection.cancel(true); + + waitForNetworkConnection = new WaitForNetworkConnection(); + waitForNetworkConnection.execute(null, new Runnable() { + @Override + public void run() { + reloadLevels(); + } + }); + } else { + if (toast != null) { + toast.cancel(); + } + + toast = Toast.makeText(getGDActivity().getApplicationContext(), getString(R.string.no_internet_connection), Toast.LENGTH_SHORT); + toast.show(); + } + + return false; + } + + return true; + } + + @Override + public void onHide(MenuScreen newMenu) { + logDebug("onHide"); + super.onHide(newMenu); + + GDActivity activity = getGDActivity(); + + if (newMenu != getGameMenu().levelScreen) { + offset = 0; + isLoading = false; + fullLoaded = false; + + if (request != null) request.cancel(); + // api.cancelRequest(); + if (waitForNetworkConnection != null) + waitForNetworkConnection.cancel(true); + } + + activity.titleLayout.removeView(sortImage); + sortImage.setVisibility(View.GONE); + } + + @Override + public void onShow() { + super.onShow(); + + GDActivity activity = getGDActivity(); + + activity.titleLayout.addView(sortImage); + sortImage.setVisibility(View.VISIBLE); + } + + @Override + public void onScroll(double percent) { + if (percent >= 97 && !isLoading && !fullLoaded) { + loadLevels(); + } + } + + @Override + public void deleteElement(LevelMenuElement el) { + super.deleteElement(el); + offset--; + } + +} diff --git a/src/org/happysanta/gd/Menu/EmptyLineMenuElement.java b/src/org/happysanta/gd/Menu/EmptyLineMenuElement.java new file mode 100755 index 0000000..e0901f9 --- /dev/null +++ b/src/org/happysanta/gd/Menu/EmptyLineMenuElement.java @@ -0,0 +1,42 @@ +package org.happysanta.gd.Menu; + +import android.view.View; +import android.view.ViewGroup; +import org.happysanta.gd.Menu.Views.MenuTextView; + +import static org.happysanta.gd.Helpers.getDp; +import static org.happysanta.gd.Helpers.getGDActivity; + +public class EmptyLineMenuElement implements MenuElement { + + protected String text; + protected int offset; + protected MenuTextView view; + + EmptyLineMenuElement(int offset) { + this.offset = offset; + + view = new MenuTextView(getGDActivity()); + view.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, getDp(offset))); + } + + @Override + public View getView() { + return view; + } + + @Override + public boolean isSelectable() { + return false; + } + + @Override + public void setText(String s) { + text = s; + } + + @Override + public void performAction(int k) { + } + +} diff --git a/src/org/happysanta/gd/Menu/HighScoreTextMenuElement.java b/src/org/happysanta/gd/Menu/HighScoreTextMenuElement.java new file mode 100755 index 0000000..fc392df --- /dev/null +++ b/src/org/happysanta/gd/Menu/HighScoreTextMenuElement.java @@ -0,0 +1,100 @@ +package org.happysanta.gd.Menu; + +import android.content.Context; +import android.graphics.Typeface; +import android.text.Spanned; +import android.view.View; +import android.widget.ImageView; +import android.widget.LinearLayout; +import org.happysanta.gd.Global; +import org.happysanta.gd.Menu.Views.MenuImageView; +import org.happysanta.gd.Menu.Views.MenuLinearLayout; +import org.happysanta.gd.R; + +import static org.happysanta.gd.Helpers.*; + +public class HighScoreTextMenuElement + extends TextMenuElement + implements MenuElement { + + protected static final int TEXT_LEFT_MARGIN = 5; + protected static final int SUBTITLE_MARGIN_BOTTOM = 8; + protected static final int SUBTITLE_TEXT_SIZE = 20; + protected static final int LAYOUT_PADDING = 3; + protected static int medals[] = new int[]{ + R.drawable.s_medal_gold, + R.drawable.s_medal_silver, + R.drawable.s_medal_bronze + }; + protected static Typeface defaultTypeface = null; + + protected boolean showMedal = false; + protected MenuLinearLayout layout; + protected MenuImageView image; + + public HighScoreTextMenuElement(String s) { + super(s); + createAllViews(); + } + + public HighScoreTextMenuElement(Spanned text) { + super(text); + createAllViews(); + } + + protected void createAllViews() { + Context context = getGDActivity(); + + layout = new MenuLinearLayout(context); + layout.setOrientation(LinearLayout.HORIZONTAL); + layout.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT)); + + image = new MenuImageView(context); + image.setScaleType(ImageView.ScaleType.CENTER); + image.setVisibility(View.GONE); + + // textView was already created in super constructor + textView.setLineSpacing(0, 1); + + if (defaultTypeface == null) { + defaultTypeface = textView.getTypeface(); + } + + LinearLayout.LayoutParams textViewLayoutParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT); + // textViewLayoutParams.setMargins(getDp(TEXT_LEFT_MARGIN), 0, 0, 0); + textView.setLayoutParams(textViewLayoutParams); + + layout.addView(image, new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.MATCH_PARENT)); + layout.addView(textView); + } + + @Override + public View getView() { + return layout; + } + + public void setMedal(boolean showMedal, int medalIndex) { + image.setVisibility(showMedal ? View.VISIBLE : View.GONE); + image.setImageResource(medals[medalIndex]); + + LinearLayout.LayoutParams textViewLayoutParams = (LinearLayout.LayoutParams) textView.getLayoutParams(); + textViewLayoutParams.setMargins(showMedal ? getDp(TEXT_LEFT_MARGIN) : 0, 0, 0, 0); + textView.setLayoutParams(textViewLayoutParams); + + this.showMedal = showMedal; + } + + public void setIsSubtitle(boolean is) { + textView.setTextSize(is ? SUBTITLE_TEXT_SIZE : TEXT_SIZE); + textView.setTypeface(is ? Global.robotoCondensedTypeface : defaultTypeface); + + LinearLayout.LayoutParams textViewLayoutParams = (LinearLayout.LayoutParams) textView.getLayoutParams(); + textViewLayoutParams.setMargins(!is && showMedal ? getDp(TEXT_LEFT_MARGIN) : 0, 0, 0, is ? getDp(SUBTITLE_MARGIN_BOTTOM) : 0); + textView.setLayoutParams(textViewLayoutParams); + } + + public void setLayoutPadding(boolean use) { + layout.setPadding(0, use ? getDp(LAYOUT_PADDING) : 0, 0, use ? getDp(LAYOUT_PADDING) : 0); + } + +} diff --git a/src/org/happysanta/gd/Menu/InstalledLevelsMenuScreen.java b/src/org/happysanta/gd/Menu/InstalledLevelsMenuScreen.java new file mode 100644 index 0000000..b3adbab --- /dev/null +++ b/src/org/happysanta/gd/Menu/InstalledLevelsMenuScreen.java @@ -0,0 +1,103 @@ +package org.happysanta.gd.Menu; + +import android.os.AsyncTask; +import android.view.ViewTreeObserver; +import org.happysanta.gd.Storage.Level; +import org.happysanta.gd.Storage.LevelsManager; + +import static org.happysanta.gd.Helpers.getGDActivity; + +public class InstalledLevelsMenuScreen extends LevelsMenuScreen { + + LevelsManager levelsManager; + protected boolean isLoading = false; + AsyncLoadLevels asyncLoadLevels = null; + + public InstalledLevelsMenuScreen(String title, MenuScreen navTarget) { + super(title, navTarget); + levelsManager = getGDActivity().levelsManager; + } + + @Override + public void loadLevels() { + showLoading(); + isLoading = true; + + asyncLoadLevels = new AsyncLoadLevels() { + @Override + public void onPostExecute(Level[] levels) { + if (status != Statuses.NORMAL) { + clearList(); + setStatus(Statuses.NORMAL); + } + hideLoading(); + + addElements = new AsyncAddElements() { + @Override + protected void onPostExecute(Void v) { + isLoading = false; + if (selectedIndex != -1) { + // listLayout.requestLayout(); + // listLayout.invalidate(); + + // View someView = findViewById(R.id.someView); + final ViewTreeObserver obs = listLayout.getViewTreeObserver(); + obs.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() { + + public boolean onPreDraw() { + scrollToItem(selectedIndex); + try { + obs.removeOnPreDrawListener(this); + } catch (IllegalStateException e) { + } + + return true; + } + }); + + // scrollToItem(selectedIndex); + } + } + }; + addElements.execute(levels); + } + }; + asyncLoadLevels.execute(); + } + + @Override + public void onShow() { + super.onShow(); + } + + @Override + public void onHide(MenuScreen newMenu) { + super.onHide(newMenu); + } + + @Override + protected boolean hideDate() { + return true; + } + + @Override + public void reloadLevels() { + if (asyncLoadLevels != null) { + asyncLoadLevels.cancel(true); + asyncLoadLevels = null; + } + + isLoading = false; + super.reloadLevels(); + } + + private class AsyncLoadLevels extends AsyncTask { + + @Override + protected Level[] doInBackground(Void... params) { + return levelsManager.getAllInstalledLevels(); + } + + } + +} diff --git a/src/org/happysanta/gd/Menu/LevelMenuElement.java b/src/org/happysanta/gd/Menu/LevelMenuElement.java new file mode 100755 index 0000000..e577e94 --- /dev/null +++ b/src/org/happysanta/gd/Menu/LevelMenuElement.java @@ -0,0 +1,370 @@ +package org.happysanta.gd.Menu; + +import android.content.Context; +import android.text.Html; +import android.text.SpannableString; +import android.view.View; +import android.view.ViewGroup; +import android.widget.LinearLayout; +import android.widget.RelativeLayout; +import org.happysanta.gd.Callback; +import org.happysanta.gd.GDActivity; +import org.happysanta.gd.Global; +import org.happysanta.gd.Menu.Views.LevelNameLeadingMarginSpan2; +import org.happysanta.gd.Menu.Views.MenuImageView; +import org.happysanta.gd.Menu.Views.MenuLinearLayout; +import org.happysanta.gd.Menu.Views.MenuRelativeLayout; +import org.happysanta.gd.Menu.Views.MenuTextView; +import org.happysanta.gd.R; +import org.happysanta.gd.Storage.Level; +import org.happysanta.gd.Storage.LevelsManager; + +import static org.happysanta.gd.Helpers.getDp; +import static org.happysanta.gd.Helpers.getGDActivity; +import static org.happysanta.gd.Helpers.getGameMenu; +import static org.happysanta.gd.Helpers.getLevelsManager; +import static org.happysanta.gd.Helpers.getString; +import static org.happysanta.gd.Helpers.logDebug; +import static org.happysanta.gd.Helpers.showConfirm; + +public class LevelMenuElement + extends ClickableMenuElement + implements MenuHandler { + + protected static final int PADDING_TOP = 7; + protected static final int PADDING_BOTTOM = 7; + protected static final int LEVEL_TEXT_SIZE = 16; + protected static final int NAME_SIZE = 20; + + protected static final int INSTALLED_MARGIN = 15; + protected static final int ACTIVE_MARGIN = 21; + + protected Level level; + + protected MenuTextView textView; + protected MenuLinearLayout mainLayout; + protected MenuRelativeLayout nameLayout; + protected MenuTextView tracksCountTextView; + protected MenuScreen screen; + protected MenuImageView installedIcon = null; + protected MenuImageView activeIcon = null; + protected boolean installed = false; + protected boolean active = false; + protected boolean showDate = true; + + public LevelMenuElement() { + } + + public LevelMenuElement(Level level, MenuScreen screen) { + this.level = level; + this.screen = screen; + + createAllViews(); + } + + @Override + protected View createMainView() { + Context context = getGDActivity(); + + mainLayout = new MenuLinearLayout(context); + mainLayout.setOrientation(LinearLayout.VERTICAL); + mainLayout.setPadding(0, getDp(PADDING_TOP), 0, getDp(PADDING_BOTTOM)); + + nameLayout = new MenuRelativeLayout(context); + // nameLayout.setOrientation(LinearLayout.HORIZONTAL); + + // Text + textView = new MenuTextView(context); + // textView.setText(level.getName()); + updateNameLine(); + textView.setTextColor(context.getResources().getColorStateList(R.drawable.menu_item_color)); + textView.setTypeface(Global.robotoCondensedTypeface); + textView.setTextSize(NAME_SIZE); + textView.setLineSpacing(0f, 1.1f); + textView.setLayoutParams(new ViewGroup.LayoutParams( + ViewGroup.LayoutParams.MATCH_PARENT, + ViewGroup.LayoutParams.WRAP_CONTENT + )); + textView.setPadding(0, getDp(PADDING_TOP), 0, 0); + + tracksCountTextView = new MenuTextView(context); + tracksCountTextView.setTextSize(LEVEL_TEXT_SIZE); + tracksCountTextView.setTypeface(Global.robotoCondensedTypeface); + updateLevelsLine(); + + nameLayout.addView(textView); + mainLayout.addView(nameLayout); + mainLayout.addView(tracksCountTextView); + + return mainLayout; + } + + public void updateNameLine() { + String name = level.getName() + (Global.DEBUG ? " (id" + level.getAnyId() + ")" : ""); + // if (!active) { + int margin = 0; + if (installed) + margin = INSTALLED_MARGIN; + else if (active) + margin = ACTIVE_MARGIN; + + SpannableString ss = new SpannableString(name); + ss.setSpan(new LevelNameLeadingMarginSpan2(1, installed || active ? getDp(margin) : 0), 0, ss.length(), 0); + textView.setTextOnUiThread(ss); + /*} else { + textView.setTextOnUiThread(Html.fromHtml(String.format(getString(R.string.active_name_tpl), name))); + }*/ + } + + public void updateLevelsLine() { + if (showDate) { + tracksCountTextView.setText(Html.fromHtml(String.format(getString(R.string.levels_count_tpl), + level.getCountEasy() + " - " + level.getCountMedium() + " - " + level.getCountHard(), level.getShortAddedDate()))); + } else { + tracksCountTextView.setText(level.getCountEasy() + " - " + level.getCountMedium() + " - " + level.getCountHard()); + } + } + + @Override + protected void onHighlightChanged() { + if (installed && installedIcon != null) { + installedIcon.setImageResource(isHighlighted ? R.drawable.ic_downloaded_selected : R.drawable.ic_downloaded); + } + if (active && activeIcon != null) { + activeIcon.setImageResource(isHighlighted ? R.drawable.ic_installed_selected : R.drawable.ic_installed); + } + } + + @Override + protected void createAllViews() { + super.createAllViews(); + + helmet.setMeasuredHeight(true); + + LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams( + LinearLayout.LayoutParams.WRAP_CONTENT, + LinearLayout.LayoutParams.WRAP_CONTENT + ); + lp.setMargins(0, getDp(PADDING_TOP * 2 + 5), 0, 0); + + helmet.setLayoutParams(lp); + } + + public void setInstalled(boolean installed) { + this.installed = installed; + if (installed) { + if (installedIcon == null) { + RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams( + RelativeLayout.LayoutParams.WRAP_CONTENT, + RelativeLayout.LayoutParams.WRAP_CONTENT + ); + // params.setMargins(0, getDp(PADDING_TOP * 2 + 2), getDp(7), 0); + params.setMargins(0, getDp(PADDING_TOP * 2 + 2), 0, 0); + + installedIcon = new MenuImageView(getGDActivity()); + installedIcon.setLayoutParams(params); + installedIcon.setImageResource(R.drawable.ic_downloaded); + } + + if (installedIcon.getParent() != nameLayout) { + nameLayout.addView(installedIcon); + } + } else if (!installed && installedIcon != null && installedIcon.getParent() == nameLayout) { + nameLayout.removeView(installedIcon); + } + + updateNameLine(); + } + + public void setActive(boolean active) { + this.active = active; + if (active) { + if (activeIcon == null) { + RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams( + RelativeLayout.LayoutParams.WRAP_CONTENT, + RelativeLayout.LayoutParams.WRAP_CONTENT + ); + // params.setMargins(0, getDp(PADDING_TOP * 2 + 2), getDp(7), 0); + params.setMargins(0, getDp(PADDING_TOP * 2 + 2), 0, 0); + + activeIcon = new MenuImageView(getGDActivity()); + activeIcon.setLayoutParams(params); + activeIcon.setImageResource(R.drawable.ic_installed); + } + + if (activeIcon.getParent() != nameLayout) { + nameLayout.addView(activeIcon); + } + } else if (!active && activeIcon != null && activeIcon.getParent() == nameLayout) { + nameLayout.removeView(activeIcon); + } + + updateNameLine(); + } + + public void setShowDate(boolean showDate) { + this.showDate = showDate; + updateLevelsLine(); + } + + @Override + public void performAction(int k) { + if (k == MenuScreen.KEY_FIRE) { + buildScreen(); + } + } + + protected void buildScreen() { + Menu menu = getGameMenu(); + MenuScreen screen = menu.levelScreen; + LevelsManager levelsManager = getLevelsManager(); + + screen.clear(); + // System.gc(); + + logDebug(level); + + screen.setNavTarget(this.screen); + screen.setTitle(level.getName()); + + if (!level.getAuthor().equals("")) + screen.addItem(new BigTextMenuElement(Html.fromHtml(String.format(getString(R.string.author_tpl), level.getAuthor())))); + if (level.getInstalledTs() > 0) + screen.addItem(new BigTextMenuElement(Html.fromHtml(String.format(getString(R.string.installed_tpl), level.getFullInstalledDate())))); + else if (level.getAddedTs() > 0) + screen.addItem(new BigTextMenuElement(Html.fromHtml(String.format(getString(R.string.added_tpl), level.getFullAddedDate())))); + screen.addItem(new BigTextMenuElement(Html.fromHtml(String.format(getString(R.string.tracks_tpl), level.getCountEasy() + " / " + level.getCountMedium() + " / " + level.getCountHard())))); + screen.addItem(menu.createEmptyLine(true)); + + if (!level.isInstalled()) { + ActionMenuElement installAction = menu.createAction(ActionMenuElement.INSTALL); + installAction.setText(String.format( + getString(R.string.install_kb), level.getSizeKb() + )); + installAction.setHandler(this); + + screen.addItem(installAction); + } else { + if (!level.isDefault()) { + ActionMenuElement installed = new ActionMenuElement(getString(R.string.installed), null); + installed.setDisabled(true); + screen.addItem(installed); + } + + if (level.getId() == levelsManager.getCurrentId()) { + ActionMenuElement active = new ActionMenuElement(getString(R.string.active), null); + active.setDisabled(true); + screen.addItem(active); + } else { + ActionMenuElement loadAction = menu.createAction(ActionMenuElement.LOAD); + loadAction.setHandler(this); + screen.addItem(loadAction); + } + + if (!level.isDefault() && levelsManager.getCurrentId() != level.getId()) { + ActionMenuElement deleteAction = menu.createAction(ActionMenuElement.DELETE); + deleteAction.setHandler(this); + + screen.addItem(deleteAction); + } + } + + screen.addItem(menu.createAction(ActionMenuElement.BACK)); + + if (menu.getCurrentMenu() != screen) { + menu.setCurrentMenu(screen, false); + } else { + screen.highlightElement(); + } + } + + @Override + public MenuScreen getCurrentMenu() { + return null; + } + + @Override + public void setCurrentMenu(MenuScreen e1, boolean flag) { + } + + @Override + public void handleAction(MenuElement item) { + if (item instanceof ActionMenuElement) { + final GDActivity gd = getGDActivity(); + final Menu menu = getGameMenu(); + + switch (((ActionMenuElement) item).getActionValue()) { + case ActionMenuElement.DELETE: + if (!level.isInstalled()) + break; + + showConfirm( + getString(R.string.delete_levels), + getString(R.string.delete_levels_confirmation), + new Runnable() { + @Override + public void run() { + gd.levelsManager.deleteAsync(level, new Runnable() { + @Override + public void run() { + long id = level.getId(); + + MenuScreen target = menu.getCurrentMenu().getNavTarget(); + if (target instanceof InstalledLevelsMenuScreen) { + InstalledLevelsMenuScreen installedScreen = (InstalledLevelsMenuScreen) target; + LevelMenuElement el = installedScreen.getElementByLevelId(id, 0); + if (el != null) + installedScreen.deleteElement(el); + level.setId(0); + menu.back(); + } else if (target instanceof DownloadLevelsMenuScreen) { + DownloadLevelsMenuScreen downloadScreen = (DownloadLevelsMenuScreen) target; + LevelMenuElement el = downloadScreen.getElementByLevelId(id, 0); + if (el != null) + el.setInstalled(false); + + level.setId(0); + buildScreen(); + } + } + }); + } + }, + null + ); + break; + + case ActionMenuElement.INSTALL: + gd.levelsManager.downloadLevel(level, new Callback() { + @Override + public void onDone(Object... objects) { + long id = (long) objects[0]; + level.setId(id); + + MenuScreen target = menu.getCurrentMenu().getNavTarget(); + if (target instanceof DownloadLevelsMenuScreen) { + DownloadLevelsMenuScreen downloadScreen = (DownloadLevelsMenuScreen) target; + LevelMenuElement el = downloadScreen.getElementByLevelId(id, 0); + if (el != null) + el.setInstalled(true); + } + + buildScreen(); + } + }); + break; + + case ActionMenuElement.LOAD: + gd.levelsManager.load(level); + // buildScreen(); + break; + } + } + } + + @Override + public String toString() { + return level.toString(); + } + +} \ No newline at end of file diff --git a/src/org/happysanta/gd/Menu/LevelsAdapter.java b/src/org/happysanta/gd/Menu/LevelsAdapter.java new file mode 100644 index 0000000..9f7ddc9 --- /dev/null +++ b/src/org/happysanta/gd/Menu/LevelsAdapter.java @@ -0,0 +1,53 @@ +package org.happysanta.gd.Menu; + +import android.content.Context; +import android.text.Html; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ArrayAdapter; +import android.widget.TextView; +import org.happysanta.gd.Global; +import org.happysanta.gd.R; +import org.happysanta.gd.Storage.Level; + +import java.util.ArrayList; + +import static org.happysanta.gd.Helpers.getString; + +public class LevelsAdapter extends ArrayAdapter { + + private ArrayList levels; + + public LevelsAdapter(Context context, ArrayList levels) { + super(context, R.layout.levels_list_item, levels); + this.levels = levels; + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + View v = convertView; + if (v == null) { + LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE); + v = inflater.inflate(R.layout.levels_list_item, null); + } + + Level level = levels.get(position); + if (level != null) { + TextView name = (TextView) v.findViewById(R.id.level_name); + TextView count = (TextView) v.findViewById(R.id.level_count); + + name.setTypeface(Global.robotoCondensedTypeface); + count.setTypeface(Global.robotoCondensedTypeface); + + name.setText(level.getName()); + count.setText(Html.fromHtml(String.format(getString(R.string.levels_count_tpl), + level.getCountEasy() + " - " + level.getCountMedium() + " - " + level.getCountHard(), level.getShortAddedDate()))); + } + + return v; + } + +} + + diff --git a/src/org/happysanta/gd/Menu/LevelsCountTextMenuElement.java b/src/org/happysanta/gd/Menu/LevelsCountTextMenuElement.java new file mode 100644 index 0000000..7ead337 --- /dev/null +++ b/src/org/happysanta/gd/Menu/LevelsCountTextMenuElement.java @@ -0,0 +1,86 @@ +package org.happysanta.gd.Menu; + +import android.content.Context; +import android.view.View; +import android.widget.LinearLayout; +import org.happysanta.gd.Menu.Views.MenuImageView; +import org.happysanta.gd.Menu.Views.MenuLinearLayout; +import org.happysanta.gd.Menu.Views.MenuTextView; +import org.happysanta.gd.R; + +import static org.happysanta.gd.Helpers.getDp; +import static org.happysanta.gd.Helpers.getGDActivity; + +public class LevelsCountTextMenuElement + extends BigTextMenuElement { + + protected static final int PADDING_LEFT = 4; + protected static final int PADDING_RIGHT = 8; + protected static final int MARGIN_RIGHT = 3; + + protected int tracks[]; + + protected MenuLinearLayout layout; + protected MenuImageView tracksImages[]; + protected MenuTextView tracksTexts[]; + + public LevelsCountTextMenuElement(String s, int easy, int medium, int hard) { + super(s); + + tracks = new int[3]; + tracks[0] = easy; + tracks[1] = medium; + tracks[2] = hard; + + createViews(); + } + + protected void createViews() { + Context context = getGDActivity(); + + layout = new MenuLinearLayout(context); + layout.setOrientation(LinearLayout.HORIZONTAL); + layout.setLayoutParams(new LinearLayout.LayoutParams( + LinearLayout.LayoutParams.MATCH_PARENT, + LinearLayout.LayoutParams.WRAP_CONTENT + )); + + tracksImages = new MenuImageView[3]; + for (int i = 0; i < 3; i++) { + tracksImages[i] = new MenuImageView(context); + tracksImages[i].setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.MATCH_PARENT)); + } + + tracksImages[0].setImageResource(R.drawable.levels_wheel0); + tracksImages[1].setImageResource(R.drawable.levels_wheel1); + tracksImages[2].setImageResource(R.drawable.levels_wheel2); + + // Tracks texts + tracksTexts = new MenuTextView[3]; + for (int i = 0; i < 3; i++) { + tracksTexts[i] = new MenuTextView(context); + setTextParams(tracksTexts[i]); + + tracksTexts[i].setText(String.valueOf(tracks[i])); + tracksTexts[i].setPadding(getDp(PADDING_LEFT), 0, getDp(PADDING_RIGHT), 0); + } + + LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT); + params.setMargins(0, 0, getDp(MARGIN_RIGHT), 0); + + textView.setLayoutParams(params); + + layout.addView(textView); + + // Add tracks to layout + for (int i = 0; i < 3; i++) { + layout.addView(tracksImages[i]); + layout.addView(tracksTexts[i]); + } + } + + @Override + public View getView() { + return layout; + } +} diff --git a/src/org/happysanta/gd/Menu/LevelsMenuScreen.java b/src/org/happysanta/gd/Menu/LevelsMenuScreen.java new file mode 100644 index 0000000..22b7539 --- /dev/null +++ b/src/org/happysanta/gd/Menu/LevelsMenuScreen.java @@ -0,0 +1,429 @@ +package org.happysanta.gd.Menu; + +import android.content.Context; +import android.os.AsyncTask; +import android.view.Gravity; +import android.view.View; +import android.widget.FrameLayout; +import android.widget.LinearLayout; +import android.widget.ProgressBar; +import android.widget.TextView; +import org.happysanta.gd.GDActivity; +import org.happysanta.gd.Menu.Views.MenuLinearLayout; +import org.happysanta.gd.R; +import org.happysanta.gd.Storage.Level; +import org.happysanta.gd.Storage.LevelsManager; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Vector; + +import static org.happysanta.gd.Helpers.getGDActivity; +import static org.happysanta.gd.Helpers.getGDView; +import static org.happysanta.gd.Helpers.getGameMenu; +import static org.happysanta.gd.Helpers.getLevelsManager; +import static org.happysanta.gd.Helpers.getString; +import static org.happysanta.gd.Helpers.logDebug; + +public class LevelsMenuScreen extends MenuScreen { + + enum Statuses {NORMAL, DOWNLOADING, ERROR} + + protected final static int ERROR_COLOR = 0xff777777; + + protected Statuses status = Statuses.NORMAL; + protected int savedScrollY = 0; + + protected Vector elements; + protected ArrayList levels; + + protected FrameLayout progressWrap; + protected ProgressBar progressBar; + + protected MenuLinearLayout listLayout; + protected TextMenuElement errorText; + protected AsyncAddElements addElements = null; + protected boolean leftFromScreen = false; + + public LevelsMenuScreen(String title, MenuScreen navTarget) { + super(title, navTarget); + + elements = new Vector(); + levels = new ArrayList<>(); + + Context context = getGDActivity(); + + // Create progress + progressWrap = new FrameLayout(context); + progressWrap.setLayoutParams(new LinearLayout.LayoutParams( + FrameLayout.LayoutParams.MATCH_PARENT, + FrameLayout.LayoutParams.MATCH_PARENT + )); + + progressBar = new ProgressBar(context); + progressBar.setIndeterminate(true); + + // Create error + errorText = new TextMenuElement(getString(R.string.download_error)); + TextView errorTextView = (TextView) errorText.getView(); + + errorTextView.setTextColor(ERROR_COLOR); + errorTextView.setLayoutParams(new LinearLayout.LayoutParams( + LinearLayout.LayoutParams.MATCH_PARENT, + LinearLayout.LayoutParams.MATCH_PARENT + )); + errorTextView.setGravity(Gravity.CENTER); + + listLayout = new MenuLinearLayout(context); + listLayout.setOrientation(LinearLayout.VERTICAL); + listLayout.setLayoutParams(new LinearLayout.LayoutParams( + LinearLayout.LayoutParams.MATCH_PARENT, + LinearLayout.LayoutParams.MATCH_PARENT + )); + + layout.addView(listLayout); + + // List view + // listView = new ListView(context); + /*listView.setLayoutParams(new LinearLayout.LayoutParams( + LinearLayout.LayoutParams.WRAP_CONTENT, + LinearLayout.LayoutParams.WRAP_CONTENT + ));*/ + + // adapter = new LevelsAdapter(context, levels); + // listView.setAdapter(adapter); + + // layout.addView(listView); + } + + public int addListItem(MenuElement item) { + elements.addElement(item); + listLayout.addView(item.getView()); + + if (item instanceof ClickableMenuElement) + ((ClickableMenuElement) item).setOnHighlightListener(this); + + return elements.size() - 1; + } + + public void setStatus(Statuses status) { + this.status = status; + + getGDView().invalidate(); + } + + protected void clearList() { + elements.removeAllElements(); + levels.clear(); + listLayout.removeAllViews(); + lastHighlighted = null; + // System.gc(); + } + + protected void showError(String error) { + clearList(); + errorText.setText(error); + addListItem(errorText); + + setStatus(Statuses.ERROR); + } + + protected void showLoading() { + // clearList(); + + if (elements.isEmpty()) { + if (progressBar.getParent() == listLayout) { + listLayout.removeView(progressBar); + } else if (progressBar.getParent() != progressWrap) { + progressWrap.addView(progressBar, new FrameLayout.LayoutParams( + FrameLayout.LayoutParams.WRAP_CONTENT, + FrameLayout.LayoutParams.WRAP_CONTENT, + Gravity.CENTER_HORIZONTAL | Gravity.CENTER_VERTICAL + )); + } + + listLayout.addView(progressWrap); + } else { + if (progressBar.getParent() == progressWrap) { + progressWrap.removeView(progressBar); + } else if (progressBar.getParent() != listLayout) { + listLayout.addView(progressBar, new LinearLayout.LayoutParams( + LinearLayout.LayoutParams.MATCH_PARENT, + LinearLayout.LayoutParams.WRAP_CONTENT, + Gravity.CENTER_HORIZONTAL + )); + } + } + + // setStatus(Statuses.DOWNLOADING); + } + + protected void hideLoading() { + if (progressBar.getParent() == listLayout) { + listLayout.removeView(progressBar); + } else if (progressBar.getParent() == progressWrap) { + // progressWrap.setVisibility(GameView.GONE); + listLayout.removeView(progressWrap); + } + } + + public void highlightFirstElement() { + for (int i = 0; i < elements.size(); i++) { + if (elements.elementAt(i) instanceof LevelMenuElement) { + highlightElementAt(i); + break; + } + } + } + + public void highlightElementAt(int index) { + LevelMenuElement item = null; + try { + item = (LevelMenuElement) elements.elementAt(index); + } catch (Exception e) { + e.printStackTrace(); + return; + } + + item.showHelmet(); + lastHighlighted = item; + selectedIndex = index; + } + + protected void load() { + clearList(); + loadLevels(); + } + + protected void loadLevels() { + + } + + @Override + public void onShow() { + super.onShow(); + GDActivity activity = getGDActivity(); + + if (leftFromScreen) { + clearList(); + leftFromScreen = false; + } + + switch (status) { + case DOWNLOADING: + break; + + case NORMAL: + if (elements.isEmpty()) { + load(); + } + break; + } + + if (lastHighlighted != null) { + lastHighlighted.showHelmet(); + } + + if (savedScrollY != 0) { + activity.scrollView.scrollTo(0, savedScrollY); + } + } + + @Override + public void onHide(MenuScreen newMenu) { + GDActivity activity = getGDActivity(); + + if (newMenu != getGameMenu().levelScreen) { + if (addElements != null) { + addElements.cancel(true); + addElements = null; + } + + savedScrollY = 0; + status = Statuses.NORMAL; + + hideLoading(); + clearList(); + + leftFromScreen = true; + } else { + savedScrollY = activity.scrollView.getScrollY(); + } + } + + protected boolean hideDate() { + return false; + } + + protected LevelsMenuScreen getThis() { + return this; + } + + public void reloadLevels() { + if (addElements != null) { + addElements.cancel(true); + addElements = null; + } + + clearList(); + loadLevels(); + } + + public LevelMenuElement getElementByLevelId(long id, long apiId) { + for (Object _el : elements) { + LevelMenuElement el = (LevelMenuElement) _el; + + if ((id > 0 && el.level.getId() == id) || apiId > 0 && el.level.getApiId() == apiId) + return el; + } + + return null; + } + + public void deleteElement(LevelMenuElement el) { + View view = el.getView(); + listLayout.removeView(view); + + int index = elements.indexOf(el); + + elements.remove(el); + levels.remove(el.level); + + if (el == lastHighlighted) { + index--; + if (index < 0) + index = 0; + + highlightElementAt(index); + } + } + + @Override + public void performAction(int k) { + logDebug("LevelsMenuScreen.performAction: k = " + k); + int from = 0; + switch (k) { + default: + if (selectedIndex != -1) { + for (int i = selectedIndex; i < elements.size(); i++) { + MenuElement item; + if ((item = (MenuElement) elements.elementAt(i)) != null && item.isSelectable()) { + item.performAction(k); + return; + } + } + } + break; + + case KEY_UP: + if (selectedIndex > 0) { + from = selectedIndex - 1; + } else { + from = elements.size() - 1; + } + + for (int i = from; i >= 0; i--) { + MenuElement el = (MenuElement) elements.elementAt(i); + if (!(el instanceof LevelMenuElement)) { + continue; + } + + highlightElementAt(i); + scrollToItem(el); + break; + } + break; + + case KEY_DOWN: + if (selectedIndex < elements.size() - 1) { + from = selectedIndex + 1; + } else { + from = 0; + } + + for (int i = from; i < elements.size(); i++) { + MenuElement el = (MenuElement) elements.elementAt(i); + if (!(el instanceof LevelMenuElement)) { + continue; + } + + highlightElementAt(i); + scrollToItem(el); + break; + } + break; + } + } + + protected void scrollToItem(int index) { + LevelMenuElement el = (LevelMenuElement) elements.elementAt(index); + // logDebug(el); + scrollToItem(el); + } + + protected class AsyncAddElements extends AsyncTask { + + @Override + protected Void doInBackground(Level[]... params) { + Level[] _levels = params[0]; + boolean checkInstalled = getThis() instanceof DownloadLevelsMenuScreen; + boolean checkActive = getThis() instanceof InstalledLevelsMenuScreen; + + ArrayList ids; + HashMap installed = null; + LevelsManager levelsManager = getLevelsManager(); + + if (checkInstalled) { + ids = new ArrayList<>(); + + for (Level level : _levels) { + ids.add(level.getApiId()); + } + + installed = getGDActivity().levelsManager.findInstalledLevels(ids); + } + + boolean alreadyHl = false; + + for (Level level : _levels) { + if (isCancelled()) { + clearList(); + return null; + } + + LevelMenuElement el = new LevelMenuElement(level, getThis()); + boolean toHl = false; + + if (hideDate()) + el.setShowDate(false); + + if (checkInstalled && installed.containsKey(level.getApiId())) { + level.setId(installed.get(level.getApiId())); + el.setInstalled(true); + } + if (checkActive && level.getId() == levelsManager.getCurrentId()) { + el.setActive(true); + toHl = true; + } + + if (!isCancelled()) { + int index = addListItem(el); + if (toHl && !alreadyHl) { + highlightElementAt(index); + // scrollToItem(index); + alreadyHl = true; + } + + if (lastHighlighted == null) + highlightFirstElement(); + } + } + + levels.addAll(Arrays.asList(_levels)); + return null; + } + + } + +} diff --git a/src/org/happysanta/gd/Menu/Menu.java b/src/org/happysanta/gd/Menu/Menu.java new file mode 100755 index 0000000..7485176 --- /dev/null +++ b/src/org/happysanta/gd/Menu/Menu.java @@ -0,0 +1,1554 @@ +package org.happysanta.gd.Menu; + +import android.app.AlertDialog; +import android.app.ProgressDialog; +import android.content.DialogInterface; +import android.graphics.Canvas; +import android.graphics.Paint; +import android.os.Environment; +import android.text.Html; +import android.text.InputType; +import android.widget.EditText; +import org.happysanta.gd.Command; +import org.happysanta.gd.FileDialog; +import org.happysanta.gd.GDActivity; +import org.happysanta.gd.Game.GameView; +import org.happysanta.gd.Global; +import org.happysanta.gd.Levels.InvalidTrackException; +import org.happysanta.gd.Levels.Loader; +import org.happysanta.gd.R; +import org.happysanta.gd.Settings; +import org.happysanta.gd.Storage.HighScores; +import org.happysanta.gd.Storage.Level; +import org.happysanta.gd.Storage.LevelsManager; +import org.acra.ACRA; + +import java.io.File; +import java.io.UnsupportedEncodingException; + +import static org.happysanta.gd.Helpers.*; +import static org.happysanta.gd.Helpers.logDebug; + +public class Menu + implements MenuHandler { + + // private final static int SETTINGS_LENGTH = 21; + // private final static boolean ENABLE_MANAGER = true; + + public MenuScreen currentMenu; + public Level level; + private HighScores currentScores; + public int selectedLeague = 0; + public boolean m_blZ = false; + public boolean menuDisabled = false; + // byte[] unlockedTracks = new byte[3]; + // byte leaguesUnlockedCount = 0; + // byte levelsUnlockedCount = 0; + int[] selectedTrack = { + 0, 0, 0 + }; + String[][] trackNames; + String[] leagues = new String[3]; + String[] fullLeaguesList = new String[4]; + // private byte[] settings; + // private SaveManager saveManager; + private Command okCommand; + private Command backCommand; + private MenuScreen mainMenu; + private MenuScreen playMenu; + private MenuScreen optionsMenu; + private MenuScreen aboutScreen; + private MenuScreen helpMenu; + private MenuScreen eraseScreen; + private MenuScreen resetScreen; + private MenuScreen finishedMenu; + private MenuScreen ingameScreen; + private SimpleMenuElementNew gameMenuItem; + // private SimpleMenuElementNew optionsMenuItem; + // private SimpleMenuElementNew helpMenuItem; + private OptionsMenuElement levelSelector; + private MenuScreen levelSelectorCurrentMenu; + private OptionsMenuElement trackSelector; + private MenuScreen trackSelectorCurrentMenu; + private OptionsMenuElement leagueSelector; + private MenuScreen leagueSelectorCurrentMenu; + private MenuScreen highScoreMenu; + private SimpleMenuElementNew highscoreItem; + private ActionMenuElement startItem; + private OptionsMenuElement perspectiveOptionItem; + private OptionsMenuElement shadowsOptionItem; + private OptionsMenuElement driverSpriteOptionItem; + private OptionsMenuElement bikeSpriteOptionItem; + private OptionsMenuElement inputOptionItem; + private OptionsMenuElement lookAheadOptionItem; + private OptionsMenuElement keyboardInMenuOptionItem; + private OptionsMenuElement vibrateOnTouchOptionItem; + private SimpleMenuElementNew clearHighscoreOptionItem; + private SimpleMenuElementNew fullResetItem; + // private ActionMenuElement yesAction; + // private ActionMenuElement noAction; + private SimpleMenuElementNew aboutMenuItem; + private MenuScreen objectiveHelpScreen; + private SimpleMenuElementNew objectiveHelpItem; + private MenuScreen keysHelpScreen; + private SimpleMenuElementNew keysHelpItem; + private MenuScreen unlockingHelpScreen; + private SimpleMenuElementNew unlockingHelpItem; + private MenuScreen highscoreHelpScreen; + private SimpleMenuElementNew highscoreHelpItem; + private MenuScreen optionsHelpScreen; + private SimpleMenuElementNew optionsHelpItem; + private NameInputMenuScreen nameScreen; + private ActionMenuElement continueAction; + // private ActionMenuElement goToMainAction; + // private ActionMenuElement exitMenuItem; + private ActionMenuElement ingameRestartAction; + private ActionMenuElement finishedRestartAction; + private ActionMenuElement nextAction; + // private ActionMenuElement okAction; + private ActionMenuElement nameAction; + private long lastTrackTime; + private int m_ajI; + private int m_atI; + private String finishedTime; + private byte[] nameChars; + // private RecordStore recordStore; + // private int m_afI = -1; + private boolean settingsLoadedOK; + private int levelIndex = 0; + private int track = 0; + private boolean leagueCompleted = false; + private boolean m_SZ = false; + private Object m_BObject; + private String[] difficultyLevels = null; /* { + "Easy", "Medium", "Hard" + }; */ + // private long finishTime = 0L; + /*private byte perspectiveOptionEnabled = 0; + private byte shadowsOptionEnabled = 0; + private byte driverSpriteOptionEnabled = 0; + private byte bikerSpriteOptionEnabled = 0; + private byte inputOptionValue = 0; + private byte lookAheadOptionEnabled = 0; + private byte keyboardInMenuEnabled = 1; + private byte vibrateOnTouchEnabled = 1;*/ + // private byte selectedTrackIndex = 0; + // private byte selectedLevel = 0; + // private byte selectedLeague = 0; + // private byte m_aTB = 0; + // private byte m_arB = 0; + private String[] onOffStrings = null; + private String[] keysetStrings = null; + // private EmptyLineMenuElement emptyLine; + // private EmptyLineMenuElement emptyLineBeforeAction; + // private AlertDialog alertDialog = null; + private Paint bgPaint; + public MenuScreen managerScreen; + public InstalledLevelsMenuScreen managerInstalledScreen; + public DownloadLevelsMenuScreen managerDownloadScreen; + // private MenuScreen managerDownloadOptionsScreen; + private SimpleMenuElementNew managerMenuItem; + public MenuScreen levelScreen; + // private SimpleMenuElement managerInstalledItem; + // private SimpleMenuElement managerDownloadItem; + // private HelmetRotationTask helmetRotationTask; + // private Timer helmetRotationTimer; + // public int helmetAngle; + + public Menu() { + // Background color (instead of raster.png) + bgPaint = new Paint(); + bgPaint.setColor(0x80FFFFFF); + } + + public void load(int step) { + GDActivity activity = getGDActivity(); + Loader loader = getLevelLoader(); + LevelsManager levelsManager = getLevelsManager(); + + level = levelsManager.getCurrentLevel(); + + switch (step) { + case 1: + m_BObject = new Object(); + nameChars = new byte[]{ + 65, 65, 65 // A A A + }; + onOffStrings = getStringArray(R.array.on_off); + keysetStrings = getStringArray(R.array.keyset); + difficultyLevels = getStringArray(R.array.difficulty); + + // saveManager = new SaveManager(); + lastTrackTime = -1L; + m_ajI = -1; + m_atI = -1; + finishedTime = null; + // settingsLoadedOK = false; + /*settings = new byte[SETTINGS_LENGTH]; + for (int l = 0; l < SETTINGS_LENGTH; l++) + settings[l] = -127;*/ + + settingsLoadedOK = true; + /*try { + recordStore = RecordStore.openRecordStore(*//*(Loader.levelsFile != null ? Loader.levelsFile.getName().hashCode() : "") + *//* + getLevelsManager().getCurrentId() + "_" + "GDTRStates", true); + settingsLoadedOK = true; + return; + } catch (Exception _ex) { + settingsLoadedOK = false; + }*/ + + break; + + case 2: + // m_afI = -1; + /*RecordEnumeration enumeration; + try { + enumeration = recordStore.enumerateRecords(null, null, false); + } catch (*//*RecordStoreNotOpen*//*Exception _ex) { + return; + } + if (enumeration.numRecords() > 0) { + byte[] abyte0; + try { + abyte0 = enumeration.nextRecord(); + enumeration.reset(); + m_afI = enumeration.nextRecordId(); + } catch (Exception _ex) { + return; + } + if (abyte0.length <= SETTINGS_LENGTH) + System.arraycopy(abyte0, 0, settings, 0, abyte0.length); + enumeration.destroy(); + }*/ + + /*byte[] chars; + if ((chars = readNameChars(16, (byte) -1)) != null && chars[0] != -1) { + for (int i = 0; i < 3; i++) + nameChars[i] = chars[i]; + + }*/ + + nameChars = Settings.getName(); + // if (nameChars[0] == 82 && nameChars[1] == 75 && nameChars[2] == 69) { + if (isNameCheat(nameChars)) { + // Unlock everything for cheat + level.setUnlockedLeagues(3); + level.setUnlockedLevels(2); + level.setUnlocked( + loader.names[0].length - 1, + loader.names[1].length - 1, + loader.names[2].length - 1 + ); + // logDebug(level); + // leaguesUnlockedCount = 3; + // levelsUnlockedCount = 2; + /*unlockedTracks[0] = (byte) (loader.names[0].length - 1); + unlockedTracks[1] = (byte) (loader.names[1].length - 1); + unlockedTracks[2] = (byte) (loader.names[2].length - 1);*/ + } else if (level.isSettingsClear()) { + level.setUnlockedLeagues(0); + level.setUnlockedLevels(1); + level.setUnlocked(0, 0, -1); + // leaguesUnlockedCount = 0; + // levelsUnlockedCount = 1; + /*unlockedTracks[0] = 0; + unlockedTracks[1] = 0; + unlockedTracks[2] = -1;*/ + } + break; + + case 3: + // Load settings + /*perspectiveOptionEnabled = readSetting(0, perspectiveOptionEnabled); + shadowsOptionEnabled = readSetting(1, shadowsOptionEnabled); + driverSpriteOptionEnabled = readSetting(2, driverSpriteOptionEnabled); + bikerSpriteOptionEnabled = readSetting(3, bikerSpriteOptionEnabled); + lookAheadOptionEnabled = readSetting(4, lookAheadOptionEnabled); + + keyboardInMenuEnabled = readSetting(13, keyboardInMenuEnabled); + inputOptionValue = readSetting(14, inputOptionValue);*/ + // m_arB = readSetting(15, m_arB); // nonsense + + /*vibrateOnTouchEnabled = readSetting(19, keyboardInMenuEnabled); + + selectedLevel = readSetting(10, selectedLevel); + selectedTrackIndex = readSetting(11, selectedTrackIndex); + selectedLeague = readSetting(12, selectedLeague);*/ + + // byte levelsSort = readSetting(20, (byte)0); + + DownloadLevelsMenuScreen.sort = Settings.getLevelsSort(); + + + levelIndex = level.getSelectedLevel(); + track = level.getSelectedTrack(); + + if (nameChars[0] != 82 || nameChars[1] != 75 || nameChars[2] != 69) { + //level.setUnlockedLeagues(); + /*leaguesUnlockedCount = readSetting(5, leaguesUnlockedCount); + levelsUnlockedCount = readSetting(6, levelsUnlockedCount); + for (int i = 0; i < 3; i++) + unlockedTracks[i] = readSetting(7 + i, unlockedTracks[i]);*/ + } + + try { + selectedTrack[level.getSelectedLevel()] = level.getSelectedTrack(); + } catch (ArrayIndexOutOfBoundsException _ex) { + level.setSelectedLevel(0); + level.setSelectedTrack(0); + selectedTrack[level.getSelectedLevel()] = level.getSelectedTrack(); + } + getLevelLoader().setPerspectiveEnabled(Settings.isPerspectiveEnabled()); + getLevelLoader().setShadowsEnabled(Settings.isShadowsEnabled()); + activity.physEngine._ifZV(Settings.isLookAheadEnabled()); + getGDView().setInputOption(Settings.getInputOption()); + // getGDView()._aZV(m_aTB == 0); + getGDView()._aZV(true); + String[] leaguesList = getStringArray(R.array.leagues); + fullLeaguesList = getStringArray(R.array.leagues_full); + trackNames = getLevelLoader().names; + + if (level.getUnlockedLeagues() < 3) { + leagues = leaguesList; + } else { + leagues = fullLeaguesList; + } + + selectedLeague = level.getSelectedLeague(); + + break; + + case 4: + mainMenu = new MenuScreen(getString(R.string.main), null); + playMenu = new MenuScreen(getString(R.string.play), mainMenu); + managerScreen = new MenuScreen(getString(R.string.mods), mainMenu); + optionsMenu = new MenuScreen(getString(R.string.options), mainMenu); + aboutScreen = new MenuScreen(getString(R.string.about) + " v" + getAppVersion(), mainMenu); + helpMenu = new MenuScreen(getString(R.string.help), mainMenu); + + continueAction = new ActionMenuElement(getString(R.string._continue), ActionMenuElement.CONTINUE, this); + nextAction = new ActionMenuElement(getString(R.string.track) + ": " + getLevelLoader().getLevelName(0, 1), ActionMenuElement.NEXT, this); + ingameRestartAction = new ActionMenuElement(getString(R.string.restart) + ": " + getLevelLoader().getLevelName(0, 0), ActionMenuElement.RESTART, this); + finishedRestartAction = new ActionMenuElement(getString(R.string.restart) + ": " + getLevelLoader().getLevelName(0, 0), ActionMenuElement.RESTART, this); + + /*nextAction = new ActionMenuElement(getString(R.string.track) + ": DEFAULT", ActionMenuElement.NEXT, this); + ingameRestartAction = new ActionMenuElement(getString(R.string.restart) + ": DEFAULT", ActionMenuElement.RESTART, this); + finishedRestartAction = new ActionMenuElement(getString(R.string.restart) + ": DEFAULT", ActionMenuElement.RESTART, this);*/ + + highScoreMenu = new MenuScreen(getString(R.string.highscores), playMenu); + finishedMenu = new MenuScreen(getString(R.string.finished), playMenu); + ingameScreen = new MenuScreen(getString(R.string.ingame), playMenu); + nameScreen = new NameInputMenuScreen(getString(R.string.enter_name), finishedMenu, nameChars); + eraseScreen = new MenuScreen(getString(R.string.confirm_clear), optionsMenu); + resetScreen = new MenuScreen(getString(R.string.confirm_reset), eraseScreen); + + gameMenuItem = new SimpleMenuElementNew(getString(R.string.play_menu), playMenu, this); + managerMenuItem = new SimpleMenuElementNew(getString(R.string.mods), managerScreen, this); + aboutMenuItem = new SimpleMenuElementNew(getString(R.string.about), aboutScreen, this); + + mainMenu.addItem(gameMenuItem); + //if (ENABLE_MANAGER) + mainMenu.addItem(new SimpleMenuElementNew(getString(R.string.mods), managerScreen, this)); + mainMenu.addItem(new SimpleMenuElementNew(getString(R.string.options), optionsMenu, this)); + mainMenu.addItem(new SimpleMenuElementNew(getString(R.string.help), helpMenu, this)); + mainMenu.addItem(aboutMenuItem); + if (Global.DEBUG) { + // mainMenu.addItem(createAction(ActionMenuElement.RESTART_WITH_NEW_LEVEL)); + mainMenu.addItem(createAction(ActionMenuElement.SEND_LOGS)); + } + mainMenu.addItem(createAction(ActionMenuElement.EXIT)); + + levelSelector = new OptionsMenuElement(getString(R.string.level), level.getSelectedLevel(), this, difficultyLevels, false, playMenu); + trackSelector = new OptionsMenuElement(getString(R.string.track), selectedTrack[level.getSelectedLevel()], this, trackNames[level.getSelectedLevel()], false, playMenu); + leagueSelector = new OptionsMenuElement(getString(R.string.league), selectedLeague, this, leagues, false, playMenu); + try { + trackSelector.setUnlockedCount(level.getUnlocked(level.getSelectedLevel())); + } catch (ArrayIndexOutOfBoundsException _ex) { + trackSelector.setUnlockedCount(0); + } + levelSelector.setUnlockedCount(level.getUnlockedLevels()); + leagueSelector.setUnlockedCount(level.getUnlockedLeagues()); + highscoreItem = new SimpleMenuElementNew(getString(R.string.highscores), highScoreMenu, this); + highScoreMenu.addItem(createAction(ActionMenuElement.BACK)); + startItem = new ActionMenuElement(getString(R.string.start) + ">", this); + playMenu.addItem(startItem); + playMenu.addItem(levelSelector); + playMenu.addItem(trackSelector); + playMenu.addItem(leagueSelector); + playMenu.addItem(highscoreItem); + playMenu.addItem(createAction(ActionMenuElement.GO_TO_MAIN)); + // if (hasPointer) + // softwareJoystickOptionItem = new ActionMenuElement("Software Joystick", m_aTB, this, onOffStrings, true, activity, optionsMenu, false); + perspectiveOptionItem = new OptionsMenuElement(getString(R.string.perspective), Settings.isPerspectiveEnabled() ? 0 : 1, this, onOffStrings, true, optionsMenu); + shadowsOptionItem = new OptionsMenuElement(getString(R.string.shadows), Settings.isShadowsEnabled() ? 0 : 1, this, onOffStrings, true, optionsMenu); + driverSpriteOptionItem = new OptionsMenuElement(getString(R.string.driver_sprite), Settings.isDriverSpriteEnabled() ? 0 : 1, this, onOffStrings, true, optionsMenu); + bikeSpriteOptionItem = new OptionsMenuElement(getString(R.string.bike_sprite), Settings.isBikeSpriteEnabled() ? 0 : 1, this, onOffStrings, true, optionsMenu); + inputOptionItem = new OptionsMenuElement(getString(R.string.input), Settings.getInputOption(), this, keysetStrings, false, optionsMenu); + lookAheadOptionItem = new OptionsMenuElement(getString(R.string.look_ahead), Settings.isLookAheadEnabled() ? 0 : 1, this, onOffStrings, true, optionsMenu); + vibrateOnTouchOptionItem = new OptionsMenuElement(getString(R.string.vibrate_on_touch), Settings.isVibrateOnTouchEnabled() ? 0 : 1, this, onOffStrings, true, optionsMenu); + keyboardInMenuOptionItem = new OptionsMenuElement(getString(R.string.keyboard_in_menu), Settings.isKeyboardInMenuEnabled() ? 0 : 1, this, onOffStrings, true, optionsMenu); + clearHighscoreOptionItem = new SimpleMenuElementNew(getString(R.string.clear_highscore), eraseScreen, this); + + // if (hasPointer) + // optionsMenu.addItem(softwareJoystickOptionItem); + optionsMenu.addItem(perspectiveOptionItem); + optionsMenu.addItem(shadowsOptionItem); + optionsMenu.addItem(driverSpriteOptionItem); + optionsMenu.addItem(bikeSpriteOptionItem); + optionsMenu.addItem(inputOptionItem); + optionsMenu.addItem(lookAheadOptionItem); + optionsMenu.addItem(vibrateOnTouchOptionItem); + optionsMenu.addItem(keyboardInMenuOptionItem); + optionsMenu.addItem(clearHighscoreOptionItem); + optionsMenu.addItem(createAction(ActionMenuElement.BACK)); + + // noAction = new ActionMenuElement(getString(R.string.no), 0, this, null, false, mainMenu, true); + // yesAction = new ActionMenuElement(getString(R.string.yes), 0, this, null, false, mainMenu, true); + fullResetItem = new SimpleMenuElementNew(getString(R.string.full_reset), resetScreen, this); + eraseScreen.addItem(new TextMenuElement(getString(R.string.erase_text1))); + eraseScreen.addItem(new TextMenuElement(getString(R.string.erase_text2))); + eraseScreen.addItem(createEmptyLine(true)); + eraseScreen.addItem(createAction(ActionMenuElement.NO)); + eraseScreen.addItem(createAction(ActionMenuElement.YES)); + eraseScreen.addItem(fullResetItem); + resetScreen.addItem(new TextMenuElement(getString(R.string.reset_text1))); + resetScreen.addItem(new TextMenuElement(getString(R.string.reset_text2))); + resetScreen.addItem(createEmptyLine(true)); + resetScreen.addItem(createAction(ActionMenuElement.NO)); + resetScreen.addItem(createAction(ActionMenuElement.YES)); + + objectiveHelpScreen = new MenuScreen(getString(R.string.objective), helpMenu); + objectiveHelpScreen.setIsTextScreen(true); + objectiveHelpItem = new SimpleMenuElementNew(getString(R.string.objective), objectiveHelpScreen, this); + objectiveHelpScreen.addItem(new TextMenuElement(Html.fromHtml(getString(R.string.objective_text)))); + objectiveHelpScreen.addItem(createAction(ActionMenuElement.BACK)); + + keysHelpScreen = new MenuScreen(getString(R.string.keys), helpMenu); + keysHelpScreen.setIsTextScreen(true); + keysHelpItem = new SimpleMenuElementNew(getString(R.string.keys), keysHelpScreen, this); + keysHelpScreen.addItem(new TextMenuElement(Html.fromHtml(getString(R.string.keyset_text)))); + keysHelpScreen.addItem(new ActionMenuElement(getString(R.string.back), ActionMenuElement.BACK, this)); + + unlockingHelpScreen = new MenuScreen(getString(R.string.unlocking), helpMenu); + unlockingHelpScreen.setIsTextScreen(true); + unlockingHelpItem = new SimpleMenuElementNew(getString(R.string.unlocking), unlockingHelpScreen, this); + unlockingHelpScreen.addItem(new TextMenuElement(Html.fromHtml(getString(R.string.unlocking_text)))); + unlockingHelpScreen.addItem(createAction(ActionMenuElement.BACK)); + + highscoreHelpScreen = new MenuScreen(getString(R.string.highscores), helpMenu); + highscoreHelpScreen.setIsTextScreen(true); + highscoreHelpItem = new SimpleMenuElementNew(getString(R.string.highscores), highscoreHelpScreen, this); + highscoreHelpScreen.addItem(new TextMenuElement(Html.fromHtml(getString(R.string.highscore_text)))); + highscoreHelpScreen.addItem(createAction(ActionMenuElement.BACK)); + + optionsHelpScreen = new MenuScreen(getString(R.string.options), helpMenu); + optionsHelpScreen.setIsTextScreen(true); + optionsHelpItem = new SimpleMenuElementNew(getString(R.string.options), optionsHelpScreen, this); + optionsHelpScreen.addItem(new TextMenuElement(Html.fromHtml(getString(R.string.options_text)))); + optionsHelpScreen.addItem(createAction(ActionMenuElement.BACK)); + + helpMenu.addItem(objectiveHelpItem); + helpMenu.addItem(keysHelpItem); + helpMenu.addItem(unlockingHelpItem); + helpMenu.addItem(highscoreHelpItem); + helpMenu.addItem(optionsHelpItem); + helpMenu.addItem(createAction(ActionMenuElement.BACK)); + + aboutScreen.setIsTextScreen(true); + aboutScreen.addItem(new TextMenuElement(Html.fromHtml(getString(R.string.about_text)))); + aboutScreen.addItem(createAction(ActionMenuElement.BACK)); + + ingameScreen.addItem(continueAction); + ingameScreen.addItem(ingameRestartAction); + ingameScreen.addItem(new SimpleMenuElementNew(getString(R.string.options), optionsMenu, this)); + ingameScreen.addItem(new SimpleMenuElementNew(getString(R.string.help), helpMenu, this)); + ingameScreen.addItem(createAction(ActionMenuElement.PLAY_MENU)); + nameAction = new ActionMenuElement(getString(R.string.name) + " - " + new String(nameChars), 0, this); + okCommand = new Command(getString(R.string.ok), 4, 1); + backCommand = new Command(getString(R.string.back), 2, 1); + setCurrentMenu(mainMenu, false); + + // LevelsManager + managerInstalledScreen = new InstalledLevelsMenuScreen(getString(R.string.installed_mods), managerScreen); + managerDownloadScreen = new DownloadLevelsMenuScreen(getString(R.string.download_mods), managerScreen); + // managerDownloadOptionsScreen = new MenuScreen(getString(R.string.download_options), managerDownloadScreen); + + /*managerInstalledScreen.setIsLevelsList(true); + managerDownloadScreen.setIsLevelsList(true);*/ + + // LevelsManager + managerScreen.addItem(new SimpleMenuElementNew(getString(R.string.download_mods), managerDownloadScreen, this)); + managerScreen.addItem(new SimpleMenuElementNew(getString(R.string.installed_mods), managerInstalledScreen, this)); + managerScreen.addItem(createEmptyLine(true)); + // managerScreen.addItem(new ActionMenuElement(getString(R.string.install_mrg), this)); + managerScreen.addItem(new ActionMenuElement(getString(R.string.install_mrg), ActionMenuElement.SELECT_FILE, this)); + + // LevelsManager installed + // managerInstalledScreen.addItem(new TextMenuElement(getString(R.string.installed_levels_text))); + + // Level screen + levelScreen = new MenuScreen("", null); + break; + } + } + + /*public void reloadLevels() { + Loader loader = getLevelLoader(); + trackNames = loader.names; + setUnlockedLevels(); + }*/ + + protected ActionMenuElement createAction(int action) { + int r; + switch (action) { + case ActionMenuElement.BACK: + r = R.string.back; + break; + + case ActionMenuElement.NO: + r = R.string.no; + break; + + case ActionMenuElement.YES: + r = R.string.yes; + break; + + case ActionMenuElement.EXIT: + r = R.string.exit; + break; + + case ActionMenuElement.OK: + r = R.string.ok; + break; + + case ActionMenuElement.PLAY_MENU: + r = R.string.play_menu; + break; + + case ActionMenuElement.GO_TO_MAIN: + r = R.string.go_to_main; + break; + + case ActionMenuElement.RESTART: + r = R.string.restart; + break; + + case ActionMenuElement.NEXT: + r = R.string.next; + break; + + case ActionMenuElement.CONTINUE: + r = R.string._continue; + break; + + case ActionMenuElement.LOAD: + r = R.string.load_this_game; + break; + + case ActionMenuElement.INSTALL: + r = R.string.install_kb; + break; + + case ActionMenuElement.DELETE: + r = R.string.delete; + break; + + case ActionMenuElement.RESTART_WITH_NEW_LEVEL: + r = R.string.restart_with_new_level; + break; + + case ActionMenuElement.SEND_LOGS: + r = R.string.send_logs; + break; + + default: + return null; + } + + return new ActionMenuElement(getString(r), action, this); + } + + public EmptyLineMenuElement createEmptyLine(boolean beforeAction) { + return new EmptyLineMenuElement(beforeAction ? 10 : 20); + } + + public int getSelectedLevel() { + return levelSelector.getSelectedOption(); + } + + public int getSelectedTrack() { + return trackSelector.getSelectedOption(); + } + + // not sure about this name + public boolean canStartTrack() { + if (m_SZ) { + m_SZ = false; + return true; + } else { + return false; + } + } + + private void saveCompletedTrack() { + // ATTENTION!!! + // WHEN CHANGING THIS CODE, COPY-PASTE TO startTrack() !!! + + LevelsManager levelsManager = getLevelsManager(); + + try { + currentScores.saveHighScore(leagueSelector.getSelectedOption(), new String(nameChars, "UTF-8"), lastTrackTime); + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + showAlert(getString(R.string.error), e.getMessage(), null); + } + // saveManager.write(); + levelsManager.saveHighScores(currentScores); + + leagueCompleted = false; + + finishedMenu.clear(); + finishedMenu.addItem(new TextMenuElement(Html.fromHtml("" + getString(R.string.time) + ": " + finishedTime))); + + System.gc(); + String[] as = currentScores.getScores(leagueSelector.getSelectedOption()); + for (int k = 0; k < as.length; k++) + if (as[k] != null) + finishedMenu.addItem(new TextMenuElement("" + (k + 1) + ". " + as[k])); + + byte byte0 = -1; + // logDebug("trackSelector.getUnlockedCount() = " + trackSelector.getUnlockedCount()); + // logDebug("trackSelector.getSelectedOption() = " + trackSelector.getSelectedOption()); + + // { + // int unlockedTracks = trackSelector.getUnlockedCount(); + // int selectedTrack = trackSelector.getSelectedOption(); + // int selectedLevel = levelSelector.getSelectedOption(); + // int unlockedInLevel = level.getUnlocked(selectedLevel); + + // logDebug("unlockedTracks (trackSelector) = " + trackSelector.getUnlockedCount()); + // logDebug("selectedTrack (trackSelector) = " + selectedTrack); + // logDebug("selectedLevel (levelSelector) = " + levelSelector.getSelectedOption()); + // logDebug("unlockedInLevel (level.getUnlocked()) = " + level.getUnlocked(levelSelector.getSelectedOption())); + + if (trackSelector.getUnlockedCount() >= trackSelector.getSelectedOption()) { + trackSelector.setUnlockedCount( + trackSelector.getSelectedOption() + 1 >= level.getUnlocked(levelSelector.getSelectedOption()) + ? trackSelector.getSelectedOption() + 1 + : level.getUnlocked(levelSelector.getSelectedOption()) + ); + level.setUnlocked(levelSelector.getSelectedOption(), + trackSelector.getUnlockedCount() >= level.getUnlocked(levelSelector.getSelectedOption()) + ? trackSelector.getUnlockedCount() + : level.getUnlocked(levelSelector.getSelectedOption()) + ); + } + // } + + // Completed league + if (trackSelector.getSelectedOption() == trackSelector.getOptionCount()) { + leagueCompleted = true; + switch (levelSelector.getSelectedOption()) { + default: + break; + + case 0: + if (level.getUnlockedLeagues() < 1) { + byte0 = 1; + level.setUnlockedLeagues(1); + // leaguesUnlockedCount = 1; + leagueSelector.setUnlockedCount(level.getUnlockedLeagues()); + } + break; + + case 1: + if (level.getUnlockedLeagues() < 2) { + byte0 = 2; + level.setUnlockedLeagues(2); + // leaguesUnlockedCount = 2; + leagueSelector.setUnlockedCount(level.getUnlockedLeagues()); + } + break; + + case 2: + if (level.getUnlockedLeagues() < 3) { + byte0 = 3; + level.setUnlockedLeagues(3); + leagueSelector.setOptions(fullLeaguesList); + leagues = fullLeaguesList; + leagueSelector.setUnlockedCount(level.getUnlockedLeagues()); + } + break; + } + + levelSelector.setUnlockedCount(levelSelector.getUnlockedCount() + 1); + + int newUnlocked = level.getUnlocked(levelSelector.getSelectedOption()) + 1, + tracksCount = level.getCount(levelSelector.getSelectedOption()); + + if (newUnlocked > tracksCount) + newUnlocked = tracksCount; + + level.setUnlocked(levelSelector.getSelectedOption(), newUnlocked); + if (level.getUnlocked(levelSelector.getUnlockedCount()) == -1) { + level.setUnlocked(levelSelector.getUnlockedCount(), 0); + } + // if (unlockedTracks[levelSelector.getUnlockedCount()] == -1) + // unlockedTracks[levelSelector.getUnlockedCount()] = 0; + } else { + trackSelector.performAction(MenuScreen.KEY_RIGHT); + } + + // int completedCount = _bbII(levelSelector.getSelectedOption()); + int completedCount = level.getUnlocked(levelSelector.getSelectedOption()); // TODO test + finishedMenu.addItem(new TextMenuElement(Html.fromHtml(String.format(getString(R.string.tracks_completed_tpl), + completedCount, trackNames[levelSelector.getSelectedOption()].length, difficultyLevels[levelSelector.getSelectedOption()])))); + System.gc(); + + if (!leagueCompleted) { + ingameRestartAction.setText(getString(R.string.restart) + ": " + getLevelLoader().getLevelName(levelSelector.getSelectedOption(), trackSelector.getSelectedOption())); + nextAction.setText(getString(R.string.next) + ": " + getLevelLoader().getLevelName(levelIndex, track + 1)); + + // getLevelsManager().updateLevelSettings(); + saveAll(); + } else { + // League completed + if (levelSelector.getSelectedOption() < levelSelector.getOptionCount()) { + levelSelector.setSelectedOption(levelSelector.getSelectedOption() + 1); + trackSelector.setSelectedOption(0); + trackSelector.setUnlockedCount(level.getUnlocked(levelSelector.getSelectedOption())); + } + + if (byte0 != -1) { + finishedMenu.addItem(new TextMenuElement(getString(R.string.congratulations) + leagues[byte0])); + if (byte0 == 3) + finishedMenu.addItem(new TextMenuElement(getString(R.string.enjoy))); + showAlert(getString(R.string.league_unlocked), getString(R.string.league_unlocked_text) + leagues[byte0], null); + + // getLevelsManager().updateLevelSettings(); + saveAll(); + } else { + boolean flag = true; + for (int i1 = 0; i1 < 3; i1++) + if (level.getUnlocked(i1) != getLevelLoader().names[i1].length - 1) + flag = false; + + if (!flag) + finishedMenu.addItem(new TextMenuElement(getString(R.string.level_completed_text))); + } + } + + if (!leagueCompleted) + finishedMenu.addItem(nextAction); + + finishedRestartAction.setText(getString(R.string.restart) + ": " + getLevelLoader().getLevelName(levelIndex, track)); + finishedMenu.addItem(finishedRestartAction); + finishedMenu.addItem(createAction(ActionMenuElement.PLAY_MENU)); + + setCurrentMenu(finishedMenu, false); + } + + //public void _hvV() { + // getGDActivity().m_di.postInvalidate(); + //} + + /* public int getGameViewScaledHeight() { + return getGDView().getScaledHeight(); + } + + public int getGameViewScaledWidth() { + return getGDView().getScaledWidth(); + } */ + + public void showMenu(int k) { + logDebug("[Menu] showMenu()"); + // k = 2; + + GDActivity gd = getGDActivity(); + GameView view = getGDView(); + Loader loader = getLevelLoader(); + + m_blZ = false; + menuDisabled = false; + switch (k) { + case 0: // Just started + setCurrentMenu(mainMenu, false); + gd.physEngine._casevV(); + m_SZ = true; + break; + + case 1: // Ingame + levelIndex = levelSelector.getSelectedOption(); + track = trackSelector.getSelectedOption(); + ingameRestartAction.setText(getString(R.string.restart) + ": " + loader.getLevelName(levelIndex, track)); + m_SZ = false; + ingameScreen.resetHighlighted(); + setCurrentMenu(ingameScreen, false); + break; + + case 2: // Finished + // finishTime = System.currentTimeMillis(); + finishedMenu.clear(); + + levelIndex = levelSelector.getSelectedOption(); + track = trackSelector.getSelectedOption(); + HighScores scores = getLevelsManager().getHighScores(levelSelector.getSelectedOption(), trackSelector.getSelectedOption()); + currentScores = scores; + + // saveManager.setTrack(levelSelector.getSelectedOption(), trackSelector.getSelectedOption()); + int place = scores.getPlace(leagueSelector.getSelectedOption(), lastTrackTime); + finishedTime = getDurationString(lastTrackTime); + + if (place >= 0 && place <= 2) { + HighScoreTextMenuElement placeText = new HighScoreTextMenuElement(""); + placeText.setText(getStringArray(R.array.finished_places)[place]); + placeText.setMedal(true, place); + + finishedMenu.addItem(placeText); + + TextMenuElement h2 = new TextMenuElement(finishedTime); + finishedMenu.addItem(h2); + + // finishedMenu.addItem(createEmptyLine(true)); + finishedMenu.addItem(createAction(ActionMenuElement.OK)); + finishedMenu.addItem(nameAction); + + setCurrentMenu(finishedMenu, false); + m_blZ = false; + } else { + saveCompletedTrack(); + } + break; + + default: + setCurrentMenu(mainMenu, false); + break; + } + + long l1 = System.currentTimeMillis(); + view.drawTimer = false; + long l4 = 0L; + int i1 = 50; + gd.physEngine._charvV(); + gd.gameToMenu(); + + do { + if (!gd.isMenuShown() || !gd.alive || currentMenu == null) + break; + + if (gd.m_cZ) { + while (gd.m_cZ) { + // logDebug("[Menu] showMenu() waiting loop"); + if (!gd.alive || currentMenu == null) { + break; + } + + try { + Thread.sleep(100L); + } catch (InterruptedException e) { + } + } + } + if (gd.physEngine != null && gd.physEngine._gotovZ()) { + int j1; + if ((j1 = gd.physEngine._dovI()) != 0 && j1 != 4) + try { + gd.physEngine._doZV(true); + } catch (NullPointerException e) { + } + gd.physEngine._charvV(); + // _hvV(); + long l2; + if ((l2 = System.currentTimeMillis()) - l4 < (long) i1) { + try { + synchronized (m_BObject) { + m_BObject.wait((long) i1 - (l2 - l4) >= 1L ? (long) i1 - (l2 - l4) : 1L); + } + } catch (InterruptedException e) { + } + l4 = System.currentTimeMillis(); + } else { + l4 = l2; + } + } else { + i1 = 50; + long l3; + if ((l3 = System.currentTimeMillis()) - l4 < (long) i1) { + Object obj; + try { + synchronized (obj = new Object()) { + obj.wait((long) i1 - (l3 - l4) >= 1L ? (long) i1 - (l3 - l4) : 1L); + } + } catch (InterruptedException e) { + } + l4 = System.currentTimeMillis(); + } else { + l4 = l3; + } + } + } while (true); + + logDebug("[Menu.showMenu] out loop"); + + gd.m_forJ += System.currentTimeMillis() - l1; + if (view != null) + view.drawTimer = true; + + if (currentMenu == null && gd != null) { + logDebug("[Menu.showMenu] currentMenu == null, set alive = false"); + gd.exiting = true; + gd.alive = false; + } + } + + public synchronized void draw(Canvas g1) { + if (currentMenu != null && !m_blZ) { + getGDView().drawGame(g1); + drawBackgroundColor(g1); + // currentMenu.draw(g1); + } + } + + private void drawBackgroundColor(Canvas g1) { + g1.drawRect(0, 0, getGDView().getScaledWidth(), getGDView().getScaledHeight(), bgPaint); + } + + public void _tryIV(int k) { + // logDebug("_tryIV k = " + k); + if (getGDView().getGameAction(k) != 8) + keyPressed(k); + } + + public void keyPressed(int k) { + if (currentMenu != null && !menuDisabled) + switch (getGDView().getGameAction(k)) { + case MenuScreen.KEY_UP: // up + currentMenu.performAction(MenuScreen.KEY_UP); + return; + + case MenuScreen.KEY_DOWN: // down + currentMenu.performAction(MenuScreen.KEY_DOWN); + return; + + case MenuScreen.KEY_FIRE: // fire + currentMenu.performAction(MenuScreen.KEY_FIRE); + return; + + case MenuScreen.KEY_RIGHT: // right + currentMenu.performAction(MenuScreen.KEY_RIGHT); + if (currentMenu == highScoreMenu) { + selectedLeague++; + if (selectedLeague > leagueSelector.getUnlockedCount()) + selectedLeague = leagueSelector.getUnlockedCount(); + showHighScoreMenu(selectedLeague); + return; + } + break; + + case MenuScreen.KEY_LEFT: // left + currentMenu.performAction(MenuScreen.KEY_LEFT); + if (currentMenu != highScoreMenu) + break; + selectedLeague--; + if (selectedLeague < 0) + selectedLeague = 0; + showHighScoreMenu(selectedLeague); + break; + } + } + + public void onCommand(Command command) { + if (command == okCommand) { + ok(); + } else if (command == backCommand && currentMenu != null) { + back(); + } + } + + public void back() { + if (currentMenu == ingameScreen) { + getGDActivity().menuToGame(); + return; + } + if (currentMenu != null) + setCurrentMenu(currentMenu.getNavTarget(), true); + } + + public void ok() { + if (currentMenu != null) { + currentMenu.performAction(1); + return; + } + } + + public MenuScreen getCurrentMenu() { + return currentMenu; + } + + public void setCurrentMenu(MenuScreen newMenu, boolean flag) { + menuDisabled = false; + GDActivity gd = getGDActivity(); + GameView view = getGDView(); + + if (!Settings.isKeyboardInMenuEnabled()) { + if (newMenu == nameScreen) { + gd.showKeyboardLayout(); + } else { + gd.hideKeyboardLayout(); + } + } + + view.removeCommand(backCommand); + if (newMenu != mainMenu && newMenu != finishedMenu && newMenu != null) + view.addCommand(backCommand); + + if (newMenu == highScoreMenu) { + selectedLeague = leagueSelector.getSelectedOption(); + showHighScoreMenu(selectedLeague); + } else if (newMenu == finishedMenu) { + // logDebug("it's finished!!!"); + nameChars = nameScreen.getChars(); + nameAction.setText(getString(R.string.name) + " - " + new String(nameChars)); + } else if (newMenu == playMenu) { + trackSelector.setOptions(getLevelLoader().names[levelSelector.getSelectedOption()], false); + if (currentMenu == trackSelectorCurrentMenu) { + selectedTrack[levelSelector.getSelectedOption()] = trackSelector.getSelectedOption(); + } + trackSelector.setUnlockedCount(level.getUnlocked(levelSelector.getSelectedOption())); + trackSelector.setSelectedOption(selectedTrack[levelSelector.getSelectedOption()]); + } + if (newMenu == mainMenu || newMenu == playMenu && gd.physEngine != null) + gd.physEngine._casevV(); + + if (currentMenu != null) + currentMenu.onHide(newMenu); + + currentMenu = newMenu; + if (currentMenu != null) { + gd.setMenu(currentMenu.getLayout()); + currentMenu.onShow(); + + // getGDActivity().setMenu(currentMenu.getTable()); + // if (!isOnOffToggle) currentMenu.scrollUp(); + } + + // getGDActivity().physEngine._casevV(); + m_blZ = false; + + // */ + } + + public void showHighScoreMenu(int league) { + HighScores highScores = getLevelsManager().getHighScores(levelSelector.getSelectedOption(), trackSelector.getSelectedOption()); + + highScoreMenu.clear(); + highScoreMenu.setTitle(getString(R.string.highscores) + ": " + getLevelLoader().getLevelName(levelSelector.getSelectedOption(), trackSelector.getSelectedOption())); + + HighScoreTextMenuElement subtitle = new HighScoreTextMenuElement(Html.fromHtml(getString(R.string.league) + ": " + leagueSelector.getOptions()[league])); + subtitle.setIsSubtitle(true); + + highScoreMenu.addItem(subtitle); + + String[] scores = highScores.getScores(league); + + for (int place = 0; place < scores.length; place++) { + if (scores[place] == null) + continue; + + HighScoreTextMenuElement h1 = new HighScoreTextMenuElement("" + (place + 1) + ". " + scores[place]); + if (place == 0) + h1.setMedal(true, 0); + else if (place == 1) + h1.setMedal(true, 1); + else if (place == 2) + h1.setMedal(true, 2); + + h1.setLayoutPadding(true); + highScoreMenu.addItem(h1); + } + + // saveManager.closeRecordStore(); + if (scores[0] == null) + highScoreMenu.addItem(new TextMenuElement(getString(R.string.no_highscores))); + + highScoreMenu.addItem(createAction(ActionMenuElement.BACK)); + highScoreMenu.highlightElement(); + + // System.gc(); + } + + public synchronized void destroy() { + currentMenu = null; + } + + public synchronized void saveAll() { + logDebug("saveAll()"); + + try { + if (level != null) { + Settings.setName(nameChars); + + level.setUnlockedLeagues(leagueSelector.getUnlockedCount()); + level.setUnlockedLevels(levelSelector.getUnlockedCount()); + + level.setSelectedLevel(levelSelector.getSelectedOption()); + level.setSelectedTrack(trackSelector.getSelectedOption()); + level.setSelectedLeague(leagueSelector.getSelectedOption()); + + getLevelsManager().updateLevelSettings(); + } else { + logDebug("saveAll(): level == null"); + } + } catch (Exception e) { + logDebug("saveAll exception: " + e); + } + } + + public void handleAction(MenuElement item) { + final GDActivity gd = getGDActivity(); + + if (currentMenu == null) { + return; + } + + if (item == startItem) + if (levelSelector.getSelectedOption() > levelSelector.getUnlockedCount() || trackSelector.getSelectedOption() > trackSelector.getUnlockedCount() || leagueSelector.getSelectedOption() > leagueSelector.getUnlockedCount()) { + showAlert("GD Classic", getString(R.string.complete_to_unlock), null); + return; + } else { + gd.physEngine._avV(); + startTrack(levelSelector.getSelectedOption(), trackSelector.getSelectedOption()); + gd.physEngine.setLeague(leagueSelector.getSelectedOption()); + m_SZ = true; + gd.menuToGame(); + return; + } + + if (item == vibrateOnTouchOptionItem) { + Settings.setVibrateOnTouchEnabled(((OptionsMenuElement) item).getSelectedOption() == 0); + } + if (item == keyboardInMenuOptionItem) { + boolean enabled = ((OptionsMenuElement) item).getSelectedOption() == 0; + Settings.setKeyboardInMenuEnabled(enabled); + if (enabled) gd.showKeyboardLayout(); + else gd.hideKeyboardLayout(); + } + if (item == perspectiveOptionItem) { + gd.physEngine._aZV(perspectiveOptionItem.getSelectedOption() == 0); + getLevelLoader().setPerspectiveEnabled(perspectiveOptionItem.getSelectedOption() == 0); + Settings.setPerspectiveEnabled(perspectiveOptionItem.getSelectedOption() == 0); + return; + } + if (item == shadowsOptionItem) { + getLevelLoader().setShadowsEnabled(shadowsOptionItem.getSelectedOption() == 0); + Settings.setShadowsEnabled(shadowsOptionItem.getSelectedOption() == 0); + return; + } + if (item == driverSpriteOptionItem) { + if (driverSpriteOptionItem._charvZ()) { + driverSpriteOptionItem.setSelectedOption(driverSpriteOptionItem.getSelectedOption() + 1); + } + Settings.setDriverSpriteEnabled(driverSpriteOptionItem.getSelectedOption() == 0); + } else if (item == bikeSpriteOptionItem) { + if (bikeSpriteOptionItem._charvZ()) { + bikeSpriteOptionItem.setSelectedOption(bikeSpriteOptionItem.getSelectedOption() + 1); + } + Settings.setBikeSpriteEnabled(bikeSpriteOptionItem.getSelectedOption() == 0); + } else { + if (item == inputOptionItem) { + if (inputOptionItem._charvZ()) + inputOptionItem.setSelectedOption(inputOptionItem.getSelectedOption() + 1); + getGDView().setInputOption(inputOptionItem.getSelectedOption()); + Settings.setInputOption(inputOptionItem.getSelectedOption()); + return; + } + if (item == lookAheadOptionItem) { + gd.physEngine._ifZV(lookAheadOptionItem.getSelectedOption() == 0); + Settings.setLookAheadEnabled(lookAheadOptionItem.getSelectedOption() == 0); + return; + } + if (item instanceof ActionMenuElement) { + if (((ActionMenuElement) item).getActionValue() == ActionMenuElement.RESTART_WITH_NEW_LEVEL) { + LevelsManager manager = gd.levelsManager; + long nextId = manager.getCurrentId() == 1 ? 2 : 1; + gd.levelsManager.load(manager.getLeveL(nextId)); + } + if (((ActionMenuElement) item).getActionValue() == ActionMenuElement.SEND_LOGS) { + gd.sendKeyboardLogs(); + } + if (((ActionMenuElement) item).getActionValue() == ActionMenuElement.SELECT_FILE) { + installFromFileBrowse(); + return; + } + if (((ActionMenuElement) item).getActionValue() == ActionMenuElement.YES) { + if (currentMenu == eraseScreen) { + getLevelsManager().clearHighScores(); + showAlert(getString(R.string.cleared), getString(R.string.cleared_text), null); + } else if (currentMenu == resetScreen) { + showAlert(getString(R.string.reset), getString(R.string.reset_text), new Runnable() { + @Override + public void run() { + resetAll(); + } + }); + } + setCurrentMenu(currentMenu.getNavTarget(), false); + return; + } + if (((ActionMenuElement) item).getActionValue() == ActionMenuElement.NO) { + setCurrentMenu(currentMenu.getNavTarget(), false); + return; + } + if (((ActionMenuElement) item).getActionValue() == ActionMenuElement.BACK) { + setCurrentMenu(currentMenu.getNavTarget(), true); + return; + } + if (((ActionMenuElement) item).getActionValue() == ActionMenuElement.PLAY_MENU) { + levelSelector.setSelectedOption(levelIndex); + trackSelector.setUnlockedCount(level.getUnlocked(levelIndex)); + trackSelector.setSelectedOption(track); + setCurrentMenu(currentMenu.getNavTarget(), false); + return; + } + if (((ActionMenuElement) item).getActionValue() == ActionMenuElement.GO_TO_MAIN) { + setCurrentMenu(mainMenu, false); + return; + } + if (((ActionMenuElement) item).getActionValue() == ActionMenuElement.EXIT) { + getGDActivity().exiting = true; + if (currentMenu != null) { + setCurrentMenu(currentMenu.getNavTarget(), false); + } else { + setCurrentMenu(null, false); + } + return; + } + } + + if (item == ingameRestartAction || item == finishedRestartAction) { + if (leagueSelector.getSelectedOption() <= leagueSelector.getUnlockedCount()) { + levelSelector.setSelectedOption(levelIndex); + trackSelector.setUnlockedCount(level.getUnlocked(levelIndex)); + trackSelector.setSelectedOption(track); + gd.physEngine.setLeague(leagueSelector.getSelectedOption()); + m_SZ = true; + gd.menuToGame(); + return; + } + } else { + if (item == nextAction) { + // if (!leagueCompleted) + // trackSelector.performAction(MenuScreen.KEY_RIGHT); + startTrack(levelSelector.getSelectedOption(), trackSelector.getSelectedOption()); + gd.physEngine.setLeague(leagueSelector.getSelectedOption()); + // saveAll(); + // getLevelsManager().updateLevelSettings(); + m_SZ = true; + gd.menuToGame(); + return; + } + if (item == continueAction) { + // _hvV(); + gd.menuToGame(); + return; + } + if (item == nameAction) { + nameScreen.resetCursorPosition(); + setCurrentMenu(nameScreen, false); + return; + } + if (item instanceof ActionMenuElement && ((ActionMenuElement) item).getActionValue() == ActionMenuElement.OK) { + saveCompletedTrack(); + return; + } + if (item == trackSelector) { + if (trackSelector._charvZ()) { + trackSelector.setUnlockedCount(level.getUnlocked(levelSelector.getSelectedOption())); + trackSelector.update(); + trackSelectorCurrentMenu = trackSelector.getCurrentMenu(); + setCurrentMenu(trackSelectorCurrentMenu, false); + // trackSelectorCurrentMenu._doIV(trackSelector.getSelectedOption()); + } + selectedTrack[levelSelector.getSelectedOption()] = trackSelector.getSelectedOption(); + return; + } + if (item == levelSelector) { + if (levelSelector._charvZ()) { + levelSelectorCurrentMenu = levelSelector.getCurrentMenu(); + setCurrentMenu(levelSelectorCurrentMenu, false); + } + trackSelector.setOptions(getLevelLoader().names[levelSelector.getSelectedOption()], false); + trackSelector.setUnlockedCount(level.getUnlocked(levelSelector.getSelectedOption())); + trackSelector.setSelectedOption(selectedTrack[levelSelector.getSelectedOption()]); + // trackSelector.update(); + // logDebug("update tracks "); + return; + } + if (item == leagueSelector && leagueSelector._charvZ()) { + leagueSelectorCurrentMenu = leagueSelector.getCurrentMenu(); + // leagueSelector.update(); + leagueSelector.setScreen(currentMenu); + setCurrentMenu(leagueSelectorCurrentMenu, false); + // leagueSelectorCurrentMenu._doIV(leagueSelector.getSelectedOption()); + } + } + } + } + + protected void startTrack(int levelIndex, int trackIndex) { + // ATTENTION!!! + // WHEN CHANGING THIS CODE, COPY-PASTE TO saveCompletedTrack() !!! + + if (Global.ACRA_ENABLED) { + ACRA.getErrorReporter().putCustomData("level_index:", String.valueOf(levelIndex)); + ACRA.getErrorReporter().putCustomData("track_index:", String.valueOf(trackIndex)); + } + + /*Menu _menu = null; + _menu.back();*/ + + try { + getLevelLoader()._doIII(levelIndex, trackIndex); + } catch (InvalidTrackException e) { + showConfirm(getString(R.string.oops), getString(R.string.e_level_damaged), new Runnable() { + @Override + public void run() { + if (trackSelector.getSelectedOption() + 1 < level.getCount(levelSelector.getSelectedOption())) { + trackSelector.setUnlockedCount(trackSelector.getSelectedOption() + 1); + level.setUnlocked(levelSelector.getSelectedOption(), trackSelector.getUnlockedCount()); + } else { + switch (levelSelector.getSelectedOption()) { + case 0: + if (level.getUnlockedLeagues() < 1) { + level.setUnlockedLeagues(1); + leagueSelector.setUnlockedCount(level.getUnlockedLeagues()); + } + break; + + case 1: + if (level.getUnlockedLeagues() < 2) { + level.setUnlockedLeagues(2); + leagueSelector.setUnlockedCount(level.getUnlockedLeagues()); + } + break; + + case 2: + if (level.getUnlockedLeagues() < 3) { + level.setUnlockedLeagues(3); + leagueSelector.setOptions(fullLeaguesList); + leagues = fullLeaguesList; + leagueSelector.setUnlockedCount(level.getUnlockedLeagues()); + } + break; + } + + int newUnlocked = level.getUnlocked(levelSelector.getSelectedOption()) + 1, + tracksCount = level.getCount(levelSelector.getSelectedOption()); + + if (newUnlocked > tracksCount) + newUnlocked = tracksCount; + + levelSelector.setUnlockedCount(levelSelector.getUnlockedCount() + 1); + level.setUnlocked(levelSelector.getSelectedOption(), newUnlocked); + } + } + }, null); + } + } + + public int _jvI() { + int k = 0; + if (driverSpriteOptionItem.getSelectedOption() == 0) + k |= 2; + if (bikeSpriteOptionItem.getSelectedOption() == 0) + k |= 1; + return k; + } + + public void _intIV(int k) { + bikeSpriteOptionItem.setSelectedOption(1); + driverSpriteOptionItem.setSelectedOption(1); + if ((k & 1) > 0) + bikeSpriteOptionItem.setSelectedOption(0); + if ((k & 2) > 0) + driverSpriteOptionItem.setSelectedOption(0); + } + + /*public int _ovI() { + return levelSelector.getSelectedOption(); + } + + public int _nvI() { + return trackSelector.getSelectedOption(); + } + + public int _lvI() { + return leagueSelector.getSelectedOption(); + }*/ + + public void setLastTrackTime(long l) { + lastTrackTime = l; + } + + /*private byte[] readNameChars(int pos, byte defaultValue) { + switch (pos) { + case 16: // '\020' + byte[] abyte0 = new byte[3]; + for (int l = 0; l < 3; l++) + abyte0[l] = settings[16 + l]; + + if (abyte0[0] == -127) + abyte0[0] = defaultValue; + return abyte0; + } + return null; + } + + private byte readSetting(int index, byte defaultValue) { + if (settings[index] == -127) + return defaultValue; + else + return settings[index]; + } + + private void saveNameChars(int pos, byte[] chars) { + if (settingsLoadedOK && pos == 16) { + for (int l = 0; l < 3; l++) + settings[16 + l] = chars[l]; + + } + }*/ + + private String getDurationString(long l) { + m_ajI = (int) (l / 100L); + m_atI = (int) (l % 100L); + String s; + if (m_ajI / 60 < 10) + s = " 0" + m_ajI / 60; + else + s = " " + m_ajI / 60; + if (m_ajI % 60 < 10) + s = s + ":0" + m_ajI % 60; + else + s = s + ":" + m_ajI % 60; + if (m_atI < 10) + s = s + ".0" + m_atI; + else + s = s + "." + m_atI; + return s; + } + + /*private void setSetting(int k, byte byte0) { + if (settingsLoadedOK) + settings[k] = byte0; + }*/ + + private void resetAll() { + Settings.resetAll(); + getLevelsManager().resetAllLevelsSettings(); + getLevelsManager().clearAllHighScores(); + + getGDActivity().fullResetting = true; + getGDActivity().destroyApp(true); + } + + public void removeCommands() { + getGDView().removeCommand(okCommand); + getGDView().removeCommand(backCommand); + } + + public void addCommands() { + if (currentMenu != mainMenu && currentMenu != finishedMenu && currentMenu != null) + getGDView().addCommand(backCommand); + getGDView().addCommand(okCommand); + } + + /*private int _bbII(int k) { + String[] as = RecordStore.listRecordStores(); + if (saveManager == null || as == null) + return 0; + int l = 0; + for (int i1 = 0; i1 < as.length; i1++) + if (as[i1].startsWith("" + k)) + l++; + + return l; + }*/ + + /*public boolean isKeyboardEnabled() { + return keyboardInMenuEnabled == 0; + }*/ + + // public boolean isVibrateOnTouchEnabled() { + // return vibrateOnTouchEnabled == 0; + //} + + /*public void hideKeyboard(boolean firstRun) { + if (!Settings.isKeyboardInMenuEnabled()) { + getGDActivity().hideKeyboardLayout(); + // MenuScreen.setSize(getGDView().getScaledWidth(), getGDView().getScaledHeight()); + } else if (firstRun) { + getGDActivity().showKeyboardLayout(); + }*//*else { + // MenuScreen.setSize(getGDView().getScaledWidth(), getGDView().getScaledHeight() - getGDActivity().getButtonsLayoutHeight()); + }*//* + } + + public void showKeyboard() { + getGDActivity().showKeyboardLayout(); + // MenuScreen.setSize(getGDView().getScaledWidth(), getGDView().getScaledHeight() - getGDActivity().getButtonsLayoutHeight()); + }*/ + + public void installFromFileBrowse() { + if (!LevelsManager.isExternalStorageReadable()) { + showAlert(getString(R.string.error), getString(R.string.e_external_storage_is_not_readable), null); + return; + } + + final GDActivity gd = getGDActivity(); + FileDialog fileDialog = new FileDialog(gd, Environment.getExternalStorageDirectory(), ".mrg"); + fileDialog.addFileListener(new FileDialog.FileSelectedListener() { + public void fileSelected(final File file) { + final EditText input = new EditText(gd); + input.setInputType(InputType.TYPE_CLASS_TEXT); + + AlertDialog.Builder alert = new AlertDialog.Builder(gd) + .setTitle(getString(R.string.enter_levels_name_title)) + .setMessage(getString(R.string.enter_levels_name)) + .setView(input) + .setPositiveButton(getString(R.string.ok), new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int whichButton) { + boolean ok = true; + String name = input.getText().toString(); + if (name.equals("")) name = file.getName(); + + ProgressDialog progressDialog = ProgressDialog.show(gd, getString(R.string.install), getString(R.string.installing), true); + + try { + gd.levelsManager.install(file, name, "", 0); + } catch (Exception e) { + ok = false; + e.printStackTrace(); + showAlert(getString(R.string.error), e.getMessage(), null); + } finally { + progressDialog.dismiss(); + } + + if (ok) { + gd.levelsManager.showSuccessfullyInstalledDialog(); + } + } + }) + .setNegativeButton(getString(R.string.cancel), null); + alert.show(); + } + }); + fileDialog.showDialog(); + } + + public static boolean isNameCheat(byte[] chars) { + return chars[0] == 82 && chars[1] == 75 && chars[2] == 69; + } + +} diff --git a/src/org/happysanta/gd/Menu/MenuElement.java b/src/org/happysanta/gd/Menu/MenuElement.java new file mode 100644 index 0000000..82fe490 --- /dev/null +++ b/src/org/happysanta/gd/Menu/MenuElement.java @@ -0,0 +1,20 @@ +package org.happysanta.gd.Menu; + +import android.view.View; + +/** + * Author: ch1p + */ +public interface MenuElement { + + // public abstract void setText(String s); + + public abstract boolean isSelectable(); + + public abstract View getView(); + + public abstract void setText(String text); + + public void performAction(int k); + +} diff --git a/src/org/happysanta/gd/Menu/MenuElementOld.java b/src/org/happysanta/gd/Menu/MenuElementOld.java new file mode 100755 index 0000000..6a4400f --- /dev/null +++ b/src/org/happysanta/gd/Menu/MenuElementOld.java @@ -0,0 +1,32 @@ +package org.happysanta.gd.Menu; + +import android.graphics.Canvas; +import android.graphics.Paint; +import android.view.View; + +public interface MenuElementOld { + + public abstract void setText(String s); + + // Why y before x?! + public abstract void draw(Canvas g, int y, int x); + + public abstract boolean isSelectable(); + + public abstract int getLineSpacing(); + + public abstract void performAction(int i); + + public abstract void setFont(Paint font); + + public abstract int getHeight(); + + public abstract int getFirstLineHeight(); + + public abstract int getXOffset(); + + public abstract void setPressed(boolean flag); + + public abstract View getView(); + +} diff --git a/src/org/happysanta/gd/Menu/MenuHandler.java b/src/org/happysanta/gd/Menu/MenuHandler.java new file mode 100755 index 0000000..208e579 --- /dev/null +++ b/src/org/happysanta/gd/Menu/MenuHandler.java @@ -0,0 +1,12 @@ +package org.happysanta.gd.Menu; + +public interface MenuHandler { + + public abstract MenuScreen getCurrentMenu(); + + public abstract void setCurrentMenu(MenuScreen e, boolean flag); + + // public abstract void destroy(); + + public abstract void handleAction(MenuElement item); +} diff --git a/src/org/happysanta/gd/Menu/MenuScreen.java b/src/org/happysanta/gd/Menu/MenuScreen.java new file mode 100755 index 0000000..c49c085 --- /dev/null +++ b/src/org/happysanta/gd/Menu/MenuScreen.java @@ -0,0 +1,277 @@ +package org.happysanta.gd.Menu; + +import android.content.Context; +import android.view.ViewTreeObserver; +import android.widget.LinearLayout; +import org.happysanta.gd.GDActivity; +import org.happysanta.gd.Menu.Views.MenuLinearLayout; + +import java.util.Vector; + +import static org.happysanta.gd.Helpers.getDp; +import static org.happysanta.gd.Helpers.getGDActivity; +import static org.happysanta.gd.Helpers.isSDK11OrHigher; +import static org.happysanta.gd.Helpers.logDebug; + +public class MenuScreen + implements OnMenuElementHighlightListener { + + public static final int KEY_FIRE = 5; + public static final int KEY_UP = 2; + public static final int KEY_DOWN = 8; + public static final int KEY_LEFT = 4; + public static final int KEY_RIGHT = 6; + + protected static final int LAYOUT_LEFT_PADDING = 30; + protected static final int LAYOUT_TOP_PADDING = 0; + protected static final int LAYOUT_BOTTOM_PADDING = 15; + + protected MenuScreen navTarget; + protected String title; + protected int selectedIndex; + protected Vector menuItems; + protected MenuLinearLayout layout; + protected ClickableMenuElement lastHighlighted; + protected boolean isTextScreen = false; + + public MenuScreen(String title, MenuScreen navTarget) { + this.title = title; + selectedIndex = -1; + menuItems = new Vector(); + this.navTarget = navTarget; + + Context context = getGDActivity(); + + layout = new MenuLinearLayout(context); + layout.setOrientation(LinearLayout.VERTICAL); + layout.setPadding(getDp(LAYOUT_LEFT_PADDING), getDp(LAYOUT_TOP_PADDING), getDp(LAYOUT_LEFT_PADDING), getDp(LAYOUT_BOTTOM_PADDING)); + + // Disable multi-touch in menu + if (isSDK11OrHigher()) + layout.setMotionEventSplittingEnabled(false); + } + + public void addItem(MenuElement item) { + layout.addView(item.getView()); + menuItems.add(item); + + if (item instanceof ClickableMenuElement) + ((ClickableMenuElement) item).setOnHighlightListener(this); + } + + protected void scrollToItem(MenuElement item) { + // int y = item.getView().getTop(); + // logDebug("scrollTo: y = " + y); + + // getGameMenu().scrollTo(y); + getGDActivity().scrollToView(item.getView()); + } + + public void performAction(int k) { + // logDebug("MenuScreen.performAction: k = " + k); + int from = 0; + switch (k) { + default: + // logDebug("selectedIndex = " + selectedIndex); + if (selectedIndex != -1) { + for (int i = selectedIndex; i < menuItems.size(); i++) { + MenuElement item; + if ((item = (MenuElement) menuItems.elementAt(i)) != null && item.isSelectable()) { + item.performAction(k); + return; + } + } + } + break; + + case KEY_UP: + if (isTextScreen) { + getGDActivity().scrollTextMenuUp(); + return; + } + + if (selectedIndex > 0 && !elementIsFirstClickable(selectedIndex)) { + from = selectedIndex - 1; + } else { + from = menuItems.size() - 1; + } + + for (int i = from; i >= 0; i--) { + MenuElement el = (MenuElement) menuItems.elementAt(i); + if (!(el instanceof ClickableMenuElement) || ((ClickableMenuElement) el).isDisabled()) { + continue; + } + + highlightElement((ClickableMenuElement) el); + selectedIndex = i; + scrollToItem(el); + break; + } + break; + + case KEY_DOWN: + if (isTextScreen) { + getGDActivity().scrollTextMenuDown(); + return; + } + + if (selectedIndex < menuItems.size() - 1) { + from = selectedIndex + 1; + } else { + from = 0; + } + for (int i = from; i < menuItems.size(); i++) { + MenuElement el = (MenuElement) menuItems.elementAt(i); + if (!(el instanceof ClickableMenuElement) || ((ClickableMenuElement) el).isDisabled()) { + continue; + } + + highlightElement((ClickableMenuElement) el); + selectedIndex = i; + scrollToItem(el); + break; + } + break; + } + } + + protected boolean elementIsFirstClickable(int index) { + for (int i = 0; i < menuItems.size(); i++) { + MenuElement el = (MenuElement) menuItems.elementAt(i); + if (!(el instanceof ClickableMenuElement) || ((ClickableMenuElement) el).isDisabled()) { + if (i == index) { + return false; + } + } else { + if (i < index) return false; + if (i == index) return true; + } + } + + return false; + } + + public MenuScreen getNavTarget() { + return navTarget; + } + + public void setNavTarget(MenuScreen target) { + navTarget = target; + } + + /*public void setIsLevelsList(boolean is) { + isLevelsList = is; + }*/ + + public void clear() { + menuItems.removeAllElements(); + layout.removeAllViews(); + + selectedIndex = -1; + lastHighlighted = null; + } + + public LinearLayout getLayout() { + return layout; + } + + protected void setTitle(String s) { + title = s; + } + + protected void updateTitle() { + final GDActivity gd = getGDActivity(); + gd.runOnUiThread(new Runnable() { + @Override + public void run() { + gd.menuTitleTextView.setText(title); + // activity.menuTitleTextView.invalidate(); + gd.titleLayout.invalidate(); + } + }); + } + + public void onHide(MenuScreen newMenu) { + } + + public void onShow() { + updateTitle(); + highlightElement(); + } + + public void resetHighlighted() { + lastHighlighted = null; + } + + public void highlightElement() { + if (lastHighlighted != null) { + lastHighlighted.showHelmet(); + final ViewTreeObserver obs = layout.getViewTreeObserver(); + obs.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() { + @Override + public boolean onPreDraw() { + try { + obs.removeOnPreDrawListener(this); + scrollToItem(lastHighlighted); + } catch (Exception e) { + } + + return true; + } + }); + } else { + for (int i = 0; i < menuItems.size(); i++) { + if (menuItems.elementAt(i) instanceof ClickableMenuElement) { + ClickableMenuElement item = (ClickableMenuElement) menuItems.elementAt(i); + if (item.isDisabled()) continue; + + highlightElement(item); + scrollToItem(lastHighlighted); + selectedIndex = i; + + break; + } + } + } + } + + public void setSelected(int index) { + try { + if (menuItems.elementAt(index) instanceof ClickableMenuElement) { + ClickableMenuElement item = (ClickableMenuElement) menuItems.elementAt(index); + if (item.isDisabled()) return; + + highlightElement(item); + selectedIndex = index; + } + } catch (Exception e) { + e.printStackTrace(); + } + } + + protected void highlightElement(ClickableMenuElement el) { + el.showHelmet(); + lastHighlighted = el; + } + + public void onScroll(double percent) { + } + + @Override + public void onElementHighlight(ClickableMenuElement el) { + lastHighlighted = el; + + int index = menuItems.indexOf(el); + if (index != -1) + selectedIndex = index; + } + + public void setIsTextScreen(boolean isTextScreen) { + this.isTextScreen = isTextScreen; + } + + /*public boolean isTextScreen() { + return isTextScreen; + }*/ + +} diff --git a/src/org/happysanta/gd/Menu/NameInputMenuScreen.java b/src/org/happysanta/gd/Menu/NameInputMenuScreen.java new file mode 100644 index 0000000..e742c7c --- /dev/null +++ b/src/org/happysanta/gd/Menu/NameInputMenuScreen.java @@ -0,0 +1,175 @@ +package org.happysanta.gd.Menu; + +import android.content.Context; +import android.graphics.Paint; +import android.graphics.Rect; +import android.view.ViewGroup; +import android.widget.LinearLayout; +import android.widget.TextView; +import org.happysanta.gd.Global; +import org.happysanta.gd.Menu.Views.MenuLinearLayout; +import org.happysanta.gd.Menu.Views.MenuTextView; + +import static org.happysanta.gd.Helpers.getDp; +import static org.happysanta.gd.Helpers.getGDActivity; +import static org.happysanta.gd.Helpers.getGameMenu; + +public class NameInputMenuScreen extends MenuScreen { + + protected static final String CURSOR = "^"; + protected static final int WORD_SPACE = 3; + + protected static int wordWidth = 0; + + protected int cursorPosition = 0; + protected byte chars[]; + + protected MenuTextView nameTextViews[]; + protected MenuTextView cursorTextViews[]; + protected MenuLinearLayout nameLayout; + protected MenuLinearLayout cursorLayout; + + static { + wordWidth = getWordWidth(); + } + + public NameInputMenuScreen(String title, MenuScreen navTarget, byte nameChars[]) { + super(title, navTarget); + + chars = nameChars; + + Context context = getGDActivity(); + + nameTextViews = new MenuTextView[3]; + cursorTextViews = new MenuTextView[3]; + + nameLayout = new MenuLinearLayout(context); + nameLayout.setOrientation(LinearLayout.HORIZONTAL); + + cursorLayout = new MenuLinearLayout(context); + cursorLayout.setOrientation(LinearLayout.HORIZONTAL); + + for (int i = 0; i < 3; i++) { + nameTextViews[i] = createTextView(); + nameLayout.addView(nameTextViews[i]); + + cursorTextViews[i] = createTextView(); + cursorLayout.addView(cursorTextViews[i]); + } + + layout.addView(nameLayout, new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT)); + layout.addView(cursorLayout, new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT)); + + updateText(); + updateCursorPosition(); + } + + protected MenuTextView createTextView() { + Context context = getGDActivity(); + MenuTextView textView = new MenuTextView(context); + textView.setTextColor(0xff000000); + textView.setTypeface(Global.robotoCondensedTypeface); + textView.setTextSize(ClickableMenuElement.TEXT_SIZE); + textView.setLayoutParams(new LinearLayout.LayoutParams( + wordWidth, + ViewGroup.LayoutParams.WRAP_CONTENT + )); + return textView; + } + + protected static int getWordWidth() { + Context context = getGDActivity(); + + String text = "W"; + TextView textView = new TextView(context); + textView.setTextSize(ClickableMenuElement.TEXT_SIZE); + textView.setTypeface(Global.robotoCondensedTypeface); + + Rect bounds = new Rect(); + + Paint textPaint = textView.getPaint(); + textPaint.getTextBounds(text, 0, text.length(), bounds); + + return bounds.width() + getDp(WORD_SPACE); + } + + @Override + public void performAction(int k) { + switch (k) { + default: + break; + + case MenuScreen.KEY_FIRE: // select + if (cursorPosition == 2) { + getGameMenu().setCurrentMenu(navTarget, false); + } else { + cursorPosition++; + updateCursorPosition(); + } + break; + + case MenuScreen.KEY_RIGHT: // right + cursorPosition++; + if (cursorPosition > 2) { + cursorPosition = 2; + } + updateCursorPosition(); + break; + + case MenuScreen.KEY_LEFT: // left + cursorPosition--; + if (cursorPosition < 0) + cursorPosition = 0; + updateCursorPosition(); + break; + + case MenuScreen.KEY_UP: // up + if (chars[cursorPosition] == 32) { + chars[cursorPosition] = 65; + updateText(); + break; + } + chars[cursorPosition]++; + if (chars[cursorPosition] > 90) { + chars[cursorPosition] = 32; + } + updateText(); + break; + + case MenuScreen.KEY_DOWN: // down + if (chars[cursorPosition] == 32) { + chars[cursorPosition] = 90; + updateText(); + break; + } + chars[cursorPosition]--; + if (chars[cursorPosition] < 65) { + chars[cursorPosition] = 32; + } + updateText(); + break; + } + } + + protected void updateText() { + for (int i = 0; i < nameTextViews.length; i++) { + nameTextViews[i].setTextOnUiThread(String.valueOf((char) chars[i])); + } + } + + protected void updateCursorPosition() { + for (int i = 0; i < cursorTextViews.length; i++) { + cursorTextViews[i].setTextOnUiThread(i == cursorPosition ? CURSOR : ""); + } + } + + public byte[] getChars() { + return chars; + } + + public void resetCursorPosition() { + cursorPosition = 0; + updateCursorPosition(); + } + +} diff --git a/src/org/happysanta/gd/Menu/OnMenuElementHighlightListener.java b/src/org/happysanta/gd/Menu/OnMenuElementHighlightListener.java new file mode 100644 index 0000000..f065bf1 --- /dev/null +++ b/src/org/happysanta/gd/Menu/OnMenuElementHighlightListener.java @@ -0,0 +1,10 @@ +package org.happysanta.gd.Menu; + +/** + * Author: ch1p + */ +public interface OnMenuElementHighlightListener { + + public abstract void onElementHighlight(ClickableMenuElement el); + +} diff --git a/src/org/happysanta/gd/Menu/OptionsMenuElement.java b/src/org/happysanta/gd/Menu/OptionsMenuElement.java new file mode 100644 index 0000000..2119b32 --- /dev/null +++ b/src/org/happysanta/gd/Menu/OptionsMenuElement.java @@ -0,0 +1,301 @@ +package org.happysanta.gd.Menu; + +import android.content.Context; +import android.view.View; +import android.widget.ImageView; +import android.widget.LinearLayout; +import org.happysanta.gd.Global; +import org.happysanta.gd.Menu.Views.MenuImageView; +import org.happysanta.gd.Menu.Views.MenuTextView; +import org.happysanta.gd.R; +// import com.grishka.agdtr.R; + +import static org.happysanta.gd.Helpers.getDp; +import static org.happysanta.gd.Helpers.getGDActivity; +import static org.happysanta.gd.Helpers.getString; +import static org.happysanta.gd.Helpers.logDebug; + +public class OptionsMenuElement + extends ClickableMenuElement + implements MenuElement, MenuHandler { + + protected int selectedIndex; + protected String options[]; + protected int unlockedCount; + protected MenuHandler handler; + protected MenuScreen optionsScreen = null; + protected MenuScreen screen = null; + protected boolean isOnOffToggle; + protected boolean m_oZ = false; + protected String selectedOption; + protected ActionMenuElement optionsScreenItems[] = null; + protected MenuImageView lockImage = null; + protected MenuTextView optionTextView = null; + + public OptionsMenuElement(String text, int selectedIndex, MenuHandler handler, String options[], boolean isOnOffToggle, MenuScreen screen) { + this.text = text; + this.selectedIndex = selectedIndex; + this.handler = handler; + this.options = options; + if (this.options == null) this.options = new String[]{""}; + unlockedCount = this.options.length - 1; + this.isOnOffToggle = isOnOffToggle; + + createAllViews(); + setSelectedOption(selectedIndex); + + if (isOnOffToggle) { + if (selectedIndex == 1) { + selectedOption = getString(R.string.off); + } else { + selectedOption = getString(R.string.on); + } + } else { + this.screen = screen; + updateSelectedOption(); + update(); + } + } + + @Override + protected void createAllViews() { + Context context = getGDActivity(); + + super.createAllViews(); + + textView.setLayoutParams(new LinearLayout.LayoutParams( + LinearLayout.LayoutParams.WRAP_CONTENT, + LinearLayout.LayoutParams.WRAP_CONTENT + )); + + optionTextView = new MenuTextView(context); + optionTextView.setText(selectedOption); + optionTextView.setTextColor(getMenuTextView().getTextColors()); + optionTextView.setTextSize(TEXT_SIZE); + optionTextView.setTypeface(Global.robotoCondensedTypeface); + optionTextView.setLayoutParams(new LinearLayout.LayoutParams( + LinearLayout.LayoutParams.WRAP_CONTENT, + LinearLayout.LayoutParams.WRAP_CONTENT + )); + optionTextView.setPadding( + textView.getPaddingLeft(), + textView.getPaddingTop(), + textView.getPaddingRight(), + textView.getPaddingBottom() + ); + + lockImage = new MenuImageView(context); + lockImage.setImageResource(ActionMenuElement.locks[0]); + lockImage.setScaleType(ImageView.ScaleType.CENTER); + lockImage.setVisibility(View.GONE); + + LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.MATCH_PARENT); + lp.setMargins(0, 0, getDp(ActionMenuElement.LOCK_IMAGE_MARGIN_RIGHT), 0); + lockImage.setLayoutParams(lp); + lockImage.setVisibility(View.GONE); + + layout.addView(lockImage); + layout.addView(optionTextView); + } + + private void updateSelectedOption() { + selectedOption = options[selectedIndex]; + updateViewText(); + + if (selectedIndex > unlockedCount && !isOnOffToggle) { + lockImage.setVisibility(View.VISIBLE); + } else { + lockImage.setVisibility(View.GONE); + } + } + + public int getUnlockedCount() { + return unlockedCount; + } + + public void setUnlockedCount(int k) { + unlockedCount = k; + if (unlockedCount > options.length - 1) + unlockedCount = options.length - 1; + if (optionsScreen != null) { + for (int l = 0; l < optionsScreenItems.length; l++) + if (l > k) + optionsScreenItems[l].setLock(true, true); + else + optionsScreenItems[l].setLock(false, false); + } + updateSelectedOption(); + } + + public int getOptionCount() { + return options.length - 1; + } + + public String[] getOptions() { + return options; + } + + public void setOptions(String as[]) { + setOptions(as, true); + } + + public void setOptions(String as[], boolean update) { + options = as; + if (selectedIndex > options.length - 1) + selectedIndex = options.length - 1; + if (unlockedCount > options.length - 1) + unlockedCount = options.length - 1; + updateSelectedOption(); + if (update) update(); + } + + public int getSelectedOption() { + return selectedIndex; + } + + public void setSelectedOption(int k) { + selectedIndex = k; + if (selectedIndex > options.length - 1) + selectedIndex = 0; + if (selectedIndex < 0) + selectedIndex = options.length - 1; + updateSelectedOption(); + } + + public void update() { + optionsScreen = new MenuScreen(text, screen); + optionsScreenItems = new ActionMenuElement[options.length]; + for (int k = 0; k < optionsScreenItems.length; k++) { + if (k > unlockedCount) { + optionsScreenItems[k] = new ActionMenuElement(options[k], this); + optionsScreenItems[k].setLock(true, true); + } else { + optionsScreenItems[k] = new ActionMenuElement(options[k], this); + } + optionsScreen.addItem(optionsScreenItems[k]); + } + optionsScreen.setSelected(selectedIndex); + + // System.gc(); + } + + public boolean _charvZ() { + if (m_oZ) { + m_oZ = false; + return true; + } else { + return m_oZ; + } + } + + @Override + public void handleAction(MenuElement item) { + int k = 0; + do { + if (k >= optionsScreenItems.length) + break; + if (item == optionsScreenItems[k]) { + selectedIndex = k; + updateSelectedOption(); + break; + } + k++; + } while (true); + + handler.setCurrentMenu(screen, true); + handler.handleAction(this); + } + + @Override + public MenuScreen getCurrentMenu() { + return optionsScreen; + } + + @Override + public void setCurrentMenu(MenuScreen e1, boolean flag) { + } + + @Override + protected void updateViewText() { + if (textView != null && textView instanceof MenuTextView) + ((MenuTextView) textView).setTextOnUiThread(getTextForView()); + if (optionTextView != null) optionTextView.setTextOnUiThread(selectedOption); + } + + @Override + public void performAction(int k) { + // logDebug("OptionMenuElement performAction: k = " + k); + switch (k) { + case MenuScreen.KEY_FIRE: + if (isOnOffToggle) { + selectedIndex++; + if (selectedIndex > 1) + selectedIndex = 0; + if (selectedIndex == 1) + selectedOption = getString(R.string.off); + else + selectedOption = getString(R.string.on); + updateViewText(); + handler.handleAction(this); + return; + } else { + m_oZ = true; + handler.handleAction(this); + return; + } + + case MenuScreen.KEY_RIGHT: + if (isOnOffToggle) { + if (selectedIndex == 1) { + selectedIndex = 0; + selectedOption = getString(R.string.on); + handler.handleAction(this); + updateViewText(); + } + return; + } + selectedIndex++; + if (selectedIndex > options.length - 1) + selectedIndex = options.length - 1; + else + handler.handleAction(this); + updateSelectedOption(); + return; + + case MenuScreen.KEY_LEFT: // '\003' + if (isOnOffToggle) { + if (selectedIndex == 0) { + selectedIndex = 1; + selectedOption = getString(R.string.off); + handler.handleAction(this); + updateViewText(); + } + return; + } + selectedIndex--; + if (selectedIndex < 0) { + selectedIndex = 0; + } else { + updateSelectedOption(); + handler.handleAction(this); + } + updateSelectedOption(); + break; + } + } + + public void setScreen(MenuScreen screen) { + this.screen = screen; + } + + @Override + protected String getTextForView() { + return text + ": "; + } + + @Override + protected void onHighlightChanged() { + lockImage.setImageResource(ActionMenuElement.locks[isHighlighted ? 2 : 0]); + } + +} diff --git a/src/org/happysanta/gd/Menu/SimpleMenuElement.java b/src/org/happysanta/gd/Menu/SimpleMenuElement.java new file mode 100755 index 0000000..57842f5 --- /dev/null +++ b/src/org/happysanta/gd/Menu/SimpleMenuElement.java @@ -0,0 +1,176 @@ +package org.happysanta.gd.Menu; + +// Decompiled by Jad v1.5.8f. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) fieldsfirst ansi + +import android.graphics.Canvas; +import android.graphics.Paint; +import android.view.View; +import android.view.ViewGroup; +import org.happysanta.gd.Global; +import org.happysanta.gd.Menu.Views.MenuTextView; + +import java.util.TimerTask; + +import static org.happysanta.gd.Helpers.getGDActivity; +import static org.happysanta.gd.Helpers.getGDView; + +public class SimpleMenuElement extends TimerTask + implements MenuElementOld { + + // public static final int LINE_SPACING = 15; + protected static Paint gFont; + + public int x; + public int y; + public int m_bI; + public int m_eI; + public int m_dI; + public int m_gotoI; + public int m_nullI; + public int m_longI; + public int m_fI; + int m_cI; + // GDActivity activity; + protected String text; + protected MenuScreen m_we; + protected MenuHandler m_hc; + protected Paint font; + protected boolean isPressed = false; + protected MenuTextView textView; + + /*static { + gFont = ActionMenuElement.getGFont(); + }*/ + + public SimpleMenuElement() { + init(); + } + + public SimpleMenuElement(int k) { + m_cI = k; + font = gFont; + } + + public SimpleMenuElement(String s, MenuScreen e1, MenuHandler c1) { + text = s + ">"; + m_we = e1; + m_hc = c1; + font = gFont; + + textView = new MenuTextView(getGDActivity()); + textView.setText(text); + textView.setTextColor(0xff000000); + // textView.setTextColor(R.drawable.menu_item_color); + textView.setTypeface(Global.robotoCondensedTypeface); + textView.setTextSize(20); + textView.setLayoutParams(new ViewGroup.LayoutParams( + ViewGroup.LayoutParams.MATCH_PARENT, + ViewGroup.LayoutParams.WRAP_CONTENT + )); + } + + public void init() { + x = y = m_bI = 0; + m_eI = m_dI = m_gotoI = 0; + m_nullI = m_longI = m_fI = 0; + } + + @Override + public View getView() { + return textView; + } + + @Override + public void run() { + getGDView()._tryIV(m_cI); + } + + @Override + public void setText(String s) { + text = s + ">"; + } + + public String getText() { + return text; + } + + @Override + public boolean isSelectable() { + return true; + } + + @Override + public void performAction(int k) { + /*switch (k) { + case MenuScreen.KEY_FIRE: + case MenuScreen.KEY_RIGHT: + m_hc.handleAction(this); + m_we.setNavTarget(m_hc.getCurrentMenu()); + m_hc.setCurrentMenu(m_we, false); + // fall through + + case 3: // '\003' + default: + return; + }*/ + } + + /* public void _aeV(MenuScreen e1) { + screen = e1; + } */ + + @Override + public void draw(Canvas g, int y, int x) { + // if (isPressed) + // setPressedColor(); + g.drawText(text, x, y - font.ascent(), font); + // if (isPressed) + // setNormalColor(); + } + + @Override + public int getLineSpacing() { + return ActionMenuElement.LINE_SPACING; + } + + @Override + public void setFont(Paint font) { + this.font = font; + } + + @Override + public int getHeight() { + return Math.round(font.descent() - font.ascent()); + } + + @Override + public int getFirstLineHeight() { + return getHeight(); + } + + /* @Override + public int getHeight() { + return getHeight() + getLineSpacing(); + } */ + + @Override + public int getXOffset() { + return ActionMenuElement.X_OFFSET; + } + + @Override + public void setPressed(boolean flag) { + isPressed = flag; + } + + /*protected void setPressedColor() { + font.setColor(ActionMenuElement.PRESSED_COLOR); + } + + protected void setNormalColor() { + font.setColor(ActionMenuElement.NORMAL_COLOR); + }*/ + +} diff --git a/src/org/happysanta/gd/Menu/SimpleMenuElementNew.java b/src/org/happysanta/gd/Menu/SimpleMenuElementNew.java new file mode 100644 index 0000000..474a6ad --- /dev/null +++ b/src/org/happysanta/gd/Menu/SimpleMenuElementNew.java @@ -0,0 +1,77 @@ +package org.happysanta.gd.Menu; + +import static org.happysanta.gd.Helpers.logDebug; + +public class SimpleMenuElementNew extends ClickableMenuElement + implements MenuElement { + + // protected static Paint gFont; + + public int x; + public int y; + /* public int m_bI; + public int m_eI; + public int m_dI; + public int m_gotoI; + public int m_nullI; + public int m_longI; + public int m_fI; + int m_cI; */ + protected MenuScreen screen; + protected MenuHandler handler; + // protected Paint font; + // protected boolean isPressed = false; + + /* static { + gFont = ActionMenuElement.getGFont(); + } */ + + /* public SimpleMenuElementNew() { + init(); + } + + public SimpleMenuElementNew(int k) { + m_cI = k; + // font = gFont; + } */ + + public SimpleMenuElementNew(String text, MenuScreen screen, MenuHandler handler) { + this.text = text + ">"; + this.screen = screen; + this.handler = handler; + + createAllViews(); + + // textView = createAllViews(); + } + + /* public void init() { + x = y = m_bI = 0; + m_eI = m_dI = m_gotoI = 0; + m_nullI = m_longI = m_fI = 0; + } */ + + @Override + public void setText(String s) { + super.setText(s + ">"); + } + + // @Override + public void performAction(int k) { + logDebug("SimpleMenuElementNew performAction k = " + k); + + switch (k) { + case MenuScreen.KEY_FIRE: + case MenuScreen.KEY_RIGHT: + handler.handleAction(this); + screen.setNavTarget(handler.getCurrentMenu()); + handler.setCurrentMenu(screen, false); + break; + } + } + + /* public void _aeV(MenuScreen e1) { + screen = e1; + } */ + +} diff --git a/src/org/happysanta/gd/Menu/TextMenuElement.java b/src/org/happysanta/gd/Menu/TextMenuElement.java new file mode 100755 index 0000000..7485389 --- /dev/null +++ b/src/org/happysanta/gd/Menu/TextMenuElement.java @@ -0,0 +1,80 @@ +package org.happysanta.gd.Menu; + +// Decompiled by Jad v1.5.8f. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) fieldsfirst ansi + +import android.content.Context; +import android.text.Html; +import android.text.Spanned; +import android.text.SpannedString; +import android.text.util.Linkify; +import android.view.View; +import android.view.ViewGroup; +import org.happysanta.gd.Menu.Views.MenuTextView; + +import static org.happysanta.gd.Helpers.getGDActivity; + +public class TextMenuElement + implements MenuElement { + + protected static final int TEXT_SIZE = 15; + protected static final int TEXT_COLOR = 0xff000000; + + protected Spanned spanned; + protected MenuTextView textView; + + public TextMenuElement(String text) { + this.spanned = SpannedString.valueOf(text); + textView = createTextView(); + } + + public TextMenuElement(Spanned text) { + this.spanned = text; + textView = createTextView(); + } + + protected MenuTextView createTextView() { + Context activity = getGDActivity(); + + MenuTextView textView = new MenuTextView(activity); + textView.setText(spanned); + textView.setTextColor(TEXT_COLOR); + textView.setTextSize(TEXT_SIZE); + textView.setLineSpacing(0f, 1.5f); + textView.setLayoutParams(new ViewGroup.LayoutParams( + ViewGroup.LayoutParams.MATCH_PARENT, + ViewGroup.LayoutParams.WRAP_CONTENT + )); + + Linkify.addLinks(textView, Linkify.WEB_URLS); + textView.setLinksClickable(true); + + return textView; + } + + @Override + public View getView() { + return textView; + } + + public String getText() { + return spanned.toString(); + } + + @Override + public void setText(String text) { + this.spanned = Html.fromHtml(text); + textView.setTextOnUiThread(spanned); + } + + @Override + public boolean isSelectable() { + return false; + } + + @Override + public void performAction(int k) { + } + +} diff --git a/src/org/happysanta/gd/Menu/Views/LevelNameLeadingMarginSpan2.java b/src/org/happysanta/gd/Menu/Views/LevelNameLeadingMarginSpan2.java new file mode 100644 index 0000000..09c744d --- /dev/null +++ b/src/org/happysanta/gd/Menu/Views/LevelNameLeadingMarginSpan2.java @@ -0,0 +1,38 @@ +package org.happysanta.gd.Menu.Views; + +import android.graphics.Canvas; +import android.graphics.Paint; +import android.text.Layout; +import android.text.style.LeadingMarginSpan; + +public class LevelNameLeadingMarginSpan2 implements LeadingMarginSpan.LeadingMarginSpan2 { + + private int margin; + private int lines; + + public LevelNameLeadingMarginSpan2(int lines, int margin) { + this.margin = margin; + this.lines = lines; + } + + @Override + public int getLeadingMargin(boolean first) { + if (first) { + return margin; + } else { + return 0; + } + } + + @Override + public void drawLeadingMargin(Canvas c, Paint p, int x, int dir, + int top, int baseline, int bottom, CharSequence text, + int start, int end, boolean first, Layout layout) { + } + + @Override + public int getLeadingMarginLineCount() { + return lines; + } + +} diff --git a/src/org/happysanta/gd/Menu/Views/MenuHelmetView.java b/src/org/happysanta/gd/Menu/Views/MenuHelmetView.java new file mode 100644 index 0000000..bb2a37a --- /dev/null +++ b/src/org/happysanta/gd/Menu/Views/MenuHelmetView.java @@ -0,0 +1,111 @@ +package org.happysanta.gd.Menu.Views; + +import android.content.Context; +import android.graphics.Canvas; +import android.graphics.Rect; +import android.graphics.RectF; +import android.util.AttributeSet; +import android.view.View; +import org.happysanta.gd.Game.Bitmap; +import org.happysanta.gd.Global; + +import static org.happysanta.gd.Helpers.getDp; +import static org.happysanta.gd.Helpers.isSDK11OrHigher; +import static org.happysanta.gd.Helpers.logDebug; + +public class MenuHelmetView extends View { + + protected static final int WIDTH = 8; + protected static final int HEIGHT = 8; + /*protected static final int PADDING_LEFT = 0; + protected static final int PADDING_TOP = 5; + protected static final int PADDING_RIGHT = 5; + protected static final int PADDING_BOTTOM = 0;*/ + + protected static int angle = 0; + protected static long angleLastMs = 0; + protected static final int angleInterval = 50; + protected static final int angleDelta = 10; + + protected boolean show = false; + protected boolean _setMeasuredHeight = false; + protected Bitmap helmet = Bitmap.get(Bitmap.HELMET); + protected static MenuHelmetView lastActive = null; + + public static void clearStaticFields() { + lastActive = null; + angle = 0; + angleLastMs = 0; + } + + public MenuHelmetView(Context context) { + super(context); + } + + public MenuHelmetView(Context context, AttributeSet attributeSet) { + super(context, attributeSet); + } + + @Override + public void onDraw(Canvas canvas) { + canvas.save(); + canvas.scale(Global.density, Global.density); + + drawHelmet(canvas); + + canvas.restore(); + invalidate(); + } + + protected void drawHelmet(Canvas canvas) { + if (show) { + long ms = System.currentTimeMillis(); + if (angleLastMs == 0 || ms - angleLastMs >= angleInterval) { + angle += angleDelta; + if (angle >= 360) angle -= 360; + angleLastMs = ms; + } + + int y = getScaledHeight() / 2 - helmet.getHeightDp() / 2; + + canvas.save(); + canvas.rotate(angle, helmet.getWidthDp() / 2, y + helmet.getHeightDp() / 2); + canvas.drawBitmap(helmet.bitmap, new Rect(0, 0, helmet.getWidth(), helmet.getHeight()), new RectF(0, y, helmet.getWidthDp(), y + helmet.getHeightDp()), null); + canvas.restore(); + } + } + + @Override + protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { + super.onMeasure(widthMeasureSpec, heightMeasureSpec); + int width = MeasureSpec.getSize(getDp(WIDTH * 2.2f)); + int height = heightMeasureSpec; + if (_setMeasuredHeight) + height = MeasureSpec.getSize(getDp(HEIGHT * 2.2f)); + else if (!isSDK11OrHigher()) { + height = MeasureSpec.getSize(getDp(HEIGHT * 4.5f)); + } + setMeasuredDimension(width, height); + } + + public void setShow(boolean show) { + setShow(show, true); + } + + public void setShow(boolean show, boolean checkLast) { + if (checkLast && lastActive != null) { + lastActive.setShow(false, false); + } + this.show = show; + lastActive = this; + } + + protected int getScaledHeight() { + return Math.round(getHeight() / Global.density); + } + + public void setMeasuredHeight(boolean setMeasuredHeight) { + this._setMeasuredHeight = setMeasuredHeight; + } + +} diff --git a/src/org/happysanta/gd/Menu/Views/MenuImageView.java b/src/org/happysanta/gd/Menu/Views/MenuImageView.java new file mode 100644 index 0000000..1ef3f70 --- /dev/null +++ b/src/org/happysanta/gd/Menu/Views/MenuImageView.java @@ -0,0 +1,34 @@ +package org.happysanta.gd.Menu.Views; + +import android.content.Context; +import android.widget.ImageView; + +import static org.happysanta.gd.Helpers.runOnUiThread; + +public class MenuImageView extends ImageView { + + public MenuImageView(Context context) { + super(context); + } + + @Override + public void setImageResource(final int resid) { + runOnUiThread(new Runnable() { + @Override + public void run() { + MenuImageView.super.setImageResource(resid); + } + }); + } + + @Override + public void setVisibility(final int visibility) { + runOnUiThread(new Runnable() { + @Override + public void run() { + MenuImageView.super.setVisibility(visibility); + } + }); + } + +} diff --git a/src/org/happysanta/gd/Menu/Views/MenuLinearLayout.java b/src/org/happysanta/gd/Menu/Views/MenuLinearLayout.java new file mode 100644 index 0000000..98f665e --- /dev/null +++ b/src/org/happysanta/gd/Menu/Views/MenuLinearLayout.java @@ -0,0 +1,68 @@ +package org.happysanta.gd.Menu.Views; + +import android.content.Context; +import android.view.MotionEvent; +import android.view.View; +import android.widget.LinearLayout; + +import static org.happysanta.gd.Helpers.runOnUiThread; + +public class MenuLinearLayout extends LinearLayout { + + boolean interceptTouchEvents = false; + + public MenuLinearLayout(Context context) { + super(context); + } + + public MenuLinearLayout(Context context, boolean interceptTouchEvents) { + super(context); + this.interceptTouchEvents = interceptTouchEvents; + } + + @Override + public void removeAllViews() { + runOnUiThread(new Runnable() { + @Override + public void run() { + MenuLinearLayout.super.removeAllViews(); + } + }); + } + + @Override + public void setVisibility(final int visibility) { + runOnUiThread(new Runnable() { + @Override + public void run() { + MenuLinearLayout.super.setVisibility(visibility); + } + }); + } + + @Override + public void addView(final View view) { + runOnUiThread(new Runnable() { + @Override + public void run() { + MenuLinearLayout.super.addView(view); + } + }); + } + + @Override + public void setPadding(final int left, final int top, final int right, final int bottom) { + runOnUiThread(new Runnable() { + @Override + public void run() { + MenuLinearLayout.super.setPadding(left, top, right, bottom); + } + }); + } + + @Override + public boolean onInterceptTouchEvent(MotionEvent evt) { + return interceptTouchEvents; + } + +} diff --git a/src/org/happysanta/gd/Menu/Views/MenuRelativeLayout.java b/src/org/happysanta/gd/Menu/Views/MenuRelativeLayout.java new file mode 100644 index 0000000..3e5e0d2 --- /dev/null +++ b/src/org/happysanta/gd/Menu/Views/MenuRelativeLayout.java @@ -0,0 +1,55 @@ +package org.happysanta.gd.Menu.Views; + +import android.content.Context; +import android.view.View; +import android.widget.RelativeLayout; + +import static org.happysanta.gd.Helpers.runOnUiThread; + +public class MenuRelativeLayout extends RelativeLayout { + + public MenuRelativeLayout(Context context) { + super(context); + } + + @Override + public void removeAllViews() { + runOnUiThread(new Runnable() { + @Override + public void run() { + MenuRelativeLayout.super.removeAllViews(); + } + }); + } + + @Override + public void setVisibility(final int visibility) { + runOnUiThread(new Runnable() { + @Override + public void run() { + MenuRelativeLayout.super.setVisibility(visibility); + } + }); + } + + @Override + public void addView(final View view) { + runOnUiThread(new Runnable() { + @Override + public void run() { + MenuRelativeLayout.super.addView(view); + } + }); + } + + @Override + public void setPadding(final int left, final int top, final int right, final int bottom) { + runOnUiThread(new Runnable() { + @Override + public void run() { + MenuRelativeLayout.super.setPadding(left, top, right, bottom); + } + }); + } + +} diff --git a/src/org/happysanta/gd/Menu/Views/MenuTextView.java b/src/org/happysanta/gd/Menu/Views/MenuTextView.java new file mode 100644 index 0000000..4b48f5f --- /dev/null +++ b/src/org/happysanta/gd/Menu/Views/MenuTextView.java @@ -0,0 +1,73 @@ +package org.happysanta.gd.Menu.Views; + +import android.content.Context; +import android.graphics.Typeface; +import android.widget.TextView; + +import static org.happysanta.gd.Helpers.runOnUiThread; + +public class MenuTextView extends TextView { + + protected boolean isAttached = false; + + public MenuTextView(Context context) { + super(context); + } + + @Override + protected void onAttachedToWindow() { + super.onAttachedToWindow(); + isAttached = true; + } + + @Override + protected void onDetachedFromWindow() { + super.onDetachedFromWindow(); + isAttached = false; + } + + @Override + public boolean isAttachedToWindow() { + return isAttached; + } + + public void setTextOnUiThread(final CharSequence sequence) { + runOnUiThread(new Runnable() { + @Override + public void run() { + MenuTextView.super.setText(sequence); + } + }); + } + + @Override + public void setTextSize(final float size) { + runOnUiThread(new Runnable() { + @Override + public void run() { + MenuTextView.super.setTextSize(size); + } + }); + } + + @Override + public void setTypeface(final Typeface typeface) { + runOnUiThread(new Runnable() { + @Override + public void run() { + MenuTextView.super.setTypeface(typeface); + } + }); + } + + @Override + public void setVisibility(final int visibility) { + runOnUiThread(new Runnable() { + @Override + public void run() { + MenuTextView.super.setVisibility(visibility); + } + }); + } + +} diff --git a/src/org/happysanta/gd/Menu/Views/MenuTitleLinearLayout.java b/src/org/happysanta/gd/Menu/Views/MenuTitleLinearLayout.java new file mode 100644 index 0000000..5c3f790 --- /dev/null +++ b/src/org/happysanta/gd/Menu/Views/MenuTitleLinearLayout.java @@ -0,0 +1,39 @@ +package org.happysanta.gd.Menu.Views; + +import android.app.Activity; +import android.widget.RelativeLayout; + +import static org.happysanta.gd.Helpers.logDebug; + +public class MenuTitleLinearLayout extends RelativeLayout { + + private Callback onSizeChangedCallback = null; + + public MenuTitleLinearLayout(Activity activity) { + super(activity); + } + + @Override + public void onSizeChanged(final int w, final int h, final int oldw, final int oldh) { + super.onSizeChanged(w, h, oldw, oldh); + + if (onSizeChangedCallback != null) { + onSizeChangedCallback.run(w, h, oldw, oldh); + } + } + + /*public void forceInvokeOnSizeChangedCallback() { + if (onSizeChangedCallback != null) { + onSizeChangedCallback.run(getWidth(), getHeight(), 0, 0); + } + }*/ + + public void setOnSizeChangedCallback(Callback callback) { + onSizeChangedCallback = callback; + } + + public interface Callback { + public abstract void run(int w, int h, int oldw, int oldh); + } + +} diff --git a/src/org/happysanta/gd/Menu/Views/MenuView.java b/src/org/happysanta/gd/Menu/Views/MenuView.java new file mode 100644 index 0000000..ba47071 --- /dev/null +++ b/src/org/happysanta/gd/Menu/Views/MenuView.java @@ -0,0 +1,12 @@ +package org.happysanta.gd.Menu.Views; + +import android.view.View; +import org.happysanta.gd.GDActivity; + +public class MenuView extends View { + + public MenuView(GDActivity activity) { + super(activity); + } + +} diff --git a/src/org/happysanta/gd/Menu/Views/ObservableScrollView.java b/src/org/happysanta/gd/Menu/Views/ObservableScrollView.java new file mode 100644 index 0000000..5801928 --- /dev/null +++ b/src/org/happysanta/gd/Menu/Views/ObservableScrollView.java @@ -0,0 +1,31 @@ +package org.happysanta.gd.Menu.Views; + +import android.content.Context; +import android.widget.ScrollView; + +public class ObservableScrollView + extends ScrollView { + + private OnScrollListener scrollListener = null; + + public ObservableScrollView(Context context) { + super(context); + } + + public void setOnScrollListener(OnScrollListener scrollListener) { + this.scrollListener = scrollListener; + } + + @Override + protected void onScrollChanged(int x, int y, int oldx, int oldy) { + super.onScrollChanged(x, y, oldx, oldy); + if (scrollListener != null) { + scrollListener.onScroll(this, x, y, oldx, oldy); + } + } + + public interface OnScrollListener { + public abstract void onScroll(ObservableScrollView scrollView, int x, int y, int oldx, int oldy); + } + +} -- cgit v1.2.3