From dfe737a8ebf1b4e449ee1e93c81062309de61c4e Mon Sep 17 00:00:00 2001 From: Max Lv Date: Sat, 28 Sep 2013 16:21:28 +0800 Subject: [PATCH] update menu --- .../md__category_background.9.png | Bin 0 -> 173 bytes .../drawable-hdpi/md__list_focused_holo.9.png | Bin 0 -> 191 bytes .../md__list_longpressed_holo.9.png | Bin 0 -> 154 bytes .../md__list_pressed_holo_dark.9.png | Bin 0 -> 159 bytes ...md__list_selector_disabled_holo_dark.9.png | Bin 0 -> 189 bytes .../md__category_background.9.png | Bin 0 -> 165 bytes .../drawable-mdpi/md__list_focused_holo.9.png | Bin 0 -> 171 bytes .../md__list_longpressed_holo.9.png | Bin 0 -> 151 bytes .../md__list_pressed_holo_dark.9.png | Bin 0 -> 158 bytes ...md__list_selector_disabled_holo_dark.9.png | Bin 0 -> 172 bytes .../md__category_background.9.png | Bin 0 -> 179 bytes .../md__list_focused_holo.9.png | Bin 0 -> 203 bytes .../md__list_longpressed_holo.9.png | Bin 0 -> 158 bytes .../md__list_pressed_holo_dark.9.png | Bin 0 -> 163 bytes ...md__list_selector_disabled_holo_dark.9.png | Bin 0 -> 190 bytes ...lector_background_transition_holo_dark.xml | 20 ++++ .../drawable/md__list_selector_holo_dark.xml | 27 +++++ src/main/res/layout/menu_row_category.xml | 5 + src/main/res/layout/menu_row_item.xml | 5 + src/main/res/values/colors.xml | 2 + src/main/res/values/ids.xml | 28 +++++ src/main/res/values/styles.xml | 31 +++++ .../com/github/shadowsocks/Shadowsocks.scala | 83 +++++++------ .../shadowsocks/database/MenuAdapter.scala | 113 ++++++++++++++++++ 24 files changed, 277 insertions(+), 37 deletions(-) create mode 100644 src/main/res/drawable-hdpi/md__category_background.9.png create mode 100644 src/main/res/drawable-hdpi/md__list_focused_holo.9.png create mode 100644 src/main/res/drawable-hdpi/md__list_longpressed_holo.9.png create mode 100644 src/main/res/drawable-hdpi/md__list_pressed_holo_dark.9.png create mode 100644 src/main/res/drawable-hdpi/md__list_selector_disabled_holo_dark.9.png create mode 100644 src/main/res/drawable-mdpi/md__category_background.9.png create mode 100644 src/main/res/drawable-mdpi/md__list_focused_holo.9.png create mode 100644 src/main/res/drawable-mdpi/md__list_longpressed_holo.9.png create mode 100644 src/main/res/drawable-mdpi/md__list_pressed_holo_dark.9.png create mode 100644 src/main/res/drawable-mdpi/md__list_selector_disabled_holo_dark.9.png create mode 100644 src/main/res/drawable-xhdpi/md__category_background.9.png create mode 100644 src/main/res/drawable-xhdpi/md__list_focused_holo.9.png create mode 100644 src/main/res/drawable-xhdpi/md__list_longpressed_holo.9.png create mode 100644 src/main/res/drawable-xhdpi/md__list_pressed_holo_dark.9.png create mode 100644 src/main/res/drawable-xhdpi/md__list_selector_disabled_holo_dark.9.png create mode 100644 src/main/res/drawable/md__list_selector_background_transition_holo_dark.xml create mode 100644 src/main/res/drawable/md__list_selector_holo_dark.xml create mode 100644 src/main/res/layout/menu_row_category.xml create mode 100644 src/main/res/layout/menu_row_item.xml create mode 100644 src/main/res/values/ids.xml create mode 100644 src/main/scala/com/github/shadowsocks/database/MenuAdapter.scala diff --git a/src/main/res/drawable-hdpi/md__category_background.9.png b/src/main/res/drawable-hdpi/md__category_background.9.png new file mode 100644 index 0000000000000000000000000000000000000000..43a20adcb19dd73d32f7555dfd96e5294800bc82 GIT binary patch literal 173 zcmeAS@N?(olHy`uVBq!ia0vp^+(2x^!3HF|ZYnwhDVAa<&kznEsNqQI0P;BtJR*yM z>N-J~(fs7;wLn3CPZ!4!kIuJO4Y>{&@Hhvq{NlFv|INDNQ&?t6z4B$!f5v;Ln>B;0 zU-ImdKI;Vst0HI7c0ssI2 literal 0 HcmV?d00001 diff --git a/src/main/res/drawable-hdpi/md__list_focused_holo.9.png b/src/main/res/drawable-hdpi/md__list_focused_holo.9.png new file mode 100644 index 0000000000000000000000000000000000000000..555270842a739eb45d404ab473ad38a4c730240c GIT binary patch literal 191 zcmeAS@N?(olHy`uVBq!ia0vp^+#t-s1|(OmDOUqhEX7WqAsj$Z!;#Vf2?p zbb>IW`N`93fr5#iE{-7*Q>RY2$k|}PUG3I8+hq?M&UySt({#?YOY9F7 zV)|4jusAQAw~U49z^wIm)#n)N-o9e&+IDtd30r~4TeZ_)uKQd*6*KFj^h@OhGw-CF i@bOgmX?1Mk5ox7hDXx8`mUDoXF?hQAxvX2?p zbb>IW`N`93fr2)kE{-7*QBRJJkl{&7FVVepxUS$Rt1LT2VAvn7lLLt0oo!v4%( tpjG6n=4tr&fORvYRP%q%M>EqU82;Q9of*be(FHVz!PC{xWt~$(699PnDoy|Z literal 0 HcmV?d00001 diff --git a/src/main/res/drawable-hdpi/md__list_pressed_holo_dark.9.png b/src/main/res/drawable-hdpi/md__list_pressed_holo_dark.9.png new file mode 100644 index 0000000000000000000000000000000000000000..5654cd69429fd0a3502a05b5f827bffab89cc7e0 GIT binary patch literal 159 zcmeAS@N?(olHy`uVBq!ia0vp^+#t-s1|(OmDOUqhEX7WqAsj$Z!;#Vf2?p zbb>IW`N`93fr5^nE{-7*QD_LZ%D`aoRl?HIGCc%n7=x#)pUXO@geCyJM=ZAh literal 0 HcmV?d00001 diff --git a/src/main/res/drawable-hdpi/md__list_selector_disabled_holo_dark.9.png b/src/main/res/drawable-hdpi/md__list_selector_disabled_holo_dark.9.png new file mode 100644 index 0000000000000000000000000000000000000000..f6fd30dcdc9c39c836e509486854f9da03486892 GIT binary patch literal 189 zcmeAS@N?(olHy`uVBq!ia0vp^;y~=k!3HF){@Qy1DVAa<&kznEsNqQI0P;BtJR*x3 z7`Qt@n9=;?>9s(?cuyC{kcif|*A4j^95`Gq9-KV8B6o6ra`I!Z80pW;7d5zZGhRBg zm{FnhT6Xzih3ZMUGkfBc^kAT_eS7{3zPQ8d#DAm4nJ zaCd?*qxs3xYk`8ko-U3d5>tD79C;fY1elknGfSSZkgss!Fq+WV_wb)ql1{DGd2)`S!@o4yre42YU?3urKd Mr>mdKI;Vst081n_F8}}l literal 0 HcmV?d00001 diff --git a/src/main/res/drawable-mdpi/md__list_longpressed_holo.9.png b/src/main/res/drawable-mdpi/md__list_longpressed_holo.9.png new file mode 100644 index 0000000000000000000000000000000000000000..3bf8e03623c94b68d31963ffe7e59c72c3dcc059 GIT binary patch literal 151 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqEX7WqAsj$Z!;#Vf4nJ zaCd?*qxs3xYk`86o-U3d5>t~CW>mH@a{g&g;s7!l1y4Byva-KaJLVIiI)OpBYodjS ofJx&-C1HsL_x|*Yp0_#7zz}{&aC*>dO_0?Lp00i_>zopr00f~Zw*UYD literal 0 HcmV?d00001 diff --git a/src/main/res/drawable-mdpi/md__list_pressed_holo_dark.9.png b/src/main/res/drawable-mdpi/md__list_pressed_holo_dark.9.png new file mode 100644 index 0000000000000000000000000000000000000000..6e77525d2dbbc1673145d60d775602c85264330d GIT binary patch literal 158 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqEX7WqAsj$Z!;#Vf4nJ zaCd?*qxs3xYk`6eo-U3d5>t~6?){p=$oZ!|i46oEul1LdSlBa@C*nY4{!0_J9HA2p woHspUxHx7V@R-QS6OjM!cw6swyHo~-e~lvMp^1B@1I=RaboFyt=akR{0Ay(_r~m)} literal 0 HcmV?d00001 diff --git a/src/main/res/drawable-mdpi/md__list_selector_disabled_holo_dark.9.png b/src/main/res/drawable-mdpi/md__list_selector_disabled_holo_dark.9.png new file mode 100644 index 0000000000000000000000000000000000000000..92da2f0dd3711a2ceb843768cafd6b91a2807b43 GIT binary patch literal 172 zcmeAS@N?(olHy`uVBq!ia0vp^{6MVD!3HFkzrK_Oq*#ibJVQ8upoSx*1IXtr@Q5sC zVBqcqVMg#;uvX%d>fBtxy+SfFGJhTv9Z9>9n%%Tr7{oI+Q@DMao9hQt@O?p#8;eZd15IY| MboFyt=akR{068-?^#A|> literal 0 HcmV?d00001 diff --git a/src/main/res/drawable-xhdpi/md__category_background.9.png b/src/main/res/drawable-xhdpi/md__category_background.9.png new file mode 100644 index 0000000000000000000000000000000000000000..942d72e65b095ad900722a8e5e7385228ae0c783 GIT binary patch literal 179 zcmeAS@N?(olHy`uVBq!ia0vp^d_e5P!3HGLFFij7q*#ibJVQ8upoSx*1IXtr@Q5sC zVBqcqVMg-D=*+w0EX1GeE8VNeS)2#7n8DN4&t;ucLK6V`fk$Nk literal 0 HcmV?d00001 diff --git a/src/main/res/drawable-xhdpi/md__list_longpressed_holo.9.png b/src/main/res/drawable-xhdpi/md__list_longpressed_holo.9.png new file mode 100644 index 0000000000000000000000000000000000000000..eda10e6123e1e1383c4617228ec0c96680d60dc7 GIT binary patch literal 158 zcmeAS@N?(olHy`uVBq!ia0vp^d?3uh1|;P@bT0xamSQK*5Dp-y;YjHK@;M7UB8wRq zxI00Z(fs7;wLn1!PZ!4!jfu$#Gb-B{xqtMx1s*(O%+nLV7IxRdaaX6Iu&3070|zpW ye6d-ZyJWwc+pgOl@x443T>9p%`1p8cx&%YrImy|zOvgZGF?hQAxvX literal 0 HcmV?d00001 diff --git a/src/main/res/drawable-xhdpi/md__list_selector_disabled_holo_dark.9.png b/src/main/res/drawable-xhdpi/md__list_selector_disabled_holo_dark.9.png new file mode 100644 index 0000000000000000000000000000000000000000..88726b69160589c8545759440e8d4e69dc984c67 GIT binary patch literal 190 zcmeAS@N?(olHy`uVBq!ia0vp^azGr$!3HF6SgS1tQk(@Ik;M!Q+?^oIXnykaTA*No zr;B4qM&sKXhJ1$tcw7#es=J@sd2yMiyW@jyg@u( + + + + + + diff --git a/src/main/res/drawable/md__list_selector_holo_dark.xml b/src/main/res/drawable/md__list_selector_holo_dark.xml new file mode 100644 index 00000000..bd71aa8b --- /dev/null +++ b/src/main/res/drawable/md__list_selector_holo_dark.xml @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + diff --git a/src/main/res/layout/menu_row_category.xml b/src/main/res/layout/menu_row_category.xml new file mode 100644 index 00000000..c89e5d96 --- /dev/null +++ b/src/main/res/layout/menu_row_category.xml @@ -0,0 +1,5 @@ + + \ No newline at end of file diff --git a/src/main/res/layout/menu_row_item.xml b/src/main/res/layout/menu_row_item.xml new file mode 100644 index 00000000..af2c4b38 --- /dev/null +++ b/src/main/res/layout/menu_row_item.xml @@ -0,0 +1,5 @@ + + \ No newline at end of file diff --git a/src/main/res/values/colors.xml b/src/main/res/values/colors.xml index bc48ae9a..c9f62e57 100644 --- a/src/main/res/values/colors.xml +++ b/src/main/res/values/colors.xml @@ -22,5 +22,7 @@ #646464 #c8c8c8 #323232 + #00000000 + #FF555555 \ No newline at end of file diff --git a/src/main/res/values/ids.xml b/src/main/res/values/ids.xml new file mode 100644 index 00000000..925ac058 --- /dev/null +++ b/src/main/res/values/ids.xml @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/main/res/values/styles.xml b/src/main/res/values/styles.xml index 93e381d0..a2272424 100644 --- a/src/main/res/values/styles.xml +++ b/src/main/res/values/styles.xml @@ -29,5 +29,36 @@ @style/Widget.Holo.Light.CompoundButton.Switch + + + + \ No newline at end of file diff --git a/src/main/scala/com/github/shadowsocks/Shadowsocks.scala b/src/main/scala/com/github/shadowsocks/Shadowsocks.scala index 8760a48c..47d83b39 100644 --- a/src/main/scala/com/github/shadowsocks/Shadowsocks.scala +++ b/src/main/scala/com/github/shadowsocks/Shadowsocks.scala @@ -46,7 +46,7 @@ import android.os._ import android.preference.{Preference, PreferenceManager} import android.util.Log import android.view.{ViewGroup, Gravity, ViewParent, KeyEvent} -import android.widget.{LinearLayout, CompoundButton, RelativeLayout, TextView} +import android.widget._ import com.actionbarsherlock.view.Menu import com.actionbarsherlock.view.MenuItem import com.google.analytics.tracking.android.EasyTracker @@ -68,7 +68,11 @@ import scala.concurrent.ops._ import android.content.SharedPreferences.OnSharedPreferenceChangeListener import com.google.ads.{AdRequest, AdSize, AdView} import net.simonvt.menudrawer.MenuDrawer -import javax.swing.text.html.ListView + +import com.github.shadowsocks.database.{MenuAdapter, Item, Category} +import scala.collection.mutable.ListBuffer +import com.github.shadowsocks.database.Category +import com.github.shadowsocks.database.Item object Shadowsocks { @@ -222,6 +226,8 @@ class Shadowsocks lazy val status = getSharedPreferences(Key.status, Context.MODE_PRIVATE) lazy val receiver = new StateBroadcastReceiver lazy val drawer = MenuDrawer.attach(this) + lazy val listView = new ListView(this) + lazy val menuAdapter = new MenuAdapter(this, getMenuList) private val handler: Handler = new Handler { override def handleMessage(msg: Message) { @@ -399,11 +405,8 @@ class Shadowsocks setHeaderRes(R.xml.shadowsocks_headers) super.onCreate(savedInstanceState) - val menuView = new TextView(this) - menuView.setTextColor(0xFFFFFFFF) - menuView.setText("As the drawer opens, the drawer indicator icon becomes smaller.") - menuView.setGravity(Gravity.CENTER) - drawer.setMenuView(menuView) + listView.setAdapter(menuAdapter) + drawer.setMenuView(listView) // The drawable that replaces the up indicator in the action bar drawer.setSlideDrawable(R.drawable.ic_drawer) @@ -440,26 +443,44 @@ class Shadowsocks handler.sendEmptyMessage(MSG_INITIAL_FINISH) } } + } -/* override def onCreateOptionsMenu(menu: Menu): Boolean = { - val isRoot = status.getBoolean(Key.isRoot, false) - menu - .add(0, 0, 0, R.string.recovery) - .setIcon(android.R.drawable.ic_menu_revert) - .setShowAsAction(MenuItem.SHOW_AS_ACTION_WITH_TEXT) - menu - .add(0, 1, 1, R.string.about) - .setIcon(android.R.drawable.ic_menu_info_details) - .setShowAsAction(MenuItem.SHOW_AS_ACTION_WITH_TEXT) - if (isRoot || Build.VERSION.SDK_INT < 17) { - menu - .add(0, 2, 2, R.string.flush_dnscache) - .setIcon(android.R.drawable.ic_menu_revert) - .setShowAsAction(MenuItem.SHOW_AS_ACTION_WITH_TEXT) - } - true - }*/ + def getProfileList: List[Item] = { + List[Item]() + } + + def getMenuList: List[Any] = { + + val buf = new ListBuffer[Any]() + + buf += new Category("Profiles") + + buf ++= getProfileList + + buf += new Category("Settings") + + buf += new Item(-1, getString(R.string.recovery), android.R.drawable.ic_menu_revert, + _ => { + EasyTracker.getTracker.sendEvent(Shadowsocks.TAG, "reset", getVersionName, 0L) + recovery() + }) + + buf += new Item(-2, getString(R.string.flush_dnscache), android.R.drawable.ic_menu_delete, + _ => { + EasyTracker.getTracker.sendEvent(Shadowsocks.TAG, "flush_dnscache", getVersionName, 0L) + flushDnsCache() + }) + + buf += new Item(-3, getString(R.string.about), android.R.drawable.ic_menu_info_details, + _ => { + EasyTracker.getTracker.sendEvent(Shadowsocks.TAG, "about", getVersionName, 0L) + showAbout() + }) + + buf.toList + + } override def onKeyDown(keyCode: Int, event: KeyEvent): Boolean = { if (keyCode == KeyEvent.KEYCODE_BACK && event.getRepeatCount == 0) { @@ -481,18 +502,6 @@ class Shadowsocks drawer.toggleMenu() return true } - case 0 => { - EasyTracker.getTracker.sendEvent(Shadowsocks.TAG, "reset", getVersionName, 0L) - recovery() - } - case 1 => { - EasyTracker.getTracker.sendEvent(Shadowsocks.TAG, "about", getVersionName, 0L) - showAbout() - } - case 2 => { - EasyTracker.getTracker.sendEvent(Shadowsocks.TAG, "flush_dnscache", getVersionName, 0L) - flushDnsCache() - } } super.onOptionsItemSelected(item) } diff --git a/src/main/scala/com/github/shadowsocks/database/MenuAdapter.scala b/src/main/scala/com/github/shadowsocks/database/MenuAdapter.scala new file mode 100644 index 00000000..1554d6a9 --- /dev/null +++ b/src/main/scala/com/github/shadowsocks/database/MenuAdapter.scala @@ -0,0 +1,113 @@ +package com.github.shadowsocks.database + +import android.content.{DialogInterface, Context} +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.BaseAdapter +import android.widget.TextView +import com.github.shadowsocks.R +import android.view.View.OnClickListener + +case class Item(id: Int, title: String, iconRes: Int, action: Int => Unit) + +case class Category (title: String) + +object MenuAdapter { + + trait MenuListener { + def onActiveViewChanged(v: View) + } + + val UNDEFINED = -1 + val CATEGORY = 0 + val ITEM = 1 + +} + +class MenuAdapter (context: Context, var items: List[Any]) extends BaseAdapter { + + def setListener(listener: MenuAdapter.MenuListener) { + mListener = listener + } + + def setActivePosition(activePosition: Int) { + mActivePosition = activePosition + } + + @Override def getCount: Int = { + items.size + } + + @Override def getItem(position: Int): Object = { + items(position).asInstanceOf[Object] + } + + @Override def getItemId(position: Int): Long = { + position + } + + @Override override def getItemViewType(position: Int): Int = { + getItem(position) match { + case Category => MenuAdapter.CATEGORY + case Item => MenuAdapter.ITEM + case _ => MenuAdapter.UNDEFINED + } + } + + @Override override def getViewTypeCount: Int = { + 3 + } + + @Override override def isEnabled(position: Int): Boolean = { + getItemViewType(position) != MenuAdapter.UNDEFINED + } + + @Override override def areAllItemsEnabled: Boolean = { + false + } + + @Override def getView(position: Int, convertView: View, parent: ViewGroup): View = { + var v: View = convertView + val item = getItem(position) + item match { + case value: Category => + if (v == null) { + v = LayoutInflater.from(context).inflate(R.layout.menu_row_category, parent, false) + } + v.asInstanceOf[TextView].setText(value.title) + case value: Item => + if (v == null) { + v = LayoutInflater.from(context).inflate(R.layout.menu_row_item, parent, false) + } + val tv: TextView = v.asInstanceOf[TextView] + tv.setText(value.title) + tv.setCompoundDrawablesWithIntrinsicBounds(value.iconRes, 0, 0, 0) + tv.setOnClickListener(new OnClickListener { + def onClick(view: View) { + val item = view.getTag(R.id.mdItem).asInstanceOf[Item] + item.action(item.id) + } + }) + + v.setTag(R.id.mdItem, value) + case _ => + } + v.setTag(R.id.mdActiveViewPosition, position) + + if (position == mActivePosition) { + if (mListener != null) mListener.onActiveViewChanged(v) + } + v + } + + def updateList(list: List[Any]) { + items = list + notifyDataSetChanged() + } + + private var mListener: MenuAdapter.MenuListener = null + private var mActivePosition: Int = 0 +} + +